From 737e177857862411ae9a51b9c6b04b126c8e7e1d Mon Sep 17 00:00:00 2001 From: Lee Anh Minh Date: Tue, 9 Jan 2024 18:25:34 +0700 Subject: [PATCH] add release 2.1.0 --- Makefile | 6 +- README.md | 10 +- deparse.c | 80 +- expected/11.17/extra/influxdb_fdw_post.out | 8913 ------------ expected/11.17/influxdb_fdw.out | 1651 --- .../schemaless/extra/influxdb_fdw_post.out | 9030 ------------- expected/11.17/schemaless/influxdb_fdw.out | 1613 --- expected/{11.17 => 12.16}/aggregate.out | 0 .../{12.12 => 12.16}/extra/aggregates.out | 0 .../extra/influxdb_fdw_post.out | 532 +- expected/{11.17 => 12.16}/extra/insert.out | 0 expected/{12.12 => 12.16}/extra/join.out | 0 expected/{11.17 => 12.16}/extra/limit.out | 0 expected/{11.17 => 12.16}/extra/prepare.out | 0 expected/{12.12 => 12.16}/extra/select.out | 0 .../{11.17 => 12.16}/extra/select_having.out | 0 expected/{12.12 => 12.16}/influxdb_fdw.out | 120 +- expected/{11.17 => 12.16}/option.out | 0 .../schemaless/add_fields.out | 0 .../schemaless/add_multi_key.out | 0 .../{12.12 => 12.16}/schemaless/add_tags.out | 0 .../{11.17 => 12.16}/schemaless/aggregate.out | 0 .../schemaless/extra/aggregates.out | 0 .../schemaless/extra/influxdb_fdw_post.out | 540 +- .../schemaless/extra/insert.out | 0 .../schemaless/extra/join.out | 0 .../schemaless/extra/limit.out | 0 .../schemaless/extra/prepare.out | 0 .../schemaless/extra/select.out | 0 .../schemaless/extra/select_having.out | 0 .../schemaless/influxdb_fdw.out | 4 +- .../schemaless/schemaless.out | 0 .../schemaless/selectfunc.out | 0 expected/{12.12 => 12.16}/selectfunc.out | 0 expected/{12.12 => 13.12}/aggregate.out | 0 expected/{13.8 => 13.12}/extra/aggregates.out | 0 .../extra/influxdb_fdw_post.out | 532 +- expected/{12.12 => 13.12}/extra/insert.out | 0 expected/{13.8 => 13.12}/extra/join.out | 0 expected/{13.8 => 13.12}/extra/limit.out | 0 expected/{13.8 => 13.12}/extra/prepare.out | 0 expected/{13.8 => 13.12}/extra/select.out | 0 .../{12.12 => 13.12}/extra/select_having.out | 0 expected/{13.8 => 13.12}/influxdb_fdw.out | 120 +- expected/{12.12 => 13.12}/option.out | 0 .../{13.8 => 13.12}/schemaless/add_fields.out | 0 .../schemaless/add_multi_key.out | 0 .../{13.8 => 13.12}/schemaless/add_tags.out | 0 .../{12.12 => 13.12}/schemaless/aggregate.out | 0 .../schemaless/extra/aggregates.out | 0 .../schemaless/extra/influxdb_fdw_post.out | 540 +- .../schemaless/extra/insert.out | 0 .../{13.8 => 13.12}/schemaless/extra/join.out | 0 .../schemaless/extra/limit.out | 0 .../schemaless/extra/prepare.out | 0 .../schemaless/extra/select.out | 0 .../schemaless/extra/select_having.out | 0 .../schemaless/influxdb_fdw.out | 4 +- .../{13.8 => 13.12}/schemaless/schemaless.out | 0 .../{13.8 => 13.12}/schemaless/selectfunc.out | 0 expected/{13.8 => 13.12}/selectfunc.out | 0 expected/{13.8 => 14.9}/aggregate.out | 0 expected/{14.5 => 14.9}/extra/aggregates.out | 0 .../extra/influxdb_fdw_post.out | 532 +- expected/{13.8 => 14.9}/extra/insert.out | 0 expected/{14.5 => 14.9}/extra/join.out | 0 expected/{14.5 => 14.9}/extra/limit.out | 0 expected/{14.5 => 14.9}/extra/prepare.out | 0 expected/{14.5 => 14.9}/extra/select.out | 0 .../{13.8 => 14.9}/extra/select_having.out | 0 expected/{15.0 => 14.9}/influxdb_fdw.out | 120 +- expected/{13.8 => 14.9}/option.out | 0 .../{14.5 => 14.9}/schemaless/add_fields.out | 0 .../schemaless/add_multi_key.out | 0 .../{14.5 => 14.9}/schemaless/add_tags.out | 0 .../{13.8 => 14.9}/schemaless/aggregate.out | 0 .../schemaless/extra/aggregates.out | 0 .../schemaless/extra/influxdb_fdw_post.out | 540 +- .../schemaless/extra/insert.out | 0 .../{14.5 => 14.9}/schemaless/extra/join.out | 0 .../{14.5 => 14.9}/schemaless/extra/limit.out | 0 .../schemaless/extra/prepare.out | 0 .../schemaless/extra/select.out | 0 .../schemaless/extra/select_having.out | 0 .../schemaless/influxdb_fdw.out | 4 +- .../{14.5 => 14.9}/schemaless/schemaless.out | 0 .../{14.5 => 14.9}/schemaless/selectfunc.out | 0 expected/{14.5 => 14.9}/selectfunc.out | 0 expected/{14.5 => 15.4}/aggregate.out | 0 expected/{15.0 => 15.4}/extra/aggregates.out | 0 .../extra/influxdb_fdw_post.out | 556 +- expected/{15.0 => 15.4}/extra/insert.out | 0 expected/{15.0 => 15.4}/extra/join.out | 0 expected/{15.0 => 15.4}/extra/limit.out | 0 expected/{15.0 => 15.4}/extra/prepare.out | 0 expected/{15.0 => 15.4}/extra/select.out | 0 .../{15.0 => 15.4}/extra/select_having.out | 0 expected/{14.5 => 15.4}/influxdb_fdw.out | 120 +- expected/{14.5 => 15.4}/option.out | 0 .../{15.0 => 15.4}/schemaless/add_fields.out | 0 .../schemaless/add_multi_key.out | 0 .../{15.0 => 15.4}/schemaless/add_tags.out | 0 .../{14.5 => 15.4}/schemaless/aggregate.out | 0 .../schemaless/extra/aggregates.out | 0 .../schemaless/extra/influxdb_fdw_post.out | 564 +- .../schemaless/extra/insert.out | 0 .../{15.0 => 15.4}/schemaless/extra/join.out | 0 .../{15.0 => 15.4}/schemaless/extra/limit.out | 0 .../schemaless/extra/prepare.out | 0 .../schemaless/extra/select.out | 0 .../schemaless/extra/select_having.out | 0 .../schemaless/influxdb_fdw.out | 4 +- .../{15.0 => 15.4}/schemaless/schemaless.out | 0 .../{15.0 => 15.4}/schemaless/selectfunc.out | 0 expected/{15.0 => 15.4}/selectfunc.out | 0 expected/{15.0 => 16.0}/aggregate.out | 0 expected/{11.17 => 16.0}/extra/aggregates.out | 813 +- expected/16.0/extra/influxdb_fdw_post.out | 11086 +++++++++++++++ expected/{14.5 => 16.0}/extra/insert.out | 29 +- expected/{11.17 => 16.0}/extra/join.out | 3078 +++-- expected/{12.12 => 16.0}/extra/limit.out | 296 +- expected/{12.12 => 16.0}/extra/prepare.out | 149 +- expected/{11.17 => 16.0}/extra/select.out | 181 +- .../{14.5 => 16.0}/extra/select_having.out | 2 + expected/16.0/influxdb_fdw.out | 1755 +++ expected/{15.0 => 16.0}/option.out | 0 .../{11.17 => 16.0}/schemaless/add_fields.out | 245 +- .../schemaless/add_multi_key.out | 246 +- .../{11.17 => 16.0}/schemaless/add_tags.out | 372 +- .../{15.0 => 16.0}/schemaless/aggregate.out | 0 .../schemaless/extra/aggregates.out | 838 +- .../schemaless/extra/influxdb_fdw_post.out | 11245 ++++++++++++++++ .../schemaless/extra/insert.out | 4 + .../{11.17 => 16.0}/schemaless/extra/join.out | 3732 +++-- .../schemaless/extra/limit.out | 296 +- .../schemaless/extra/prepare.out | 146 +- .../schemaless/extra/select.out | 164 +- .../schemaless/extra/select_having.out | 4 + expected/16.0/schemaless/influxdb_fdw.out | 1603 +++ .../{11.17 => 16.0}/schemaless/schemaless.out | 24 +- .../{11.17 => 16.0}/schemaless/selectfunc.out | 1634 +-- expected/{11.17 => 16.0}/selectfunc.out | 1640 +-- influxdb_fdw.c | 233 +- influxdb_fdw.h | 14 +- influxdb_query.c | 46 +- option.c | 33 +- query.cpp | 83 +- query.go | 64 +- query_cxx.h | 2 + sql/{11.17 => 12.16}/aggregate.sql | 0 sql/{11.17 => 12.16}/extra/aggregates.sql | 0 .../extra/influxdb_fdw_post.sql | 12 +- sql/{11.17 => 12.16}/extra/init.sql | 0 sql/{11.17 => 12.16}/extra/insert.sql | 0 sql/{12.12 => 12.16}/extra/join.sql | 0 sql/{11.17 => 12.16}/extra/limit.sql | 0 sql/{11.17 => 12.16}/extra/prepare.sql | 0 sql/{11.17 => 12.16}/extra/select.sql | 0 sql/{11.17 => 12.16}/extra/select_having.sql | 0 sql/{14.5 => 12.16}/influxdb_fdw.sql | 63 + sql/{11.17 => 12.16}/init.sql | 0 sql/{11.17 => 12.16}/option.sql | 0 .../schemaless/add_fields.sql | 0 .../schemaless/add_multi_key.sql | 0 sql/{11.17 => 12.16}/schemaless/add_tags.sql | 0 sql/{11.17 => 12.16}/schemaless/aggregate.sql | 0 .../schemaless/extra/aggregates.sql | 0 .../schemaless/extra/influxdb_fdw_post.sql | 20 +- .../schemaless/extra/insert.sql | 0 .../schemaless/extra/join.sql | 0 .../schemaless/extra/limit.sql | 0 .../schemaless/extra/prepare.sql | 0 .../schemaless/extra/select.sql | 0 .../schemaless/extra/select_having.sql | 0 .../schemaless/influxdb_fdw.sql | 0 sql/{11.17 => 12.16}/schemaless/init.sql | 0 .../schemaless/schemaless.sql | 0 .../schemaless/selectfunc.sql | 0 sql/{11.17 => 12.16}/selectfunc.sql | 0 sql/{12.12 => 13.12}/aggregate.sql | 0 sql/{12.12 => 13.12}/extra/aggregates.sql | 0 .../extra/influxdb_fdw_post.sql | 12 +- sql/{12.12 => 13.12}/extra/init.sql | 0 sql/{12.12 => 13.12}/extra/insert.sql | 0 sql/{13.8 => 13.12}/extra/join.sql | 0 sql/{12.12 => 13.12}/extra/limit.sql | 0 sql/{12.12 => 13.12}/extra/prepare.sql | 0 sql/{12.12 => 13.12}/extra/select.sql | 0 sql/{12.12 => 13.12}/extra/select_having.sql | 0 sql/{11.17 => 13.12}/influxdb_fdw.sql | 63 + sql/{12.12 => 13.12}/init.sql | 0 sql/{12.12 => 13.12}/option.sql | 0 .../schemaless/add_fields.sql | 0 .../schemaless/add_multi_key.sql | 0 sql/{12.12 => 13.12}/schemaless/add_tags.sql | 0 sql/{12.12 => 13.12}/schemaless/aggregate.sql | 0 .../schemaless/extra/aggregates.sql | 0 .../schemaless/extra/influxdb_fdw_post.sql | 20 +- .../schemaless/extra/insert.sql | 0 sql/{13.8 => 13.12}/schemaless/extra/join.sql | 0 .../schemaless/extra/limit.sql | 0 .../schemaless/extra/prepare.sql | 0 .../schemaless/extra/select.sql | 0 .../schemaless/extra/select_having.sql | 0 .../schemaless/influxdb_fdw.sql | 0 sql/{12.12 => 13.12}/schemaless/init.sql | 0 .../schemaless/schemaless.sql | 0 .../schemaless/selectfunc.sql | 0 sql/{12.12 => 13.12}/selectfunc.sql | 0 sql/{13.8 => 14.9}/aggregate.sql | 0 sql/{14.5 => 14.9}/extra/aggregates.sql | 0 .../extra/influxdb_fdw_post.sql | 12 +- sql/{13.8 => 14.9}/extra/init.sql | 0 sql/{13.8 => 14.9}/extra/insert.sql | 0 sql/{14.5 => 14.9}/extra/join.sql | 0 sql/{14.5 => 14.9}/extra/limit.sql | 0 sql/{14.5 => 14.9}/extra/prepare.sql | 0 sql/{14.5 => 14.9}/extra/select.sql | 0 sql/{13.8 => 14.9}/extra/select_having.sql | 0 sql/{13.8 => 14.9}/influxdb_fdw.sql | 63 + sql/{13.8 => 14.9}/init.sql | 0 sql/{13.8 => 14.9}/option.sql | 0 sql/{13.8 => 14.9}/schemaless/add_fields.sql | 0 .../schemaless/add_multi_key.sql | 0 sql/{13.8 => 14.9}/schemaless/add_tags.sql | 0 sql/{13.8 => 14.9}/schemaless/aggregate.sql | 0 .../schemaless/extra/aggregates.sql | 0 .../schemaless/extra/influxdb_fdw_post.sql | 20 +- .../schemaless/extra/insert.sql | 0 sql/{14.5 => 14.9}/schemaless/extra/join.sql | 0 sql/{14.5 => 14.9}/schemaless/extra/limit.sql | 0 .../schemaless/extra/prepare.sql | 0 .../schemaless/extra/select.sql | 0 .../schemaless/extra/select_having.sql | 0 .../schemaless/influxdb_fdw.sql | 0 sql/{13.8 => 14.9}/schemaless/init.sql | 0 sql/{13.8 => 14.9}/schemaless/schemaless.sql | 0 sql/{13.8 => 14.9}/schemaless/selectfunc.sql | 0 sql/{13.8 => 14.9}/selectfunc.sql | 0 sql/15.0/influxdb_fdw.sql | 625 - sql/{14.5 => 15.4}/aggregate.sql | 0 sql/{15.0 => 15.4}/extra/aggregates.sql | 0 .../extra/influxdb_fdw_post.sql | 12 +- sql/{14.5 => 15.4}/extra/init.sql | 0 sql/{15.0 => 15.4}/extra/insert.sql | 0 sql/{15.0 => 15.4}/extra/join.sql | 0 sql/{15.0 => 15.4}/extra/limit.sql | 0 sql/{15.0 => 15.4}/extra/prepare.sql | 0 sql/{15.0 => 15.4}/extra/select.sql | 0 sql/{15.0 => 15.4}/extra/select_having.sql | 0 sql/{12.12 => 15.4}/influxdb_fdw.sql | 63 + sql/{14.5 => 15.4}/init.sql | 0 sql/{14.5 => 15.4}/option.sql | 0 sql/{15.0 => 15.4}/schemaless/add_fields.sql | 0 .../schemaless/add_multi_key.sql | 0 sql/{15.0 => 15.4}/schemaless/add_tags.sql | 0 sql/{14.5 => 15.4}/schemaless/aggregate.sql | 0 .../schemaless/extra/aggregates.sql | 0 .../schemaless/extra/influxdb_fdw_post.sql | 20 +- .../schemaless/extra/insert.sql | 0 sql/{15.0 => 15.4}/schemaless/extra/join.sql | 0 sql/{15.0 => 15.4}/schemaless/extra/limit.sql | 0 .../schemaless/extra/prepare.sql | 0 .../schemaless/extra/select.sql | 0 .../schemaless/extra/select_having.sql | 0 .../schemaless/influxdb_fdw.sql | 0 sql/{14.5 => 15.4}/schemaless/init.sql | 0 sql/{14.5 => 15.4}/schemaless/schemaless.sql | 0 sql/{14.5 => 15.4}/schemaless/selectfunc.sql | 0 sql/{14.5 => 15.4}/selectfunc.sql | 0 sql/{15.0 => 16.0}/aggregate.sql | 0 sql/{13.8 => 16.0}/extra/aggregates.sql | 430 +- .../extra/influxdb_fdw_post.sql | 2904 +++- sql/{15.0 => 16.0}/extra/init.sql | 0 sql/{14.5 => 16.0}/extra/insert.sql | 29 +- sql/{11.17 => 16.0}/extra/join.sql | 1737 ++- sql/{13.8 => 16.0}/extra/limit.sql | 141 +- sql/{13.8 => 16.0}/extra/prepare.sql | 84 +- sql/{13.8 => 16.0}/extra/select.sql | 165 +- sql/{14.5 => 16.0}/extra/select_having.sql | 2 + sql/16.0/influxdb_fdw.sql | 688 + sql/{15.0 => 16.0}/init.sql | 0 sql/{15.0 => 16.0}/option.sql | 0 sql/{14.5 => 16.0}/schemaless/add_fields.sql | 48 +- .../schemaless/add_multi_key.sql | 53 +- sql/{14.5 => 16.0}/schemaless/add_tags.sql | 22 +- sql/{15.0 => 16.0}/schemaless/aggregate.sql | 0 .../schemaless/extra/aggregates.sql | 467 +- .../schemaless/extra/influxdb_fdw_post.sql | 2987 +++- .../schemaless/extra/insert.sql | 4 + sql/{11.17 => 16.0}/schemaless/extra/join.sql | 1797 ++- sql/{13.8 => 16.0}/schemaless/extra/limit.sql | 141 +- .../schemaless/extra/prepare.sql | 85 +- .../schemaless/extra/select.sql | 165 +- .../schemaless/extra/select_having.sql | 4 + .../schemaless/influxdb_fdw.sql | 2 + sql/{15.0 => 16.0}/schemaless/init.sql | 0 sql/{15.0 => 16.0}/schemaless/schemaless.sql | 0 sql/{15.0 => 16.0}/schemaless/selectfunc.sql | 0 sql/{15.0 => 16.0}/selectfunc.sql | 0 test.sh | 7 + 301 files changed, 47261 insertions(+), 31898 deletions(-) delete mode 100644 expected/11.17/extra/influxdb_fdw_post.out delete mode 100644 expected/11.17/influxdb_fdw.out delete mode 100644 expected/11.17/schemaless/extra/influxdb_fdw_post.out delete mode 100644 expected/11.17/schemaless/influxdb_fdw.out rename expected/{11.17 => 12.16}/aggregate.out (100%) rename expected/{12.12 => 12.16}/extra/aggregates.out (100%) rename expected/{12.12 => 12.16}/extra/influxdb_fdw_post.out (91%) rename expected/{11.17 => 12.16}/extra/insert.out (100%) rename expected/{12.12 => 12.16}/extra/join.out (100%) rename expected/{11.17 => 12.16}/extra/limit.out (100%) rename expected/{11.17 => 12.16}/extra/prepare.out (100%) rename expected/{12.12 => 12.16}/extra/select.out (100%) rename expected/{11.17 => 12.16}/extra/select_having.out (100%) rename expected/{12.12 => 12.16}/influxdb_fdw.out (92%) rename expected/{11.17 => 12.16}/option.out (100%) rename expected/{12.12 => 12.16}/schemaless/add_fields.out (100%) rename expected/{12.12 => 12.16}/schemaless/add_multi_key.out (100%) rename expected/{12.12 => 12.16}/schemaless/add_tags.out (100%) rename expected/{11.17 => 12.16}/schemaless/aggregate.out (100%) rename expected/{12.12 => 12.16}/schemaless/extra/aggregates.out (100%) rename expected/{12.12 => 12.16}/schemaless/extra/influxdb_fdw_post.out (90%) rename expected/{11.17 => 12.16}/schemaless/extra/insert.out (100%) rename expected/{12.12 => 12.16}/schemaless/extra/join.out (100%) rename expected/{11.17 => 12.16}/schemaless/extra/limit.out (100%) rename expected/{11.17 => 12.16}/schemaless/extra/prepare.out (100%) rename expected/{11.17 => 12.16}/schemaless/extra/select.out (100%) rename expected/{11.17 => 12.16}/schemaless/extra/select_having.out (100%) rename expected/{13.8 => 12.16}/schemaless/influxdb_fdw.out (99%) rename expected/{12.12 => 12.16}/schemaless/schemaless.out (100%) rename expected/{12.12 => 12.16}/schemaless/selectfunc.out (100%) rename expected/{12.12 => 12.16}/selectfunc.out (100%) rename expected/{12.12 => 13.12}/aggregate.out (100%) rename expected/{13.8 => 13.12}/extra/aggregates.out (100%) rename expected/{13.8 => 13.12}/extra/influxdb_fdw_post.out (91%) rename expected/{12.12 => 13.12}/extra/insert.out (100%) rename expected/{13.8 => 13.12}/extra/join.out (100%) rename expected/{13.8 => 13.12}/extra/limit.out (100%) rename expected/{13.8 => 13.12}/extra/prepare.out (100%) rename expected/{13.8 => 13.12}/extra/select.out (100%) rename expected/{12.12 => 13.12}/extra/select_having.out (100%) rename expected/{13.8 => 13.12}/influxdb_fdw.out (92%) rename expected/{12.12 => 13.12}/option.out (100%) rename expected/{13.8 => 13.12}/schemaless/add_fields.out (100%) rename expected/{13.8 => 13.12}/schemaless/add_multi_key.out (100%) rename expected/{13.8 => 13.12}/schemaless/add_tags.out (100%) rename expected/{12.12 => 13.12}/schemaless/aggregate.out (100%) rename expected/{13.8 => 13.12}/schemaless/extra/aggregates.out (100%) rename expected/{13.8 => 13.12}/schemaless/extra/influxdb_fdw_post.out (90%) rename expected/{12.12 => 13.12}/schemaless/extra/insert.out (100%) rename expected/{13.8 => 13.12}/schemaless/extra/join.out (100%) rename expected/{13.8 => 13.12}/schemaless/extra/limit.out (100%) rename expected/{13.8 => 13.12}/schemaless/extra/prepare.out (100%) rename expected/{12.12 => 13.12}/schemaless/extra/select.out (100%) rename expected/{12.12 => 13.12}/schemaless/extra/select_having.out (100%) rename expected/{12.12 => 13.12}/schemaless/influxdb_fdw.out (99%) rename expected/{13.8 => 13.12}/schemaless/schemaless.out (100%) rename expected/{13.8 => 13.12}/schemaless/selectfunc.out (100%) rename expected/{13.8 => 13.12}/selectfunc.out (100%) rename expected/{13.8 => 14.9}/aggregate.out (100%) rename expected/{14.5 => 14.9}/extra/aggregates.out (100%) rename expected/{14.5 => 14.9}/extra/influxdb_fdw_post.out (92%) rename expected/{13.8 => 14.9}/extra/insert.out (100%) rename expected/{14.5 => 14.9}/extra/join.out (100%) rename expected/{14.5 => 14.9}/extra/limit.out (100%) rename expected/{14.5 => 14.9}/extra/prepare.out (100%) rename expected/{14.5 => 14.9}/extra/select.out (100%) rename expected/{13.8 => 14.9}/extra/select_having.out (100%) rename expected/{15.0 => 14.9}/influxdb_fdw.out (92%) rename expected/{13.8 => 14.9}/option.out (100%) rename expected/{14.5 => 14.9}/schemaless/add_fields.out (100%) rename expected/{14.5 => 14.9}/schemaless/add_multi_key.out (100%) rename expected/{14.5 => 14.9}/schemaless/add_tags.out (100%) rename expected/{13.8 => 14.9}/schemaless/aggregate.out (100%) rename expected/{14.5 => 14.9}/schemaless/extra/aggregates.out (100%) rename expected/{14.5 => 14.9}/schemaless/extra/influxdb_fdw_post.out (91%) rename expected/{13.8 => 14.9}/schemaless/extra/insert.out (100%) rename expected/{14.5 => 14.9}/schemaless/extra/join.out (100%) rename expected/{14.5 => 14.9}/schemaless/extra/limit.out (100%) rename expected/{14.5 => 14.9}/schemaless/extra/prepare.out (100%) rename expected/{14.5 => 14.9}/schemaless/extra/select.out (100%) rename expected/{13.8 => 14.9}/schemaless/extra/select_having.out (100%) rename expected/{14.5 => 14.9}/schemaless/influxdb_fdw.out (99%) rename expected/{14.5 => 14.9}/schemaless/schemaless.out (100%) rename expected/{14.5 => 14.9}/schemaless/selectfunc.out (100%) rename expected/{14.5 => 14.9}/selectfunc.out (100%) rename expected/{14.5 => 15.4}/aggregate.out (100%) rename expected/{15.0 => 15.4}/extra/aggregates.out (100%) rename expected/{15.0 => 15.4}/extra/influxdb_fdw_post.out (92%) rename expected/{15.0 => 15.4}/extra/insert.out (100%) rename expected/{15.0 => 15.4}/extra/join.out (100%) rename expected/{15.0 => 15.4}/extra/limit.out (100%) rename expected/{15.0 => 15.4}/extra/prepare.out (100%) rename expected/{15.0 => 15.4}/extra/select.out (100%) rename expected/{15.0 => 15.4}/extra/select_having.out (100%) rename expected/{14.5 => 15.4}/influxdb_fdw.out (92%) rename expected/{14.5 => 15.4}/option.out (100%) rename expected/{15.0 => 15.4}/schemaless/add_fields.out (100%) rename expected/{15.0 => 15.4}/schemaless/add_multi_key.out (100%) rename expected/{15.0 => 15.4}/schemaless/add_tags.out (100%) rename expected/{14.5 => 15.4}/schemaless/aggregate.out (100%) rename expected/{15.0 => 15.4}/schemaless/extra/aggregates.out (100%) rename expected/{15.0 => 15.4}/schemaless/extra/influxdb_fdw_post.out (91%) rename expected/{15.0 => 15.4}/schemaless/extra/insert.out (100%) rename expected/{15.0 => 15.4}/schemaless/extra/join.out (100%) rename expected/{15.0 => 15.4}/schemaless/extra/limit.out (100%) rename expected/{15.0 => 15.4}/schemaless/extra/prepare.out (100%) rename expected/{15.0 => 15.4}/schemaless/extra/select.out (100%) rename expected/{15.0 => 15.4}/schemaless/extra/select_having.out (100%) rename expected/{15.0 => 15.4}/schemaless/influxdb_fdw.out (99%) rename expected/{15.0 => 15.4}/schemaless/schemaless.out (100%) rename expected/{15.0 => 15.4}/schemaless/selectfunc.out (100%) rename expected/{15.0 => 15.4}/selectfunc.out (100%) rename expected/{15.0 => 16.0}/aggregate.out (100%) rename expected/{11.17 => 16.0}/extra/aggregates.out (81%) create mode 100644 expected/16.0/extra/influxdb_fdw_post.out rename expected/{14.5 => 16.0}/extra/insert.out (97%) rename expected/{11.17 => 16.0}/extra/join.out (80%) rename expected/{12.12 => 16.0}/extra/limit.out (89%) rename expected/{12.12 => 16.0}/extra/prepare.out (80%) rename expected/{11.17 => 16.0}/extra/select.out (96%) rename expected/{14.5 => 16.0}/extra/select_having.out (99%) create mode 100644 expected/16.0/influxdb_fdw.out rename expected/{15.0 => 16.0}/option.out (100%) rename expected/{11.17 => 16.0}/schemaless/add_fields.out (91%) rename expected/{11.17 => 16.0}/schemaless/add_multi_key.out (95%) rename expected/{11.17 => 16.0}/schemaless/add_tags.out (91%) rename expected/{15.0 => 16.0}/schemaless/aggregate.out (100%) rename expected/{11.17 => 16.0}/schemaless/extra/aggregates.out (82%) create mode 100644 expected/16.0/schemaless/extra/influxdb_fdw_post.out rename expected/{14.5 => 16.0}/schemaless/extra/insert.out (99%) rename expected/{11.17 => 16.0}/schemaless/extra/join.out (76%) rename expected/{12.12 => 16.0}/schemaless/extra/limit.out (89%) rename expected/{12.12 => 16.0}/schemaless/extra/prepare.out (87%) rename expected/{13.8 => 16.0}/schemaless/extra/select.out (98%) rename expected/{14.5 => 16.0}/schemaless/extra/select_having.out (98%) create mode 100644 expected/16.0/schemaless/influxdb_fdw.out rename expected/{11.17 => 16.0}/schemaless/schemaless.out (99%) rename expected/{11.17 => 16.0}/schemaless/selectfunc.out (94%) rename expected/{11.17 => 16.0}/selectfunc.out (92%) rename sql/{11.17 => 12.16}/aggregate.sql (100%) rename sql/{11.17 => 12.16}/extra/aggregates.sql (100%) rename sql/{13.8 => 12.16}/extra/influxdb_fdw_post.sql (99%) rename sql/{11.17 => 12.16}/extra/init.sql (100%) rename sql/{11.17 => 12.16}/extra/insert.sql (100%) rename sql/{12.12 => 12.16}/extra/join.sql (100%) rename sql/{11.17 => 12.16}/extra/limit.sql (100%) rename sql/{11.17 => 12.16}/extra/prepare.sql (100%) rename sql/{11.17 => 12.16}/extra/select.sql (100%) rename sql/{11.17 => 12.16}/extra/select_having.sql (100%) rename sql/{14.5 => 12.16}/influxdb_fdw.sql (88%) rename sql/{11.17 => 12.16}/init.sql (100%) rename sql/{11.17 => 12.16}/option.sql (100%) rename sql/{11.17 => 12.16}/schemaless/add_fields.sql (100%) rename sql/{11.17 => 12.16}/schemaless/add_multi_key.sql (100%) rename sql/{11.17 => 12.16}/schemaless/add_tags.sql (100%) rename sql/{11.17 => 12.16}/schemaless/aggregate.sql (100%) rename sql/{11.17 => 12.16}/schemaless/extra/aggregates.sql (100%) rename sql/{12.12 => 12.16}/schemaless/extra/influxdb_fdw_post.sql (99%) rename sql/{11.17 => 12.16}/schemaless/extra/insert.sql (100%) rename sql/{12.12 => 12.16}/schemaless/extra/join.sql (100%) rename sql/{11.17 => 12.16}/schemaless/extra/limit.sql (100%) rename sql/{11.17 => 12.16}/schemaless/extra/prepare.sql (100%) rename sql/{11.17 => 12.16}/schemaless/extra/select.sql (100%) rename sql/{11.17 => 12.16}/schemaless/extra/select_having.sql (100%) rename sql/{11.17 => 12.16}/schemaless/influxdb_fdw.sql (100%) rename sql/{11.17 => 12.16}/schemaless/init.sql (100%) rename sql/{11.17 => 12.16}/schemaless/schemaless.sql (100%) rename sql/{11.17 => 12.16}/schemaless/selectfunc.sql (100%) rename sql/{11.17 => 12.16}/selectfunc.sql (100%) rename sql/{12.12 => 13.12}/aggregate.sql (100%) rename sql/{12.12 => 13.12}/extra/aggregates.sql (100%) rename sql/{11.17 => 13.12}/extra/influxdb_fdw_post.sql (99%) rename sql/{12.12 => 13.12}/extra/init.sql (100%) rename sql/{12.12 => 13.12}/extra/insert.sql (100%) rename sql/{13.8 => 13.12}/extra/join.sql (100%) rename sql/{12.12 => 13.12}/extra/limit.sql (100%) rename sql/{12.12 => 13.12}/extra/prepare.sql (100%) rename sql/{12.12 => 13.12}/extra/select.sql (100%) rename sql/{12.12 => 13.12}/extra/select_having.sql (100%) rename sql/{11.17 => 13.12}/influxdb_fdw.sql (88%) rename sql/{12.12 => 13.12}/init.sql (100%) rename sql/{12.12 => 13.12}/option.sql (100%) rename sql/{12.12 => 13.12}/schemaless/add_fields.sql (100%) rename sql/{12.12 => 13.12}/schemaless/add_multi_key.sql (100%) rename sql/{12.12 => 13.12}/schemaless/add_tags.sql (100%) rename sql/{12.12 => 13.12}/schemaless/aggregate.sql (100%) rename sql/{12.12 => 13.12}/schemaless/extra/aggregates.sql (100%) rename sql/{13.8 => 13.12}/schemaless/extra/influxdb_fdw_post.sql (99%) rename sql/{12.12 => 13.12}/schemaless/extra/insert.sql (100%) rename sql/{13.8 => 13.12}/schemaless/extra/join.sql (100%) rename sql/{12.12 => 13.12}/schemaless/extra/limit.sql (100%) rename sql/{12.12 => 13.12}/schemaless/extra/prepare.sql (100%) rename sql/{12.12 => 13.12}/schemaless/extra/select.sql (100%) rename sql/{12.12 => 13.12}/schemaless/extra/select_having.sql (100%) rename sql/{12.12 => 13.12}/schemaless/influxdb_fdw.sql (100%) rename sql/{12.12 => 13.12}/schemaless/init.sql (100%) rename sql/{12.12 => 13.12}/schemaless/schemaless.sql (100%) rename sql/{12.12 => 13.12}/schemaless/selectfunc.sql (100%) rename sql/{12.12 => 13.12}/selectfunc.sql (100%) rename sql/{13.8 => 14.9}/aggregate.sql (100%) rename sql/{14.5 => 14.9}/extra/aggregates.sql (100%) rename sql/{14.5 => 14.9}/extra/influxdb_fdw_post.sql (99%) rename sql/{13.8 => 14.9}/extra/init.sql (100%) rename sql/{13.8 => 14.9}/extra/insert.sql (100%) rename sql/{14.5 => 14.9}/extra/join.sql (100%) rename sql/{14.5 => 14.9}/extra/limit.sql (100%) rename sql/{14.5 => 14.9}/extra/prepare.sql (100%) rename sql/{14.5 => 14.9}/extra/select.sql (100%) rename sql/{13.8 => 14.9}/extra/select_having.sql (100%) rename sql/{13.8 => 14.9}/influxdb_fdw.sql (88%) rename sql/{13.8 => 14.9}/init.sql (100%) rename sql/{13.8 => 14.9}/option.sql (100%) rename sql/{13.8 => 14.9}/schemaless/add_fields.sql (100%) rename sql/{13.8 => 14.9}/schemaless/add_multi_key.sql (100%) rename sql/{13.8 => 14.9}/schemaless/add_tags.sql (100%) rename sql/{13.8 => 14.9}/schemaless/aggregate.sql (100%) rename sql/{14.5 => 14.9}/schemaless/extra/aggregates.sql (100%) rename sql/{14.5 => 14.9}/schemaless/extra/influxdb_fdw_post.sql (99%) rename sql/{13.8 => 14.9}/schemaless/extra/insert.sql (100%) rename sql/{14.5 => 14.9}/schemaless/extra/join.sql (100%) rename sql/{14.5 => 14.9}/schemaless/extra/limit.sql (100%) rename sql/{14.5 => 14.9}/schemaless/extra/prepare.sql (100%) rename sql/{14.5 => 14.9}/schemaless/extra/select.sql (100%) rename sql/{13.8 => 14.9}/schemaless/extra/select_having.sql (100%) rename sql/{13.8 => 14.9}/schemaless/influxdb_fdw.sql (100%) rename sql/{13.8 => 14.9}/schemaless/init.sql (100%) rename sql/{13.8 => 14.9}/schemaless/schemaless.sql (100%) rename sql/{13.8 => 14.9}/schemaless/selectfunc.sql (100%) rename sql/{13.8 => 14.9}/selectfunc.sql (100%) delete mode 100644 sql/15.0/influxdb_fdw.sql rename sql/{14.5 => 15.4}/aggregate.sql (100%) rename sql/{15.0 => 15.4}/extra/aggregates.sql (100%) rename sql/{15.0 => 15.4}/extra/influxdb_fdw_post.sql (99%) rename sql/{14.5 => 15.4}/extra/init.sql (100%) rename sql/{15.0 => 15.4}/extra/insert.sql (100%) rename sql/{15.0 => 15.4}/extra/join.sql (100%) rename sql/{15.0 => 15.4}/extra/limit.sql (100%) rename sql/{15.0 => 15.4}/extra/prepare.sql (100%) rename sql/{15.0 => 15.4}/extra/select.sql (100%) rename sql/{15.0 => 15.4}/extra/select_having.sql (100%) rename sql/{12.12 => 15.4}/influxdb_fdw.sql (88%) rename sql/{14.5 => 15.4}/init.sql (100%) rename sql/{14.5 => 15.4}/option.sql (100%) rename sql/{15.0 => 15.4}/schemaless/add_fields.sql (100%) rename sql/{15.0 => 15.4}/schemaless/add_multi_key.sql (100%) rename sql/{15.0 => 15.4}/schemaless/add_tags.sql (100%) rename sql/{14.5 => 15.4}/schemaless/aggregate.sql (100%) rename sql/{15.0 => 15.4}/schemaless/extra/aggregates.sql (100%) rename sql/{15.0 => 15.4}/schemaless/extra/influxdb_fdw_post.sql (99%) rename sql/{15.0 => 15.4}/schemaless/extra/insert.sql (100%) rename sql/{15.0 => 15.4}/schemaless/extra/join.sql (100%) rename sql/{15.0 => 15.4}/schemaless/extra/limit.sql (100%) rename sql/{15.0 => 15.4}/schemaless/extra/prepare.sql (100%) rename sql/{15.0 => 15.4}/schemaless/extra/select.sql (100%) rename sql/{15.0 => 15.4}/schemaless/extra/select_having.sql (100%) rename sql/{15.0 => 15.4}/schemaless/influxdb_fdw.sql (100%) rename sql/{14.5 => 15.4}/schemaless/init.sql (100%) rename sql/{14.5 => 15.4}/schemaless/schemaless.sql (100%) rename sql/{14.5 => 15.4}/schemaless/selectfunc.sql (100%) rename sql/{14.5 => 15.4}/selectfunc.sql (100%) rename sql/{15.0 => 16.0}/aggregate.sql (100%) rename sql/{13.8 => 16.0}/extra/aggregates.sql (86%) rename sql/{12.12 => 16.0}/extra/influxdb_fdw_post.sql (68%) rename sql/{15.0 => 16.0}/extra/init.sql (100%) rename sql/{14.5 => 16.0}/extra/insert.sql (96%) rename sql/{11.17 => 16.0}/extra/join.sql (80%) rename sql/{13.8 => 16.0}/extra/limit.sql (98%) rename sql/{13.8 => 16.0}/extra/prepare.sql (85%) rename sql/{13.8 => 16.0}/extra/select.sql (95%) rename sql/{14.5 => 16.0}/extra/select_having.sql (98%) create mode 100644 sql/16.0/influxdb_fdw.sql rename sql/{15.0 => 16.0}/init.sql (100%) rename sql/{15.0 => 16.0}/option.sql (100%) rename sql/{14.5 => 16.0}/schemaless/add_fields.sql (86%) rename sql/{14.5 => 16.0}/schemaless/add_multi_key.sql (93%) rename sql/{14.5 => 16.0}/schemaless/add_tags.sql (96%) rename sql/{15.0 => 16.0}/schemaless/aggregate.sql (100%) rename sql/{13.8 => 16.0}/schemaless/extra/aggregates.sql (85%) rename sql/{11.17 => 16.0}/schemaless/extra/influxdb_fdw_post.sql (73%) rename sql/{14.5 => 16.0}/schemaless/extra/insert.sql (99%) rename sql/{11.17 => 16.0}/schemaless/extra/join.sql (83%) rename sql/{13.8 => 16.0}/schemaless/extra/limit.sql (97%) rename sql/{13.8 => 16.0}/schemaless/extra/prepare.sql (84%) rename sql/{13.8 => 16.0}/schemaless/extra/select.sql (95%) rename sql/{14.5 => 16.0}/schemaless/extra/select_having.sql (98%) rename sql/{14.5 => 16.0}/schemaless/influxdb_fdw.sql (99%) rename sql/{15.0 => 16.0}/schemaless/init.sql (100%) rename sql/{15.0 => 16.0}/schemaless/schemaless.sql (100%) rename sql/{15.0 => 16.0}/schemaless/selectfunc.sql (100%) rename sql/{15.0 => 16.0}/selectfunc.sql (100%) diff --git a/Makefile b/Makefile index c321771..7a93911 100644 --- a/Makefile +++ b/Makefile @@ -47,7 +47,7 @@ endif #!CXX_CLIENT EXTENSION = influxdb_fdw DATA = influxdb_fdw--1.0.sql influxdb_fdw--1.1.sql influxdb_fdw--1.1--1.2.sql influxdb_fdw--1.2.sql influxdb_fdw--1.3.sql -REGRESS = aggregate influxdb_fdw selectfunc extra/join extra/limit extra/aggregates extra/insert extra/prepare extra/select_having extra/select extra/influxdb_fdw_post schemaless/aggregate schemaless/influxdb_fdw schemaless/selectfunc schemaless/schemaless schemaless/extra/join schemaless/extra/limit schemaless/extra/aggregates schemaless/extra/prepare schemaless/extra/select_having schemaless/extra/insert schemaless/extra/select schemaless/extra/influxdb_fdw_post schemaless/add_fields schemaless/add_tags schemaless/add_multi_key +REGRESS = extra/aggregates UNAME = uname OS := $(shell $(UNAME)) @@ -75,8 +75,8 @@ MAJORVERSION := $(basename $(VERSION)) endif endif -ifeq (,$(findstring $(MAJORVERSION), 11 12 13 14 15)) -$(error PostgreSQL 11, 12, 13, 14 or 15 is required to compile this extension) +ifeq (,$(findstring $(MAJORVERSION), 12 13 14 15 16.0)) +$(error PostgreSQL 12, 13, 14, 15 or 16.0 is required to compile this extension) endif ifdef REGRESS_PREFIX diff --git a/README.md b/README.md index da038c3..093cc57 100644 --- a/README.md +++ b/README.md @@ -2,7 +2,7 @@ InfluxDB Foreign Data Wrapper for PostgreSQL ============================================ This is a foreign data wrapper (FDW) to connect [PostgreSQL](https://www.postgresql.org/) -to [InfluxDB](https://www.influxdata.com) database file. This FDW works with PostgreSQL 11, 12, 13, 14, 15 and confirmed with +to [InfluxDB](https://www.influxdata.com) database file. This FDW works with PostgreSQL 12, 13, 14, 15, 16.0 and confirmed with - InfluxDB 1.8: with either [influxdb1-go](#install-influxdb-go-client-library) client or [influxdb-cxx](#install-influxdb_cxx-client-library) client. - InfluxDB 2.2: with [influxdb-cxx](#install-influxdb_cxx-client-library) client via InfluxDB v1 compatibility API. @@ -288,7 +288,7 @@ Supported platforms `influxdb_fdw` was developed on Linux, and should run on any reasonably POSIX-compliant system. -`influxdb_fdw` is designed to be compatible with PostgreSQL 11 ~ 15. +`influxdb_fdw` is designed to be compatible with PostgreSQL 12 ~ 16.0. Installation ------------ @@ -780,6 +780,10 @@ the number of points with field1 and field2 are different in *InfluxDB* database - Conditions like `WHERE time + interval '1 day' < now()` do not work. Please use `WHERE time < now() - interval '1 day'`. - InfluxDB FDW does not return an error even if it is overflow. - `EXP` function of *InfluxDB* may return different precision number for different PC. +- InfluxDB only supports some basic types for tags (string only) and fields (string, float, integer or boolean) => most Postgres types cannot be supported. +- `IMPORT FOREIGN SCHEMA` should be used to identify foreign tables. + - If the user defines it manually, it is necessary to use the correct mapping type in the foreign table to avoid some unexpected behavior because of type mismatch or unsupported in InfluxDB. + - If a user wants to use an unsupported type with InfluxDB data, PostgreSQL's explicit cast functions should be used instead of define column type in foreign table directly. When a query to foreign tables fails, you can find why it fails by seeing a query executed in *InfluxDB* with `EXPLAIN VERBOSE`. @@ -812,7 +816,7 @@ Reference FDW realisation, `postgres_fdw` License ------- -Copyright (c) 2018-2023, TOSHIBA CORPORATION +Copyright (c) 2018, TOSHIBA CORPORATION Copyright (c) 2011-2016, EnterpriseDB Corporation diff --git a/deparse.c b/deparse.c index 1871e96..431db0c 100644 --- a/deparse.c +++ b/deparse.c @@ -19,12 +19,16 @@ #include "access/htup_details.h" #include "access/sysattr.h" #include "catalog/pg_aggregate.h" +#include "catalog/pg_authid.h" #include "catalog/pg_collation.h" #include "catalog/pg_namespace.h" #include "catalog/pg_operator.h" #include "catalog/pg_proc.h" +#include "catalog/pg_ts_config.h" +#include "catalog/pg_ts_dict.h" #include "catalog/pg_type.h" #include "commands/defrem.h" +#include "miscadmin.h" #include "nodes/nodeFuncs.h" #include "nodes/plannodes.h" #include "optimizer/clauses.h" @@ -228,7 +232,7 @@ static bool influxdb_foreign_expr_walker(Node *node, /* * Functions to construct string representation of a node tree. */ -static void influxdb_deparse_expr(Expr *expr, deparse_expr_cxt *context); +static void influxdb_deparse_expr(Expr *node, deparse_expr_cxt *context); static void influxdb_deparse_var(Var *node, deparse_expr_cxt *context); static void influxdb_deparse_const(Const *node, deparse_expr_cxt *context, int showtype); static void influxdb_deparse_param(Param *node, deparse_expr_cxt *context); @@ -287,6 +291,7 @@ bool influxdb_is_star_func(Oid funcid, char *in); static bool influxdb_is_unique_func(Oid funcid, char *in); static bool influxdb_is_supported_builtin_func(Oid funcid, char *in); static bool exist_in_function_list(char *funcname, const char **funclist); +static void add_backslash(StringInfo buf, const char *ptr, const char *regex_special); /* * Local variables. @@ -2116,6 +2121,24 @@ influxdb_deparse_column_ref(StringInfo buf, int varno, int varattno, Oid vartype } } +static void +add_backslash(StringInfo buf, const char *ptr, const char *regex_special) +{ + char ch = *ptr; + + /* Check regex special character */ + if (strchr(regex_special, ch) != NULL) + { + /* Escape this char */ + appendStringInfoChar(buf, '\\'); + appendStringInfoChar(buf, ch); + } + else + { + appendStringInfoChar(buf, ch); + } +} + /* * Append a SQL string regex representing "val" to buf. * @@ -2167,23 +2190,13 @@ influxdb_deparse_string_regex(StringInfo buf, const char *val) elog(ERROR, "invalid pattern matching"); } else - default: { - char ch = *ptr; - - /* Check regex special character */ - if (strchr(regex_special, ch) != NULL) - { - /* Escape this char */ - appendStringInfoChar(buf, '\\'); - appendStringInfoChar(buf, ch); - } - else - { - appendStringInfoChar(buf, ch); - } + add_backslash(buf, ptr, regex_special); } break; + default: + add_backslash(buf, ptr, regex_special); + break; } ptr++; @@ -3462,6 +3475,13 @@ influxdb_append_group_by_clause(List *tlist, deparse_expr_cxt *context) Assert(!query->groupingSets); context->influx_fill_expr = NULL; + /* + * We intentionally print query->groupClause not processed_groupClause, + * leaving it to the remote planner to get rid of any redundant GROUP BY + * items again. This is necessary in case processed_groupClause reduced + * to empty, and in any case the redundancy situation on the remote might + * be different than what we think here. + */ foreach(lc, query->groupClause) { SortGroupClause *grp = (SortGroupClause *) lfirst(lc); @@ -3808,7 +3828,7 @@ influxdb_is_tag_key(const char *colname, Oid reloid) ListCell *lc; /* Get FDW options */ - options = influxdb_get_options(reloid); + options = influxdb_get_options(reloid, GetUserId()); /* If there is no tag in "tags" option, it means column is field */ if (!options->tags_list) @@ -3831,19 +3851,13 @@ influxdb_is_tag_key(const char *colname, Oid reloid) *****************************************************************************/ /* - * influxdb_contain_functions + * influxdb_contain_functions_walker * Recursively search for functions within a clause. * * Returns true if any function (or operator implemented by function) is found. * * We will recursively look into TargetEntry exprs. */ -static bool -influxdb_contain_functions(Node *clause) -{ - return influxdb_contain_functions_walker(clause, NULL); -} - static bool influxdb_contain_functions_walker(Node *node, void *context) { @@ -3860,10 +3874,10 @@ influxdb_contain_functions_walker(Node *node, void *context) { /* Recurse into subselects */ return query_tree_walker((Query *) node, - influxdb_contain_functions, + influxdb_contain_functions_walker, context, 0); } - return expression_tree_walker(node, influxdb_contain_functions, + return expression_tree_walker(node, influxdb_contain_functions_walker, context); } @@ -3894,7 +3908,7 @@ influxdb_is_foreign_function_tlist(PlannerInfo *root, { TargetEntry *tle = lfirst_node(TargetEntry, lc); - if (influxdb_contain_functions((Node *) tle->expr)) + if (influxdb_contain_functions_walker((Node *) tle->expr, NULL)) { is_contain_function = true; break; @@ -4149,7 +4163,7 @@ influxdb_get_number_tag_key(Oid relid, schemaless_info *pslinfo) influxdb_opt *options; /* Get FDW options */ - options = influxdb_get_options(relid); + options = influxdb_get_options(relid, GetUserId()); return list_length(options->tags_list); } @@ -4558,3 +4572,15 @@ influxdb_escape_record_string(char *string) return buffer->data; } + +/* + * Construct DROP MEASUREMENT query. + * This query deletes all data and series from the specified + * and deletes the measurement from the index. + */ +void +influxdb_deparse_drop_measurement_stmt(StringInfo buf, Relation rel) +{ + appendStringInfo(buf, "DROP MEASUREMENT "); + influxdb_deparse_relation(buf, rel); +} diff --git a/expected/11.17/extra/influxdb_fdw_post.out b/expected/11.17/extra/influxdb_fdw_post.out deleted file mode 100644 index 04784c9..0000000 --- a/expected/11.17/extra/influxdb_fdw_post.out +++ /dev/null @@ -1,8913 +0,0 @@ --- =================================================================== --- create FDW objects --- =================================================================== -\set ECHO none ---Testcase 1: -CREATE EXTENSION influxdb_fdw; ---Testcase 2: -CREATE SERVER testserver1 FOREIGN DATA WRAPPER influxdb_fdw; ---Testcase 3: -CREATE SERVER influxdb_svr FOREIGN DATA WRAPPER influxdb_fdw - OPTIONS (dbname 'postdb', :SERVER); ---Testcase 4: -CREATE SERVER influxdb_svr2 FOREIGN DATA WRAPPER influxdb_fdw - OPTIONS (dbname 'postdb', :SERVER); ---Testcase 5: -CREATE USER MAPPING FOR public SERVER testserver1 OPTIONS (user 'value', password 'value'); ---Testcase 6: -CREATE USER MAPPING FOR CURRENT_USER SERVER influxdb_svr OPTIONS (:AUTHENTICATION); ---Testcase 7: -CREATE USER MAPPING FOR CURRENT_USER SERVER influxdb_svr2 OPTIONS (:AUTHENTICATION); --- =================================================================== --- create objects used through FDW influxdb server --- =================================================================== ---Testcase 8: -CREATE TYPE user_enum AS ENUM ('foo', 'bar', 'buz'); ---Testcase 9: -CREATE SCHEMA "S 1"; ---Testcase 10: -CREATE FOREIGN TABLE "S 1"."T 0" ( - "C 1" int NOT NULL, - c2 int NOT NULL, - c3 text, - time timestamp, - c6 varchar(10), - c7 char(10), - c8 text -) SERVER influxdb_svr OPTIONS (table 'T0', tags 'c3'); ---Testcase 11: -CREATE FOREIGN TABLE "S 1"."T 1" ( - "C 1" int NOT NULL, - c2 int NOT NULL, - c3 text, - time timestamp, - c6 varchar(10), - c7 char(10), - c8 text -) SERVER influxdb_svr OPTIONS (table 'T1', tags 'c3'); ---Testcase 12: -CREATE FOREIGN TABLE "S 1"."T 2" ( - c1 int NOT NULL, - c2 text -) SERVER influxdb_svr OPTIONS (table 'T2', tags 'c2'); ---Testcase 13: -CREATE FOREIGN TABLE "S 1"."T 3" ( - c1 int NOT NULL, - c2 int NOT NULL, - c3 text -) SERVER influxdb_svr OPTIONS (table 'T3', tags 'c3'); ---Testcase 14: -CREATE FOREIGN TABLE "S 1"."T 4" ( - c1 int NOT NULL, - c2 int NOT NULL, - c3 text -) SERVER influxdb_svr OPTIONS (table 'T4', tags 'c3'); --- Disable autovacuum for these tables to avoid unexpected effects of that ---ALTER TABLE "S 1"."T 1" SET (autovacuum_enabled = 'false'); ---ALTER TABLE "S 1"."T 2" SET (autovacuum_enabled = 'false'); ---ALTER TABLE "S 1"."T 3" SET (autovacuum_enabled = 'false'); ---ALTER TABLE "S 1"."T 4" SET (autovacuum_enabled = 'false'); ---Testcase 15: -INSERT INTO "S 1"."T 1" - SELECT id, - id % 10, - to_char(id, 'FM00000'), - '1970-01-01'::timestamp + ((id % 100) || ' days')::interval, - id % 10, - id % 10, - 'foo'::text - FROM generate_series(1, 1000) id; ---Testcase 16: -INSERT INTO "S 1"."T 2" - SELECT id, - 'AAA' || to_char(id, 'FM000') - FROM generate_series(1, 100) id; ---Testcase 17: -INSERT INTO "S 1"."T 3" - SELECT id, - id + 1, - 'AAA' || to_char(id, 'FM000') - FROM generate_series(1, 100) id; ---Testcase 18: -DELETE FROM "S 1"."T 3" WHERE c1 % 2 != 0; -- delete for outer join tests ---Testcase 19: -INSERT INTO "S 1"."T 4" - SELECT id, - id + 1, - 'AAA' || to_char(id, 'FM000') - FROM generate_series(1, 100) id; ---Testcase 20: -DELETE FROM "S 1"."T 4" WHERE c1 % 3 != 0; -- delete for outer join tests ---ANALYZE "S 1"."T 1"; ---ANALYZE "S 1"."T 2"; ---ANALYZE "S 1"."T 3"; ---ANALYZE "S 1"."T 4"; --- =================================================================== --- create foreign tables --- =================================================================== ---Testcase 21: -CREATE FOREIGN TABLE ft1 ( - c0 int, - c1 int NOT NULL, - c2 int NOT NULL, - c3 text, - time timestamp, - c6 varchar(10), - c7 char(10) default 'ft1', - c8 text -) SERVER influxdb_svr; -ALTER FOREIGN TABLE ft1 DROP COLUMN c0; ---Testcase 22: -CREATE FOREIGN TABLE ft2 ( - c1 int NOT NULL, - c2 int NOT NULL, - cx int, - c3 text, - time timestamp, - c6 varchar(10), - c7 char(10) default 'ft2', - c8 text -) SERVER influxdb_svr; -ALTER FOREIGN TABLE ft2 DROP COLUMN cx; ---Testcase 23: -CREATE FOREIGN TABLE ft4 ( - c1 int NOT NULL, - c2 int NOT NULL, - c3 text -) SERVER influxdb_svr OPTIONS (table 'T3', tags 'c3'); ---Testcase 24: -CREATE FOREIGN TABLE ft5 ( - c1 int NOT NULL, - c2 int NOT NULL, - c3 text -) SERVER influxdb_svr OPTIONS (table 'T4', tags 'c3'); ---Testcase 25: -CREATE FOREIGN TABLE ft6 ( - c1 int NOT NULL, - c2 int NOT NULL, - c3 text -) SERVER influxdb_svr2 OPTIONS (table 'T4', tags 'c3'); --- =================================================================== --- tests for validator --- =================================================================== --- requiressl and some other parameters are omitted because --- valid values for them depend on configure options -ALTER SERVER testserver1 OPTIONS ( - -- use_remote_estimate 'false', - -- updatable 'true', - -- fdw_startup_cost '123.456', - -- fdw_tuple_cost '0.123', - -- service 'value', - -- connect_timeout 'value', - dbname 'value', - host 'value', - -- hostaddr 'value', - port 'value' - --client_encoding 'value', - -- application_name 'value', - --fallback_application_name 'value', - -- keepalives 'value', - -- keepalives_idle 'value', - -- keepalives_interval 'value', - -- tcp_user_timeout 'value', - -- requiressl 'value', - -- sslcompression 'value', - -- sslmode 'value', - -- sslcert 'value', - -- sslkey 'value', - -- sslrootcert 'value', - -- sslcrl 'value', - --requirepeer 'value', - -- krbsrvname 'value', - -- gsslib 'value', - --replication 'value' -); --- influxdb_fdw does not support option extensions --- Error, invalid list syntax ---ALTER SERVER testserver1 OPTIONS (ADD extensions 'foo; bar'); --- OK but gets a warning ---ALTER SERVER testserver1 OPTIONS (ADD extensions 'foo, bar'); ---ALTER SERVER testserver1 OPTIONS (DROP extensions); -ALTER USER MAPPING FOR public SERVER testserver1 - OPTIONS (DROP user, DROP password); --- Attempt to add a valid option that's not allowed in a user mapping ---ALTER USER MAPPING FOR public SERVER testserver1 --- OPTIONS (ADD sslmode 'require'); --- But we can add valid ones fine ---ALTER USER MAPPING FOR public SERVER testserver1 --- OPTIONS (ADD sslpassword 'dummy'); --- Ensure valid options we haven't used in a user mapping yet are --- permitted to check validation. ---ALTER USER MAPPING FOR public SERVER testserver1 --- OPTIONS (ADD sslkey 'value', ADD sslcert 'value'); -ALTER FOREIGN TABLE ft1 OPTIONS (table 'T1', tags 'c3'); -ALTER FOREIGN TABLE ft2 OPTIONS (table 'T1', tags 'c3'); -ALTER FOREIGN TABLE ft1 ALTER COLUMN c1 OPTIONS (column_name 'C 1'); -ALTER FOREIGN TABLE ft2 ALTER COLUMN c1 OPTIONS (column_name 'C 1'); ---Testcase 26: -\det+ - List of foreign tables - Schema | Table | Server | FDW options | Description ---------+-------+---------------+---------------------------+------------- - public | ft1 | influxdb_svr | ("table" 'T1', tags 'c3') | - public | ft2 | influxdb_svr | ("table" 'T1', tags 'c3') | - public | ft4 | influxdb_svr | ("table" 'T3', tags 'c3') | - public | ft5 | influxdb_svr | ("table" 'T4', tags 'c3') | - public | ft6 | influxdb_svr2 | ("table" 'T4', tags 'c3') | -(5 rows) - --- Test that alteration of server options causes reconnection --- Remote's errors might be non-English, so hide them to ensure stable results -\set VERBOSITY terse ---Testcase 27: -SELECT c3, time FROM ft1 ORDER BY c3, c1 LIMIT 1; -- should work - c3 | time --------+-------------------------- - 00001 | Fri Jan 02 00:00:00 1970 -(1 row) - -ALTER SERVER influxdb_svr OPTIONS (SET dbname 'no such database'); ---Testcase 28: -SELECT c3, time FROM ft1 ORDER BY c3, c1 LIMIT 1; -- should fail -ERROR: influxdb_fdw : database not found: no such database -DO $d$ - BEGIN - EXECUTE $$ALTER SERVER influxdb_svr - OPTIONS (SET dbname 'postdb')$$; - END; -$d$; ---Testcase 29: -SELECT c3, time FROM ft1 ORDER BY c3, c1 LIMIT 1; -- should work again - c3 | time --------+-------------------------- - 00001 | Fri Jan 02 00:00:00 1970 -(1 row) - -\set VERBOSITY default --- =================================================================== --- simple queries --- =================================================================== --- single table without alias ---Testcase 30: -EXPLAIN (COSTS OFF) SELECT * FROM ft1 ORDER BY c3, c1 OFFSET 100 LIMIT 10; - QUERY PLAN ---------------------------------- - Limit - -> Sort - Sort Key: c3, c1 - -> Foreign Scan on ft1 -(4 rows) - ---Testcase 31: -SELECT * FROM ft1 ORDER BY c3, c1 OFFSET 100 LIMIT 10; - c1 | c2 | c3 | time | c6 | c7 | c8 ------+----+-------+--------------------------+----+------------+----- - 101 | 1 | 00101 | Fri Jan 02 00:00:00 1970 | 1 | 1 | foo - 102 | 2 | 00102 | Sat Jan 03 00:00:00 1970 | 2 | 2 | foo - 103 | 3 | 00103 | Sun Jan 04 00:00:00 1970 | 3 | 3 | foo - 104 | 4 | 00104 | Mon Jan 05 00:00:00 1970 | 4 | 4 | foo - 105 | 5 | 00105 | Tue Jan 06 00:00:00 1970 | 5 | 5 | foo - 106 | 6 | 00106 | Wed Jan 07 00:00:00 1970 | 6 | 6 | foo - 107 | 7 | 00107 | Thu Jan 08 00:00:00 1970 | 7 | 7 | foo - 108 | 8 | 00108 | Fri Jan 09 00:00:00 1970 | 8 | 8 | foo - 109 | 9 | 00109 | Sat Jan 10 00:00:00 1970 | 9 | 9 | foo - 110 | 0 | 00110 | Sun Jan 11 00:00:00 1970 | 0 | 0 | foo -(10 rows) - --- single table with alias - also test that tableoid sort is not pushed to remote side ---Testcase 32: -EXPLAIN (VERBOSE, COSTS OFF) SELECT * FROM ft1 t1 ORDER BY t1.c3, t1.c1, t1.tableoid OFFSET 100 LIMIT 10; - QUERY PLAN ------------------------------------------------------------------------------------- - Limit - Output: c1, c2, c3, "time", c6, c7, c8, tableoid - -> Sort - Output: c1, c2, c3, "time", c6, c7, c8, tableoid - Sort Key: t1.c3, t1.c1, t1.tableoid - -> Foreign Scan on public.ft1 t1 - Output: c1, c2, c3, "time", c6, c7, c8, tableoid - InfluxDB query: SELECT "C 1", "c2", "c3", "c6", "c7", "c8" FROM "T1" -(8 rows) - ---Testcase 33: -SELECT * FROM ft1 t1 ORDER BY t1.c3, t1.c1, t1.tableoid OFFSET 100 LIMIT 10; - c1 | c2 | c3 | time | c6 | c7 | c8 ------+----+-------+--------------------------+----+------------+----- - 101 | 1 | 00101 | Fri Jan 02 00:00:00 1970 | 1 | 1 | foo - 102 | 2 | 00102 | Sat Jan 03 00:00:00 1970 | 2 | 2 | foo - 103 | 3 | 00103 | Sun Jan 04 00:00:00 1970 | 3 | 3 | foo - 104 | 4 | 00104 | Mon Jan 05 00:00:00 1970 | 4 | 4 | foo - 105 | 5 | 00105 | Tue Jan 06 00:00:00 1970 | 5 | 5 | foo - 106 | 6 | 00106 | Wed Jan 07 00:00:00 1970 | 6 | 6 | foo - 107 | 7 | 00107 | Thu Jan 08 00:00:00 1970 | 7 | 7 | foo - 108 | 8 | 00108 | Fri Jan 09 00:00:00 1970 | 8 | 8 | foo - 109 | 9 | 00109 | Sat Jan 10 00:00:00 1970 | 9 | 9 | foo - 110 | 0 | 00110 | Sun Jan 11 00:00:00 1970 | 0 | 0 | foo -(10 rows) - --- whole-row reference ---Testcase 34: -EXPLAIN (VERBOSE, COSTS OFF) SELECT t1 FROM ft1 t1 ORDER BY t1.c3, t1.c1 OFFSET 100 LIMIT 10; - QUERY PLAN ------------------------------------------------------------------------------------- - Limit - Output: t1.*, c3, c1 - -> Sort - Output: t1.*, c3, c1 - Sort Key: t1.c3, t1.c1 - -> Foreign Scan on public.ft1 t1 - Output: t1.*, c3, c1 - InfluxDB query: SELECT "C 1", "c2", "c3", "c6", "c7", "c8" FROM "T1" -(8 rows) - ---Testcase 35: -SELECT t1 FROM ft1 t1 ORDER BY t1.c3, t1.c1 OFFSET 100 LIMIT 10; - t1 -------------------------------------------------------------- - (101,1,00101,"Fri Jan 02 00:00:00 1970",1,"1 ",foo) - (102,2,00102,"Sat Jan 03 00:00:00 1970",2,"2 ",foo) - (103,3,00103,"Sun Jan 04 00:00:00 1970",3,"3 ",foo) - (104,4,00104,"Mon Jan 05 00:00:00 1970",4,"4 ",foo) - (105,5,00105,"Tue Jan 06 00:00:00 1970",5,"5 ",foo) - (106,6,00106,"Wed Jan 07 00:00:00 1970",6,"6 ",foo) - (107,7,00107,"Thu Jan 08 00:00:00 1970",7,"7 ",foo) - (108,8,00108,"Fri Jan 09 00:00:00 1970",8,"8 ",foo) - (109,9,00109,"Sat Jan 10 00:00:00 1970",9,"9 ",foo) - (110,0,00110,"Sun Jan 11 00:00:00 1970",0,"0 ",foo) -(10 rows) - --- empty result ---Testcase 36: -SELECT * FROM ft1 WHERE false; - c1 | c2 | c3 | time | c6 | c7 | c8 -----+----+----+------+----+----+---- -(0 rows) - --- with WHERE clause ---Testcase 37: -EXPLAIN (VERBOSE, COSTS OFF) SELECT * FROM ft1 t1 WHERE t1.c1 = 101 AND t1.c6 = '1' AND t1.c7 >= '1'; - QUERY PLAN ------------------------------------------------------------------------------------------------------------------ - Foreign Scan on public.ft1 t1 - Output: c1, c2, c3, "time", c6, c7, c8 - Filter: (t1.c7 >= '1'::bpchar) - InfluxDB query: SELECT "C 1", "c2", "c3", "c6", "c7", "c8" FROM "T1" WHERE (("C 1" = 101)) AND (("c6" = '1')) -(4 rows) - ---Testcase 38: -SELECT * FROM ft1 t1 WHERE t1.c1 = 101 AND t1.c6 = '1' AND t1.c7 >= '1'; - c1 | c2 | c3 | time | c6 | c7 | c8 ------+----+-------+--------------------------+----+------------+----- - 101 | 1 | 00101 | Fri Jan 02 00:00:00 1970 | 1 | 1 | foo -(1 row) - --- with FOR UPDATE/SHARE ---Testcase 39: -EXPLAIN (VERBOSE, COSTS OFF) SELECT * FROM ft1 t1 WHERE c1 = 101 FOR UPDATE; - QUERY PLAN ----------------------------------------------------------------------------------------------------- - LockRows - Output: c1, c2, c3, "time", c6, c7, c8, t1.* - -> Foreign Scan on public.ft1 t1 - Output: c1, c2, c3, "time", c6, c7, c8, t1.* - InfluxDB query: SELECT "C 1", "c2", "c3", "c6", "c7", "c8" FROM "T1" WHERE (("C 1" = 101)) -(5 rows) - ---Testcase 40: -SELECT * FROM ft1 t1 WHERE c1 = 101 FOR UPDATE; - c1 | c2 | c3 | time | c6 | c7 | c8 ------+----+-------+--------------------------+----+------------+----- - 101 | 1 | 00101 | Fri Jan 02 00:00:00 1970 | 1 | 1 | foo -(1 row) - ---Testcase 41: -EXPLAIN (VERBOSE, COSTS OFF) SELECT * FROM ft1 t1 WHERE c1 = 102 FOR SHARE; - QUERY PLAN ----------------------------------------------------------------------------------------------------- - LockRows - Output: c1, c2, c3, "time", c6, c7, c8, t1.* - -> Foreign Scan on public.ft1 t1 - Output: c1, c2, c3, "time", c6, c7, c8, t1.* - InfluxDB query: SELECT "C 1", "c2", "c3", "c6", "c7", "c8" FROM "T1" WHERE (("C 1" = 102)) -(5 rows) - ---Testcase 42: -SELECT * FROM ft1 t1 WHERE c1 = 102 FOR SHARE; - c1 | c2 | c3 | time | c6 | c7 | c8 ------+----+-------+--------------------------+----+------------+----- - 102 | 2 | 00102 | Sat Jan 03 00:00:00 1970 | 2 | 2 | foo -(1 row) - --- aggregate ---Testcase 43: -SELECT COUNT(*) FROM ft1 t1; - count -------- - 1000 -(1 row) - --- subquery ---Testcase 44: -SELECT * FROM ft1 t1 WHERE t1.c3 IN (SELECT c3 FROM ft2 t2 WHERE c1 <= 10) ORDER BY c1; - c1 | c2 | c3 | time | c6 | c7 | c8 -----+----+-------+--------------------------+----+------------+----- - 1 | 1 | 00001 | Fri Jan 02 00:00:00 1970 | 1 | 1 | foo - 2 | 2 | 00002 | Sat Jan 03 00:00:00 1970 | 2 | 2 | foo - 3 | 3 | 00003 | Sun Jan 04 00:00:00 1970 | 3 | 3 | foo - 4 | 4 | 00004 | Mon Jan 05 00:00:00 1970 | 4 | 4 | foo - 5 | 5 | 00005 | Tue Jan 06 00:00:00 1970 | 5 | 5 | foo - 6 | 6 | 00006 | Wed Jan 07 00:00:00 1970 | 6 | 6 | foo - 7 | 7 | 00007 | Thu Jan 08 00:00:00 1970 | 7 | 7 | foo - 8 | 8 | 00008 | Fri Jan 09 00:00:00 1970 | 8 | 8 | foo - 9 | 9 | 00009 | Sat Jan 10 00:00:00 1970 | 9 | 9 | foo - 10 | 0 | 00010 | Sun Jan 11 00:00:00 1970 | 0 | 0 | foo -(10 rows) - --- subquery+MAX ---Testcase 45: -SELECT * FROM ft1 t1 WHERE t1.c3 = (SELECT MAX(c3) FROM ft2 t2) ORDER BY c1; - c1 | c2 | c3 | time | c6 | c7 | c8 -------+----+-------+--------------------------+----+------------+----- - 1000 | 0 | 01000 | Thu Jan 01 00:00:00 1970 | 0 | 0 | foo -(1 row) - --- used in CTE ---Testcase 46: -WITH t1 AS (SELECT * FROM ft1 WHERE c1 <= 10) SELECT t2.c1, t2.c2, t2.c3, t2.time FROM t1, ft2 t2 WHERE t1.c1 = t2.c1 ORDER BY t1.c1; - c1 | c2 | c3 | time -----+----+-------+-------------------------- - 1 | 1 | 00001 | Fri Jan 02 00:00:00 1970 - 2 | 2 | 00002 | Sat Jan 03 00:00:00 1970 - 3 | 3 | 00003 | Sun Jan 04 00:00:00 1970 - 4 | 4 | 00004 | Mon Jan 05 00:00:00 1970 - 5 | 5 | 00005 | Tue Jan 06 00:00:00 1970 - 6 | 6 | 00006 | Wed Jan 07 00:00:00 1970 - 7 | 7 | 00007 | Thu Jan 08 00:00:00 1970 - 8 | 8 | 00008 | Fri Jan 09 00:00:00 1970 - 9 | 9 | 00009 | Sat Jan 10 00:00:00 1970 - 10 | 0 | 00010 | Sun Jan 11 00:00:00 1970 -(10 rows) - --- fixed values ---Testcase 47: -SELECT 'fixed', NULL FROM ft1 t1 WHERE c1 = 1; - ?column? | ?column? -----------+---------- - fixed | -(1 row) - --- Test forcing the remote server to produce sorted data for a merge join. -SET enable_hashjoin TO false; -SET enable_nestloop TO false; --- inner join; expressions in the clauses appear in the equivalence class list ---Testcase 48: -EXPLAIN (VERBOSE, COSTS OFF) - SELECT t1.c1, t2."C 1" FROM ft2 t1 JOIN "S 1"."T 1" t2 ON (t1.c1 = t2."C 1") OFFSET 100 LIMIT 10; - QUERY PLAN ------------------------------------------------------------- - Limit - Output: t1.c1, t2."C 1" - -> Merge Join - Output: t1.c1, t2."C 1" - Merge Cond: (t1.c1 = t2."C 1") - -> Sort - Output: t1.c1 - Sort Key: t1.c1 - -> Foreign Scan on public.ft2 t1 - Output: t1.c1 - InfluxDB query: SELECT "C 1" FROM "T1" - -> Sort - Output: t2."C 1" - Sort Key: t2."C 1" - -> Foreign Scan on "S 1"."T 1" t2 - Output: t2."C 1" - InfluxDB query: SELECT "C 1" FROM "T1" -(17 rows) - ---Testcase 49: -SELECT t1.c1, t2."C 1" FROM ft2 t1 JOIN "S 1"."T 1" t2 ON (t1.c1 = t2."C 1") OFFSET 100 LIMIT 10; - c1 | C 1 ------+----- - 101 | 101 - 102 | 102 - 103 | 103 - 104 | 104 - 105 | 105 - 106 | 106 - 107 | 107 - 108 | 108 - 109 | 109 - 110 | 110 -(10 rows) - --- outer join; expressions in the clauses do not appear in equivalence class --- list but no output change as compared to the previous query ---Testcase 50: -EXPLAIN (VERBOSE, COSTS OFF) - SELECT t1.c1, t2."C 1" FROM ft2 t1 LEFT JOIN "S 1"."T 1" t2 ON (t1.c1 = t2."C 1") OFFSET 100 LIMIT 10; - QUERY PLAN ------------------------------------------------------------- - Limit - Output: t1.c1, t2."C 1" - -> Merge Left Join - Output: t1.c1, t2."C 1" - Merge Cond: (t1.c1 = t2."C 1") - -> Sort - Output: t1.c1 - Sort Key: t1.c1 - -> Foreign Scan on public.ft2 t1 - Output: t1.c1 - InfluxDB query: SELECT "C 1" FROM "T1" - -> Sort - Output: t2."C 1" - Sort Key: t2."C 1" - -> Foreign Scan on "S 1"."T 1" t2 - Output: t2."C 1" - InfluxDB query: SELECT "C 1" FROM "T1" -(17 rows) - ---Testcase 51: -SELECT t1.c1, t2."C 1" FROM ft2 t1 LEFT JOIN "S 1"."T 1" t2 ON (t1.c1 = t2."C 1") OFFSET 100 LIMIT 10; - c1 | C 1 ------+----- - 101 | 101 - 102 | 102 - 103 | 103 - 104 | 104 - 105 | 105 - 106 | 106 - 107 | 107 - 108 | 108 - 109 | 109 - 110 | 110 -(10 rows) - --- A join between 2 foreign tables. ORDER BY clause is added to the --- foreign join so that the other table can be joined using merge join strategy. ---Testcase 52: -EXPLAIN (VERBOSE, COSTS OFF) - SELECT t1."C 1" FROM "S 1"."T 1" t1 left join ft1 t2 join ft2 t3 on (t2.c1 = t3.c1) on (t3.c1 = t1."C 1") OFFSET 100 LIMIT 10; - QUERY PLAN ------------------------------------------------------------------------- - Limit - Output: t1."C 1" - -> Merge Left Join - Output: t1."C 1" - Merge Cond: (t1."C 1" = t3.c1) - -> Sort - Output: t1."C 1" - Sort Key: t1."C 1" - -> Foreign Scan on "S 1"."T 1" t1 - Output: t1."C 1" - InfluxDB query: SELECT "C 1" FROM "T1" - -> Materialize - Output: t3.c1 - -> Merge Join - Output: t3.c1 - Merge Cond: (t2.c1 = t3.c1) - -> Sort - Output: t2.c1 - Sort Key: t2.c1 - -> Foreign Scan on public.ft1 t2 - Output: t2.c1 - InfluxDB query: SELECT "C 1" FROM "T1" - -> Sort - Output: t3.c1 - Sort Key: t3.c1 - -> Foreign Scan on public.ft2 t3 - Output: t3.c1 - InfluxDB query: SELECT "C 1" FROM "T1" -(28 rows) - ---Testcase 53: -SELECT t1."C 1" FROM "S 1"."T 1" t1 left join ft1 t2 join ft2 t3 on (t2.c1 = t3.c1) on (t3.c1 = t1."C 1") OFFSET 100 LIMIT 10; - C 1 ------ - 101 - 102 - 103 - 104 - 105 - 106 - 107 - 108 - 109 - 110 -(10 rows) - --- Test similar to above, except that the full join prevents any equivalence --- classes from being merged. This produces single relation equivalence classes --- included in join restrictions. ---Testcase 54: -EXPLAIN (VERBOSE, COSTS OFF) - SELECT t1."C 1", t2.c1, t3.c1 FROM "S 1"."T 1" t1 left join ft1 t2 full join ft2 t3 on (t2.c1 = t3.c1) on (t3.c1 = t1."C 1") OFFSET 100 LIMIT 10; - QUERY PLAN ------------------------------------------------------------------------- - Limit - Output: t1."C 1", t2.c1, t3.c1 - -> Merge Left Join - Output: t1."C 1", t2.c1, t3.c1 - Merge Cond: (t1."C 1" = t3.c1) - -> Sort - Output: t1."C 1" - Sort Key: t1."C 1" - -> Foreign Scan on "S 1"."T 1" t1 - Output: t1."C 1" - InfluxDB query: SELECT "C 1" FROM "T1" - -> Materialize - Output: t3.c1, t2.c1 - -> Merge Left Join - Output: t3.c1, t2.c1 - Merge Cond: (t3.c1 = t2.c1) - -> Sort - Output: t3.c1 - Sort Key: t3.c1 - -> Foreign Scan on public.ft2 t3 - Output: t3.c1 - InfluxDB query: SELECT "C 1" FROM "T1" - -> Sort - Output: t2.c1 - Sort Key: t2.c1 - -> Foreign Scan on public.ft1 t2 - Output: t2.c1 - InfluxDB query: SELECT "C 1" FROM "T1" -(28 rows) - ---Testcase 55: -SELECT t1."C 1", t2.c1, t3.c1 FROM "S 1"."T 1" t1 left join ft1 t2 full join ft2 t3 on (t2.c1 = t3.c1) on (t3.c1 = t1."C 1") OFFSET 100 LIMIT 10; - C 1 | c1 | c1 ------+-----+----- - 101 | 101 | 101 - 102 | 102 | 102 - 103 | 103 | 103 - 104 | 104 | 104 - 105 | 105 | 105 - 106 | 106 | 106 - 107 | 107 | 107 - 108 | 108 | 108 - 109 | 109 | 109 - 110 | 110 | 110 -(10 rows) - --- Test similar to above with all full outer joins ---Testcase 56: -EXPLAIN (VERBOSE, COSTS OFF) - SELECT t1."C 1", t2.c1, t3.c1 FROM "S 1"."T 1" t1 full join ft1 t2 full join ft2 t3 on (t2.c1 = t3.c1) on (t3.c1 = t1."C 1") OFFSET 100 LIMIT 10; - QUERY PLAN ------------------------------------------------------------------------- - Limit - Output: t1."C 1", t2.c1, t3.c1 - -> Merge Full Join - Output: t1."C 1", t2.c1, t3.c1 - Merge Cond: (t1."C 1" = t3.c1) - -> Sort - Output: t1."C 1" - Sort Key: t1."C 1" - -> Foreign Scan on "S 1"."T 1" t1 - Output: t1."C 1" - InfluxDB query: SELECT "C 1" FROM "T1" - -> Sort - Output: t2.c1, t3.c1 - Sort Key: t3.c1 - -> Merge Full Join - Output: t2.c1, t3.c1 - Merge Cond: (t2.c1 = t3.c1) - -> Sort - Output: t2.c1 - Sort Key: t2.c1 - -> Foreign Scan on public.ft1 t2 - Output: t2.c1 - InfluxDB query: SELECT "C 1" FROM "T1" - -> Sort - Output: t3.c1 - Sort Key: t3.c1 - -> Foreign Scan on public.ft2 t3 - Output: t3.c1 - InfluxDB query: SELECT "C 1" FROM "T1" -(29 rows) - ---Testcase 57: -SELECT t1."C 1", t2.c1, t3.c1 FROM "S 1"."T 1" t1 full join ft1 t2 full join ft2 t3 on (t2.c1 = t3.c1) on (t3.c1 = t1."C 1") OFFSET 100 LIMIT 10; - C 1 | c1 | c1 ------+-----+----- - 101 | 101 | 101 - 102 | 102 | 102 - 103 | 103 | 103 - 104 | 104 | 104 - 105 | 105 | 105 - 106 | 106 | 106 - 107 | 107 | 107 - 108 | 108 | 108 - 109 | 109 | 109 - 110 | 110 | 110 -(10 rows) - -RESET enable_hashjoin; -RESET enable_nestloop; --- =================================================================== --- WHERE with remotely-executable conditions --- =================================================================== ---Testcase 58: -EXPLAIN (VERBOSE, COSTS OFF) SELECT * FROM ft1 t1 WHERE t1.c1 = 1; -- Var, OpExpr(b), Const - QUERY PLAN --------------------------------------------------------------------------------------------- - Foreign Scan on public.ft1 t1 - Output: c1, c2, c3, "time", c6, c7, c8 - InfluxDB query: SELECT "C 1", "c2", "c3", "c6", "c7", "c8" FROM "T1" WHERE (("C 1" = 1)) -(3 rows) - ---Testcase 59: -EXPLAIN (VERBOSE, COSTS OFF) SELECT * FROM ft1 t1 WHERE t1.c1 = 100 AND t1.c2 = 0; -- BoolExpr - QUERY PLAN ---------------------------------------------------------------------------------------------------------------- - Foreign Scan on public.ft1 t1 - Output: c1, c2, c3, "time", c6, c7, c8 - InfluxDB query: SELECT "C 1", "c2", "c3", "c6", "c7", "c8" FROM "T1" WHERE (("C 1" = 100)) AND (("c2" = 0)) -(3 rows) - ---Testcase 60: -EXPLAIN (VERBOSE, COSTS OFF) SELECT * FROM ft1 t1 WHERE c1 IS NULL; -- NullTest - QUERY PLAN ------------------------------------------------------------------------- - Foreign Scan on public.ft1 t1 - Output: c1, c2, c3, "time", c6, c7, c8 - Filter: (t1.c1 IS NULL) - InfluxDB query: SELECT "C 1", "c2", "c3", "c6", "c7", "c8" FROM "T1" -(4 rows) - ---Testcase 61: -EXPLAIN (VERBOSE, COSTS OFF) SELECT * FROM ft1 t1 WHERE c1 IS NOT NULL; -- NullTest - QUERY PLAN ------------------------------------------------------------------------- - Foreign Scan on public.ft1 t1 - Output: c1, c2, c3, "time", c6, c7, c8 - Filter: (t1.c1 IS NOT NULL) - InfluxDB query: SELECT "C 1", "c2", "c3", "c6", "c7", "c8" FROM "T1" -(4 rows) - ---Testcase 62: -EXPLAIN (VERBOSE, COSTS OFF) SELECT * FROM ft1 t1 WHERE round(abs(c1), 0) = 1; -- FuncExpr - QUERY PLAN ------------------------------------------------------------------------- - Foreign Scan on public.ft1 t1 - Output: c1, c2, c3, "time", c6, c7, c8 - Filter: (round((abs(t1.c1))::numeric, 0) = '1'::numeric) - InfluxDB query: SELECT "C 1", "c2", "c3", "c6", "c7", "c8" FROM "T1" -(4 rows) - ---Testcase 63: -EXPLAIN (VERBOSE, COSTS OFF) SELECT * FROM ft1 t1 WHERE c1 = -c1; -- OpExpr(l) - QUERY PLAN ----------------------------------------------------------------------------------------------------- - Foreign Scan on public.ft1 t1 - Output: c1, c2, c3, "time", c6, c7, c8 - InfluxDB query: SELECT "C 1", "c2", "c3", "c6", "c7", "c8" FROM "T1" WHERE (("C 1" = (- "C 1"))) -(3 rows) - ---Testcase 64: -EXPLAIN (VERBOSE, COSTS OFF) SELECT * FROM ft1 t1 WHERE 1 = c1!; -- OpExpr(r) - QUERY PLAN ------------------------------------------------------------------------- - Foreign Scan on public.ft1 t1 - Output: c1, c2, c3, "time", c6, c7, c8 - Filter: ('1'::numeric = ((t1.c1)::bigint !)) - InfluxDB query: SELECT "C 1", "c2", "c3", "c6", "c7", "c8" FROM "T1" -(4 rows) - ---Testcase 65: -EXPLAIN (VERBOSE, COSTS OFF) SELECT * FROM ft1 t1 WHERE (c1 IS NOT NULL) IS DISTINCT FROM (c1 IS NOT NULL); -- DistinctExpr - QUERY PLAN ------------------------------------------------------------------------- - Foreign Scan on public.ft1 t1 - Output: c1, c2, c3, "time", c6, c7, c8 - Filter: ((t1.c1 IS NOT NULL) IS DISTINCT FROM (t1.c1 IS NOT NULL)) - InfluxDB query: SELECT "C 1", "c2", "c3", "c6", "c7", "c8" FROM "T1" -(4 rows) - ---Testcase 66: -EXPLAIN (VERBOSE, COSTS OFF) SELECT * FROM ft1 t1 WHERE c1 = ANY(ARRAY[c2, 1, c1 + 0]); -- ScalarArrayOpExpr - QUERY PLAN ---------------------------------------------------------------------------------------------------------------------------------------- - Foreign Scan on public.ft1 t1 - Output: c1, c2, c3, "time", c6, c7, c8 - InfluxDB query: SELECT "C 1", "c2", "c3", "c6", "c7", "c8" FROM "T1" WHERE (("C 1" = "c2") OR ("C 1" = 1) OR ("C 1" = ("C 1" + 0))) -(3 rows) - ---Testcase 67: -EXPLAIN (VERBOSE, COSTS OFF) SELECT * FROM ft1 t1 WHERE c1 = (ARRAY[c1,c2,3])[1]; -- SubscriptingRef - QUERY PLAN ------------------------------------------------------------------------- - Foreign Scan on public.ft1 t1 - Output: c1, c2, c3, "time", c6, c7, c8 - Filter: (t1.c1 = (ARRAY[t1.c1, t1.c2, 3])[1]) - InfluxDB query: SELECT "C 1", "c2", "c3", "c6", "c7", "c8" FROM "T1" -(4 rows) - ---Testcase 68: -EXPLAIN (VERBOSE, COSTS OFF) SELECT * FROM ft1 t1 WHERE c6 = E'foo''s\\bar'; -- check special chars - QUERY PLAN -------------------------------------------------------------------------------------------------------- - Foreign Scan on public.ft1 t1 - Output: c1, c2, c3, "time", c6, c7, c8 - InfluxDB query: SELECT "C 1", "c2", "c3", "c6", "c7", "c8" FROM "T1" WHERE (("c6" = 'foo''s\\bar')) -(3 rows) - ---Testcase 69: -EXPLAIN (VERBOSE, COSTS OFF) SELECT * FROM ft1 t1 WHERE c8 = 'foo'; -- can't be sent to remote - QUERY PLAN ------------------------------------------------------------------------------------------------ - Foreign Scan on public.ft1 t1 - Output: c1, c2, c3, "time", c6, c7, c8 - InfluxDB query: SELECT "C 1", "c2", "c3", "c6", "c7", "c8" FROM "T1" WHERE (("c8" = 'foo')) -(3 rows) - --- parameterized remote path for foreign table ---Testcase 70: -EXPLAIN (VERBOSE, COSTS OFF) - SELECT * FROM "S 1"."T 1" a, ft2 b WHERE a."C 1" = 47 AND b.c1 = a.c2; - QUERY PLAN ---------------------------------------------------------------------------------------------------------- - Hash Join - Output: a."C 1", a.c2, a.c3, a."time", a.c6, a.c7, a.c8, b.c1, b.c2, b.c3, b."time", b.c6, b.c7, b.c8 - Hash Cond: (b.c1 = a.c2) - -> Foreign Scan on public.ft2 b - Output: b.c1, b.c2, b.c3, b."time", b.c6, b.c7, b.c8 - InfluxDB query: SELECT "C 1", "c2", "c3", "c6", "c7", "c8" FROM "T1" - -> Hash - Output: a."C 1", a.c2, a.c3, a."time", a.c6, a.c7, a.c8 - -> Foreign Scan on "S 1"."T 1" a - Output: a."C 1", a.c2, a.c3, a."time", a.c6, a.c7, a.c8 - InfluxDB query: SELECT "C 1", "c2", "c3", "c6", "c7", "c8" FROM "T1" WHERE (("C 1" = 47)) -(11 rows) - ---Testcase 71: -SELECT * FROM ft2 a, ft2 b WHERE a.c1 = 47 AND b.c1 = a.c2; - c1 | c2 | c3 | time | c6 | c7 | c8 | c1 | c2 | c3 | time | c6 | c7 | c8 -----+----+-------+--------------------------+----+------------+-----+----+----+-------+--------------------------+----+------------+----- - 47 | 7 | 00047 | Tue Feb 17 00:00:00 1970 | 7 | 7 | foo | 7 | 7 | 00007 | Thu Jan 08 00:00:00 1970 | 7 | 7 | foo -(1 row) - --- check both safe and unsafe join conditions ---Testcase 72: -EXPLAIN (VERBOSE, COSTS OFF) - SELECT * FROM ft2 a, ft2 b - WHERE a.c2 = 6 AND b.c1 = a.c1 AND a.c8 = 'foo' AND b.c7 = upper(a.c7); - QUERY PLAN ----------------------------------------------------------------------------------------------------------------------------- - Hash Join - Output: a.c1, a.c2, a.c3, a."time", a.c6, a.c7, a.c8, b.c1, b.c2, b.c3, b."time", b.c6, b.c7, b.c8 - Hash Cond: ((b.c1 = a.c1) AND ((b.c7)::text = upper((a.c7)::text))) - -> Foreign Scan on public.ft2 b - Output: b.c1, b.c2, b.c3, b."time", b.c6, b.c7, b.c8 - InfluxDB query: SELECT "C 1", "c2", "c3", "c6", "c7", "c8" FROM "T1" - -> Hash - Output: a.c1, a.c2, a.c3, a."time", a.c6, a.c7, a.c8 - -> Foreign Scan on public.ft2 a - Output: a.c1, a.c2, a.c3, a."time", a.c6, a.c7, a.c8 - InfluxDB query: SELECT "C 1", "c2", "c3", "c6", "c7", "c8" FROM "T1" WHERE (("c2" = 6)) AND (("c8" = 'foo')) -(11 rows) - ---Testcase 73: -SELECT * FROM ft2 a, ft2 b -WHERE a.c2 = 6 AND b.c1 = a.c1 AND a.c8 = 'foo' AND b.c7 = upper(a.c7) ORDER BY a.c1; - c1 | c2 | c3 | time | c6 | c7 | c8 | c1 | c2 | c3 | time | c6 | c7 | c8 ------+----+-------+--------------------------+----+------------+-----+-----+----+-------+--------------------------+----+------------+----- - 6 | 6 | 00006 | Wed Jan 07 00:00:00 1970 | 6 | 6 | foo | 6 | 6 | 00006 | Wed Jan 07 00:00:00 1970 | 6 | 6 | foo - 16 | 6 | 00016 | Sat Jan 17 00:00:00 1970 | 6 | 6 | foo | 16 | 6 | 00016 | Sat Jan 17 00:00:00 1970 | 6 | 6 | foo - 26 | 6 | 00026 | Tue Jan 27 00:00:00 1970 | 6 | 6 | foo | 26 | 6 | 00026 | Tue Jan 27 00:00:00 1970 | 6 | 6 | foo - 36 | 6 | 00036 | Fri Feb 06 00:00:00 1970 | 6 | 6 | foo | 36 | 6 | 00036 | Fri Feb 06 00:00:00 1970 | 6 | 6 | foo - 46 | 6 | 00046 | Mon Feb 16 00:00:00 1970 | 6 | 6 | foo | 46 | 6 | 00046 | Mon Feb 16 00:00:00 1970 | 6 | 6 | foo - 56 | 6 | 00056 | Thu Feb 26 00:00:00 1970 | 6 | 6 | foo | 56 | 6 | 00056 | Thu Feb 26 00:00:00 1970 | 6 | 6 | foo - 66 | 6 | 00066 | Sun Mar 08 00:00:00 1970 | 6 | 6 | foo | 66 | 6 | 00066 | Sun Mar 08 00:00:00 1970 | 6 | 6 | foo - 76 | 6 | 00076 | Wed Mar 18 00:00:00 1970 | 6 | 6 | foo | 76 | 6 | 00076 | Wed Mar 18 00:00:00 1970 | 6 | 6 | foo - 86 | 6 | 00086 | Sat Mar 28 00:00:00 1970 | 6 | 6 | foo | 86 | 6 | 00086 | Sat Mar 28 00:00:00 1970 | 6 | 6 | foo - 96 | 6 | 00096 | Tue Apr 07 00:00:00 1970 | 6 | 6 | foo | 96 | 6 | 00096 | Tue Apr 07 00:00:00 1970 | 6 | 6 | foo - 106 | 6 | 00106 | Wed Jan 07 00:00:00 1970 | 6 | 6 | foo | 106 | 6 | 00106 | Wed Jan 07 00:00:00 1970 | 6 | 6 | foo - 116 | 6 | 00116 | Sat Jan 17 00:00:00 1970 | 6 | 6 | foo | 116 | 6 | 00116 | Sat Jan 17 00:00:00 1970 | 6 | 6 | foo - 126 | 6 | 00126 | Tue Jan 27 00:00:00 1970 | 6 | 6 | foo | 126 | 6 | 00126 | Tue Jan 27 00:00:00 1970 | 6 | 6 | foo - 136 | 6 | 00136 | Fri Feb 06 00:00:00 1970 | 6 | 6 | foo | 136 | 6 | 00136 | Fri Feb 06 00:00:00 1970 | 6 | 6 | foo - 146 | 6 | 00146 | Mon Feb 16 00:00:00 1970 | 6 | 6 | foo | 146 | 6 | 00146 | Mon Feb 16 00:00:00 1970 | 6 | 6 | foo - 156 | 6 | 00156 | Thu Feb 26 00:00:00 1970 | 6 | 6 | foo | 156 | 6 | 00156 | Thu Feb 26 00:00:00 1970 | 6 | 6 | foo - 166 | 6 | 00166 | Sun Mar 08 00:00:00 1970 | 6 | 6 | foo | 166 | 6 | 00166 | Sun Mar 08 00:00:00 1970 | 6 | 6 | foo - 176 | 6 | 00176 | Wed Mar 18 00:00:00 1970 | 6 | 6 | foo | 176 | 6 | 00176 | Wed Mar 18 00:00:00 1970 | 6 | 6 | foo - 186 | 6 | 00186 | Sat Mar 28 00:00:00 1970 | 6 | 6 | foo | 186 | 6 | 00186 | Sat Mar 28 00:00:00 1970 | 6 | 6 | foo - 196 | 6 | 00196 | Tue Apr 07 00:00:00 1970 | 6 | 6 | foo | 196 | 6 | 00196 | Tue Apr 07 00:00:00 1970 | 6 | 6 | foo - 206 | 6 | 00206 | Wed Jan 07 00:00:00 1970 | 6 | 6 | foo | 206 | 6 | 00206 | Wed Jan 07 00:00:00 1970 | 6 | 6 | foo - 216 | 6 | 00216 | Sat Jan 17 00:00:00 1970 | 6 | 6 | foo | 216 | 6 | 00216 | Sat Jan 17 00:00:00 1970 | 6 | 6 | foo - 226 | 6 | 00226 | Tue Jan 27 00:00:00 1970 | 6 | 6 | foo | 226 | 6 | 00226 | Tue Jan 27 00:00:00 1970 | 6 | 6 | foo - 236 | 6 | 00236 | Fri Feb 06 00:00:00 1970 | 6 | 6 | foo | 236 | 6 | 00236 | Fri Feb 06 00:00:00 1970 | 6 | 6 | foo - 246 | 6 | 00246 | Mon Feb 16 00:00:00 1970 | 6 | 6 | foo | 246 | 6 | 00246 | Mon Feb 16 00:00:00 1970 | 6 | 6 | foo - 256 | 6 | 00256 | Thu Feb 26 00:00:00 1970 | 6 | 6 | foo | 256 | 6 | 00256 | Thu Feb 26 00:00:00 1970 | 6 | 6 | foo - 266 | 6 | 00266 | Sun Mar 08 00:00:00 1970 | 6 | 6 | foo | 266 | 6 | 00266 | Sun Mar 08 00:00:00 1970 | 6 | 6 | foo - 276 | 6 | 00276 | Wed Mar 18 00:00:00 1970 | 6 | 6 | foo | 276 | 6 | 00276 | Wed Mar 18 00:00:00 1970 | 6 | 6 | foo - 286 | 6 | 00286 | Sat Mar 28 00:00:00 1970 | 6 | 6 | foo | 286 | 6 | 00286 | Sat Mar 28 00:00:00 1970 | 6 | 6 | foo - 296 | 6 | 00296 | Tue Apr 07 00:00:00 1970 | 6 | 6 | foo | 296 | 6 | 00296 | Tue Apr 07 00:00:00 1970 | 6 | 6 | foo - 306 | 6 | 00306 | Wed Jan 07 00:00:00 1970 | 6 | 6 | foo | 306 | 6 | 00306 | Wed Jan 07 00:00:00 1970 | 6 | 6 | foo - 316 | 6 | 00316 | Sat Jan 17 00:00:00 1970 | 6 | 6 | foo | 316 | 6 | 00316 | Sat Jan 17 00:00:00 1970 | 6 | 6 | foo - 326 | 6 | 00326 | Tue Jan 27 00:00:00 1970 | 6 | 6 | foo | 326 | 6 | 00326 | Tue Jan 27 00:00:00 1970 | 6 | 6 | foo - 336 | 6 | 00336 | Fri Feb 06 00:00:00 1970 | 6 | 6 | foo | 336 | 6 | 00336 | Fri Feb 06 00:00:00 1970 | 6 | 6 | foo - 346 | 6 | 00346 | Mon Feb 16 00:00:00 1970 | 6 | 6 | foo | 346 | 6 | 00346 | Mon Feb 16 00:00:00 1970 | 6 | 6 | foo - 356 | 6 | 00356 | Thu Feb 26 00:00:00 1970 | 6 | 6 | foo | 356 | 6 | 00356 | Thu Feb 26 00:00:00 1970 | 6 | 6 | foo - 366 | 6 | 00366 | Sun Mar 08 00:00:00 1970 | 6 | 6 | foo | 366 | 6 | 00366 | Sun Mar 08 00:00:00 1970 | 6 | 6 | foo - 376 | 6 | 00376 | Wed Mar 18 00:00:00 1970 | 6 | 6 | foo | 376 | 6 | 00376 | Wed Mar 18 00:00:00 1970 | 6 | 6 | foo - 386 | 6 | 00386 | Sat Mar 28 00:00:00 1970 | 6 | 6 | foo | 386 | 6 | 00386 | Sat Mar 28 00:00:00 1970 | 6 | 6 | foo - 396 | 6 | 00396 | Tue Apr 07 00:00:00 1970 | 6 | 6 | foo | 396 | 6 | 00396 | Tue Apr 07 00:00:00 1970 | 6 | 6 | foo - 406 | 6 | 00406 | Wed Jan 07 00:00:00 1970 | 6 | 6 | foo | 406 | 6 | 00406 | Wed Jan 07 00:00:00 1970 | 6 | 6 | foo - 416 | 6 | 00416 | Sat Jan 17 00:00:00 1970 | 6 | 6 | foo | 416 | 6 | 00416 | Sat Jan 17 00:00:00 1970 | 6 | 6 | foo - 426 | 6 | 00426 | Tue Jan 27 00:00:00 1970 | 6 | 6 | foo | 426 | 6 | 00426 | Tue Jan 27 00:00:00 1970 | 6 | 6 | foo - 436 | 6 | 00436 | Fri Feb 06 00:00:00 1970 | 6 | 6 | foo | 436 | 6 | 00436 | Fri Feb 06 00:00:00 1970 | 6 | 6 | foo - 446 | 6 | 00446 | Mon Feb 16 00:00:00 1970 | 6 | 6 | foo | 446 | 6 | 00446 | Mon Feb 16 00:00:00 1970 | 6 | 6 | foo - 456 | 6 | 00456 | Thu Feb 26 00:00:00 1970 | 6 | 6 | foo | 456 | 6 | 00456 | Thu Feb 26 00:00:00 1970 | 6 | 6 | foo - 466 | 6 | 00466 | Sun Mar 08 00:00:00 1970 | 6 | 6 | foo | 466 | 6 | 00466 | Sun Mar 08 00:00:00 1970 | 6 | 6 | foo - 476 | 6 | 00476 | Wed Mar 18 00:00:00 1970 | 6 | 6 | foo | 476 | 6 | 00476 | Wed Mar 18 00:00:00 1970 | 6 | 6 | foo - 486 | 6 | 00486 | Sat Mar 28 00:00:00 1970 | 6 | 6 | foo | 486 | 6 | 00486 | Sat Mar 28 00:00:00 1970 | 6 | 6 | foo - 496 | 6 | 00496 | Tue Apr 07 00:00:00 1970 | 6 | 6 | foo | 496 | 6 | 00496 | Tue Apr 07 00:00:00 1970 | 6 | 6 | foo - 506 | 6 | 00506 | Wed Jan 07 00:00:00 1970 | 6 | 6 | foo | 506 | 6 | 00506 | Wed Jan 07 00:00:00 1970 | 6 | 6 | foo - 516 | 6 | 00516 | Sat Jan 17 00:00:00 1970 | 6 | 6 | foo | 516 | 6 | 00516 | Sat Jan 17 00:00:00 1970 | 6 | 6 | foo - 526 | 6 | 00526 | Tue Jan 27 00:00:00 1970 | 6 | 6 | foo | 526 | 6 | 00526 | Tue Jan 27 00:00:00 1970 | 6 | 6 | foo - 536 | 6 | 00536 | Fri Feb 06 00:00:00 1970 | 6 | 6 | foo | 536 | 6 | 00536 | Fri Feb 06 00:00:00 1970 | 6 | 6 | foo - 546 | 6 | 00546 | Mon Feb 16 00:00:00 1970 | 6 | 6 | foo | 546 | 6 | 00546 | Mon Feb 16 00:00:00 1970 | 6 | 6 | foo - 556 | 6 | 00556 | Thu Feb 26 00:00:00 1970 | 6 | 6 | foo | 556 | 6 | 00556 | Thu Feb 26 00:00:00 1970 | 6 | 6 | foo - 566 | 6 | 00566 | Sun Mar 08 00:00:00 1970 | 6 | 6 | foo | 566 | 6 | 00566 | Sun Mar 08 00:00:00 1970 | 6 | 6 | foo - 576 | 6 | 00576 | Wed Mar 18 00:00:00 1970 | 6 | 6 | foo | 576 | 6 | 00576 | Wed Mar 18 00:00:00 1970 | 6 | 6 | foo - 586 | 6 | 00586 | Sat Mar 28 00:00:00 1970 | 6 | 6 | foo | 586 | 6 | 00586 | Sat Mar 28 00:00:00 1970 | 6 | 6 | foo - 596 | 6 | 00596 | Tue Apr 07 00:00:00 1970 | 6 | 6 | foo | 596 | 6 | 00596 | Tue Apr 07 00:00:00 1970 | 6 | 6 | foo - 606 | 6 | 00606 | Wed Jan 07 00:00:00 1970 | 6 | 6 | foo | 606 | 6 | 00606 | Wed Jan 07 00:00:00 1970 | 6 | 6 | foo - 616 | 6 | 00616 | Sat Jan 17 00:00:00 1970 | 6 | 6 | foo | 616 | 6 | 00616 | Sat Jan 17 00:00:00 1970 | 6 | 6 | foo - 626 | 6 | 00626 | Tue Jan 27 00:00:00 1970 | 6 | 6 | foo | 626 | 6 | 00626 | Tue Jan 27 00:00:00 1970 | 6 | 6 | foo - 636 | 6 | 00636 | Fri Feb 06 00:00:00 1970 | 6 | 6 | foo | 636 | 6 | 00636 | Fri Feb 06 00:00:00 1970 | 6 | 6 | foo - 646 | 6 | 00646 | Mon Feb 16 00:00:00 1970 | 6 | 6 | foo | 646 | 6 | 00646 | Mon Feb 16 00:00:00 1970 | 6 | 6 | foo - 656 | 6 | 00656 | Thu Feb 26 00:00:00 1970 | 6 | 6 | foo | 656 | 6 | 00656 | Thu Feb 26 00:00:00 1970 | 6 | 6 | foo - 666 | 6 | 00666 | Sun Mar 08 00:00:00 1970 | 6 | 6 | foo | 666 | 6 | 00666 | Sun Mar 08 00:00:00 1970 | 6 | 6 | foo - 676 | 6 | 00676 | Wed Mar 18 00:00:00 1970 | 6 | 6 | foo | 676 | 6 | 00676 | Wed Mar 18 00:00:00 1970 | 6 | 6 | foo - 686 | 6 | 00686 | Sat Mar 28 00:00:00 1970 | 6 | 6 | foo | 686 | 6 | 00686 | Sat Mar 28 00:00:00 1970 | 6 | 6 | foo - 696 | 6 | 00696 | Tue Apr 07 00:00:00 1970 | 6 | 6 | foo | 696 | 6 | 00696 | Tue Apr 07 00:00:00 1970 | 6 | 6 | foo - 706 | 6 | 00706 | Wed Jan 07 00:00:00 1970 | 6 | 6 | foo | 706 | 6 | 00706 | Wed Jan 07 00:00:00 1970 | 6 | 6 | foo - 716 | 6 | 00716 | Sat Jan 17 00:00:00 1970 | 6 | 6 | foo | 716 | 6 | 00716 | Sat Jan 17 00:00:00 1970 | 6 | 6 | foo - 726 | 6 | 00726 | Tue Jan 27 00:00:00 1970 | 6 | 6 | foo | 726 | 6 | 00726 | Tue Jan 27 00:00:00 1970 | 6 | 6 | foo - 736 | 6 | 00736 | Fri Feb 06 00:00:00 1970 | 6 | 6 | foo | 736 | 6 | 00736 | Fri Feb 06 00:00:00 1970 | 6 | 6 | foo - 746 | 6 | 00746 | Mon Feb 16 00:00:00 1970 | 6 | 6 | foo | 746 | 6 | 00746 | Mon Feb 16 00:00:00 1970 | 6 | 6 | foo - 756 | 6 | 00756 | Thu Feb 26 00:00:00 1970 | 6 | 6 | foo | 756 | 6 | 00756 | Thu Feb 26 00:00:00 1970 | 6 | 6 | foo - 766 | 6 | 00766 | Sun Mar 08 00:00:00 1970 | 6 | 6 | foo | 766 | 6 | 00766 | Sun Mar 08 00:00:00 1970 | 6 | 6 | foo - 776 | 6 | 00776 | Wed Mar 18 00:00:00 1970 | 6 | 6 | foo | 776 | 6 | 00776 | Wed Mar 18 00:00:00 1970 | 6 | 6 | foo - 786 | 6 | 00786 | Sat Mar 28 00:00:00 1970 | 6 | 6 | foo | 786 | 6 | 00786 | Sat Mar 28 00:00:00 1970 | 6 | 6 | foo - 796 | 6 | 00796 | Tue Apr 07 00:00:00 1970 | 6 | 6 | foo | 796 | 6 | 00796 | Tue Apr 07 00:00:00 1970 | 6 | 6 | foo - 806 | 6 | 00806 | Wed Jan 07 00:00:00 1970 | 6 | 6 | foo | 806 | 6 | 00806 | Wed Jan 07 00:00:00 1970 | 6 | 6 | foo - 816 | 6 | 00816 | Sat Jan 17 00:00:00 1970 | 6 | 6 | foo | 816 | 6 | 00816 | Sat Jan 17 00:00:00 1970 | 6 | 6 | foo - 826 | 6 | 00826 | Tue Jan 27 00:00:00 1970 | 6 | 6 | foo | 826 | 6 | 00826 | Tue Jan 27 00:00:00 1970 | 6 | 6 | foo - 836 | 6 | 00836 | Fri Feb 06 00:00:00 1970 | 6 | 6 | foo | 836 | 6 | 00836 | Fri Feb 06 00:00:00 1970 | 6 | 6 | foo - 846 | 6 | 00846 | Mon Feb 16 00:00:00 1970 | 6 | 6 | foo | 846 | 6 | 00846 | Mon Feb 16 00:00:00 1970 | 6 | 6 | foo - 856 | 6 | 00856 | Thu Feb 26 00:00:00 1970 | 6 | 6 | foo | 856 | 6 | 00856 | Thu Feb 26 00:00:00 1970 | 6 | 6 | foo - 866 | 6 | 00866 | Sun Mar 08 00:00:00 1970 | 6 | 6 | foo | 866 | 6 | 00866 | Sun Mar 08 00:00:00 1970 | 6 | 6 | foo - 876 | 6 | 00876 | Wed Mar 18 00:00:00 1970 | 6 | 6 | foo | 876 | 6 | 00876 | Wed Mar 18 00:00:00 1970 | 6 | 6 | foo - 886 | 6 | 00886 | Sat Mar 28 00:00:00 1970 | 6 | 6 | foo | 886 | 6 | 00886 | Sat Mar 28 00:00:00 1970 | 6 | 6 | foo - 896 | 6 | 00896 | Tue Apr 07 00:00:00 1970 | 6 | 6 | foo | 896 | 6 | 00896 | Tue Apr 07 00:00:00 1970 | 6 | 6 | foo - 906 | 6 | 00906 | Wed Jan 07 00:00:00 1970 | 6 | 6 | foo | 906 | 6 | 00906 | Wed Jan 07 00:00:00 1970 | 6 | 6 | foo - 916 | 6 | 00916 | Sat Jan 17 00:00:00 1970 | 6 | 6 | foo | 916 | 6 | 00916 | Sat Jan 17 00:00:00 1970 | 6 | 6 | foo - 926 | 6 | 00926 | Tue Jan 27 00:00:00 1970 | 6 | 6 | foo | 926 | 6 | 00926 | Tue Jan 27 00:00:00 1970 | 6 | 6 | foo - 936 | 6 | 00936 | Fri Feb 06 00:00:00 1970 | 6 | 6 | foo | 936 | 6 | 00936 | Fri Feb 06 00:00:00 1970 | 6 | 6 | foo - 946 | 6 | 00946 | Mon Feb 16 00:00:00 1970 | 6 | 6 | foo | 946 | 6 | 00946 | Mon Feb 16 00:00:00 1970 | 6 | 6 | foo - 956 | 6 | 00956 | Thu Feb 26 00:00:00 1970 | 6 | 6 | foo | 956 | 6 | 00956 | Thu Feb 26 00:00:00 1970 | 6 | 6 | foo - 966 | 6 | 00966 | Sun Mar 08 00:00:00 1970 | 6 | 6 | foo | 966 | 6 | 00966 | Sun Mar 08 00:00:00 1970 | 6 | 6 | foo - 976 | 6 | 00976 | Wed Mar 18 00:00:00 1970 | 6 | 6 | foo | 976 | 6 | 00976 | Wed Mar 18 00:00:00 1970 | 6 | 6 | foo - 986 | 6 | 00986 | Sat Mar 28 00:00:00 1970 | 6 | 6 | foo | 986 | 6 | 00986 | Sat Mar 28 00:00:00 1970 | 6 | 6 | foo - 996 | 6 | 00996 | Tue Apr 07 00:00:00 1970 | 6 | 6 | foo | 996 | 6 | 00996 | Tue Apr 07 00:00:00 1970 | 6 | 6 | foo -(100 rows) - --- bug before 9.3.5 due to sloppy handling of remote-estimate parameters ---Testcase 74: -SELECT * FROM ft1 WHERE c1 = ANY (ARRAY(SELECT c1 FROM ft2 WHERE c1 < 5)); - c1 | c2 | c3 | time | c6 | c7 | c8 -----+----+-------+--------------------------+----+------------+----- - 1 | 1 | 00001 | Fri Jan 02 00:00:00 1970 | 1 | 1 | foo - 2 | 2 | 00002 | Sat Jan 03 00:00:00 1970 | 2 | 2 | foo - 3 | 3 | 00003 | Sun Jan 04 00:00:00 1970 | 3 | 3 | foo - 4 | 4 | 00004 | Mon Jan 05 00:00:00 1970 | 4 | 4 | foo -(4 rows) - ---Testcase 75: -SELECT * FROM ft2 WHERE c1 = ANY (ARRAY(SELECT c1 FROM ft1 WHERE c1 < 5)); - c1 | c2 | c3 | time | c6 | c7 | c8 -----+----+-------+--------------------------+----+------------+----- - 1 | 1 | 00001 | Fri Jan 02 00:00:00 1970 | 1 | 1 | foo - 2 | 2 | 00002 | Sat Jan 03 00:00:00 1970 | 2 | 2 | foo - 3 | 3 | 00003 | Sun Jan 04 00:00:00 1970 | 3 | 3 | foo - 4 | 4 | 00004 | Mon Jan 05 00:00:00 1970 | 4 | 4 | foo -(4 rows) - --- we should not push order by clause with volatile expressions or unsafe --- collations ---Testcase 76: -EXPLAIN (VERBOSE, COSTS OFF) - SELECT * FROM ft2 ORDER BY ft2.c1, random(); - QUERY PLAN ------------------------------------------------------------------------------- - Sort - Output: c1, c2, c3, "time", c6, c7, c8, (random()) - Sort Key: ft2.c1, (random()) - -> Foreign Scan on public.ft2 - Output: c1, c2, c3, "time", c6, c7, c8, random() - InfluxDB query: SELECT "C 1", "c2", "c3", "c6", "c7", "c8" FROM "T1" -(6 rows) - ---Testcase 77: -EXPLAIN (VERBOSE, COSTS OFF) - SELECT * FROM ft2 ORDER BY ft2.c1, ft2.c3 collate "C"; - QUERY PLAN ------------------------------------------------------------------------------- - Sort - Output: c1, c2, c3, "time", c6, c7, c8, ((c3)::text) - Sort Key: ft2.c1, ft2.c3 COLLATE "C" - -> Foreign Scan on public.ft2 - Output: c1, c2, c3, "time", c6, c7, c8, c3 - InfluxDB query: SELECT "C 1", "c2", "c3", "c6", "c7", "c8" FROM "T1" -(6 rows) - --- user-defined operator/function ---Testcase 78: -CREATE FUNCTION influxdb_fdw_abs(int) RETURNS int AS $$ -BEGIN -RETURN abs($1); -END -$$ LANGUAGE plpgsql IMMUTABLE; ---Testcase 79: -CREATE OPERATOR === ( - LEFTARG = int, - RIGHTARG = int, - PROCEDURE = int4eq, - COMMUTATOR = === -); --- built-in operators and functions can be shipped for remote execution ---Testcase 80: -EXPLAIN (VERBOSE, COSTS OFF) - SELECT count(c3) FROM ft1 t1 WHERE t1.c1 = abs(t1.c2); - QUERY PLAN ----------------------------------------------------------------------------------- - Aggregate - Output: count(c3) - -> Foreign Scan on public.ft1 t1 - Output: c3 - InfluxDB query: SELECT "c3", "C 1" FROM "T1" WHERE (("C 1" = abs("c2"))) -(5 rows) - ---Testcase 81: -SELECT count(c3) FROM ft1 t1 WHERE t1.c1 = abs(t1.c2); - count -------- - 9 -(1 row) - ---Testcase 82: -EXPLAIN (VERBOSE, COSTS OFF) - SELECT count(c3) FROM ft1 t1 WHERE t1.c1 = t1.c2; - QUERY PLAN ------------------------------------------------------------------------------ - Aggregate - Output: count(c3) - -> Foreign Scan on public.ft1 t1 - Output: c3 - InfluxDB query: SELECT "c3", "C 1" FROM "T1" WHERE (("C 1" = "c2")) -(5 rows) - ---Testcase 83: -SELECT count(c3) FROM ft1 t1 WHERE t1.c1 = t1.c2; - count -------- - 9 -(1 row) - --- by default, user-defined ones cannot ---Testcase 84: -EXPLAIN (VERBOSE, COSTS OFF) - SELECT count(c3) FROM ft1 t1 WHERE t1.c1 = influxdb_fdw_abs(t1.c2); - QUERY PLAN ------------------------------------------------------------- - Aggregate - Output: count(c3) - -> Foreign Scan on public.ft1 t1 - Output: c3 - Filter: (t1.c1 = influxdb_fdw_abs(t1.c2)) - InfluxDB query: SELECT "C 1", "c2", "c3" FROM "T1" -(6 rows) - ---Testcase 85: -SELECT count(c3) FROM ft1 t1 WHERE t1.c1 = influxdb_fdw_abs(t1.c2); - count -------- - 9 -(1 row) - ---Testcase 86: -EXPLAIN (VERBOSE, COSTS OFF) - SELECT count(c3) FROM ft1 t1 WHERE t1.c1 === t1.c2; - QUERY PLAN ------------------------------------------------------------- - Aggregate - Output: count(c3) - -> Foreign Scan on public.ft1 t1 - Output: c3 - Filter: (t1.c1 === t1.c2) - InfluxDB query: SELECT "C 1", "c2", "c3" FROM "T1" -(6 rows) - ---Testcase 87: -SELECT count(c3) FROM ft1 t1 WHERE t1.c1 === t1.c2; - count -------- - 9 -(1 row) - --- ORDER BY can be shipped, though ---Testcase 88: -EXPLAIN (VERBOSE, COSTS OFF) - SELECT * FROM ft1 t1 WHERE t1.c1 === t1.c2 order by t1.c2 limit 1; - QUERY PLAN ------------------------------------------------------------------------------------- - Limit - Output: c1, c2, c3, "time", c6, c7, c8 - -> Sort - Output: c1, c2, c3, "time", c6, c7, c8 - Sort Key: t1.c2 - -> Foreign Scan on public.ft1 t1 - Output: c1, c2, c3, "time", c6, c7, c8 - Filter: (t1.c1 === t1.c2) - InfluxDB query: SELECT "C 1", "c2", "c3", "c6", "c7", "c8" FROM "T1" -(9 rows) - ---Testcase 89: -SELECT * FROM ft1 t1 WHERE t1.c1 === t1.c2 order by t1.c2 limit 1; - c1 | c2 | c3 | time | c6 | c7 | c8 -----+----+-------+--------------------------+----+------------+----- - 1 | 1 | 00001 | Fri Jan 02 00:00:00 1970 | 1 | 1 | foo -(1 row) - --- but let's put them in an extension ... -ALTER EXTENSION influxdb_fdw ADD FUNCTION influxdb_fdw_abs(int); -ALTER EXTENSION influxdb_fdw ADD OPERATOR === (int, int); --- ALTER SERVER loopback OPTIONS (ADD extensions 'influxdb_fdw'); --- ... now they can be shipped ---Testcase 90: -EXPLAIN (VERBOSE, COSTS OFF) - SELECT count(c3) FROM ft1 t1 WHERE t1.c1 = influxdb_fdw_abs(t1.c2); - QUERY PLAN ------------------------------------------------------------- - Aggregate - Output: count(c3) - -> Foreign Scan on public.ft1 t1 - Output: c3 - Filter: (t1.c1 = influxdb_fdw_abs(t1.c2)) - InfluxDB query: SELECT "C 1", "c2", "c3" FROM "T1" -(6 rows) - ---Testcase 91: -SELECT count(c3) FROM ft1 t1 WHERE t1.c1 = influxdb_fdw_abs(t1.c2); - count -------- - 9 -(1 row) - ---Testcase 92: -EXPLAIN (VERBOSE, COSTS OFF) - SELECT count(c3) FROM ft1 t1 WHERE t1.c1 === t1.c2; - QUERY PLAN ------------------------------------------------------------- - Aggregate - Output: count(c3) - -> Foreign Scan on public.ft1 t1 - Output: c3 - Filter: (t1.c1 === t1.c2) - InfluxDB query: SELECT "C 1", "c2", "c3" FROM "T1" -(6 rows) - ---Testcase 93: -SELECT count(c3) FROM ft1 t1 WHERE t1.c1 === t1.c2; - count -------- - 9 -(1 row) - --- and both ORDER BY and LIMIT can be shipped ---Testcase 94: -EXPLAIN (VERBOSE, COSTS OFF) - SELECT * FROM ft1 t1 WHERE t1.c1 === t1.c2 order by t1.c2 limit 1; - QUERY PLAN ------------------------------------------------------------------------------------- - Limit - Output: c1, c2, c3, "time", c6, c7, c8 - -> Sort - Output: c1, c2, c3, "time", c6, c7, c8 - Sort Key: t1.c2 - -> Foreign Scan on public.ft1 t1 - Output: c1, c2, c3, "time", c6, c7, c8 - Filter: (t1.c1 === t1.c2) - InfluxDB query: SELECT "C 1", "c2", "c3", "c6", "c7", "c8" FROM "T1" -(9 rows) - ---Testcase 95: -SELECT * FROM ft1 t1 WHERE t1.c1 === t1.c2 order by t1.c2 limit 1; - c1 | c2 | c3 | time | c6 | c7 | c8 -----+----+-------+--------------------------+----+------------+----- - 1 | 1 | 00001 | Fri Jan 02 00:00:00 1970 | 1 | 1 | foo -(1 row) - --- =================================================================== --- JOIN queries --- =================================================================== --- join two tables ---Testcase 96: -EXPLAIN (VERBOSE, COSTS OFF) -SELECT t1.c1, t2.c1 FROM ft1 t1 JOIN ft2 t2 ON (t1.c1 = t2.c1) ORDER BY t1.c3, t1.c1 OFFSET 100 LIMIT 10; - QUERY PLAN ------------------------------------------------------------------------- - Limit - Output: t1.c1, t2.c1, t1.c3 - -> Sort - Output: t1.c1, t2.c1, t1.c3 - Sort Key: t1.c3, t1.c1 - -> Merge Join - Output: t1.c1, t2.c1, t1.c3 - Merge Cond: (t1.c1 = t2.c1) - -> Sort - Output: t1.c1, t1.c3 - Sort Key: t1.c1 - -> Foreign Scan on public.ft1 t1 - Output: t1.c1, t1.c3 - InfluxDB query: SELECT "C 1", "c3" FROM "T1" - -> Sort - Output: t2.c1 - Sort Key: t2.c1 - -> Foreign Scan on public.ft2 t2 - Output: t2.c1 - InfluxDB query: SELECT "C 1" FROM "T1" -(20 rows) - ---Testcase 97: -SELECT t1.c1, t2.c1 FROM ft1 t1 JOIN ft2 t2 ON (t1.c1 = t2.c1) ORDER BY t1.c3, t1.c1 OFFSET 100 LIMIT 10; - c1 | c1 ------+----- - 101 | 101 - 102 | 102 - 103 | 103 - 104 | 104 - 105 | 105 - 106 | 106 - 107 | 107 - 108 | 108 - 109 | 109 - 110 | 110 -(10 rows) - --- join three tables ---Testcase 98: -EXPLAIN (VERBOSE, COSTS OFF) -SELECT t1.c1, t2.c2, t3.c3 FROM ft1 t1 JOIN ft2 t2 ON (t1.c1 = t2.c1) JOIN ft4 t3 ON (t3.c1 = t1.c1) ORDER BY t1.c3, t1.c1 OFFSET 10 LIMIT 10; - QUERY PLAN ------------------------------------------------------------------------------------- - Limit - Output: t1.c1, t2.c2, t3.c3, t1.c3 - -> Sort - Output: t1.c1, t2.c2, t3.c3, t1.c3 - Sort Key: t1.c3, t1.c1 - -> Merge Join - Output: t1.c1, t2.c2, t3.c3, t1.c3 - Merge Cond: (t2.c1 = t1.c1) - -> Sort - Output: t2.c2, t2.c1 - Sort Key: t2.c1 - -> Foreign Scan on public.ft2 t2 - Output: t2.c2, t2.c1 - InfluxDB query: SELECT "C 1", "c2" FROM "T1" - -> Materialize - Output: t1.c1, t1.c3, t3.c3, t3.c1 - -> Merge Join - Output: t1.c1, t1.c3, t3.c3, t3.c1 - Merge Cond: (t1.c1 = t3.c1) - -> Sort - Output: t1.c1, t1.c3 - Sort Key: t1.c1 - -> Foreign Scan on public.ft1 t1 - Output: t1.c1, t1.c3 - InfluxDB query: SELECT "C 1", "c3" FROM "T1" - -> Sort - Output: t3.c3, t3.c1 - Sort Key: t3.c1 - -> Foreign Scan on public.ft4 t3 - Output: t3.c3, t3.c1 - InfluxDB query: SELECT "c1", "c3" FROM "T3" -(31 rows) - ---Testcase 99: -SELECT t1.c1, t2.c2, t3.c3 FROM ft1 t1 JOIN ft2 t2 ON (t1.c1 = t2.c1) JOIN ft4 t3 ON (t3.c1 = t1.c1) ORDER BY t1.c3, t1.c1 OFFSET 10 LIMIT 10; - c1 | c2 | c3 -----+----+-------- - 22 | 2 | AAA022 - 24 | 4 | AAA024 - 26 | 6 | AAA026 - 28 | 8 | AAA028 - 30 | 0 | AAA030 - 32 | 2 | AAA032 - 34 | 4 | AAA034 - 36 | 6 | AAA036 - 38 | 8 | AAA038 - 40 | 0 | AAA040 -(10 rows) - --- left outer join ---Testcase 100: -EXPLAIN (VERBOSE, COSTS OFF) -SELECT t1.c1, t2.c1 FROM ft4 t1 LEFT JOIN ft5 t2 ON (t1.c1 = t2.c1) ORDER BY t1.c1, t2.c1 OFFSET 10 LIMIT 10; - QUERY PLAN ------------------------------------------------------------------ - Limit - Output: t1.c1, t2.c1 - -> Sort - Output: t1.c1, t2.c1 - Sort Key: t1.c1, t2.c1 - -> Merge Left Join - Output: t1.c1, t2.c1 - Merge Cond: (t1.c1 = t2.c1) - -> Sort - Output: t1.c1 - Sort Key: t1.c1 - -> Foreign Scan on public.ft4 t1 - Output: t1.c1 - InfluxDB query: SELECT "c1" FROM "T3" - -> Sort - Output: t2.c1 - Sort Key: t2.c1 - -> Foreign Scan on public.ft5 t2 - Output: t2.c1 - InfluxDB query: SELECT "c1" FROM "T4" -(20 rows) - ---Testcase 101: -SELECT t1.c1, t2.c1 FROM ft4 t1 LEFT JOIN ft5 t2 ON (t1.c1 = t2.c1) ORDER BY t1.c1, t2.c1 OFFSET 10 LIMIT 10; - c1 | c1 -----+---- - 22 | - 24 | 24 - 26 | - 28 | - 30 | 30 - 32 | - 34 | - 36 | 36 - 38 | - 40 | -(10 rows) - --- left outer join three tables ---Testcase 102: -EXPLAIN (VERBOSE, COSTS OFF) -SELECT t1.c1, t2.c2, t3.c3 FROM ft2 t1 LEFT JOIN ft2 t2 ON (t1.c1 = t2.c1) LEFT JOIN ft4 t3 ON (t2.c1 = t3.c1) OFFSET 10 LIMIT 10; - QUERY PLAN ------------------------------------------------------------------------- - Limit - Output: t1.c1, t2.c2, t3.c3 - -> Nested Loop Left Join - Output: t1.c1, t2.c2, t3.c3 - Join Filter: (t2.c1 = t3.c1) - -> Nested Loop Left Join - Output: t1.c1, t2.c2, t2.c1 - Join Filter: (t1.c1 = t2.c1) - -> Foreign Scan on public.ft2 t1 - Output: t1.c1 - InfluxDB query: SELECT "C 1" FROM "T1" - -> Materialize - Output: t2.c2, t2.c1 - -> Foreign Scan on public.ft2 t2 - Output: t2.c2, t2.c1 - InfluxDB query: SELECT "C 1", "c2" FROM "T1" - -> Materialize - Output: t3.c3, t3.c1 - -> Foreign Scan on public.ft4 t3 - Output: t3.c3, t3.c1 - InfluxDB query: SELECT "c1", "c3" FROM "T3" -(21 rows) - ---Testcase 103: -SELECT t1.c1, t2.c2, t3.c3 FROM ft2 t1 LEFT JOIN ft2 t2 ON (t1.c1 = t2.c1) LEFT JOIN ft4 t3 ON (t2.c1 = t3.c1) ORDER BY t1.c1 OFFSET 10 LIMIT 10; - c1 | c2 | c3 -----+----+-------- - 11 | 1 | - 12 | 2 | AAA012 - 13 | 3 | - 14 | 4 | AAA014 - 15 | 5 | - 16 | 6 | AAA016 - 17 | 7 | - 18 | 8 | AAA018 - 19 | 9 | - 20 | 0 | AAA020 -(10 rows) - --- left outer join + placement of clauses. --- clauses within the nullable side are not pulled up, but top level clause on --- non-nullable side is pushed into non-nullable side ---Testcase 104: -EXPLAIN (VERBOSE, COSTS OFF) -SELECT t1.c1, t1.c2, t2.c1, t2.c2 FROM ft4 t1 LEFT JOIN (SELECT * FROM ft5 WHERE c1 < 10) t2 ON (t1.c1 = t2.c1) WHERE t1.c1 < 10; - QUERY PLAN -------------------------------------------------------------------------------- - Hash Left Join - Output: t1.c1, t1.c2, ft5.c1, ft5.c2 - Hash Cond: (t1.c1 = ft5.c1) - -> Foreign Scan on public.ft4 t1 - Output: t1.c1, t1.c2, t1.c3 - InfluxDB query: SELECT "c1", "c2" FROM "T3" WHERE (("c1" < 10)) - -> Hash - Output: ft5.c1, ft5.c2 - -> Foreign Scan on public.ft5 - Output: ft5.c1, ft5.c2 - InfluxDB query: SELECT "c1", "c2" FROM "T4" WHERE (("c1" < 10)) -(11 rows) - ---Testcase 105: -SELECT t1.c1, t1.c2, t2.c1, t2.c2 FROM ft4 t1 LEFT JOIN (SELECT * FROM ft5 WHERE c1 < 10) t2 ON (t1.c1 = t2.c1) WHERE t1.c1 < 10; - c1 | c2 | c1 | c2 -----+----+----+---- - 2 | 3 | | - 4 | 5 | | - 6 | 7 | 6 | 7 - 8 | 9 | | -(4 rows) - --- clauses within the nullable side are not pulled up, but the top level clause --- on nullable side is not pushed down into nullable side ---Testcase 106: -EXPLAIN (VERBOSE, COSTS OFF) -SELECT t1.c1, t1.c2, t2.c1, t2.c2 FROM ft4 t1 LEFT JOIN (SELECT * FROM ft5 WHERE c1 < 10) t2 ON (t1.c1 = t2.c1) - WHERE (t2.c1 < 10 OR t2.c1 IS NULL) AND t1.c1 < 10; - QUERY PLAN -------------------------------------------------------------------------------- - Hash Left Join - Output: t1.c1, t1.c2, ft5.c1, ft5.c2 - Hash Cond: (t1.c1 = ft5.c1) - Filter: ((ft5.c1 < 10) OR (ft5.c1 IS NULL)) - -> Foreign Scan on public.ft4 t1 - Output: t1.c1, t1.c2, t1.c3 - InfluxDB query: SELECT "c1", "c2" FROM "T3" WHERE (("c1" < 10)) - -> Hash - Output: ft5.c1, ft5.c2 - -> Foreign Scan on public.ft5 - Output: ft5.c1, ft5.c2 - InfluxDB query: SELECT "c1", "c2" FROM "T4" WHERE (("c1" < 10)) -(12 rows) - ---Testcase 107: -SELECT t1.c1, t1.c2, t2.c1, t2.c2 FROM ft4 t1 LEFT JOIN (SELECT * FROM ft5 WHERE c1 < 10) t2 ON (t1.c1 = t2.c1) - WHERE (t2.c1 < 10 OR t2.c1 IS NULL) AND t1.c1 < 10; - c1 | c2 | c1 | c2 -----+----+----+---- - 2 | 3 | | - 4 | 5 | | - 6 | 7 | 6 | 7 - 8 | 9 | | -(4 rows) - --- right outer join ---Testcase 108: -EXPLAIN (VERBOSE, COSTS OFF) -SELECT t1.c1, t2.c1 FROM ft5 t1 RIGHT JOIN ft4 t2 ON (t1.c1 = t2.c1) ORDER BY t2.c1, t1.c1 OFFSET 10 LIMIT 10; - QUERY PLAN ------------------------------------------------------------------ - Limit - Output: t1.c1, t2.c1 - -> Sort - Output: t1.c1, t2.c1 - Sort Key: t2.c1, t1.c1 - -> Merge Left Join - Output: t1.c1, t2.c1 - Merge Cond: (t2.c1 = t1.c1) - -> Sort - Output: t2.c1 - Sort Key: t2.c1 - -> Foreign Scan on public.ft4 t2 - Output: t2.c1 - InfluxDB query: SELECT "c1" FROM "T3" - -> Sort - Output: t1.c1 - Sort Key: t1.c1 - -> Foreign Scan on public.ft5 t1 - Output: t1.c1 - InfluxDB query: SELECT "c1" FROM "T4" -(20 rows) - ---Testcase 109: -SELECT t1.c1, t2.c1 FROM ft5 t1 RIGHT JOIN ft4 t2 ON (t1.c1 = t2.c1) ORDER BY t2.c1, t1.c1 OFFSET 10 LIMIT 10; - c1 | c1 -----+---- - | 22 - 24 | 24 - | 26 - | 28 - 30 | 30 - | 32 - | 34 - 36 | 36 - | 38 - | 40 -(10 rows) - --- right outer join three tables ---Testcase 110: -EXPLAIN (VERBOSE, COSTS OFF) -SELECT t1.c1, t2.c2, t3.c3 FROM ft2 t1 RIGHT JOIN ft2 t2 ON (t1.c1 = t2.c1) RIGHT JOIN ft4 t3 ON (t2.c1 = t3.c1) OFFSET 10 LIMIT 10; - QUERY PLAN ------------------------------------------------------------------------- - Limit - Output: t1.c1, t2.c2, t3.c3 - -> Nested Loop Left Join - Output: t1.c1, t2.c2, t3.c3 - Join Filter: (t1.c1 = t2.c1) - -> Nested Loop Left Join - Output: t3.c3, t2.c2, t2.c1 - Join Filter: (t2.c1 = t3.c1) - -> Foreign Scan on public.ft4 t3 - Output: t3.c1, t3.c2, t3.c3 - InfluxDB query: SELECT "c1", "c3" FROM "T3" - -> Materialize - Output: t2.c2, t2.c1 - -> Foreign Scan on public.ft2 t2 - Output: t2.c2, t2.c1 - InfluxDB query: SELECT "C 1", "c2" FROM "T1" - -> Materialize - Output: t1.c1 - -> Foreign Scan on public.ft2 t1 - Output: t1.c1 - InfluxDB query: SELECT "C 1" FROM "T1" -(21 rows) - ---Testcase 111: -SELECT t1.c1, t2.c2, t3.c3 FROM ft2 t1 RIGHT JOIN ft2 t2 ON (t1.c1 = t2.c1) RIGHT JOIN ft4 t3 ON (t2.c1 = t3.c1) OFFSET 10 LIMIT 10; - c1 | c2 | c3 -----+----+-------- - 22 | 2 | AAA022 - 24 | 4 | AAA024 - 26 | 6 | AAA026 - 28 | 8 | AAA028 - 30 | 0 | AAA030 - 32 | 2 | AAA032 - 34 | 4 | AAA034 - 36 | 6 | AAA036 - 38 | 8 | AAA038 - 40 | 0 | AAA040 -(10 rows) - --- full outer join ---Testcase 112: -EXPLAIN (VERBOSE, COSTS OFF) -SELECT t1.c1, t2.c1 FROM ft4 t1 FULL JOIN ft5 t2 ON (t1.c1 = t2.c1) ORDER BY t1.c1, t2.c1 OFFSET 45 LIMIT 10; - QUERY PLAN ------------------------------------------------------------------ - Limit - Output: t1.c1, t2.c1 - -> Sort - Output: t1.c1, t2.c1 - Sort Key: t1.c1, t2.c1 - -> Merge Full Join - Output: t1.c1, t2.c1 - Merge Cond: (t1.c1 = t2.c1) - -> Sort - Output: t1.c1 - Sort Key: t1.c1 - -> Foreign Scan on public.ft4 t1 - Output: t1.c1 - InfluxDB query: SELECT "c1" FROM "T3" - -> Sort - Output: t2.c1 - Sort Key: t2.c1 - -> Foreign Scan on public.ft5 t2 - Output: t2.c1 - InfluxDB query: SELECT "c1" FROM "T4" -(20 rows) - ---Testcase 113: -SELECT t1.c1, t2.c1 FROM ft4 t1 FULL JOIN ft5 t2 ON (t1.c1 = t2.c1) ORDER BY t1.c1, t2.c1 OFFSET 45 LIMIT 10; - c1 | c1 ------+---- - 92 | - 94 | - 96 | 96 - 98 | - 100 | - | 3 - | 9 - | 15 - | 21 - | 27 -(10 rows) - --- full outer join with restrictions on the joining relations --- a. the joining relations are both base relations ---Testcase 114: -EXPLAIN (VERBOSE, COSTS OFF) -SELECT t1.c1, t2.c1 FROM (SELECT c1 FROM ft4 WHERE c1 between 50 and 60) t1 FULL JOIN (SELECT c1 FROM ft5 WHERE c1 between 50 and 60) t2 ON (t1.c1 = t2.c1) ORDER BY t1.c1, t2.c1; - QUERY PLAN ---------------------------------------------------------------------------------------------------- - Sort - Output: ft4.c1, ft5.c1 - Sort Key: ft4.c1, ft5.c1 - -> Hash Full Join - Output: ft4.c1, ft5.c1 - Hash Cond: (ft4.c1 = ft5.c1) - -> Foreign Scan on public.ft4 - Output: ft4.c1, ft4.c2, ft4.c3 - InfluxDB query: SELECT "c1" FROM "T3" WHERE (("c1" >= 50)) AND (("c1" <= 60)) - -> Hash - Output: ft5.c1 - -> Foreign Scan on public.ft5 - Output: ft5.c1 - InfluxDB query: SELECT "c1" FROM "T4" WHERE (("c1" >= 50)) AND (("c1" <= 60)) -(14 rows) - ---Testcase 115: -SELECT t1.c1, t2.c1 FROM (SELECT c1 FROM ft4 WHERE c1 between 50 and 60) t1 FULL JOIN (SELECT c1 FROM ft5 WHERE c1 between 50 and 60) t2 ON (t1.c1 = t2.c1) ORDER BY t1.c1, t2.c1; - c1 | c1 -----+---- - 50 | - 52 | - 54 | 54 - 56 | - 58 | - 60 | 60 - | 51 - | 57 -(8 rows) - ---Testcase 116: -EXPLAIN (VERBOSE, COSTS OFF) -SELECT 1 FROM (SELECT c1 FROM ft4 WHERE c1 between 50 and 60) t1 FULL JOIN (SELECT c1 FROM ft5 WHERE c1 between 50 and 60) t2 ON (TRUE) OFFSET 10 LIMIT 10; - QUERY PLAN ------------------------------------------------------------------------------------------------- - Limit - Output: 1 - -> Merge Full Join - Output: 1 - -> Foreign Scan on public.ft4 - Output: ft4.c1, ft4.c2, ft4.c3 - InfluxDB query: SELECT * FROM "T3" WHERE (("c1" >= 50)) AND (("c1" <= 60)) - -> Materialize - Output: ft5.c1, ft5.c2, ft5.c3 - -> Foreign Scan on public.ft5 - Output: ft5.c1, ft5.c2, ft5.c3 - InfluxDB query: SELECT * FROM "T4" WHERE (("c1" >= 50)) AND (("c1" <= 60)) -(12 rows) - ---Testcase 117: -SELECT 1 FROM (SELECT c1 FROM ft4 WHERE c1 between 50 and 60) t1 FULL JOIN (SELECT c1 FROM ft5 WHERE c1 between 50 and 60) t2 ON (TRUE) OFFSET 10 LIMIT 10; - ?column? ----------- - 1 - 1 - 1 - 1 - 1 - 1 - 1 - 1 - 1 - 1 -(10 rows) - --- b. one of the joining relations is a base relation and the other is a join --- relation ---Testcase 118: -EXPLAIN (VERBOSE, COSTS OFF) -SELECT t1.c1, ss.a, ss.b FROM (SELECT c1 FROM ft4 WHERE c1 between 50 and 60) t1 FULL JOIN (SELECT t2.c1, t3.c1 FROM ft4 t2 LEFT JOIN ft5 t3 ON (t2.c1 = t3.c1) WHERE (t2.c1 between 50 and 60)) ss(a, b) ON (t1.c1 = ss.a) ORDER BY t1.c1, ss.a, ss.b; - QUERY PLAN ---------------------------------------------------------------------------------------------------------- - Sort - Output: ft4.c1, t2.c1, t3.c1 - Sort Key: ft4.c1, t2.c1, t3.c1 - -> Hash Full Join - Output: ft4.c1, t2.c1, t3.c1 - Hash Cond: (t2.c1 = ft4.c1) - -> Hash Right Join - Output: t2.c1, t3.c1 - Hash Cond: (t3.c1 = t2.c1) - -> Foreign Scan on public.ft5 t3 - Output: t3.c1, t3.c2, t3.c3 - InfluxDB query: SELECT "c1" FROM "T4" - -> Hash - Output: t2.c1 - -> Foreign Scan on public.ft4 t2 - Output: t2.c1 - InfluxDB query: SELECT "c1" FROM "T3" WHERE (("c1" >= 50)) AND (("c1" <= 60)) - -> Hash - Output: ft4.c1 - -> Foreign Scan on public.ft4 - Output: ft4.c1 - InfluxDB query: SELECT "c1" FROM "T3" WHERE (("c1" >= 50)) AND (("c1" <= 60)) -(22 rows) - ---Testcase 119: -SELECT t1.c1, ss.a, ss.b FROM (SELECT c1 FROM ft4 WHERE c1 between 50 and 60) t1 FULL JOIN (SELECT t2.c1, t3.c1 FROM ft4 t2 LEFT JOIN ft5 t3 ON (t2.c1 = t3.c1) WHERE (t2.c1 between 50 and 60)) ss(a, b) ON (t1.c1 = ss.a) ORDER BY t1.c1, ss.a, ss.b; - c1 | a | b -----+----+---- - 50 | 50 | - 52 | 52 | - 54 | 54 | 54 - 56 | 56 | - 58 | 58 | - 60 | 60 | 60 -(6 rows) - --- c. test deparsing the remote query as nested subqueries ---Testcase 120: -EXPLAIN (VERBOSE, COSTS OFF) -SELECT t1.c1, ss.a, ss.b FROM (SELECT c1 FROM ft4 WHERE c1 between 50 and 60) t1 FULL JOIN (SELECT t2.c1, t3.c1 FROM (SELECT c1 FROM ft4 WHERE c1 between 50 and 60) t2 FULL JOIN (SELECT c1 FROM ft5 WHERE c1 between 50 and 60) t3 ON (t2.c1 = t3.c1) WHERE t2.c1 IS NULL OR t2.c1 IS NOT NULL) ss(a, b) ON (t1.c1 = ss.a) ORDER BY t1.c1, ss.a, ss.b; - QUERY PLAN ---------------------------------------------------------------------------------------------------------- - Sort - Output: ft4.c1, ft4_1.c1, ft5.c1 - Sort Key: ft4.c1, ft4_1.c1, ft5.c1 - -> Hash Full Join - Output: ft4.c1, ft4_1.c1, ft5.c1 - Hash Cond: (ft4_1.c1 = ft4.c1) - -> Hash Full Join - Output: ft4_1.c1, ft5.c1 - Hash Cond: (ft4_1.c1 = ft5.c1) - Filter: ((ft4_1.c1 IS NULL) OR (ft4_1.c1 IS NOT NULL)) - -> Foreign Scan on public.ft4 ft4_1 - Output: ft4_1.c1, ft4_1.c2, ft4_1.c3 - InfluxDB query: SELECT "c1" FROM "T3" WHERE (("c1" >= 50)) AND (("c1" <= 60)) - -> Hash - Output: ft5.c1 - -> Foreign Scan on public.ft5 - Output: ft5.c1 - InfluxDB query: SELECT "c1" FROM "T4" WHERE (("c1" >= 50)) AND (("c1" <= 60)) - -> Hash - Output: ft4.c1 - -> Foreign Scan on public.ft4 - Output: ft4.c1 - InfluxDB query: SELECT "c1" FROM "T3" WHERE (("c1" >= 50)) AND (("c1" <= 60)) -(23 rows) - ---Testcase 121: -SELECT t1.c1, ss.a, ss.b FROM (SELECT c1 FROM ft4 WHERE c1 between 50 and 60) t1 FULL JOIN (SELECT t2.c1, t3.c1 FROM (SELECT c1 FROM ft4 WHERE c1 between 50 and 60) t2 FULL JOIN (SELECT c1 FROM ft5 WHERE c1 between 50 and 60) t3 ON (t2.c1 = t3.c1) WHERE t2.c1 IS NULL OR t2.c1 IS NOT NULL) ss(a, b) ON (t1.c1 = ss.a) ORDER BY t1.c1, ss.a, ss.b; - c1 | a | b -----+----+---- - 50 | 50 | - 52 | 52 | - 54 | 54 | 54 - 56 | 56 | - 58 | 58 | - 60 | 60 | 60 - | | 51 - | | 57 -(8 rows) - --- d. test deparsing rowmarked relations as subqueries ---Testcase 122: -EXPLAIN (VERBOSE, COSTS OFF) -SELECT t1.c1, ss.a, ss.b FROM (SELECT c1 FROM "S 1"."T 3" WHERE c1 = 50) t1 INNER JOIN (SELECT t2.c1, t3.c1 FROM (SELECT c1 FROM ft4 WHERE c1 between 50 and 60) t2 FULL JOIN (SELECT c1 FROM ft5 WHERE c1 between 50 and 60) t3 ON (t2.c1 = t3.c1) WHERE t2.c1 IS NULL OR t2.c1 IS NOT NULL) ss(a, b) ON (TRUE) ORDER BY t1.c1, ss.a, ss.b FOR UPDATE OF t1; - QUERY PLAN ---------------------------------------------------------------------------------------------------------------------------------- - LockRows - Output: "T 3".c1, ft4.c1, ft5.c1, "T 3".*, ft4.*, ft5.* - -> Sort - Output: "T 3".c1, ft4.c1, ft5.c1, "T 3".*, ft4.*, ft5.* - Sort Key: ft4.c1, ft5.c1 - -> Nested Loop - Output: "T 3".c1, ft4.c1, ft5.c1, "T 3".*, ft4.*, ft5.* - -> Foreign Scan on "S 1"."T 3" - Output: "T 3".c1, "T 3".* - InfluxDB query: SELECT "c1", "c2", "c3" FROM "T3" WHERE (("c1" = 50)) - -> Materialize - Output: ft4.c1, ft4.*, ft5.c1, ft5.* - -> Merge Full Join - Output: ft4.c1, ft4.*, ft5.c1, ft5.* - Merge Cond: (ft4.c1 = ft5.c1) - Filter: ((ft4.c1 IS NULL) OR (ft4.c1 IS NOT NULL)) - -> Sort - Output: ft4.c1, ft4.* - Sort Key: ft4.c1 - -> Foreign Scan on public.ft4 - Output: ft4.c1, ft4.* - InfluxDB query: SELECT "c1", "c2", "c3" FROM "T3" WHERE (("c1" >= 50)) AND (("c1" <= 60)) - -> Sort - Output: ft5.c1, ft5.* - Sort Key: ft5.c1 - -> Foreign Scan on public.ft5 - Output: ft5.c1, ft5.* - InfluxDB query: SELECT "c1", "c2", "c3" FROM "T4" WHERE (("c1" >= 50)) AND (("c1" <= 60)) -(28 rows) - ---Testcase 123: -SELECT t1.c1, ss.a, ss.b FROM (SELECT c1 FROM "S 1"."T 3" WHERE c1 = 50) t1 INNER JOIN (SELECT t2.c1, t3.c1 FROM (SELECT c1 FROM ft4 WHERE c1 between 50 and 60) t2 FULL JOIN (SELECT c1 FROM ft5 WHERE c1 between 50 and 60) t3 ON (t2.c1 = t3.c1) WHERE t2.c1 IS NULL OR t2.c1 IS NOT NULL) ss(a, b) ON (TRUE) ORDER BY t1.c1, ss.a, ss.b FOR UPDATE OF t1; - c1 | a | b -----+----+---- - 50 | 50 | - 50 | 52 | - 50 | 54 | 54 - 50 | 56 | - 50 | 58 | - 50 | 60 | 60 - 50 | | 51 - 50 | | 57 -(8 rows) - --- full outer join + inner join ---Testcase 124: -EXPLAIN (VERBOSE, COSTS OFF) -SELECT t1.c1, t2.c1, t3.c1 FROM ft4 t1 INNER JOIN ft5 t2 ON (t1.c1 = t2.c1 + 1 and t1.c1 between 50 and 60) FULL JOIN ft4 t3 ON (t2.c1 = t3.c1) ORDER BY t1.c1, t2.c1, t3.c1 LIMIT 10; - QUERY PLAN ---------------------------------------------------------------------------------------------------------------------- - Limit - Output: t1.c1, t2.c1, t3.c1 - -> Sort - Output: t1.c1, t2.c1, t3.c1 - Sort Key: t1.c1, t2.c1, t3.c1 - -> Hash Full Join - Output: t1.c1, t2.c1, t3.c1 - Hash Cond: (t3.c1 = t2.c1) - -> Foreign Scan on public.ft4 t3 - Output: t3.c1, t3.c2, t3.c3 - InfluxDB query: SELECT "c1" FROM "T3" - -> Hash - Output: t1.c1, t2.c1 - -> Hash Join - Output: t1.c1, t2.c1 - Hash Cond: ((t2.c1 + 1) = t1.c1) - -> Foreign Scan on public.ft5 t2 - Output: t2.c1, t2.c2, t2.c3 - InfluxDB query: SELECT "c1" FROM "T4" - -> Hash - Output: t1.c1 - -> Foreign Scan on public.ft4 t1 - Output: t1.c1 - InfluxDB query: SELECT "c1" FROM "T3" WHERE (("c1" >= 50)) AND (("c1" <= 60)) -(24 rows) - ---Testcase 125: -SELECT t1.c1, t2.c1, t3.c1 FROM ft4 t1 INNER JOIN ft5 t2 ON (t1.c1 = t2.c1 + 1 and t1.c1 between 50 and 60) FULL JOIN ft4 t3 ON (t2.c1 = t3.c1) ORDER BY t1.c1, t2.c1, t3.c1 LIMIT 10; - c1 | c1 | c1 -----+----+---- - 52 | 51 | - 58 | 57 | - | | 2 - | | 4 - | | 6 - | | 8 - | | 10 - | | 12 - | | 14 - | | 16 -(10 rows) - --- full outer join three tables ---Testcase 126: -EXPLAIN (VERBOSE, COSTS OFF) -SELECT t1.c1, t2.c2, t3.c3 FROM ft2 t1 FULL JOIN ft2 t2 ON (t1.c1 = t2.c1) FULL JOIN ft4 t3 ON (t2.c1 = t3.c1) OFFSET 10 LIMIT 10; - QUERY PLAN ------------------------------------------------------------------------- - Limit - Output: t1.c1, t2.c2, t3.c3 - -> Hash Full Join - Output: t1.c1, t2.c2, t3.c3 - Hash Cond: (t2.c1 = t3.c1) - -> Hash Full Join - Output: t1.c1, t2.c2, t2.c1 - Hash Cond: (t1.c1 = t2.c1) - -> Foreign Scan on public.ft2 t1 - Output: t1.c1 - InfluxDB query: SELECT "C 1" FROM "T1" - -> Hash - Output: t2.c2, t2.c1 - -> Foreign Scan on public.ft2 t2 - Output: t2.c2, t2.c1 - InfluxDB query: SELECT "C 1", "c2" FROM "T1" - -> Hash - Output: t3.c3, t3.c1 - -> Foreign Scan on public.ft4 t3 - Output: t3.c3, t3.c1 - InfluxDB query: SELECT "c1", "c3" FROM "T3" -(21 rows) - ---Testcase 127: -SELECT t1.c1, t2.c2, t3.c3 FROM ft2 t1 FULL JOIN ft2 t2 ON (t1.c1 = t2.c1) FULL JOIN ft4 t3 ON (t2.c1 = t3.c1) ORDER BY t1.c1 OFFSET 10 LIMIT 10; - c1 | c2 | c3 -----+----+-------- - 11 | 1 | - 12 | 2 | AAA012 - 13 | 3 | - 14 | 4 | AAA014 - 15 | 5 | - 16 | 6 | AAA016 - 17 | 7 | - 18 | 8 | AAA018 - 19 | 9 | - 20 | 0 | AAA020 -(10 rows) - --- full outer join + right outer join ---Testcase 128: -EXPLAIN (VERBOSE, COSTS OFF) -SELECT t1.c1, t2.c2, t3.c3 FROM ft2 t1 FULL JOIN ft2 t2 ON (t1.c1 = t2.c1) RIGHT JOIN ft4 t3 ON (t2.c1 = t3.c1) OFFSET 10 LIMIT 10; - QUERY PLAN ------------------------------------------------------------------------- - Limit - Output: t1.c1, t2.c2, t3.c3 - -> Nested Loop Left Join - Output: t1.c1, t2.c2, t3.c3 - Join Filter: (t1.c1 = t2.c1) - -> Nested Loop Left Join - Output: t3.c3, t2.c2, t2.c1 - Join Filter: (t2.c1 = t3.c1) - -> Foreign Scan on public.ft4 t3 - Output: t3.c1, t3.c2, t3.c3 - InfluxDB query: SELECT "c1", "c3" FROM "T3" - -> Materialize - Output: t2.c2, t2.c1 - -> Foreign Scan on public.ft2 t2 - Output: t2.c2, t2.c1 - InfluxDB query: SELECT "C 1", "c2" FROM "T1" - -> Materialize - Output: t1.c1 - -> Foreign Scan on public.ft2 t1 - Output: t1.c1 - InfluxDB query: SELECT "C 1" FROM "T1" -(21 rows) - ---Testcase 129: -SELECT t1.c1, t2.c2, t3.c3 FROM ft2 t1 FULL JOIN ft2 t2 ON (t1.c1 = t2.c1) RIGHT JOIN ft4 t3 ON (t2.c1 = t3.c1) OFFSET 10 LIMIT 10; - c1 | c2 | c3 -----+----+-------- - 22 | 2 | AAA022 - 24 | 4 | AAA024 - 26 | 6 | AAA026 - 28 | 8 | AAA028 - 30 | 0 | AAA030 - 32 | 2 | AAA032 - 34 | 4 | AAA034 - 36 | 6 | AAA036 - 38 | 8 | AAA038 - 40 | 0 | AAA040 -(10 rows) - --- right outer join + full outer join ---Testcase 130: -EXPLAIN (VERBOSE, COSTS OFF) -SELECT t1.c1, t2.c2, t3.c3 FROM ft2 t1 RIGHT JOIN ft2 t2 ON (t1.c1 = t2.c1) FULL JOIN ft4 t3 ON (t2.c1 = t3.c1) OFFSET 10 LIMIT 10; - QUERY PLAN ------------------------------------------------------------------- - Limit - Output: t1.c1, t2.c2, t3.c3 - -> Hash Full Join - Output: t1.c1, t2.c2, t3.c3 - Hash Cond: (t2.c1 = t3.c1) - -> Nested Loop Left Join - Output: t2.c2, t2.c1, t1.c1 - Join Filter: (t1.c1 = t2.c1) - -> Foreign Scan on public.ft2 t2 - Output: t2.c2, t2.c1 - InfluxDB query: SELECT "C 1", "c2" FROM "T1" - -> Materialize - Output: t1.c1 - -> Foreign Scan on public.ft2 t1 - Output: t1.c1 - InfluxDB query: SELECT "C 1" FROM "T1" - -> Hash - Output: t3.c3, t3.c1 - -> Foreign Scan on public.ft4 t3 - Output: t3.c3, t3.c1 - InfluxDB query: SELECT "c1", "c3" FROM "T3" -(21 rows) - ---Testcase 131: -SELECT t1.c1, t2.c2, t3.c3 FROM ft2 t1 RIGHT JOIN ft2 t2 ON (t1.c1 = t2.c1) FULL JOIN ft4 t3 ON (t2.c1 = t3.c1) ORDER BY t1.c1 OFFSET 10 LIMIT 10; - c1 | c2 | c3 -----+----+-------- - 11 | 1 | - 12 | 2 | AAA012 - 13 | 3 | - 14 | 4 | AAA014 - 15 | 5 | - 16 | 6 | AAA016 - 17 | 7 | - 18 | 8 | AAA018 - 19 | 9 | - 20 | 0 | AAA020 -(10 rows) - --- full outer join + left outer join ---Testcase 132: -EXPLAIN (VERBOSE, COSTS OFF) -SELECT t1.c1, t2.c2, t3.c3 FROM ft2 t1 FULL JOIN ft2 t2 ON (t1.c1 = t2.c1) LEFT JOIN ft4 t3 ON (t2.c1 = t3.c1) OFFSET 10 LIMIT 10; - QUERY PLAN ------------------------------------------------------------------------- - Limit - Output: t1.c1, t2.c2, t3.c3 - -> Nested Loop Left Join - Output: t1.c1, t2.c2, t3.c3 - Join Filter: (t2.c1 = t3.c1) - -> Hash Full Join - Output: t1.c1, t2.c2, t2.c1 - Hash Cond: (t1.c1 = t2.c1) - -> Foreign Scan on public.ft2 t1 - Output: t1.c1 - InfluxDB query: SELECT "C 1" FROM "T1" - -> Hash - Output: t2.c2, t2.c1 - -> Foreign Scan on public.ft2 t2 - Output: t2.c2, t2.c1 - InfluxDB query: SELECT "C 1", "c2" FROM "T1" - -> Materialize - Output: t3.c3, t3.c1 - -> Foreign Scan on public.ft4 t3 - Output: t3.c3, t3.c1 - InfluxDB query: SELECT "c1", "c3" FROM "T3" -(21 rows) - ---Testcase 133: -SELECT t1.c1, t2.c2, t3.c3 FROM ft2 t1 FULL JOIN ft2 t2 ON (t1.c1 = t2.c1) LEFT JOIN ft4 t3 ON (t2.c1 = t3.c1) ORDER BY t1.c1 OFFSET 10 LIMIT 10; - c1 | c2 | c3 -----+----+-------- - 11 | 1 | - 12 | 2 | AAA012 - 13 | 3 | - 14 | 4 | AAA014 - 15 | 5 | - 16 | 6 | AAA016 - 17 | 7 | - 18 | 8 | AAA018 - 19 | 9 | - 20 | 0 | AAA020 -(10 rows) - --- left outer join + full outer join ---Testcase 134: -EXPLAIN (VERBOSE, COSTS OFF) -SELECT t1.c1, t2.c2, t3.c3 FROM ft2 t1 LEFT JOIN ft2 t2 ON (t1.c1 = t2.c1) FULL JOIN ft4 t3 ON (t2.c1 = t3.c1) OFFSET 10 LIMIT 10; - QUERY PLAN ------------------------------------------------------------------------- - Limit - Output: t1.c1, t2.c2, t3.c3 - -> Hash Full Join - Output: t1.c1, t2.c2, t3.c3 - Hash Cond: (t2.c1 = t3.c1) - -> Nested Loop Left Join - Output: t1.c1, t2.c2, t2.c1 - Join Filter: (t1.c1 = t2.c1) - -> Foreign Scan on public.ft2 t1 - Output: t1.c1 - InfluxDB query: SELECT "C 1" FROM "T1" - -> Materialize - Output: t2.c2, t2.c1 - -> Foreign Scan on public.ft2 t2 - Output: t2.c2, t2.c1 - InfluxDB query: SELECT "C 1", "c2" FROM "T1" - -> Hash - Output: t3.c3, t3.c1 - -> Foreign Scan on public.ft4 t3 - Output: t3.c3, t3.c1 - InfluxDB query: SELECT "c1", "c3" FROM "T3" -(21 rows) - ---Testcase 135: -SELECT t1.c1, t2.c2, t3.c3 FROM ft2 t1 LEFT JOIN ft2 t2 ON (t1.c1 = t2.c1) FULL JOIN ft4 t3 ON (t2.c1 = t3.c1) ORDER BY t1.c1 OFFSET 10 LIMIT 10; - c1 | c2 | c3 -----+----+-------- - 11 | 1 | - 12 | 2 | AAA012 - 13 | 3 | - 14 | 4 | AAA014 - 15 | 5 | - 16 | 6 | AAA016 - 17 | 7 | - 18 | 8 | AAA018 - 19 | 9 | - 20 | 0 | AAA020 -(10 rows) - --- right outer join + left outer join ---Testcase 136: -EXPLAIN (VERBOSE, COSTS OFF) -SELECT t1.c1, t2.c2, t3.c3 FROM ft2 t1 RIGHT JOIN ft2 t2 ON (t1.c1 = t2.c1) LEFT JOIN ft4 t3 ON (t2.c1 = t3.c1) OFFSET 10 LIMIT 10; - QUERY PLAN ------------------------------------------------------------------------ - Limit - Output: t1.c1, t2.c2, t3.c3 - -> Nested Loop Left Join - Output: t1.c1, t2.c2, t3.c3 - Join Filter: (t1.c1 = t2.c1) - -> Nested Loop Left Join - Output: t2.c2, t2.c1, t3.c3 - Join Filter: (t2.c1 = t3.c1) - -> Foreign Scan on public.ft2 t2 - Output: t2.c2, t2.c1 - InfluxDB query: SELECT "C 1", "c2" FROM "T1" - -> Materialize - Output: t3.c3, t3.c1 - -> Foreign Scan on public.ft4 t3 - Output: t3.c3, t3.c1 - InfluxDB query: SELECT "c1", "c3" FROM "T3" - -> Materialize - Output: t1.c1 - -> Foreign Scan on public.ft2 t1 - Output: t1.c1 - InfluxDB query: SELECT "C 1" FROM "T1" -(21 rows) - ---Testcase 137: -SELECT t1.c1, t2.c2, t3.c3 FROM ft2 t1 RIGHT JOIN ft2 t2 ON (t1.c1 = t2.c1) LEFT JOIN ft4 t3 ON (t2.c1 = t3.c1) ORDER BY t1.c1 OFFSET 10 LIMIT 10; - c1 | c2 | c3 -----+----+-------- - 11 | 1 | - 12 | 2 | AAA012 - 13 | 3 | - 14 | 4 | AAA014 - 15 | 5 | - 16 | 6 | AAA016 - 17 | 7 | - 18 | 8 | AAA018 - 19 | 9 | - 20 | 0 | AAA020 -(10 rows) - --- left outer join + right outer join ---Testcase 138: -EXPLAIN (VERBOSE, COSTS OFF) -SELECT t1.c1, t2.c2, t3.c3 FROM ft2 t1 LEFT JOIN ft2 t2 ON (t1.c1 = t2.c1) RIGHT JOIN ft4 t3 ON (t2.c1 = t3.c1) OFFSET 10 LIMIT 10; - QUERY PLAN ------------------------------------------------------------------------- - Limit - Output: t1.c1, t2.c2, t3.c3 - -> Hash Right Join - Output: t1.c1, t2.c2, t3.c3 - Hash Cond: (t2.c1 = t3.c1) - -> Nested Loop - Output: t1.c1, t2.c2, t2.c1 - Join Filter: (t1.c1 = t2.c1) - -> Foreign Scan on public.ft2 t1 - Output: t1.c1 - InfluxDB query: SELECT "C 1" FROM "T1" - -> Materialize - Output: t2.c2, t2.c1 - -> Foreign Scan on public.ft2 t2 - Output: t2.c2, t2.c1 - InfluxDB query: SELECT "C 1", "c2" FROM "T1" - -> Hash - Output: t3.c3, t3.c1 - -> Foreign Scan on public.ft4 t3 - Output: t3.c3, t3.c1 - InfluxDB query: SELECT "c1", "c3" FROM "T3" -(21 rows) - ---Testcase 139: -SELECT t1.c1, t2.c2, t3.c3 FROM ft2 t1 LEFT JOIN ft2 t2 ON (t1.c1 = t2.c1) RIGHT JOIN ft4 t3 ON (t2.c1 = t3.c1) ORDER BY t1.c1 OFFSET 10 LIMIT 10; - c1 | c2 | c3 -----+----+-------- - 22 | 2 | AAA022 - 24 | 4 | AAA024 - 26 | 6 | AAA026 - 28 | 8 | AAA028 - 30 | 0 | AAA030 - 32 | 2 | AAA032 - 34 | 4 | AAA034 - 36 | 6 | AAA036 - 38 | 8 | AAA038 - 40 | 0 | AAA040 -(10 rows) - --- full outer join + WHERE clause, only matched rows ---Testcase 140: -EXPLAIN (VERBOSE, COSTS OFF) -SELECT t1.c1, t2.c1 FROM ft4 t1 FULL JOIN ft5 t2 ON (t1.c1 = t2.c1) WHERE (t1.c1 = t2.c1 OR t1.c1 IS NULL) ORDER BY t1.c1, t2.c1 OFFSET 10 LIMIT 10; - QUERY PLAN ------------------------------------------------------------------ - Limit - Output: t1.c1, t2.c1 - -> Sort - Output: t1.c1, t2.c1 - Sort Key: t1.c1, t2.c1 - -> Merge Full Join - Output: t1.c1, t2.c1 - Merge Cond: (t1.c1 = t2.c1) - Filter: ((t1.c1 = t2.c1) OR (t1.c1 IS NULL)) - -> Sort - Output: t1.c1 - Sort Key: t1.c1 - -> Foreign Scan on public.ft4 t1 - Output: t1.c1 - InfluxDB query: SELECT "c1" FROM "T3" - -> Sort - Output: t2.c1 - Sort Key: t2.c1 - -> Foreign Scan on public.ft5 t2 - Output: t2.c1 - InfluxDB query: SELECT "c1" FROM "T4" -(21 rows) - ---Testcase 141: -SELECT t1.c1, t2.c1 FROM ft4 t1 FULL JOIN ft5 t2 ON (t1.c1 = t2.c1) WHERE (t1.c1 = t2.c1 OR t1.c1 IS NULL) ORDER BY t1.c1, t2.c1 OFFSET 10 LIMIT 10; - c1 | c1 -----+---- - 66 | 66 - 72 | 72 - 78 | 78 - 84 | 84 - 90 | 90 - 96 | 96 - | 3 - | 9 - | 15 - | 21 -(10 rows) - --- full outer join + WHERE clause with shippable extensions set ---Testcase 142: -EXPLAIN (VERBOSE, COSTS OFF) -SELECT t1.c1, t2.c2, t1.c3 FROM ft1 t1 FULL JOIN ft2 t2 ON (t1.c1 = t2.c1) WHERE influxdb_fdw_abs(t1.c1) > 0 OFFSET 10 LIMIT 10; - QUERY PLAN ------------------------------------------------------------------- - Limit - Output: t1.c1, t2.c2, t1.c3 - -> Hash Full Join - Output: t1.c1, t2.c2, t1.c3 - Hash Cond: (t2.c1 = t1.c1) - Filter: (influxdb_fdw_abs(t1.c1) > 0) - -> Foreign Scan on public.ft2 t2 - Output: t2.c2, t2.c1 - InfluxDB query: SELECT "C 1", "c2" FROM "T1" - -> Hash - Output: t1.c1, t1.c3 - -> Foreign Scan on public.ft1 t1 - Output: t1.c1, t1.c3 - InfluxDB query: SELECT "C 1", "c3" FROM "T1" -(14 rows) - --- skip, influxdb does not have option 'extensions' --- ALTER SERVER influxdb_svr OPTIONS (DROP extensions); --- full outer join + WHERE clause with shippable extensions not set --- EXPLAIN (VERBOSE, COSTS OFF) --- SELECT t1.c1, t2.c2, t1.c3 FROM ft1 t1 FULL JOIN ft2 t2 ON (t1.c1 = t2.c1) WHERE influxdb_fdw_abs(t1.c1) > 0 OFFSET 10 LIMIT 10; --- ALTER SERVER loopback OPTIONS (ADD extensions 'influxdb_fdw'); --- join two tables with FOR UPDATE clause --- tests whole-row reference for row marks ---Testcase 143: -EXPLAIN (VERBOSE, COSTS OFF) -SELECT t1.c1, t2.c1 FROM ft1 t1 JOIN ft2 t2 ON (t1.c1 = t2.c1) ORDER BY t1.c3, t1.c1 OFFSET 100 LIMIT 10 FOR UPDATE OF t1; - QUERY PLAN ------------------------------------------------------------------------------------------------------- - Limit - Output: t1.c1, t2.c1, t1.c3, t1.*, t2.* - -> LockRows - Output: t1.c1, t2.c1, t1.c3, t1.*, t2.* - -> Sort - Output: t1.c1, t2.c1, t1.c3, t1.*, t2.* - Sort Key: t1.c3, t1.c1 - -> Hash Join - Output: t1.c1, t2.c1, t1.c3, t1.*, t2.* - Hash Cond: (t2.c1 = t1.c1) - -> Foreign Scan on public.ft2 t2 - Output: t2.c1, t2.* - InfluxDB query: SELECT "C 1", "c2", "c3", "c6", "c7", "c8" FROM "T1" - -> Hash - Output: t1.c1, t1.c3, t1.* - -> Foreign Scan on public.ft1 t1 - Output: t1.c1, t1.c3, t1.* - InfluxDB query: SELECT "C 1", "c2", "c3", "c6", "c7", "c8" FROM "T1" -(18 rows) - ---Testcase 144: -SELECT t1.c1, t2.c1 FROM ft1 t1 JOIN ft2 t2 ON (t1.c1 = t2.c1) ORDER BY t1.c3, t1.c1 OFFSET 100 LIMIT 10 FOR UPDATE OF t1; - c1 | c1 ------+----- - 101 | 101 - 102 | 102 - 103 | 103 - 104 | 104 - 105 | 105 - 106 | 106 - 107 | 107 - 108 | 108 - 109 | 109 - 110 | 110 -(10 rows) - ---Testcase 145: -EXPLAIN (VERBOSE, COSTS OFF) -SELECT t1.c1, t2.c1 FROM ft1 t1 JOIN ft2 t2 ON (t1.c1 = t2.c1) ORDER BY t1.c3, t1.c1 OFFSET 100 LIMIT 10 FOR UPDATE; - QUERY PLAN ------------------------------------------------------------------------------------------------------- - Limit - Output: t1.c1, t2.c1, t1.c3, t1.*, t2.* - -> LockRows - Output: t1.c1, t2.c1, t1.c3, t1.*, t2.* - -> Sort - Output: t1.c1, t2.c1, t1.c3, t1.*, t2.* - Sort Key: t1.c3, t1.c1 - -> Hash Join - Output: t1.c1, t2.c1, t1.c3, t1.*, t2.* - Hash Cond: (t2.c1 = t1.c1) - -> Foreign Scan on public.ft2 t2 - Output: t2.c1, t2.* - InfluxDB query: SELECT "C 1", "c2", "c3", "c6", "c7", "c8" FROM "T1" - -> Hash - Output: t1.c1, t1.c3, t1.* - -> Foreign Scan on public.ft1 t1 - Output: t1.c1, t1.c3, t1.* - InfluxDB query: SELECT "C 1", "c2", "c3", "c6", "c7", "c8" FROM "T1" -(18 rows) - ---Testcase 146: -SELECT t1.c1, t2.c1 FROM ft1 t1 JOIN ft2 t2 ON (t1.c1 = t2.c1) ORDER BY t1.c3, t1.c1 OFFSET 100 LIMIT 10 FOR UPDATE; - c1 | c1 ------+----- - 101 | 101 - 102 | 102 - 103 | 103 - 104 | 104 - 105 | 105 - 106 | 106 - 107 | 107 - 108 | 108 - 109 | 109 - 110 | 110 -(10 rows) - --- join two tables with FOR SHARE clause ---Testcase 147: -EXPLAIN (VERBOSE, COSTS OFF) -SELECT t1.c1, t2.c1 FROM ft1 t1 JOIN ft2 t2 ON (t1.c1 = t2.c1) ORDER BY t1.c3, t1.c1 OFFSET 100 LIMIT 10 FOR SHARE OF t1; - QUERY PLAN ------------------------------------------------------------------------------------------------------- - Limit - Output: t1.c1, t2.c1, t1.c3, t1.*, t2.* - -> LockRows - Output: t1.c1, t2.c1, t1.c3, t1.*, t2.* - -> Sort - Output: t1.c1, t2.c1, t1.c3, t1.*, t2.* - Sort Key: t1.c3, t1.c1 - -> Hash Join - Output: t1.c1, t2.c1, t1.c3, t1.*, t2.* - Hash Cond: (t2.c1 = t1.c1) - -> Foreign Scan on public.ft2 t2 - Output: t2.c1, t2.* - InfluxDB query: SELECT "C 1", "c2", "c3", "c6", "c7", "c8" FROM "T1" - -> Hash - Output: t1.c1, t1.c3, t1.* - -> Foreign Scan on public.ft1 t1 - Output: t1.c1, t1.c3, t1.* - InfluxDB query: SELECT "C 1", "c2", "c3", "c6", "c7", "c8" FROM "T1" -(18 rows) - ---Testcase 148: -SELECT t1.c1, t2.c1 FROM ft1 t1 JOIN ft2 t2 ON (t1.c1 = t2.c1) ORDER BY t1.c3, t1.c1 OFFSET 100 LIMIT 10 FOR SHARE OF t1; - c1 | c1 ------+----- - 101 | 101 - 102 | 102 - 103 | 103 - 104 | 104 - 105 | 105 - 106 | 106 - 107 | 107 - 108 | 108 - 109 | 109 - 110 | 110 -(10 rows) - ---Testcase 149: -EXPLAIN (VERBOSE, COSTS OFF) -SELECT t1.c1, t2.c1 FROM ft1 t1 JOIN ft2 t2 ON (t1.c1 = t2.c1) ORDER BY t1.c3, t1.c1 OFFSET 100 LIMIT 10 FOR SHARE; - QUERY PLAN ------------------------------------------------------------------------------------------------------- - Limit - Output: t1.c1, t2.c1, t1.c3, t1.*, t2.* - -> LockRows - Output: t1.c1, t2.c1, t1.c3, t1.*, t2.* - -> Sort - Output: t1.c1, t2.c1, t1.c3, t1.*, t2.* - Sort Key: t1.c3, t1.c1 - -> Hash Join - Output: t1.c1, t2.c1, t1.c3, t1.*, t2.* - Hash Cond: (t2.c1 = t1.c1) - -> Foreign Scan on public.ft2 t2 - Output: t2.c1, t2.* - InfluxDB query: SELECT "C 1", "c2", "c3", "c6", "c7", "c8" FROM "T1" - -> Hash - Output: t1.c1, t1.c3, t1.* - -> Foreign Scan on public.ft1 t1 - Output: t1.c1, t1.c3, t1.* - InfluxDB query: SELECT "C 1", "c2", "c3", "c6", "c7", "c8" FROM "T1" -(18 rows) - ---Testcase 150: -SELECT t1.c1, t2.c1 FROM ft1 t1 JOIN ft2 t2 ON (t1.c1 = t2.c1) ORDER BY t1.c3, t1.c1 OFFSET 100 LIMIT 10 FOR SHARE; - c1 | c1 ------+----- - 101 | 101 - 102 | 102 - 103 | 103 - 104 | 104 - 105 | 105 - 106 | 106 - 107 | 107 - 108 | 108 - 109 | 109 - 110 | 110 -(10 rows) - --- join in CTE ---Testcase 151: -EXPLAIN (VERBOSE, COSTS OFF) -WITH t (c1_1, c1_3, c2_1) AS MATERIALIZED (SELECT t1.c1, t1.c3, t2.c1 FROM ft1 t1 JOIN ft2 t2 ON (t1.c1 = t2.c1)) SELECT c1_1, c2_1 FROM t ORDER BY c1_3, c1_1 OFFSET 100 LIMIT 10; -ERROR: syntax error at or near "MATERIALIZED" -LINE 2: WITH t (c1_1, c1_3, c2_1) AS MATERIALIZED (SELECT t1.c1, t1.... - ^ ---Testcase 152: -WITH t (c1_1, c1_3, c2_1) AS MATERIALIZED (SELECT t1.c1, t1.c3, t2.c1 FROM ft1 t1 JOIN ft2 t2 ON (t1.c1 = t2.c1)) SELECT c1_1, c2_1 FROM t ORDER BY c1_3, c1_1 OFFSET 100 LIMIT 10; -ERROR: syntax error at or near "MATERIALIZED" -LINE 1: WITH t (c1_1, c1_3, c2_1) AS MATERIALIZED (SELECT t1.c1, t1.... - ^ --- ctid with whole-row reference ---Testcase 153: -EXPLAIN (VERBOSE, COSTS OFF) -SELECT t1.ctid, t1, t2, t1.c1 FROM ft1 t1 JOIN ft2 t2 ON (t1.c1 = t2.c1) ORDER BY t1.c3, t1.c1 OFFSET 100 LIMIT 10; - QUERY PLAN ------------------------------------------------------------------------------------------------- - Limit - Output: t1.ctid, t1.*, t2.*, t1.c1, t1.c3 - -> Sort - Output: t1.ctid, t1.*, t2.*, t1.c1, t1.c3 - Sort Key: t1.c3, t1.c1 - -> Hash Join - Output: t1.ctid, t1.*, t2.*, t1.c1, t1.c3 - Hash Cond: (t2.c1 = t1.c1) - -> Foreign Scan on public.ft2 t2 - Output: t2.*, t2.c1 - InfluxDB query: SELECT "C 1", "c2", "c3", "c6", "c7", "c8" FROM "T1" - -> Hash - Output: t1.ctid, t1.*, t1.c1, t1.c3 - -> Foreign Scan on public.ft1 t1 - Output: t1.ctid, t1.*, t1.c1, t1.c3 - InfluxDB query: SELECT "C 1", "c2", "c3", "c6", "c7", "c8" FROM "T1" -(16 rows) - --- SEMI JOIN, not pushed down ---Testcase 154: -EXPLAIN (VERBOSE, COSTS OFF) -SELECT t1.c1 FROM ft1 t1 WHERE EXISTS (SELECT 1 FROM ft2 t2 WHERE t1.c1 = t2.c1) ORDER BY t1.c1 OFFSET 100 LIMIT 10; - QUERY PLAN ------------------------------------------------------------------------- - Limit - Output: t1.c1 - -> Sort - Output: t1.c1 - Sort Key: t1.c1 - -> Hash Join - Output: t1.c1 - Inner Unique: true - Hash Cond: (t1.c1 = t2.c1) - -> Foreign Scan on public.ft1 t1 - Output: t1.c1 - InfluxDB query: SELECT "C 1" FROM "T1" - -> Hash - Output: t2.c1 - -> HashAggregate - Output: t2.c1 - Group Key: t2.c1 - -> Foreign Scan on public.ft2 t2 - Output: t2.c1 - InfluxDB query: SELECT "C 1" FROM "T1" -(20 rows) - ---Testcase 155: -SELECT t1.c1 FROM ft1 t1 WHERE EXISTS (SELECT 1 FROM ft2 t2 WHERE t1.c1 = t2.c1) ORDER BY t1.c1 OFFSET 100 LIMIT 10; - c1 ------ - 101 - 102 - 103 - 104 - 105 - 106 - 107 - 108 - 109 - 110 -(10 rows) - --- ANTI JOIN, not pushed down ---Testcase 156: -EXPLAIN (VERBOSE, COSTS OFF) -SELECT t1.c1 FROM ft1 t1 WHERE NOT EXISTS (SELECT 1 FROM ft2 t2 WHERE t1.c1 = t2.c2) ORDER BY t1.c1 OFFSET 100 LIMIT 10; - QUERY PLAN ------------------------------------------------------------------ - Limit - Output: t1.c1 - -> Sort - Output: t1.c1 - Sort Key: t1.c1 - -> Hash Anti Join - Output: t1.c1 - Hash Cond: (t1.c1 = t2.c2) - -> Foreign Scan on public.ft1 t1 - Output: t1.c1 - InfluxDB query: SELECT "C 1" FROM "T1" - -> Hash - Output: t2.c2 - -> Foreign Scan on public.ft2 t2 - Output: t2.c2 - InfluxDB query: SELECT "c2" FROM "T1" -(16 rows) - ---Testcase 157: -SELECT t1.c1 FROM ft1 t1 WHERE NOT EXISTS (SELECT 1 FROM ft2 t2 WHERE t1.c1 = t2.c2) ORDER BY t1.c1 OFFSET 100 LIMIT 10; - c1 ------ - 110 - 111 - 112 - 113 - 114 - 115 - 116 - 117 - 118 - 119 -(10 rows) - --- CROSS JOIN can be pushed down ---Testcase 158: -EXPLAIN (VERBOSE, COSTS OFF) -SELECT t1.c1, t2.c1 FROM ft1 t1 CROSS JOIN ft2 t2 ORDER BY t1.c1, t2.c1 OFFSET 100 LIMIT 10; - QUERY PLAN ------------------------------------------------------------------- - Limit - Output: t1.c1, t2.c1 - -> Sort - Output: t1.c1, t2.c1 - Sort Key: t1.c1, t2.c1 - -> Nested Loop - Output: t1.c1, t2.c1 - -> Foreign Scan on public.ft1 t1 - Output: t1.c1 - InfluxDB query: SELECT "C 1" FROM "T1" - -> Materialize - Output: t2.c1 - -> Foreign Scan on public.ft2 t2 - Output: t2.c1 - InfluxDB query: SELECT "C 1" FROM "T1" -(15 rows) - ---Testcase 159: -SELECT t1.c1, t2.c1 FROM ft1 t1 CROSS JOIN ft2 t2 ORDER BY t1.c1, t2.c1 OFFSET 100 LIMIT 10; - c1 | c1 -----+----- - 1 | 101 - 1 | 102 - 1 | 103 - 1 | 104 - 1 | 105 - 1 | 106 - 1 | 107 - 1 | 108 - 1 | 109 - 1 | 110 -(10 rows) - --- different server, not pushed down. No result expected. ---Testcase 160: -EXPLAIN (VERBOSE, COSTS OFF) -SELECT t1.c1, t2.c1 FROM ft5 t1 JOIN ft6 t2 ON (t1.c1 = t2.c1) ORDER BY t1.c1, t2.c1 OFFSET 100 LIMIT 10; - QUERY PLAN ------------------------------------------------------------ - Limit - Output: t1.c1, t2.c1 - -> Merge Join - Output: t1.c1, t2.c1 - Merge Cond: (t1.c1 = t2.c1) - -> Sort - Output: t1.c1 - Sort Key: t1.c1 - -> Foreign Scan on public.ft5 t1 - Output: t1.c1 - InfluxDB query: SELECT "c1" FROM "T4" - -> Sort - Output: t2.c1 - Sort Key: t2.c1 - -> Foreign Scan on public.ft6 t2 - Output: t2.c1 - InfluxDB query: SELECT "c1" FROM "T4" -(17 rows) - ---Testcase 161: -SELECT t1.c1, t2.c1 FROM ft5 t1 JOIN ft6 t2 ON (t1.c1 = t2.c1) ORDER BY t1.c1, t2.c1 OFFSET 100 LIMIT 10; - c1 | c1 -----+---- -(0 rows) - --- unsafe join conditions (c8 has a UDT), not pushed down. Practically a CROSS --- JOIN since c8 in both tables has same value. ---Testcase 162: -EXPLAIN (VERBOSE, COSTS OFF) -SELECT t1.c1, t2.c1 FROM ft1 t1 LEFT JOIN ft2 t2 ON (t1.c8 = t2.c8) ORDER BY t1.c1, t2.c1 OFFSET 100 LIMIT 10; - QUERY PLAN ------------------------------------------------------------------------- - Limit - Output: t1.c1, t2.c1 - -> Sort - Output: t1.c1, t2.c1 - Sort Key: t1.c1, t2.c1 - -> Merge Left Join - Output: t1.c1, t2.c1 - Merge Cond: (t1.c8 = t2.c8) - -> Sort - Output: t1.c1, t1.c8 - Sort Key: t1.c8 - -> Foreign Scan on public.ft1 t1 - Output: t1.c1, t1.c8 - InfluxDB query: SELECT "C 1", "c8" FROM "T1" - -> Sort - Output: t2.c1, t2.c8 - Sort Key: t2.c8 - -> Foreign Scan on public.ft2 t2 - Output: t2.c1, t2.c8 - InfluxDB query: SELECT "C 1", "c8" FROM "T1" -(20 rows) - ---Testcase 163: -SELECT t1.c1, t2.c1 FROM ft1 t1 LEFT JOIN ft2 t2 ON (t1.c8 = t2.c8) ORDER BY t1.c1, t2.c1 OFFSET 100 LIMIT 10; - c1 | c1 -----+----- - 1 | 101 - 1 | 102 - 1 | 103 - 1 | 104 - 1 | 105 - 1 | 106 - 1 | 107 - 1 | 108 - 1 | 109 - 1 | 110 -(10 rows) - --- unsafe conditions on one side (c8 has a UDT), not pushed down. ---Testcase 164: -EXPLAIN (VERBOSE, COSTS OFF) -SELECT t1.c1, t2.c1 FROM ft1 t1 LEFT JOIN ft2 t2 ON (t1.c1 = t2.c1) WHERE t1.c8 = 'foo' ORDER BY t1.c3, t1.c1 OFFSET 100 LIMIT 10; - QUERY PLAN ------------------------------------------------------------------------------------------------ - Limit - Output: t1.c1, t2.c1, t1.c3 - -> Sort - Output: t1.c1, t2.c1, t1.c3 - Sort Key: t1.c3, t1.c1 - -> Hash Right Join - Output: t1.c1, t2.c1, t1.c3 - Hash Cond: (t2.c1 = t1.c1) - -> Foreign Scan on public.ft2 t2 - Output: t2.c1 - InfluxDB query: SELECT "C 1" FROM "T1" - -> Hash - Output: t1.c1, t1.c3 - -> Foreign Scan on public.ft1 t1 - Output: t1.c1, t1.c3 - InfluxDB query: SELECT "C 1", "c3" FROM "T1" WHERE (("c8" = 'foo')) -(16 rows) - ---Testcase 165: -SELECT t1.c1, t2.c1 FROM ft1 t1 LEFT JOIN ft2 t2 ON (t1.c1 = t2.c1) WHERE t1.c8 = 'foo' ORDER BY t1.c3, t1.c1 OFFSET 100 LIMIT 10; - c1 | c1 ------+----- - 101 | 101 - 102 | 102 - 103 | 103 - 104 | 104 - 105 | 105 - 106 | 106 - 107 | 107 - 108 | 108 - 109 | 109 - 110 | 110 -(10 rows) - --- join where unsafe to pushdown condition in WHERE clause has a column not --- in the SELECT clause. In this test unsafe clause needs to have column --- references from both joining sides so that the clause is not pushed down --- into one of the joining sides. ---Testcase 166: -EXPLAIN (VERBOSE, COSTS OFF) -SELECT t1.c1, t2.c1 FROM ft1 t1 JOIN ft2 t2 ON (t1.c1 = t2.c1) WHERE t1.c8 = t2.c8 ORDER BY t1.c3, t1.c1 OFFSET 100 LIMIT 10; - QUERY PLAN ------------------------------------------------------------------------------- - Limit - Output: t1.c1, t2.c1, t1.c3 - -> Sort - Output: t1.c1, t2.c1, t1.c3 - Sort Key: t1.c3, t1.c1 - -> Merge Join - Output: t1.c1, t2.c1, t1.c3 - Merge Cond: ((t1.c1 = t2.c1) AND (t1.c8 = t2.c8)) - -> Sort - Output: t1.c1, t1.c3, t1.c8 - Sort Key: t1.c1, t1.c8 - -> Foreign Scan on public.ft1 t1 - Output: t1.c1, t1.c3, t1.c8 - InfluxDB query: SELECT "C 1", "c3", "c8" FROM "T1" - -> Sort - Output: t2.c1, t2.c8 - Sort Key: t2.c1, t2.c8 - -> Foreign Scan on public.ft2 t2 - Output: t2.c1, t2.c8 - InfluxDB query: SELECT "C 1", "c8" FROM "T1" -(20 rows) - ---Testcase 167: -SELECT t1.c1, t2.c1 FROM ft1 t1 JOIN ft2 t2 ON (t1.c1 = t2.c1) WHERE t1.c8 = t2.c8 ORDER BY t1.c3, t1.c1 OFFSET 100 LIMIT 10; - c1 | c1 ------+----- - 101 | 101 - 102 | 102 - 103 | 103 - 104 | 104 - 105 | 105 - 106 | 106 - 107 | 107 - 108 | 108 - 109 | 109 - 110 | 110 -(10 rows) - --- Aggregate after UNION, for testing setrefs ---Testcase 168: -EXPLAIN (VERBOSE, COSTS OFF) -SELECT t1c1, avg(t1c1 + t2c1) FROM (SELECT t1.c1, t2.c1 FROM ft1 t1 JOIN ft2 t2 ON (t1.c1 = t2.c1) UNION SELECT t1.c1, t2.c1 FROM ft1 t1 JOIN ft2 t2 ON (t1.c1 = t2.c1)) AS t (t1c1, t2c1) GROUP BY t1c1 ORDER BY t1c1 OFFSET 100 LIMIT 10; - QUERY PLAN ------------------------------------------------------------------------------------- - Limit - Output: t1.c1, (avg((t1.c1 + t2.c1))) - -> Sort - Output: t1.c1, (avg((t1.c1 + t2.c1))) - Sort Key: t1.c1 - -> HashAggregate - Output: t1.c1, avg((t1.c1 + t2.c1)) - Group Key: t1.c1 - -> HashAggregate - Output: t1.c1, t2.c1 - Group Key: t1.c1, t2.c1 - -> Append - -> Merge Join - Output: t1.c1, t2.c1 - Merge Cond: (t1.c1 = t2.c1) - -> Sort - Output: t1.c1 - Sort Key: t1.c1 - -> Foreign Scan on public.ft1 t1 - Output: t1.c1 - InfluxDB query: SELECT "C 1" FROM "T1" - -> Sort - Output: t2.c1 - Sort Key: t2.c1 - -> Foreign Scan on public.ft2 t2 - Output: t2.c1 - InfluxDB query: SELECT "C 1" FROM "T1" - -> Merge Join - Output: t1_1.c1, t2_1.c1 - Merge Cond: (t1_1.c1 = t2_1.c1) - -> Sort - Output: t1_1.c1 - Sort Key: t1_1.c1 - -> Foreign Scan on public.ft1 t1_1 - Output: t1_1.c1 - InfluxDB query: SELECT "C 1" FROM "T1" - -> Sort - Output: t2_1.c1 - Sort Key: t2_1.c1 - -> Foreign Scan on public.ft2 t2_1 - Output: t2_1.c1 - InfluxDB query: SELECT "C 1" FROM "T1" -(42 rows) - ---Testcase 169: -SELECT t1c1, avg(t1c1 + t2c1) FROM (SELECT t1.c1, t2.c1 FROM ft1 t1 JOIN ft2 t2 ON (t1.c1 = t2.c1) UNION SELECT t1.c1, t2.c1 FROM ft1 t1 JOIN ft2 t2 ON (t1.c1 = t2.c1)) AS t (t1c1, t2c1) GROUP BY t1c1 ORDER BY t1c1 OFFSET 100 LIMIT 10; - t1c1 | avg -------+---------------------- - 101 | 202.0000000000000000 - 102 | 204.0000000000000000 - 103 | 206.0000000000000000 - 104 | 208.0000000000000000 - 105 | 210.0000000000000000 - 106 | 212.0000000000000000 - 107 | 214.0000000000000000 - 108 | 216.0000000000000000 - 109 | 218.0000000000000000 - 110 | 220.0000000000000000 -(10 rows) - --- join with lateral reference ---Testcase 170: -EXPLAIN (VERBOSE, COSTS OFF) -SELECT t1."C 1" FROM "S 1"."T 1" t1, LATERAL (SELECT DISTINCT t2.c1, t3.c1 FROM ft1 t2, ft2 t3 WHERE t2.c1 = t3.c1 AND t2.c2 = t1.c2) q ORDER BY t1."C 1" OFFSET 10 LIMIT 10; - QUERY PLAN --------------------------------------------------------------------------------------------------------- - Limit - Output: t1."C 1" - -> Sort - Output: t1."C 1" - Sort Key: t1."C 1" - -> Nested Loop - Output: t1."C 1" - -> Foreign Scan on "S 1"."T 1" t1 - Output: t1."C 1", t1.c2, t1.c3, t1."time", t1.c6, t1.c7, t1.c8 - InfluxDB query: SELECT "C 1", "c2" FROM "T1" - -> Unique - Output: t2.c1, t3.c1 - -> Sort - Output: t2.c1, t3.c1 - Sort Key: t2.c1 - -> Hash Join - Output: t2.c1, t3.c1 - Hash Cond: (t3.c1 = t2.c1) - -> Foreign Scan on public.ft2 t3 - Output: t3.c1 - InfluxDB query: SELECT "C 1" FROM "T1" - -> Hash - Output: t2.c1 - -> Foreign Scan on public.ft1 t2 - Output: t2.c1 - InfluxDB query: SELECT "C 1" FROM "T1" WHERE (("c2" = $1)) -(26 rows) - ---Testcase 171: -SELECT t1."C 1" FROM "S 1"."T 1" t1, LATERAL (SELECT DISTINCT t2.c1, t3.c1 FROM ft1 t2, ft2 t3 WHERE t2.c1 = t3.c1 AND t2.c2 = t1.c2) q ORDER BY t1."C 1" OFFSET 10 LIMIT 10; - C 1 ------ - 1 - 1 - 1 - 1 - 1 - 1 - 1 - 1 - 1 - 1 -(10 rows) - --- non-Var items in targetlist of the nullable rel of a join preventing --- push-down in some cases --- unable to push {ft1, ft2} ---Testcase 172: -EXPLAIN (VERBOSE, COSTS OFF) -SELECT q.a, ft2.c1 FROM (SELECT 13 FROM ft1 WHERE c1 = 13) q(a) RIGHT JOIN ft2 ON (q.a = ft2.c1) WHERE ft2.c1 BETWEEN 10 AND 15; - QUERY PLAN ------------------------------------------------------------------------------------------- - Nested Loop Left Join - Output: (13), ft2.c1 - Join Filter: (13 = ft2.c1) - -> Foreign Scan on public.ft2 - Output: ft2.c1 - InfluxDB query: SELECT "C 1" FROM "T1" WHERE (("C 1" >= 10)) AND (("C 1" <= 15)) - -> Materialize - Output: (13) - -> Foreign Scan on public.ft1 - Output: 13 - InfluxDB query: SELECT * FROM "T1" WHERE (("C 1" = 13)) -(11 rows) - ---Testcase 173: -SELECT q.a, ft2.c1 FROM (SELECT 13 FROM ft1 WHERE c1 = 13) q(a) RIGHT JOIN ft2 ON (q.a = ft2.c1) WHERE ft2.c1 BETWEEN 10 AND 15; - a | c1 -----+---- - | 10 - | 11 - | 12 - 13 | 13 - | 14 - | 15 -(6 rows) - --- ok to push {ft1, ft2} but not {ft1, ft2, ft4} ---Testcase 174: -EXPLAIN (VERBOSE, COSTS OFF) -SELECT ft4.c1, q.* FROM ft4 LEFT JOIN (SELECT 13, ft1.c1, ft2.c1 FROM ft1 RIGHT JOIN ft2 ON (ft1.c1 = ft2.c1) WHERE ft1.c1 = 12) q(a, b, c) ON (ft4.c1 = q.b) WHERE ft4.c1 BETWEEN 10 AND 15; - QUERY PLAN ---------------------------------------------------------------------------------------------- - Hash Right Join - Output: ft4.c1, (13), ft1.c1, ft2.c1 - Hash Cond: (ft1.c1 = ft4.c1) - -> Nested Loop - Output: ft1.c1, ft2.c1, 13 - -> Foreign Scan on public.ft1 - Output: ft1.c1 - InfluxDB query: SELECT "C 1" FROM "T1" WHERE (("C 1" = 12)) - -> Materialize - Output: ft2.c1 - -> Foreign Scan on public.ft2 - Output: ft2.c1 - InfluxDB query: SELECT "C 1" FROM "T1" WHERE (("C 1" = 12)) - -> Hash - Output: ft4.c1 - -> Foreign Scan on public.ft4 - Output: ft4.c1 - InfluxDB query: SELECT "c1" FROM "T3" WHERE (("c1" >= 10)) AND (("c1" <= 15)) -(18 rows) - ---Testcase 175: -SELECT ft4.c1, q.* FROM ft4 LEFT JOIN (SELECT 13, ft1.c1, ft2.c1 FROM ft1 RIGHT JOIN ft2 ON (ft1.c1 = ft2.c1) WHERE ft1.c1 = 12) q(a, b, c) ON (ft4.c1 = q.b) WHERE ft4.c1 BETWEEN 10 AND 15 ORDER BY ft4.c1; - c1 | a | b | c -----+----+----+---- - 10 | | | - 12 | 13 | 12 | 12 - 14 | | | -(3 rows) - --- join with nullable side with some columns with null values --- influxdb_fdw does not support UPDATE --- UPDATE ft5 SET c3 = null where c1 % 9 = 0; ---Testcase 176: -EXPLAIN (VERBOSE, COSTS OFF) -SELECT ft5, ft5.c1, ft5.c2, ft5.c3, ft4.c1, ft4.c2 FROM ft5 left join ft4 on ft5.c1 = ft4.c1 WHERE ft4.c1 BETWEEN 10 and 30 ORDER BY ft5.c1, ft4.c1; - QUERY PLAN ---------------------------------------------------------------------------------------------------------- - Sort - Output: ft5.*, ft5.c1, ft5.c2, ft5.c3, ft4.c1, ft4.c2 - Sort Key: ft5.c1 - -> Hash Join - Output: ft5.*, ft5.c1, ft5.c2, ft5.c3, ft4.c1, ft4.c2 - Hash Cond: (ft5.c1 = ft4.c1) - -> Foreign Scan on public.ft5 - Output: ft5.*, ft5.c1, ft5.c2, ft5.c3 - InfluxDB query: SELECT "c1", "c2", "c3" FROM "T4" - -> Hash - Output: ft4.c1, ft4.c2 - -> Foreign Scan on public.ft4 - Output: ft4.c1, ft4.c2 - InfluxDB query: SELECT "c1", "c2" FROM "T3" WHERE (("c1" >= 10)) AND (("c1" <= 30)) -(14 rows) - ---Testcase 177: -SELECT ft5, ft5.c1, ft5.c2, ft5.c3, ft4.c1, ft4.c2 FROM ft5 left join ft4 on ft5.c1 = ft4.c1 WHERE ft4.c1 BETWEEN 10 and 30 ORDER BY ft5.c1, ft4.c1; - ft5 | c1 | c2 | c3 | c1 | c2 -----------------+----+----+--------+----+---- - (12,13,AAA012) | 12 | 13 | AAA012 | 12 | 13 - (18,19,AAA018) | 18 | 19 | AAA018 | 18 | 19 - (24,25,AAA024) | 24 | 25 | AAA024 | 24 | 25 - (30,31,AAA030) | 30 | 31 | AAA030 | 30 | 31 -(4 rows) - --- multi-way join involving multiple merge joins --- (this case used to have EPQ-related planning problems) ---Testcase 178: -CREATE FOREIGN TABLE local_tbl (c1 int NOT NULL, c2 int NOT NULL, c3 text) SERVER influxdb_svr OPTIONS (table 'local_tbl'); ---Testcase 179: -INSERT INTO local_tbl SELECT id, id % 10, to_char(id, 'FM0000') FROM generate_series(1, 1000) id; ---ANALYZE local_tbl; -SET enable_nestloop TO false; -SET enable_hashjoin TO false; ---Testcase 180: -EXPLAIN (VERBOSE, COSTS OFF) -SELECT * FROM ft1, ft2, ft4, ft5, local_tbl WHERE ft1.c1 = ft2.c1 AND ft1.c2 = ft4.c1 - AND ft1.c2 = ft5.c1 AND ft1.c2 = local_tbl.c1 AND ft1.c1 < 100 AND ft2.c1 < 100 ORDER BY ft1.c1 FOR UPDATE; - QUERY PLAN ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- - LockRows - Output: ft1.c1, ft1.c2, ft1.c3, ft1."time", ft1.c6, ft1.c7, ft1.c8, ft2.c1, ft2.c2, ft2.c3, ft2."time", ft2.c6, ft2.c7, ft2.c8, ft4.c1, ft4.c2, ft4.c3, ft5.c1, ft5.c2, ft5.c3, local_tbl.c1, local_tbl.c2, local_tbl.c3, ft1.*, ft2.*, ft4.*, ft5.*, local_tbl.* - -> Sort - Output: ft1.c1, ft1.c2, ft1.c3, ft1."time", ft1.c6, ft1.c7, ft1.c8, ft2.c1, ft2.c2, ft2.c3, ft2."time", ft2.c6, ft2.c7, ft2.c8, ft4.c1, ft4.c2, ft4.c3, ft5.c1, ft5.c2, ft5.c3, local_tbl.c1, local_tbl.c2, local_tbl.c3, ft1.*, ft2.*, ft4.*, ft5.*, local_tbl.* - Sort Key: ft1.c1 - -> Merge Join - Output: ft1.c1, ft1.c2, ft1.c3, ft1."time", ft1.c6, ft1.c7, ft1.c8, ft2.c1, ft2.c2, ft2.c3, ft2."time", ft2.c6, ft2.c7, ft2.c8, ft4.c1, ft4.c2, ft4.c3, ft5.c1, ft5.c2, ft5.c3, local_tbl.c1, local_tbl.c2, local_tbl.c3, ft1.*, ft2.*, ft4.*, ft5.*, local_tbl.* - Merge Cond: (ft1.c2 = local_tbl.c1) - -> Merge Join - Output: ft1.c1, ft1.c2, ft1.c3, ft1."time", ft1.c6, ft1.c7, ft1.c8, ft1.*, ft2.c1, ft2.c2, ft2.c3, ft2."time", ft2.c6, ft2.c7, ft2.c8, ft2.*, ft4.c1, ft4.c2, ft4.c3, ft4.*, ft5.c1, ft5.c2, ft5.c3, ft5.* - Merge Cond: (ft1.c2 = ft5.c1) - -> Merge Join - Output: ft1.c1, ft1.c2, ft1.c3, ft1."time", ft1.c6, ft1.c7, ft1.c8, ft1.*, ft2.c1, ft2.c2, ft2.c3, ft2."time", ft2.c6, ft2.c7, ft2.c8, ft2.*, ft4.c1, ft4.c2, ft4.c3, ft4.* - Merge Cond: (ft1.c2 = ft4.c1) - -> Sort - Output: ft1.c1, ft1.c2, ft1.c3, ft1."time", ft1.c6, ft1.c7, ft1.c8, ft1.*, ft2.c1, ft2.c2, ft2.c3, ft2."time", ft2.c6, ft2.c7, ft2.c8, ft2.* - Sort Key: ft1.c2 - -> Merge Join - Output: ft1.c1, ft1.c2, ft1.c3, ft1."time", ft1.c6, ft1.c7, ft1.c8, ft1.*, ft2.c1, ft2.c2, ft2.c3, ft2."time", ft2.c6, ft2.c7, ft2.c8, ft2.* - Merge Cond: (ft1.c1 = ft2.c1) - -> Sort - Output: ft1.c1, ft1.c2, ft1.c3, ft1."time", ft1.c6, ft1.c7, ft1.c8, ft1.* - Sort Key: ft1.c1 - -> Foreign Scan on public.ft1 - Output: ft1.c1, ft1.c2, ft1.c3, ft1."time", ft1.c6, ft1.c7, ft1.c8, ft1.* - InfluxDB query: SELECT "C 1", "c2", "c3", "c6", "c7", "c8" FROM "T1" WHERE (("C 1" < 100)) - -> Sort - Output: ft2.c1, ft2.c2, ft2.c3, ft2."time", ft2.c6, ft2.c7, ft2.c8, ft2.* - Sort Key: ft2.c1 - -> Foreign Scan on public.ft2 - Output: ft2.c1, ft2.c2, ft2.c3, ft2."time", ft2.c6, ft2.c7, ft2.c8, ft2.* - InfluxDB query: SELECT "C 1", "c2", "c3", "c6", "c7", "c8" FROM "T1" WHERE (("C 1" < 100)) - -> Sort - Output: ft4.c1, ft4.c2, ft4.c3, ft4.* - Sort Key: ft4.c1 - -> Foreign Scan on public.ft4 - Output: ft4.c1, ft4.c2, ft4.c3, ft4.* - InfluxDB query: SELECT "c1", "c2", "c3" FROM "T3" - -> Sort - Output: ft5.c1, ft5.c2, ft5.c3, ft5.* - Sort Key: ft5.c1 - -> Foreign Scan on public.ft5 - Output: ft5.c1, ft5.c2, ft5.c3, ft5.* - InfluxDB query: SELECT "c1", "c2", "c3" FROM "T4" - -> Sort - Output: local_tbl.c1, local_tbl.c2, local_tbl.c3, local_tbl.* - Sort Key: local_tbl.c1 - -> Foreign Scan on public.local_tbl - Output: local_tbl.c1, local_tbl.c2, local_tbl.c3, local_tbl.* - InfluxDB query: SELECT "c1", "c2", "c3" FROM "local_tbl" -(50 rows) - ---Testcase 181: -SELECT * FROM ft1, ft2, ft4, ft5, local_tbl WHERE ft1.c1 = ft2.c1 AND ft1.c2 = ft4.c1 - AND ft1.c2 = ft5.c1 AND ft1.c2 = local_tbl.c1 AND ft1.c1 < 100 AND ft2.c1 < 100 ORDER BY ft1.c1 FOR UPDATE; - c1 | c2 | c3 | time | c6 | c7 | c8 | c1 | c2 | c3 | time | c6 | c7 | c8 | c1 | c2 | c3 | c1 | c2 | c3 | c1 | c2 | c3 -----+----+-------+--------------------------+----+------------+-----+----+----+-------+--------------------------+----+------------+-----+----+----+--------+----+----+--------+----+----+------ - 6 | 6 | 00006 | Wed Jan 07 00:00:00 1970 | 6 | 6 | foo | 6 | 6 | 00006 | Wed Jan 07 00:00:00 1970 | 6 | 6 | foo | 6 | 7 | AAA006 | 6 | 7 | AAA006 | 6 | 6 | 0006 - 16 | 6 | 00016 | Sat Jan 17 00:00:00 1970 | 6 | 6 | foo | 16 | 6 | 00016 | Sat Jan 17 00:00:00 1970 | 6 | 6 | foo | 6 | 7 | AAA006 | 6 | 7 | AAA006 | 6 | 6 | 0006 - 26 | 6 | 00026 | Tue Jan 27 00:00:00 1970 | 6 | 6 | foo | 26 | 6 | 00026 | Tue Jan 27 00:00:00 1970 | 6 | 6 | foo | 6 | 7 | AAA006 | 6 | 7 | AAA006 | 6 | 6 | 0006 - 36 | 6 | 00036 | Fri Feb 06 00:00:00 1970 | 6 | 6 | foo | 36 | 6 | 00036 | Fri Feb 06 00:00:00 1970 | 6 | 6 | foo | 6 | 7 | AAA006 | 6 | 7 | AAA006 | 6 | 6 | 0006 - 46 | 6 | 00046 | Mon Feb 16 00:00:00 1970 | 6 | 6 | foo | 46 | 6 | 00046 | Mon Feb 16 00:00:00 1970 | 6 | 6 | foo | 6 | 7 | AAA006 | 6 | 7 | AAA006 | 6 | 6 | 0006 - 56 | 6 | 00056 | Thu Feb 26 00:00:00 1970 | 6 | 6 | foo | 56 | 6 | 00056 | Thu Feb 26 00:00:00 1970 | 6 | 6 | foo | 6 | 7 | AAA006 | 6 | 7 | AAA006 | 6 | 6 | 0006 - 66 | 6 | 00066 | Sun Mar 08 00:00:00 1970 | 6 | 6 | foo | 66 | 6 | 00066 | Sun Mar 08 00:00:00 1970 | 6 | 6 | foo | 6 | 7 | AAA006 | 6 | 7 | AAA006 | 6 | 6 | 0006 - 76 | 6 | 00076 | Wed Mar 18 00:00:00 1970 | 6 | 6 | foo | 76 | 6 | 00076 | Wed Mar 18 00:00:00 1970 | 6 | 6 | foo | 6 | 7 | AAA006 | 6 | 7 | AAA006 | 6 | 6 | 0006 - 86 | 6 | 00086 | Sat Mar 28 00:00:00 1970 | 6 | 6 | foo | 86 | 6 | 00086 | Sat Mar 28 00:00:00 1970 | 6 | 6 | foo | 6 | 7 | AAA006 | 6 | 7 | AAA006 | 6 | 6 | 0006 - 96 | 6 | 00096 | Tue Apr 07 00:00:00 1970 | 6 | 6 | foo | 96 | 6 | 00096 | Tue Apr 07 00:00:00 1970 | 6 | 6 | foo | 6 | 7 | AAA006 | 6 | 7 | AAA006 | 6 | 6 | 0006 -(10 rows) - -RESET enable_nestloop; -RESET enable_hashjoin; ---Testcase 182: -DELETE FROM local_tbl; -DROP FOREIGN TABLE local_tbl; --- check join pushdown in situations where multiple userids are involved ---Testcase 183: -CREATE ROLE regress_view_owner SUPERUSER; ---Testcase 184: -CREATE USER MAPPING FOR regress_view_owner SERVER influxdb_svr OPTIONS (:AUTHENTICATION); -GRANT SELECT ON ft4 TO regress_view_owner; -GRANT SELECT ON ft5 TO regress_view_owner; ---Testcase 185: -CREATE VIEW v4 AS SELECT * FROM ft4; ---Testcase 186: -CREATE VIEW v5 AS SELECT * FROM ft5; -ALTER VIEW v5 OWNER TO regress_view_owner; ---Testcase 187: -EXPLAIN (VERBOSE, COSTS OFF) -SELECT t1.c1, t2.c2 FROM v4 t1 LEFT JOIN v5 t2 ON (t1.c1 = t2.c1) ORDER BY t1.c1, t2.c1 OFFSET 10 LIMIT 10; -- can't be pushed down, different view owners - QUERY PLAN ------------------------------------------------------------------------ - Limit - Output: ft4.c1, ft5.c2, ft5.c1 - -> Sort - Output: ft4.c1, ft5.c2, ft5.c1 - Sort Key: ft4.c1, ft5.c1 - -> Merge Right Join - Output: ft4.c1, ft5.c2, ft5.c1 - Merge Cond: (ft5.c1 = ft4.c1) - -> Sort - Output: ft5.c2, ft5.c1 - Sort Key: ft5.c1 - -> Foreign Scan on public.ft5 - Output: ft5.c2, ft5.c1 - InfluxDB query: SELECT "c1", "c2" FROM "T4" - -> Sort - Output: ft4.c1 - Sort Key: ft4.c1 - -> Foreign Scan on public.ft4 - Output: ft4.c1 - InfluxDB query: SELECT "c1" FROM "T3" -(20 rows) - ---Testcase 188: -SELECT t1.c1, t2.c2 FROM v4 t1 LEFT JOIN v5 t2 ON (t1.c1 = t2.c1) ORDER BY t1.c1, t2.c1 OFFSET 10 LIMIT 10; - c1 | c2 -----+---- - 22 | - 24 | 25 - 26 | - 28 | - 30 | 31 - 32 | - 34 | - 36 | 37 - 38 | - 40 | -(10 rows) - -ALTER VIEW v4 OWNER TO regress_view_owner; ---Testcase 189: -EXPLAIN (VERBOSE, COSTS OFF) -SELECT t1.c1, t2.c2 FROM v4 t1 LEFT JOIN v5 t2 ON (t1.c1 = t2.c1) ORDER BY t1.c1, t2.c1 OFFSET 10 LIMIT 10; -- can be pushed down - QUERY PLAN ------------------------------------------------------------------------ - Limit - Output: ft4.c1, ft5.c2, ft5.c1 - -> Sort - Output: ft4.c1, ft5.c2, ft5.c1 - Sort Key: ft4.c1, ft5.c1 - -> Merge Right Join - Output: ft4.c1, ft5.c2, ft5.c1 - Merge Cond: (ft5.c1 = ft4.c1) - -> Sort - Output: ft5.c2, ft5.c1 - Sort Key: ft5.c1 - -> Foreign Scan on public.ft5 - Output: ft5.c2, ft5.c1 - InfluxDB query: SELECT "c1", "c2" FROM "T4" - -> Sort - Output: ft4.c1 - Sort Key: ft4.c1 - -> Foreign Scan on public.ft4 - Output: ft4.c1 - InfluxDB query: SELECT "c1" FROM "T3" -(20 rows) - ---Testcase 190: -SELECT t1.c1, t2.c2 FROM v4 t1 LEFT JOIN v5 t2 ON (t1.c1 = t2.c1) ORDER BY t1.c1, t2.c1 OFFSET 10 LIMIT 10; - c1 | c2 -----+---- - 22 | - 24 | 25 - 26 | - 28 | - 30 | 31 - 32 | - 34 | - 36 | 37 - 38 | - 40 | -(10 rows) - ---Testcase 191: -EXPLAIN (VERBOSE, COSTS OFF) -SELECT t1.c1, t2.c2 FROM v4 t1 LEFT JOIN ft5 t2 ON (t1.c1 = t2.c1) ORDER BY t1.c1, t2.c1 OFFSET 10 LIMIT 10; -- can't be pushed down, view owner not current user - QUERY PLAN ------------------------------------------------------------------------ - Limit - Output: ft4.c1, t2.c2, t2.c1 - -> Sort - Output: ft4.c1, t2.c2, t2.c1 - Sort Key: ft4.c1, t2.c1 - -> Merge Right Join - Output: ft4.c1, t2.c2, t2.c1 - Merge Cond: (t2.c1 = ft4.c1) - -> Sort - Output: t2.c2, t2.c1 - Sort Key: t2.c1 - -> Foreign Scan on public.ft5 t2 - Output: t2.c2, t2.c1 - InfluxDB query: SELECT "c1", "c2" FROM "T4" - -> Sort - Output: ft4.c1 - Sort Key: ft4.c1 - -> Foreign Scan on public.ft4 - Output: ft4.c1 - InfluxDB query: SELECT "c1" FROM "T3" -(20 rows) - ---Testcase 192: -SELECT t1.c1, t2.c2 FROM v4 t1 LEFT JOIN ft5 t2 ON (t1.c1 = t2.c1) ORDER BY t1.c1, t2.c1 OFFSET 10 LIMIT 10; - c1 | c2 -----+---- - 22 | - 24 | 25 - 26 | - 28 | - 30 | 31 - 32 | - 34 | - 36 | 37 - 38 | - 40 | -(10 rows) - -ALTER VIEW v4 OWNER TO CURRENT_USER; ---Testcase 193: -EXPLAIN (VERBOSE, COSTS OFF) -SELECT t1.c1, t2.c2 FROM v4 t1 LEFT JOIN ft5 t2 ON (t1.c1 = t2.c1) ORDER BY t1.c1, t2.c1 OFFSET 10 LIMIT 10; -- can be pushed down - QUERY PLAN ------------------------------------------------------------------------ - Limit - Output: ft4.c1, t2.c2, t2.c1 - -> Sort - Output: ft4.c1, t2.c2, t2.c1 - Sort Key: ft4.c1, t2.c1 - -> Merge Right Join - Output: ft4.c1, t2.c2, t2.c1 - Merge Cond: (t2.c1 = ft4.c1) - -> Sort - Output: t2.c2, t2.c1 - Sort Key: t2.c1 - -> Foreign Scan on public.ft5 t2 - Output: t2.c2, t2.c1 - InfluxDB query: SELECT "c1", "c2" FROM "T4" - -> Sort - Output: ft4.c1 - Sort Key: ft4.c1 - -> Foreign Scan on public.ft4 - Output: ft4.c1 - InfluxDB query: SELECT "c1" FROM "T3" -(20 rows) - ---Testcase 194: -SELECT t1.c1, t2.c2 FROM v4 t1 LEFT JOIN ft5 t2 ON (t1.c1 = t2.c1) ORDER BY t1.c1, t2.c1 OFFSET 10 LIMIT 10; - c1 | c2 -----+---- - 22 | - 24 | 25 - 26 | - 28 | - 30 | 31 - 32 | - 34 | - 36 | 37 - 38 | - 40 | -(10 rows) - -ALTER VIEW v4 OWNER TO regress_view_owner; --- cleanup ---Testcase 195: -DROP OWNED BY regress_view_owner; ---Testcase 196: -DROP ROLE regress_view_owner; --- =================================================================== --- Aggregate and grouping queries --- =================================================================== --- Simple aggregates ---Testcase 197: -explain (verbose, costs off) -select count(c6), sum(c1), avg(c1), min(c2), max(c1), stddev(c2), sum(c1) * (random() <= 1)::int as sum2 from ft1 where c2 < 5 group by c2 order by 1, 2; - QUERY PLAN ---------------------------------------------------------------------------------------------------------------------------------------------------- - Result - Output: (count(c6)), (sum(c1)), (avg(c1)), (min(c2)), (max(c1)), (stddev(c2)), ((sum(c1)) * ((random() <= '1'::double precision))::integer), c2 - -> Sort - Output: (count(c6)), (sum(c1)), (avg(c1)), (min(c2)), (max(c1)), (stddev(c2)), c2 - Sort Key: (count(ft1.c6)), (sum(ft1.c1)) - -> HashAggregate - Output: count(c6), sum(c1), avg(c1), min(c2), max(c1), stddev(c2), c2 - Group Key: ft1.c2 - -> Foreign Scan on public.ft1 - Output: c6, c1, c2 - InfluxDB query: SELECT "C 1", "c2", "c6" FROM "T1" WHERE (("c2" < 5)) -(11 rows) - ---Testcase 198: -select count(c6), sum(c1), avg(c1), min(c2), max(c1), stddev(c2), sum(c1) * (random() <= 1)::int as sum2 from ft1 where c2 < 5 group by c2 order by 1, 2; - count | sum | avg | min | max | stddev | sum2 --------+-------+----------------------+-----+------+--------+------- - 100 | 49600 | 496.0000000000000000 | 1 | 991 | 0 | 49600 - 100 | 49700 | 497.0000000000000000 | 2 | 992 | 0 | 49700 - 100 | 49800 | 498.0000000000000000 | 3 | 993 | 0 | 49800 - 100 | 49900 | 499.0000000000000000 | 4 | 994 | 0 | 49900 - 100 | 50500 | 505.0000000000000000 | 0 | 1000 | 0 | 50500 -(5 rows) - ---Testcase 199: -explain (verbose, costs off) -select count(c6), sum(c1), avg(c1), min(c2), max(c1), stddev(c2), sum(c1) * (random() <= 1)::int as sum2 from ft1 where c2 < 5 group by c2 order by 1, 2 limit 1; - QUERY PLAN ---------------------------------------------------------------------------------------------------------------------------------------------------------- - Limit - Output: (count(c6)), (sum(c1)), (avg(c1)), (min(c2)), (max(c1)), (stddev(c2)), (((sum(c1)) * ((random() <= '1'::double precision))::integer)), c2 - -> Result - Output: (count(c6)), (sum(c1)), (avg(c1)), (min(c2)), (max(c1)), (stddev(c2)), ((sum(c1)) * ((random() <= '1'::double precision))::integer), c2 - -> Sort - Output: (count(c6)), (sum(c1)), (avg(c1)), (min(c2)), (max(c1)), (stddev(c2)), c2 - Sort Key: (count(ft1.c6)), (sum(ft1.c1)) - -> HashAggregate - Output: count(c6), sum(c1), avg(c1), min(c2), max(c1), stddev(c2), c2 - Group Key: ft1.c2 - -> Foreign Scan on public.ft1 - Output: c6, c1, c2 - InfluxDB query: SELECT "C 1", "c2", "c6" FROM "T1" WHERE (("c2" < 5)) -(13 rows) - ---Testcase 200: -select count(c6), sum(c1), avg(c1), min(c2), max(c1), stddev(c2), sum(c1) * (random() <= 1)::int as sum2 from ft1 where c2 < 5 group by c2 order by 1, 2 limit 1; - count | sum | avg | min | max | stddev | sum2 --------+-------+----------------------+-----+-----+--------+------- - 100 | 49600 | 496.0000000000000000 | 1 | 991 | 0 | 49600 -(1 row) - --- Aggregate is not pushed down as aggregation contains random() ---Testcase 201: -explain (verbose, costs off) -select sum(c1 * (random() <= 1)::int) as sum, avg(c1) from ft1; - QUERY PLAN -------------------------------------------------------------------------------- - Aggregate - Output: sum((c1 * ((random() <= '1'::double precision))::integer)), avg(c1) - -> Foreign Scan on public.ft1 - Output: c1 - InfluxDB query: SELECT "C 1" FROM "T1" -(5 rows) - --- Aggregate over join query ---Testcase 202: -explain (verbose, costs off) -select count(*), sum(t1.c1), avg(t2.c1) from ft1 t1 inner join ft1 t2 on (t1.c2 = t2.c2) where t1.c2 = 6; - QUERY PLAN -------------------------------------------------------------------------------------- - Aggregate - Output: count(*), sum(t1.c1), avg(t2.c1) - -> Nested Loop - Output: t1.c1, t2.c1 - -> Foreign Scan on public.ft1 t1 - Output: t1.c1, t1.c2 - InfluxDB query: SELECT "C 1", "c2" FROM "T1" WHERE (("c2" = 6)) - -> Materialize - Output: t2.c1, t2.c2 - -> Foreign Scan on public.ft1 t2 - Output: t2.c1, t2.c2 - InfluxDB query: SELECT "C 1", "c2" FROM "T1" WHERE (("c2" = 6)) -(12 rows) - ---Testcase 203: -select count(*), sum(t1.c1), avg(t2.c1) from ft1 t1 inner join ft1 t2 on (t1.c2 = t2.c2) where t1.c2 = 6; - count | sum | avg --------+---------+---------------------- - 10000 | 5010000 | 501.0000000000000000 -(1 row) - --- Not pushed down due to local conditions present in underneath input rel ---Testcase 204: -explain (verbose, costs off) -select sum(t1.c1), count(t2.c1) from ft1 t1 inner join ft2 t2 on (t1.c1 = t2.c1) where ((t1.c1 * t2.c1)/(t1.c1 * t2.c1)) * random() <= 1; - QUERY PLAN ----------------------------------------------------------------------------------------------------------------------- - Aggregate - Output: sum(t1.c1), count(t2.c1) - -> Merge Join - Output: t1.c1, t2.c1 - Merge Cond: (t1.c1 = t2.c1) - Join Filter: (((((t1.c1 * t2.c1) / (t1.c1 * t2.c1)))::double precision * random()) <= '1'::double precision) - -> Sort - Output: t1.c1 - Sort Key: t1.c1 - -> Foreign Scan on public.ft1 t1 - Output: t1.c1 - InfluxDB query: SELECT "C 1" FROM "T1" - -> Sort - Output: t2.c1 - Sort Key: t2.c1 - -> Foreign Scan on public.ft2 t2 - Output: t2.c1 - InfluxDB query: SELECT "C 1" FROM "T1" -(18 rows) - --- GROUP BY clause having expressions ---Testcase 205: -explain (verbose, costs off) -select c2/2, sum(c2) * (c2/2) from ft1 group by c2/2 order by c2/2; - QUERY PLAN ------------------------------------------------------ - Sort - Output: ((c2 / 2)), ((sum(c2) * ((c2 / 2)))) - Sort Key: ((ft1.c2 / 2)) - -> HashAggregate - Output: ((c2 / 2)), (sum(c2) * ((c2 / 2))) - Group Key: (ft1.c2 / 2) - -> Foreign Scan on public.ft1 - Output: (c2 / 2), c2 - InfluxDB query: SELECT "c2" FROM "T1" -(9 rows) - ---Testcase 206: -select c2/2, sum(c2) * (c2/2) from ft1 group by c2/2 order by c2/2; - ?column? | ?column? -----------+---------- - 0 | 0 - 1 | 500 - 2 | 1800 - 3 | 3900 - 4 | 6800 -(5 rows) - --- Aggregates in subquery are pushed down. ---Testcase 207: -explain (verbose, costs off) -select count(x.a), sum(x.a) from (select c2 a, sum(c1) b from ft1 group by c2, sqrt(c1) order by 1, 2) x; - QUERY PLAN -------------------------------------------------------------------------------- - Aggregate - Output: count(ft1.c2), sum(ft1.c2) - -> Sort - Output: ft1.c2, (sum(ft1.c1)), (sqrt((ft1.c1)::double precision)) - Sort Key: ft1.c2, (sum(ft1.c1)) - -> HashAggregate - Output: ft1.c2, sum(ft1.c1), (sqrt((ft1.c1)::double precision)) - Group Key: ft1.c2, sqrt((ft1.c1)::double precision) - -> Foreign Scan on public.ft1 - Output: ft1.c2, sqrt((ft1.c1)::double precision), ft1.c1 - InfluxDB query: SELECT "C 1", "c2" FROM "T1" -(11 rows) - ---Testcase 208: -select count(x.a), sum(x.a) from (select c2 a, sum(c1) b from ft1 group by c2, sqrt(c1) order by 1, 2) x; - count | sum --------+------ - 1000 | 4500 -(1 row) - --- Aggregate is still pushed down by taking unshippable expression out ---Testcase 209: -explain (verbose, costs off) -select c2 * (random() <= 1)::int as sum1, sum(c1) * c2 as sum2 from ft1 group by c2 order by 1, 2; - QUERY PLAN ---------------------------------------------------------------------------------------------------- - Sort - Output: ((c2 * ((random() <= '1'::double precision))::integer)), ((sum(c1) * c2)), c2 - Sort Key: ((ft1.c2 * ((random() <= '1'::double precision))::integer)), ((sum(ft1.c1) * ft1.c2)) - -> HashAggregate - Output: (c2 * ((random() <= '1'::double precision))::integer), (sum(c1) * c2), c2 - Group Key: ft1.c2 - -> Foreign Scan on public.ft1 - Output: c2, c1 - InfluxDB query: SELECT "C 1", "c2" FROM "T1" -(9 rows) - ---Testcase 210: -select c2 * (random() <= 1)::int as sum1, sum(c1) * c2 as sum2 from ft1 group by c2 order by 1, 2; - sum1 | sum2 -------+-------- - 0 | 0 - 1 | 49600 - 2 | 99400 - 3 | 149400 - 4 | 199600 - 5 | 250000 - 6 | 300600 - 7 | 351400 - 8 | 402400 - 9 | 453600 -(10 rows) - --- Aggregate with unshippable GROUP BY clause are not pushed ---Testcase 211: -explain (verbose, costs off) -select c2 * (random() <= 1)::int as c2 from ft2 group by c2 * (random() <= 1)::int order by 1; - QUERY PLAN ------------------------------------------------------------------------------- - Sort - Output: ((c2 * ((random() <= '1'::double precision))::integer)) - Sort Key: ((ft2.c2 * ((random() <= '1'::double precision))::integer)) - -> HashAggregate - Output: ((c2 * ((random() <= '1'::double precision))::integer)) - Group Key: (ft2.c2 * ((random() <= '1'::double precision))::integer) - -> Foreign Scan on public.ft2 - Output: (c2 * ((random() <= '1'::double precision))::integer) - InfluxDB query: SELECT "c2" FROM "T1" -(9 rows) - --- GROUP BY clause in various forms, cardinal, alias and constant expression ---Testcase 212: -explain (verbose, costs off) -select count(c2) w, c2 x, 5 y, 7.0 z from ft1 group by 2, y, 9.0::int order by 2; - QUERY PLAN ------------------------------------------------------ - Sort - Output: (count(c2)), c2, 5, 7.0, 9 - Sort Key: ft1.c2 - -> HashAggregate - Output: count(c2), c2, (5), 7.0, (9) - Group Key: ft1.c2, 5, 9 - -> Foreign Scan on public.ft1 - Output: c2, 5, 9 - InfluxDB query: SELECT "c2" FROM "T1" -(9 rows) - ---Testcase 213: -select count(c2) w, c2 x, 5 y, 7.0 z from ft1 group by 2, y, 9.0::int order by 2; - w | x | y | z ------+---+---+----- - 100 | 0 | 5 | 7.0 - 100 | 1 | 5 | 7.0 - 100 | 2 | 5 | 7.0 - 100 | 3 | 5 | 7.0 - 100 | 4 | 5 | 7.0 - 100 | 5 | 5 | 7.0 - 100 | 6 | 5 | 7.0 - 100 | 7 | 5 | 7.0 - 100 | 8 | 5 | 7.0 - 100 | 9 | 5 | 7.0 -(10 rows) - --- GROUP BY clause referring to same column multiple times --- Also, ORDER BY contains an aggregate function ---Testcase 214: -explain (verbose, costs off) -select c2, c2 from ft1 where c2 > 6 group by 1, 2 order by sum(c1); - QUERY PLAN -------------------------------------------------------------------------------- - Sort - Output: c2, c2, (sum(c1)) - Sort Key: (sum(ft1.c1)) - -> HashAggregate - Output: c2, c2, sum(c1) - Group Key: ft1.c2, ft1.c2 - -> Foreign Scan on public.ft1 - Output: c2, c2, c1 - InfluxDB query: SELECT "C 1", "c2" FROM "T1" WHERE (("c2" > 6)) -(9 rows) - ---Testcase 215: -select c2, c2 from ft1 where c2 > 6 group by 1, 2 order by sum(c1); - c2 | c2 -----+---- - 7 | 7 - 8 | 8 - 9 | 9 -(3 rows) - --- Testing HAVING clause shippability ---Testcase 216: -explain (verbose, costs off) -select c2, sum(c1) from ft2 group by c2 having avg(c1) < 500 and sum(c1) < 49800 order by c2; - QUERY PLAN ----------------------------------------------------------------------------- - Sort - Output: c2, (sum(c1)) - Sort Key: ft2.c2 - -> HashAggregate - Output: c2, sum(c1) - Group Key: ft2.c2 - Filter: ((avg(ft2.c1) < '500'::numeric) AND (sum(ft2.c1) < 49800)) - -> Foreign Scan on public.ft2 - Output: c2, c1 - InfluxDB query: SELECT "C 1", "c2" FROM "T1" -(10 rows) - ---Testcase 217: -select c2, sum(c1) from ft2 group by c2 having avg(c1) < 500 and sum(c1) < 49800 order by c2; - c2 | sum -----+------- - 1 | 49600 - 2 | 49700 -(2 rows) - --- Unshippable HAVING clause will be evaluated locally, and other qual in HAVING clause is pushed down ---Testcase 218: -explain (verbose, costs off) -select count(*) from (select time, count(c1) from ft1 group by time, sqrt(c2) having (avg(c1) / avg(c1)) * random() <= 1 and avg(c1) < 500) x; - QUERY PLAN ----------------------------------------------------------------------------------------------------------------------------------------------- - Aggregate - Output: count(*) - -> HashAggregate - Output: ft1."time", NULL::bigint, (sqrt((ft1.c2)::double precision)) - Group Key: ft1."time", sqrt((ft1.c2)::double precision) - Filter: ((avg(ft1.c1) < '500'::numeric) AND ((((avg(ft1.c1) / avg(ft1.c1)))::double precision * random()) <= '1'::double precision)) - -> Foreign Scan on public.ft1 - Output: ft1."time", sqrt((ft1.c2)::double precision), ft1.c1 - InfluxDB query: SELECT "C 1", "c2" FROM "T1" -(9 rows) - ---Testcase 219: -select count(*) from (select time, count(c1) from ft1 group by time, sqrt(c2) having (avg(c1) / avg(c1)) * random() <= 1 and avg(c1) < 500) x; - count -------- - 49 -(1 row) - --- Aggregate in HAVING clause is not pushable, and thus aggregation is not pushed down ---Testcase 220: -explain (verbose, costs off) -select sum(c1) from ft1 group by c2 having avg(c1 * (random() <= 1)::int) > 100 order by 1; - QUERY PLAN ---------------------------------------------------------------------------------------------------- - Sort - Output: (sum(c1)), c2 - Sort Key: (sum(ft1.c1)) - -> HashAggregate - Output: sum(c1), c2 - Group Key: ft1.c2 - Filter: (avg((ft1.c1 * ((random() <= '1'::double precision))::integer)) > '100'::numeric) - -> Foreign Scan on public.ft1 - Output: c1, c2 - InfluxDB query: SELECT "C 1", "c2" FROM "T1" -(10 rows) - --- Remote aggregate in combination with a local Param (for the output --- of an initplan) can be trouble, per bug #15781 ---Testcase 221: -explain (verbose, costs off) -select exists(select 1 from pg_enum), sum(c1) from ft1; - QUERY PLAN ------------------------------------------------ - Foreign Scan - Output: $0, (sum(ft1.c1)) - InfluxDB query: SELECT sum("C 1") FROM "T1" - InitPlan 1 (returns $0) - -> Seq Scan on pg_catalog.pg_enum -(5 rows) - ---Testcase 222: -select exists(select 1 from pg_enum), sum(c1) from ft1; - exists | sum ---------+-------- - t | 500500 -(1 row) - ---Testcase 223: -explain (verbose, costs off) -select exists(select 1 from pg_enum), sum(c1) from ft1 group by 1; - QUERY PLAN ------------------------------------------------- - GroupAggregate - Output: ($0), sum(ft1.c1) - Group Key: $0 - InitPlan 1 (returns $0) - -> Seq Scan on pg_catalog.pg_enum - -> Foreign Scan on public.ft1 - Output: $0, ft1.c1 - InfluxDB query: SELECT "C 1" FROM "T1" -(8 rows) - ---Testcase 224: -select exists(select 1 from pg_enum), sum(c1) from ft1 group by 1; - exists | sum ---------+-------- - t | 500500 -(1 row) - --- Testing ORDER BY, DISTINCT, FILTER, Ordered-sets and VARIADIC within aggregates --- ORDER BY within aggregate, same column used to order ---Testcase 225: -explain (verbose, costs off) -select array_agg(c1 order by c1) from ft1 where c1 < 100 group by c2 order by 1; - QUERY PLAN ----------------------------------------------------------------------------------------- - Sort - Output: (array_agg(c1 ORDER BY c1)), c2 - Sort Key: (array_agg(ft1.c1 ORDER BY ft1.c1)) - -> GroupAggregate - Output: array_agg(c1 ORDER BY c1), c2 - Group Key: ft1.c2 - -> Sort - Output: c2, c1 - Sort Key: ft1.c2 - -> Foreign Scan on public.ft1 - Output: c2, c1 - InfluxDB query: SELECT "C 1", "c2" FROM "T1" WHERE (("C 1" < 100)) -(12 rows) - ---Testcase 226: -select array_agg(c1 order by c1) from ft1 where c1 < 100 group by c2 order by 1; - array_agg --------------------------------- - {1,11,21,31,41,51,61,71,81,91} - {2,12,22,32,42,52,62,72,82,92} - {3,13,23,33,43,53,63,73,83,93} - {4,14,24,34,44,54,64,74,84,94} - {5,15,25,35,45,55,65,75,85,95} - {6,16,26,36,46,56,66,76,86,96} - {7,17,27,37,47,57,67,77,87,97} - {8,18,28,38,48,58,68,78,88,98} - {9,19,29,39,49,59,69,79,89,99} - {10,20,30,40,50,60,70,80,90} -(10 rows) - --- ORDER BY within aggregate, different column used to order also using DESC ---Testcase 227: -explain (verbose, costs off) -select array_agg(time order by c1 desc) from ft2 where c2 = 6 and c1 < 50; - QUERY PLAN --------------------------------------------------------------------------------------- - Aggregate - Output: array_agg("time" ORDER BY c1 DESC) - -> Foreign Scan on public.ft2 - Output: "time", c1 - InfluxDB query: SELECT "C 1" FROM "T1" WHERE (("C 1" < 50)) AND (("c2" = 6)) -(5 rows) - ---Testcase 228: -select array_agg(time order by c1 desc) from ft2 where c2 = 6 and c1 < 50; - array_agg ------------------------------------------------------------------------------------------------------------------------------------------- - {"Mon Feb 16 00:00:00 1970","Fri Feb 06 00:00:00 1970","Tue Jan 27 00:00:00 1970","Sat Jan 17 00:00:00 1970","Wed Jan 07 00:00:00 1970"} -(1 row) - --- DISTINCT within aggregate ---Testcase 229: -explain (verbose, costs off) -select array_agg(distinct (t1.c1)%5) from ft4 t1 full join ft5 t2 on (t1.c1 = t2.c1) where t1.c1 < 20 or (t1.c1 is null and t2.c1 < 5) group by (t2.c1)%3 order by 1; - QUERY PLAN ---------------------------------------------------------------------------------- - Sort - Output: (array_agg(DISTINCT (t1.c1 % 5))), ((t2.c1 % 3)) - Sort Key: (array_agg(DISTINCT (t1.c1 % 5))) - -> GroupAggregate - Output: array_agg(DISTINCT (t1.c1 % 5)), ((t2.c1 % 3)) - Group Key: ((t2.c1 % 3)) - -> Sort - Output: ((t2.c1 % 3)), t1.c1 - Sort Key: ((t2.c1 % 3)) - -> Merge Full Join - Output: (t2.c1 % 3), t1.c1 - Merge Cond: (t1.c1 = t2.c1) - Filter: ((t1.c1 < 20) OR ((t1.c1 IS NULL) AND (t2.c1 < 5))) - -> Sort - Output: t1.c1 - Sort Key: t1.c1 - -> Foreign Scan on public.ft4 t1 - Output: t1.c1 - InfluxDB query: SELECT "c1" FROM "T3" - -> Sort - Output: t2.c1 - Sort Key: t2.c1 - -> Foreign Scan on public.ft5 t2 - Output: t2.c1 - InfluxDB query: SELECT "c1" FROM "T4" -(25 rows) - ---Testcase 230: -select array_agg(distinct (t1.c1)%5) from ft4 t1 full join ft5 t2 on (t1.c1 = t2.c1) where t1.c1 < 20 or (t1.c1 is null and t2.c1 < 5) group by (t2.c1)%3 order by 1; - array_agg --------------- - {0,1,2,3,4} - {1,2,3,NULL} -(2 rows) - --- DISTINCT combined with ORDER BY within aggregate ---Testcase 231: -explain (verbose, costs off) -select array_agg(distinct (t1.c1)%5 order by (t1.c1)%5) from ft4 t1 full join ft5 t2 on (t1.c1 = t2.c1) where t1.c1 < 20 or (t1.c1 is null and t2.c1 < 5) group by (t2.c1)%3 order by 1; - QUERY PLAN -------------------------------------------------------------------------------------- - Sort - Output: (array_agg(DISTINCT (t1.c1 % 5) ORDER BY (t1.c1 % 5))), ((t2.c1 % 3)) - Sort Key: (array_agg(DISTINCT (t1.c1 % 5) ORDER BY (t1.c1 % 5))) - -> GroupAggregate - Output: array_agg(DISTINCT (t1.c1 % 5) ORDER BY (t1.c1 % 5)), ((t2.c1 % 3)) - Group Key: ((t2.c1 % 3)) - -> Sort - Output: ((t2.c1 % 3)), t1.c1 - Sort Key: ((t2.c1 % 3)) - -> Merge Full Join - Output: (t2.c1 % 3), t1.c1 - Merge Cond: (t1.c1 = t2.c1) - Filter: ((t1.c1 < 20) OR ((t1.c1 IS NULL) AND (t2.c1 < 5))) - -> Sort - Output: t1.c1 - Sort Key: t1.c1 - -> Foreign Scan on public.ft4 t1 - Output: t1.c1 - InfluxDB query: SELECT "c1" FROM "T3" - -> Sort - Output: t2.c1 - Sort Key: t2.c1 - -> Foreign Scan on public.ft5 t2 - Output: t2.c1 - InfluxDB query: SELECT "c1" FROM "T4" -(25 rows) - ---Testcase 232: -select array_agg(distinct (t1.c1)%5 order by (t1.c1)%5) from ft4 t1 full join ft5 t2 on (t1.c1 = t2.c1) where t1.c1 < 20 or (t1.c1 is null and t2.c1 < 5) group by (t2.c1)%3 order by 1; - array_agg --------------- - {0,1,2,3,4} - {1,2,3,NULL} -(2 rows) - ---Testcase 233: -explain (verbose, costs off) -select array_agg(distinct (t1.c1)%5 order by (t1.c1)%5 desc nulls last) from ft4 t1 full join ft5 t2 on (t1.c1 = t2.c1) where t1.c1 < 20 or (t1.c1 is null and t2.c1 < 5) group by (t2.c1)%3 order by 1; - QUERY PLAN ------------------------------------------------------------------------------------------------------ - Sort - Output: (array_agg(DISTINCT (t1.c1 % 5) ORDER BY (t1.c1 % 5) DESC NULLS LAST)), ((t2.c1 % 3)) - Sort Key: (array_agg(DISTINCT (t1.c1 % 5) ORDER BY (t1.c1 % 5) DESC NULLS LAST)) - -> GroupAggregate - Output: array_agg(DISTINCT (t1.c1 % 5) ORDER BY (t1.c1 % 5) DESC NULLS LAST), ((t2.c1 % 3)) - Group Key: ((t2.c1 % 3)) - -> Sort - Output: ((t2.c1 % 3)), t1.c1 - Sort Key: ((t2.c1 % 3)) - -> Merge Full Join - Output: (t2.c1 % 3), t1.c1 - Merge Cond: (t1.c1 = t2.c1) - Filter: ((t1.c1 < 20) OR ((t1.c1 IS NULL) AND (t2.c1 < 5))) - -> Sort - Output: t1.c1 - Sort Key: t1.c1 - -> Foreign Scan on public.ft4 t1 - Output: t1.c1 - InfluxDB query: SELECT "c1" FROM "T3" - -> Sort - Output: t2.c1 - Sort Key: t2.c1 - -> Foreign Scan on public.ft5 t2 - Output: t2.c1 - InfluxDB query: SELECT "c1" FROM "T4" -(25 rows) - ---Testcase 234: -select array_agg(distinct (t1.c1)%5 order by (t1.c1)%5 desc nulls last) from ft4 t1 full join ft5 t2 on (t1.c1 = t2.c1) where t1.c1 < 20 or (t1.c1 is null and t2.c1 < 5) group by (t2.c1)%3 order by 1; - array_agg --------------- - {3,2,1,NULL} - {4,3,2,1,0} -(2 rows) - --- FILTER within aggregate ---Testcase 235: -explain (verbose, costs off) -select sum(c1) filter (where c1 < 100 and c2 > 5) from ft1 group by c2 order by 1 nulls last; - QUERY PLAN ----------------------------------------------------------------------------- - Sort - Output: (sum(c1) FILTER (WHERE ((c1 < 100) AND (c2 > 5)))), c2 - Sort Key: (sum(ft1.c1) FILTER (WHERE ((ft1.c1 < 100) AND (ft1.c2 > 5)))) - -> HashAggregate - Output: sum(c1) FILTER (WHERE ((c1 < 100) AND (c2 > 5))), c2 - Group Key: ft1.c2 - -> Foreign Scan on public.ft1 - Output: c1, c2 - InfluxDB query: SELECT "C 1", "c2" FROM "T1" -(9 rows) - ---Testcase 236: -select sum(c1) filter (where c1 < 100 and c2 > 5) from ft1 group by c2 order by 1 nulls last; - sum ------ - 510 - 520 - 530 - 540 - - - - - - -(10 rows) - --- DISTINCT, ORDER BY and FILTER within aggregate ---Testcase 237: -explain (verbose, costs off) -select sum(c1%3), sum(distinct c1%3 order by c1%3) filter (where c1%3 < 2), c2 from ft1 where c2 = 6 group by c2; - QUERY PLAN ------------------------------------------------------------------------------------------------------ - GroupAggregate - Output: sum((c1 % 3)), sum(DISTINCT (c1 % 3) ORDER BY (c1 % 3)) FILTER (WHERE ((c1 % 3) < 2)), c2 - Group Key: ft1.c2 - -> Foreign Scan on public.ft1 - Output: c1, c2 - InfluxDB query: SELECT "C 1", "c2" FROM "T1" WHERE (("c2" = 6)) -(6 rows) - ---Testcase 238: -select sum(c1%3), sum(distinct c1%3 order by c1%3) filter (where c1%3 < 2), c2 from ft1 where c2 = 6 group by c2; - sum | sum | c2 ------+-----+---- - 99 | 1 | 6 -(1 row) - --- Outer query is aggregation query ---Testcase 239: -explain (verbose, costs off) -select distinct (select count(*) filter (where t2.c2 = 6 and t2.c1 < 10) from ft1 t1 where t1.c1 = 6) from ft2 t2 where t2.c2 % 6 = 0 order by 1; - QUERY PLAN -------------------------------------------------------------------------------------------- - Unique - Output: ((SubPlan 1)) - -> Sort - Output: ((SubPlan 1)) - Sort Key: ((SubPlan 1)) - -> Aggregate - Output: (SubPlan 1) - -> Foreign Scan on public.ft2 t2 - Output: t2.c2, t2.c1 - InfluxDB query: SELECT "C 1", "c2" FROM "T1" WHERE ((("c2" % 6) = 0)) - SubPlan 1 - -> Foreign Scan on public.ft1 t1 - Output: count(*) FILTER (WHERE ((t2.c2 = 6) AND (t2.c1 < 10))) - InfluxDB query: SELECT * FROM "T1" WHERE (("C 1" = 6)) -(14 rows) - ---Testcase 240: -select distinct (select count(*) filter (where t2.c2 = 6 and t2.c1 < 10) from ft1 t1 where t1.c1 = 6) from ft2 t2 where t2.c2 % 6 = 0 order by 1; - count -------- - 1 -(1 row) - --- Inner query is aggregation query ---Testcase 241: -explain (verbose, costs off) -select distinct (select count(t1.c1) filter (where t2.c2 = 6 and t2.c1 < 10) from ft1 t1 where t1.c1 = 6) from ft2 t2 where t2.c2 % 6 = 0 order by 1; - QUERY PLAN ------------------------------------------------------------------------------------------- - Unique - Output: ((SubPlan 1)) - -> Sort - Output: ((SubPlan 1)) - Sort Key: ((SubPlan 1)) - -> Foreign Scan on public.ft2 t2 - Output: (SubPlan 1) - InfluxDB query: SELECT "C 1", "c2" FROM "T1" WHERE ((("c2" % 6) = 0)) - SubPlan 1 - -> Aggregate - Output: count(t1.c1) FILTER (WHERE ((t2.c2 = 6) AND (t2.c1 < 10))) - -> Foreign Scan on public.ft1 t1 - Output: t1.c1 - InfluxDB query: SELECT "C 1" FROM "T1" WHERE (("C 1" = 6)) -(14 rows) - ---Testcase 242: -select distinct (select count(t1.c1) filter (where t2.c2 = 6 and t2.c1 < 10) from ft1 t1 where t1.c1 = 6) from ft2 t2 where t2.c2 % 6 = 0 order by 1; - count -------- - 0 - 1 -(2 rows) - --- Aggregate not pushed down as FILTER condition is not pushable ---Testcase 243: -explain (verbose, costs off) -select sum(c1) filter (where (c1 / c1) * random() <= 1) from ft1 group by c2 order by 1; - QUERY PLAN ------------------------------------------------------------------------------------------------------------------------- - Sort - Output: (sum(c1) FILTER (WHERE ((((c1 / c1))::double precision * random()) <= '1'::double precision))), c2 - Sort Key: (sum(ft1.c1) FILTER (WHERE ((((ft1.c1 / ft1.c1))::double precision * random()) <= '1'::double precision))) - -> HashAggregate - Output: sum(c1) FILTER (WHERE ((((c1 / c1))::double precision * random()) <= '1'::double precision)), c2 - Group Key: ft1.c2 - -> Foreign Scan on public.ft1 - Output: c1, c2 - InfluxDB query: SELECT "C 1", "c2" FROM "T1" -(9 rows) - ---Testcase 244: -explain (verbose, costs off) -select sum(c2) filter (where c2 in (select c2 from ft1 where c2 < 5)) from ft1; - QUERY PLAN --------------------------------------------------------------------- - Aggregate - Output: sum(ft1.c2) FILTER (WHERE (hashed SubPlan 1)) - -> Foreign Scan on public.ft1 - Output: ft1.c2 - InfluxDB query: SELECT "c2" FROM "T1" - SubPlan 1 - -> Foreign Scan on public.ft1 ft1_1 - Output: ft1_1.c2 - InfluxDB query: SELECT "c2" FROM "T1" WHERE (("c2" < 5)) -(9 rows) - --- Ordered-sets within aggregate ---Testcase 245: -explain (verbose, costs off) -select c2, rank('10'::varchar) within group (order by c6), percentile_cont(c2/10::numeric) within group (order by c1) from ft1 where c2 < 10 group by c2 having percentile_cont(c2/10::numeric) within group (order by c1) < 500 order by c2; - QUERY PLAN ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ - GroupAggregate - Output: c2, rank('10'::character varying) WITHIN GROUP (ORDER BY c6), percentile_cont((((c2)::numeric / '10'::numeric))::double precision) WITHIN GROUP (ORDER BY ((c1)::double precision)) - Group Key: ft1.c2 - Filter: (percentile_cont((((ft1.c2)::numeric / '10'::numeric))::double precision) WITHIN GROUP (ORDER BY ((ft1.c1)::double precision)) < '500'::double precision) - -> Sort - Output: c2, c6, c1 - Sort Key: ft1.c2 - -> Foreign Scan on public.ft1 - Output: c2, c6, c1 - InfluxDB query: SELECT "C 1", "c2", "c6" FROM "T1" WHERE (("c2" < 10)) -(10 rows) - ---Testcase 246: -select c2, rank('10'::varchar) within group (order by c6), percentile_cont(c2/10::numeric) within group (order by c1) from ft1 where c2 < 10 group by c2 having percentile_cont(c2/10::numeric) within group (order by c1) < 500 order by c2; - c2 | rank | percentile_cont -----+------+----------------- - 0 | 101 | 10 - 1 | 101 | 100 - 2 | 1 | 200 - 3 | 1 | 300 - 4 | 1 | 400 -(5 rows) - --- Using multiple arguments within aggregates ---Testcase 247: -explain (verbose, costs off) -select c1, rank(c1, c2) within group (order by c1, c2) from ft1 group by c1, c2 having c1 = 6 order by 1; - QUERY PLAN --------------------------------------------------------------------------------- - GroupAggregate - Output: c1, rank(c1, c2) WITHIN GROUP (ORDER BY c1, c2), c2 - Group Key: ft1.c1, ft1.c2 - -> Sort - Output: c1, c2 - Sort Key: ft1.c2 - -> Foreign Scan on public.ft1 - Output: c1, c2 - InfluxDB query: SELECT "C 1", "c2" FROM "T1" WHERE (("C 1" = 6)) -(9 rows) - ---Testcase 248: -select c1, rank(c1, c2) within group (order by c1, c2) from ft1 group by c1, c2 having c1 = 6 order by 1; - c1 | rank -----+------ - 6 | 1 -(1 row) - --- User defined function for user defined aggregate, VARIADIC ---Testcase 249: -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)'; ---Testcase 250: -create aggregate least_agg(variadic items anyarray) ( - stype = anyelement, sfunc = least_accum -); --- Disable hash aggregation for plan stability. -set enable_hashagg to false; --- Not pushed down due to user defined aggregate ---Testcase 251: -explain (verbose, costs off) -select c2, least_agg(c1) from ft1 group by c2 order by c2; - QUERY PLAN ------------------------------------------------------------- - GroupAggregate - Output: c2, least_agg(VARIADIC ARRAY[c1]) - Group Key: ft1.c2 - -> Sort - Output: c2, c1 - Sort Key: ft1.c2 - -> Foreign Scan on public.ft1 - Output: c2, c1 - InfluxDB query: SELECT "C 1", "c2" FROM "T1" -(9 rows) - --- Add function and aggregate into extension -alter extension influxdb_fdw add function least_accum(anyelement, variadic anyarray); -alter extension influxdb_fdw add aggregate least_agg(variadic items anyarray); --- Now aggregate will be pushed. Aggregate will display VARIADIC argument. ---Testcase 252: -explain (verbose, costs off) -select c2, least_agg(c1) from ft1 where c2 < 100 group by c2 order by c2; - QUERY PLAN ---------------------------------------------------------------------------------- - GroupAggregate - Output: c2, least_agg(VARIADIC ARRAY[c1]) - Group Key: ft1.c2 - -> Sort - Output: c2, c1 - Sort Key: ft1.c2 - -> Foreign Scan on public.ft1 - Output: c2, c1 - InfluxDB query: SELECT "C 1", "c2" FROM "T1" WHERE (("c2" < 100)) -(9 rows) - ---Testcase 253: -select c2, least_agg(c1) from ft1 where c2 < 100 group by c2 order by c2; - c2 | least_agg -----+----------- - 0 | 10 - 1 | 1 - 2 | 2 - 3 | 3 - 4 | 4 - 5 | 5 - 6 | 6 - 7 | 7 - 8 | 8 - 9 | 9 -(10 rows) - --- Remove function and aggregate from extension -alter extension influxdb_fdw drop function least_accum(anyelement, variadic anyarray); -alter extension influxdb_fdw drop aggregate least_agg(variadic items anyarray); --- Not pushed down as we have dropped objects from extension. ---Testcase 254: -explain (verbose, costs off) -select c2, least_agg(c1) from ft1 group by c2 order by c2; - QUERY PLAN ------------------------------------------------------------- - GroupAggregate - Output: c2, least_agg(VARIADIC ARRAY[c1]) - Group Key: ft1.c2 - -> Sort - Output: c2, c1 - Sort Key: ft1.c2 - -> Foreign Scan on public.ft1 - Output: c2, c1 - InfluxDB query: SELECT "C 1", "c2" FROM "T1" -(9 rows) - --- Cleanup -reset enable_hashagg; ---Testcase 255: -drop aggregate least_agg(variadic items anyarray); ---Testcase 256: -drop function least_accum(anyelement, variadic anyarray); --- Testing USING OPERATOR() in ORDER BY within aggregate. --- For this, we need user defined operators along with operator family and --- operator class. Create those and then add them in extension. Note that --- user defined objects are considered unshippable unless they are part of --- the extension. ---Testcase 257: -create operator public.<^ ( - leftarg = int4, - rightarg = int4, - procedure = int4eq -); ---Testcase 258: -create operator public.=^ ( - leftarg = int4, - rightarg = int4, - procedure = int4lt -); ---Testcase 259: -create operator public.>^ ( - leftarg = int4, - rightarg = int4, - procedure = int4gt -); ---Testcase 260: -create operator family my_op_family using btree; ---Testcase 261: -create function my_op_cmp(a int, b int) returns int as - $$begin return btint4cmp(a, b); end $$ language plpgsql; ---Testcase 262: -create operator class my_op_class for type int using btree family my_op_family as - operator 1 public.<^, - operator 3 public.=^, - operator 5 public.>^, - function 1 my_op_cmp(int, int); --- This will not be pushed as user defined sort operator is not part of the --- extension yet. ---Testcase 263: -explain (verbose, costs off) -select array_agg(c1 order by c1 using operator(public.<^)) from ft2 where c2 = 6 and c1 < 100 group by c2; - QUERY PLAN ---------------------------------------------------------------------------------------------- - GroupAggregate - Output: array_agg(c1 ORDER BY c1 USING <^ NULLS LAST), c2 - Group Key: ft2.c2 - -> Foreign Scan on public.ft2 - Output: c1, c2 - InfluxDB query: SELECT "C 1", "c2" FROM "T1" WHERE (("C 1" < 100)) AND (("c2" = 6)) -(6 rows) - --- Update local stats on ft2 ---ANALYZE ft2; --- Add into extension -alter extension influxdb_fdw add operator class my_op_class using btree; -alter extension influxdb_fdw add function my_op_cmp(a int, b int); -alter extension influxdb_fdw add operator family my_op_family using btree; -alter extension influxdb_fdw add operator public.<^(int, int); -alter extension influxdb_fdw add operator public.=^(int, int); -alter extension influxdb_fdw add operator public.>^(int, int); --- Now this will be pushed as sort operator is part of the extension. ---Testcase 264: -explain (verbose, costs off) -select array_agg(c1 order by c1 using operator(public.<^)) from ft2 where c2 = 6 and c1 < 100 group by c2; - QUERY PLAN ---------------------------------------------------------------------------------------------- - GroupAggregate - Output: array_agg(c1 ORDER BY c1 USING <^ NULLS LAST), c2 - Group Key: ft2.c2 - -> Foreign Scan on public.ft2 - Output: c1, c2 - InfluxDB query: SELECT "C 1", "c2" FROM "T1" WHERE (("C 1" < 100)) AND (("c2" = 6)) -(6 rows) - ---Testcase 265: -select array_agg(c1 order by c1 using operator(public.<^)) from ft2 where c2 = 6 and c1 < 100 group by c2; - array_agg --------------------------------- - {6,16,26,36,46,56,66,76,86,96} -(1 row) - --- Remove from extension -alter extension influxdb_fdw drop operator class my_op_class using btree; -alter extension influxdb_fdw drop function my_op_cmp(a int, b int); -alter extension influxdb_fdw drop operator family my_op_family using btree; -alter extension influxdb_fdw drop operator public.<^(int, int); -alter extension influxdb_fdw drop operator public.=^(int, int); -alter extension influxdb_fdw drop operator public.>^(int, int); --- This will not be pushed as sort operator is now removed from the extension. ---Testcase 266: -explain (verbose, costs off) -select array_agg(c1 order by c1 using operator(public.<^)) from ft2 where c2 = 6 and c1 < 100 group by c2; - QUERY PLAN ---------------------------------------------------------------------------------------------- - GroupAggregate - Output: array_agg(c1 ORDER BY c1 USING <^ NULLS LAST), c2 - Group Key: ft2.c2 - -> Foreign Scan on public.ft2 - Output: c1, c2 - InfluxDB query: SELECT "C 1", "c2" FROM "T1" WHERE (("C 1" < 100)) AND (("c2" = 6)) -(6 rows) - --- Cleanup ---Testcase 267: -drop operator class my_op_class using btree; ---Testcase 268: -drop function my_op_cmp(a int, b int); ---Testcase 269: -drop operator family my_op_family using btree; ---Testcase 270: -drop operator public.>^(int, int); ---Testcase 271: -drop operator public.=^(int, int); ---Testcase 272: -drop operator public.<^(int, int); --- Input relation to aggregate push down hook is not safe to pushdown and thus --- the aggregate cannot be pushed down to foreign server. ---Testcase 273: -explain (verbose, costs off) -select count(t1.c3) from ft2 t1 left join ft2 t2 on (t1.c1 = random() * t2.c2); - QUERY PLAN -------------------------------------------------------------------------------------------- - Aggregate - Output: count(t1.c3) - -> Nested Loop Left Join - Output: t1.c3 - Join Filter: ((t1.c1)::double precision = (random() * (t2.c2)::double precision)) - -> Foreign Scan on public.ft2 t1 - Output: t1.c3, t1.c1 - InfluxDB query: SELECT "C 1", "c3" FROM "T1" - -> Materialize - Output: t2.c2 - -> Foreign Scan on public.ft2 t2 - Output: t2.c2 - InfluxDB query: SELECT "c2" FROM "T1" -(13 rows) - --- Subquery in FROM clause having aggregate ---Testcase 274: -explain (verbose, costs off) -select count(*), x.b from ft1, (select c2 a, sum(c1) b from ft1 group by c2) x where ft1.c2 = x.a group by x.b order by 1, 2; - QUERY PLAN ------------------------------------------------------------------------------------- - Sort - Output: (count(*)), x.b - Sort Key: (count(*)), x.b - -> HashAggregate - Output: count(*), x.b - Group Key: x.b - -> Hash Join - Output: x.b - Inner Unique: true - Hash Cond: (ft1.c2 = x.a) - -> Foreign Scan on public.ft1 - Output: ft1.c2 - InfluxDB query: SELECT "c2" FROM "T1" - -> Hash - Output: x.b, x.a - -> Subquery Scan on x - Output: x.b, x.a - -> HashAggregate - Output: ft1_1.c2, sum(ft1_1.c1) - Group Key: ft1_1.c2 - -> Foreign Scan on public.ft1 ft1_1 - Output: ft1_1.c2, ft1_1.c1 - InfluxDB query: SELECT "C 1", "c2" FROM "T1" -(23 rows) - ---Testcase 275: -select count(*), x.b from ft1, (select c2 a, sum(c1) b from ft1 group by c2) x where ft1.c2 = x.a group by x.b order by 1, 2; - count | b --------+------- - 100 | 49600 - 100 | 49700 - 100 | 49800 - 100 | 49900 - 100 | 50000 - 100 | 50100 - 100 | 50200 - 100 | 50300 - 100 | 50400 - 100 | 50500 -(10 rows) - --- FULL join with IS NULL check in HAVING ---Testcase 276: -explain (verbose, costs off) -select avg(t1.c1), sum(t2.c1) from ft4 t1 full join ft5 t2 on (t1.c1 = t2.c1) group by t2.c1 having (avg(t1.c1) is null and sum(t2.c1) < 10) or sum(t2.c1) is null order by 1 nulls last, 2; - QUERY PLAN ----------------------------------------------------------------------------------------- - Sort - Output: (avg(t1.c1)), (sum(t2.c1)), t2.c1 - Sort Key: (avg(t1.c1)), (sum(t2.c1)) - -> HashAggregate - Output: avg(t1.c1), sum(t2.c1), t2.c1 - Group Key: t2.c1 - Filter: (((avg(t1.c1) IS NULL) AND (sum(t2.c1) < 10)) OR (sum(t2.c1) IS NULL)) - -> Merge Full Join - Output: t2.c1, t1.c1 - Merge Cond: (t1.c1 = t2.c1) - -> Sort - Output: t1.c1 - Sort Key: t1.c1 - -> Foreign Scan on public.ft4 t1 - Output: t1.c1 - InfluxDB query: SELECT "c1" FROM "T3" - -> Sort - Output: t2.c1 - Sort Key: t2.c1 - -> Foreign Scan on public.ft5 t2 - Output: t2.c1 - InfluxDB query: SELECT "c1" FROM "T4" -(22 rows) - ---Testcase 277: -select avg(t1.c1), sum(t2.c1) from ft4 t1 full join ft5 t2 on (t1.c1 = t2.c1) group by t2.c1 having (avg(t1.c1) is null and sum(t2.c1) < 10) or sum(t2.c1) is null order by 1 nulls last, 2; - avg | sum ----------------------+----- - 51.0000000000000000 | - | 3 - | 9 -(3 rows) - --- Aggregate over FULL join needing to deparse the joining relations as --- subqueries. ---Testcase 278: -explain (verbose, costs off) -select count(*), sum(t1.c1), avg(t2.c1) from (select c1 from ft4 where c1 between 50 and 60) t1 full join (select c1 from ft5 where c1 between 50 and 60) t2 on (t1.c1 = t2.c1); - QUERY PLAN ---------------------------------------------------------------------------------------------------- - Aggregate - Output: count(*), sum(ft4.c1), avg(ft5.c1) - -> Hash Full Join - Output: ft4.c1, ft5.c1 - Hash Cond: (ft4.c1 = ft5.c1) - -> Foreign Scan on public.ft4 - Output: ft4.c1, ft4.c2, ft4.c3 - InfluxDB query: SELECT "c1" FROM "T3" WHERE (("c1" >= 50)) AND (("c1" <= 60)) - -> Hash - Output: ft5.c1 - -> Foreign Scan on public.ft5 - Output: ft5.c1 - InfluxDB query: SELECT "c1" FROM "T4" WHERE (("c1" >= 50)) AND (("c1" <= 60)) -(13 rows) - ---Testcase 279: -select count(*), sum(t1.c1), avg(t2.c1) from (select c1 from ft4 where c1 between 50 and 60) t1 full join (select c1 from ft5 where c1 between 50 and 60) t2 on (t1.c1 = t2.c1); - count | sum | avg --------+-----+--------------------- - 8 | 330 | 55.5000000000000000 -(1 row) - --- ORDER BY expression is part of the target list but not pushed down to --- foreign server. ---Testcase 280: -explain (verbose, costs off) -select sum(c2) * (random() <= 1)::int as sum from ft1 order by 1; - QUERY PLAN --------------------------------------------------------------------------------- - Sort - Output: (((sum(c2)) * ((random() <= '1'::double precision))::integer)) - Sort Key: (((sum(ft1.c2)) * ((random() <= '1'::double precision))::integer)) - -> Foreign Scan - Output: ((sum(c2)) * ((random() <= '1'::double precision))::integer) - InfluxDB query: SELECT sum("c2") FROM "T1" -(6 rows) - ---Testcase 281: -select sum(c2) * (random() <= 1)::int as sum from ft1 order by 1; - sum ------- - 4500 -(1 row) - --- LATERAL join, with parameterization -set enable_hashagg to false; ---Testcase 282: -explain (verbose, costs off) -select c2, sum from "S 1"."T 1" t1, lateral (select sum(t2.c1 + t1."C 1") sum from ft2 t2 group by t2.c1) qry where t1.c2 * 2 = qry.sum and t1.c2 < 3 and t1."C 1" < 100 order by 1; - QUERY PLAN ---------------------------------------------------------------------------------------------------- - Sort - Output: t1.c2, qry.sum - Sort Key: t1.c2 - -> Nested Loop - Output: t1.c2, qry.sum - -> Foreign Scan on "S 1"."T 1" t1 - Output: t1."C 1", t1.c2, t1.c3, t1."time", t1.c6, t1.c7, t1.c8 - InfluxDB query: SELECT "C 1", "c2" FROM "T1" WHERE (("c2" < 3)) AND (("C 1" < 100)) - -> Subquery Scan on qry - Output: qry.sum, t2.c1 - Filter: ((t1.c2 * 2) = qry.sum) - -> GroupAggregate - Output: sum((t2.c1 + t1."C 1")), t2.c1 - Group Key: t2.c1 - -> Sort - Output: t2.c1 - Sort Key: t2.c1 - -> Foreign Scan on public.ft2 t2 - Output: t2.c1 - InfluxDB query: SELECT "C 1" FROM "T1" -(20 rows) - ---Testcase 283: -select c2, sum from "S 1"."T 1" t1, lateral (select sum(t2.c1 + t1."C 1") sum from ft2 t2 group by t2.c1) qry where t1.c2 * 2 = qry.sum and t1.c2 < 3 and t1."C 1" < 100 order by 1; - c2 | sum -----+----- - 1 | 2 - 2 | 4 -(2 rows) - -reset enable_hashagg; --- bug #15613: bad plan for foreign table scan with lateral reference ---Testcase 284: -EXPLAIN (VERBOSE, COSTS OFF) -SELECT ref_0.c2, subq_1.* -FROM - "S 1"."T 1" AS ref_0, - LATERAL ( - SELECT ref_0."C 1" c1, subq_0.* - FROM (SELECT ref_0.c2, ref_1.c3 - FROM ft1 AS ref_1) AS subq_0 - RIGHT JOIN ft2 AS ref_3 ON (subq_0.c3 = ref_3.c3) - ) AS subq_1 -WHERE ref_0."C 1" < 10 AND subq_1.c3 = '00001' -ORDER BY ref_0."C 1"; - QUERY PLAN ---------------------------------------------------------------------------------------------------------- - Sort - Output: ref_0.c2, ref_0."C 1", (ref_0.c2), ref_1.c3, ref_0."C 1" - Sort Key: ref_0."C 1" - -> Nested Loop - Output: ref_0.c2, ref_0."C 1", (ref_0.c2), ref_1.c3, ref_0."C 1" - -> Nested Loop - Output: ref_0.c2, ref_0."C 1", ref_1.c3, (ref_0.c2) - -> Foreign Scan on "S 1"."T 1" ref_0 - Output: ref_0."C 1", ref_0.c2, ref_0.c3, ref_0."time", ref_0.c6, ref_0.c7, ref_0.c8 - InfluxDB query: SELECT "C 1", "c2" FROM "T1" WHERE (("C 1" < 10)) - -> Foreign Scan on public.ft1 ref_1 - Output: ref_1.c3, ref_0.c2 - InfluxDB query: SELECT "c3", "C 1" FROM "T1" WHERE (("c3" = '00001')) - -> Materialize - Output: ref_3.c3 - -> Foreign Scan on public.ft2 ref_3 - Output: ref_3.c3 - InfluxDB query: SELECT "c3", "C 1" FROM "T1" WHERE (("c3" = '00001')) -(18 rows) - ---Testcase 285: -SELECT ref_0.c2, subq_1.* -FROM - "S 1"."T 1" AS ref_0, - LATERAL ( - SELECT ref_0."C 1" c1, subq_0.* - FROM (SELECT ref_0.c2, ref_1.c3 - FROM ft1 AS ref_1) AS subq_0 - RIGHT JOIN ft2 AS ref_3 ON (subq_0.c3 = ref_3.c3) - ) AS subq_1 -WHERE ref_0."C 1" < 10 AND subq_1.c3 = '00001' -ORDER BY ref_0."C 1"; - c2 | c1 | c2 | c3 -----+----+----+------- - 1 | 1 | 1 | 00001 - 2 | 2 | 2 | 00001 - 3 | 3 | 3 | 00001 - 4 | 4 | 4 | 00001 - 5 | 5 | 5 | 00001 - 6 | 6 | 6 | 00001 - 7 | 7 | 7 | 00001 - 8 | 8 | 8 | 00001 - 9 | 9 | 9 | 00001 -(9 rows) - --- Check with placeHolderVars ---Testcase 286: -explain (verbose, costs off) -select sum(q.a), count(q.b) from ft4 left join (select 13, avg(ft1.c1), sum(ft2.c1) from ft1 right join ft2 on (ft1.c1 = ft2.c1)) q(a, b, c) on (ft4.c1 <= q.b); - QUERY PLAN ------------------------------------------------------------------------------------- - Aggregate - Output: sum(q.a), count(q.b) - -> Nested Loop Left Join - Output: q.a, q.b - Inner Unique: true - Join Filter: ((ft4.c1)::numeric <= q.b) - -> Foreign Scan on public.ft4 - Output: ft4.c1, ft4.c2, ft4.c3 - InfluxDB query: SELECT "c1" FROM "T3" - -> Materialize - Output: q.a, q.b - -> Subquery Scan on q - Output: q.a, q.b - -> Aggregate - Output: 13, avg(ft1.c1), NULL::bigint - -> Merge Left Join - Output: ft1.c1 - Merge Cond: (ft2.c1 = ft1.c1) - -> Sort - Output: ft2.c1 - Sort Key: ft2.c1 - -> Foreign Scan on public.ft2 - Output: ft2.c1 - InfluxDB query: SELECT "C 1" FROM "T1" - -> Sort - Output: ft1.c1 - Sort Key: ft1.c1 - -> Foreign Scan on public.ft1 - Output: ft1.c1 - InfluxDB query: SELECT "C 1" FROM "T1" -(30 rows) - ---Testcase 287: -select sum(q.a), count(q.b) from ft4 left join (select 13, avg(ft1.c1), sum(ft2.c1) from ft1 right join ft2 on (ft1.c1 = ft2.c1)) q(a, b, c) on (ft4.c1 <= q.b); - sum | count ------+------- - 650 | 50 -(1 row) - --- Not supported cases --- Grouping sets ---Testcase 288: -explain (verbose, costs off) -select c2, sum(c1) from ft1 where c2 < 3 group by rollup(c2) order by 1 nulls last; - QUERY PLAN -------------------------------------------------------------------------------- - Sort - Output: c2, (sum(c1)) - Sort Key: ft1.c2 - -> MixedAggregate - Output: c2, sum(c1) - Hash Key: ft1.c2 - Group Key: () - -> Foreign Scan on public.ft1 - Output: c2, c1 - InfluxDB query: SELECT "C 1", "c2" FROM "T1" WHERE (("c2" < 3)) -(10 rows) - ---Testcase 289: -select c2, sum(c1) from ft1 where c2 < 3 group by rollup(c2) order by 1 nulls last; - c2 | sum -----+-------- - 0 | 50500 - 1 | 49600 - 2 | 49700 - | 149800 -(4 rows) - ---Testcase 290: -explain (verbose, costs off) -select c2, sum(c1) from ft1 where c2 < 3 group by cube(c2) order by 1 nulls last; - QUERY PLAN -------------------------------------------------------------------------------- - Sort - Output: c2, (sum(c1)) - Sort Key: ft1.c2 - -> MixedAggregate - Output: c2, sum(c1) - Hash Key: ft1.c2 - Group Key: () - -> Foreign Scan on public.ft1 - Output: c2, c1 - InfluxDB query: SELECT "C 1", "c2" FROM "T1" WHERE (("c2" < 3)) -(10 rows) - ---Testcase 291: -select c2, sum(c1) from ft1 where c2 < 3 group by cube(c2) order by 1 nulls last; - c2 | sum -----+-------- - 0 | 50500 - 1 | 49600 - 2 | 49700 - | 149800 -(4 rows) - ---Testcase 292: -explain (verbose, costs off) -select c2, c6, sum(c1) from ft1 where c2 < 3 group by grouping sets(c2, c6) order by 1 nulls last, 2 nulls last; - QUERY PLAN -------------------------------------------------------------------------------------- - Sort - Output: c2, c6, (sum(c1)) - Sort Key: ft1.c2, ft1.c6 - -> HashAggregate - Output: c2, c6, sum(c1) - Hash Key: ft1.c2 - Hash Key: ft1.c6 - -> Foreign Scan on public.ft1 - Output: c2, c6, c1 - InfluxDB query: SELECT "C 1", "c2", "c6" FROM "T1" WHERE (("c2" < 3)) -(10 rows) - ---Testcase 293: -select c2, c6, sum(c1) from ft1 where c2 < 3 group by grouping sets(c2, c6) order by 1 nulls last, 2 nulls last; - c2 | c6 | sum -----+----+------- - 0 | | 50500 - 1 | | 49600 - 2 | | 49700 - | 0 | 50500 - | 1 | 49600 - | 2 | 49700 -(6 rows) - ---Testcase 294: -explain (verbose, costs off) -select c2, sum(c1), grouping(c2) from ft1 where c2 < 3 group by c2 order by 1 nulls last; - QUERY PLAN -------------------------------------------------------------------------------- - Sort - Output: c2, (sum(c1)), (GROUPING(c2)) - Sort Key: ft1.c2 - -> HashAggregate - Output: c2, sum(c1), GROUPING(c2) - Group Key: ft1.c2 - -> Foreign Scan on public.ft1 - Output: c2, c1 - InfluxDB query: SELECT "C 1", "c2" FROM "T1" WHERE (("c2" < 3)) -(9 rows) - ---Testcase 295: -select c2, sum(c1), grouping(c2) from ft1 where c2 < 3 group by c2 order by 1 nulls last; - c2 | sum | grouping -----+-------+---------- - 0 | 50500 | 0 - 1 | 49600 | 0 - 2 | 49700 | 0 -(3 rows) - --- DISTINCT itself is not pushed down, whereas underneath aggregate is pushed ---Testcase 296: -explain (verbose, costs off) -select distinct sum(c1)/1000 s from ft2 where c2 < 6 group by c2 order by 1; - QUERY PLAN -------------------------------------------------------------------------------------- - Unique - Output: ((sum(c1) / 1000)), c2 - -> Sort - Output: ((sum(c1) / 1000)), c2 - Sort Key: ((sum(ft2.c1) / 1000)) - -> HashAggregate - Output: (sum(c1) / 1000), c2 - Group Key: ft2.c2 - -> Foreign Scan on public.ft2 - Output: c1, c2 - InfluxDB query: SELECT "C 1", "c2" FROM "T1" WHERE (("c2" < 6)) -(11 rows) - ---Testcase 297: -select distinct sum(c1)/1000 s from ft2 where c2 < 6 group by c2 order by 1; - s ----- - 49 - 50 -(2 rows) - --- WindowAgg ---Testcase 298: -explain (verbose, costs off) -select c2, sum(c2), count(c2) over (partition by c2%2) from ft2 where c2 < 10 group by c2 order by 1; - QUERY PLAN -------------------------------------------------------------------------------------- - Sort - Output: c2, (sum(c2)), (count(c2) OVER (?)), ((c2 % 2)) - Sort Key: ft2.c2 - -> WindowAgg - Output: c2, (sum(c2)), count(c2) OVER (?), ((c2 % 2)) - -> Sort - Output: c2, ((c2 % 2)), (sum(c2)) - Sort Key: ((ft2.c2 % 2)) - -> HashAggregate - Output: c2, (c2 % 2), sum(c2) - Group Key: ft2.c2 - -> Foreign Scan on public.ft2 - Output: c2 - InfluxDB query: SELECT "c2" FROM "T1" WHERE (("c2" < 10)) -(14 rows) - ---Testcase 299: -select c2, sum(c2), count(c2) over (partition by c2%2) from ft2 where c2 < 10 group by c2 order by 1; - c2 | sum | count -----+-----+------- - 0 | 0 | 5 - 1 | 100 | 5 - 2 | 200 | 5 - 3 | 300 | 5 - 4 | 400 | 5 - 5 | 500 | 5 - 6 | 600 | 5 - 7 | 700 | 5 - 8 | 800 | 5 - 9 | 900 | 5 -(10 rows) - ---Testcase 300: -explain (verbose, costs off) -select c2, array_agg(c2) over (partition by c2%2 order by c2 desc) from ft1 where c2 < 10 group by c2 order by 1; - QUERY PLAN -------------------------------------------------------------------------------------- - Sort - Output: c2, (array_agg(c2) OVER (?)), ((c2 % 2)) - Sort Key: ft1.c2 - -> WindowAgg - Output: c2, array_agg(c2) OVER (?), ((c2 % 2)) - -> Sort - Output: c2, ((c2 % 2)) - Sort Key: ((ft1.c2 % 2)), ft1.c2 DESC - -> HashAggregate - Output: c2, (c2 % 2) - Group Key: ft1.c2 - -> Foreign Scan on public.ft1 - Output: c2 - InfluxDB query: SELECT "c2" FROM "T1" WHERE (("c2" < 10)) -(14 rows) - ---Testcase 301: -select c2, array_agg(c2) over (partition by c2%2 order by c2 desc) from ft1 where c2 < 10 group by c2 order by 1; - c2 | array_agg -----+------------- - 0 | {8,6,4,2,0} - 1 | {9,7,5,3,1} - 2 | {8,6,4,2} - 3 | {9,7,5,3} - 4 | {8,6,4} - 5 | {9,7,5} - 6 | {8,6} - 7 | {9,7} - 8 | {8} - 9 | {9} -(10 rows) - ---Testcase 302: -explain (verbose, costs off) -select c2, array_agg(c2) over (partition by c2%2 order by c2 range between current row and unbounded following) from ft1 where c2 < 10 group by c2 order by 1; - QUERY PLAN -------------------------------------------------------------------------------------- - Sort - Output: c2, (array_agg(c2) OVER (?)), ((c2 % 2)) - Sort Key: ft1.c2 - -> WindowAgg - Output: c2, array_agg(c2) OVER (?), ((c2 % 2)) - -> Sort - Output: c2, ((c2 % 2)) - Sort Key: ((ft1.c2 % 2)), ft1.c2 - -> HashAggregate - Output: c2, (c2 % 2) - Group Key: ft1.c2 - -> Foreign Scan on public.ft1 - Output: c2 - InfluxDB query: SELECT "c2" FROM "T1" WHERE (("c2" < 10)) -(14 rows) - ---Testcase 303: -select c2, array_agg(c2) over (partition by c2%2 order by c2 range between current row and unbounded following) from ft1 where c2 < 10 group by c2 order by 1; - c2 | array_agg -----+------------- - 0 | {0,2,4,6,8} - 1 | {1,3,5,7,9} - 2 | {2,4,6,8} - 3 | {3,5,7,9} - 4 | {4,6,8} - 5 | {5,7,9} - 6 | {6,8} - 7 | {7,9} - 8 | {8} - 9 | {9} -(10 rows) - --- =================================================================== --- parameterized queries --- =================================================================== --- simple join ---Testcase 304: -PREPARE st1(int, int) AS SELECT t1.c3, t2.c3 FROM ft1 t1, ft2 t2 WHERE t1.c1 = $1 AND t2.c1 = $2; ---Testcase 305: -EXPLAIN (VERBOSE, COSTS OFF) EXECUTE st1(1, 2); - QUERY PLAN --------------------------------------------------------------------------------- - Nested Loop - Output: t1.c3, t2.c3 - -> Foreign Scan on public.ft1 t1 - Output: t1.c3 - InfluxDB query: SELECT "c3", "C 1" FROM "T1" WHERE (("C 1" = 1)) - -> Materialize - Output: t2.c3 - -> Foreign Scan on public.ft2 t2 - Output: t2.c3 - InfluxDB query: SELECT "c3", "C 1" FROM "T1" WHERE (("C 1" = 2)) -(10 rows) - ---Testcase 306: -EXECUTE st1(1, 1); - c3 | c3 --------+------- - 00001 | 00001 -(1 row) - ---Testcase 307: -EXECUTE st1(101, 101); - c3 | c3 --------+------- - 00101 | 00101 -(1 row) - --- subquery using stable function (can't be sent to remote) ---Testcase 308: -PREPARE st2(int) AS SELECT * FROM ft1 t1 WHERE t1.c1 < $2 AND t1.c3 IN (SELECT c3 FROM ft2 t2 WHERE c1 > $1 AND date(time) = '1970-01-17'::date) ORDER BY c1; ---Testcase 309: -EXPLAIN (VERBOSE, COSTS OFF) EXECUTE st2(10, 20); - QUERY PLAN ---------------------------------------------------------------------------------------------------------- - Sort - Output: t1.c1, t1.c2, t1.c3, t1."time", t1.c6, t1.c7, t1.c8 - Sort Key: t1.c1 - -> Hash Semi Join - Output: t1.c1, t1.c2, t1.c3, t1."time", t1.c6, t1.c7, t1.c8 - Hash Cond: (t1.c3 = t2.c3) - -> Foreign Scan on public.ft1 t1 - Output: t1.c1, t1.c2, t1.c3, t1."time", t1.c6, t1.c7, t1.c8 - InfluxDB query: SELECT "C 1", "c2", "c3", "c6", "c7", "c8" FROM "T1" WHERE (("C 1" < 20)) - -> Hash - Output: t2.c3 - -> Foreign Scan on public.ft2 t2 - Output: t2.c3 - Filter: (date(t2."time") = '01-17-1970'::date) - InfluxDB query: SELECT "c3", "C 1" FROM "T1" WHERE (("C 1" > 10)) -(15 rows) - ---Testcase 310: -EXECUTE st2(10, 20); - c1 | c2 | c3 | time | c6 | c7 | c8 -----+----+-------+--------------------------+----+------------+----- - 16 | 6 | 00016 | Sat Jan 17 00:00:00 1970 | 6 | 6 | foo -(1 row) - ---Testcase 311: -EXECUTE st2(101, 121); - c1 | c2 | c3 | time | c6 | c7 | c8 ------+----+-------+--------------------------+----+------------+----- - 116 | 6 | 00116 | Sat Jan 17 00:00:00 1970 | 6 | 6 | foo -(1 row) - --- subquery using immutable function (can be sent to remote) ---Testcase 312: -PREPARE st3(int) AS SELECT * FROM ft1 t1 WHERE t1.c1 < $2 AND t1.c3 IN (SELECT c3 FROM ft2 t2 WHERE c1 > $1 AND date(time) = '1970-01-17'::date) ORDER BY c1; ---Testcase 313: -EXPLAIN (VERBOSE, COSTS OFF) EXECUTE st3(10, 20); - QUERY PLAN ---------------------------------------------------------------------------------------------------------- - Sort - Output: t1.c1, t1.c2, t1.c3, t1."time", t1.c6, t1.c7, t1.c8 - Sort Key: t1.c1 - -> Hash Semi Join - Output: t1.c1, t1.c2, t1.c3, t1."time", t1.c6, t1.c7, t1.c8 - Hash Cond: (t1.c3 = t2.c3) - -> Foreign Scan on public.ft1 t1 - Output: t1.c1, t1.c2, t1.c3, t1."time", t1.c6, t1.c7, t1.c8 - InfluxDB query: SELECT "C 1", "c2", "c3", "c6", "c7", "c8" FROM "T1" WHERE (("C 1" < 20)) - -> Hash - Output: t2.c3 - -> Foreign Scan on public.ft2 t2 - Output: t2.c3 - Filter: (date(t2."time") = '01-17-1970'::date) - InfluxDB query: SELECT "c3", "C 1" FROM "T1" WHERE (("C 1" > 10)) -(15 rows) - ---Testcase 314: -EXECUTE st3(10, 20); - c1 | c2 | c3 | time | c6 | c7 | c8 -----+----+-------+--------------------------+----+------------+----- - 16 | 6 | 00016 | Sat Jan 17 00:00:00 1970 | 6 | 6 | foo -(1 row) - ---Testcase 315: -EXECUTE st3(20, 30); - c1 | c2 | c3 | time | c6 | c7 | c8 -----+----+----+------+----+----+---- -(0 rows) - --- custom plan should be chosen initially ---Testcase 316: -PREPARE st4(int) AS SELECT * FROM ft1 t1 WHERE t1.c1 = $1; ---Testcase 317: -EXPLAIN (VERBOSE, COSTS OFF) EXECUTE st4(1); - QUERY PLAN --------------------------------------------------------------------------------------------- - Foreign Scan on public.ft1 t1 - Output: c1, c2, c3, "time", c6, c7, c8 - InfluxDB query: SELECT "C 1", "c2", "c3", "c6", "c7", "c8" FROM "T1" WHERE (("C 1" = 1)) -(3 rows) - ---Testcase 318: -EXPLAIN (VERBOSE, COSTS OFF) EXECUTE st4(1); - QUERY PLAN --------------------------------------------------------------------------------------------- - Foreign Scan on public.ft1 t1 - Output: c1, c2, c3, "time", c6, c7, c8 - InfluxDB query: SELECT "C 1", "c2", "c3", "c6", "c7", "c8" FROM "T1" WHERE (("C 1" = 1)) -(3 rows) - ---Testcase 319: -EXPLAIN (VERBOSE, COSTS OFF) EXECUTE st4(1); - QUERY PLAN --------------------------------------------------------------------------------------------- - Foreign Scan on public.ft1 t1 - Output: c1, c2, c3, "time", c6, c7, c8 - InfluxDB query: SELECT "C 1", "c2", "c3", "c6", "c7", "c8" FROM "T1" WHERE (("C 1" = 1)) -(3 rows) - ---Testcase 320: -EXPLAIN (VERBOSE, COSTS OFF) EXECUTE st4(1); - QUERY PLAN --------------------------------------------------------------------------------------------- - Foreign Scan on public.ft1 t1 - Output: c1, c2, c3, "time", c6, c7, c8 - InfluxDB query: SELECT "C 1", "c2", "c3", "c6", "c7", "c8" FROM "T1" WHERE (("C 1" = 1)) -(3 rows) - ---Testcase 321: -EXPLAIN (VERBOSE, COSTS OFF) EXECUTE st4(1); - QUERY PLAN --------------------------------------------------------------------------------------------- - Foreign Scan on public.ft1 t1 - Output: c1, c2, c3, "time", c6, c7, c8 - InfluxDB query: SELECT "C 1", "c2", "c3", "c6", "c7", "c8" FROM "T1" WHERE (("C 1" = 1)) -(3 rows) - --- once we try it enough times, should switch to generic plan ---Testcase 322: -EXPLAIN (VERBOSE, COSTS OFF) EXECUTE st4(1); - QUERY PLAN ---------------------------------------------------------------------------------------------- - Foreign Scan on public.ft1 t1 - Output: c1, c2, c3, "time", c6, c7, c8 - InfluxDB query: SELECT "C 1", "c2", "c3", "c6", "c7", "c8" FROM "T1" WHERE (("C 1" = $1)) -(3 rows) - --- value of $1 should not be sent to remote ---Testcase 323: -PREPARE st5(text,int) AS SELECT * FROM ft1 t1 WHERE c8 = $1 and c1 = $2; ---Testcase 324: -EXPLAIN (VERBOSE, COSTS OFF) EXECUTE st5('foo', 1); - QUERY PLAN ------------------------------------------------------------------------------------------------------------------ - Foreign Scan on public.ft1 t1 - Output: c1, c2, c3, "time", c6, c7, c8 - InfluxDB query: SELECT "C 1", "c2", "c3", "c6", "c7", "c8" FROM "T1" WHERE (("c8" = 'foo')) AND (("C 1" = 1)) -(3 rows) - ---Testcase 325: -EXPLAIN (VERBOSE, COSTS OFF) EXECUTE st5('foo', 1); - QUERY PLAN ------------------------------------------------------------------------------------------------------------------ - Foreign Scan on public.ft1 t1 - Output: c1, c2, c3, "time", c6, c7, c8 - InfluxDB query: SELECT "C 1", "c2", "c3", "c6", "c7", "c8" FROM "T1" WHERE (("c8" = 'foo')) AND (("C 1" = 1)) -(3 rows) - ---Testcase 326: -EXPLAIN (VERBOSE, COSTS OFF) EXECUTE st5('foo', 1); - QUERY PLAN ------------------------------------------------------------------------------------------------------------------ - Foreign Scan on public.ft1 t1 - Output: c1, c2, c3, "time", c6, c7, c8 - InfluxDB query: SELECT "C 1", "c2", "c3", "c6", "c7", "c8" FROM "T1" WHERE (("c8" = 'foo')) AND (("C 1" = 1)) -(3 rows) - ---Testcase 327: -EXPLAIN (VERBOSE, COSTS OFF) EXECUTE st5('foo', 1); - QUERY PLAN ------------------------------------------------------------------------------------------------------------------ - Foreign Scan on public.ft1 t1 - Output: c1, c2, c3, "time", c6, c7, c8 - InfluxDB query: SELECT "C 1", "c2", "c3", "c6", "c7", "c8" FROM "T1" WHERE (("c8" = 'foo')) AND (("C 1" = 1)) -(3 rows) - ---Testcase 328: -EXPLAIN (VERBOSE, COSTS OFF) EXECUTE st5('foo', 1); - QUERY PLAN ------------------------------------------------------------------------------------------------------------------ - Foreign Scan on public.ft1 t1 - Output: c1, c2, c3, "time", c6, c7, c8 - InfluxDB query: SELECT "C 1", "c2", "c3", "c6", "c7", "c8" FROM "T1" WHERE (("c8" = 'foo')) AND (("C 1" = 1)) -(3 rows) - ---Testcase 329: -EXPLAIN (VERBOSE, COSTS OFF) EXECUTE st5('foo', 1); - QUERY PLAN ---------------------------------------------------------------------------------------------------------------- - Foreign Scan on public.ft1 t1 - Output: c1, c2, c3, "time", c6, c7, c8 - InfluxDB query: SELECT "C 1", "c2", "c3", "c6", "c7", "c8" FROM "T1" WHERE (("c8" = $1)) AND (("C 1" = $2)) -(3 rows) - ---Testcase 330: -EXECUTE st5('foo', 1); - c1 | c2 | c3 | time | c6 | c7 | c8 -----+----+-------+--------------------------+----+------------+----- - 1 | 1 | 00001 | Fri Jan 02 00:00:00 1970 | 1 | 1 | foo -(1 row) - --- altering FDW options requires replanning ---Testcase 331: -PREPARE st6 AS SELECT * FROM ft1 t1 WHERE t1.c1 = t1.c2; ---Testcase 332: -EXPLAIN (VERBOSE, COSTS OFF) EXECUTE st6; - QUERY PLAN ------------------------------------------------------------------------------------------------ - Foreign Scan on public.ft1 t1 - Output: c1, c2, c3, "time", c6, c7, c8 - InfluxDB query: SELECT "C 1", "c2", "c3", "c6", "c7", "c8" FROM "T1" WHERE (("C 1" = "c2")) -(3 rows) - ---Testcase 333: -PREPARE st7 AS INSERT INTO ft1 (c1,c2,c3) VALUES (1001,101,'foo'); ---Testcase 334: -EXPLAIN (VERBOSE, COSTS OFF) EXECUTE st7; - QUERY PLAN ------------------------------------------------------------------------------------------------------------------------------------------------------------- - Insert on public.ft1 - -> Result - Output: NULL::integer, 1001, 101, 'foo'::text, NULL::timestamp without time zone, NULL::character varying, 'ft1 '::character(10), NULL::text -(3 rows) - ---Testcase 335: -INSERT INTO "S 1"."T 0" SELECT * FROM "S 1"."T 1"; -ALTER FOREIGN TABLE ft1 OPTIONS (SET table 'T0'); ---Testcase 336: -EXPLAIN (VERBOSE, COSTS OFF) EXECUTE st6; - QUERY PLAN ------------------------------------------------------------------------------------------------ - Foreign Scan on public.ft1 t1 - Output: c1, c2, c3, "time", c6, c7, c8 - InfluxDB query: SELECT "C 1", "c2", "c3", "c6", "c7", "c8" FROM "T0" WHERE (("C 1" = "c2")) -(3 rows) - ---Testcase 337: -EXECUTE st6; - c1 | c2 | c3 | time | c6 | c7 | c8 -----+----+-------+--------------------------+----+------------+----- - 1 | 1 | 00001 | Fri Jan 02 00:00:00 1970 | 1 | 1 | foo - 2 | 2 | 00002 | Sat Jan 03 00:00:00 1970 | 2 | 2 | foo - 3 | 3 | 00003 | Sun Jan 04 00:00:00 1970 | 3 | 3 | foo - 4 | 4 | 00004 | Mon Jan 05 00:00:00 1970 | 4 | 4 | foo - 5 | 5 | 00005 | Tue Jan 06 00:00:00 1970 | 5 | 5 | foo - 6 | 6 | 00006 | Wed Jan 07 00:00:00 1970 | 6 | 6 | foo - 7 | 7 | 00007 | Thu Jan 08 00:00:00 1970 | 7 | 7 | foo - 8 | 8 | 00008 | Fri Jan 09 00:00:00 1970 | 8 | 8 | foo - 9 | 9 | 00009 | Sat Jan 10 00:00:00 1970 | 9 | 9 | foo -(9 rows) - ---Testcase 338: -EXPLAIN (VERBOSE, COSTS OFF) EXECUTE st7; - QUERY PLAN ------------------------------------------------------------------------------------------------------------------------------------------------------------- - Insert on public.ft1 - -> Result - Output: NULL::integer, 1001, 101, 'foo'::text, NULL::timestamp without time zone, NULL::character varying, 'ft1 '::character(10), NULL::text -(3 rows) - ---Testcase 339: -DELETE FROM "S 1"."T 0"; -ALTER FOREIGN TABLE ft1 OPTIONS (SET table 'T1'); ---Testcase 340: -PREPARE st8 AS SELECT count(c3) FROM ft1 t1 WHERE t1.c1 === t1.c2; ---Testcase 341: -EXPLAIN (VERBOSE, COSTS OFF) EXECUTE st8; - QUERY PLAN ------------------------------------------------------------- - Aggregate - Output: count(c3) - -> Foreign Scan on public.ft1 t1 - Output: c3 - Filter: (t1.c1 === t1.c2) - InfluxDB query: SELECT "C 1", "c2", "c3" FROM "T1" -(6 rows) - --- Skip, influxdb_fdw does not support extensions --- ALTER SERVER loopback OPTIONS (DROP extensions); ---Testcase 342: -EXPLAIN (VERBOSE, COSTS OFF) EXECUTE st8; - QUERY PLAN ------------------------------------------------------------- - Aggregate - Output: count(c3) - -> Foreign Scan on public.ft1 t1 - Output: c3 - Filter: (t1.c1 === t1.c2) - InfluxDB query: SELECT "C 1", "c2", "c3" FROM "T1" -(6 rows) - ---Testcase 343: -EXECUTE st8; - count -------- - 9 -(1 row) - --- ALTER SERVER loopback OPTIONS (ADD extensions 'influxdb_fdw'); --- cleanup -DEALLOCATE st1; -DEALLOCATE st2; -DEALLOCATE st3; -DEALLOCATE st4; -DEALLOCATE st5; -DEALLOCATE st6; -DEALLOCATE st7; -DEALLOCATE st8; --- System columns, except ctid and oid, should not be sent to remote ---Testcase 344: -EXPLAIN (VERBOSE, COSTS OFF) -SELECT * FROM ft1 t1 WHERE t1.tableoid = 'pg_class'::regclass LIMIT 1; - QUERY PLAN ------------------------------------------------------------------------------- - Limit - Output: c1, c2, c3, "time", c6, c7, c8 - -> Foreign Scan on public.ft1 t1 - Output: c1, c2, c3, "time", c6, c7, c8 - Filter: (t1.tableoid = '1259'::oid) - InfluxDB query: SELECT "C 1", "c2", "c3", "c6", "c7", "c8" FROM "T1" -(6 rows) - ---Testcase 345: -SELECT * FROM ft1 t1 WHERE t1.tableoid = 'ft1'::regclass ORDER BY c1 LIMIT 1; - c1 | c2 | c3 | time | c6 | c7 | c8 -----+----+-------+--------------------------+----+------------+----- - 1 | 1 | 00001 | Fri Jan 02 00:00:00 1970 | 1 | 1 | foo -(1 row) - ---Testcase 346: -EXPLAIN (VERBOSE, COSTS OFF) -SELECT tableoid::regclass, * FROM ft1 t1 LIMIT 1; - QUERY PLAN ------------------------------------------------------------------------------- - Limit - Output: ((tableoid)::regclass), c1, c2, c3, "time", c6, c7, c8 - -> Foreign Scan on public.ft1 t1 - Output: (tableoid)::regclass, c1, c2, c3, "time", c6, c7, c8 - InfluxDB query: SELECT "C 1", "c2", "c3", "c6", "c7", "c8" FROM "T1" -(5 rows) - ---Testcase 347: -SELECT tableoid::regclass, * FROM ft1 t1 ORDER BY c1 LIMIT 1; - tableoid | c1 | c2 | c3 | time | c6 | c7 | c8 -----------+----+----+-------+--------------------------+----+------------+----- - ft1 | 1 | 1 | 00001 | Fri Jan 02 00:00:00 1970 | 1 | 1 | foo -(1 row) - ---Testcase 348: -EXPLAIN (VERBOSE, COSTS OFF) -SELECT * FROM ft1 t1 WHERE t1.ctid = '(0,2)'; - QUERY PLAN ------------------------------------------------------------------------- - Foreign Scan on public.ft1 t1 - Output: c1, c2, c3, "time", c6, c7, c8 - Filter: (t1.ctid = '(0,2)'::tid) - InfluxDB query: SELECT "C 1", "c2", "c3", "c6", "c7", "c8" FROM "T1" -(4 rows) - ---Testcase 349: -SELECT * FROM ft1 t1 WHERE t1.ctid = '(0,2)'; - c1 | c2 | c3 | time | c6 | c7 | c8 -----+----+----+------+----+----+---- -(0 rows) - ---Testcase 350: -EXPLAIN (VERBOSE, COSTS OFF) -SELECT ctid, * FROM ft1 t1 LIMIT 1; - QUERY PLAN ------------------------------------------------------------------------------- - Limit - Output: ctid, c1, c2, c3, "time", c6, c7, c8 - -> Foreign Scan on public.ft1 t1 - Output: ctid, c1, c2, c3, "time", c6, c7, c8 - InfluxDB query: SELECT "C 1", "c2", "c3", "c6", "c7", "c8" FROM "T1" -(5 rows) - ---Testcase 351: -SELECT ctid, * FROM ft1 t1 ORDER BY c1 LIMIT 1; - ctid | c1 | c2 | c3 | time | c6 | c7 | c8 -----------------+----+----+-------+--------------------------+----+------------+----- - (4294967295,0) | 1 | 1 | 00001 | Fri Jan 02 00:00:00 1970 | 1 | 1 | foo -(1 row) - --- =================================================================== --- used in PL/pgSQL function --- =================================================================== ---Testcase 352: -CREATE OR REPLACE FUNCTION f_test(p_c1 int) RETURNS int AS $$ -DECLARE - v_c1 int; -BEGIN ---Testcase 353: - SELECT c1 INTO v_c1 FROM ft1 WHERE c1 = p_c1 LIMIT 1; - PERFORM c1 FROM ft1 WHERE c1 = p_c1 AND p_c1 = v_c1 LIMIT 1; - RETURN v_c1; -END; -$$ LANGUAGE plpgsql; ---Testcase 354: -SELECT f_test(100); - f_test --------- - 100 -(1 row) - ---Testcase 355: -DROP FUNCTION f_test(int); --- =================================================================== --- conversion error --- =================================================================== -ALTER FOREIGN TABLE ft1 ALTER COLUMN c8 TYPE int; ---Testcase 356: -SELECT * FROM ft1 WHERE c1 = 1; -- ERROR -ERROR: invalid input syntax for integer: "foo" ---Testcase 357: -SELECT ft1.c1, ft2.c2, ft1.c8 FROM ft1, ft2 WHERE ft1.c1 = ft2.c1 AND ft1.c1 = 1; -- ERROR -ERROR: invalid input syntax for integer: "foo" ---Testcase 358: -SELECT ft1.c1, ft2.c2, ft1 FROM ft1, ft2 WHERE ft1.c1 = ft2.c1 AND ft1.c1 = 1; -- ERROR -ERROR: invalid input syntax for integer: "foo" ---Testcase 359: -SELECT sum(c2), array_agg(c8) FROM ft1 GROUP BY c8; -- ERROR -ERROR: invalid input syntax for integer: "foo" -ALTER FOREIGN TABLE ft1 ALTER COLUMN c8 TYPE text; -/* --- influxdb_fdw does not support transactions --- =================================================================== --- subtransaction --- + local/remote error doesn't break cursor --- =================================================================== -BEGIN; -DECLARE c CURSOR FOR SELECT * FROM ft1 ORDER BY c1; -FETCH c; -SAVEPOINT s; -ERROR OUT; -- ERROR -ROLLBACK TO s; -FETCH c; -SAVEPOINT s; -SELECT * FROM ft1 WHERE 1 / (c1 - 1) > 0; -- ERROR -ROLLBACK TO s; -FETCH c; -SELECT * FROM ft1 ORDER BY c1 LIMIT 1; -COMMIT; -*/ --- =================================================================== --- test handling of collations --- =================================================================== ---Testcase 360: -create foreign table loct3 (f1 text collate "C", f2 text, f3 varchar(10)) server influxdb_svr options (table 'loct3'); ---Testcase 361: -create foreign table ft3 (f1 text collate "C", f2 text, f3 varchar(10)) - server influxdb_svr options (table 'loct3'); --- can be sent to remote ---Testcase 362: -explain (verbose, costs off) select * from ft3 where f1 = 'foo'; - QUERY PLAN -------------------------------------------------------------------------------- - Foreign Scan on public.ft3 - Output: f1, f2, f3 - InfluxDB query: SELECT "f1", "f2", "f3" FROM "loct3" WHERE (("f1" = 'foo')) -(3 rows) - ---Testcase 363: -explain (verbose, costs off) select * from ft3 where f1 COLLATE "C" = 'foo'; - QUERY PLAN -------------------------------------------------------------------------------- - Foreign Scan on public.ft3 - Output: f1, f2, f3 - InfluxDB query: SELECT "f1", "f2", "f3" FROM "loct3" WHERE (("f1" = 'foo')) -(3 rows) - ---Testcase 364: -explain (verbose, costs off) select * from ft3 where f2 = 'foo'; - QUERY PLAN -------------------------------------------------------------------------------- - Foreign Scan on public.ft3 - Output: f1, f2, f3 - InfluxDB query: SELECT "f1", "f2", "f3" FROM "loct3" WHERE (("f2" = 'foo')) -(3 rows) - ---Testcase 365: -explain (verbose, costs off) select * from ft3 where f3 = 'foo'; - QUERY PLAN -------------------------------------------------------------------------------- - Foreign Scan on public.ft3 - Output: f1, f2, f3 - InfluxDB query: SELECT "f1", "f2", "f3" FROM "loct3" WHERE (("f3" = 'foo')) -(3 rows) - ---Testcase 366: -explain (verbose, costs off) select * from ft3 f, loct3 l - where f.f3 = l.f3 and l.f1 = 'foo'; - QUERY PLAN -------------------------------------------------------------------------------------------- - Hash Join - Output: f.f1, f.f2, f.f3, l.f1, l.f2, l.f3 - Hash Cond: ((f.f3)::text = (l.f3)::text) - -> Foreign Scan on public.ft3 f - Output: f.f1, f.f2, f.f3 - InfluxDB query: SELECT "f1", "f2", "f3" FROM "loct3" - -> Hash - Output: l.f1, l.f2, l.f3 - -> Foreign Scan on public.loct3 l - Output: l.f1, l.f2, l.f3 - InfluxDB query: SELECT "f1", "f2", "f3" FROM "loct3" WHERE (("f1" = 'foo')) -(11 rows) - --- can't be sent to remote ---Testcase 367: -explain (verbose, costs off) select * from ft3 where f1 COLLATE "POSIX" = 'foo'; - QUERY PLAN --------------------------------------------------------- - Foreign Scan on public.ft3 - Output: f1, f2, f3 - Filter: ((ft3.f1)::text = 'foo'::text) - InfluxDB query: SELECT "f1", "f2", "f3" FROM "loct3" -(4 rows) - ---Testcase 368: -explain (verbose, costs off) select * from ft3 where f1 = 'foo' COLLATE "C"; - QUERY PLAN --------------------------------------------------------- - Foreign Scan on public.ft3 - Output: f1, f2, f3 - Filter: (ft3.f1 = 'foo'::text COLLATE "C") - InfluxDB query: SELECT "f1", "f2", "f3" FROM "loct3" -(4 rows) - ---Testcase 369: -explain (verbose, costs off) select * from ft3 where f2 COLLATE "C" = 'foo'; - QUERY PLAN --------------------------------------------------------- - Foreign Scan on public.ft3 - Output: f1, f2, f3 - Filter: ((ft3.f2)::text = 'foo'::text) - InfluxDB query: SELECT "f1", "f2", "f3" FROM "loct3" -(4 rows) - ---Testcase 370: -explain (verbose, costs off) select * from ft3 where f2 = 'foo' COLLATE "C"; - QUERY PLAN --------------------------------------------------------- - Foreign Scan on public.ft3 - Output: f1, f2, f3 - Filter: (ft3.f2 = 'foo'::text COLLATE "C") - InfluxDB query: SELECT "f1", "f2", "f3" FROM "loct3" -(4 rows) - ---Testcase 371: -explain (verbose, costs off) select * from ft3 f, loct3 l - where f.f3 = l.f3 COLLATE "POSIX" and l.f1 = 'foo'; - QUERY PLAN -------------------------------------------------------------------------------------------- - Hash Join - Output: f.f1, f.f2, f.f3, l.f1, l.f2, l.f3 - Hash Cond: ((f.f3)::text = (l.f3)::text) - -> Foreign Scan on public.ft3 f - Output: f.f1, f.f2, f.f3 - InfluxDB query: SELECT "f1", "f2", "f3" FROM "loct3" - -> Hash - Output: l.f1, l.f2, l.f3 - -> Foreign Scan on public.loct3 l - Output: l.f1, l.f2, l.f3 - InfluxDB query: SELECT "f1", "f2", "f3" FROM "loct3" WHERE (("f1" = 'foo')) -(11 rows) - --- influxdb_fdw does not support UPDATE --- =================================================================== --- test writable foreign table stuff --- =================================================================== ---Testcase 372: -EXPLAIN (verbose, costs off) -INSERT INTO ft2 (c1,c2,c3) SELECT c1+1000,c2+100, c3 || c3 FROM ft2 ORDER BY c1 LIMIT 20; - QUERY PLAN -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- - Insert on public.ft2 - -> Subquery Scan on "*SELECT*" - Output: "*SELECT*"."?column?", "*SELECT*"."?column?_1", NULL::integer, "*SELECT*"."?column?_2", NULL::timestamp without time zone, NULL::character varying, 'ft2 '::character(10), NULL::text - -> Limit - Output: ((ft2_1.c1 + 1000)), ((ft2_1.c2 + 100)), ((ft2_1.c3 || ft2_1.c3)), ft2_1.c1 - -> Sort - Output: ((ft2_1.c1 + 1000)), ((ft2_1.c2 + 100)), ((ft2_1.c3 || ft2_1.c3)), ft2_1.c1 - Sort Key: ft2_1.c1 - -> Foreign Scan on public.ft2 ft2_1 - Output: (ft2_1.c1 + 1000), (ft2_1.c2 + 100), (ft2_1.c3 || ft2_1.c3), ft2_1.c1 - InfluxDB query: SELECT "C 1", "c2", "c3" FROM "T1" -(11 rows) - ---Testcase 373: -INSERT INTO ft2 (c1,c2,c3) SELECT c1+1000,c2+100, c3 || c3 FROM ft2 ORDER BY c1 LIMIT 20; ---Testcase 374: -INSERT INTO ft2 (c1,c2,c3) VALUES (1101,201,'aaa'), (1102,202,'bbb'), (1103,203,'ccc'); ---Testcase 375: -SELECT c1, c2, c3, c6, c7, c8 FROM ft2 WHERE c2 > 200; - c1 | c2 | c3 | c6 | c7 | c8 -------+-----+-----+----+------------+---- - 1101 | 201 | aaa | | ft2 | - 1102 | 202 | bbb | | ft2 | - 1103 | 203 | ccc | | ft2 | -(3 rows) - ---Testcase 376: -INSERT INTO ft2 (c1,c2,c3) VALUES (1104,204,'ddd'), (1105,205,'eee'); ---EXPLAIN (verbose, costs off) ---UPDATE ft2 SET c2 = c2 + 300, c3 = c3 || '_update3' WHERE c1 % 10 = 3; -- can be pushed down ---UPDATE ft2 SET c2 = c2 + 300, c3 = c3 || '_update3' WHERE c1 % 10 = 3; ---EXPLAIN (verbose, costs off) ---UPDATE ft2 SET c2 = c2 + 400, c3 = c3 || '_update7' WHERE c1 % 10 = 7 RETURNING *; -- can be pushed down ---UPDATE ft2 SET c2 = c2 + 400, c3 = c3 || '_update7' WHERE c1 % 10 = 7 RETURNING *; ---EXPLAIN (verbose, costs off) ---UPDATE ft2 SET c2 = ft2.c2 + 500, c3 = ft2.c3 || '_update9', c7 = DEFAULT --- FROM ft1 WHERE ft1.c1 = ft2.c2 AND ft1.c1 % 10 = 9; -- can be pushed down ---UPDATE ft2 SET c2 = ft2.c2 + 500, c3 = ft2.c3 || '_update9', c7 = DEFAULT --- FROM ft1 WHERE ft1.c1 = ft2.c2 AND ft1.c1 % 10 = 9; ---Testcase 377: -EXPLAIN (verbose, costs off) - DELETE FROM ft2 WHERE c1 % 10 = 5; -- can be pushed down - QUERY PLAN ---------------------------------------------------------------------------------- - Delete on public.ft2 - -> Foreign Scan on public.ft2 - Output: c3, "time" - InfluxDB query: SELECT "c3", "C 1" FROM "T1" WHERE ((("C 1" % 10) = 5)) -(4 rows) - ---Testcase 378: -SELECT c1 FROM ft2 WHERE c1 % 10 = 5 ORDER BY c1; - c1 ------- - 5 - 15 - 25 - 35 - 45 - 55 - 65 - 75 - 85 - 95 - 105 - 115 - 125 - 135 - 145 - 155 - 165 - 175 - 185 - 195 - 205 - 215 - 225 - 235 - 245 - 255 - 265 - 275 - 285 - 295 - 305 - 315 - 325 - 335 - 345 - 355 - 365 - 375 - 385 - 395 - 405 - 415 - 425 - 435 - 445 - 455 - 465 - 475 - 485 - 495 - 505 - 515 - 525 - 535 - 545 - 555 - 565 - 575 - 585 - 595 - 605 - 615 - 625 - 635 - 645 - 655 - 665 - 675 - 685 - 695 - 705 - 715 - 725 - 735 - 745 - 755 - 765 - 775 - 785 - 795 - 805 - 815 - 825 - 835 - 845 - 855 - 865 - 875 - 885 - 895 - 905 - 915 - 925 - 935 - 945 - 955 - 965 - 975 - 985 - 995 - 1005 - 1015 - 1105 -(103 rows) - ---Testcase 379: -DELETE FROM ft2 WHERE c1 % 10 = 5; ---Testcase 380: -SELECT c1 FROM ft2 WHERE c1 % 10 = 5; - c1 ----- -(0 rows) - ---Testcase 381: -EXPLAIN (verbose, costs off) -DELETE FROM ft2 USING ft1 WHERE ft1.c1 = ft2.c2 AND ft1.c1 % 10 = 2; - QUERY PLAN ---------------------------------------------------------------------------------------------------------------------- - Delete on public.ft2 - -> Hash Join - Output: ft2.c3, ft2."time", ft1.* - Hash Cond: (ft2.c2 = ft1.c1) - -> Foreign Scan on public.ft2 - Output: ft2.c3, ft2."time", ft2.c2 - InfluxDB query: SELECT "c2", "c3" FROM "T1" - -> Hash - Output: ft1.*, ft1.c1 - -> Foreign Scan on public.ft1 - Output: ft1.*, ft1.c1 - InfluxDB query: SELECT "C 1", "c2", "c3", "c6", "c7", "c8" FROM "T1" WHERE ((("C 1" % 10) = 2)) -(12 rows) - ---Testcase 382: -DELETE FROM ft2 USING ft1 WHERE ft1.c1 = ft2.c2 AND ft1.c1 % 10 = 2; ---Testcase 383: -SELECT c1,c2,c3 FROM ft2 ORDER BY c1; - c1 | c2 | c3 -------+-----+------------ - 1 | 1 | 00001 - 3 | 3 | 00003 - 4 | 4 | 00004 - 6 | 6 | 00006 - 7 | 7 | 00007 - 8 | 8 | 00008 - 9 | 9 | 00009 - 10 | 0 | 00010 - 11 | 1 | 00011 - 13 | 3 | 00013 - 14 | 4 | 00014 - 16 | 6 | 00016 - 17 | 7 | 00017 - 18 | 8 | 00018 - 19 | 9 | 00019 - 20 | 0 | 00020 - 21 | 1 | 00021 - 23 | 3 | 00023 - 24 | 4 | 00024 - 26 | 6 | 00026 - 27 | 7 | 00027 - 28 | 8 | 00028 - 29 | 9 | 00029 - 30 | 0 | 00030 - 31 | 1 | 00031 - 33 | 3 | 00033 - 34 | 4 | 00034 - 36 | 6 | 00036 - 37 | 7 | 00037 - 38 | 8 | 00038 - 39 | 9 | 00039 - 40 | 0 | 00040 - 41 | 1 | 00041 - 43 | 3 | 00043 - 44 | 4 | 00044 - 46 | 6 | 00046 - 47 | 7 | 00047 - 48 | 8 | 00048 - 49 | 9 | 00049 - 50 | 0 | 00050 - 51 | 1 | 00051 - 53 | 3 | 00053 - 54 | 4 | 00054 - 56 | 6 | 00056 - 57 | 7 | 00057 - 58 | 8 | 00058 - 59 | 9 | 00059 - 60 | 0 | 00060 - 61 | 1 | 00061 - 63 | 3 | 00063 - 64 | 4 | 00064 - 66 | 6 | 00066 - 67 | 7 | 00067 - 68 | 8 | 00068 - 69 | 9 | 00069 - 70 | 0 | 00070 - 71 | 1 | 00071 - 73 | 3 | 00073 - 74 | 4 | 00074 - 76 | 6 | 00076 - 77 | 7 | 00077 - 78 | 8 | 00078 - 79 | 9 | 00079 - 80 | 0 | 00080 - 81 | 1 | 00081 - 83 | 3 | 00083 - 84 | 4 | 00084 - 86 | 6 | 00086 - 87 | 7 | 00087 - 88 | 8 | 00088 - 89 | 9 | 00089 - 90 | 0 | 00090 - 91 | 1 | 00091 - 93 | 3 | 00093 - 94 | 4 | 00094 - 96 | 6 | 00096 - 97 | 7 | 00097 - 98 | 8 | 00098 - 99 | 9 | 00099 - 100 | 0 | 00100 - 101 | 1 | 00101 - 103 | 3 | 00103 - 104 | 4 | 00104 - 106 | 6 | 00106 - 107 | 7 | 00107 - 108 | 8 | 00108 - 109 | 9 | 00109 - 110 | 0 | 00110 - 111 | 1 | 00111 - 113 | 3 | 00113 - 114 | 4 | 00114 - 116 | 6 | 00116 - 117 | 7 | 00117 - 118 | 8 | 00118 - 119 | 9 | 00119 - 120 | 0 | 00120 - 121 | 1 | 00121 - 123 | 3 | 00123 - 124 | 4 | 00124 - 126 | 6 | 00126 - 127 | 7 | 00127 - 128 | 8 | 00128 - 129 | 9 | 00129 - 130 | 0 | 00130 - 131 | 1 | 00131 - 133 | 3 | 00133 - 134 | 4 | 00134 - 136 | 6 | 00136 - 137 | 7 | 00137 - 138 | 8 | 00138 - 139 | 9 | 00139 - 140 | 0 | 00140 - 141 | 1 | 00141 - 143 | 3 | 00143 - 144 | 4 | 00144 - 146 | 6 | 00146 - 147 | 7 | 00147 - 148 | 8 | 00148 - 149 | 9 | 00149 - 150 | 0 | 00150 - 151 | 1 | 00151 - 153 | 3 | 00153 - 154 | 4 | 00154 - 156 | 6 | 00156 - 157 | 7 | 00157 - 158 | 8 | 00158 - 159 | 9 | 00159 - 160 | 0 | 00160 - 161 | 1 | 00161 - 163 | 3 | 00163 - 164 | 4 | 00164 - 166 | 6 | 00166 - 167 | 7 | 00167 - 168 | 8 | 00168 - 169 | 9 | 00169 - 170 | 0 | 00170 - 171 | 1 | 00171 - 173 | 3 | 00173 - 174 | 4 | 00174 - 176 | 6 | 00176 - 177 | 7 | 00177 - 178 | 8 | 00178 - 179 | 9 | 00179 - 180 | 0 | 00180 - 181 | 1 | 00181 - 183 | 3 | 00183 - 184 | 4 | 00184 - 186 | 6 | 00186 - 187 | 7 | 00187 - 188 | 8 | 00188 - 189 | 9 | 00189 - 190 | 0 | 00190 - 191 | 1 | 00191 - 193 | 3 | 00193 - 194 | 4 | 00194 - 196 | 6 | 00196 - 197 | 7 | 00197 - 198 | 8 | 00198 - 199 | 9 | 00199 - 200 | 0 | 00200 - 201 | 1 | 00201 - 203 | 3 | 00203 - 204 | 4 | 00204 - 206 | 6 | 00206 - 207 | 7 | 00207 - 208 | 8 | 00208 - 209 | 9 | 00209 - 210 | 0 | 00210 - 211 | 1 | 00211 - 213 | 3 | 00213 - 214 | 4 | 00214 - 216 | 6 | 00216 - 217 | 7 | 00217 - 218 | 8 | 00218 - 219 | 9 | 00219 - 220 | 0 | 00220 - 221 | 1 | 00221 - 223 | 3 | 00223 - 224 | 4 | 00224 - 226 | 6 | 00226 - 227 | 7 | 00227 - 228 | 8 | 00228 - 229 | 9 | 00229 - 230 | 0 | 00230 - 231 | 1 | 00231 - 233 | 3 | 00233 - 234 | 4 | 00234 - 236 | 6 | 00236 - 237 | 7 | 00237 - 238 | 8 | 00238 - 239 | 9 | 00239 - 240 | 0 | 00240 - 241 | 1 | 00241 - 243 | 3 | 00243 - 244 | 4 | 00244 - 246 | 6 | 00246 - 247 | 7 | 00247 - 248 | 8 | 00248 - 249 | 9 | 00249 - 250 | 0 | 00250 - 251 | 1 | 00251 - 253 | 3 | 00253 - 254 | 4 | 00254 - 256 | 6 | 00256 - 257 | 7 | 00257 - 258 | 8 | 00258 - 259 | 9 | 00259 - 260 | 0 | 00260 - 261 | 1 | 00261 - 263 | 3 | 00263 - 264 | 4 | 00264 - 266 | 6 | 00266 - 267 | 7 | 00267 - 268 | 8 | 00268 - 269 | 9 | 00269 - 270 | 0 | 00270 - 271 | 1 | 00271 - 273 | 3 | 00273 - 274 | 4 | 00274 - 276 | 6 | 00276 - 277 | 7 | 00277 - 278 | 8 | 00278 - 279 | 9 | 00279 - 280 | 0 | 00280 - 281 | 1 | 00281 - 283 | 3 | 00283 - 284 | 4 | 00284 - 286 | 6 | 00286 - 287 | 7 | 00287 - 288 | 8 | 00288 - 289 | 9 | 00289 - 290 | 0 | 00290 - 291 | 1 | 00291 - 293 | 3 | 00293 - 294 | 4 | 00294 - 296 | 6 | 00296 - 297 | 7 | 00297 - 298 | 8 | 00298 - 299 | 9 | 00299 - 300 | 0 | 00300 - 301 | 1 | 00301 - 303 | 3 | 00303 - 304 | 4 | 00304 - 306 | 6 | 00306 - 307 | 7 | 00307 - 308 | 8 | 00308 - 309 | 9 | 00309 - 310 | 0 | 00310 - 311 | 1 | 00311 - 313 | 3 | 00313 - 314 | 4 | 00314 - 316 | 6 | 00316 - 317 | 7 | 00317 - 318 | 8 | 00318 - 319 | 9 | 00319 - 320 | 0 | 00320 - 321 | 1 | 00321 - 323 | 3 | 00323 - 324 | 4 | 00324 - 326 | 6 | 00326 - 327 | 7 | 00327 - 328 | 8 | 00328 - 329 | 9 | 00329 - 330 | 0 | 00330 - 331 | 1 | 00331 - 333 | 3 | 00333 - 334 | 4 | 00334 - 336 | 6 | 00336 - 337 | 7 | 00337 - 338 | 8 | 00338 - 339 | 9 | 00339 - 340 | 0 | 00340 - 341 | 1 | 00341 - 343 | 3 | 00343 - 344 | 4 | 00344 - 346 | 6 | 00346 - 347 | 7 | 00347 - 348 | 8 | 00348 - 349 | 9 | 00349 - 350 | 0 | 00350 - 351 | 1 | 00351 - 353 | 3 | 00353 - 354 | 4 | 00354 - 356 | 6 | 00356 - 357 | 7 | 00357 - 358 | 8 | 00358 - 359 | 9 | 00359 - 360 | 0 | 00360 - 361 | 1 | 00361 - 363 | 3 | 00363 - 364 | 4 | 00364 - 366 | 6 | 00366 - 367 | 7 | 00367 - 368 | 8 | 00368 - 369 | 9 | 00369 - 370 | 0 | 00370 - 371 | 1 | 00371 - 373 | 3 | 00373 - 374 | 4 | 00374 - 376 | 6 | 00376 - 377 | 7 | 00377 - 378 | 8 | 00378 - 379 | 9 | 00379 - 380 | 0 | 00380 - 381 | 1 | 00381 - 383 | 3 | 00383 - 384 | 4 | 00384 - 386 | 6 | 00386 - 387 | 7 | 00387 - 388 | 8 | 00388 - 389 | 9 | 00389 - 390 | 0 | 00390 - 391 | 1 | 00391 - 393 | 3 | 00393 - 394 | 4 | 00394 - 396 | 6 | 00396 - 397 | 7 | 00397 - 398 | 8 | 00398 - 399 | 9 | 00399 - 400 | 0 | 00400 - 401 | 1 | 00401 - 403 | 3 | 00403 - 404 | 4 | 00404 - 406 | 6 | 00406 - 407 | 7 | 00407 - 408 | 8 | 00408 - 409 | 9 | 00409 - 410 | 0 | 00410 - 411 | 1 | 00411 - 413 | 3 | 00413 - 414 | 4 | 00414 - 416 | 6 | 00416 - 417 | 7 | 00417 - 418 | 8 | 00418 - 419 | 9 | 00419 - 420 | 0 | 00420 - 421 | 1 | 00421 - 423 | 3 | 00423 - 424 | 4 | 00424 - 426 | 6 | 00426 - 427 | 7 | 00427 - 428 | 8 | 00428 - 429 | 9 | 00429 - 430 | 0 | 00430 - 431 | 1 | 00431 - 433 | 3 | 00433 - 434 | 4 | 00434 - 436 | 6 | 00436 - 437 | 7 | 00437 - 438 | 8 | 00438 - 439 | 9 | 00439 - 440 | 0 | 00440 - 441 | 1 | 00441 - 443 | 3 | 00443 - 444 | 4 | 00444 - 446 | 6 | 00446 - 447 | 7 | 00447 - 448 | 8 | 00448 - 449 | 9 | 00449 - 450 | 0 | 00450 - 451 | 1 | 00451 - 453 | 3 | 00453 - 454 | 4 | 00454 - 456 | 6 | 00456 - 457 | 7 | 00457 - 458 | 8 | 00458 - 459 | 9 | 00459 - 460 | 0 | 00460 - 461 | 1 | 00461 - 463 | 3 | 00463 - 464 | 4 | 00464 - 466 | 6 | 00466 - 467 | 7 | 00467 - 468 | 8 | 00468 - 469 | 9 | 00469 - 470 | 0 | 00470 - 471 | 1 | 00471 - 473 | 3 | 00473 - 474 | 4 | 00474 - 476 | 6 | 00476 - 477 | 7 | 00477 - 478 | 8 | 00478 - 479 | 9 | 00479 - 480 | 0 | 00480 - 481 | 1 | 00481 - 483 | 3 | 00483 - 484 | 4 | 00484 - 486 | 6 | 00486 - 487 | 7 | 00487 - 488 | 8 | 00488 - 489 | 9 | 00489 - 490 | 0 | 00490 - 491 | 1 | 00491 - 493 | 3 | 00493 - 494 | 4 | 00494 - 496 | 6 | 00496 - 497 | 7 | 00497 - 498 | 8 | 00498 - 499 | 9 | 00499 - 500 | 0 | 00500 - 501 | 1 | 00501 - 503 | 3 | 00503 - 504 | 4 | 00504 - 506 | 6 | 00506 - 507 | 7 | 00507 - 508 | 8 | 00508 - 509 | 9 | 00509 - 510 | 0 | 00510 - 511 | 1 | 00511 - 513 | 3 | 00513 - 514 | 4 | 00514 - 516 | 6 | 00516 - 517 | 7 | 00517 - 518 | 8 | 00518 - 519 | 9 | 00519 - 520 | 0 | 00520 - 521 | 1 | 00521 - 523 | 3 | 00523 - 524 | 4 | 00524 - 526 | 6 | 00526 - 527 | 7 | 00527 - 528 | 8 | 00528 - 529 | 9 | 00529 - 530 | 0 | 00530 - 531 | 1 | 00531 - 533 | 3 | 00533 - 534 | 4 | 00534 - 536 | 6 | 00536 - 537 | 7 | 00537 - 538 | 8 | 00538 - 539 | 9 | 00539 - 540 | 0 | 00540 - 541 | 1 | 00541 - 543 | 3 | 00543 - 544 | 4 | 00544 - 546 | 6 | 00546 - 547 | 7 | 00547 - 548 | 8 | 00548 - 549 | 9 | 00549 - 550 | 0 | 00550 - 551 | 1 | 00551 - 553 | 3 | 00553 - 554 | 4 | 00554 - 556 | 6 | 00556 - 557 | 7 | 00557 - 558 | 8 | 00558 - 559 | 9 | 00559 - 560 | 0 | 00560 - 561 | 1 | 00561 - 563 | 3 | 00563 - 564 | 4 | 00564 - 566 | 6 | 00566 - 567 | 7 | 00567 - 568 | 8 | 00568 - 569 | 9 | 00569 - 570 | 0 | 00570 - 571 | 1 | 00571 - 573 | 3 | 00573 - 574 | 4 | 00574 - 576 | 6 | 00576 - 577 | 7 | 00577 - 578 | 8 | 00578 - 579 | 9 | 00579 - 580 | 0 | 00580 - 581 | 1 | 00581 - 583 | 3 | 00583 - 584 | 4 | 00584 - 586 | 6 | 00586 - 587 | 7 | 00587 - 588 | 8 | 00588 - 589 | 9 | 00589 - 590 | 0 | 00590 - 591 | 1 | 00591 - 593 | 3 | 00593 - 594 | 4 | 00594 - 596 | 6 | 00596 - 597 | 7 | 00597 - 598 | 8 | 00598 - 599 | 9 | 00599 - 600 | 0 | 00600 - 601 | 1 | 00601 - 603 | 3 | 00603 - 604 | 4 | 00604 - 606 | 6 | 00606 - 607 | 7 | 00607 - 608 | 8 | 00608 - 609 | 9 | 00609 - 610 | 0 | 00610 - 611 | 1 | 00611 - 613 | 3 | 00613 - 614 | 4 | 00614 - 616 | 6 | 00616 - 617 | 7 | 00617 - 618 | 8 | 00618 - 619 | 9 | 00619 - 620 | 0 | 00620 - 621 | 1 | 00621 - 623 | 3 | 00623 - 624 | 4 | 00624 - 626 | 6 | 00626 - 627 | 7 | 00627 - 628 | 8 | 00628 - 629 | 9 | 00629 - 630 | 0 | 00630 - 631 | 1 | 00631 - 633 | 3 | 00633 - 634 | 4 | 00634 - 636 | 6 | 00636 - 637 | 7 | 00637 - 638 | 8 | 00638 - 639 | 9 | 00639 - 640 | 0 | 00640 - 641 | 1 | 00641 - 643 | 3 | 00643 - 644 | 4 | 00644 - 646 | 6 | 00646 - 647 | 7 | 00647 - 648 | 8 | 00648 - 649 | 9 | 00649 - 650 | 0 | 00650 - 651 | 1 | 00651 - 653 | 3 | 00653 - 654 | 4 | 00654 - 656 | 6 | 00656 - 657 | 7 | 00657 - 658 | 8 | 00658 - 659 | 9 | 00659 - 660 | 0 | 00660 - 661 | 1 | 00661 - 663 | 3 | 00663 - 664 | 4 | 00664 - 666 | 6 | 00666 - 667 | 7 | 00667 - 668 | 8 | 00668 - 669 | 9 | 00669 - 670 | 0 | 00670 - 671 | 1 | 00671 - 673 | 3 | 00673 - 674 | 4 | 00674 - 676 | 6 | 00676 - 677 | 7 | 00677 - 678 | 8 | 00678 - 679 | 9 | 00679 - 680 | 0 | 00680 - 681 | 1 | 00681 - 683 | 3 | 00683 - 684 | 4 | 00684 - 686 | 6 | 00686 - 687 | 7 | 00687 - 688 | 8 | 00688 - 689 | 9 | 00689 - 690 | 0 | 00690 - 691 | 1 | 00691 - 693 | 3 | 00693 - 694 | 4 | 00694 - 696 | 6 | 00696 - 697 | 7 | 00697 - 698 | 8 | 00698 - 699 | 9 | 00699 - 700 | 0 | 00700 - 701 | 1 | 00701 - 703 | 3 | 00703 - 704 | 4 | 00704 - 706 | 6 | 00706 - 707 | 7 | 00707 - 708 | 8 | 00708 - 709 | 9 | 00709 - 710 | 0 | 00710 - 711 | 1 | 00711 - 713 | 3 | 00713 - 714 | 4 | 00714 - 716 | 6 | 00716 - 717 | 7 | 00717 - 718 | 8 | 00718 - 719 | 9 | 00719 - 720 | 0 | 00720 - 721 | 1 | 00721 - 723 | 3 | 00723 - 724 | 4 | 00724 - 726 | 6 | 00726 - 727 | 7 | 00727 - 728 | 8 | 00728 - 729 | 9 | 00729 - 730 | 0 | 00730 - 731 | 1 | 00731 - 733 | 3 | 00733 - 734 | 4 | 00734 - 736 | 6 | 00736 - 737 | 7 | 00737 - 738 | 8 | 00738 - 739 | 9 | 00739 - 740 | 0 | 00740 - 741 | 1 | 00741 - 743 | 3 | 00743 - 744 | 4 | 00744 - 746 | 6 | 00746 - 747 | 7 | 00747 - 748 | 8 | 00748 - 749 | 9 | 00749 - 750 | 0 | 00750 - 751 | 1 | 00751 - 753 | 3 | 00753 - 754 | 4 | 00754 - 756 | 6 | 00756 - 757 | 7 | 00757 - 758 | 8 | 00758 - 759 | 9 | 00759 - 760 | 0 | 00760 - 761 | 1 | 00761 - 763 | 3 | 00763 - 764 | 4 | 00764 - 766 | 6 | 00766 - 767 | 7 | 00767 - 768 | 8 | 00768 - 769 | 9 | 00769 - 770 | 0 | 00770 - 771 | 1 | 00771 - 773 | 3 | 00773 - 774 | 4 | 00774 - 776 | 6 | 00776 - 777 | 7 | 00777 - 778 | 8 | 00778 - 779 | 9 | 00779 - 780 | 0 | 00780 - 781 | 1 | 00781 - 783 | 3 | 00783 - 784 | 4 | 00784 - 786 | 6 | 00786 - 787 | 7 | 00787 - 788 | 8 | 00788 - 789 | 9 | 00789 - 790 | 0 | 00790 - 791 | 1 | 00791 - 793 | 3 | 00793 - 794 | 4 | 00794 - 796 | 6 | 00796 - 797 | 7 | 00797 - 798 | 8 | 00798 - 799 | 9 | 00799 - 800 | 0 | 00800 - 801 | 1 | 00801 - 803 | 3 | 00803 - 804 | 4 | 00804 - 806 | 6 | 00806 - 807 | 7 | 00807 - 808 | 8 | 00808 - 809 | 9 | 00809 - 810 | 0 | 00810 - 811 | 1 | 00811 - 813 | 3 | 00813 - 814 | 4 | 00814 - 816 | 6 | 00816 - 817 | 7 | 00817 - 818 | 8 | 00818 - 819 | 9 | 00819 - 820 | 0 | 00820 - 821 | 1 | 00821 - 823 | 3 | 00823 - 824 | 4 | 00824 - 826 | 6 | 00826 - 827 | 7 | 00827 - 828 | 8 | 00828 - 829 | 9 | 00829 - 830 | 0 | 00830 - 831 | 1 | 00831 - 833 | 3 | 00833 - 834 | 4 | 00834 - 836 | 6 | 00836 - 837 | 7 | 00837 - 838 | 8 | 00838 - 839 | 9 | 00839 - 840 | 0 | 00840 - 841 | 1 | 00841 - 843 | 3 | 00843 - 844 | 4 | 00844 - 846 | 6 | 00846 - 847 | 7 | 00847 - 848 | 8 | 00848 - 849 | 9 | 00849 - 850 | 0 | 00850 - 851 | 1 | 00851 - 853 | 3 | 00853 - 854 | 4 | 00854 - 856 | 6 | 00856 - 857 | 7 | 00857 - 858 | 8 | 00858 - 859 | 9 | 00859 - 860 | 0 | 00860 - 861 | 1 | 00861 - 863 | 3 | 00863 - 864 | 4 | 00864 - 866 | 6 | 00866 - 867 | 7 | 00867 - 868 | 8 | 00868 - 869 | 9 | 00869 - 870 | 0 | 00870 - 871 | 1 | 00871 - 873 | 3 | 00873 - 874 | 4 | 00874 - 876 | 6 | 00876 - 877 | 7 | 00877 - 878 | 8 | 00878 - 879 | 9 | 00879 - 880 | 0 | 00880 - 881 | 1 | 00881 - 883 | 3 | 00883 - 884 | 4 | 00884 - 886 | 6 | 00886 - 887 | 7 | 00887 - 888 | 8 | 00888 - 889 | 9 | 00889 - 890 | 0 | 00890 - 891 | 1 | 00891 - 893 | 3 | 00893 - 894 | 4 | 00894 - 896 | 6 | 00896 - 897 | 7 | 00897 - 898 | 8 | 00898 - 899 | 9 | 00899 - 900 | 0 | 00900 - 901 | 1 | 00901 - 903 | 3 | 00903 - 904 | 4 | 00904 - 906 | 6 | 00906 - 907 | 7 | 00907 - 908 | 8 | 00908 - 909 | 9 | 00909 - 910 | 0 | 00910 - 911 | 1 | 00911 - 913 | 3 | 00913 - 914 | 4 | 00914 - 916 | 6 | 00916 - 917 | 7 | 00917 - 918 | 8 | 00918 - 919 | 9 | 00919 - 920 | 0 | 00920 - 921 | 1 | 00921 - 923 | 3 | 00923 - 924 | 4 | 00924 - 926 | 6 | 00926 - 927 | 7 | 00927 - 928 | 8 | 00928 - 929 | 9 | 00929 - 930 | 0 | 00930 - 931 | 1 | 00931 - 933 | 3 | 00933 - 934 | 4 | 00934 - 936 | 6 | 00936 - 937 | 7 | 00937 - 938 | 8 | 00938 - 939 | 9 | 00939 - 940 | 0 | 00940 - 941 | 1 | 00941 - 943 | 3 | 00943 - 944 | 4 | 00944 - 946 | 6 | 00946 - 947 | 7 | 00947 - 948 | 8 | 00948 - 949 | 9 | 00949 - 950 | 0 | 00950 - 951 | 1 | 00951 - 953 | 3 | 00953 - 954 | 4 | 00954 - 956 | 6 | 00956 - 957 | 7 | 00957 - 958 | 8 | 00958 - 959 | 9 | 00959 - 960 | 0 | 00960 - 961 | 1 | 00961 - 963 | 3 | 00963 - 964 | 4 | 00964 - 966 | 6 | 00966 - 967 | 7 | 00967 - 968 | 8 | 00968 - 969 | 9 | 00969 - 970 | 0 | 00970 - 971 | 1 | 00971 - 973 | 3 | 00973 - 974 | 4 | 00974 - 976 | 6 | 00976 - 977 | 7 | 00977 - 978 | 8 | 00978 - 979 | 9 | 00979 - 980 | 0 | 00980 - 981 | 1 | 00981 - 983 | 3 | 00983 - 984 | 4 | 00984 - 986 | 6 | 00986 - 987 | 7 | 00987 - 988 | 8 | 00988 - 989 | 9 | 00989 - 990 | 0 | 00990 - 991 | 1 | 00991 - 993 | 3 | 00993 - 994 | 4 | 00994 - 996 | 6 | 00996 - 997 | 7 | 00997 - 998 | 8 | 00998 - 999 | 9 | 00999 - 1000 | 0 | 01000 - 1001 | 101 | 0000100001 - 1003 | 103 | 0000300003 - 1004 | 104 | 0000400004 - 1006 | 106 | 0000600006 - 1007 | 107 | 0000700007 - 1008 | 108 | 0000800008 - 1009 | 109 | 0000900009 - 1010 | 100 | 0001000010 - 1011 | 101 | 0001100011 - 1013 | 103 | 0001300013 - 1014 | 104 | 0001400014 - 1016 | 106 | 0001600016 - 1017 | 107 | 0001700017 - 1018 | 108 | 0001800018 - 1019 | 109 | 0001900019 - 1020 | 100 | 0002000020 - 1101 | 201 | aaa - 1103 | 203 | ccc - 1104 | 204 | ddd -(819 rows) - ---Testcase 384: -EXPLAIN (verbose, costs off) -INSERT INTO ft2 (c1,c2,c3) VALUES (1200,999,'foo'); - QUERY PLAN ------------------------------------------------------------------------------------------------------------------------------------------------------------- - Insert on public.ft2 - -> Result - Output: 1200, 999, NULL::integer, 'foo'::text, NULL::timestamp without time zone, NULL::character varying, 'ft2 '::character(10), NULL::text -(3 rows) - ---Testcase 385: -INSERT INTO ft2 (c1,c2,c3) VALUES (1200,999,'foo'); ---Testcase 386: -SELECT c1 FROM ft2 WHERE c1 = 1200 AND c2 = 999; - c1 ------- - 1200 -(1 row) - ---EXPLAIN (verbose, costs off) ---UPDATE ft2 SET c3 = 'bar' WHERE c1 = 1200 RETURNING tableoid::regclass; -- can be pushed down ---UPDATE ft2 SET c3 = 'bar' WHERE c1 = 1200 RETURNING tableoid::regclass; ---Testcase 387: -EXPLAIN (verbose, costs off) -DELETE FROM ft2 WHERE c1 = 1200; - QUERY PLAN ------------------------------------------------------------------------------ - Delete on public.ft2 - -> Foreign Scan on public.ft2 - Output: c3, "time" - InfluxDB query: SELECT "c3", "C 1" FROM "T1" WHERE (("C 1" = 1200)) -(4 rows) - ---Testcase 388: -SELECT c1 FROM ft2 WHERE c1 = 1200; - c1 ------- - 1200 -(1 row) - ---Testcase 389: -DELETE FROM ft2 WHERE c1 = 1200; ---Testcase 390: -SELECT c1 FROM ft2 WHERE c1 = 1200; - c1 ----- -(0 rows) - --- Test UPDATE/DELETE with RETURNING on a three-table join ---Testcase 391: -INSERT INTO ft2 (c1,c2,c3) - SELECT id, id - 1200, to_char(id, 'FM00000') FROM generate_series(1201, 1300) id; ---EXPLAIN (verbose, costs off) ---UPDATE ft2 SET c3 = 'foo' --- FROM ft4 INNER JOIN ft5 ON (ft4.c1 = ft5.c1) --- WHERE ft2.c1 > 1200 AND ft2.c2 = ft4.c1 --- RETURNING ft2, ft2.*, ft4, ft4.*; -- can be pushed down ---UPDATE ft2 SET c3 = 'foo' --- FROM ft4 INNER JOIN ft5 ON (ft4.c1 = ft5.c1) --- WHERE ft2.c1 > 1200 AND ft2.c2 = ft4.c1 --- RETURNING ft2, ft2.*, ft4, ft4.*; ---Testcase 392: -EXPLAIN (verbose, costs off) -DELETE FROM ft2 - USING ft4 LEFT JOIN ft5 ON (ft4.c1 = ft5.c1) - WHERE ft2.c1 > 1200 AND ft2.c1 % 10 = 0 AND ft2.c2 = ft4.c1; -- can be pushed down - QUERY PLAN ------------------------------------------------------------------------------------------------------------------------------ - Delete on public.ft2 - -> Hash Right Join - Output: ft2.c3, ft2."time", ft4.*, ft5.* - Hash Cond: (ft5.c1 = ft4.c1) - -> Foreign Scan on public.ft5 - Output: ft5.*, ft5.c1 - InfluxDB query: SELECT "c1", "c2", "c3" FROM "T4" - -> Hash - Output: ft2.c3, ft2."time", ft4.*, ft4.c1 - -> Hash Join - Output: ft2.c3, ft2."time", ft4.*, ft4.c1 - Hash Cond: (ft4.c1 = ft2.c2) - -> Foreign Scan on public.ft4 - Output: ft4.*, ft4.c1 - InfluxDB query: SELECT "c1", "c2", "c3" FROM "T3" - -> Hash - Output: ft2.c3, ft2."time", ft2.c2 - -> Foreign Scan on public.ft2 - Output: ft2.c3, ft2."time", ft2.c2 - InfluxDB query: SELECT "c2", "c3" FROM "T1" WHERE (("C 1" > 1200)) AND ((("C 1" % 10) = 0)) -(20 rows) - ---Testcase 393: -SELECT 100 FROM ft2, - ft4 LEFT JOIN ft5 ON (ft4.c1 = ft5.c1) - WHERE ft2.c1 > 1200 AND ft2.c1 % 10 = 0 AND ft2.c2 = ft4.c1; - ?column? ----------- - 100 - 100 - 100 - 100 - 100 - 100 - 100 - 100 - 100 - 100 -(10 rows) - ---Testcase 394: -DELETE FROM ft2 - USING ft4 LEFT JOIN ft5 ON (ft4.c1 = ft5.c1) - WHERE ft2.c1 > 1200 AND ft2.c1 % 10 = 0 AND ft2.c2 = ft4.c1; ---Testcase 395: -SELECT 100 FROM ft2, - ft4 LEFT JOIN ft5 ON (ft4.c1 = ft5.c1) - WHERE ft2.c1 > 1200 AND ft2.c1 % 10 = 0 AND ft2.c2 = ft4.c1; - ?column? ----------- -(0 rows) - ---Testcase 396: -DELETE FROM ft2 WHERE ft2.c1 > 1200; --- Test UPDATE with a MULTIEXPR sub-select --- (maybe someday this'll be remotely executable, but not today) ---EXPLAIN (verbose, costs off) ---UPDATE ft2 AS target SET (c2, c7) = ( --- SELECT c2 * 10, c7 --- FROM ft2 AS src --- WHERE target.c1 = src.c1 ---) WHERE c1 > 1100; ---UPDATE ft2 AS target SET (c2, c7) = ( --- SELECT c2 * 10, c7 --- FROM ft2 AS src --- WHERE targ--et.c1 = src.c1 ---) WHERE c1 > 1100; ---UPDATE ft2 AS target SET (c2) = ( --- SELECT c2 / 10 --- FROM ft2 AS src --- WHERE targ--et.c1 = src.c1 ---) WHERE c1 > 1100; --- Test UPDATE/DELETE with WHERE or JOIN/ON conditions containing --- user-defined operators/functions ---Testcase 397: -INSERT INTO ft2 (c1,c2,c3) - SELECT id, id % 10, to_char(id, 'FM00000') FROM generate_series(2001, 2010) id; ---EXPLAIN (verbose, costs off) ---UPDATE ft2 SET c3 = 'bar' WHERE influxdb_fdw_abs(c1) > 2000 RETURNING *; -- can't be pushed down ---UPDATE ft2 SET c3 = 'bar' WHERE influxdb_fdw_abs(c1) > 2000 RETURNING *; ---EXPLAIN (verbose, costs off) ---UPDATE ft2 SET c3 = 'baz' --- FROM ft4 INNER JOIN ft5 ON (ft4.c1 = ft5.c1) --- WHERE ft2.c1 > 2000 AND ft2.c2 === ft4.c1 --- RETURNING ft2.*, ft4.*, ft5.*; -- can't be pushed down ---UPDATE ft2 SET c3 = 'baz' --- FROM ft4 INNER JOIN ft5 ON (ft4.c1 = ft5.c1) --- WHERE ft2.c1 > 2000 AND ft2.c2 === ft4.c1 --- RETURNING ft2.*, ft4.*, ft5.*; ---Testcase 398: -EXPLAIN (verbose, costs off) -DELETE FROM ft2 - USING ft4 INNER JOIN ft5 ON (ft4.c1 === ft5.c1) - WHERE ft2.c1 > 2000 AND ft2.c2 = ft4.c1; -- can't be pushed down - QUERY PLAN ----------------------------------------------------------------------------------------------- - Delete on public.ft2 - -> Nested Loop - Output: ft2.c3, ft2."time", ft4.*, ft5.* - Join Filter: (ft4.c1 === ft5.c1) - -> Hash Join - Output: ft2.c3, ft2."time", ft4.*, ft4.c1 - Hash Cond: (ft4.c1 = ft2.c2) - -> Foreign Scan on public.ft4 - Output: ft4.*, ft4.c1 - InfluxDB query: SELECT "c1", "c2", "c3" FROM "T3" - -> Hash - Output: ft2.c3, ft2."time", ft2.c2 - -> Foreign Scan on public.ft2 - Output: ft2.c3, ft2."time", ft2.c2 - InfluxDB query: SELECT "c2", "c3" FROM "T1" WHERE (("C 1" > 2000)) - -> Materialize - Output: ft5.*, ft5.c1 - -> Foreign Scan on public.ft5 - Output: ft5.*, ft5.c1 - InfluxDB query: SELECT "c1", "c2", "c3" FROM "T4" -(20 rows) - ---Testcase 399: -SELECT ft2.c1, ft2.c2, ft2.c3 - FROM ft2, ft4 INNER JOIN ft5 ON (ft4.c1 === ft5.c1) - WHERE ft2.c1 > 2000 AND ft2.c2 = ft4.c1; - c1 | c2 | c3 -------+----+------- - 2006 | 6 | 02006 -(1 row) - ---Testcase 400: -DELETE FROM ft2 - USING ft4 INNER JOIN ft5 ON (ft4.c1 === ft5.c1) - WHERE ft2.c1 > 2000 AND ft2.c2 = ft4.c1; ---Testcase 401: -SELECT ft2.c1, ft2.c2, ft2.c3 - FROM ft2, ft4 INNER JOIN ft5 ON (ft4.c1 === ft5.c1) - WHERE ft2.c1 > 2000 AND ft2.c2 = ft4.c1; - c1 | c2 | c3 -----+----+---- -(0 rows) - ---Testcase 402: -DELETE FROM ft2 WHERE ft2.c1 > 2000; --- Test that trigger on remote table works as expected ---Testcase 403: -CREATE OR REPLACE FUNCTION "S 1".F_BRTRIG() RETURNS trigger AS $$ -BEGIN - NEW.c3 = NEW.c3 || '_trig_update'; - RETURN NEW; -END; -$$ LANGUAGE plpgsql; ---Testcase 404: -CREATE TRIGGER t1_br_insert BEFORE INSERT OR UPDATE - ON "S 1"."T 1" FOR EACH ROW EXECUTE PROCEDURE "S 1".F_BRTRIG(); ---Testcase 405: -INSERT INTO ft2 (c1,c2,c3) VALUES (1208, 818, 'fff'); ---Testcase 406: -SELECT c1, c2, c3, c6, c7, c8 FROM ft2 WHERE c1 = 1208; - c1 | c2 | c3 | c6 | c7 | c8 -------+-----+-----+----+------------+---- - 1208 | 818 | fff | | ft2 | -(1 row) - ---Testcase 407: -INSERT INTO ft2 (c1,c2,c3,c6) VALUES (1218, 818, 'ggg', '(--;'); ---Testcase 408: -SELECT c1, c2, c3, c6, c7, c8 FROM ft2 WHERE c1 = 1218; - c1 | c2 | c3 | c6 | c7 | c8 -------+-----+-----+------+------------+---- - 1218 | 818 | ggg | (--; | ft2 | -(1 row) - ---UPDATE ft2 SET c2 = c2 + 600 WHERE c1 % 10 = 8 AND c1 < 1200 RETURNING *; --- Test errors thrown on remote side during update -ALTER TABLE "S 1"."T 1" ADD CONSTRAINT c2positive CHECK (c2 >= 0); --- influxdb_fdw does not support key, ON CONFLICT ---INSERT INTO ft1(c1, c2) VALUES(11, 12); -- duplicate key ---Testcase 409: -INSERT INTO ft1(c1, c2) VALUES(11, 12) ON CONFLICT DO NOTHING; -- works -ERROR: ON CONFLICT is not supported ---Testcase 410: -INSERT INTO ft1(c1, c2) VALUES(11, 12) ON CONFLICT (c1, c2) DO NOTHING; -- unsupported -ERROR: there is no unique or exclusion constraint matching the ON CONFLICT specification ---Testcase 411: -INSERT INTO ft1(c1, c2) VALUES(11, 12) ON CONFLICT (c1, c2) DO UPDATE SET c3 = 'ffg'; -- unsupported -ERROR: there is no unique or exclusion constraint matching the ON CONFLICT specification ---INSERT INTO ft1(c1, c2) VALUES(1111, -2); -- c2positive ---UPDATE ft1 SET c2 = -c2 WHERE c1 = 1; -- c2positive -/* --- influxdb_fdw does not support transactions --- Test savepoint/rollback behavior -select c2, count(*) from ft2 where c2 < 500 group by 1 order by 1; -select c2, count(*) from "S 1"."T 1" where c2 < 500 group by 1 order by 1; -begin; -update ft2 set c2 = 42 where c2 = 0; -select c2, count(*) from ft2 where c2 < 500 group by 1 order by 1; -savepoint s1; -update ft2 set c2 = 44 where c2 = 4; -select c2, count(*) from ft2 where c2 < 500 group by 1 order by 1; -release savepoint s1; -select c2, count(*) from ft2 where c2 < 500 group by 1 order by 1; -savepoint s2; -update ft2 set c2 = 46 where c2 = 6; -select c2, count(*) from ft2 where c2 < 500 group by 1 order by 1; -rollback to savepoint s2; -select c2, count(*) from ft2 where c2 < 500 group by 1 order by 1; -release savepoint s2; -select c2, count(*) from ft2 where c2 < 500 group by 1 order by 1; -savepoint s3; -update ft2 set c2 = -2 where c2 = 42 and c1 = 10; -- fail on remote side -rollback to savepoint s3; -select c2, count(*) from ft2 where c2 < 500 group by 1 order by 1; -release savepoint s3; -select c2, count(*) from ft2 where c2 < 500 group by 1 order by 1; --- none of the above is committed yet remotely -select c2, count(*) from "S 1"."T 1" where c2 < 500 group by 1 order by 1; -commit; -select c2, count(*) from ft2 where c2 < 500 group by 1 order by 1; -select c2, count(*) from "S 1"."T 1" where c2 < 500 group by 1 order by 1; -*/ --- Above DMLs add data with c6 as NULL in ft1, so test ORDER BY NULLS LAST and NULLs --- FIRST behavior here. --- ORDER BY DESC NULLS LAST options ---Testcase 412: -EXPLAIN (VERBOSE, COSTS OFF) SELECT * FROM ft1 ORDER BY c6 DESC NULLS LAST, c1 OFFSET 795 LIMIT 10; - QUERY PLAN ------------------------------------------------------------------------------------- - Limit - Output: c1, c2, c3, "time", c6, c7, c8 - -> Sort - Output: c1, c2, c3, "time", c6, c7, c8 - Sort Key: ft1.c6 DESC NULLS LAST, ft1.c1 - -> Foreign Scan on public.ft1 - Output: c1, c2, c3, "time", c6, c7, c8 - InfluxDB query: SELECT "C 1", "c2", "c3", "c6", "c7", "c8" FROM "T1" -(8 rows) - ---Testcase 413: -SELECT c1, c2, c3, c6, c7, c8 FROM ft1 ORDER BY c6 DESC NULLS LAST, c1 OFFSET 795 LIMIT 10; - c1 | c2 | c3 | c6 | c7 | c8 -------+-----+------------+------+------------+----- - 960 | 0 | 00960 | 0 | 0 | foo - 970 | 0 | 00970 | 0 | 0 | foo - 980 | 0 | 00980 | 0 | 0 | foo - 990 | 0 | 00990 | 0 | 0 | foo - 1000 | 0 | 01000 | 0 | 0 | foo - 1218 | 818 | ggg | (--; | ft2 | - 1001 | 101 | 0000100001 | | ft2 | - 1003 | 103 | 0000300003 | | ft2 | - 1004 | 104 | 0000400004 | | ft2 | - 1006 | 106 | 0000600006 | | ft2 | -(10 rows) - --- ORDER BY DESC NULLS FIRST options ---Testcase 414: -EXPLAIN (VERBOSE, COSTS OFF) SELECT * FROM ft1 ORDER BY c6 DESC NULLS FIRST, c1 OFFSET 15 LIMIT 10; - QUERY PLAN ------------------------------------------------------------------------------------- - Limit - Output: c1, c2, c3, "time", c6, c7, c8 - -> Sort - Output: c1, c2, c3, "time", c6, c7, c8 - Sort Key: ft1.c6 DESC, ft1.c1 - -> Foreign Scan on public.ft1 - Output: c1, c2, c3, "time", c6, c7, c8 - InfluxDB query: SELECT "C 1", "c2", "c3", "c6", "c7", "c8" FROM "T1" -(8 rows) - ---Testcase 415: -SELECT c1, c2, c3, c6, c7, c8 FROM ft1 ORDER BY c6 DESC NULLS FIRST, c1 OFFSET 15 LIMIT 10; - c1 | c2 | c3 | c6 | c7 | c8 -------+-----+------------+----+------------+----- - 1020 | 100 | 0002000020 | | ft2 | - 1101 | 201 | aaa | | ft2 | - 1103 | 203 | ccc | | ft2 | - 1104 | 204 | ddd | | ft2 | - 1208 | 818 | fff | | ft2 | - 9 | 9 | 00009 | 9 | 9 | foo - 19 | 9 | 00019 | 9 | 9 | foo - 29 | 9 | 00029 | 9 | 9 | foo - 39 | 9 | 00039 | 9 | 9 | foo - 49 | 9 | 00049 | 9 | 9 | foo -(10 rows) - --- ORDER BY ASC NULLS FIRST options ---Testcase 416: -EXPLAIN (VERBOSE, COSTS OFF) SELECT * FROM ft1 ORDER BY c6 ASC NULLS FIRST, c1 OFFSET 15 LIMIT 10; - QUERY PLAN ------------------------------------------------------------------------------------- - Limit - Output: c1, c2, c3, "time", c6, c7, c8 - -> Sort - Output: c1, c2, c3, "time", c6, c7, c8 - Sort Key: ft1.c6 NULLS FIRST, ft1.c1 - -> Foreign Scan on public.ft1 - Output: c1, c2, c3, "time", c6, c7, c8 - InfluxDB query: SELECT "C 1", "c2", "c3", "c6", "c7", "c8" FROM "T1" -(8 rows) - ---Testcase 417: -SELECT c1, c2, c3, c6, c7, c8 FROM ft1 ORDER BY c6 ASC NULLS FIRST, c1 OFFSET 15 LIMIT 10; - c1 | c2 | c3 | c6 | c7 | c8 -------+-----+------------+------+------------+----- - 1020 | 100 | 0002000020 | | ft2 | - 1101 | 201 | aaa | | ft2 | - 1103 | 203 | ccc | | ft2 | - 1104 | 204 | ddd | | ft2 | - 1208 | 818 | fff | | ft2 | - 1218 | 818 | ggg | (--; | ft2 | - 10 | 0 | 00010 | 0 | 0 | foo - 20 | 0 | 00020 | 0 | 0 | foo - 30 | 0 | 00030 | 0 | 0 | foo - 40 | 0 | 00040 | 0 | 0 | foo -(10 rows) - --- =================================================================== --- test check constraints --- =================================================================== --- Consistent check constraints provide consistent results -ALTER FOREIGN TABLE ft1 ADD CONSTRAINT ft1_c2positive CHECK (c2 >= 0); ---Testcase 418: -EXPLAIN (VERBOSE, COSTS OFF) SELECT count(*) FROM ft1 WHERE c2 < 0; - QUERY PLAN ----------------------------------------------------------------- - Foreign Scan - Output: (count(*)) - InfluxDB query: SELECT count(*) FROM "T1" WHERE (("c2" < 0)) -(3 rows) - --- InfluxDB return null value because it does not have any record. ---Testcase 419: -SELECT count(*) FROM ft1 WHERE c2 < 0; - count -------- -(0 rows) - -SET constraint_exclusion = 'on'; ---Testcase 420: -EXPLAIN (VERBOSE, COSTS OFF) SELECT count(*) FROM ft1 WHERE c2 < 0; - QUERY PLAN --------------------------------- - Aggregate - Output: count(*) - -> Result - One-Time Filter: false -(4 rows) - ---Testcase 421: -SELECT count(*) FROM ft1 WHERE c2 < 0; - count -------- - 0 -(1 row) - -RESET constraint_exclusion; --- check constraint is enforced on the remote side, not locally --- INSERT INTO ft1(c1, c2) VALUES(1111, -2); -- c2positive --- UPDATE ft1 SET c2 = -c2 WHERE c1 = 1; -- c2positive -ALTER FOREIGN TABLE ft1 DROP CONSTRAINT ft1_c2positive; --- But inconsistent check constraints provide inconsistent results -ALTER FOREIGN TABLE ft1 ADD CONSTRAINT ft1_c2negative CHECK (c2 < 0); ---Testcase 422: -EXPLAIN (VERBOSE, COSTS OFF) SELECT count(*) FROM ft1 WHERE c2 >= 0; - QUERY PLAN ------------------------------------------------------------------ - Foreign Scan - Output: (count(*)) - InfluxDB query: SELECT count(*) FROM "T1" WHERE (("c2" >= 0)) -(3 rows) - ---Testcase 423: -SELECT count(*) FROM ft1 WHERE c2 >= 0; - count -------- - 821 -(1 row) - -SET constraint_exclusion = 'on'; ---Testcase 424: -EXPLAIN (VERBOSE, COSTS OFF) SELECT count(*) FROM ft1 WHERE c2 >= 0; - QUERY PLAN --------------------------------- - Aggregate - Output: count(*) - -> Result - One-Time Filter: false -(4 rows) - ---Testcase 425: -SELECT count(*) FROM ft1 WHERE c2 >= 0; - count -------- - 0 -(1 row) - -RESET constraint_exclusion; --- local check constraint is not actually enforced ---Testcase 426: -INSERT INTO ft1(c1, c2) VALUES(1111, 2); --- UPDATE ft1 SET c2 = c2 + 1 WHERE c1 = 1; -ALTER FOREIGN TABLE ft1 DROP CONSTRAINT ft1_c2negative; --- influxdb_fdw does not support this feature --- =================================================================== --- test WITH CHECK OPTION constraints --- =================================================================== ---Testcase 427: -CREATE FUNCTION row_before_insupd_trigfunc() RETURNS trigger AS $$BEGIN NEW.a := NEW.a + 10; RETURN NEW; END$$ LANGUAGE plpgsql; ---Testcase 428: -CREATE FOREIGN TABLE base_tbl (a int, b int) SERVER influxdb_svr OPTIONS (table 'base_tbl'); ---ALTER FOREIGN TABLE base_tbl SET (autovacuum_enabled = 'false'); ---Testcase 429: -CREATE TRIGGER row_before_insupd_trigger BEFORE INSERT OR UPDATE ON base_tbl FOR EACH ROW EXECUTE PROCEDURE row_before_insupd_trigfunc(); ---Testcase 430: -CREATE FOREIGN TABLE foreign_tbl (a int, b int) - SERVER influxdb_svr OPTIONS (table 'base_tbl'); ---Testcase 431: -CREATE VIEW rw_view AS SELECT * FROM base_tbl - WHERE a < b WITH CHECK OPTION; ---Testcase 432: -\d+ rw_view - View "public.rw_view" - Column | Type | Collation | Nullable | Default | Storage | Description ---------+---------+-----------+----------+---------+---------+------------- - a | integer | | | | plain | - b | integer | | | | plain | -View definition: - SELECT base_tbl.a, - base_tbl.b - FROM base_tbl - WHERE base_tbl.a < base_tbl.b; -Options: check_option=cascaded - ---Testcase 433: -EXPLAIN (VERBOSE, COSTS OFF) -INSERT INTO rw_view VALUES (0, 5); - QUERY PLAN ---------------------------- - Insert on public.base_tbl - -> Result - Output: 0, 5 -(3 rows) - ---Testcase 434: -INSERT INTO rw_view VALUES (0, 5); -- should fail -ERROR: new row violates check option for view "rw_view" -DETAIL: Failing row contains (10, 5). ---Testcase 435: -EXPLAIN (VERBOSE, COSTS OFF) -INSERT INTO rw_view VALUES (0, 15); - QUERY PLAN ---------------------------- - Insert on public.base_tbl - -> Result - Output: 0, 15 -(3 rows) - ---Testcase 436: -INSERT INTO rw_view VALUES (0, 15); -- ok ---Testcase 437: -SELECT * FROM foreign_tbl; - a | b -----+---- - 10 | 5 - 10 | 15 -(2 rows) - ---EXPLAIN (VERBOSE, COSTS OFF) ---UPDATE rw_view SET b = b + 5; ---UPDATE rw_view SET b = b + 5; -- should fail ---EXPLAIN (VERBOSE, COSTS OFF) ---UPDATE rw_view SET b = b + 15; ---UPDATE rw_view SET b = b + 15; -- ok ---SELECT * FROM foreign_tbl; ---Testcase 438: -DELETE FROM foreign_tbl; -DROP FOREIGN TABLE foreign_tbl CASCADE; ---Testcase 439: -DROP TRIGGER row_before_insupd_trigger ON base_tbl; ---Testcase 440: -DROP FOREIGN TABLE base_tbl CASCADE; -NOTICE: drop cascades to view rw_view --- influxdb_fdw does not support partitions --- test WCO for partitions ---Testcase 441: -CREATE FOREIGN TABLE child_tbl (a int, b int) SERVER influxdb_svr OPTIONS (table 'child_tbl'); ---ALTER FOREIGN TABLE child_tbl SET (autovacuum_enabled = 'false'); ---Testcase 442: -CREATE TRIGGER row_before_insupd_trigger BEFORE INSERT OR UPDATE ON child_tbl FOR EACH ROW EXECUTE PROCEDURE row_before_insupd_trigfunc(); ---Testcase 443: -CREATE FOREIGN TABLE foreign_tbl (a int, b int) - SERVER influxdb_svr OPTIONS (table 'child_tbl'); ---Testcase 444: -CREATE TABLE parent_tbl (a int, b int) PARTITION BY RANGE(a); -ALTER TABLE parent_tbl ATTACH PARTITION child_tbl FOR VALUES FROM (0) TO (100); ---Testcase 445: -CREATE VIEW rw_view AS SELECT * FROM parent_tbl - WHERE a < b WITH CHECK OPTION; ---Testcase 446: -\d+ rw_view - View "public.rw_view" - Column | Type | Collation | Nullable | Default | Storage | Description ---------+---------+-----------+----------+---------+---------+------------- - a | integer | | | | plain | - b | integer | | | | plain | -View definition: - SELECT parent_tbl.a, - parent_tbl.b - FROM parent_tbl - WHERE parent_tbl.a < parent_tbl.b; -Options: check_option=cascaded - ---Testcase 447: -EXPLAIN (VERBOSE, COSTS OFF) -INSERT INTO rw_view VALUES (0, 5); - QUERY PLAN ------------------------------ - Insert on public.parent_tbl - -> Result - Output: 0, 5 -(3 rows) - ---Testcase 448: -INSERT INTO rw_view VALUES (0, 5); -- should fail -ERROR: Not support partition insert ---Testcase 449: -EXPLAIN (VERBOSE, COSTS OFF) -INSERT INTO rw_view VALUES (0, 15); - QUERY PLAN ------------------------------ - Insert on public.parent_tbl - -> Result - Output: 0, 15 -(3 rows) - ---Testcase 450: -INSERT INTO rw_view VALUES (0, 15); -- ok -ERROR: Not support partition insert ---Testcase 451: -SELECT * FROM foreign_tbl; - a | b ----+--- -(0 rows) - ---EXPLAIN (VERBOSE, COSTS OFF) ---UPDATE rw_view SET b = b + 5; ---UPDATE rw_view SET b = b + 5; -- should fail ---EXPLAIN (VERBOSE, COSTS OFF) ---UPDATE rw_view SET b = b + 15; ---UPDATE rw_view SET b = b + 15; -- ok ---SELECT * FROM foreign_tbl; ---Testcase 452: -DROP FOREIGN TABLE foreign_tbl CASCADE; ---Testcase 453: -DROP TRIGGER row_before_insupd_trigger ON child_tbl; ---Testcase 454: -DROP FOREIGN TABLE child_tbl CASCADE; ---Testcase 455: -DROP TABLE parent_tbl CASCADE; -NOTICE: drop cascades to view rw_view ---Testcase 456: -DROP FUNCTION row_before_insupd_trigfunc; --- =================================================================== --- test serial columns (ie, sequence-based defaults) --- =================================================================== ---Testcase 457: -create foreign table loc1 (f1 serial, f2 text) - server influxdb_svr options(table 'loc1'); ---alter foreign table loc1 set (autovacuum_enabled = 'false'); ---Testcase 458: -create foreign table rem1 (f1 serial, f2 text) - server influxdb_svr options(table 'loc1'); ---Testcase 459: -select pg_catalog.setval('rem1_f1_seq', 10, false); - setval --------- - 10 -(1 row) - ---Testcase 460: -insert into loc1(f2) values('hi'); ---Testcase 461: -insert into rem1(f2) values('hi remote'); ---Testcase 462: -insert into loc1(f2) values('bye'); ---Testcase 463: -insert into rem1(f2) values('bye remote'); ---Testcase 464: -select * from loc1; - f1 | f2 -----+------------ - 1 | hi - 10 | hi remote - 2 | bye - 11 | bye remote -(4 rows) - ---Testcase 465: -select * from rem1; - f1 | f2 -----+------------ - 1 | hi - 10 | hi remote - 2 | bye - 11 | bye remote -(4 rows) - --- =================================================================== --- test generated columns --- =================================================================== ---Testcase 466: -create foreign table gloc1 (a int, b int generated always as (a * 2) stored) - server influxdb_svr options(table 'gloc1'); -ERROR: syntax error at or near "(" -LINE 1: ...ign table gloc1 (a int, b int generated always as (a * 2) st... - ^ ---alter foreign table gloc1 set (autovacuum_enabled = 'false'); ---Testcase 467: -create foreign table grem1 ( - a int, - b int generated always as (a * 2) stored) - server influxdb_svr options(table 'gloc1'); -ERROR: syntax error at or near "(" -LINE 3: b int generated always as (a * 2) stored) - ^ ---Testcase 468: -insert into grem1 (a) values (1), (22); -ERROR: relation "grem1" does not exist -LINE 1: insert into grem1 (a) values (1), (22); - ^ ---update grem1 set a = 22 where a = 2; ---Testcase 469: -select * from gloc1; -ERROR: relation "gloc1" does not exist -LINE 1: select * from gloc1; - ^ ---Testcase 470: -select * from grem1; -ERROR: relation "grem1" does not exist -LINE 1: select * from grem1; - ^ --- Clean up: -delete from grem1; -ERROR: relation "grem1" does not exist -LINE 1: delete from grem1; - ^ --- =================================================================== --- test local triggers --- =================================================================== --- Trigger functions "borrowed" from triggers regress test. ---Testcase 471: -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;$$; ---Testcase 472: -CREATE TRIGGER trig_stmt_before BEFORE DELETE OR INSERT OR UPDATE ON rem1 - FOR EACH STATEMENT EXECUTE PROCEDURE trigger_func(); ---Testcase 473: -CREATE TRIGGER trig_stmt_after AFTER DELETE OR INSERT OR UPDATE ON rem1 - FOR EACH STATEMENT EXECUTE PROCEDURE trigger_func(); ---Testcase 474: -CREATE OR REPLACE FUNCTION trigger_data() RETURNS trigger -LANGUAGE plpgsql AS $$ - -declare - oldnew text[]; - relid text; - argstr text; -begin - - relid := TG_relid::regclass; - argstr := ''; - 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 '%(%) % % % ON %', - tg_name, argstr, TG_when, TG_level, TG_OP, relid; - oldnew := '{}'::text[]; - if TG_OP != 'INSERT' then - oldnew := array_append(oldnew, format('OLD: %s', OLD)); - end if; - - if TG_OP != 'DELETE' then - oldnew := array_append(oldnew, format('NEW: %s', NEW)); - end if; - - RAISE NOTICE '%', array_to_string(oldnew, ','); - - if TG_OP = 'DELETE' then - return OLD; - else - return NEW; - end if; -end; -$$; --- Test basic functionality ---Testcase 475: -CREATE TRIGGER trig_row_before -BEFORE INSERT OR UPDATE OR DELETE ON rem1 -FOR EACH ROW EXECUTE PROCEDURE trigger_data(23,'skidoo'); ---Testcase 476: -CREATE TRIGGER trig_row_after -AFTER INSERT OR UPDATE OR DELETE ON rem1 -FOR EACH ROW EXECUTE PROCEDURE trigger_data(23,'skidoo'); ---Testcase 477: -delete from rem1; -NOTICE: trigger_func() called: action = DELETE, when = BEFORE, level = STATEMENT -NOTICE: trig_row_before(23, skidoo) BEFORE ROW DELETE ON rem1 -NOTICE: OLD: (1,hi) -NOTICE: trig_row_before(23, skidoo) BEFORE ROW DELETE ON rem1 -NOTICE: OLD: (10,"hi remote") -NOTICE: trig_row_before(23, skidoo) BEFORE ROW DELETE ON rem1 -NOTICE: OLD: (2,bye) -NOTICE: trig_row_before(23, skidoo) BEFORE ROW DELETE ON rem1 -NOTICE: OLD: (11,"bye remote") -NOTICE: trig_row_after(23, skidoo) AFTER ROW DELETE ON rem1 -NOTICE: OLD: (1,hi) -NOTICE: trig_row_after(23, skidoo) AFTER ROW DELETE ON rem1 -NOTICE: OLD: (10,"hi remote") -NOTICE: trig_row_after(23, skidoo) AFTER ROW DELETE ON rem1 -NOTICE: OLD: (2,bye) -NOTICE: trig_row_after(23, skidoo) AFTER ROW DELETE ON rem1 -NOTICE: OLD: (11,"bye remote") -NOTICE: trigger_func() called: action = DELETE, when = AFTER, level = STATEMENT ---Testcase 478: -insert into rem1 values(1,'insert'); -NOTICE: trigger_func() called: action = INSERT, when = BEFORE, level = STATEMENT -NOTICE: trig_row_before(23, skidoo) BEFORE ROW INSERT ON rem1 -NOTICE: NEW: (1,insert) -NOTICE: trig_row_after(23, skidoo) AFTER ROW INSERT ON rem1 -NOTICE: NEW: (1,insert) -NOTICE: trigger_func() called: action = INSERT, when = AFTER, level = STATEMENT ---update rem1 set f2 = 'update' where f1 = 1; ---update rem1 set f2 = f2 || f2; --- cleanup ---Testcase 479: -DROP TRIGGER trig_row_before ON rem1; ---Testcase 480: -DROP TRIGGER trig_row_after ON rem1; ---Testcase 481: -DROP TRIGGER trig_stmt_before ON rem1; ---Testcase 482: -DROP TRIGGER trig_stmt_after ON rem1; ---Testcase 483: -DELETE from rem1; --- Test multiple AFTER ROW triggers on a foreign table ---Testcase 484: -CREATE TRIGGER trig_row_after1 -AFTER INSERT OR UPDATE OR DELETE ON rem1 -FOR EACH ROW EXECUTE PROCEDURE trigger_data(23,'skidoo'); ---Testcase 485: -CREATE TRIGGER trig_row_after2 -AFTER INSERT OR UPDATE OR DELETE ON rem1 -FOR EACH ROW EXECUTE PROCEDURE trigger_data(23,'skidoo'); ---Testcase 486: -insert into rem1 values(1,'insert'); -NOTICE: trig_row_after1(23, skidoo) AFTER ROW INSERT ON rem1 -NOTICE: NEW: (1,insert) -NOTICE: trig_row_after2(23, skidoo) AFTER ROW INSERT ON rem1 -NOTICE: NEW: (1,insert) ---update rem1 set f2 = 'update' where f1 = 1; ---update rem1 set f2 = f2 || f2; ---Testcase 487: -delete from rem1; -NOTICE: trig_row_after1(23, skidoo) AFTER ROW DELETE ON rem1 -NOTICE: OLD: (1,insert) -NOTICE: trig_row_after2(23, skidoo) AFTER ROW DELETE ON rem1 -NOTICE: OLD: (1,insert) --- cleanup ---Testcase 488: -DROP TRIGGER trig_row_after1 ON rem1; ---Testcase 489: -DROP TRIGGER trig_row_after2 ON rem1; --- Test WHEN conditions ---Testcase 490: -CREATE TRIGGER trig_row_before_insupd -BEFORE INSERT OR UPDATE ON rem1 -FOR EACH ROW -WHEN (NEW.f2 like '%update%') -EXECUTE PROCEDURE trigger_data(23,'skidoo'); ---Testcase 491: -CREATE TRIGGER trig_row_after_insupd -AFTER INSERT OR UPDATE ON rem1 -FOR EACH ROW -WHEN (NEW.f2 like '%update%') -EXECUTE PROCEDURE trigger_data(23,'skidoo'); --- Insert or update not matching: nothing happens ---Testcase 492: -INSERT INTO rem1 values(1, 'insert'); ---UPDATE rem1 set f2 = 'test'; --- Insert or update matching: triggers are fired ---Testcase 493: -INSERT INTO rem1 values(2, 'update'); -NOTICE: trig_row_before_insupd(23, skidoo) BEFORE ROW INSERT ON rem1 -NOTICE: NEW: (2,update) -NOTICE: trig_row_after_insupd(23, skidoo) AFTER ROW INSERT ON rem1 -NOTICE: NEW: (2,update) ---UPDATE rem1 set f2 = 'update update' where f1 = '2'; ---Testcase 494: -CREATE TRIGGER trig_row_before_delete -BEFORE DELETE ON rem1 -FOR EACH ROW -WHEN (OLD.f2 like '%update%') -EXECUTE PROCEDURE trigger_data(23,'skidoo'); ---Testcase 495: -CREATE TRIGGER trig_row_after_delete -AFTER DELETE ON rem1 -FOR EACH ROW -WHEN (OLD.f2 like '%update%') -EXECUTE PROCEDURE trigger_data(23,'skidoo'); --- Trigger is fired for f1=2, not for f1=1 ---Testcase 496: -DELETE FROM rem1; -NOTICE: trig_row_before_delete(23, skidoo) BEFORE ROW DELETE ON rem1 -NOTICE: OLD: (2,update) -NOTICE: trig_row_after_delete(23, skidoo) AFTER ROW DELETE ON rem1 -NOTICE: OLD: (2,update) --- cleanup ---Testcase 497: -DROP TRIGGER trig_row_before_insupd ON rem1; ---Testcase 498: -DROP TRIGGER trig_row_after_insupd ON rem1; ---Testcase 499: -DROP TRIGGER trig_row_before_delete ON rem1; ---Testcase 500: -DROP TRIGGER trig_row_after_delete ON rem1; --- Test various RETURN statements in BEFORE triggers. ---Testcase 501: -CREATE FUNCTION trig_row_before_insupdate() RETURNS TRIGGER AS $$ - BEGIN - NEW.f2 := NEW.f2 || ' triggered !'; - RETURN NEW; - END -$$ language plpgsql; ---Testcase 502: -CREATE TRIGGER trig_row_before_insupd -BEFORE INSERT OR UPDATE ON rem1 -FOR EACH ROW EXECUTE PROCEDURE trig_row_before_insupdate(); --- The new values should have 'triggered' appended ---Testcase 503: -INSERT INTO rem1 values(1, 'insert'); ---Testcase 504: -SELECT * from loc1; - f1 | f2 -----+-------------------- - 1 | insert triggered ! -(1 row) - ---Testcase 505: -INSERT INTO rem1 values(2, 'insert'); ---Testcase 506: -SELECT f2 FROM rem1 WHERE f1 = 2; - f2 --------------------- - insert triggered ! -(1 row) - ---Testcase 507: -SELECT * from loc1; - f1 | f2 -----+-------------------- - 1 | insert triggered ! - 2 | insert triggered ! -(2 rows) - ---UPDATE rem1 set f2 = ''; ---SELECT * from loc1; ---UPDATE rem1 set f2 = 'skidoo' RETURNING f2; ---SELECT * from loc1; ---EXPLAIN (verbose, costs off) ---UPDATE rem1 set f1 = 10; -- all columns should be transmitted ---UPDATE rem1 set f1 = 10; ---SELECT * from loc1; ---Testcase 508: -DELETE FROM rem1; --- Add a second trigger, to check that the changes are propagated correctly --- from trigger to trigger ---Testcase 509: -CREATE TRIGGER trig_row_before_insupd2 -BEFORE INSERT OR UPDATE ON rem1 -FOR EACH ROW EXECUTE PROCEDURE trig_row_before_insupdate(); ---Testcase 510: -INSERT INTO rem1 values(1, 'insert'); ---Testcase 511: -SELECT * from loc1; - f1 | f2 -----+-------------------------------- - 1 | insert triggered ! triggered ! -(1 row) - ---Testcase 512: -INSERT INTO rem1 values(2, 'insert'); ---Testcase 513: -SELECT f2 FROM rem1 WHERE f1 = 2; - f2 --------------------------------- - insert triggered ! triggered ! -(1 row) - ---Testcase 514: -SELECT * from loc1; - f1 | f2 -----+-------------------------------- - 1 | insert triggered ! triggered ! - 2 | insert triggered ! triggered ! -(2 rows) - ---UPDATE rem1 set f2 = ''; ---SELECT * from loc1; ---UPDATE rem1 set f2 = 'skidoo' RETURNING f2; ---SELECT * from loc1; ---Testcase 515: -DROP TRIGGER trig_row_before_insupd ON rem1; ---Testcase 516: -DROP TRIGGER trig_row_before_insupd2 ON rem1; ---Testcase 517: -DELETE from rem1; ---Testcase 518: -INSERT INTO rem1 VALUES (1, 'test'); --- Test with a trigger returning NULL ---Testcase 519: -CREATE FUNCTION trig_null() RETURNS TRIGGER AS $$ - BEGIN - RETURN NULL; - END -$$ language plpgsql; ---Testcase 520: -CREATE TRIGGER trig_null -BEFORE INSERT OR UPDATE OR DELETE ON rem1 -FOR EACH ROW EXECUTE PROCEDURE trig_null(); --- Nothing should have changed. ---Testcase 521: -INSERT INTO rem1 VALUES (2, 'test2'); ---Testcase 522: -SELECT * from loc1; - f1 | f2 -----+------ - 1 | test -(1 row) - ---UPDATE rem1 SET f2 = 'test2'; ---SELECT * from loc1; ---Testcase 523: -DELETE from rem1; ---Testcase 524: -SELECT * from loc1; - f1 | f2 -----+------ - 1 | test -(1 row) - ---Testcase 525: -DROP TRIGGER trig_null ON rem1; ---Testcase 526: -DELETE from rem1; --- Test a combination of local and remote triggers ---Testcase 527: -CREATE TRIGGER trig_row_before -BEFORE INSERT OR UPDATE OR DELETE ON rem1 -FOR EACH ROW EXECUTE PROCEDURE trigger_data(23,'skidoo'); ---Testcase 528: -CREATE TRIGGER trig_row_after -AFTER INSERT OR UPDATE OR DELETE ON rem1 -FOR EACH ROW EXECUTE PROCEDURE trigger_data(23,'skidoo'); ---Testcase 529: -CREATE TRIGGER trig_local_before BEFORE INSERT OR UPDATE ON loc1 -FOR EACH ROW EXECUTE PROCEDURE trig_row_before_insupdate(); ---Testcase 530: -INSERT INTO rem1(f2) VALUES ('test'); -NOTICE: trig_row_before(23, skidoo) BEFORE ROW INSERT ON rem1 -NOTICE: NEW: (12,test) -NOTICE: trig_row_after(23, skidoo) AFTER ROW INSERT ON rem1 -NOTICE: NEW: (12,test) ---UPDATE rem1 SET f2 = 'testo'; --- Test returning a system attribute ---Testcase 531: -INSERT INTO rem1(f2) VALUES ('test'); -NOTICE: trig_row_before(23, skidoo) BEFORE ROW INSERT ON rem1 -NOTICE: NEW: (13,test) -NOTICE: trig_row_after(23, skidoo) AFTER ROW INSERT ON rem1 -NOTICE: NEW: (13,test) ---Testcase 532: -SELECT * FROM rem1 WHERE f2 = 'test'; - f1 | f2 -----+------ - 12 | test - 13 | test -(2 rows) - --- cleanup ---Testcase 533: -DROP TRIGGER trig_row_before ON rem1; ---Testcase 534: -DROP TRIGGER trig_row_after ON rem1; ---Testcase 535: -DROP TRIGGER trig_local_before ON loc1; --- Test direct foreign table modification functionality --- Test with statement-level triggers ---Testcase 536: -CREATE TRIGGER trig_stmt_before - BEFORE DELETE OR INSERT OR UPDATE ON rem1 - FOR EACH STATEMENT EXECUTE PROCEDURE trigger_func(); ---EXPLAIN (verbose, costs off) ---UPDATE rem1 set f2 = ''; -- can be pushed down ---Testcase 537: -EXPLAIN (verbose, costs off) -DELETE FROM rem1; -- can be pushed down - QUERY PLAN --------------------------------------------- - Delete on public.rem1 - -> Foreign Delete on public.rem1 - InfluxDB query: DELETE FROM "loc1" -(3 rows) - ---Testcase 538: -DROP TRIGGER trig_stmt_before ON rem1; ---Testcase 539: -CREATE TRIGGER trig_stmt_after - AFTER DELETE OR INSERT OR UPDATE ON rem1 - FOR EACH STATEMENT EXECUTE PROCEDURE trigger_func(); ---EXPLAIN (verbose, costs off) ---UPDATE rem1 set f2 = ''; -- can be pushed down ---Testcase 540: -EXPLAIN (verbose, costs off) -DELETE FROM rem1; -- can be pushed down - QUERY PLAN --------------------------------------------- - Delete on public.rem1 - -> Foreign Delete on public.rem1 - InfluxDB query: DELETE FROM "loc1" -(3 rows) - ---Testcase 541: -DROP TRIGGER trig_stmt_after ON rem1; --- Test with row-level ON INSERT triggers ---Testcase 542: -CREATE TRIGGER trig_row_before_insert -BEFORE INSERT ON rem1 -FOR EACH ROW EXECUTE PROCEDURE trigger_data(23,'skidoo'); ---EXPLAIN (verbose, costs off) ---UPDATE rem1 set f2 = ''; -- can be pushed down ---Testcase 543: -EXPLAIN (verbose, costs off) -DELETE FROM rem1; -- can be pushed down - QUERY PLAN --------------------------------------------- - Delete on public.rem1 - -> Foreign Delete on public.rem1 - InfluxDB query: DELETE FROM "loc1" -(3 rows) - ---Testcase 544: -DROP TRIGGER trig_row_before_insert ON rem1; ---Testcase 545: -CREATE TRIGGER trig_row_after_insert -AFTER INSERT ON rem1 -FOR EACH ROW EXECUTE PROCEDURE trigger_data(23,'skidoo'); ---EXPLAIN (verbose, costs off) ---UPDATE rem1 set f2 = ''; -- can be pushed down ---Testcase 546: -EXPLAIN (verbose, costs off) -DELETE FROM rem1; -- can be pushed down - QUERY PLAN --------------------------------------------- - Delete on public.rem1 - -> Foreign Delete on public.rem1 - InfluxDB query: DELETE FROM "loc1" -(3 rows) - ---Testcase 547: -DROP TRIGGER trig_row_after_insert ON rem1; --- Test with row-level ON UPDATE triggers ---Testcase 548: -CREATE TRIGGER trig_row_before_update -BEFORE UPDATE ON rem1 -FOR EACH ROW EXECUTE PROCEDURE trigger_data(23,'skidoo'); ---EXPLAIN (verbose, costs off) ---UPDATE rem1 set f2 = ''; -- can't be pushed down ---Testcase 549: -EXPLAIN (verbose, costs off) -DELETE FROM rem1; -- can be pushed down - QUERY PLAN --------------------------------------------- - Delete on public.rem1 - -> Foreign Delete on public.rem1 - InfluxDB query: DELETE FROM "loc1" -(3 rows) - ---Testcase 550: -DROP TRIGGER trig_row_before_update ON rem1; ---Testcase 551: -CREATE TRIGGER trig_row_after_update -AFTER UPDATE ON rem1 -FOR EACH ROW EXECUTE PROCEDURE trigger_data(23,'skidoo'); ---EXPLAIN (verbose, costs off) ---UPDATE rem1 set f2 = ''; -- can't be pushed down ---Testcase 552: -EXPLAIN (verbose, costs off) -DELETE FROM rem1; -- can be pushed down - QUERY PLAN --------------------------------------------- - Delete on public.rem1 - -> Foreign Delete on public.rem1 - InfluxDB query: DELETE FROM "loc1" -(3 rows) - ---Testcase 553: -DROP TRIGGER trig_row_after_update ON rem1; --- Test with row-level ON DELETE triggers ---Testcase 554: -CREATE TRIGGER trig_row_before_delete -BEFORE DELETE ON rem1 -FOR EACH ROW EXECUTE PROCEDURE trigger_data(23,'skidoo'); ---EXPLAIN (verbose, costs off) ---UPDATE rem1 set f2 = ''; -- can be pushed down ---Testcase 555: -EXPLAIN (verbose, costs off) -DELETE FROM rem1; -- can't be pushed down - QUERY PLAN -------------------------------------------------------- - Delete on public.rem1 - -> Foreign Scan on public.rem1 - Output: rem1.* - InfluxDB query: SELECT "f1", "f2" FROM "loc1" -(4 rows) - ---Testcase 556: -DROP TRIGGER trig_row_before_delete ON rem1; ---Testcase 557: -CREATE TRIGGER trig_row_after_delete -AFTER DELETE ON rem1 -FOR EACH ROW EXECUTE PROCEDURE trigger_data(23,'skidoo'); ---EXPLAIN (verbose, costs off) ---UPDATE rem1 set f2 = ''; -- can be pushed down ---Testcase 558: -EXPLAIN (verbose, costs off) -DELETE FROM rem1; -- can't be pushed down - QUERY PLAN -------------------------------------------------------- - Delete on public.rem1 - -> Foreign Scan on public.rem1 - Output: rem1.* - InfluxDB query: SELECT "f1", "f2" FROM "loc1" -(4 rows) - ---Testcase 559: -DROP TRIGGER trig_row_after_delete ON rem1; --- =================================================================== --- test inheritance features --- =================================================================== ---Testcase 560: -CREATE TABLE a (aa TEXT); ---CREATE TABLE loct (aa TEXT, bb TEXT); -ALTER TABLE a SET (autovacuum_enabled = 'false'); ---ALTER TABLE loct SET (autovacuum_enabled = 'false'); --- Because influxdb_fdw does not support UPDATE, to test locally --- we create local table. ---Testcase 561: -CREATE TABLE b (bb TEXT) INHERITS (a); ---Testcase 562: -INSERT INTO a(aa) VALUES('aaa'); ---Testcase 563: -INSERT INTO a(aa) VALUES('aaaa'); ---Testcase 564: -INSERT INTO a(aa) VALUES('aaaaa'); ---Testcase 565: -INSERT INTO b(aa) VALUES('bbb'); ---Testcase 566: -INSERT INTO b(aa) VALUES('bbbb'); ---Testcase 567: -INSERT INTO b(aa) VALUES('bbbbb'); ---Testcase 568: -SELECT tableoid::regclass, * FROM a; - tableoid | aa -----------+------- - a | aaa - a | aaaa - a | aaaaa - b | bbb - b | bbbb - b | bbbbb -(6 rows) - ---Testcase 569: -SELECT tableoid::regclass, * FROM b; - tableoid | aa | bb -----------+-------+---- - b | bbb | - b | bbbb | - b | bbbbb | -(3 rows) - ---Testcase 570: -SELECT tableoid::regclass, * FROM ONLY a; - tableoid | aa -----------+------- - a | aaa - a | aaaa - a | aaaaa -(3 rows) - ---Testcase 571: -UPDATE a SET aa = 'zzzzzz' WHERE aa LIKE 'aaaa%'; ---Testcase 572: -SELECT tableoid::regclass, * FROM a; - tableoid | aa -----------+-------- - a | aaa - a | zzzzzz - a | zzzzzz - b | bbb - b | bbbb - b | bbbbb -(6 rows) - ---Testcase 573: -SELECT tableoid::regclass, * FROM b; - tableoid | aa | bb -----------+-------+---- - b | bbb | - b | bbbb | - b | bbbbb | -(3 rows) - ---Testcase 574: -SELECT tableoid::regclass, * FROM ONLY a; - tableoid | aa -----------+-------- - a | aaa - a | zzzzzz - a | zzzzzz -(3 rows) - ---Testcase 575: -UPDATE b SET aa = 'new'; ---Testcase 576: -SELECT tableoid::regclass, * FROM a; - tableoid | aa -----------+-------- - a | aaa - a | zzzzzz - a | zzzzzz - b | new - b | new - b | new -(6 rows) - ---Testcase 577: -SELECT tableoid::regclass, * FROM b; - tableoid | aa | bb -----------+-----+---- - b | new | - b | new | - b | new | -(3 rows) - ---Testcase 578: -SELECT tableoid::regclass, * FROM ONLY a; - tableoid | aa -----------+-------- - a | aaa - a | zzzzzz - a | zzzzzz -(3 rows) - ---Testcase 579: -UPDATE a SET aa = 'newtoo'; ---Testcase 580: -SELECT tableoid::regclass, * FROM a; - tableoid | aa -----------+-------- - a | newtoo - a | newtoo - a | newtoo - b | newtoo - b | newtoo - b | newtoo -(6 rows) - ---Testcase 581: -SELECT tableoid::regclass, * FROM b; - tableoid | aa | bb -----------+--------+---- - b | newtoo | - b | newtoo | - b | newtoo | -(3 rows) - ---Testcase 582: -SELECT tableoid::regclass, * FROM ONLY a; - tableoid | aa -----------+-------- - a | newtoo - a | newtoo - a | newtoo -(3 rows) - ---Testcase 583: -DELETE FROM a; ---Testcase 584: -SELECT tableoid::regclass, * FROM a; - tableoid | aa -----------+---- -(0 rows) - ---Testcase 585: -SELECT tableoid::regclass, * FROM b; - tableoid | aa | bb -----------+----+---- -(0 rows) - ---Testcase 586: -SELECT tableoid::regclass, * FROM ONLY a; - tableoid | aa -----------+---- -(0 rows) - ---Testcase 587: -DROP TABLE a CASCADE; -NOTICE: drop cascades to table b ---DROP TABLE loct; --- Check SELECT FOR UPDATE/SHARE with an inherited source table ---Testcase 588: -create foreign table loct1 (f1 int, f2 int, f3 int) server influxdb_svr options(table 'loct1'); ---Testcase 589: -create foreign table loct2 (f1 int, f2 int, f3 int) server influxdb_svr options(table 'loct2'); ---alter table loct1 set (autovacuum_enabled = 'false'); ---alter table loct2 set (autovacuum_enabled = 'false'); ---Testcase 590: -create foreign table foo (f1 int, f2 int) - server influxdb_svr options (table 'foo'); ---Testcase 591: -create foreign table foo2 (f3 int) inherits (foo) - server influxdb_svr options (table 'loct1'); ---Testcase 592: -create foreign table bar (f1 int, f2 int) - server influxdb_svr options (table 'bar'); ---Testcase 593: -create foreign table bar2 (f3 int) inherits (bar) - server influxdb_svr options (table 'loct2'); ---alter table foo set (autovacuum_enabled = 'false'); ---alter table bar set (autovacuum_enabled = 'false'); ---Testcase 594: -insert into foo values(1,1); ---Testcase 595: -insert into foo values(3,3); ---Testcase 596: -insert into foo2 values(2,2,2); ---Testcase 597: -insert into foo2 values(4,4,4); ---Testcase 598: -insert into bar values(1,11); ---Testcase 599: -insert into bar values(2,22); ---Testcase 600: -insert into bar values(6,66); ---Testcase 601: -insert into bar2 values(3,33,33); ---Testcase 602: -insert into bar2 values(4,44,44); ---Testcase 603: -insert into bar2 values(7,77,77); ---Testcase 604: -explain (verbose, costs off) -select * from bar where f1 in (select f1 from foo); - QUERY PLAN --------------------------------------------------------------------- - Hash Join - Output: bar.f1, bar.f2 - Inner Unique: true - Hash Cond: (bar.f1 = foo.f1) - -> Append - -> Foreign Scan on public.bar - Output: bar.f1, bar.f2 - InfluxDB query: SELECT "f1", "f2" FROM "bar" - -> Foreign Scan on public.bar2 - Output: bar2.f1, bar2.f2 - InfluxDB query: SELECT "f1", "f2" FROM "loct2" - -> Hash - Output: foo.f1 - -> HashAggregate - Output: foo.f1 - Group Key: foo.f1 - -> Append - -> Foreign Scan on public.foo - Output: foo.f1 - InfluxDB query: SELECT "f1" FROM "foo" - -> Foreign Scan on public.foo2 - Output: foo2.f1 - InfluxDB query: SELECT "f1" FROM "loct1" -(23 rows) - ---Testcase 605: -select * from bar where f1 in (select f1 from foo); - f1 | f2 -----+---- - 1 | 11 - 2 | 22 - 3 | 33 - 4 | 44 -(4 rows) - ---Testcase 606: -explain (verbose, costs off) -select * from bar where f1 in (select f1 from foo); - QUERY PLAN --------------------------------------------------------------------- - Hash Join - Output: bar.f1, bar.f2 - Inner Unique: true - Hash Cond: (bar.f1 = foo.f1) - -> Append - -> Foreign Scan on public.bar - Output: bar.f1, bar.f2 - InfluxDB query: SELECT "f1", "f2" FROM "bar" - -> Foreign Scan on public.bar2 - Output: bar2.f1, bar2.f2 - InfluxDB query: SELECT "f1", "f2" FROM "loct2" - -> Hash - Output: foo.f1 - -> HashAggregate - Output: foo.f1 - Group Key: foo.f1 - -> Append - -> Foreign Scan on public.foo - Output: foo.f1 - InfluxDB query: SELECT "f1" FROM "foo" - -> Foreign Scan on public.foo2 - Output: foo2.f1 - InfluxDB query: SELECT "f1" FROM "loct1" -(23 rows) - ---Testcase 607: -select * from bar where f1 in (select f1 from foo); - f1 | f2 -----+---- - 1 | 11 - 2 | 22 - 3 | 33 - 4 | 44 -(4 rows) - -/* --- influxdb_fdw does not support UPDATE --- Check UPDATE with inherited target and an inherited source table -explain (verbose, costs off) -update bar set f2 = f2 + 100 where f1 in (select f1 from foo); -update bar set f2 = f2 + 100 where f1 in (select f1 from foo); - -select tableoid::regclass, * from bar order by 1,2; - --- Check UPDATE with inherited target and an appendrel subquery -explain (verbose, costs off) -update bar set f2 = f2 + 100 -from - ( select f1 from foo union all select f1+3 from foo ) ss -where bar.f1 = ss.f1; -update bar set f2 = f2 + 100 -from - ( select f1 from foo union all select f1+3 from foo ) ss -where bar.f1 = ss.f1; - -select tableoid::regclass, * from bar order by 1,2; - --- Test forcing the remote server to produce sorted data for a merge join, --- but the foreign table is an inheritance child. -truncate table loct1; -truncate table only foo; -\set num_rows_foo 2000 -insert into loct1 select generate_series(0, :num_rows_foo, 2), generate_series(0, :num_rows_foo, 2), generate_series(0, :num_rows_foo, 2); -insert into foo select generate_series(1, :num_rows_foo, 2), generate_series(1, :num_rows_foo, 2); -SET enable_hashjoin to false; -SET enable_nestloop to false; -alter foreign table foo2 options (use_remote_estimate 'true'); -create index i_loct1_f1 on loct1(f1); -create index i_foo_f1 on foo(f1); -analyze foo; -analyze loct1; --- inner join; expressions in the clauses appear in the equivalence class list -explain (verbose, costs off) - select foo.f1, loct1.f1 from foo join loct1 on (foo.f1 = loct1.f1) order by foo.f2 offset 10 limit 10; -select foo.f1, loct1.f1 from foo join loct1 on (foo.f1 = loct1.f1) order by foo.f2 offset 10 limit 10; --- outer join; expressions in the clauses do not appear in equivalence class --- list but no output change as compared to the previous query -explain (verbose, costs off) - select foo.f1, loct1.f1 from foo left join loct1 on (foo.f1 = loct1.f1) order by foo.f2 offset 10 limit 10; -select foo.f1, loct1.f1 from foo left join loct1 on (foo.f1 = loct1.f1) order by foo.f2 offset 10 limit 10; -RESET enable_hashjoin; -RESET enable_nestloop; - --- Test that WHERE CURRENT OF is not supported -begin; -declare c cursor for select * from bar where f1 = 7; -fetch from c; -update bar set f2 = null where current of c; -rollback; - -explain (verbose, costs off) -delete from foo where f1 < 5 returning *; -delete from foo where f1 < 5 returning *; -explain (verbose, costs off) -update bar set f2 = f2 + 100 returning *; -update bar set f2 = f2 + 100 returning *; - --- Test that UPDATE/DELETE with inherited target works with row-level triggers -CREATE TRIGGER trig_row_before -BEFORE UPDATE OR DELETE ON bar2 -FOR EACH ROW EXECUTE PROCEDURE trigger_data(23,'skidoo'); - -CREATE TRIGGER trig_row_after -AFTER UPDATE OR DELETE ON bar2 -FOR EACH ROW EXECUTE PROCEDURE trigger_data(23,'skidoo'); - -explain (verbose, costs off) -update bar set f2 = f2 + 100; -update bar set f2 = f2 + 100; - -explain (verbose, costs off) -delete from bar where f2 < 400; -delete from bar where f2 < 400; - --- cleanup -drop table foo cascade; -drop table bar cascade; -drop table loct1; -drop table loct2; - --- Test pushing down UPDATE/DELETE joins to the remote server -create table parent (a int, b text); -create table loct1 (a int, b text); -create table loct2 (a int, b text); -create foreign table remt1 (a int, b text) - server influxdb_svr options (table 'loct1'); -create foreign table remt2 (a int, b text) - server influxdb_svr options (table 'loct2'); -alter foreign table remt1 inherit parent; - -insert into remt1 values (1, 'foo'); -insert into remt1 values (2, 'bar'); -insert into remt2 values (1, 'foo'); -insert into remt2 values (2, 'bar'); - -analyze remt1; -analyze remt2; - -explain (verbose, costs off) -update parent set b = parent.b || remt2.b from remt2 where parent.a = remt2.a returning *; -update parent set b = parent.b || remt2.b from remt2 where parent.a = remt2.a returning *; -explain (verbose, costs off) -delete from parent using remt2 where parent.a = remt2.a returning parent; -delete from parent using remt2 where parent.a = remt2.a returning parent; - --- cleanup -drop foreign table remt1; -drop foreign table remt2; -drop table loct1; -drop table loct2; -drop table parent; -*/ -/* --- Skip test because influxdb does not support partitions table, COPY --- =================================================================== --- test tuple routing for foreign-table partitions --- =================================================================== - --- Test insert tuple routing -create table itrtest (a int, b text) partition by list (a); -create table loct1 (a int check (a in (1)), b text); -create foreign table remp1 (a int check (a in (1)), b text) server loopback options (table_name 'loct1'); -create table loct2 (a int check (a in (2)), b text); -create foreign table remp2 (b text, a int check (a in (2))) server loopback options (table_name 'loct2'); -alter table itrtest attach partition remp1 for values in (1); -alter table itrtest attach partition remp2 for values in (2); - -insert into itrtest values (1, 'foo'); -insert into itrtest values (1, 'bar') returning *; -insert into itrtest values (2, 'baz'); -insert into itrtest values (2, 'qux') returning *; -insert into itrtest values (1, 'test1'), (2, 'test2') returning *; - -select tableoid::regclass, * FROM itrtest; -select tableoid::regclass, * FROM remp1; -select tableoid::regclass, * FROM remp2; - -delete from itrtest; - -create unique index loct1_idx on loct1 (a); - --- DO NOTHING without an inference specification is supported -insert into itrtest values (1, 'foo') on conflict do nothing returning *; -insert into itrtest values (1, 'foo') on conflict do nothing returning *; - --- But other cases are not supported -insert into itrtest values (1, 'bar') on conflict (a) do nothing; -insert into itrtest values (1, 'bar') on conflict (a) do update set b = excluded.b; - -select tableoid::regclass, * FROM itrtest; - -delete from itrtest; - -drop index loct1_idx; - --- Test that remote triggers work with insert tuple routing -create function br_insert_trigfunc() returns trigger as $$ -begin - new.b := new.b || ' triggered !'; - return new; -end -$$ language plpgsql; -create trigger loct1_br_insert_trigger before insert on loct1 - for each row execute procedure br_insert_trigfunc(); -create trigger loct2_br_insert_trigger before insert on loct2 - for each row execute procedure br_insert_trigfunc(); - --- The new values are concatenated with ' triggered !' -insert into itrtest values (1, 'foo') returning *; -insert into itrtest values (2, 'qux') returning *; -insert into itrtest values (1, 'test1'), (2, 'test2') returning *; -with result as (insert into itrtest values (1, 'test1'), (2, 'test2') returning *) select * from result; - -drop trigger loct1_br_insert_trigger on loct1; -drop trigger loct2_br_insert_trigger on loct2; - -drop table itrtest; -drop table loct1; -drop table loct2; - --- Test update tuple routing -create table utrtest (a int, b text) partition by list (a); -create table loct (a int check (a in (1)), b text); -create foreign table remp (a int check (a in (1)), b text) server loopback options (table_name 'loct'); -create table locp (a int check (a in (2)), b text); -alter table utrtest attach partition remp for values in (1); -alter table utrtest attach partition locp for values in (2); - -insert into utrtest values (1, 'foo'); -insert into utrtest values (2, 'qux'); - -select tableoid::regclass, * FROM utrtest; -select tableoid::regclass, * FROM remp; -select tableoid::regclass, * FROM locp; - --- It's not allowed to move a row from a partition that is foreign to another -update utrtest set a = 2 where b = 'foo' returning *; - --- But the reverse is allowed -update utrtest set a = 1 where b = 'qux' returning *; - -select tableoid::regclass, * FROM utrtest; -select tableoid::regclass, * FROM remp; -select tableoid::regclass, * FROM locp; - --- The executor should not let unexercised FDWs shut down -update utrtest set a = 1 where b = 'foo'; - --- Test that remote triggers work with update tuple routing -create trigger loct_br_insert_trigger before insert on loct - for each row execute procedure br_insert_trigfunc(); - -delete from utrtest; -insert into utrtest values (2, 'qux'); - --- Check case where the foreign partition is a subplan target rel -explain (verbose, costs off) -update utrtest set a = 1 where a = 1 or a = 2 returning *; --- The new values are concatenated with ' triggered !' -update utrtest set a = 1 where a = 1 or a = 2 returning *; - -delete from utrtest; -insert into utrtest values (2, 'qux'); - --- Check case where the foreign partition isn't a subplan target rel -explain (verbose, costs off) -update utrtest set a = 1 where a = 2 returning *; --- The new values are concatenated with ' triggered !' -update utrtest set a = 1 where a = 2 returning *; - -drop trigger loct_br_insert_trigger on loct; - --- We can move rows to a foreign partition that has been updated already, --- but can't move rows to a foreign partition that hasn't been updated yet - -delete from utrtest; -insert into utrtest values (1, 'foo'); -insert into utrtest values (2, 'qux'); - --- Test the former case: --- with a direct modification plan -explain (verbose, costs off) -update utrtest set a = 1 returning *; -update utrtest set a = 1 returning *; - -delete from utrtest; -insert into utrtest values (1, 'foo'); -insert into utrtest values (2, 'qux'); - --- with a non-direct modification plan -explain (verbose, costs off) -update utrtest set a = 1 from (values (1), (2)) s(x) where a = s.x returning *; -update utrtest set a = 1 from (values (1), (2)) s(x) where a = s.x returning *; - --- Change the definition of utrtest so that the foreign partition get updated --- after the local partition -delete from utrtest; -alter table utrtest detach partition remp; -drop foreign table remp; -alter table loct drop constraint loct_a_check; -alter table loct add check (a in (3)); -create foreign table remp (a int check (a in (3)), b text) server loopback options (table_name 'loct'); -alter table utrtest attach partition remp for values in (3); -insert into utrtest values (2, 'qux'); -insert into utrtest values (3, 'xyzzy'); - --- Test the latter case: --- with a direct modification plan -explain (verbose, costs off) -update utrtest set a = 3 returning *; -update utrtest set a = 3 returning *; -- ERROR - --- with a non-direct modification plan -explain (verbose, costs off) -update utrtest set a = 3 from (values (2), (3)) s(x) where a = s.x returning *; -update utrtest set a = 3 from (values (2), (3)) s(x) where a = s.x returning *; -- ERROR - -drop table utrtest; -drop table loct; - --- Test copy tuple routing -create table ctrtest (a int, b text) partition by list (a); -create table loct1 (a int check (a in (1)), b text); -create foreign table remp1 (a int check (a in (1)), b text) server loopback options (table_name 'loct1'); -create table loct2 (a int check (a in (2)), b text); -create foreign table remp2 (b text, a int check (a in (2))) server loopback options (table_name 'loct2'); -alter table ctrtest attach partition remp1 for values in (1); -alter table ctrtest attach partition remp2 for values in (2); - -copy ctrtest from stdin; -1 foo -2 qux -\. - -select tableoid::regclass, * FROM ctrtest; -select tableoid::regclass, * FROM remp1; -select tableoid::regclass, * FROM remp2; - --- Copying into foreign partitions directly should work as well -copy remp1 from stdin; -1 bar -\. - -select tableoid::regclass, * FROM remp1; - -drop table ctrtest; -drop table loct1; -drop table loct2; - --- =================================================================== --- test COPY FROM --- =================================================================== - -create table loc2 (f1 int, f2 text); -alter table loc2 set (autovacuum_enabled = 'false'); -create foreign table rem2 (f1 int, f2 text) server loopback options(table_name 'loc2'); - --- Test basic functionality -copy rem2 from stdin; -1 foo -2 bar -\. -select * from rem2; - -delete from rem2; - --- Test check constraints -alter table loc2 add constraint loc2_f1positive check (f1 >= 0); -alter foreign table rem2 add constraint rem2_f1positive check (f1 >= 0); - --- check constraint is enforced on the remote side, not locally -copy rem2 from stdin; -1 foo -2 bar -\. -copy rem2 from stdin; -- ERROR --1 xyzzy -\. -select * from rem2; - -alter foreign table rem2 drop constraint rem2_f1positive; -alter table loc2 drop constraint loc2_f1positive; - -delete from rem2; - --- Test local triggers -create trigger trig_stmt_before before insert on rem2 - for each statement execute procedure trigger_func(); -create trigger trig_stmt_after after insert on rem2 - for each statement execute procedure trigger_func(); -create trigger trig_row_before before insert on rem2 - for each row execute procedure trigger_data(23,'skidoo'); -create trigger trig_row_after after insert on rem2 - for each row execute procedure trigger_data(23,'skidoo'); - -copy rem2 from stdin; -1 foo -2 bar -\. -select * from rem2; - -drop trigger trig_row_before on rem2; -drop trigger trig_row_after on rem2; -drop trigger trig_stmt_before on rem2; -drop trigger trig_stmt_after on rem2; - -delete from rem2; - -create trigger trig_row_before_insert before insert on rem2 - for each row execute procedure trig_row_before_insupdate(); - --- The new values are concatenated with ' triggered !' -copy rem2 from stdin; -1 foo -2 bar -\. -select * from rem2; - -drop trigger trig_row_before_insert on rem2; - -delete from rem2; - -create trigger trig_null before insert on rem2 - for each row execute procedure trig_null(); - --- Nothing happens -copy rem2 from stdin; -1 foo -2 bar -\. -select * from rem2; - -drop trigger trig_null on rem2; - -delete from rem2; - --- Test remote triggers -create trigger trig_row_before_insert before insert on loc2 - for each row execute procedure trig_row_before_insupdate(); - --- The new values are concatenated with ' triggered !' -copy rem2 from stdin; -1 foo -2 bar -\. -select * from rem2; - -drop trigger trig_row_before_insert on loc2; - -delete from rem2; - -create trigger trig_null before insert on loc2 - for each row execute procedure trig_null(); - --- Nothing happens -copy rem2 from stdin; -1 foo -2 bar -\. -select * from rem2; - -drop trigger trig_null on loc2; - -delete from rem2; - --- Test a combination of local and remote triggers -create trigger rem2_trig_row_before before insert on rem2 - for each row execute procedure trigger_data(23,'skidoo'); -create trigger rem2_trig_row_after after insert on rem2 - for each row execute procedure trigger_data(23,'skidoo'); -create trigger loc2_trig_row_before_insert before insert on loc2 - for each row execute procedure trig_row_before_insupdate(); - -copy rem2 from stdin; -1 foo -2 bar -\. -select * from rem2; - -drop trigger rem2_trig_row_before on rem2; -drop trigger rem2_trig_row_after on rem2; -drop trigger loc2_trig_row_before_insert on loc2; - -delete from rem2; - --- test COPY FROM with foreign table created in the same transaction -create table loc3 (f1 int, f2 text); -begin; -create foreign table rem3 (f1 int, f2 text) - server loopback options(table_name 'loc3'); -copy rem3 from stdin; -1 foo -2 bar -\. -commit; -select * from rem3; -drop foreign table rem3; -drop table loc3; -*/ --- =================================================================== --- test IMPORT FOREIGN SCHEMA --- =================================================================== ---Testcase 608: -CREATE SCHEMA import_influx1; -IMPORT FOREIGN SCHEMA public FROM SERVER influxdb_svr INTO import_influx1; ---Testcase 609: -\det+ import_influx1.* - List of foreign tables - Schema | Table | Server | FDW options | Description -----------------+-------+--------------+---------------------------+------------- - import_influx1 | T1 | influxdb_svr | ("table" 'T1', tags 'c3') | - import_influx1 | T2 | influxdb_svr | ("table" 'T2', tags 'c2') | - import_influx1 | T3 | influxdb_svr | ("table" 'T3', tags 'c3') | - import_influx1 | T4 | influxdb_svr | ("table" 'T4', tags 'c3') | - import_influx1 | bar | influxdb_svr | ("table" 'bar') | - import_influx1 | foo | influxdb_svr | ("table" 'foo') | - import_influx1 | loc1 | influxdb_svr | ("table" 'loc1') | - import_influx1 | loct1 | influxdb_svr | ("table" 'loct1') | - import_influx1 | loct2 | influxdb_svr | ("table" 'loct2') | -(9 rows) - ---Testcase 610: -\d import_influx1.* - Foreign table "import_influx1.T1" - Column | Type | Collation | Nullable | Default | FDW options ---------+--------------------------+-----------+----------+---------+------------- - time | timestamp with time zone | | | | - c3 | text | | | | - C 1 | bigint | | | | - c2 | bigint | | | | - c6 | text | | | | - c7 | text | | | | - c8 | text | | | | -Server: influxdb_svr -FDW options: ("table" 'T1', tags 'c3') - - Foreign table "import_influx1.T2" - Column | Type | Collation | Nullable | Default | FDW options ---------+--------------------------+-----------+----------+---------+------------- - time | timestamp with time zone | | | | - c2 | text | | | | - c1 | bigint | | | | -Server: influxdb_svr -FDW options: ("table" 'T2', tags 'c2') - - Foreign table "import_influx1.T3" - Column | Type | Collation | Nullable | Default | FDW options ---------+--------------------------+-----------+----------+---------+------------- - time | timestamp with time zone | | | | - c3 | text | | | | - c1 | bigint | | | | - c2 | bigint | | | | -Server: influxdb_svr -FDW options: ("table" 'T3', tags 'c3') - - Foreign table "import_influx1.T4" - Column | Type | Collation | Nullable | Default | FDW options ---------+--------------------------+-----------+----------+---------+------------- - time | timestamp with time zone | | | | - c3 | text | | | | - c1 | bigint | | | | - c2 | bigint | | | | -Server: influxdb_svr -FDW options: ("table" 'T4', tags 'c3') - - Foreign table "import_influx1.bar" - Column | Type | Collation | Nullable | Default | FDW options ---------+--------------------------+-----------+----------+---------+------------- - time | timestamp with time zone | | | | - f1 | bigint | | | | - f2 | bigint | | | | -Server: influxdb_svr -FDW options: ("table" 'bar') - - Foreign table "import_influx1.foo" - Column | Type | Collation | Nullable | Default | FDW options ---------+--------------------------+-----------+----------+---------+------------- - time | timestamp with time zone | | | | - f1 | bigint | | | | - f2 | bigint | | | | -Server: influxdb_svr -FDW options: ("table" 'foo') - - Foreign table "import_influx1.loc1" - Column | Type | Collation | Nullable | Default | FDW options ---------+--------------------------+-----------+----------+---------+------------- - time | timestamp with time zone | | | | - f1 | bigint | | | | - f2 | text | | | | -Server: influxdb_svr -FDW options: ("table" 'loc1') - - Foreign table "import_influx1.loct1" - Column | Type | Collation | Nullable | Default | FDW options ---------+--------------------------+-----------+----------+---------+------------- - time | timestamp with time zone | | | | - f1 | bigint | | | | - f2 | bigint | | | | - f3 | bigint | | | | -Server: influxdb_svr -FDW options: ("table" 'loct1') - - Foreign table "import_influx1.loct2" - Column | Type | Collation | Nullable | Default | FDW options ---------+--------------------------+-----------+----------+---------+------------- - time | timestamp with time zone | | | | - f1 | bigint | | | | - f2 | bigint | | | | - f3 | bigint | | | | -Server: influxdb_svr -FDW options: ("table" 'loct2') - --- Options ---Testcase 611: -CREATE SCHEMA import_influx2; -IMPORT FOREIGN SCHEMA public FROM SERVER influxdb_svr INTO import_influx2 - OPTIONS (import_default 'true'); -ERROR: invalid option "import_default" ---Testcase 612: -\det+ import_influx2.* - List of foreign tables - Schema | Table | Server | FDW options | Description ---------+-------+--------+-------------+------------- -(0 rows) - ---Testcase 613: -\d import_influx2.* ---Testcase 614: -CREATE SCHEMA import_influx3; -IMPORT FOREIGN SCHEMA public FROM SERVER influxdb_svr INTO import_influx3 - OPTIONS (import_collate 'false', import_not_null 'false'); -ERROR: invalid option "import_collate" ---Testcase 615: -\det+ import_influx3.* - List of foreign tables - Schema | Table | Server | FDW options | Description ---------+-------+--------+-------------+------------- -(0 rows) - ---Testcase 616: -\d import_influx3.* --- Check LIMIT TO and EXCEPT ---Testcase 617: -CREATE SCHEMA import_influx4; -IMPORT FOREIGN SCHEMA public LIMIT TO ("T1", loct, nonesuch) - FROM SERVER influxdb_svr INTO import_influx4; ---Testcase 618: -\det+ import_influx4.* - List of foreign tables - Schema | Table | Server | FDW options | Description -----------------+-------+--------------+---------------------------+------------- - import_influx4 | T1 | influxdb_svr | ("table" 'T1', tags 'c3') | -(1 row) - -IMPORT FOREIGN SCHEMA public EXCEPT ("T1", loct, nonesuch) - FROM SERVER influxdb_svr INTO import_influx4; ---Testcase 619: -\det+ import_influx4.* - List of foreign tables - Schema | Table | Server | FDW options | Description -----------------+-------+--------------+---------------------------+------------- - import_influx4 | T1 | influxdb_svr | ("table" 'T1', tags 'c3') | - import_influx4 | T2 | influxdb_svr | ("table" 'T2', tags 'c2') | - import_influx4 | T3 | influxdb_svr | ("table" 'T3', tags 'c3') | - import_influx4 | T4 | influxdb_svr | ("table" 'T4', tags 'c3') | - import_influx4 | bar | influxdb_svr | ("table" 'bar') | - import_influx4 | foo | influxdb_svr | ("table" 'foo') | - import_influx4 | loc1 | influxdb_svr | ("table" 'loc1') | - import_influx4 | loct1 | influxdb_svr | ("table" 'loct1') | - import_influx4 | loct2 | influxdb_svr | ("table" 'loct2') | -(9 rows) - --- Assorted error cases -IMPORT FOREIGN SCHEMA public FROM SERVER influxdb_svr INTO import_influx4; -ERROR: relation "T1" already exists -CONTEXT: importing foreign table "T1" -IMPORT FOREIGN SCHEMA nonesuch FROM SERVER influxdb_svr INTO import_influx4; -ERROR: relation "T1" already exists -CONTEXT: importing foreign table "T1" -IMPORT FOREIGN SCHEMA nonesuch FROM SERVER influxdb_svr INTO notthere; -ERROR: schema "notthere" does not exist -IMPORT FOREIGN SCHEMA nonesuch FROM SERVER nowhere INTO notthere; -ERROR: server "nowhere" does not exist -/* --- Skip these test, influxdb_fdw does not support fetch_size option, partition table --- Check case of a type present only on the remote server. --- We can fake this by dropping the type locally in our transaction. -CREATE TYPE "Colors" AS ENUM ('red', 'green', 'blue'); -CREATE TABLE import_source.t5 (c1 int, c2 text collate "C", "Col" "Colors"); - -CREATE SCHEMA import_dest5; -BEGIN; -DROP TYPE "Colors" CASCADE; -IMPORT FOREIGN SCHEMA import_source LIMIT TO (t5) - FROM SERVER loopback INTO import_dest5; -- ERROR - -ROLLBACK; - -BEGIN; - - -CREATE SERVER fetch101 FOREIGN DATA WRAPPER postgres_fdw OPTIONS( fetch_size '101' ); - -SELECT count(*) -FROM pg_foreign_server -WHERE srvname = 'fetch101' -AND srvoptions @> array['fetch_size=101']; - -ALTER SERVER fetch101 OPTIONS( SET fetch_size '202' ); - -SELECT count(*) -FROM pg_foreign_server -WHERE srvname = 'fetch101' -AND srvoptions @> array['fetch_size=101']; - -SELECT count(*) -FROM pg_foreign_server -WHERE srvname = 'fetch101' -AND srvoptions @> array['fetch_size=202']; - -CREATE FOREIGN TABLE table30000 ( x int ) SERVER fetch101 OPTIONS ( fetch_size '30000' ); - -SELECT COUNT(*) -FROM pg_foreign_table -WHERE ftrelid = 'table30000'::regclass -AND ftoptions @> array['fetch_size=30000']; - -ALTER FOREIGN TABLE table30000 OPTIONS ( SET fetch_size '60000'); - -SELECT COUNT(*) -FROM pg_foreign_table -WHERE ftrelid = 'table30000'::regclass -AND ftoptions @> array['fetch_size=30000']; - -SELECT COUNT(*) -FROM pg_foreign_table -WHERE ftrelid = 'table30000'::regclass -AND ftoptions @> array['fetch_size=60000']; - -ROLLBACK; - --- =================================================================== --- test partitionwise joins --- =================================================================== -SET enable_partitionwise_join=on; - -CREATE TABLE fprt1 (a int, b int, c varchar) PARTITION BY RANGE(a); -CREATE TABLE fprt1_p1 (LIKE fprt1); -CREATE TABLE fprt1_p2 (LIKE fprt1); -ALTER TABLE fprt1_p1 SET (autovacuum_enabled = 'false'); -ALTER TABLE fprt1_p2 SET (autovacuum_enabled = 'false'); -INSERT INTO fprt1_p1 SELECT i, i, to_char(i/50, 'FM0000') FROM generate_series(0, 249, 2) i; -INSERT INTO fprt1_p2 SELECT i, i, to_char(i/50, 'FM0000') FROM generate_series(250, 499, 2) i; -CREATE FOREIGN TABLE ftprt1_p1 PARTITION OF fprt1 FOR VALUES FROM (0) TO (250) - SERVER loopback OPTIONS (table_name 'fprt1_p1', use_remote_estimate 'true'); -CREATE FOREIGN TABLE ftprt1_p2 PARTITION OF fprt1 FOR VALUES FROM (250) TO (500) - SERVER loopback OPTIONS (TABLE_NAME 'fprt1_p2'); -ANALYZE fprt1; -ANALYZE fprt1_p1; -ANALYZE fprt1_p2; - -CREATE TABLE fprt2 (a int, b int, c varchar) PARTITION BY RANGE(b); -CREATE TABLE fprt2_p1 (LIKE fprt2); -CREATE TABLE fprt2_p2 (LIKE fprt2); -ALTER TABLE fprt2_p1 SET (autovacuum_enabled = 'false'); -ALTER TABLE fprt2_p2 SET (autovacuum_enabled = 'false'); -INSERT INTO fprt2_p1 SELECT i, i, to_char(i/50, 'FM0000') FROM generate_series(0, 249, 3) i; -INSERT INTO fprt2_p2 SELECT i, i, to_char(i/50, 'FM0000') FROM generate_series(250, 499, 3) i; -CREATE FOREIGN TABLE ftprt2_p1 (b int, c varchar, a int) - SERVER loopback OPTIONS (table_name 'fprt2_p1', use_remote_estimate 'true'); -ALTER TABLE fprt2 ATTACH PARTITION ftprt2_p1 FOR VALUES FROM (0) TO (250); -CREATE FOREIGN TABLE ftprt2_p2 PARTITION OF fprt2 FOR VALUES FROM (250) TO (500) - SERVER loopback OPTIONS (table_name 'fprt2_p2', use_remote_estimate 'true'); -ANALYZE fprt2; -ANALYZE fprt2_p1; -ANALYZE fprt2_p2; - --- inner join three tables -EXPLAIN (COSTS OFF) -SELECT t1.a,t2.b,t3.c FROM fprt1 t1 INNER JOIN fprt2 t2 ON (t1.a = t2.b) INNER JOIN fprt1 t3 ON (t2.b = t3.a) WHERE t1.a % 25 =0 ORDER BY 1,2,3; -SELECT t1.a,t2.b,t3.c FROM fprt1 t1 INNER JOIN fprt2 t2 ON (t1.a = t2.b) INNER JOIN fprt1 t3 ON (t2.b = t3.a) WHERE t1.a % 25 =0 ORDER BY 1,2,3; - --- left outer join + nullable clause -EXPLAIN (VERBOSE, COSTS OFF) -SELECT t1.a,t2.b,t2.c FROM fprt1 t1 LEFT JOIN (SELECT * FROM fprt2 WHERE a < 10) t2 ON (t1.a = t2.b and t1.b = t2.a) WHERE t1.a < 10 ORDER BY 1,2,3; -SELECT t1.a,t2.b,t2.c FROM fprt1 t1 LEFT JOIN (SELECT * FROM fprt2 WHERE a < 10) t2 ON (t1.a = t2.b and t1.b = t2.a) WHERE t1.a < 10 ORDER BY 1,2,3; - --- with whole-row reference; partitionwise join does not apply -EXPLAIN (COSTS OFF) -SELECT t1.wr, t2.wr FROM (SELECT t1 wr, a FROM fprt1 t1 WHERE t1.a % 25 = 0) t1 FULL JOIN (SELECT t2 wr, b FROM fprt2 t2 WHERE t2.b % 25 = 0) t2 ON (t1.a = t2.b) ORDER BY 1,2; -SELECT t1.wr, t2.wr FROM (SELECT t1 wr, a FROM fprt1 t1 WHERE t1.a % 25 = 0) t1 FULL JOIN (SELECT t2 wr, b FROM fprt2 t2 WHERE t2.b % 25 = 0) t2 ON (t1.a = t2.b) ORDER BY 1,2; - --- join with lateral reference -EXPLAIN (COSTS OFF) -SELECT t1.a,t1.b FROM fprt1 t1, LATERAL (SELECT t2.a, t2.b FROM fprt2 t2 WHERE t1.a = t2.b AND t1.b = t2.a) q WHERE t1.a%25 = 0 ORDER BY 1,2; -SELECT t1.a,t1.b FROM fprt1 t1, LATERAL (SELECT t2.a, t2.b FROM fprt2 t2 WHERE t1.a = t2.b AND t1.b = t2.a) q WHERE t1.a%25 = 0 ORDER BY 1,2; - --- with PHVs, partitionwise join selected but no join pushdown -EXPLAIN (COSTS OFF) -SELECT t1.a, t1.phv, t2.b, t2.phv FROM (SELECT 't1_phv' phv, * FROM fprt1 WHERE a % 25 = 0) t1 FULL JOIN (SELECT 't2_phv' phv, * FROM fprt2 WHERE b % 25 = 0) t2 ON (t1.a = t2.b) ORDER BY t1.a, t2.b; -SELECT t1.a, t1.phv, t2.b, t2.phv FROM (SELECT 't1_phv' phv, * FROM fprt1 WHERE a % 25 = 0) t1 FULL JOIN (SELECT 't2_phv' phv, * FROM fprt2 WHERE b % 25 = 0) t2 ON (t1.a = t2.b) ORDER BY t1.a, t2.b; - --- test FOR UPDATE; partitionwise join does not apply -EXPLAIN (COSTS OFF) -SELECT t1.a, t2.b FROM fprt1 t1 INNER JOIN fprt2 t2 ON (t1.a = t2.b) WHERE t1.a % 25 = 0 ORDER BY 1,2 FOR UPDATE OF t1; -SELECT t1.a, t2.b FROM fprt1 t1 INNER JOIN fprt2 t2 ON (t1.a = t2.b) WHERE t1.a % 25 = 0 ORDER BY 1,2 FOR UPDATE OF t1; - -RESET enable_partitionwise_join; - - --- =================================================================== --- test partitionwise aggregates --- =================================================================== - -CREATE TABLE pagg_tab (a int, b int, c text) PARTITION BY RANGE(a); - -CREATE TABLE pagg_tab_p1 (LIKE pagg_tab); -CREATE TABLE pagg_tab_p2 (LIKE pagg_tab); -CREATE TABLE pagg_tab_p3 (LIKE pagg_tab); - -INSERT INTO pagg_tab_p1 SELECT i % 30, i % 50, to_char(i/30, 'FM0000') FROM generate_series(1, 3000) i WHERE (i % 30) < 10; -INSERT INTO pagg_tab_p2 SELECT i % 30, i % 50, to_char(i/30, 'FM0000') FROM generate_series(1, 3000) i WHERE (i % 30) < 20 and (i % 30) >= 10; -INSERT INTO pagg_tab_p3 SELECT i % 30, i % 50, to_char(i/30, 'FM0000') FROM generate_series(1, 3000) i WHERE (i % 30) < 30 and (i % 30) >= 20; - --- Create foreign partitions -CREATE FOREIGN TABLE fpagg_tab_p1 PARTITION OF pagg_tab FOR VALUES FROM (0) TO (10) SERVER loopback OPTIONS (table_name 'pagg_tab_p1'); -CREATE FOREIGN TABLE fpagg_tab_p2 PARTITION OF pagg_tab FOR VALUES FROM (10) TO (20) SERVER loopback OPTIONS (table_name 'pagg_tab_p2'); -CREATE FOREIGN TABLE fpagg_tab_p3 PARTITION OF pagg_tab FOR VALUES FROM (20) TO (30) SERVER loopback OPTIONS (table_name 'pagg_tab_p3'); - -ANALYZE pagg_tab; -ANALYZE fpagg_tab_p1; -ANALYZE fpagg_tab_p2; -ANALYZE fpagg_tab_p3; - --- When GROUP BY clause matches with PARTITION KEY. --- Plan with partitionwise aggregates is disabled -SET enable_partitionwise_aggregate TO false; -EXPLAIN (COSTS OFF) -SELECT a, sum(b), min(b), count(*) FROM pagg_tab GROUP BY a HAVING avg(b) < 22 ORDER BY 1; - --- Plan with partitionwise aggregates is enabled -SET enable_partitionwise_aggregate TO true; -EXPLAIN (COSTS OFF) -SELECT a, sum(b), min(b), count(*) FROM pagg_tab GROUP BY a HAVING avg(b) < 22 ORDER BY 1; -SELECT a, sum(b), min(b), count(*) FROM pagg_tab GROUP BY a HAVING avg(b) < 22 ORDER BY 1; - --- Check with whole-row reference --- Should have all the columns in the target list for the given relation -EXPLAIN (VERBOSE, COSTS OFF) -SELECT a, count(t1) FROM pagg_tab t1 GROUP BY a HAVING avg(b) < 22 ORDER BY 1; -SELECT a, count(t1) FROM pagg_tab t1 GROUP BY a HAVING avg(b) < 22 ORDER BY 1; - --- When GROUP BY clause does not match with PARTITION KEY. -EXPLAIN (COSTS OFF) -SELECT b, avg(a), max(a), count(*) FROM pagg_tab GROUP BY b HAVING sum(a) < 700 ORDER BY 1; -*/ -/* --- Skip test, influxdb_fdw does not support nosuperuser --- =================================================================== --- access rights and superuser --- =================================================================== - --- Non-superuser cannot create a FDW without a password in the connstr -CREATE ROLE regress_nosuper NOSUPERUSER; - -GRANT USAGE ON FOREIGN DATA WRAPPER influxdb_fdw TO regress_nosuper; - -SET ROLE regress_nosuper; - -SHOW is_superuser; - --- This will be OK, we can create the FDW -DO $d$ - BEGIN - EXECUTE $$CREATE SERVER loopback_nopw FOREIGN DATA WRAPPER influxdb_fdw - OPTIONS (dbname '$$||current_database()||$$', - port '$$||current_setting('port')||$$' - )$$; - END; -$d$; - --- But creation of user mappings for non-superusers should fail -CREATE USER MAPPING FOR public SERVER loopback_nopw; -CREATE USER MAPPING FOR CURRENT_USER SERVER loopback_nopw; - -CREATE FOREIGN TABLE ft1_nopw ( - c1 int NOT NULL, - c2 int NOT NULL, - c3 text, - c4 timestamptz, - c5 timestamp, - c6 varchar(10), - c7 char(10) default 'ft1', - c8 user_enum -) SERVER loopback_nopw OPTIONS (schema_name 'public', table_name 'ft1'); - -SELECT * FROM ft1_nopw LIMIT 1; - --- If we add a password to the connstr it'll fail, because we don't allow passwords --- in connstrs only in user mappings. - -DO $d$ - BEGIN - EXECUTE $$ALTER SERVER loopback_nopw OPTIONS (ADD password 'dummypw')$$; - END; -$d$; - --- If we add a password for our user mapping instead, we should get a different --- error because the password wasn't actually *used* when we run with trust auth. --- --- This won't work with installcheck, but neither will most of the FDW checks. - -ALTER USER MAPPING FOR CURRENT_USER SERVER loopback_nopw OPTIONS (ADD password 'dummypw'); - -SELECT * FROM ft1_nopw LIMIT 1; - --- Unpriv user cannot make the mapping passwordless -ALTER USER MAPPING FOR CURRENT_USER SERVER loopback_nopw OPTIONS (ADD password_required 'false'); - - -SELECT * FROM ft1_nopw LIMIT 1; - -RESET ROLE; - --- But the superuser can -ALTER USER MAPPING FOR regress_nosuper SERVER loopback_nopw OPTIONS (ADD password_required 'false'); - -SET ROLE regress_nosuper; - --- Should finally work now -SELECT * FROM ft1_nopw LIMIT 1; - --- unpriv user also cannot set sslcert / sslkey on the user mapping --- first set password_required so we see the right error messages -ALTER USER MAPPING FOR CURRENT_USER SERVER loopback_nopw OPTIONS (SET password_required 'true'); -ALTER USER MAPPING FOR CURRENT_USER SERVER loopback_nopw OPTIONS (ADD sslcert 'foo.crt'); -ALTER USER MAPPING FOR CURRENT_USER SERVER loopback_nopw OPTIONS (ADD sslkey 'foo.key'); - --- We're done with the role named after a specific user and need to check the --- changes to the public mapping. -DROP USER MAPPING FOR CURRENT_USER SERVER loopback_nopw; - --- This will fail again as it'll resolve the user mapping for public, which --- lacks password_required=false -SELECT * FROM ft1_nopw LIMIT 1; - -RESET ROLE; - --- The user mapping for public is passwordless and lacks the password_required=false --- mapping option, but will work because the current user is a superuser. -SELECT * FROM ft1_nopw LIMIT 1; - --- cleanup -DROP USER MAPPING FOR public SERVER loopback_nopw; -DROP OWNED BY regress_nosuper; -DROP ROLE regress_nosuper; -*/ --- influxdb_fdw does not support transactions --- Two-phase transactions are not supported. ---BEGIN; ---Testcase 620: -SELECT count(*) FROM ft1; - count -------- - 822 -(1 row) - --- error here ---PREPARE TRANSACTION 'fdw_tpc'; ---ROLLBACK; --- Clean-up -delete from ft1; -delete from ft2; -delete from ft4; -delete from ft5; -delete from foo; -delete from bar; -delete from loct1; -delete from loct2; -delete from rem1; -drop foreign table foo cascade; -NOTICE: drop cascades to foreign table foo2 -drop foreign table bar cascade; -NOTICE: drop cascades to foreign table bar2 -drop foreign table loct1; -drop foreign table loct2; -drop foreign table ft1; -drop foreign table ft2; -drop foreign table ft4; -drop foreign table ft5; -DROP TYPE IF EXISTS user_enum; -DROP SCHEMA IF EXISTS "S 1" CASCADE; -NOTICE: drop cascades to 6 other objects -DETAIL: drop cascades to foreign table "S 1"."T 0" -drop cascades to foreign table "S 1"."T 1" -drop cascades to foreign table "S 1"."T 2" -drop cascades to foreign table "S 1"."T 3" -drop cascades to foreign table "S 1"."T 4" -drop cascades to function "S 1".f_brtrig() -DROP FUNCTION IF EXISTS trigger_func(); -DROP FUNCTION IF EXISTS trig_row_before_insupdate(); -DROP FUNCTION IF EXISTS trig_null(); -DROP SCHEMA IF EXISTS import_influx1 CASCADE; -NOTICE: drop cascades to 9 other objects -DETAIL: drop cascades to foreign table import_influx1."T1" -drop cascades to foreign table import_influx1."T2" -drop cascades to foreign table import_influx1."T3" -drop cascades to foreign table import_influx1."T4" -drop cascades to foreign table import_influx1.bar -drop cascades to foreign table import_influx1.foo -drop cascades to foreign table import_influx1.loc1 -drop cascades to foreign table import_influx1.loct1 -drop cascades to foreign table import_influx1.loct2 -DROP SCHEMA IF EXISTS import_influx2 CASCADE; -DROP SCHEMA IF EXISTS import_influx3 CASCADE; -DROP SCHEMA IF EXISTS import_influx4 CASCADE; -NOTICE: drop cascades to 9 other objects -DETAIL: drop cascades to foreign table import_influx4."T1" -drop cascades to foreign table import_influx4."T2" -drop cascades to foreign table import_influx4."T3" -drop cascades to foreign table import_influx4."T4" -drop cascades to foreign table import_influx4.bar -drop cascades to foreign table import_influx4.foo -drop cascades to foreign table import_influx4.loc1 -drop cascades to foreign table import_influx4.loct1 -drop cascades to foreign table import_influx4.loct2 ---Testcase 621: -DROP USER MAPPING FOR public SERVER testserver1; ---Testcase 622: -DROP USER MAPPING FOR CURRENT_USER SERVER influxdb_svr; ---Testcase 623: -DROP USER MAPPING FOR CURRENT_USER SERVER influxdb_svr2; ---Testcase 624: -DROP SERVER testserver1 CASCADE; ---Testcase 625: -DROP SERVER influxdb_svr CASCADE; -NOTICE: drop cascades to 4 other objects -DETAIL: drop cascades to foreign table loct3 -drop cascades to foreign table ft3 -drop cascades to foreign table loc1 -drop cascades to foreign table rem1 ---Testcase 626: -DROP SERVER influxdb_svr2 CASCADE; -NOTICE: drop cascades to foreign table ft6 ---Testcase 627: -DROP EXTENSION influxdb_fdw CASCADE; diff --git a/expected/11.17/influxdb_fdw.out b/expected/11.17/influxdb_fdw.out deleted file mode 100644 index 9a352df..0000000 --- a/expected/11.17/influxdb_fdw.out +++ /dev/null @@ -1,1651 +0,0 @@ ---SET log_min_messages=debug1; ---SET client_min_messages=debug1; ---Testcase 1: -SET datestyle=ISO; --- timestamp with time zone differs based on this ---Testcase 2: -SET timezone='Japan'; -\set ECHO none ---Testcase 3: -CREATE EXTENSION influxdb_fdw; ---Testcase 4: -CREATE SERVER server1 FOREIGN DATA WRAPPER influxdb_fdw OPTIONS -(dbname 'mydb', :SERVER); ---Testcase 5: -CREATE USER MAPPING FOR CURRENT_USER SERVER server1 OPTIONS (:AUTHENTICATION); --- import time column as timestamp and text type -IMPORT FOREIGN SCHEMA public FROM SERVER server1 INTO public OPTIONS(import_time_text 'true'); ---Testcase 6: -SELECT * FROM cpu; - time | time_text | tag1 | tag2 | value1 | value2 | value3 | value4 -------------------------+----------------------+--------+--------+--------+--------+--------+-------- - 2015-08-18 09:00:00+09 | 2015-08-18T00:00:00Z | tag1_A | tag2_A | 100 | 0.5 | str | t - 2015-08-18 09:00:00+09 | 2015-08-18T00:00:00Z | tag1_B | | 100 | 2 | | f - 2015-08-18 09:48:08+09 | 2015-08-18T00:48:08Z | | tag2_A | | 2 | | -(3 rows) - ---Testcase 7: -SELECT tag1, value1 FROM cpu; - tag1 | value1 ---------+-------- - tag1_A | 100 - tag1_B | 100 -(2 rows) - ---Testcase 8: -SELECT value1, time, value2 FROM cpu; - value1 | time | value2 ---------+------------------------+-------- - 100 | 2015-08-18 09:00:00+09 | 0.5 - 100 | 2015-08-18 09:00:00+09 | 2 - | 2015-08-18 09:48:08+09 | 2 -(3 rows) - ---Testcase 9: -SELECT value1, time_text, value2 FROM cpu; - value1 | time_text | value2 ---------+----------------------+-------- - 100 | 2015-08-18T00:00:00Z | 0.5 - 100 | 2015-08-18T00:00:00Z | 2 - | 2015-08-18T00:48:08Z | 2 -(3 rows) - ---Testcase 10: -DROP FOREIGN TABLE cpu; ---Testcase 11: -DROP FOREIGN TABLE t3; ---Testcase 12: -DROP FOREIGN TABLE t4; ---Testcase 13: -DROP FOREIGN TABLE tx; ---Testcase 14: -DROP FOREIGN TABLE numbers; --- test EXECPT -IMPORT FOREIGN SCHEMA public EXCEPT (cpu, t3, t4, tx, numbers) FROM SERVER server1 INTO public; ---Testcase 15: -SELECT ftoptions FROM pg_foreign_table; - ftoptions ------------ -(0 rows) - --- test LIMIT TO -IMPORT FOREIGN SCHEMA public LIMIT TO (cpu) FROM SERVER server1 INTO public; ---Testcase 16: -SELECT ftoptions FROM pg_foreign_table; - ftoptions ------------------------------- - {table=cpu,"tags=tag1,tag2"} -(1 row) - ---Testcase 17: -DROP FOREIGN TABLE cpu; -IMPORT FOREIGN SCHEMA public FROM SERVER server1 INTO public OPTIONS(import_time_text 'false'); ---Testcase 18: -SELECT * FROM cpu; - time | tag1 | tag2 | value1 | value2 | value3 | value4 -------------------------+--------+--------+--------+--------+--------+-------- - 2015-08-18 09:00:00+09 | tag1_A | tag2_A | 100 | 0.5 | str | t - 2015-08-18 09:00:00+09 | tag1_B | | 100 | 2 | | f - 2015-08-18 09:48:08+09 | | tag2_A | | 2 | | -(3 rows) - ---Testcase 19: -SELECT tag1, value1 FROM cpu; - tag1 | value1 ---------+-------- - tag1_A | 100 - tag1_B | 100 -(2 rows) - ---Testcase 20: -SELECT value1, time, value2 FROM cpu; - value1 | time | value2 ---------+------------------------+-------- - 100 | 2015-08-18 09:00:00+09 | 0.5 - 100 | 2015-08-18 09:00:00+09 | 2 - | 2015-08-18 09:48:08+09 | 2 -(3 rows) - ---Testcase 21: -SELECT tag1 FROM cpu; - tag1 --------- - tag1_A - tag1_B -(2 rows) - ---Testcase 22: -SELECT * FROM numbers; - time | tag1 | a | b -------------------------+------+---+----- - 1970-01-01 09:00:00+09 | a | 1 | One - 1970-01-01 09:00:01+09 | a | 2 | Two -(2 rows) - ---Testcase 23: -\d cpu; - Foreign table "public.cpu" - Column | Type | Collation | Nullable | Default | FDW options ---------+--------------------------+-----------+----------+---------+------------- - time | timestamp with time zone | | | | - tag1 | text | | | | - tag2 | text | | | | - value1 | bigint | | | | - value2 | double precision | | | | - value3 | text | | | | - value4 | boolean | | | | -Server: server1 -FDW options: ("table" 'cpu', tags 'tag1,tag2') - ---Testcase 24: -SELECT * FROM cpu WHERE value1=100; - time | tag1 | tag2 | value1 | value2 | value3 | value4 -------------------------+--------+--------+--------+--------+--------+-------- - 2015-08-18 09:00:00+09 | tag1_A | tag2_A | 100 | 0.5 | str | t - 2015-08-18 09:00:00+09 | tag1_B | | 100 | 2 | | f -(2 rows) - ---Testcase 25: -SELECT * FROM cpu WHERE value2=0.5; - time | tag1 | tag2 | value1 | value2 | value3 | value4 -------------------------+--------+--------+--------+--------+--------+-------- - 2015-08-18 09:00:00+09 | tag1_A | tag2_A | 100 | 0.5 | str | t -(1 row) - ---Testcase 26: -SELECT * FROM cpu WHERE value3='str'; - time | tag1 | tag2 | value1 | value2 | value3 | value4 -------------------------+--------+--------+--------+--------+--------+-------- - 2015-08-18 09:00:00+09 | tag1_A | tag2_A | 100 | 0.5 | str | t -(1 row) - ---Testcase 27: -SELECT * FROM cpu WHERE value4=true; - time | tag1 | tag2 | value1 | value2 | value3 | value4 -------------------------+--------+--------+--------+--------+--------+-------- - 2015-08-18 09:00:00+09 | tag1_A | tag2_A | 100 | 0.5 | str | t -(1 row) - ---Testcase 28: -SELECT * FROM cpu WHERE NOT (value4 AND value1=100); - time | tag1 | tag2 | value1 | value2 | value3 | value4 -------------------------+--------+------+--------+--------+--------+-------- - 2015-08-18 09:00:00+09 | tag1_B | | 100 | 2 | | f -(1 row) - ---Testcase 29: -SELECT * FROM cpu WHERE tag1='tag1_A'; - time | tag1 | tag2 | value1 | value2 | value3 | value4 -------------------------+--------+--------+--------+--------+--------+-------- - 2015-08-18 09:00:00+09 | tag1_A | tag2_A | 100 | 0.5 | str | t -(1 row) - ---Testcase 30: -EXPLAIN (VERBOSE, COSTS OFF) -SELECT * FROM cpu WHERE value3 IS NULL; - QUERY PLAN --------------------------------------------------------------------------------------------- - Foreign Scan on public.cpu - Output: "time", tag1, tag2, value1, value2, value3, value4 - Filter: (cpu.value3 IS NULL) - InfluxDB query: SELECT "tag1", "tag2", "value1", "value2", "value3", "value4" FROM "cpu" -(4 rows) - ---Testcase 31: -SELECT * FROM cpu WHERE value3 IS NULL; - time | tag1 | tag2 | value1 | value2 | value3 | value4 -------------------------+--------+--------+--------+--------+--------+-------- - 2015-08-18 09:00:00+09 | tag1_B | | 100 | 2 | | f - 2015-08-18 09:48:08+09 | | tag2_A | | 2 | | -(2 rows) - ---Testcase 32: -SELECT * FROM cpu WHERE tag2 IS NULL; - time | tag1 | tag2 | value1 | value2 | value3 | value4 -------------------------+--------+------+--------+--------+--------+-------- - 2015-08-18 09:00:00+09 | tag1_B | | 100 | 2 | | f -(1 row) - ---Testcase 33: -SELECT * FROM cpu WHERE value3 IS NOT NULL; - time | tag1 | tag2 | value1 | value2 | value3 | value4 -------------------------+--------+--------+--------+--------+--------+-------- - 2015-08-18 09:00:00+09 | tag1_A | tag2_A | 100 | 0.5 | str | t -(1 row) - ---Testcase 34: -SELECT * FROM cpu WHERE tag2 IS NOT NULL; - time | tag1 | tag2 | value1 | value2 | value3 | value4 -------------------------+--------+--------+--------+--------+--------+-------- - 2015-08-18 09:00:00+09 | tag1_A | tag2_A | 100 | 0.5 | str | t - 2015-08-18 09:48:08+09 | | tag2_A | | 2 | | -(2 rows) - --- InfluxDB not support compare timestamp with OR condition ---Testcase 35: -SELECT * FROM cpu WHERE time = '2015-08-18 09:48:08+09' OR value2 = 0.5; - time | tag1 | tag2 | value1 | value2 | value3 | value4 -------------------------+--------+--------+--------+--------+--------+-------- - 2015-08-18 09:00:00+09 | tag1_A | tag2_A | 100 | 0.5 | str | t - 2015-08-18 09:48:08+09 | | tag2_A | | 2 | | -(2 rows) - --- InfluxDB not support compare timestamp with != or <> ---Testcase 36: -SELECT * FROM cpu WHERE time != '2015-08-18 09:48:08+09'; - time | tag1 | tag2 | value1 | value2 | value3 | value4 -------------------------+--------+--------+--------+--------+--------+-------- - 2015-08-18 09:00:00+09 | tag1_A | tag2_A | 100 | 0.5 | str | t - 2015-08-18 09:00:00+09 | tag1_B | | 100 | 2 | | f -(2 rows) - ---Testcase 37: -SELECT * FROM cpu WHERE time <> '2015-08-18 09:48:08+09'; - time | tag1 | tag2 | value1 | value2 | value3 | value4 -------------------------+--------+--------+--------+--------+--------+-------- - 2015-08-18 09:00:00+09 | tag1_A | tag2_A | 100 | 0.5 | str | t - 2015-08-18 09:00:00+09 | tag1_B | | 100 | 2 | | f -(2 rows) - ---Testcase 38: -SELECT * FROM cpu WHERE time = '2015-08-18 09:48:08+09' OR value2 = 0.5; - time | tag1 | tag2 | value1 | value2 | value3 | value4 -------------------------+--------+--------+--------+--------+--------+-------- - 2015-08-18 09:00:00+09 | tag1_A | tag2_A | 100 | 0.5 | str | t - 2015-08-18 09:48:08+09 | | tag2_A | | 2 | | -(2 rows) - --- There is inconsitency for search of missing values between tag and field ---Testcase 39: -EXPLAIN (VERBOSE, COSTS OFF) -SELECT * FROM cpu WHERE value3 = ''; - QUERY PLAN --------------------------------------------------------------------------------------------------------------------- - Foreign Scan on public.cpu - Output: "time", tag1, tag2, value1, value2, value3, value4 - InfluxDB query: SELECT "tag1", "tag2", "value1", "value2", "value3", "value4" FROM "cpu" WHERE (("value3" = '')) -(3 rows) - ---Testcase 40: -SELECT * FROM cpu WHERE value3 = ''; - time | tag1 | tag2 | value1 | value2 | value3 | value4 -------+------+------+--------+--------+--------+-------- -(0 rows) - ---Testcase 41: -EXPLAIN (VERBOSE, COSTS OFF) -SELECT * FROM cpu WHERE tag2 = ''; - QUERY PLAN ------------------------------------------------------------------------------------------------------------------- - Foreign Scan on public.cpu - Output: "time", tag1, tag2, value1, value2, value3, value4 - InfluxDB query: SELECT "tag1", "tag2", "value1", "value2", "value3", "value4" FROM "cpu" WHERE (("tag2" = '')) -(3 rows) - ---Testcase 42: -SELECT * FROM cpu WHERE tag2 = ''; - time | tag1 | tag2 | value1 | value2 | value3 | value4 -------------------------+--------+------+--------+--------+--------+-------- - 2015-08-18 09:00:00+09 | tag1_B | | 100 | 2 | | f -(1 row) - ---Testcase 43: -SELECT * FROM cpu WHERE tag1 IN ('tag1_A', 'tag1_B'); - time | tag1 | tag2 | value1 | value2 | value3 | value4 -------------------------+--------+--------+--------+--------+--------+-------- - 2015-08-18 09:00:00+09 | tag1_A | tag2_A | 100 | 0.5 | str | t - 2015-08-18 09:00:00+09 | tag1_B | | 100 | 2 | | f -(2 rows) - ---Testcase 44: -EXPLAIN VERBOSE -SELECT * FROM cpu WHERE tag1 IN ('tag1_A', 'tag1_B'); - QUERY PLAN -------------------------------------------------------------------------------------------------------------------------------------------- - Foreign Scan on public.cpu (cost=10.00..6.00 rows=6 width=121) - Output: "time", tag1, tag2, value1, value2, value3, value4 - InfluxDB query: SELECT "tag1", "tag2", "value1", "value2", "value3", "value4" FROM "cpu" WHERE ("tag1" = 'tag1_A' OR "tag1" = 'tag1_B') -(3 rows) - --- Rows which have no tag are considered to have empty string ---Testcase 45: -SELECT * FROM cpu WHERE tag1 NOT IN ('tag1_A', 'tag1_B'); - time | tag1 | tag2 | value1 | value2 | value3 | value4 -------------------------+------+--------+--------+--------+--------+-------- - 2015-08-18 09:48:08+09 | | tag2_A | | 2 | | -(1 row) - ---Testcase 46: -EXPLAIN VERBOSE -SELECT * FROM cpu WHERE tag1 NOT IN ('tag1_A', 'tag1_B'); - QUERY PLAN ----------------------------------------------------------------------------------------------------------------------------------------------- - Foreign Scan on public.cpu (cost=10.00..558.00 rows=558 width=121) - Output: "time", tag1, tag2, value1, value2, value3, value4 - InfluxDB query: SELECT "tag1", "tag2", "value1", "value2", "value3", "value4" FROM "cpu" WHERE ("tag1" <> 'tag1_A' AND "tag1" <> 'tag1_B') -(3 rows) - --- test IN/NOT IN ---Testcase 47: -SELECT * FROM cpu WHERE time IN ('2015-08-18 09:48:08+09','2016-08-28 07:44:00+07'); - time | tag1 | tag2 | value1 | value2 | value3 | value4 -------------------------+------+--------+--------+--------+--------+-------- - 2015-08-18 09:48:08+09 | | tag2_A | | 2 | | -(1 row) - ---Testcase 48: -SELECT * FROM cpu WHERE time NOT IN ('2015-08-18 09:48:08+09','2016-08-28 07:44:00+07'); - time | tag1 | tag2 | value1 | value2 | value3 | value4 -------------------------+--------+--------+--------+--------+--------+-------- - 2015-08-18 09:00:00+09 | tag1_A | tag2_A | 100 | 0.5 | str | t - 2015-08-18 09:00:00+09 | tag1_B | | 100 | 2 | | f -(2 rows) - ---Testcase 49: -SELECT * FROM cpu WHERE value1 NOT IN (100, 97); - time | tag1 | tag2 | value1 | value2 | value3 | value4 -------+------+------+--------+--------+--------+-------- -(0 rows) - ---Testcase 50: -SELECT * FROM cpu WHERE value1 IN (100, 97); - time | tag1 | tag2 | value1 | value2 | value3 | value4 -------------------------+--------+--------+--------+--------+--------+-------- - 2015-08-18 09:00:00+09 | tag1_A | tag2_A | 100 | 0.5 | str | t - 2015-08-18 09:00:00+09 | tag1_B | | 100 | 2 | | f -(2 rows) - ---Testcase 51: -SELECT * FROM cpu WHERE value2 IN (0.5, 10.9); - time | tag1 | tag2 | value1 | value2 | value3 | value4 -------------------------+--------+--------+--------+--------+--------+-------- - 2015-08-18 09:00:00+09 | tag1_A | tag2_A | 100 | 0.5 | str | t -(1 row) - ---Testcase 52: -SELECT * FROM cpu WHERE value2 NOT IN (2, 9.7); - time | tag1 | tag2 | value1 | value2 | value3 | value4 -------------------------+--------+--------+--------+--------+--------+-------- - 2015-08-18 09:00:00+09 | tag1_A | tag2_A | 100 | 0.5 | str | t -(1 row) - ---Testcase 53: -SELECT * FROM cpu WHERE value4 NOT IN ('true', 'true'); - time | tag1 | tag2 | value1 | value2 | value3 | value4 -------------------------+--------+------+--------+--------+--------+-------- - 2015-08-18 09:00:00+09 | tag1_B | | 100 | 2 | | f -(1 row) - ---Testcase 54: -SELECT * FROM cpu WHERE time IN ('2015-08-18 09:48:08+09','2016-08-28 07:44:00+07'); - time | tag1 | tag2 | value1 | value2 | value3 | value4 -------------------------+------+--------+--------+--------+--------+-------- - 2015-08-18 09:48:08+09 | | tag2_A | | 2 | | -(1 row) - ---Testcase 55: -SELECT * FROM cpu WHERE time NOT IN ('2015-08-18 09:48:08+09','2016-08-28 07:44:00+07'); - time | tag1 | tag2 | value1 | value2 | value3 | value4 -------------------------+--------+--------+--------+--------+--------+-------- - 2015-08-18 09:00:00+09 | tag1_A | tag2_A | 100 | 0.5 | str | t - 2015-08-18 09:00:00+09 | tag1_B | | 100 | 2 | | f -(2 rows) - ---Testcase 56: -SELECT * FROM cpu WHERE value1 NOT IN (100, 97); - time | tag1 | tag2 | value1 | value2 | value3 | value4 -------+------+------+--------+--------+--------+-------- -(0 rows) - ---Testcase 57: -SELECT * FROM cpu WHERE value1 IN (100, 97); - time | tag1 | tag2 | value1 | value2 | value3 | value4 -------------------------+--------+--------+--------+--------+--------+-------- - 2015-08-18 09:00:00+09 | tag1_A | tag2_A | 100 | 0.5 | str | t - 2015-08-18 09:00:00+09 | tag1_B | | 100 | 2 | | f -(2 rows) - ---Testcase 58: -SELECT * FROM cpu WHERE value2 IN (0.5, 10.9); - time | tag1 | tag2 | value1 | value2 | value3 | value4 -------------------------+--------+--------+--------+--------+--------+-------- - 2015-08-18 09:00:00+09 | tag1_A | tag2_A | 100 | 0.5 | str | t -(1 row) - ---Testcase 59: -SELECT * FROM cpu WHERE value2 NOT IN (2, 9.7); - time | tag1 | tag2 | value1 | value2 | value3 | value4 -------------------------+--------+--------+--------+--------+--------+-------- - 2015-08-18 09:00:00+09 | tag1_A | tag2_A | 100 | 0.5 | str | t -(1 row) - ---Testcase 60: -SELECT * FROM cpu WHERE value4 NOT IN ('true', 'true'); - time | tag1 | tag2 | value1 | value2 | value3 | value4 -------------------------+--------+------+--------+--------+--------+-------- - 2015-08-18 09:00:00+09 | tag1_B | | 100 | 2 | | f -(1 row) - ---Testcase 61: -SELECT * FROM cpu WHERE value4 IN ('f', 't'); - time | tag1 | tag2 | value1 | value2 | value3 | value4 -------------------------+--------+--------+--------+--------+--------+-------- - 2015-08-18 09:00:00+09 | tag1_A | tag2_A | 100 | 0.5 | str | t - 2015-08-18 09:00:00+09 | tag1_B | | 100 | 2 | | f -(2 rows) - ---Testcase 62: -CREATE FOREIGN TABLE t1(time timestamp with time zone , tag1 text, value1 integer) SERVER server1 OPTIONS (table 'cpu'); ---Testcase 63: -CREATE FOREIGN TABLE t2(time timestamp , tag1 text, value1 integer) SERVER server1 OPTIONS (table 'cpu'); ---Testcase 64: -SELECT * FROM t1; - time | tag1 | value1 -------------------------+--------+-------- - 2015-08-18 09:00:00+09 | tag1_A | 100 - 2015-08-18 09:00:00+09 | tag1_B | 100 -(2 rows) - ---Testcase 65: -SELECT * FROM t2; - time | tag1 | value1 ----------------------+--------+-------- - 2015-08-18 00:00:00 | tag1_A | 100 - 2015-08-18 00:00:00 | tag1_B | 100 -(2 rows) - --- In following four queries, timestamp condition is added to InfluxQL as "time = '2015-08-18 00:00:00'" ---Testcase 66: -SELECT * FROM t1 WHERE time = TIMESTAMP WITH TIME ZONE '2015-08-18 09:00:00+09'; - time | tag1 | value1 -------------------------+--------+-------- - 2015-08-18 09:00:00+09 | tag1_A | 100 - 2015-08-18 09:00:00+09 | tag1_B | 100 -(2 rows) - ---Testcase 67: -SELECT * FROM t1 WHERE time = TIMESTAMP '2015-08-18 00:00:00'; - time | tag1 | value1 -------------------------+--------+-------- - 2015-08-18 09:00:00+09 | tag1_A | 100 - 2015-08-18 09:00:00+09 | tag1_B | 100 -(2 rows) - ---Testcase 68: -SELECT * FROM t2 WHERE time = TIMESTAMP WITH TIME ZONE '2015-08-18 09:00:00+09'; - time | tag1 | value1 ----------------------+--------+-------- - 2015-08-18 00:00:00 | tag1_A | 100 - 2015-08-18 00:00:00 | tag1_B | 100 -(2 rows) - ---Testcase 69: -SELECT * FROM t2 WHERE time = TIMESTAMP '2015-08-18 00:00:00'; - time | tag1 | value1 ----------------------+--------+-------- - 2015-08-18 00:00:00 | tag1_A | 100 - 2015-08-18 00:00:00 | tag1_B | 100 -(2 rows) - --- pushdown now() ---Testcase 70: -SELECT * FROM t2 WHERE now() > time; - time | tag1 | value1 ----------------------+--------+-------- - 2015-08-18 00:00:00 | tag1_A | 100 - 2015-08-18 00:00:00 | tag1_B | 100 -(2 rows) - ---Testcase 71: -EXPLAIN VERBOSE -SELECT * FROM t2 WHERE now() > time; - QUERY PLAN ------------------------------------------------------------------------------ - Foreign Scan on public.t2 (cost=10.00..401.00 rows=401 width=44) - Output: "time", tag1, value1 - InfluxDB query: SELECT "tag1", "value1" FROM "cpu" WHERE ((now() > time)) -(3 rows) - ---Testcase 72: -SELECT * FROM t2 WHERE time = TIMESTAMP WITH TIME ZONE '2015-08-26 05:43:21.1+00' - interval '1 week 1 day 5 hour 43 minute 21 second 100 millisecond'; - time | tag1 | value1 ----------------------+--------+-------- - 2015-08-18 00:00:00 | tag1_A | 100 - 2015-08-18 00:00:00 | tag1_B | 100 -(2 rows) - ---Testcase 73: -EXPLAIN VERBOSE -SELECT * FROM t2 WHERE time = TIMESTAMP WITH TIME ZONE '2015-08-26 05:43:21.1+00' - interval '1 week 1 day 5 hour 43 minute 21 second 100 millisecond'; - QUERY PLAN ---------------------------------------------------------------------------------------------------------------------- - Foreign Scan on public.t2 (cost=10.00..6.00 rows=6 width=44) - Output: "time", tag1, value1 - InfluxDB query: SELECT "tag1", "value1" FROM "cpu" WHERE ((time = ('2015-08-26 05:43:21.1' - 8d5h43m21s100000u))) -(3 rows) - --- InfluxDB does not seem to support time column + interval, so below query returns empty result --- SELECT * FROM t2 WHERE time + interval '1 week 1 day 5 hour 43 minute 21 second 100 millisecond' = TIMESTAMP WITH TIME ZONE '2015-08-26 05:43:21.1+00'; --- EXPLAIN (VERBOSE, COSTS OFF) --- SELECT * FROM t2 WHERE time + interval '1 week 1 day 5 hour 43 minute 21 second 100 millisecond' = TIMESTAMP WITH TIME ZONE '2015-08-26 05:43:21.1+00'; --- InfluxDB does not support month or year interval, so not push down ---Testcase 74: -SELECT * FROM t2 WHERE time = TIMESTAMP '2015-09-18 00:00:00' - interval '1 months'; - time | tag1 | value1 ----------------------+--------+-------- - 2015-08-18 00:00:00 | tag1_A | 100 - 2015-08-18 00:00:00 | tag1_B | 100 -(2 rows) - ---Testcase 75: -EXPLAIN VERBOSE -SELECT * FROM t2 WHERE time = TIMESTAMP '2015-09-18 00:00:00' - interval '1 months'; - QUERY PLAN ---------------------------------------------------------------------------------------------- - Foreign Scan on public.t2 (cost=10.00..6.00 rows=6 width=44) - Output: "time", tag1, value1 - InfluxDB query: SELECT "tag1", "value1" FROM "cpu" WHERE ((time = '2015-08-18 00:00:00')) -(3 rows) - ---Testcase 76: -SELECT * FROM t2 WHERE value1 = ANY (ARRAY(SELECT value1 FROM t1 WHERE value1 < 1000)); - time | tag1 | value1 ----------------------+--------+-------- - 2015-08-18 00:00:00 | tag1_A | 100 - 2015-08-18 00:00:00 | tag1_B | 100 -(2 rows) - --- ANY with ARRAY expression ---Testcase 77: -EXPLAIN VERBOSE -SELECT a, b FROM numbers WHERE a = ANY(ARRAY[1, a + 1]); - QUERY PLAN ------------------------------------------------------------------------------------------ - Foreign Scan on public.numbers (cost=10.00..13.00 rows=13 width=40) - Output: a, b - InfluxDB query: SELECT "a", "b" FROM "numbers" WHERE (("a" = 1) OR ("a" = ("a" + 1))) -(3 rows) - ---Testcase 78: -SELECT a, b FROM numbers WHERE a = ANY(ARRAY[1, a + 1]); - a | b ----+----- - 1 | One -(1 row) - ---Testcase 79: -EXPLAIN VERBOSE -SELECT a, b FROM numbers WHERE a <> ANY(ARRAY[1, a + 1]); - QUERY PLAN -------------------------------------------------------------------------------------------- - Foreign Scan on public.numbers (cost=10.00..1280.00 rows=1280 width=40) - Output: a, b - InfluxDB query: SELECT "a", "b" FROM "numbers" WHERE (("a" <> 1) OR ("a" <> ("a" + 1))) -(3 rows) - ---Testcase 80: -SELECT a, b FROM numbers WHERE a <> ANY(ARRAY[1, a + 1]); - a | b ----+----- - 1 | One - 2 | Two -(2 rows) - ---Testcase 81: -EXPLAIN VERBOSE -SELECT a, b FROM numbers WHERE a >= ANY(ARRAY[1, a + 1]); - QUERY PLAN -------------------------------------------------------------------------------------------- - Foreign Scan on public.numbers (cost=10.00..711.00 rows=711 width=40) - Output: a, b - InfluxDB query: SELECT "a", "b" FROM "numbers" WHERE (("a" >= 1) OR ("a" >= ("a" + 1))) -(3 rows) - ---Testcase 82: -SELECT a, b FROM numbers WHERE a >= ANY(ARRAY[1, a + 1]); - a | b ----+----- - 1 | One - 2 | Two -(2 rows) - ---Testcase 83: -EXPLAIN VERBOSE -SELECT a, b FROM numbers WHERE a <= ANY(ARRAY[1, a + 1]); - QUERY PLAN -------------------------------------------------------------------------------------------- - Foreign Scan on public.numbers (cost=10.00..711.00 rows=711 width=40) - Output: a, b - InfluxDB query: SELECT "a", "b" FROM "numbers" WHERE (("a" <= 1) OR ("a" <= ("a" + 1))) -(3 rows) - ---Testcase 84: -SELECT a, b FROM numbers WHERE a <= ANY(ARRAY[1, a + 1]); - a | b ----+----- - 1 | One - 2 | Two -(2 rows) - ---Testcase 85: -EXPLAIN VERBOSE -SELECT a, b FROM numbers WHERE a > ANY(ARRAY[1, a + 1]); - QUERY PLAN ------------------------------------------------------------------------------------------ - Foreign Scan on public.numbers (cost=10.00..711.00 rows=711 width=40) - Output: a, b - InfluxDB query: SELECT "a", "b" FROM "numbers" WHERE (("a" > 1) OR ("a" > ("a" + 1))) -(3 rows) - ---Testcase 86: -SELECT a, b FROM numbers WHERE a > ANY(ARRAY[1, a + 1]); - a | b ----+----- - 2 | Two -(1 row) - ---Testcase 87: -EXPLAIN VERBOSE -SELECT a, b FROM numbers WHERE a < ANY(ARRAY[1, a + 1]); - QUERY PLAN ------------------------------------------------------------------------------------------ - Foreign Scan on public.numbers (cost=10.00..711.00 rows=711 width=40) - Output: a, b - InfluxDB query: SELECT "a", "b" FROM "numbers" WHERE (("a" < 1) OR ("a" < ("a" + 1))) -(3 rows) - ---Testcase 88: -SELECT a, b FROM numbers WHERE a < ANY(ARRAY[1, a + 1]); - a | b ----+----- - 1 | One - 2 | Two -(2 rows) - --- ANY with ARRAY const ---Testcase 89: -EXPLAIN VERBOSE -SELECT a, b FROM numbers WHERE a = ANY(ARRAY[1, 2]); - QUERY PLAN ------------------------------------------------------------------------------ - Foreign Scan on public.numbers (cost=10.00..13.00 rows=13 width=40) - Output: a, b - InfluxDB query: SELECT "a", "b" FROM "numbers" WHERE ("a" = 1 OR "a" = 2) -(3 rows) - ---Testcase 90: -SELECT a, b FROM numbers WHERE a = ANY(ARRAY[1, 2]); - a | b ----+----- - 1 | One - 2 | Two -(2 rows) - ---Testcase 91: -EXPLAIN VERBOSE -SELECT a, b FROM numbers WHERE a <> ANY(ARRAY[1, 2]); - QUERY PLAN -------------------------------------------------------------------------------- - Foreign Scan on public.numbers (cost=10.00..1280.00 rows=1280 width=40) - Output: a, b - InfluxDB query: SELECT "a", "b" FROM "numbers" WHERE ("a" <> 1 OR "a" <> 2) -(3 rows) - ---Testcase 92: -SELECT a, b FROM numbers WHERE a <> ANY(ARRAY[1, 2]); - a | b ----+----- - 1 | One - 2 | Two -(2 rows) - ---Testcase 93: -EXPLAIN VERBOSE -SELECT a, b FROM numbers WHERE a >= ANY(ARRAY[1, 2]); - QUERY PLAN -------------------------------------------------------------------------------- - Foreign Scan on public.numbers (cost=10.00..711.00 rows=711 width=40) - Output: a, b - InfluxDB query: SELECT "a", "b" FROM "numbers" WHERE ("a" >= 1 OR "a" >= 2) -(3 rows) - ---Testcase 94: -SELECT a, b FROM numbers WHERE a >= ANY(ARRAY[1, 2]); - a | b ----+----- - 1 | One - 2 | Two -(2 rows) - ---Testcase 95: -EXPLAIN VERBOSE -SELECT a, b FROM numbers WHERE a <= ANY(ARRAY[1, 2]); - QUERY PLAN -------------------------------------------------------------------------------- - Foreign Scan on public.numbers (cost=10.00..711.00 rows=711 width=40) - Output: a, b - InfluxDB query: SELECT "a", "b" FROM "numbers" WHERE ("a" <= 1 OR "a" <= 2) -(3 rows) - ---Testcase 96: -SELECT a, b FROM numbers WHERE a <= ANY(ARRAY[1, 2]); - a | b ----+----- - 1 | One - 2 | Two -(2 rows) - ---Testcase 97: -EXPLAIN VERBOSE -SELECT a, b FROM numbers WHERE a > ANY(ARRAY[1, 2]); - QUERY PLAN ------------------------------------------------------------------------------ - Foreign Scan on public.numbers (cost=10.00..711.00 rows=711 width=40) - Output: a, b - InfluxDB query: SELECT "a", "b" FROM "numbers" WHERE ("a" > 1 OR "a" > 2) -(3 rows) - ---Testcase 98: -SELECT a, b FROM numbers WHERE a > ANY(ARRAY[1, 2]); - a | b ----+----- - 2 | Two -(1 row) - ---Testcase 99: -EXPLAIN VERBOSE -SELECT a, b FROM numbers WHERE a < ANY(ARRAY[1, 2]); - QUERY PLAN ------------------------------------------------------------------------------ - Foreign Scan on public.numbers (cost=10.00..711.00 rows=711 width=40) - Output: a, b - InfluxDB query: SELECT "a", "b" FROM "numbers" WHERE ("a" < 1 OR "a" < 2) -(3 rows) - ---Testcase 100: -SELECT a, b FROM numbers WHERE a < ANY(ARRAY[1, 2]); - a | b ----+----- - 1 | One -(1 row) - ---Testcase 101: -EXPLAIN VERBOSE -SELECT a, b FROM numbers WHERE a = ANY('{1, 2, 3}'); - QUERY PLAN ----------------------------------------------------------------------------------------- - Foreign Scan on public.numbers (cost=10.00..19.00 rows=19 width=40) - Output: a, b - InfluxDB query: SELECT "a", "b" FROM "numbers" WHERE ("a" = 1 OR "a" = 2 OR "a" = 3) -(3 rows) - ---Testcase 102: -SELECT a, b FROM numbers WHERE a = ANY('{1, 2, 3}'); - a | b ----+----- - 1 | One - 2 | Two -(2 rows) - ---Testcase 103: -EXPLAIN VERBOSE -SELECT a, b FROM numbers WHERE a <> ANY('{1, 2, 3}'); - QUERY PLAN -------------------------------------------------------------------------------------------- - Foreign Scan on public.numbers (cost=10.00..1280.00 rows=1280 width=40) - Output: a, b - InfluxDB query: SELECT "a", "b" FROM "numbers" WHERE ("a" <> 1 OR "a" <> 2 OR "a" <> 3) -(3 rows) - ---Testcase 104: -SELECT a, b FROM numbers WHERE a <> ANY('{1, 2, 3}'); - a | b ----+----- - 1 | One - 2 | Two -(2 rows) - --- ALL with ARRAY expression ---Testcase 105: -EXPLAIN VERBOSE -SELECT a, b FROM numbers WHERE a = ALL(ARRAY[1, a * 1]); - QUERY PLAN ------------------------------------------------------------------------------------------- - Foreign Scan on public.numbers (cost=10.00..1.00 rows=1 width=40) - Output: a, b - InfluxDB query: SELECT "a", "b" FROM "numbers" WHERE (("a" = 1) AND ("a" = ("a" * 1))) -(3 rows) - ---Testcase 106: -SELECT a, b FROM numbers WHERE a = ALL(ARRAY[1, a * 1]); - a | b ----+----- - 1 | One -(1 row) - ---Testcase 107: -EXPLAIN VERBOSE -SELECT a, b FROM numbers WHERE a <> ALL(ARRAY[1, a + 1]); - QUERY PLAN --------------------------------------------------------------------------------------------- - Foreign Scan on public.numbers (cost=10.00..1267.00 rows=1267 width=40) - Output: a, b - InfluxDB query: SELECT "a", "b" FROM "numbers" WHERE (("a" <> 1) AND ("a" <> ("a" + 1))) -(3 rows) - ---Testcase 108: -SELECT a, b FROM numbers WHERE a <> ALL(ARRAY[1, a + 1]); - a | b ----+----- - 2 | Two -(1 row) - ---Testcase 109: -EXPLAIN VERBOSE -SELECT a, b FROM numbers WHERE a >= ALL(ARRAY[1, a / 1]); - QUERY PLAN --------------------------------------------------------------------------------------------- - Foreign Scan on public.numbers (cost=10.00..142.00 rows=142 width=40) - Output: a, b - InfluxDB query: SELECT "a", "b" FROM "numbers" WHERE (("a" >= 1) AND ("a" >= ("a" / 1))) -(3 rows) - ---Testcase 110: -SELECT a, b FROM numbers WHERE a >= ALL(ARRAY[1, a / 1]); - a | b ----+----- - 1 | One - 2 | Two -(2 rows) - ---Testcase 111: -EXPLAIN VERBOSE -SELECT a, b FROM numbers WHERE a <= ALL(ARRAY[1, a + 1]); - QUERY PLAN --------------------------------------------------------------------------------------------- - Foreign Scan on public.numbers (cost=10.00..142.00 rows=142 width=40) - Output: a, b - InfluxDB query: SELECT "a", "b" FROM "numbers" WHERE (("a" <= 1) AND ("a" <= ("a" + 1))) -(3 rows) - ---Testcase 112: -SELECT a, b FROM numbers WHERE a <= ALL(ARRAY[1, a + 1]); - a | b ----+----- - 1 | One -(1 row) - ---Testcase 113: -EXPLAIN VERBOSE -SELECT a, b FROM numbers WHERE a > ALL(ARRAY[1, a - 1]); - QUERY PLAN ------------------------------------------------------------------------------------------- - Foreign Scan on public.numbers (cost=10.00..142.00 rows=142 width=40) - Output: a, b - InfluxDB query: SELECT "a", "b" FROM "numbers" WHERE (("a" > 1) AND ("a" > ("a" - 1))) -(3 rows) - ---Testcase 114: -SELECT a, b FROM numbers WHERE a > ALL(ARRAY[1, a - 1]); - a | b ----+----- - 2 | Two -(1 row) - ---Testcase 115: -EXPLAIN VERBOSE -SELECT a, b FROM numbers WHERE a < ALL(ARRAY[2, a + 1]); - QUERY PLAN ------------------------------------------------------------------------------------------- - Foreign Scan on public.numbers (cost=10.00..142.00 rows=142 width=40) - Output: a, b - InfluxDB query: SELECT "a", "b" FROM "numbers" WHERE (("a" < 2) AND ("a" < ("a" + 1))) -(3 rows) - ---Testcase 116: -SELECT a, b FROM numbers WHERE a < ALL(ARRAY[2, a + 1]); - a | b ----+----- - 1 | One -(1 row) - --- ALL with ARRAY const ---Testcase 117: -EXPLAIN VERBOSE -SELECT a, b FROM numbers WHERE a = ALL(ARRAY[1, 1]); - QUERY PLAN ------------------------------------------------------------------------------- - Foreign Scan on public.numbers (cost=10.00..1.00 rows=1 width=40) - Output: a, b - InfluxDB query: SELECT "a", "b" FROM "numbers" WHERE ("a" = 1 AND "a" = 1) -(3 rows) - ---Testcase 118: -SELECT a, b FROM numbers WHERE a = ALL(ARRAY[1, 1]); - a | b ----+----- - 1 | One -(1 row) - ---Testcase 119: -EXPLAIN VERBOSE -SELECT a, b FROM numbers WHERE a <> ALL(ARRAY[1, 3]); - QUERY PLAN --------------------------------------------------------------------------------- - Foreign Scan on public.numbers (cost=10.00..1267.00 rows=1267 width=40) - Output: a, b - InfluxDB query: SELECT "a", "b" FROM "numbers" WHERE ("a" <> 1 AND "a" <> 3) -(3 rows) - ---Testcase 120: -SELECT a, b FROM numbers WHERE a <> ALL(ARRAY[1, 3]); - a | b ----+----- - 2 | Two -(1 row) - ---Testcase 121: -EXPLAIN VERBOSE -SELECT a, b FROM numbers WHERE a >= ALL(ARRAY[1, 2]); - QUERY PLAN --------------------------------------------------------------------------------- - Foreign Scan on public.numbers (cost=10.00..142.00 rows=142 width=40) - Output: a, b - InfluxDB query: SELECT "a", "b" FROM "numbers" WHERE ("a" >= 1 AND "a" >= 2) -(3 rows) - ---Testcase 122: -SELECT a, b FROM numbers WHERE a >= ALL(ARRAY[1, 2]); - a | b ----+----- - 2 | Two -(1 row) - ---Testcase 123: -EXPLAIN VERBOSE -SELECT a, b FROM numbers WHERE a <= ALL(ARRAY[1, 2]); - QUERY PLAN --------------------------------------------------------------------------------- - Foreign Scan on public.numbers (cost=10.00..142.00 rows=142 width=40) - Output: a, b - InfluxDB query: SELECT "a", "b" FROM "numbers" WHERE ("a" <= 1 AND "a" <= 2) -(3 rows) - ---Testcase 124: -SELECT a, b FROM numbers WHERE a <= ALL(ARRAY[1, 2]); - a | b ----+----- - 1 | One -(1 row) - ---Testcase 125: -EXPLAIN VERBOSE -SELECT a, b FROM numbers WHERE a > ALL(ARRAY[0, 1]); - QUERY PLAN ------------------------------------------------------------------------------- - Foreign Scan on public.numbers (cost=10.00..142.00 rows=142 width=40) - Output: a, b - InfluxDB query: SELECT "a", "b" FROM "numbers" WHERE ("a" > 0 AND "a" > 1) -(3 rows) - ---Testcase 126: -SELECT a, b FROM numbers WHERE a > ALL(ARRAY[0, 1]); - a | b ----+----- - 2 | Two -(1 row) - ---Testcase 127: -EXPLAIN VERBOSE -SELECT a, b FROM numbers WHERE a < ALL(ARRAY[2, 3]); - QUERY PLAN ------------------------------------------------------------------------------- - Foreign Scan on public.numbers (cost=10.00..142.00 rows=142 width=40) - Output: a, b - InfluxDB query: SELECT "a", "b" FROM "numbers" WHERE ("a" < 2 AND "a" < 3) -(3 rows) - ---Testcase 128: -SELECT a, b FROM numbers WHERE a < ALL(ARRAY[2, 3]); - a | b ----+----- - 1 | One -(1 row) - --- ANY/ALL with TEXT ARRAY const ---Testcase 129: -EXPLAIN VERBOSE -SELECT a, b FROM numbers WHERE b = ANY(ARRAY['One', 'Two']); - QUERY PLAN -------------------------------------------------------------------------------------- - Foreign Scan on public.numbers (cost=10.00..13.00 rows=13 width=40) - Output: a, b - InfluxDB query: SELECT "a", "b" FROM "numbers" WHERE ("b" = 'One' OR "b" = 'Two') -(3 rows) - ---Testcase 130: -SELECT a, b FROM numbers WHERE b = ANY(ARRAY['One', 'Two']); - a | b ----+----- - 1 | One - 2 | Two -(2 rows) - ---Testcase 131: -EXPLAIN VERBOSE -SELECT a, b FROM numbers WHERE b <> ALL(ARRAY['One', 'Four']); - QUERY PLAN ------------------------------------------------------------------------------------------ - Foreign Scan on public.numbers (cost=10.00..1267.00 rows=1267 width=40) - Output: a, b - InfluxDB query: SELECT "a", "b" FROM "numbers" WHERE ("b" <> 'One' AND "b" <> 'Four') -(3 rows) - ---Testcase 132: -SELECT a, b FROM numbers WHERE b <> ALL(ARRAY['One', 'Four']); - a | b ----+----- - 2 | Two -(1 row) - ---Testcase 133: -EXPLAIN VERBOSE -SELECT a, b FROM numbers WHERE b > ANY(ARRAY['One', 'Two']); - QUERY PLAN ------------------------------------------------------------------------- - Foreign Scan on public.numbers (cost=10.00..711.00 rows=711 width=40) - Output: a, b - Filter: (numbers.b > ANY ('{One,Two}'::text[])) - InfluxDB query: SELECT "a", "b" FROM "numbers" -(4 rows) - ---Testcase 134: -SELECT a, b FROM numbers WHERE b > ANY(ARRAY['One', 'Two']); - a | b ----+----- - 2 | Two -(1 row) - ---Testcase 135: -EXPLAIN VERBOSE -SELECT * FROM numbers WHERE b > ALL(ARRAY['Four', 'Five']); - QUERY PLAN ----------------------------------------------------------------------- - Foreign Scan on public.numbers (cost=10.00..87.00 rows=87 width=80) - Output: "time", tag1, a, b - Filter: (numbers.b > ALL ('{Four,Five}'::text[])) - InfluxDB query: SELECT "tag1", "a", "b" FROM "numbers" -(4 rows) - ---Testcase 136: -SELECT a, b FROM numbers WHERE b > ALL(ARRAY['Four', 'Five']); - a | b ----+----- - 1 | One - 2 | Two -(2 rows) - ---Testcase 137: -DROP FOREIGN TABLE numbers; ---Testcase 138: -ALTER SERVER server1 OPTIONS (SET dbname 'no such database'); ---Testcase 139: -SELECT * FROM t1; -ERROR: influxdb_fdw : database not found: no such database ---Testcase 140: -ALTER SERVER server1 OPTIONS (SET dbname 'mydb'); ---Testcase 141: -SELECT * FROM t1; - time | tag1 | value1 -------------------------+--------+-------- - 2015-08-18 09:00:00+09 | tag1_A | 100 - 2015-08-18 09:00:00+09 | tag1_B | 100 -(2 rows) - --- map time column to both timestamp and text ---Testcase 142: -CREATE FOREIGN TABLE t5(t timestamp OPTIONS (column_name 'time'), tag1 text OPTIONS (column_name 'time'), v1 integer OPTIONS (column_name 'value1')) SERVER server1 OPTIONS (table 'cpu'); ---Testcase 143: -SELECT * FROM t5; - t | tag1 | v1 ----------------------+----------------------+----- - 2015-08-18 00:00:00 | 2015-08-18T00:00:00Z | 100 - 2015-08-18 00:00:00 | 2015-08-18T00:00:00Z | 100 -(2 rows) - ---get version ---Testcase 144: -\df influxdb_fdw* - List of functions - Schema | Name | Result data type | Argument data types | Type ---------+------------------------+------------------+---------------------+------ - public | influxdb_fdw_handler | fdw_handler | | func - public | influxdb_fdw_validator | void | text[], oid | func - public | influxdb_fdw_version | integer | | func -(3 rows) - ---Testcase 145: -SELECT * FROM public.influxdb_fdw_version(); - influxdb_fdw_version ----------------------- - 20000 -(1 row) - ---Testcase 146: -SELECT influxdb_fdw_version(); - influxdb_fdw_version ----------------------- - 20000 -(1 row) - ---Test pushdown LIMIT...OFFSET ---Testcase 147: -EXPLAIN (VERBOSE, COSTS OFF) -SELECT tableoid::regclass, * FROM t1 LIMIT 1 OFFSET 0; - QUERY PLAN ------------------------------------------------------------- - Limit - Output: ((tableoid)::regclass), "time", tag1, value1 - -> Foreign Scan on public.t1 - Output: (tableoid)::regclass, "time", tag1, value1 - InfluxDB query: SELECT "tag1", "value1" FROM "cpu" -(5 rows) - ---Testcase 148: -SELECT tableoid::regclass, * FROM t1 LIMIT 1 OFFSET 0; - tableoid | time | tag1 | value1 -----------+------------------------+--------+-------- - t1 | 2015-08-18 09:00:00+09 | tag1_A | 100 -(1 row) - ---Testcase 149: -EXPLAIN (VERBOSE, COSTS OFF) -SELECT tableoid::regclass, * FROM t1 LIMIT 1 OFFSET 1; - QUERY PLAN ------------------------------------------------------------- - Limit - Output: ((tableoid)::regclass), "time", tag1, value1 - -> Foreign Scan on public.t1 - Output: (tableoid)::regclass, "time", tag1, value1 - InfluxDB query: SELECT "tag1", "value1" FROM "cpu" -(5 rows) - ---Testcase 150: -SELECT tableoid::regclass, * FROM t1 LIMIT 1 OFFSET 1; - tableoid | time | tag1 | value1 -----------+------------------------+--------+-------- - t1 | 2015-08-18 09:00:00+09 | tag1_B | 100 -(1 row) - ---Testcase 151: -EXPLAIN (VERBOSE, COSTS OFF) -SELECT ctid, * FROM t1 LIMIT 1 OFFSET 0; - QUERY PLAN ------------------------------------------------------------- - Limit - Output: ctid, "time", tag1, value1 - -> Foreign Scan on public.t1 - Output: ctid, "time", tag1, value1 - InfluxDB query: SELECT "tag1", "value1" FROM "cpu" -(5 rows) - ---Testcase 152: -SELECT ctid, * FROM t1 LIMIT 1 OFFSET 0; - ctid | time | tag1 | value1 -----------------+------------------------+--------+-------- - (4294967295,0) | 2015-08-18 09:00:00+09 | tag1_A | 100 -(1 row) - ---Testcase 153: -EXPLAIN (VERBOSE, COSTS OFF) -SELECT ctid, * FROM t2 LIMIT 10 OFFSET 20; - QUERY PLAN ------------------------------------------------------------- - Limit - Output: ctid, "time", tag1, value1 - -> Foreign Scan on public.t2 - Output: ctid, "time", tag1, value1 - InfluxDB query: SELECT "tag1", "value1" FROM "cpu" -(5 rows) - ---Testcase 154: -SELECT ctid, * FROM t2 LIMIT 10 OFFSET 20; - ctid | time | tag1 | value1 -------+------+------+-------- -(0 rows) - ---Testcase 155: -EXPLAIN (VERBOSE, COSTS OFF) -SELECT * FROM - t1 - LEFT JOIN t2 - ON t2.value1 = 123, - LATERAL (SELECT t2.value1, t1.tag1 FROM t1 LIMIT 1 OFFSET 0) AS ss -WHERE t1.value1 = ss.value1; - QUERY PLAN -------------------------------------------------------------------------------------------------- - Nested Loop - Output: t1."time", t1.tag1, t1.value1, t2."time", t2.tag1, t2.value1, (t2.value1), t1_1.tag1 - Join Filter: (t1.value1 = (t2.value1)) - -> Nested Loop Left Join - Output: t1."time", t1.tag1, t1.value1, t2."time", t2.tag1, t2.value1 - -> Foreign Scan on public.t1 - Output: t1."time", t1.tag1, t1.value1 - InfluxDB query: SELECT "tag1", "value1" FROM "cpu" - -> Materialize - Output: t2."time", t2.tag1, t2.value1 - -> Foreign Scan on public.t2 - Output: t2."time", t2.tag1, t2.value1 - InfluxDB query: SELECT "tag1", "value1" FROM "cpu" WHERE (("value1" = 123)) - -> Limit - Output: (t2.value1), t1_1.tag1 - -> Foreign Scan on public.t1 t1_1 - Output: t2.value1, t1_1.tag1 - InfluxDB query: SELECT "tag1" FROM "cpu" -(18 rows) - ---Testcase 156: -EXPLAIN (VERBOSE, COSTS OFF) -SELECT * FROM - t1 - LEFT JOIN t2 - ON t2.value1 = 123, - LATERAL (SELECT t2.value1, t1.tag1 FROM t1 LIMIT 1 OFFSET 0) AS ss1, - LATERAL (SELECT ss1.* from t3 LIMIT 1 OFFSET 20) AS ss2 -WHERE t1.value1 = ss2.value1; - QUERY PLAN ----------------------------------------------------------------------------------------------------------------------------- - Nested Loop - Output: t1."time", t1.tag1, t1.value1, t2."time", t2.tag1, t2.value1, (t2.value1), t1_1.tag1, ((t2.value1)), (t1_1.tag1) - Join Filter: (t1.value1 = ((t2.value1))) - -> Nested Loop - Output: t1."time", t1.tag1, t1.value1, t2."time", t2.tag1, t2.value1, (t2.value1), t1_1.tag1 - -> Nested Loop Left Join - Output: t1."time", t1.tag1, t1.value1, t2."time", t2.tag1, t2.value1 - -> Foreign Scan on public.t1 - Output: t1."time", t1.tag1, t1.value1 - InfluxDB query: SELECT "tag1", "value1" FROM "cpu" - -> Materialize - Output: t2."time", t2.tag1, t2.value1 - -> Foreign Scan on public.t2 - Output: t2."time", t2.tag1, t2.value1 - InfluxDB query: SELECT "tag1", "value1" FROM "cpu" WHERE (("value1" = 123)) - -> Limit - Output: (t2.value1), t1_1.tag1 - -> Foreign Scan on public.t1 t1_1 - Output: t2.value1, t1_1.tag1 - InfluxDB query: SELECT "tag1" FROM "cpu" - -> Limit - Output: ((t2.value1)), (t1_1.tag1) - -> Foreign Scan on public.t3 - Output: (t2.value1), t1_1.tag1 - InfluxDB query: SELECT * FROM "t3" -(25 rows) - ---Testcase 157: -DROP FOREIGN TABLE cpu; ---Testcase 158: -DROP FOREIGN TABLE t1; ---Testcase 159: -DROP FOREIGN TABLE t2; ---Testcase 160: -DROP FOREIGN TABLE t3; ---Testcase 161: -DROP FOREIGN TABLE t4; ---Testcase 162: -DROP FOREIGN TABLE t5; ---Testcase 163: -DROP FOREIGN TABLE tx; --- test INSERT, DELETE -IMPORT FOREIGN SCHEMA public FROM SERVER server1 INTO public OPTIONS(import_time_text 'true'); ---Testcase 164: -SELECT * FROM cpu; - time | time_text | tag1 | tag2 | value1 | value2 | value3 | value4 -------------------------+----------------------+--------+--------+--------+--------+--------+-------- - 2015-08-18 09:00:00+09 | 2015-08-18T00:00:00Z | tag1_A | tag2_A | 100 | 0.5 | str | t - 2015-08-18 09:00:00+09 | 2015-08-18T00:00:00Z | tag1_B | | 100 | 2 | | f - 2015-08-18 09:48:08+09 | 2015-08-18T00:48:08Z | | tag2_A | | 2 | | -(3 rows) - ---Testcase 165: -EXPLAIN VERBOSE -INSERT INTO cpu(time, tag1, tag2, value1, value2, value3, value4) VALUES('2021-01-01 00:00:01+09', 'tag1_K', 'tag2_H', 200, 5.5, 'test1', true); - QUERY PLAN ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ - Insert on public.cpu (cost=0.00..0.01 rows=1 width=153) - -> Result (cost=0.00..0.01 rows=1 width=153) - Output: '2021-01-01 00:00:01+09'::timestamp with time zone, NULL::text, 'tag1_K'::text, 'tag2_H'::text, '200'::bigint, '5.5'::double precision, 'test1'::text, true -(3 rows) - ---Testcase 166: -INSERT INTO cpu(time, tag1, tag2, value1, value2, value3, value4) VALUES('2021-01-01 00:00:01+09', 'tag1_K', 'tag2_H', 200, 5.5, 'test', true); ---Testcase 167: -SELECT * FROM cpu; - time | time_text | tag1 | tag2 | value1 | value2 | value3 | value4 -------------------------+----------------------+--------+--------+--------+--------+--------+-------- - 2015-08-18 09:00:00+09 | 2015-08-18T00:00:00Z | tag1_A | tag2_A | 100 | 0.5 | str | t - 2015-08-18 09:00:00+09 | 2015-08-18T00:00:00Z | tag1_B | | 100 | 2 | | f - 2015-08-18 09:48:08+09 | 2015-08-18T00:48:08Z | | tag2_A | | 2 | | - 2021-01-01 00:00:01+09 | 2020-12-31T15:00:01Z | tag1_K | tag2_H | 200 | 5.5 | test | t -(4 rows) - ---Testcase 168: -EXPLAIN VERBOSE -INSERT INTO cpu(time, tag1, tag2, value1, value2, value3, value4) VALUES('2021-01-02 00:00:02+05', 'tag1_I', 'tag2_E', 300, 15.5, 'test2', false), - ('2029-02-02 00:02:02+04', 'tag1_U', 'tag2_DZ', (SELECT 350), (SELECT i FROM (VALUES(6.9)) AS foo (i)), 'funny', true); - QUERY PLAN ------------------------------------------------------------------------------------------------------------------------------------------------------------------------- - Insert on public.cpu (cost=0.02..0.04 rows=2 width=153) - InitPlan 1 (returns $0) - -> Result (cost=0.00..0.01 rows=1 width=4) - Output: 350 - InitPlan 2 (returns $1) - -> Result (cost=0.00..0.01 rows=1 width=32) - Output: 6.9 - -> Values Scan on "*VALUES*" (cost=0.00..0.03 rows=2 width=153) - Output: "*VALUES*".column1, NULL::text, "*VALUES*".column2, "*VALUES*".column3, "*VALUES*".column4, "*VALUES*".column5, "*VALUES*".column6, "*VALUES*".column7 -(9 rows) - ---Testcase 169: -INSERT INTO cpu(time, tag1, tag2, value1, value2, value3, value4) VALUES('2021-01-02 00:00:02+05', 'tag1_I', 'tag2_E', 300, 15.5, 'test2', false), - ('2029-02-02 00:02:02+04', 'tag1_U', 'tag2_DZ', (SELECT 350), (SELECT i FROM (VALUES(6.9)) AS foo (i)), 'funny', true); ---Testcase 170: -SELECT * FROM cpu; - time | time_text | tag1 | tag2 | value1 | value2 | value3 | value4 -------------------------+----------------------+--------+---------+--------+--------+--------+-------- - 2015-08-18 09:00:00+09 | 2015-08-18T00:00:00Z | tag1_A | tag2_A | 100 | 0.5 | str | t - 2015-08-18 09:00:00+09 | 2015-08-18T00:00:00Z | tag1_B | | 100 | 2 | | f - 2015-08-18 09:48:08+09 | 2015-08-18T00:48:08Z | | tag2_A | | 2 | | - 2021-01-01 00:00:01+09 | 2020-12-31T15:00:01Z | tag1_K | tag2_H | 200 | 5.5 | test | t - 2021-01-02 04:00:02+09 | 2021-01-01T19:00:02Z | tag1_I | tag2_E | 300 | 15.5 | test2 | f - 2029-02-02 05:02:02+09 | 2029-02-01T20:02:02Z | tag1_U | tag2_DZ | 350 | 6.9 | funny | t -(6 rows) - ---Testcase 171: -INSERT INTO cpu(tag2, value1) VALUES('tag2_KH', 400); ---Testcase 172: -SELECT tag1, tag2, value1, value2, value3, value4 FROM cpu; - tag1 | tag2 | value1 | value2 | value3 | value4 ---------+---------+--------+--------+--------+-------- - tag1_A | tag2_A | 100 | 0.5 | str | t - tag1_B | | 100 | 2 | | f - | tag2_A | | 2 | | - tag1_K | tag2_H | 200 | 5.5 | test | t - tag1_I | tag2_E | 300 | 15.5 | test2 | f - | tag2_KH | 400 | | | - tag1_U | tag2_DZ | 350 | 6.9 | funny | t -(7 rows) - ---Testcase 173: -EXPLAIN VERBOSE -DELETE FROM cpu WHERE tag2 = 'tag2_KH'; - QUERY PLAN -------------------------------------------------------------------------- - Delete on public.cpu (cost=10.00..3.00 rows=3 width=104) - -> Foreign Delete on public.cpu (cost=10.00..3.00 rows=3 width=104) - InfluxDB query: DELETE FROM "cpu" WHERE (("tag2" = 'tag2_KH')) -(3 rows) - ---Testcase 174: -DELETE FROM cpu WHERE tag2 = 'tag2_KH'; ---Testcase 175: -SELECT tag1, tag2, value1, value2, value3, value4 FROM cpu; - tag1 | tag2 | value1 | value2 | value3 | value4 ---------+---------+--------+--------+--------+-------- - tag1_A | tag2_A | 100 | 0.5 | str | t - tag1_B | | 100 | 2 | | f - | tag2_A | | 2 | | - tag1_K | tag2_H | 200 | 5.5 | test | t - tag1_I | tag2_E | 300 | 15.5 | test2 | f - tag1_U | tag2_DZ | 350 | 6.9 | funny | t -(6 rows) - ---Testcase 176: -EXPLAIN VERBOSE -DELETE FROM cpu WHERE time = '2021-01-02 04:00:02+09'; - QUERY PLAN ----------------------------------------------------------------------------------- - Delete on public.cpu (cost=10.00..3.00 rows=3 width=104) - -> Foreign Delete on public.cpu (cost=10.00..3.00 rows=3 width=104) - InfluxDB query: DELETE FROM "cpu" WHERE ((time = '2021-01-01 19:00:02')) -(3 rows) - ---Testcase 177: -DELETE FROM cpu WHERE time = '2021-01-02 04:00:02+09'; ---Testcase 178: -SELECT * FROM cpu; - time | time_text | tag1 | tag2 | value1 | value2 | value3 | value4 -------------------------+----------------------+--------+---------+--------+--------+--------+-------- - 2015-08-18 09:00:00+09 | 2015-08-18T00:00:00Z | tag1_A | tag2_A | 100 | 0.5 | str | t - 2015-08-18 09:00:00+09 | 2015-08-18T00:00:00Z | tag1_B | | 100 | 2 | | f - 2015-08-18 09:48:08+09 | 2015-08-18T00:48:08Z | | tag2_A | | 2 | | - 2021-01-01 00:00:01+09 | 2020-12-31T15:00:01Z | tag1_K | tag2_H | 200 | 5.5 | test | t - 2029-02-02 05:02:02+09 | 2029-02-01T20:02:02Z | tag1_U | tag2_DZ | 350 | 6.9 | funny | t -(5 rows) - ---Testcase 179: -EXPLAIN VERBOSE -DELETE FROM cpu WHERE time < '2018-07-07' AND tag1 != 'tag1_B'; - QUERY PLAN -------------------------------------------------------------------------------------------------------------- - Delete on public.cpu (cost=10.00..212.00 rows=212 width=104) - -> Foreign Delete on public.cpu (cost=10.00..212.00 rows=212 width=104) - InfluxDB query: DELETE FROM "cpu" WHERE ((time < '2018-07-06 15:00:00')) AND (("tag1" <> 'tag1_B')) -(3 rows) - ---Testcase 180: -DELETE FROM cpu WHERE time < '2018-07-07' AND tag1 != 'tag1_B'; ---Testcase 181: -SELECT * FROM cpu; - time | time_text | tag1 | tag2 | value1 | value2 | value3 | value4 -------------------------+----------------------+--------+---------+--------+--------+--------+-------- - 2015-08-18 09:00:00+09 | 2015-08-18T00:00:00Z | tag1_B | | 100 | 2 | | f - 2021-01-01 00:00:01+09 | 2020-12-31T15:00:01Z | tag1_K | tag2_H | 200 | 5.5 | test | t - 2029-02-02 05:02:02+09 | 2029-02-01T20:02:02Z | tag1_U | tag2_DZ | 350 | 6.9 | funny | t -(3 rows) - --- Test INSERT, DELETE with time_text column ---Testcase 182: -INSERT INTO cpu(time_text, tag1, tag2, value1, value2, value3, value4) VALUES('2021-02-02T00:00:00Z', 'tag1_D', 'tag2_E', 600, 20.2, 'test3', true); ---Testcase 183: -SELECT * FROM cpu; - time | time_text | tag1 | tag2 | value1 | value2 | value3 | value4 -------------------------+----------------------+--------+---------+--------+--------+--------+-------- - 2015-08-18 09:00:00+09 | 2015-08-18T00:00:00Z | tag1_B | | 100 | 2 | | f - 2021-01-01 00:00:01+09 | 2020-12-31T15:00:01Z | tag1_K | tag2_H | 200 | 5.5 | test | t - 2021-02-02 09:00:00+09 | 2021-02-02T00:00:00Z | tag1_D | tag2_E | 600 | 20.2 | test3 | t - 2029-02-02 05:02:02+09 | 2029-02-01T20:02:02Z | tag1_U | tag2_DZ | 350 | 6.9 | funny | t -(4 rows) - ---Testcase 184: -INSERT INTO cpu(time_text, tag1, value2) VALUES('2021-02-02T00:00:00.123456789Z', 'tag1_P', 25.8); ---Testcase 185: -SELECT * FROM cpu; - time | time_text | tag1 | tag2 | value1 | value2 | value3 | value4 --------------------------------+--------------------------------+--------+---------+--------+--------+--------+-------- - 2015-08-18 09:00:00+09 | 2015-08-18T00:00:00Z | tag1_B | | 100 | 2 | | f - 2021-01-01 00:00:01+09 | 2020-12-31T15:00:01Z | tag1_K | tag2_H | 200 | 5.5 | test | t - 2021-02-02 09:00:00+09 | 2021-02-02T00:00:00Z | tag1_D | tag2_E | 600 | 20.2 | test3 | t - 2021-02-02 09:00:00.123457+09 | 2021-02-02T00:00:00.123456789Z | tag1_P | | | 25.8 | | - 2029-02-02 05:02:02+09 | 2029-02-01T20:02:02Z | tag1_U | tag2_DZ | 350 | 6.9 | funny | t -(5 rows) - ---Testcase 186: -INSERT INTO cpu(time_text, tag1, value2) VALUES('2021-02-02 00:00:01', 'tag1_J', 37.1); ---Testcase 187: -SELECT * FROM cpu; - time | time_text | tag1 | tag2 | value1 | value2 | value3 | value4 --------------------------------+--------------------------------+--------+---------+--------+--------+--------+-------- - 2015-08-18 09:00:00+09 | 2015-08-18T00:00:00Z | tag1_B | | 100 | 2 | | f - 2021-01-01 00:00:01+09 | 2020-12-31T15:00:01Z | tag1_K | tag2_H | 200 | 5.5 | test | t - 2021-02-02 09:00:00+09 | 2021-02-02T00:00:00Z | tag1_D | tag2_E | 600 | 20.2 | test3 | t - 2021-02-02 09:00:00.123457+09 | 2021-02-02T00:00:00.123456789Z | tag1_P | | | 25.8 | | - 2021-02-02 09:00:01+09 | 2021-02-02T00:00:01Z | tag1_J | | | 37.1 | | - 2029-02-02 05:02:02+09 | 2029-02-01T20:02:02Z | tag1_U | tag2_DZ | 350 | 6.9 | funny | t -(6 rows) - ---Testcase 188: -INSERT INTO cpu(time, time_text, tag1, tag2, value1, value2, value3, value4) VALUES('2021-02-02 00:00:01+05', '2021-02-02T00:00:02.123456789Z', 'tag1_A', 'tag2_B', 200, 5.5, 'test', true); -WARNING: Inserting value has both 'time_text' and 'time' columns specified. The 'time' will be ignored. ---Testcase 189: -SELECT * FROM cpu; - time | time_text | tag1 | tag2 | value1 | value2 | value3 | value4 --------------------------------+--------------------------------+--------+---------+--------+--------+--------+-------- - 2015-08-18 09:00:00+09 | 2015-08-18T00:00:00Z | tag1_B | | 100 | 2 | | f - 2021-01-01 00:00:01+09 | 2020-12-31T15:00:01Z | tag1_K | tag2_H | 200 | 5.5 | test | t - 2021-02-02 09:00:00+09 | 2021-02-02T00:00:00Z | tag1_D | tag2_E | 600 | 20.2 | test3 | t - 2021-02-02 09:00:00.123457+09 | 2021-02-02T00:00:00.123456789Z | tag1_P | | | 25.8 | | - 2021-02-02 09:00:01+09 | 2021-02-02T00:00:01Z | tag1_J | | | 37.1 | | - 2021-02-02 09:00:02.123457+09 | 2021-02-02T00:00:02.123456789Z | tag1_A | tag2_B | 200 | 5.5 | test | t - 2029-02-02 05:02:02+09 | 2029-02-01T20:02:02Z | tag1_U | tag2_DZ | 350 | 6.9 | funny | t -(7 rows) - ---Testcase 190: -INSERT INTO cpu(time_text, time, tag1, tag2, value1, value2, value3, value4) VALUES('2021-02-03T00:00:03.123456789Z', '2021-03-03 00:00:01+07', 'tag1_C', 'tag2_D', 200, 5.5, 'test', true); -WARNING: Inserting value has both 'time_text' and 'time' columns specified. The 'time' will be ignored. ---Testcase 191: -SELECT * FROM cpu; - time | time_text | tag1 | tag2 | value1 | value2 | value3 | value4 --------------------------------+--------------------------------+--------+---------+--------+--------+--------+-------- - 2015-08-18 09:00:00+09 | 2015-08-18T00:00:00Z | tag1_B | | 100 | 2 | | f - 2021-01-01 00:00:01+09 | 2020-12-31T15:00:01Z | tag1_K | tag2_H | 200 | 5.5 | test | t - 2021-02-02 09:00:00+09 | 2021-02-02T00:00:00Z | tag1_D | tag2_E | 600 | 20.2 | test3 | t - 2021-02-02 09:00:00.123457+09 | 2021-02-02T00:00:00.123456789Z | tag1_P | | | 25.8 | | - 2021-02-02 09:00:01+09 | 2021-02-02T00:00:01Z | tag1_J | | | 37.1 | | - 2021-02-02 09:00:02.123457+09 | 2021-02-02T00:00:02.123456789Z | tag1_A | tag2_B | 200 | 5.5 | test | t - 2021-02-03 09:00:03.123457+09 | 2021-02-03T00:00:03.123456789Z | tag1_C | tag2_D | 200 | 5.5 | test | t - 2029-02-02 05:02:02+09 | 2029-02-01T20:02:02Z | tag1_U | tag2_DZ | 350 | 6.9 | funny | t -(8 rows) - ---Testcase 192: -EXPLAIN VERBOSE -DELETE FROM cpu WHERE time_text = '2021-02-02T00:00:00.123456789Z'; - QUERY PLAN ---------------------------------------------------------------------------------------------- - Delete on public.cpu (cost=10.00..3.00 rows=3 width=104) - -> Foreign Delete on public.cpu (cost=10.00..3.00 rows=3 width=104) - InfluxDB query: DELETE FROM "cpu" WHERE ((time = '2021-02-02T00:00:00.123456789Z')) -(3 rows) - ---Testcase 193: -DELETE FROM cpu WHERE time_text = '2021-02-02T00:00:00.123456789Z'; ---Testcase 194: -SELECT * FROM cpu; - time | time_text | tag1 | tag2 | value1 | value2 | value3 | value4 --------------------------------+--------------------------------+--------+---------+--------+--------+--------+-------- - 2015-08-18 09:00:00+09 | 2015-08-18T00:00:00Z | tag1_B | | 100 | 2 | | f - 2021-01-01 00:00:01+09 | 2020-12-31T15:00:01Z | tag1_K | tag2_H | 200 | 5.5 | test | t - 2021-02-02 09:00:00+09 | 2021-02-02T00:00:00Z | tag1_D | tag2_E | 600 | 20.2 | test3 | t - 2021-02-02 09:00:01+09 | 2021-02-02T00:00:01Z | tag1_J | | | 37.1 | | - 2021-02-02 09:00:02.123457+09 | 2021-02-02T00:00:02.123456789Z | tag1_A | tag2_B | 200 | 5.5 | test | t - 2021-02-03 09:00:03.123457+09 | 2021-02-03T00:00:03.123456789Z | tag1_C | tag2_D | 200 | 5.5 | test | t - 2029-02-02 05:02:02+09 | 2029-02-01T20:02:02Z | tag1_U | tag2_DZ | 350 | 6.9 | funny | t -(7 rows) - ---Testcase 195: -EXPLAIN VERBOSE -DELETE FROM cpu WHERE time_text = '2021-02-02T00:00:01Z' AND tag1 = 'tag1_J'; - QUERY PLAN -------------------------------------------------------------------------------------------------------------- - Delete on public.cpu (cost=10.00..1.00 rows=1 width=104) - -> Foreign Delete on public.cpu (cost=10.00..1.00 rows=1 width=104) - InfluxDB query: DELETE FROM "cpu" WHERE ((time = '2021-02-02T00:00:01Z')) AND (("tag1" = 'tag1_J')) -(3 rows) - ---Testcase 196: -DELETE FROM cpu WHERE time_text = '2021-02-02T00:00:01Z' AND tag1 = 'tag1_J'; ---Testcase 197: -SELECT * FROM cpu; - time | time_text | tag1 | tag2 | value1 | value2 | value3 | value4 --------------------------------+--------------------------------+--------+---------+--------+--------+--------+-------- - 2015-08-18 09:00:00+09 | 2015-08-18T00:00:00Z | tag1_B | | 100 | 2 | | f - 2021-01-01 00:00:01+09 | 2020-12-31T15:00:01Z | tag1_K | tag2_H | 200 | 5.5 | test | t - 2021-02-02 09:00:00+09 | 2021-02-02T00:00:00Z | tag1_D | tag2_E | 600 | 20.2 | test3 | t - 2021-02-02 09:00:02.123457+09 | 2021-02-02T00:00:02.123456789Z | tag1_A | tag2_B | 200 | 5.5 | test | t - 2021-02-03 09:00:03.123457+09 | 2021-02-03T00:00:03.123456789Z | tag1_C | tag2_D | 200 | 5.5 | test | t - 2029-02-02 05:02:02+09 | 2029-02-01T20:02:02Z | tag1_U | tag2_DZ | 350 | 6.9 | funny | t -(6 rows) - ---Testcase 198: -EXPLAIN VERBOSE -DELETE FROM cpu WHERE time_text = '2021-02-02 00:00:00' OR time ='2029-02-02 05:02:02+09'; - QUERY PLAN --------------------------------------------------------------------------------------------------------------------------------------- - Delete on public.cpu (cost=10.00..6.00 rows=6 width=104) - -> Foreign Scan on public.cpu (cost=10.00..6.00 rows=6 width=104) - Output: "time", time_text, tag1, tag2 - Filter: ((cpu.time_text = '2021-02-02 00:00:00'::text) OR (cpu."time" = '2029-02-02 05:02:02+09'::timestamp with time zone)) - InfluxDB query: SELECT "tag1", "tag2", "value1" FROM "cpu" -(5 rows) - ---Testcase 199: -DELETE FROM cpu WHERE time_text = '2021-02-02 00:00:00' OR time ='2029-02-02 05:02:02+09'; ---Testcase 200: -SELECT * FROM cpu; - time | time_text | tag1 | tag2 | value1 | value2 | value3 | value4 --------------------------------+--------------------------------+--------+--------+--------+--------+--------+-------- - 2015-08-18 09:00:00+09 | 2015-08-18T00:00:00Z | tag1_B | | 100 | 2 | | f - 2021-01-01 00:00:01+09 | 2020-12-31T15:00:01Z | tag1_K | tag2_H | 200 | 5.5 | test | t - 2021-02-02 09:00:00+09 | 2021-02-02T00:00:00Z | tag1_D | tag2_E | 600 | 20.2 | test3 | t - 2021-02-02 09:00:02.123457+09 | 2021-02-02T00:00:02.123456789Z | tag1_A | tag2_B | 200 | 5.5 | test | t - 2021-02-03 09:00:03.123457+09 | 2021-02-03T00:00:03.123456789Z | tag1_C | tag2_D | 200 | 5.5 | test | t -(5 rows) - --- InfluxDB_FDW will store time data for Field values as a strings ---Testcase 204: -CREATE FOREIGN TABLE tmp_time ( -time timestamp, -c1 time, -c2 timestamp, -c3 timestamp with time zone -) SERVER server1 OPTIONS (table 'tmp_time'); ---Testcase 205: -SELECT * FROM tmp_time; - time | c1 | c2 | c3 -------+----+----+---- -(0 rows) - ---Testcase 206: -INSERT INTO tmp_time (time, c1) VALUES ('1900-01-01 01:01:01', '01:02:03'); ---Testcase 207: -INSERT INTO tmp_time (time, c1) VALUES ('2100-01-01 01:01:01', '04:05:06'); ---Testcase 208: -INSERT INTO tmp_time (time, c1) VALUES ('1990-01-01 01:01:01', '07:08:09'); ---Testcase 209: -INSERT INTO tmp_time (time, c2) VALUES ('2020-12-27 03:02:56.634467', '1950-02-02 02:02:02'); ---Testcase 210: -INSERT INTO tmp_time (time, c3) VALUES ('2021-12-27 03:02:56.668301', '1800-02-02 02:02:02+9'); ---Testcase 210: -INSERT INTO tmp_time (time, c1, c2, c3) VALUES ('2022-05-06 07:08:09', '07:08:09', '2022-05-06 07:08:09', '2022-05-06 07:08:09+9'); ---Testcase 211: --- 1800-02-02 02:02:02+9 is Daylight Saving Time (DST) changes in Japan. --- Timezone setting Japan so it will plus 18s:59 --- https://www.timeanddate.com/time/zone/japan/tokyo?syear=1850 -SELECT * FROM tmp_time; - time | c1 | c2 | c3 -----------------------------+----------+---------------------+------------------------------ - 1900-01-01 01:01:01 | 01:02:03 | | - 1990-01-01 01:01:01 | 07:08:09 | | - 2020-12-27 03:02:56.634467 | | 1950-02-02 02:02:02 | - 2021-12-27 03:02:56.668301 | | | 1800-02-02 02:21:01+09:18:59 - 2022-05-06 07:08:09 | 07:08:09 | 2022-05-06 07:08:09 | 2022-05-06 07:08:09+09 - 2100-01-01 01:01:01 | 04:05:06 | | -(6 rows) - --- Recover data -:RECOVER_INIT_TXT_DROP_BUCKET; -:RECOVER_INIT_TXT_CREATE_BUCKET; -:RECOVER_INIT_TXT; ---Testcase 201: -DROP USER MAPPING FOR CURRENT_USER SERVER server1; ---Testcase 202: -DROP SERVER server1 CASCADE; -NOTICE: drop cascades to 6 other objects -DETAIL: drop cascades to foreign table cpu -drop cascades to foreign table numbers -drop cascades to foreign table t3 -drop cascades to foreign table t4 -drop cascades to foreign table tx -drop cascades to foreign table tmp_time ---Testcase 203: -DROP EXTENSION influxdb_fdw CASCADE; diff --git a/expected/11.17/schemaless/extra/influxdb_fdw_post.out b/expected/11.17/schemaless/extra/influxdb_fdw_post.out deleted file mode 100644 index f3bc226..0000000 --- a/expected/11.17/schemaless/extra/influxdb_fdw_post.out +++ /dev/null @@ -1,9030 +0,0 @@ --- =================================================================== --- create FDW objects --- =================================================================== -\set ECHO none ---Testcase 1: -CREATE EXTENSION influxdb_fdw; ---Testcase 2: -CREATE SERVER testserver1 FOREIGN DATA WRAPPER influxdb_fdw; ---Testcase 3: -CREATE SERVER influxdb_svr FOREIGN DATA WRAPPER influxdb_fdw - OPTIONS (dbname 'postdb', :SERVER); ---Testcase 4: -CREATE SERVER influxdb_svr2 FOREIGN DATA WRAPPER influxdb_fdw - OPTIONS (dbname 'postdb', :SERVER); ---Testcase 5: -CREATE USER MAPPING FOR public SERVER testserver1 OPTIONS (user 'value', password 'value'); ---Testcase 6: -CREATE USER MAPPING FOR CURRENT_USER SERVER influxdb_svr OPTIONS (:AUTHENTICATION); ---Testcase 7: -CREATE USER MAPPING FOR CURRENT_USER SERVER influxdb_svr2 OPTIONS (:AUTHENTICATION); --- =================================================================== --- create objects used through FDW influxdb server --- =================================================================== ---Testcase 8: -CREATE TYPE user_enum AS ENUM ('foo', 'bar', 'buz'); ---Testcase 9: -CREATE SCHEMA "S 1"; ---Testcase 10: -CREATE FOREIGN TABLE "S 1"."T 0" (time timestamp, tags jsonb OPTIONS(tags 'true'), fields jsonb OPTIONS(fields 'true')) SERVER influxdb_svr OPTIONS (table 'T0', tags 'c3', schemaless 'true'); -CREATE FOREIGN TABLE "S 1".s1t0 ( - "C 1" int NOT NULL, - c2 int NOT NULL, - c3 text, - time timestamp, - c6 varchar(10), - c7 char(10), - c8 text -) SERVER influxdb_svr OPTIONS (table 'T0', tags 'c3'); ---Testcase 11: -CREATE FOREIGN TABLE "S 1"."T 1" (time timestamp, tags jsonb OPTIONS(tags 'true'), fields jsonb OPTIONS(fields 'true')) SERVER influxdb_svr OPTIONS (table 'T1', tags 'c3', schemaless 'true'); -CREATE FOREIGN TABLE "S 1".s1t1 ( - "C 1" int NOT NULL, - c2 int NOT NULL, - c3 text, - time timestamp, - c6 varchar(10), - c7 char(10), - c8 text -) SERVER influxdb_svr OPTIONS (table 'T1', tags 'c3'); ---Testcase 12: -CREATE FOREIGN TABLE "S 1"."T 2" (tags jsonb OPTIONS(tags 'true'), fields jsonb OPTIONS(fields 'true')) SERVER influxdb_svr OPTIONS (table 'T2', tags 'c2', schemaless 'true'); -CREATE FOREIGN TABLE "S 1".s1t2 ( - c1 int NOT NULL, - c2 text -) SERVER influxdb_svr OPTIONS (table 'T2', tags 'c2'); ---Testcase 13: -CREATE FOREIGN TABLE "S 1"."T 3" (tags jsonb OPTIONS(tags 'true'), fields jsonb OPTIONS(fields 'true')) SERVER influxdb_svr OPTIONS (table 'T3', tags 'c3', schemaless 'true'); -CREATE FOREIGN TABLE "S 1".s1t3 ( - c1 int NOT NULL, - c2 int NOT NULL, - c3 text -) SERVER influxdb_svr OPTIONS (table 'T3', tags 'c3'); ---Testcase 14: -CREATE FOREIGN TABLE "S 1"."T 4" (tags jsonb OPTIONS(tags 'true'), fields jsonb OPTIONS(fields 'true')) SERVER influxdb_svr OPTIONS (table 'T4', tags 'c3', schemaless 'true'); -CREATE FOREIGN TABLE "S 1".s1t4 ( - c1 int NOT NULL, - c2 int NOT NULL, - c3 text -) SERVER influxdb_svr OPTIONS (table 'T4', tags 'c3'); --- Disable autovacuum for these tables to avoid unexpected effects of that ---ALTER TABLE "S 1"."T 1" SET (autovacuum_enabled = 'false'); ---ALTER TABLE "S 1"."T 2" SET (autovacuum_enabled = 'false'); ---ALTER TABLE "S 1"."T 3" SET (autovacuum_enabled = 'false'); ---ALTER TABLE "S 1"."T 4" SET (autovacuum_enabled = 'false'); ---Testcase 15: -INSERT INTO "S 1".s1t1 - SELECT id, - id % 10, - to_char(id, 'FM00000'), - '1970-01-01'::timestamp + ((id % 100) || ' days')::interval, - id % 10, - id % 10, - 'foo'::text - FROM generate_series(1, 1000) id; ---Testcase 16: -INSERT INTO "S 1".s1t2 - SELECT id, - 'AAA' || to_char(id, 'FM000') - FROM generate_series(1, 100) id; ---Testcase 17: -INSERT INTO "S 1".s1t3 - SELECT id, - id + 1, - 'AAA' || to_char(id, 'FM000') - FROM generate_series(1, 100) id; ---Testcase 18: -DELETE FROM "S 1".s1t3 WHERE c1 % 2 != 0; -- delete for outer join tests ---Testcase 19: -INSERT INTO "S 1".s1t4 - SELECT id, - id + 1, - 'AAA' || to_char(id, 'FM000') - FROM generate_series(1, 100) id; ---Testcase 20: -DELETE FROM "S 1".s1t4 WHERE c1 % 3 != 0; -- delete for outer join tests ---ANALYZE "S 1"."T 1"; ---ANALYZE "S 1"."T 2"; ---ANALYZE "S 1"."T 3"; ---ANALYZE "S 1"."T 4"; --- =================================================================== --- create foreign tables --- =================================================================== ---Testcase 21: -CREATE FOREIGN TABLE ft1 (time timestamp, tags jsonb OPTIONS(tags 'true'), fields jsonb OPTIONS(fields 'true')) SERVER influxdb_svr OPTIONS (schemaless 'true'); -CREATE FOREIGN TABLE ft1_nsc ( - c0 int, - c1 int NOT NULL, - c2 int NOT NULL, - c3 text, - time timestamp, - c6 varchar(10), - c7 char(10) default 'ft1', - c8 text -) SERVER influxdb_svr; -ALTER FOREIGN TABLE ft1_nsc DROP COLUMN c0; ---Testcase 22: -CREATE FOREIGN TABLE ft2 (time timestamp, tags jsonb OPTIONS(tags 'true'), fields jsonb OPTIONS(fields 'true')) SERVER influxdb_svr OPTIONS (schemaless 'true'); -CREATE FOREIGN TABLE ft2_nsc ( - c1 int NOT NULL, - c2 int NOT NULL, - cx int, - c3 text, - time timestamp, - c6 varchar(10), - c7 char(10) default 'ft2', - c8 text -) SERVER influxdb_svr; -ALTER FOREIGN TABLE ft2_nsc DROP COLUMN cx; ---Testcase 23: -CREATE FOREIGN TABLE ft4 (tags jsonb OPTIONS(tags 'true'), fields jsonb OPTIONS(fields 'true')) SERVER influxdb_svr OPTIONS (table 'T3', tags 'c3', schemaless 'true'); -CREATE FOREIGN TABLE ft4_nsc ( - c1 int NOT NULL, - c2 int NOT NULL, - c3 text -) SERVER influxdb_svr OPTIONS (table 'T3', tags 'c3'); ---Testcase 24: -CREATE FOREIGN TABLE ft5 (tags jsonb OPTIONS(tags 'true'), fields jsonb OPTIONS(fields 'true')) SERVER influxdb_svr OPTIONS (table 'T4', tags 'c3', schemaless 'true'); -CREATE FOREIGN TABLE ft5_nsc ( - c1 int NOT NULL, - c2 int NOT NULL, - c3 text -) SERVER influxdb_svr OPTIONS (table 'T4', tags 'c3'); ---Testcase 25: -CREATE FOREIGN TABLE ft6 (tags jsonb OPTIONS(tags 'true'), fields jsonb OPTIONS(fields 'true')) SERVER influxdb_svr2 OPTIONS (table 'T4', tags 'c3', schemaless 'true'); --- =================================================================== --- tests for validator --- =================================================================== --- requiressl and some other parameters are omitted because --- valid values for them depend on configure options -ALTER SERVER testserver1 OPTIONS ( - -- use_remote_estimate 'false', - -- updatable 'true', - -- fdw_startup_cost '123.456', - -- fdw_tuple_cost '0.123', - -- service 'value', - -- connect_timeout 'value', - dbname 'value', - host 'value', - -- hostaddr 'value', - port 'value' - --client_encoding 'value', - -- application_name 'value', - --fallback_application_name 'value', - -- keepalives 'value', - -- keepalives_idle 'value', - -- keepalives_interval 'value', - -- tcp_user_timeout 'value', - -- requiressl 'value', - -- sslcompression 'value', - -- sslmode 'value', - -- sslcert 'value', - -- sslkey 'value', - -- sslrootcert 'value', - -- sslcrl 'value', - --requirepeer 'value', - -- krbsrvname 'value', - -- gsslib 'value', - --replication 'value' -); --- influxdb_fdw does not support option extensions --- Error, invalid list syntax ---ALTER SERVER testserver1 OPTIONS (ADD extensions 'foo; bar'); --- OK but gets a warning ---ALTER SERVER testserver1 OPTIONS (ADD extensions 'foo, bar'); ---ALTER SERVER testserver1 OPTIONS (DROP extensions); -ALTER USER MAPPING FOR public SERVER testserver1 - OPTIONS (DROP user, DROP password); --- Attempt to add a valid option that's not allowed in a user mapping ---ALTER USER MAPPING FOR public SERVER testserver1 --- OPTIONS (ADD sslmode 'require'); --- But we can add valid ones fine ---ALTER USER MAPPING FOR public SERVER testserver1 --- OPTIONS (ADD sslpassword 'dummy'); --- Ensure valid options we haven't used in a user mapping yet are --- permitted to check validation. ---ALTER USER MAPPING FOR public SERVER testserver1 --- OPTIONS (ADD sslkey 'value', ADD sslcert 'value'); -ALTER FOREIGN TABLE ft1 OPTIONS (table 'T1', tags 'c3'); -ALTER FOREIGN TABLE ft1_nsc OPTIONS (table 'T1', tags 'c3'); -ALTER FOREIGN TABLE ft2 OPTIONS (table 'T1', tags 'c3'); -ALTER FOREIGN TABLE ft2_nsc OPTIONS (table 'T1', tags 'c3'); -ALTER FOREIGN TABLE ft1_nsc ALTER COLUMN c1 OPTIONS (column_name 'C 1'); -ALTER FOREIGN TABLE ft2_nsc ALTER COLUMN c1 OPTIONS (column_name 'C 1'); ---Testcase 26: -\det+ - List of foreign tables - Schema | Table | Server | FDW options | Description ---------+---------+---------------+----------------------------------------------+------------- - public | ft1 | influxdb_svr | (schemaless 'true', "table" 'T1', tags 'c3') | - public | ft1_nsc | influxdb_svr | ("table" 'T1', tags 'c3') | - public | ft2 | influxdb_svr | (schemaless 'true', "table" 'T1', tags 'c3') | - public | ft2_nsc | influxdb_svr | ("table" 'T1', tags 'c3') | - public | ft4 | influxdb_svr | ("table" 'T3', tags 'c3', schemaless 'true') | - public | ft4_nsc | influxdb_svr | ("table" 'T3', tags 'c3') | - public | ft5 | influxdb_svr | ("table" 'T4', tags 'c3', schemaless 'true') | - public | ft5_nsc | influxdb_svr | ("table" 'T4', tags 'c3') | - public | ft6 | influxdb_svr2 | ("table" 'T4', tags 'c3', schemaless 'true') | -(9 rows) - --- Test that alteration of server options causes reconnection --- Remote's errors might be non-English, so hide them to ensure stable results -\set VERBOSITY terse ---Testcase 27: -SELECT tags->>'c3' c3, time FROM ft1 ORDER BY tags->>'c3', (fields->>'C 1')::int LIMIT 1; -- should work - c3 | time --------+-------------------------- - 00001 | Fri Jan 02 00:00:00 1970 -(1 row) - -ALTER SERVER influxdb_svr OPTIONS (SET dbname 'no such database'); ---Testcase 28: -SELECT tags->>'c3' c3, time FROM ft1 ORDER BY tags->>'c3', (fields->>'C 1')::int LIMIT 1; -- should fail -ERROR: influxdb_fdw : database not found: no such database -DO $d$ - BEGIN - EXECUTE $$ALTER SERVER influxdb_svr - OPTIONS (SET dbname 'postdb')$$; - END; -$d$; ---Testcase 29: -SELECT tags->>'c3' c3, time FROM ft1 ORDER BY tags->>'c3', (fields->>'C 1')::int LIMIT 1; -- should work again - c3 | time --------+-------------------------- - 00001 | Fri Jan 02 00:00:00 1970 -(1 row) - -\set VERBOSITY default --- =================================================================== --- simple queries --- =================================================================== --- single table without alias ---Testcase 30: -EXPLAIN (COSTS OFF) SELECT * FROM ft1 ORDER BY tags->>'c3', (fields->>'C 1')::int OFFSET 100 LIMIT 10; - QUERY PLAN ----------------------------------------------------------------------------------- - Limit - -> Sort - Sort Key: ((tags ->> 'c3'::text)), (((fields ->> 'C 1'::text))::integer) - -> Foreign Scan on ft1 -(4 rows) - ---Testcase 31: -SELECT * FROM ft1 ORDER BY tags->>'c3', (fields->>'C 1')::int OFFSET 100 LIMIT 10; - time | tags | fields ---------------------------+-----------------+----------------------------------------------------------------------- - Fri Jan 02 00:00:00 1970 | {"c3": "00101"} | {"c2": "1", "c6": "1", "c7": "1 ", "c8": "foo", "C 1": "101"} - Sat Jan 03 00:00:00 1970 | {"c3": "00102"} | {"c2": "2", "c6": "2", "c7": "2 ", "c8": "foo", "C 1": "102"} - Sun Jan 04 00:00:00 1970 | {"c3": "00103"} | {"c2": "3", "c6": "3", "c7": "3 ", "c8": "foo", "C 1": "103"} - Mon Jan 05 00:00:00 1970 | {"c3": "00104"} | {"c2": "4", "c6": "4", "c7": "4 ", "c8": "foo", "C 1": "104"} - Tue Jan 06 00:00:00 1970 | {"c3": "00105"} | {"c2": "5", "c6": "5", "c7": "5 ", "c8": "foo", "C 1": "105"} - Wed Jan 07 00:00:00 1970 | {"c3": "00106"} | {"c2": "6", "c6": "6", "c7": "6 ", "c8": "foo", "C 1": "106"} - Thu Jan 08 00:00:00 1970 | {"c3": "00107"} | {"c2": "7", "c6": "7", "c7": "7 ", "c8": "foo", "C 1": "107"} - Fri Jan 09 00:00:00 1970 | {"c3": "00108"} | {"c2": "8", "c6": "8", "c7": "8 ", "c8": "foo", "C 1": "108"} - Sat Jan 10 00:00:00 1970 | {"c3": "00109"} | {"c2": "9", "c6": "9", "c7": "9 ", "c8": "foo", "C 1": "109"} - Sun Jan 11 00:00:00 1970 | {"c3": "00110"} | {"c2": "0", "c6": "0", "c7": "0 ", "c8": "foo", "C 1": "110"} -(10 rows) - --- single table with alias - also test that tableoid sort is not pushed to remote side ---Testcase 32: -EXPLAIN (VERBOSE, COSTS OFF) SELECT * FROM ft1 t1 ORDER BY t1.tags->>'c3', (t1.fields->>'C 1')::int, t1.tableoid OFFSET 100 LIMIT 10; - QUERY PLAN ------------------------------------------------------------------------------------------------------------------- - Limit - Output: "time", tags, fields, ((tags ->> 'c3'::text)), (((fields ->> 'C 1'::text))::integer), tableoid - -> Sort - Output: "time", tags, fields, ((tags ->> 'c3'::text)), (((fields ->> 'C 1'::text))::integer), tableoid - Sort Key: ((t1.tags ->> 'c3'::text)), (((t1.fields ->> 'C 1'::text))::integer), t1.tableoid - -> Foreign Scan on public.ft1 t1 - Output: "time", tags, fields, (tags ->> 'c3'::text), ((fields ->> 'C 1'::text))::integer, tableoid - InfluxDB query: SELECT * FROM "T1" -(8 rows) - ---Testcase 33: -SELECT * FROM ft1 t1 ORDER BY t1.tags->>'c3', (t1.fields->>'C 1')::int, t1.tableoid OFFSET 100 LIMIT 10; - time | tags | fields ---------------------------+-----------------+----------------------------------------------------------------------- - Fri Jan 02 00:00:00 1970 | {"c3": "00101"} | {"c2": "1", "c6": "1", "c7": "1 ", "c8": "foo", "C 1": "101"} - Sat Jan 03 00:00:00 1970 | {"c3": "00102"} | {"c2": "2", "c6": "2", "c7": "2 ", "c8": "foo", "C 1": "102"} - Sun Jan 04 00:00:00 1970 | {"c3": "00103"} | {"c2": "3", "c6": "3", "c7": "3 ", "c8": "foo", "C 1": "103"} - Mon Jan 05 00:00:00 1970 | {"c3": "00104"} | {"c2": "4", "c6": "4", "c7": "4 ", "c8": "foo", "C 1": "104"} - Tue Jan 06 00:00:00 1970 | {"c3": "00105"} | {"c2": "5", "c6": "5", "c7": "5 ", "c8": "foo", "C 1": "105"} - Wed Jan 07 00:00:00 1970 | {"c3": "00106"} | {"c2": "6", "c6": "6", "c7": "6 ", "c8": "foo", "C 1": "106"} - Thu Jan 08 00:00:00 1970 | {"c3": "00107"} | {"c2": "7", "c6": "7", "c7": "7 ", "c8": "foo", "C 1": "107"} - Fri Jan 09 00:00:00 1970 | {"c3": "00108"} | {"c2": "8", "c6": "8", "c7": "8 ", "c8": "foo", "C 1": "108"} - Sat Jan 10 00:00:00 1970 | {"c3": "00109"} | {"c2": "9", "c6": "9", "c7": "9 ", "c8": "foo", "C 1": "109"} - Sun Jan 11 00:00:00 1970 | {"c3": "00110"} | {"c2": "0", "c6": "0", "c7": "0 ", "c8": "foo", "C 1": "110"} -(10 rows) - --- whole-row reference ---Testcase 34: -EXPLAIN (VERBOSE, COSTS OFF) SELECT t1 FROM ft1 t1 ORDER BY t1.tags->>'c3', (t1.fields->>'C 1')::int OFFSET 100 LIMIT 10; - QUERY PLAN ----------------------------------------------------------------------------------------- - Limit - Output: t1.*, ((tags ->> 'c3'::text)), (((fields ->> 'C 1'::text))::integer) - -> Sort - Output: t1.*, ((tags ->> 'c3'::text)), (((fields ->> 'C 1'::text))::integer) - Sort Key: ((t1.tags ->> 'c3'::text)), (((t1.fields ->> 'C 1'::text))::integer) - -> Foreign Scan on public.ft1 t1 - Output: t1.*, (tags ->> 'c3'::text), ((fields ->> 'C 1'::text))::integer - InfluxDB query: SELECT * FROM "T1" -(8 rows) - ---Testcase 35: -SELECT t1 FROM ft1 t1 ORDER BY t1.tags->>'c3', (t1.fields->>'C 1')::int OFFSET 100 LIMIT 10; - t1 ------------------------------------------------------------------------------------------------------------------------------------------------- - ("Fri Jan 02 00:00:00 1970","{""c3"": ""00101""}","{""c2"": ""1"", ""c6"": ""1"", ""c7"": ""1 "", ""c8"": ""foo"", ""C 1"": ""101""}") - ("Sat Jan 03 00:00:00 1970","{""c3"": ""00102""}","{""c2"": ""2"", ""c6"": ""2"", ""c7"": ""2 "", ""c8"": ""foo"", ""C 1"": ""102""}") - ("Sun Jan 04 00:00:00 1970","{""c3"": ""00103""}","{""c2"": ""3"", ""c6"": ""3"", ""c7"": ""3 "", ""c8"": ""foo"", ""C 1"": ""103""}") - ("Mon Jan 05 00:00:00 1970","{""c3"": ""00104""}","{""c2"": ""4"", ""c6"": ""4"", ""c7"": ""4 "", ""c8"": ""foo"", ""C 1"": ""104""}") - ("Tue Jan 06 00:00:00 1970","{""c3"": ""00105""}","{""c2"": ""5"", ""c6"": ""5"", ""c7"": ""5 "", ""c8"": ""foo"", ""C 1"": ""105""}") - ("Wed Jan 07 00:00:00 1970","{""c3"": ""00106""}","{""c2"": ""6"", ""c6"": ""6"", ""c7"": ""6 "", ""c8"": ""foo"", ""C 1"": ""106""}") - ("Thu Jan 08 00:00:00 1970","{""c3"": ""00107""}","{""c2"": ""7"", ""c6"": ""7"", ""c7"": ""7 "", ""c8"": ""foo"", ""C 1"": ""107""}") - ("Fri Jan 09 00:00:00 1970","{""c3"": ""00108""}","{""c2"": ""8"", ""c6"": ""8"", ""c7"": ""8 "", ""c8"": ""foo"", ""C 1"": ""108""}") - ("Sat Jan 10 00:00:00 1970","{""c3"": ""00109""}","{""c2"": ""9"", ""c6"": ""9"", ""c7"": ""9 "", ""c8"": ""foo"", ""C 1"": ""109""}") - ("Sun Jan 11 00:00:00 1970","{""c3"": ""00110""}","{""c2"": ""0"", ""c6"": ""0"", ""c7"": ""0 "", ""c8"": ""foo"", ""C 1"": ""110""}") -(10 rows) - --- empty result ---Testcase 36: -SELECT * FROM ft1 WHERE false; - time | tags | fields -------+------+-------- -(0 rows) - --- with WHERE clause ---Testcase 37: -EXPLAIN (VERBOSE, COSTS OFF) SELECT * FROM ft1 t1 WHERE (t1.fields->>'C 1')::int = 101 AND t1.fields->>'c6' = '1' AND t1.fields->>'c7' >= '1'; - QUERY PLAN -------------------------------------------------------------------------------- - Foreign Scan on public.ft1 t1 - Output: "time", tags, fields - Filter: ((t1.fields ->> 'c7'::text) >= '1'::text) - InfluxDB query: SELECT * FROM "T1" WHERE (("c6" = '1')) AND (("C 1" = 101)) -(4 rows) - ---Testcase 38: -SELECT * FROM ft1 t1 WHERE (t1.fields->>'C 1')::int = 101 AND t1.fields->>'c6' = '1' AND t1.fields->>'c7' >= '1'; - time | tags | fields ---------------------------+-----------------+----------------------------------------------------------------------- - Fri Jan 02 00:00:00 1970 | {"c3": "00101"} | {"c2": "1", "c6": "1", "c7": "1 ", "c8": "foo", "C 1": "101"} -(1 row) - --- with FOR UPDATE/SHARE ---Testcase 39: -EXPLAIN (VERBOSE, COSTS OFF) SELECT * FROM ft1 t1 WHERE (fields->>'C 1')::int = 101 FOR UPDATE; - QUERY PLAN ------------------------------------------------------------------- - LockRows - Output: "time", tags, fields, t1.* - -> Foreign Scan on public.ft1 t1 - Output: "time", tags, fields, t1.* - InfluxDB query: SELECT * FROM "T1" WHERE (("C 1" = 101)) -(5 rows) - ---Testcase 40: -SELECT * FROM ft1 t1 WHERE (fields->>'C 1')::int = 101 FOR UPDATE; - time | tags | fields ---------------------------+-----------------+----------------------------------------------------------------------- - Fri Jan 02 00:00:00 1970 | {"c3": "00101"} | {"c2": "1", "c6": "1", "c7": "1 ", "c8": "foo", "C 1": "101"} -(1 row) - ---Testcase 41: -EXPLAIN (VERBOSE, COSTS OFF) SELECT * FROM ft1 t1 WHERE (fields->>'C 1')::int = 102 FOR SHARE; - QUERY PLAN ------------------------------------------------------------------- - LockRows - Output: "time", tags, fields, t1.* - -> Foreign Scan on public.ft1 t1 - Output: "time", tags, fields, t1.* - InfluxDB query: SELECT * FROM "T1" WHERE (("C 1" = 102)) -(5 rows) - ---Testcase 42: -SELECT * FROM ft1 t1 WHERE (fields->>'C 1')::int = 102 FOR SHARE; - time | tags | fields ---------------------------+-----------------+----------------------------------------------------------------------- - Sat Jan 03 00:00:00 1970 | {"c3": "00102"} | {"c2": "2", "c6": "2", "c7": "2 ", "c8": "foo", "C 1": "102"} -(1 row) - --- aggregate ---Testcase 43: -SELECT COUNT(*) FROM ft1 t1; - count -------- - 1000 -(1 row) - --- subquery ---Testcase 44: -SELECT * FROM ft1 t1 WHERE t1.tags->>'c3' IN (SELECT tags->>'c3' FROM ft2 t2 WHERE (fields->>'C 1')::int <= 10) ORDER BY (fields->>'C 1')::int; - time | tags | fields ---------------------------+-----------------+---------------------------------------------------------------------- - Fri Jan 02 00:00:00 1970 | {"c3": "00001"} | {"c2": "1", "c6": "1", "c7": "1 ", "c8": "foo", "C 1": "1"} - Sat Jan 03 00:00:00 1970 | {"c3": "00002"} | {"c2": "2", "c6": "2", "c7": "2 ", "c8": "foo", "C 1": "2"} - Sun Jan 04 00:00:00 1970 | {"c3": "00003"} | {"c2": "3", "c6": "3", "c7": "3 ", "c8": "foo", "C 1": "3"} - Mon Jan 05 00:00:00 1970 | {"c3": "00004"} | {"c2": "4", "c6": "4", "c7": "4 ", "c8": "foo", "C 1": "4"} - Tue Jan 06 00:00:00 1970 | {"c3": "00005"} | {"c2": "5", "c6": "5", "c7": "5 ", "c8": "foo", "C 1": "5"} - Wed Jan 07 00:00:00 1970 | {"c3": "00006"} | {"c2": "6", "c6": "6", "c7": "6 ", "c8": "foo", "C 1": "6"} - Thu Jan 08 00:00:00 1970 | {"c3": "00007"} | {"c2": "7", "c6": "7", "c7": "7 ", "c8": "foo", "C 1": "7"} - Fri Jan 09 00:00:00 1970 | {"c3": "00008"} | {"c2": "8", "c6": "8", "c7": "8 ", "c8": "foo", "C 1": "8"} - Sat Jan 10 00:00:00 1970 | {"c3": "00009"} | {"c2": "9", "c6": "9", "c7": "9 ", "c8": "foo", "C 1": "9"} - Sun Jan 11 00:00:00 1970 | {"c3": "00010"} | {"c2": "0", "c6": "0", "c7": "0 ", "c8": "foo", "C 1": "10"} -(10 rows) - --- subquery+MAX ---Testcase 45: -SELECT * FROM ft1 t1 WHERE t1.tags->>'c3' = (SELECT MAX(tags->>'c3') FROM ft2 t2) ORDER BY (fields->>'C 1')::int; - time | tags | fields ---------------------------+-----------------+------------------------------------------------------------------------ - Thu Jan 01 00:00:00 1970 | {"c3": "01000"} | {"c2": "0", "c6": "0", "c7": "0 ", "c8": "foo", "C 1": "1000"} -(1 row) - --- used in CTE ---Testcase 46: -WITH t1 AS (SELECT * FROM ft1 WHERE (fields->>'C 1')::int <= 10) SELECT (t2.fields->>'C 1')::int c1, (t2.fields->>'c2')::int c2, t2.tags->>'c3' c3, t2.time FROM t1, ft2 t2 WHERE (t1.fields->>'C 1')::int = (t2.fields->>'C 1')::int ORDER BY (t1.fields->>'C 1')::int; - c1 | c2 | c3 | time -----+----+-------+-------------------------- - 1 | 1 | 00001 | Fri Jan 02 00:00:00 1970 - 2 | 2 | 00002 | Sat Jan 03 00:00:00 1970 - 3 | 3 | 00003 | Sun Jan 04 00:00:00 1970 - 4 | 4 | 00004 | Mon Jan 05 00:00:00 1970 - 5 | 5 | 00005 | Tue Jan 06 00:00:00 1970 - 6 | 6 | 00006 | Wed Jan 07 00:00:00 1970 - 7 | 7 | 00007 | Thu Jan 08 00:00:00 1970 - 8 | 8 | 00008 | Fri Jan 09 00:00:00 1970 - 9 | 9 | 00009 | Sat Jan 10 00:00:00 1970 - 10 | 0 | 00010 | Sun Jan 11 00:00:00 1970 -(10 rows) - --- fixed values ---Testcase 47: -SELECT 'fixed', NULL FROM ft1 t1 WHERE (fields->>'C 1')::int = 1; - ?column? | ?column? -----------+---------- - fixed | -(1 row) - --- Test forcing the remote server to produce sorted data for a merge join. -SET enable_hashjoin TO false; -SET enable_nestloop TO false; --- inner join; expressions in the clauses appear in the equivalence class list ---Testcase 48: -EXPLAIN (VERBOSE, COSTS OFF) - SELECT t1.c1, t2."C 1" FROM (SELECT (fields->>'C 1')::int c1, (fields->>'c2')::int c2, tags->>'c3' c3, fields->>'c4' c4, fields->>'c5' c5, fields->>'c6' c6, fields->>'c7' c7, fields->>'c8' c8 FROM ft2 t1) t1 JOIN (SELECT (fields->>'C 1')::int "C 1", (fields->>'c2')::int c2, tags->>'c3' c3, fields->>'c4' c4, fields->>'c5' c5, fields->>'c6' c6, fields->>'c7' c7, fields->>'c8' c8 FROM "S 1"."T 1" t2) t2 ON ((t1.c1)::int = (t2."C 1")::int) OFFSET 100 LIMIT 10; - QUERY PLAN ------------------------------------------------------------------------------------------------------------ - Limit - Output: (((t1.fields ->> 'C 1'::text))::integer), (((t2.fields ->> 'C 1'::text))::integer) - -> Merge Join - Output: (((t1.fields ->> 'C 1'::text))::integer), (((t2.fields ->> 'C 1'::text))::integer) - Merge Cond: ((((t1.fields ->> 'C 1'::text))::integer) = (((t2.fields ->> 'C 1'::text))::integer)) - -> Sort - Output: t1.fields, (((t1.fields ->> 'C 1'::text))::integer) - Sort Key: (((t1.fields ->> 'C 1'::text))::integer) - -> Foreign Scan on public.ft2 t1 - Output: t1.fields, ((t1.fields ->> 'C 1'::text))::integer - InfluxDB query: SELECT * FROM "T1" - -> Sort - Output: t2.fields, (((t2.fields ->> 'C 1'::text))::integer) - Sort Key: (((t2.fields ->> 'C 1'::text))::integer) - -> Foreign Scan on "S 1"."T 1" t2 - Output: t2.fields, ((t2.fields ->> 'C 1'::text))::integer - InfluxDB query: SELECT * FROM "T1" -(17 rows) - ---Testcase 49: -SELECT t1.c1, t2."C 1" FROM (SELECT (fields->>'C 1')::int c1, (fields->>'c2')::int c2, tags->>'c3' c3, fields->>'c4' c4, fields->>'c5' c5, fields->>'c6' c6, fields->>'c7' c7, fields->>'c8' c8 FROM ft2 t1) t1 JOIN (SELECT (fields->>'C 1')::int "C 1", (fields->>'c2')::int c2, tags->>'c3' c3, fields->>'c4' c4, fields->>'c5' c5, fields->>'c6' c6, fields->>'c7' c7, fields->>'c8' c8 FROM "S 1"."T 1" t2) t2 ON ((t1.c1)::int = (t2."C 1")::int) OFFSET 100 LIMIT 10; - c1 | C 1 ------+----- - 101 | 101 - 102 | 102 - 103 | 103 - 104 | 104 - 105 | 105 - 106 | 106 - 107 | 107 - 108 | 108 - 109 | 109 - 110 | 110 -(10 rows) - --- outer join; expressions in the clauses do not appear in equivalence class --- list but no output change as compared to the previous query ---Testcase 50: -EXPLAIN (VERBOSE, COSTS OFF) - SELECT t1.c1, t2."C 1" FROM (SELECT (fields->>'C 1')::int c1, (fields->>'c2')::int c2, tags->>'c3' c3, fields->>'c4' c4, fields->>'c5' c5, fields->>'c6' c6, fields->>'c7' c7, fields->>'c8' c8 FROM ft2 t1) t1 LEFT JOIN (SELECT (fields->>'C 1')::int "C 1", (fields->>'c2')::int c2, tags->>'c3' c3, fields->>'c4' c4, fields->>'c5' c5, fields->>'c6' c6, fields->>'c7' c7, fields->>'c8' c8 FROM "S 1"."T 1" t2) t2 ON ((t1.c1)::int = (t2."C 1")::int) OFFSET 100 LIMIT 10; - QUERY PLAN ------------------------------------------------------------------------------------------------------------ - Limit - Output: (((t1.fields ->> 'C 1'::text))::integer), (((t2.fields ->> 'C 1'::text))::integer) - -> Merge Left Join - Output: (((t1.fields ->> 'C 1'::text))::integer), ((t2.fields ->> 'C 1'::text))::integer - Merge Cond: ((((t1.fields ->> 'C 1'::text))::integer) = (((t2.fields ->> 'C 1'::text))::integer)) - -> Sort - Output: t1.fields, (((t1.fields ->> 'C 1'::text))::integer) - Sort Key: (((t1.fields ->> 'C 1'::text))::integer) - -> Foreign Scan on public.ft2 t1 - Output: t1.fields, ((t1.fields ->> 'C 1'::text))::integer - InfluxDB query: SELECT * FROM "T1" - -> Sort - Output: t2.fields, (((t2.fields ->> 'C 1'::text))::integer) - Sort Key: (((t2.fields ->> 'C 1'::text))::integer) - -> Foreign Scan on "S 1"."T 1" t2 - Output: t2.fields, ((t2.fields ->> 'C 1'::text))::integer - InfluxDB query: SELECT * FROM "T1" -(17 rows) - ---Testcase 51: -SELECT t1.c1, t2."C 1" FROM (SELECT (fields->>'C 1')::int c1, (fields->>'c2')::int c2, tags->>'c3' c3, fields->>'c4' c4, fields->>'c5' c5, fields->>'c6' c6, fields->>'c7' c7, fields->>'c8' c8 FROM ft2 t1) t1 LEFT JOIN (SELECT (fields->>'C 1')::int "C 1", (fields->>'c2')::int c2, tags->>'c3' c3, fields->>'c4' c4, fields->>'c5' c5, fields->>'c6' c6, fields->>'c7' c7, fields->>'c8' c8 FROM "S 1"."T 1" t2) t2 ON ((t1.c1)::int = (t2."C 1")::int) OFFSET 100 LIMIT 10; - c1 | C 1 ------+----- - 101 | 101 - 102 | 102 - 103 | 103 - 104 | 104 - 105 | 105 - 106 | 106 - 107 | 107 - 108 | 108 - 109 | 109 - 110 | 110 -(10 rows) - --- A join between 2 foreign tables. ORDER BY clause is added to the --- foreign join so that the other table can be joined using merge join strategy. ---Testcase 52: -EXPLAIN (VERBOSE, COSTS OFF) - SELECT t1."C 1" FROM (SELECT (fields->>'C 1')::int "C 1", (fields->>'c2')::int c2, tags->>'c3' c3, fields->>'c4' c4, fields->>'c5' c5, fields->>'c6' c6, fields->>'c7' c7, fields->>'c8' c8 FROM "S 1"."T 1" t1) t1 left join (SELECT (fields->>'C 1')::int c1, (fields->>'c2')::int c2, tags->>'c3' c3, fields->>'c4' c4, fields->>'c5' c5, fields->>'c6' c6, fields->>'c7' c7, fields->>'c8' c8 FROM ft1 t2) t2 join (SELECT (fields->>'C 1')::int c1, (fields->>'c2')::int c2, tags->>'c3' c3, fields->>'c4' c4, fields->>'c5' c5, fields->>'c6' c6, fields->>'c7' c7, fields->>'c8' c8 FROM ft2 t3) t3 on ((t2.c1)::int = (t3.c1)::int) on ((t3.c1)::int = (t1."C 1")::int) OFFSET 100 LIMIT 10; - QUERY PLAN ------------------------------------------------------------------------------------------------------------------------ - Limit - Output: (((t1.fields ->> 'C 1'::text))::integer) - -> Merge Left Join - Output: (((t1.fields ->> 'C 1'::text))::integer) - Merge Cond: ((((t1.fields ->> 'C 1'::text))::integer) = ((t3.fields ->> 'C 1'::text))::integer) - -> Sort - Output: t1.fields, (((t1.fields ->> 'C 1'::text))::integer) - Sort Key: (((t1.fields ->> 'C 1'::text))::integer) - -> Foreign Scan on "S 1"."T 1" t1 - Output: t1.fields, ((t1.fields ->> 'C 1'::text))::integer - InfluxDB query: SELECT * FROM "T1" - -> Materialize - Output: t3.fields - -> Merge Join - Output: t3.fields - Merge Cond: ((((t2.fields ->> 'C 1'::text))::integer) = (((t3.fields ->> 'C 1'::text))::integer)) - -> Sort - Output: t2.fields, (((t2.fields ->> 'C 1'::text))::integer) - Sort Key: (((t2.fields ->> 'C 1'::text))::integer) - -> Foreign Scan on public.ft1 t2 - Output: t2.fields, ((t2.fields ->> 'C 1'::text))::integer - InfluxDB query: SELECT * FROM "T1" - -> Sort - Output: t3.fields, (((t3.fields ->> 'C 1'::text))::integer) - Sort Key: (((t3.fields ->> 'C 1'::text))::integer) - -> Foreign Scan on public.ft2 t3 - Output: t3.fields, ((t3.fields ->> 'C 1'::text))::integer - InfluxDB query: SELECT * FROM "T1" -(28 rows) - ---Testcase 53: -SELECT t1."C 1" FROM (SELECT (fields->>'C 1')::int "C 1", (fields->>'c2')::int c2, tags->>'c3' c3, fields->>'c4' c4, fields->>'c5' c5, fields->>'c6' c6, fields->>'c7' c7, fields->>'c8' c8 FROM "S 1"."T 1" t1) t1 left join (SELECT (fields->>'C 1')::int c1, (fields->>'c2')::int c2, tags->>'c3' c3, fields->>'c4' c4, fields->>'c5' c5, fields->>'c6' c6, fields->>'c7' c7, fields->>'c8' c8 FROM ft1 t2) t2 join (SELECT (fields->>'C 1')::int c1, (fields->>'c2')::int c2, tags->>'c3' c3, fields->>'c4' c4, fields->>'c5' c5, fields->>'c6' c6, fields->>'c7' c7, fields->>'c8' c8 FROM ft2 t3) t3 on ((t2.c1)::int = (t3.c1)::int) on ((t3.c1)::int = (t1."C 1")::int) OFFSET 100 LIMIT 10; - C 1 ------ - 101 - 102 - 103 - 104 - 105 - 106 - 107 - 108 - 109 - 110 -(10 rows) - --- Test similar to above, except that the full join prevents any equivalence --- classes from being merged. This produces single relation equivalence classes --- included in join restrictions. ---Testcase 54: -EXPLAIN (VERBOSE, COSTS OFF) - SELECT t1."C 1", t2.c1, t3.c1 FROM (SELECT (fields->>'C 1')::int "C 1", (fields->>'c2')::int c2, tags->>'c3' c3, fields->>'c4' c4, fields->>'c5' c5, fields->>'c6' c6, fields->>'c7' c7, fields->>'c8' c8 FROM "S 1"."T 1" t1) t1 left join (SELECT (fields->>'C 1')::int c1, (fields->>'c2')::int c2, tags->>'c3' c3, fields->>'c4' c4, fields->>'c5' c5, fields->>'c6' c6, fields->>'c7' c7, fields->>'c8' c8 FROM ft1 t2) t2 full join (SELECT (fields->>'C 1')::int c1, (fields->>'c2')::int c2, tags->>'c3' c3, fields->>'c4' c4, fields->>'c5' c5, fields->>'c6' c6, fields->>'c7' c7, fields->>'c8' c8 FROM ft2 t3) t3 on ((t2.c1)::int = (t3.c1)::int) on ((t3.c1)::int = (t1."C 1")::int) OFFSET 100 LIMIT 10; - QUERY PLAN ------------------------------------------------------------------------------------------------------------------------------------------- - Limit - Output: (((t1.fields ->> 'C 1'::text))::integer), (((t2.fields ->> 'C 1'::text))::integer), (((t3.fields ->> 'C 1'::text))::integer) - -> Merge Left Join - Output: (((t1.fields ->> 'C 1'::text))::integer), ((t2.fields ->> 'C 1'::text))::integer, ((t3.fields ->> 'C 1'::text))::integer - Merge Cond: ((((t1.fields ->> 'C 1'::text))::integer) = ((t3.fields ->> 'C 1'::text))::integer) - -> Sort - Output: t1.fields, (((t1.fields ->> 'C 1'::text))::integer) - Sort Key: (((t1.fields ->> 'C 1'::text))::integer) - -> Foreign Scan on "S 1"."T 1" t1 - Output: t1.fields, ((t1.fields ->> 'C 1'::text))::integer - InfluxDB query: SELECT * FROM "T1" - -> Materialize - Output: t3.fields, t2.fields - -> Merge Left Join - Output: t3.fields, t2.fields - Merge Cond: ((((t3.fields ->> 'C 1'::text))::integer) = (((t2.fields ->> 'C 1'::text))::integer)) - -> Sort - Output: t3.fields, (((t3.fields ->> 'C 1'::text))::integer) - Sort Key: (((t3.fields ->> 'C 1'::text))::integer) - -> Foreign Scan on public.ft2 t3 - Output: t3.fields, ((t3.fields ->> 'C 1'::text))::integer - InfluxDB query: SELECT * FROM "T1" - -> Sort - Output: t2.fields, (((t2.fields ->> 'C 1'::text))::integer) - Sort Key: (((t2.fields ->> 'C 1'::text))::integer) - -> Foreign Scan on public.ft1 t2 - Output: t2.fields, ((t2.fields ->> 'C 1'::text))::integer - InfluxDB query: SELECT * FROM "T1" -(28 rows) - ---Testcase 55: -SELECT t1."C 1", t2.c1, t3.c1 FROM (SELECT (fields->>'C 1')::int "C 1", (fields->>'c2')::int c2, tags->>'c3' c3, fields->>'c4' c4, fields->>'c5' c5, fields->>'c6' c6, fields->>'c7' c7, fields->>'c8' c8 FROM "S 1"."T 1" t1) t1 left join (SELECT (fields->>'C 1')::int c1, (fields->>'c2')::int c2, tags->>'c3' c3, fields->>'c4' c4, fields->>'c5' c5, fields->>'c6' c6, fields->>'c7' c7, fields->>'c8' c8 FROM ft1 t2) t2 full join (SELECT (fields->>'C 1')::int c1, (fields->>'c2')::int c2, tags->>'c3' c3, fields->>'c4' c4, fields->>'c5' c5, fields->>'c6' c6, fields->>'c7' c7, fields->>'c8' c8 FROM ft2 t3) t3 on ((t2.c1)::int = (t3.c1)::int) on ((t3.c1)::int = (t1."C 1")::int) OFFSET 100 LIMIT 10; - C 1 | c1 | c1 ------+-----+----- - 101 | 101 | 101 - 102 | 102 | 102 - 103 | 103 | 103 - 104 | 104 | 104 - 105 | 105 | 105 - 106 | 106 | 106 - 107 | 107 | 107 - 108 | 108 | 108 - 109 | 109 | 109 - 110 | 110 | 110 -(10 rows) - --- Test similar to above with all full outer joins ---Testcase 56: -EXPLAIN (VERBOSE, COSTS OFF) - SELECT t1."C 1", t2.c1, t3.c1 FROM (SELECT (fields->>'C 1')::int "C 1", (fields->>'c2')::int c2, tags->>'c3' c3, fields->>'c4' c4, fields->>'c5' c5, fields->>'c6' c6, fields->>'c7' c7, fields->>'c8' c8 FROM "S 1"."T 1" t1) t1 full join (SELECT (fields->>'C 1')::int c1, (fields->>'c2')::int c2, tags->>'c3' c3, fields->>'c4' c4, fields->>'c5' c5, fields->>'c6' c6, fields->>'c7' c7, fields->>'c8' c8 FROM ft1 t2) t2 full join (SELECT (fields->>'C 1')::int c1, (fields->>'c2')::int c2, tags->>'c3' c3, fields->>'c4' c4, fields->>'c5' c5, fields->>'c6' c6, fields->>'c7' c7, fields->>'c8' c8 FROM ft2 t3) t3 on ((t2.c1)::int = (t3.c1)::int) on ((t3.c1)::int = (t1."C 1")::int) OFFSET 100 LIMIT 10; - QUERY PLAN ----------------------------------------------------------------------------------------------------------------------------------------- - Limit - Output: (((t1.fields ->> 'C 1'::text))::integer), (((t2.fields ->> 'C 1'::text))::integer), (((t3.fields ->> 'C 1'::text))::integer) - -> Merge Full Join - Output: ((t1.fields ->> 'C 1'::text))::integer, ((t2.fields ->> 'C 1'::text))::integer, ((t3.fields ->> 'C 1'::text))::integer - Merge Cond: ((((t1.fields ->> 'C 1'::text))::integer) = (((t3.fields ->> 'C 1'::text))::integer)) - -> Sort - Output: t1.fields, (((t1.fields ->> 'C 1'::text))::integer) - Sort Key: (((t1.fields ->> 'C 1'::text))::integer) - -> Foreign Scan on "S 1"."T 1" t1 - Output: t1.fields, ((t1.fields ->> 'C 1'::text))::integer - InfluxDB query: SELECT * FROM "T1" - -> Sort - Output: t2.fields, t3.fields, (((t3.fields ->> 'C 1'::text))::integer) - Sort Key: (((t3.fields ->> 'C 1'::text))::integer) - -> Merge Full Join - Output: t2.fields, t3.fields, ((t3.fields ->> 'C 1'::text))::integer - Merge Cond: ((((t2.fields ->> 'C 1'::text))::integer) = (((t3.fields ->> 'C 1'::text))::integer)) - -> Sort - Output: t2.fields, (((t2.fields ->> 'C 1'::text))::integer) - Sort Key: (((t2.fields ->> 'C 1'::text))::integer) - -> Foreign Scan on public.ft1 t2 - Output: t2.fields, ((t2.fields ->> 'C 1'::text))::integer - InfluxDB query: SELECT * FROM "T1" - -> Sort - Output: t3.fields, (((t3.fields ->> 'C 1'::text))::integer) - Sort Key: (((t3.fields ->> 'C 1'::text))::integer) - -> Foreign Scan on public.ft2 t3 - Output: t3.fields, ((t3.fields ->> 'C 1'::text))::integer - InfluxDB query: SELECT * FROM "T1" -(29 rows) - ---Testcase 57: -SELECT t1."C 1", t2.c1, t3.c1 FROM (SELECT (fields->>'C 1')::int "C 1", (fields->>'c2')::int c2, tags->>'c3' c3, fields->>'c4' c4, fields->>'c5' c5, fields->>'c6' c6, fields->>'c7' c7, fields->>'c8' c8 FROM "S 1"."T 1" t1) t1 full join (SELECT (fields->>'C 1')::int c1, (fields->>'c2')::int c2, tags->>'c3' c3, fields->>'c4' c4, fields->>'c5' c5, fields->>'c6' c6, fields->>'c7' c7, fields->>'c8' c8 FROM ft1 t2) t2 full join (SELECT (fields->>'C 1')::int c1, (fields->>'c2')::int c2, tags->>'c3' c3, fields->>'c4' c4, fields->>'c5' c5, fields->>'c6' c6, fields->>'c7' c7, fields->>'c8' c8 FROM ft2 t3) t3 on ((t2.c1)::int = (t3.c1)::int) on ((t3.c1)::int = (t1."C 1")::int) OFFSET 100 LIMIT 10; - C 1 | c1 | c1 ------+-----+----- - 101 | 101 | 101 - 102 | 102 | 102 - 103 | 103 | 103 - 104 | 104 | 104 - 105 | 105 | 105 - 106 | 106 | 106 - 107 | 107 | 107 - 108 | 108 | 108 - 109 | 109 | 109 - 110 | 110 | 110 -(10 rows) - -RESET enable_hashjoin; -RESET enable_nestloop; --- =================================================================== --- WHERE with remotely-executable conditions --- =================================================================== ---Testcase 58: -EXPLAIN (VERBOSE, COSTS OFF) SELECT * FROM ft1 t1 WHERE (t1.fields->>'C 1')::int = 1; -- Var, OpExpr(b), Const - QUERY PLAN ----------------------------------------------------------- - Foreign Scan on public.ft1 t1 - Output: "time", tags, fields - InfluxDB query: SELECT * FROM "T1" WHERE (("C 1" = 1)) -(3 rows) - ---Testcase 59: -EXPLAIN (VERBOSE, COSTS OFF) SELECT * FROM ft1 t1 WHERE (t1.fields->>'C 1')::int = 100 AND (t1.fields->>'c2')::int = 0; -- BoolExpr - QUERY PLAN ------------------------------------------------------------------------------ - Foreign Scan on public.ft1 t1 - Output: "time", tags, fields - InfluxDB query: SELECT * FROM "T1" WHERE (("C 1" = 100)) AND (("c2" = 0)) -(3 rows) - ---Testcase 60: -EXPLAIN (VERBOSE, COSTS OFF) SELECT * FROM ft1 t1 WHERE (t1.fields->>'C 1')::int IS NULL; -- NullTest - QUERY PLAN ------------------------------------------------------------- - Foreign Scan on public.ft1 t1 - Output: "time", tags, fields - Filter: (((t1.fields ->> 'C 1'::text))::integer IS NULL) - InfluxDB query: SELECT * FROM "T1" -(4 rows) - ---Testcase 61: -EXPLAIN (VERBOSE, COSTS OFF) SELECT * FROM ft1 t1 WHERE (t1.fields->>'C 1')::int IS NOT NULL; -- NullTest - QUERY PLAN ----------------------------------------------------------------- - Foreign Scan on public.ft1 t1 - Output: "time", tags, fields - Filter: (((t1.fields ->> 'C 1'::text))::integer IS NOT NULL) - InfluxDB query: SELECT * FROM "T1" -(4 rows) - ---Testcase 62: -EXPLAIN (VERBOSE, COSTS OFF) SELECT * FROM ft1 t1 WHERE round(abs((t1.fields->>'C 1')::int), 0) = 1; -- FuncExpr - QUERY PLAN ---------------------------------------------------------------------------------------------- - Foreign Scan on public.ft1 t1 - Output: "time", tags, fields - Filter: (round((abs(((t1.fields ->> 'C 1'::text))::integer))::numeric, 0) = '1'::numeric) - InfluxDB query: SELECT * FROM "T1" -(4 rows) - ---Testcase 63: -EXPLAIN (VERBOSE, COSTS OFF) SELECT * FROM ft1 t1 WHERE (t1.fields->>'C 1')::int = -(t1.fields->>'C 1')::int; -- OpExpr(l) - QUERY PLAN ------------------------------------------------------------------- - Foreign Scan on public.ft1 t1 - Output: "time", tags, fields - InfluxDB query: SELECT * FROM "T1" WHERE (("C 1" = (- "C 1"))) -(3 rows) - ---Testcase 64: -EXPLAIN (VERBOSE, COSTS OFF) SELECT * FROM ft1 t1 WHERE 1 = (t1.fields->>'C 1')::int!; -- OpExpr(r) - QUERY PLAN ---------------------------------------------------------------------------------- - Foreign Scan on public.ft1 t1 - Output: "time", tags, fields - Filter: ('1'::numeric = ((((t1.fields ->> 'C 1'::text))::integer)::bigint !)) - InfluxDB query: SELECT * FROM "T1" -(4 rows) - ---Testcase 65: -EXPLAIN (VERBOSE, COSTS OFF) SELECT * FROM ft1 t1 WHERE ((t1.fields->>'C 1')::int IS NOT NULL) IS DISTINCT FROM ((t1.fields->>'C 1')::int IS NOT NULL); -- DistinctExpr - QUERY PLAN ----------------------------------------------------------------------------------------------------------------------------------------- - Foreign Scan on public.ft1 t1 - Output: "time", tags, fields - Filter: ((((t1.fields ->> 'C 1'::text))::integer IS NOT NULL) IS DISTINCT FROM (((t1.fields ->> 'C 1'::text))::integer IS NOT NULL)) - InfluxDB query: SELECT * FROM "T1" -(4 rows) - ---Testcase 66: -EXPLAIN (VERBOSE, COSTS OFF) SELECT * FROM ft1 t1 WHERE (t1.fields->>'C 1')::int = ANY(ARRAY[(fields->>'c2')::int, 1, (t1.fields->>'C 1')::int + 0]); -- ScalarArrayOpExpr - QUERY PLAN ------------------------------------------------------------------------------------------------------ - Foreign Scan on public.ft1 t1 - Output: "time", tags, fields - InfluxDB query: SELECT * FROM "T1" WHERE (("C 1" = "c2") OR ("C 1" = 1) OR ("C 1" = ("C 1" + 0))) -(3 rows) - ---Testcase 67: -EXPLAIN (VERBOSE, COSTS OFF) SELECT * FROM ft1 t1 WHERE (t1.fields->>'C 1')::int = (ARRAY[(t1.fields->>'C 1')::int,(fields->>'c2')::int,3])[1]; -- SubscriptingRef - QUERY PLAN ---------------------------------------------------------------------------------------------------------------------------------------------------- - Foreign Scan on public.ft1 t1 - Output: "time", tags, fields - Filter: (((t1.fields ->> 'C 1'::text))::integer = (ARRAY[((t1.fields ->> 'C 1'::text))::integer, ((t1.fields ->> 'c2'::text))::integer, 3])[1]) - InfluxDB query: SELECT * FROM "T1" -(4 rows) - ---Testcase 68: -EXPLAIN (VERBOSE, COSTS OFF) SELECT * FROM ft1 t1 WHERE fields->>'c6' = E'foo''s\\bar'; -- check special chars - QUERY PLAN ---------------------------------------------------------------------- - Foreign Scan on public.ft1 t1 - Output: "time", tags, fields - InfluxDB query: SELECT * FROM "T1" WHERE (("c6" = 'foo''s\\bar')) -(3 rows) - ---Testcase 69: -EXPLAIN (VERBOSE, COSTS OFF) SELECT * FROM ft1 t1 WHERE fields->>'c8' = 'foo'; -- can't be sent to remote - QUERY PLAN -------------------------------------------------------------- - Foreign Scan on public.ft1 t1 - Output: "time", tags, fields - InfluxDB query: SELECT * FROM "T1" WHERE (("c8" = 'foo')) -(3 rows) - --- parameterized remote path for foreign table ---Testcase 70: -EXPLAIN (VERBOSE, COSTS OFF) - SELECT * FROM "S 1"."T 1" a, ft2 b WHERE (a.fields->>'C 1')::int = 47 AND (b.fields->>'C 1')::int = (a.fields->>'c2')::int; - QUERY PLAN ---------------------------------------------------------------------------------------------- - Hash Join - Output: a."time", a.tags, a.fields, b."time", b.tags, b.fields - Hash Cond: (((b.fields ->> 'C 1'::text))::integer = ((a.fields ->> 'c2'::text))::integer) - -> Foreign Scan on public.ft2 b - Output: b."time", b.tags, b.fields - InfluxDB query: SELECT * FROM "T1" - -> Hash - Output: a."time", a.tags, a.fields - -> Foreign Scan on "S 1"."T 1" a - Output: a."time", a.tags, a.fields - InfluxDB query: SELECT * FROM "T1" WHERE (("C 1" = 47)) -(11 rows) - ---Testcase 71: -SELECT * FROM ft2 a, ft2 b WHERE (a.fields->>'C 1')::int = 47 AND (b.fields->>'C 1')::int = (a.fields->>'c2')::int; - time | tags | fields | time | tags | fields ---------------------------+-----------------+----------------------------------------------------------------------+--------------------------+-----------------+--------------------------------------------------------------------- - Tue Feb 17 00:00:00 1970 | {"c3": "00047"} | {"c2": "7", "c6": "7", "c7": "7 ", "c8": "foo", "C 1": "47"} | Thu Jan 08 00:00:00 1970 | {"c3": "00007"} | {"c2": "7", "c6": "7", "c7": "7 ", "c8": "foo", "C 1": "7"} -(1 row) - --- check both safe and unsafe join conditions ---Testcase 72: -EXPLAIN (VERBOSE, COSTS OFF) - SELECT * FROM ft2 a, ft2 b - WHERE (a.fields->>'c2')::int = 6 AND (b.fields->>'C 1')::int = (a.fields->>'C 1')::int AND a.fields->>'c8' = 'foo' AND b.fields->>'c7' = upper(a.fields->>'c7'); - QUERY PLAN -------------------------------------------------------------------------------------------------------------------------------------------------------------------- - Hash Join - Output: a."time", a.tags, a.fields, b."time", b.tags, b.fields - Hash Cond: ((((b.fields ->> 'C 1'::text))::integer = ((a.fields ->> 'C 1'::text))::integer) AND ((b.fields ->> 'c7'::text) = upper((a.fields ->> 'c7'::text)))) - -> Foreign Scan on public.ft2 b - Output: b."time", b.tags, b.fields - InfluxDB query: SELECT * FROM "T1" - -> Hash - Output: a."time", a.tags, a.fields - -> Foreign Scan on public.ft2 a - Output: a."time", a.tags, a.fields - InfluxDB query: SELECT * FROM "T1" WHERE (("c8" = 'foo')) AND (("c2" = 6)) -(11 rows) - ---Testcase 73: -SELECT * FROM ft2 a, ft2 b -WHERE (a.fields->>'c2')::int = 6 AND (b.fields->>'C 1')::int = (a.fields->>'C 1')::int AND a.fields->>'c8' = 'foo' AND b.fields->>'c7' = upper(a.fields->>'c7') ORDER BY (a.fields->>'C 1')::int; - time | tags | fields | time | tags | fields ---------------------------+-----------------+-----------------------------------------------------------------------+--------------------------+-----------------+----------------------------------------------------------------------- - Wed Jan 07 00:00:00 1970 | {"c3": "00006"} | {"c2": "6", "c6": "6", "c7": "6 ", "c8": "foo", "C 1": "6"} | Wed Jan 07 00:00:00 1970 | {"c3": "00006"} | {"c2": "6", "c6": "6", "c7": "6 ", "c8": "foo", "C 1": "6"} - Sat Jan 17 00:00:00 1970 | {"c3": "00016"} | {"c2": "6", "c6": "6", "c7": "6 ", "c8": "foo", "C 1": "16"} | Sat Jan 17 00:00:00 1970 | {"c3": "00016"} | {"c2": "6", "c6": "6", "c7": "6 ", "c8": "foo", "C 1": "16"} - Tue Jan 27 00:00:00 1970 | {"c3": "00026"} | {"c2": "6", "c6": "6", "c7": "6 ", "c8": "foo", "C 1": "26"} | Tue Jan 27 00:00:00 1970 | {"c3": "00026"} | {"c2": "6", "c6": "6", "c7": "6 ", "c8": "foo", "C 1": "26"} - Fri Feb 06 00:00:00 1970 | {"c3": "00036"} | {"c2": "6", "c6": "6", "c7": "6 ", "c8": "foo", "C 1": "36"} | Fri Feb 06 00:00:00 1970 | {"c3": "00036"} | {"c2": "6", "c6": "6", "c7": "6 ", "c8": "foo", "C 1": "36"} - Mon Feb 16 00:00:00 1970 | {"c3": "00046"} | {"c2": "6", "c6": "6", "c7": "6 ", "c8": "foo", "C 1": "46"} | Mon Feb 16 00:00:00 1970 | {"c3": "00046"} | {"c2": "6", "c6": "6", "c7": "6 ", "c8": "foo", "C 1": "46"} - Thu Feb 26 00:00:00 1970 | {"c3": "00056"} | {"c2": "6", "c6": "6", "c7": "6 ", "c8": "foo", "C 1": "56"} | Thu Feb 26 00:00:00 1970 | {"c3": "00056"} | {"c2": "6", "c6": "6", "c7": "6 ", "c8": "foo", "C 1": "56"} - Sun Mar 08 00:00:00 1970 | {"c3": "00066"} | {"c2": "6", "c6": "6", "c7": "6 ", "c8": "foo", "C 1": "66"} | Sun Mar 08 00:00:00 1970 | {"c3": "00066"} | {"c2": "6", "c6": "6", "c7": "6 ", "c8": "foo", "C 1": "66"} - Wed Mar 18 00:00:00 1970 | {"c3": "00076"} | {"c2": "6", "c6": "6", "c7": "6 ", "c8": "foo", "C 1": "76"} | Wed Mar 18 00:00:00 1970 | {"c3": "00076"} | {"c2": "6", "c6": "6", "c7": "6 ", "c8": "foo", "C 1": "76"} - Sat Mar 28 00:00:00 1970 | {"c3": "00086"} | {"c2": "6", "c6": "6", "c7": "6 ", "c8": "foo", "C 1": "86"} | Sat Mar 28 00:00:00 1970 | {"c3": "00086"} | {"c2": "6", "c6": "6", "c7": "6 ", "c8": "foo", "C 1": "86"} - Tue Apr 07 00:00:00 1970 | {"c3": "00096"} | {"c2": "6", "c6": "6", "c7": "6 ", "c8": "foo", "C 1": "96"} | Tue Apr 07 00:00:00 1970 | {"c3": "00096"} | {"c2": "6", "c6": "6", "c7": "6 ", "c8": "foo", "C 1": "96"} - Wed Jan 07 00:00:00 1970 | {"c3": "00106"} | {"c2": "6", "c6": "6", "c7": "6 ", "c8": "foo", "C 1": "106"} | Wed Jan 07 00:00:00 1970 | {"c3": "00106"} | {"c2": "6", "c6": "6", "c7": "6 ", "c8": "foo", "C 1": "106"} - Sat Jan 17 00:00:00 1970 | {"c3": "00116"} | {"c2": "6", "c6": "6", "c7": "6 ", "c8": "foo", "C 1": "116"} | Sat Jan 17 00:00:00 1970 | {"c3": "00116"} | {"c2": "6", "c6": "6", "c7": "6 ", "c8": "foo", "C 1": "116"} - Tue Jan 27 00:00:00 1970 | {"c3": "00126"} | {"c2": "6", "c6": "6", "c7": "6 ", "c8": "foo", "C 1": "126"} | Tue Jan 27 00:00:00 1970 | {"c3": "00126"} | {"c2": "6", "c6": "6", "c7": "6 ", "c8": "foo", "C 1": "126"} - Fri Feb 06 00:00:00 1970 | {"c3": "00136"} | {"c2": "6", "c6": "6", "c7": "6 ", "c8": "foo", "C 1": "136"} | Fri Feb 06 00:00:00 1970 | {"c3": "00136"} | {"c2": "6", "c6": "6", "c7": "6 ", "c8": "foo", "C 1": "136"} - Mon Feb 16 00:00:00 1970 | {"c3": "00146"} | {"c2": "6", "c6": "6", "c7": "6 ", "c8": "foo", "C 1": "146"} | Mon Feb 16 00:00:00 1970 | {"c3": "00146"} | {"c2": "6", "c6": "6", "c7": "6 ", "c8": "foo", "C 1": "146"} - Thu Feb 26 00:00:00 1970 | {"c3": "00156"} | {"c2": "6", "c6": "6", "c7": "6 ", "c8": "foo", "C 1": "156"} | Thu Feb 26 00:00:00 1970 | {"c3": "00156"} | {"c2": "6", "c6": "6", "c7": "6 ", "c8": "foo", "C 1": "156"} - Sun Mar 08 00:00:00 1970 | {"c3": "00166"} | {"c2": "6", "c6": "6", "c7": "6 ", "c8": "foo", "C 1": "166"} | Sun Mar 08 00:00:00 1970 | {"c3": "00166"} | {"c2": "6", "c6": "6", "c7": "6 ", "c8": "foo", "C 1": "166"} - Wed Mar 18 00:00:00 1970 | {"c3": "00176"} | {"c2": "6", "c6": "6", "c7": "6 ", "c8": "foo", "C 1": "176"} | Wed Mar 18 00:00:00 1970 | {"c3": "00176"} | {"c2": "6", "c6": "6", "c7": "6 ", "c8": "foo", "C 1": "176"} - Sat Mar 28 00:00:00 1970 | {"c3": "00186"} | {"c2": "6", "c6": "6", "c7": "6 ", "c8": "foo", "C 1": "186"} | Sat Mar 28 00:00:00 1970 | {"c3": "00186"} | {"c2": "6", "c6": "6", "c7": "6 ", "c8": "foo", "C 1": "186"} - Tue Apr 07 00:00:00 1970 | {"c3": "00196"} | {"c2": "6", "c6": "6", "c7": "6 ", "c8": "foo", "C 1": "196"} | Tue Apr 07 00:00:00 1970 | {"c3": "00196"} | {"c2": "6", "c6": "6", "c7": "6 ", "c8": "foo", "C 1": "196"} - Wed Jan 07 00:00:00 1970 | {"c3": "00206"} | {"c2": "6", "c6": "6", "c7": "6 ", "c8": "foo", "C 1": "206"} | Wed Jan 07 00:00:00 1970 | {"c3": "00206"} | {"c2": "6", "c6": "6", "c7": "6 ", "c8": "foo", "C 1": "206"} - Sat Jan 17 00:00:00 1970 | {"c3": "00216"} | {"c2": "6", "c6": "6", "c7": "6 ", "c8": "foo", "C 1": "216"} | Sat Jan 17 00:00:00 1970 | {"c3": "00216"} | {"c2": "6", "c6": "6", "c7": "6 ", "c8": "foo", "C 1": "216"} - Tue Jan 27 00:00:00 1970 | {"c3": "00226"} | {"c2": "6", "c6": "6", "c7": "6 ", "c8": "foo", "C 1": "226"} | Tue Jan 27 00:00:00 1970 | {"c3": "00226"} | {"c2": "6", "c6": "6", "c7": "6 ", "c8": "foo", "C 1": "226"} - Fri Feb 06 00:00:00 1970 | {"c3": "00236"} | {"c2": "6", "c6": "6", "c7": "6 ", "c8": "foo", "C 1": "236"} | Fri Feb 06 00:00:00 1970 | {"c3": "00236"} | {"c2": "6", "c6": "6", "c7": "6 ", "c8": "foo", "C 1": "236"} - Mon Feb 16 00:00:00 1970 | {"c3": "00246"} | {"c2": "6", "c6": "6", "c7": "6 ", "c8": "foo", "C 1": "246"} | Mon Feb 16 00:00:00 1970 | {"c3": "00246"} | {"c2": "6", "c6": "6", "c7": "6 ", "c8": "foo", "C 1": "246"} - Thu Feb 26 00:00:00 1970 | {"c3": "00256"} | {"c2": "6", "c6": "6", "c7": "6 ", "c8": "foo", "C 1": "256"} | Thu Feb 26 00:00:00 1970 | {"c3": "00256"} | {"c2": "6", "c6": "6", "c7": "6 ", "c8": "foo", "C 1": "256"} - Sun Mar 08 00:00:00 1970 | {"c3": "00266"} | {"c2": "6", "c6": "6", "c7": "6 ", "c8": "foo", "C 1": "266"} | Sun Mar 08 00:00:00 1970 | {"c3": "00266"} | {"c2": "6", "c6": "6", "c7": "6 ", "c8": "foo", "C 1": "266"} - Wed Mar 18 00:00:00 1970 | {"c3": "00276"} | {"c2": "6", "c6": "6", "c7": "6 ", "c8": "foo", "C 1": "276"} | Wed Mar 18 00:00:00 1970 | {"c3": "00276"} | {"c2": "6", "c6": "6", "c7": "6 ", "c8": "foo", "C 1": "276"} - Sat Mar 28 00:00:00 1970 | {"c3": "00286"} | {"c2": "6", "c6": "6", "c7": "6 ", "c8": "foo", "C 1": "286"} | Sat Mar 28 00:00:00 1970 | {"c3": "00286"} | {"c2": "6", "c6": "6", "c7": "6 ", "c8": "foo", "C 1": "286"} - Tue Apr 07 00:00:00 1970 | {"c3": "00296"} | {"c2": "6", "c6": "6", "c7": "6 ", "c8": "foo", "C 1": "296"} | Tue Apr 07 00:00:00 1970 | {"c3": "00296"} | {"c2": "6", "c6": "6", "c7": "6 ", "c8": "foo", "C 1": "296"} - Wed Jan 07 00:00:00 1970 | {"c3": "00306"} | {"c2": "6", "c6": "6", "c7": "6 ", "c8": "foo", "C 1": "306"} | Wed Jan 07 00:00:00 1970 | {"c3": "00306"} | {"c2": "6", "c6": "6", "c7": "6 ", "c8": "foo", "C 1": "306"} - Sat Jan 17 00:00:00 1970 | {"c3": "00316"} | {"c2": "6", "c6": "6", "c7": "6 ", "c8": "foo", "C 1": "316"} | Sat Jan 17 00:00:00 1970 | {"c3": "00316"} | {"c2": "6", "c6": "6", "c7": "6 ", "c8": "foo", "C 1": "316"} - Tue Jan 27 00:00:00 1970 | {"c3": "00326"} | {"c2": "6", "c6": "6", "c7": "6 ", "c8": "foo", "C 1": "326"} | Tue Jan 27 00:00:00 1970 | {"c3": "00326"} | {"c2": "6", "c6": "6", "c7": "6 ", "c8": "foo", "C 1": "326"} - Fri Feb 06 00:00:00 1970 | {"c3": "00336"} | {"c2": "6", "c6": "6", "c7": "6 ", "c8": "foo", "C 1": "336"} | Fri Feb 06 00:00:00 1970 | {"c3": "00336"} | {"c2": "6", "c6": "6", "c7": "6 ", "c8": "foo", "C 1": "336"} - Mon Feb 16 00:00:00 1970 | {"c3": "00346"} | {"c2": "6", "c6": "6", "c7": "6 ", "c8": "foo", "C 1": "346"} | Mon Feb 16 00:00:00 1970 | {"c3": "00346"} | {"c2": "6", "c6": "6", "c7": "6 ", "c8": "foo", "C 1": "346"} - Thu Feb 26 00:00:00 1970 | {"c3": "00356"} | {"c2": "6", "c6": "6", "c7": "6 ", "c8": "foo", "C 1": "356"} | Thu Feb 26 00:00:00 1970 | {"c3": "00356"} | {"c2": "6", "c6": "6", "c7": "6 ", "c8": "foo", "C 1": "356"} - Sun Mar 08 00:00:00 1970 | {"c3": "00366"} | {"c2": "6", "c6": "6", "c7": "6 ", "c8": "foo", "C 1": "366"} | Sun Mar 08 00:00:00 1970 | {"c3": "00366"} | {"c2": "6", "c6": "6", "c7": "6 ", "c8": "foo", "C 1": "366"} - Wed Mar 18 00:00:00 1970 | {"c3": "00376"} | {"c2": "6", "c6": "6", "c7": "6 ", "c8": "foo", "C 1": "376"} | Wed Mar 18 00:00:00 1970 | {"c3": "00376"} | {"c2": "6", "c6": "6", "c7": "6 ", "c8": "foo", "C 1": "376"} - Sat Mar 28 00:00:00 1970 | {"c3": "00386"} | {"c2": "6", "c6": "6", "c7": "6 ", "c8": "foo", "C 1": "386"} | Sat Mar 28 00:00:00 1970 | {"c3": "00386"} | {"c2": "6", "c6": "6", "c7": "6 ", "c8": "foo", "C 1": "386"} - Tue Apr 07 00:00:00 1970 | {"c3": "00396"} | {"c2": "6", "c6": "6", "c7": "6 ", "c8": "foo", "C 1": "396"} | Tue Apr 07 00:00:00 1970 | {"c3": "00396"} | {"c2": "6", "c6": "6", "c7": "6 ", "c8": "foo", "C 1": "396"} - Wed Jan 07 00:00:00 1970 | {"c3": "00406"} | {"c2": "6", "c6": "6", "c7": "6 ", "c8": "foo", "C 1": "406"} | Wed Jan 07 00:00:00 1970 | {"c3": "00406"} | {"c2": "6", "c6": "6", "c7": "6 ", "c8": "foo", "C 1": "406"} - Sat Jan 17 00:00:00 1970 | {"c3": "00416"} | {"c2": "6", "c6": "6", "c7": "6 ", "c8": "foo", "C 1": "416"} | Sat Jan 17 00:00:00 1970 | {"c3": "00416"} | {"c2": "6", "c6": "6", "c7": "6 ", "c8": "foo", "C 1": "416"} - Tue Jan 27 00:00:00 1970 | {"c3": "00426"} | {"c2": "6", "c6": "6", "c7": "6 ", "c8": "foo", "C 1": "426"} | Tue Jan 27 00:00:00 1970 | {"c3": "00426"} | {"c2": "6", "c6": "6", "c7": "6 ", "c8": "foo", "C 1": "426"} - Fri Feb 06 00:00:00 1970 | {"c3": "00436"} | {"c2": "6", "c6": "6", "c7": "6 ", "c8": "foo", "C 1": "436"} | Fri Feb 06 00:00:00 1970 | {"c3": "00436"} | {"c2": "6", "c6": "6", "c7": "6 ", "c8": "foo", "C 1": "436"} - Mon Feb 16 00:00:00 1970 | {"c3": "00446"} | {"c2": "6", "c6": "6", "c7": "6 ", "c8": "foo", "C 1": "446"} | Mon Feb 16 00:00:00 1970 | {"c3": "00446"} | {"c2": "6", "c6": "6", "c7": "6 ", "c8": "foo", "C 1": "446"} - Thu Feb 26 00:00:00 1970 | {"c3": "00456"} | {"c2": "6", "c6": "6", "c7": "6 ", "c8": "foo", "C 1": "456"} | Thu Feb 26 00:00:00 1970 | {"c3": "00456"} | {"c2": "6", "c6": "6", "c7": "6 ", "c8": "foo", "C 1": "456"} - Sun Mar 08 00:00:00 1970 | {"c3": "00466"} | {"c2": "6", "c6": "6", "c7": "6 ", "c8": "foo", "C 1": "466"} | Sun Mar 08 00:00:00 1970 | {"c3": "00466"} | {"c2": "6", "c6": "6", "c7": "6 ", "c8": "foo", "C 1": "466"} - Wed Mar 18 00:00:00 1970 | {"c3": "00476"} | {"c2": "6", "c6": "6", "c7": "6 ", "c8": "foo", "C 1": "476"} | Wed Mar 18 00:00:00 1970 | {"c3": "00476"} | {"c2": "6", "c6": "6", "c7": "6 ", "c8": "foo", "C 1": "476"} - Sat Mar 28 00:00:00 1970 | {"c3": "00486"} | {"c2": "6", "c6": "6", "c7": "6 ", "c8": "foo", "C 1": "486"} | Sat Mar 28 00:00:00 1970 | {"c3": "00486"} | {"c2": "6", "c6": "6", "c7": "6 ", "c8": "foo", "C 1": "486"} - Tue Apr 07 00:00:00 1970 | {"c3": "00496"} | {"c2": "6", "c6": "6", "c7": "6 ", "c8": "foo", "C 1": "496"} | Tue Apr 07 00:00:00 1970 | {"c3": "00496"} | {"c2": "6", "c6": "6", "c7": "6 ", "c8": "foo", "C 1": "496"} - Wed Jan 07 00:00:00 1970 | {"c3": "00506"} | {"c2": "6", "c6": "6", "c7": "6 ", "c8": "foo", "C 1": "506"} | Wed Jan 07 00:00:00 1970 | {"c3": "00506"} | {"c2": "6", "c6": "6", "c7": "6 ", "c8": "foo", "C 1": "506"} - Sat Jan 17 00:00:00 1970 | {"c3": "00516"} | {"c2": "6", "c6": "6", "c7": "6 ", "c8": "foo", "C 1": "516"} | Sat Jan 17 00:00:00 1970 | {"c3": "00516"} | {"c2": "6", "c6": "6", "c7": "6 ", "c8": "foo", "C 1": "516"} - Tue Jan 27 00:00:00 1970 | {"c3": "00526"} | {"c2": "6", "c6": "6", "c7": "6 ", "c8": "foo", "C 1": "526"} | Tue Jan 27 00:00:00 1970 | {"c3": "00526"} | {"c2": "6", "c6": "6", "c7": "6 ", "c8": "foo", "C 1": "526"} - Fri Feb 06 00:00:00 1970 | {"c3": "00536"} | {"c2": "6", "c6": "6", "c7": "6 ", "c8": "foo", "C 1": "536"} | Fri Feb 06 00:00:00 1970 | {"c3": "00536"} | {"c2": "6", "c6": "6", "c7": "6 ", "c8": "foo", "C 1": "536"} - Mon Feb 16 00:00:00 1970 | {"c3": "00546"} | {"c2": "6", "c6": "6", "c7": "6 ", "c8": "foo", "C 1": "546"} | Mon Feb 16 00:00:00 1970 | {"c3": "00546"} | {"c2": "6", "c6": "6", "c7": "6 ", "c8": "foo", "C 1": "546"} - Thu Feb 26 00:00:00 1970 | {"c3": "00556"} | {"c2": "6", "c6": "6", "c7": "6 ", "c8": "foo", "C 1": "556"} | Thu Feb 26 00:00:00 1970 | {"c3": "00556"} | {"c2": "6", "c6": "6", "c7": "6 ", "c8": "foo", "C 1": "556"} - Sun Mar 08 00:00:00 1970 | {"c3": "00566"} | {"c2": "6", "c6": "6", "c7": "6 ", "c8": "foo", "C 1": "566"} | Sun Mar 08 00:00:00 1970 | {"c3": "00566"} | {"c2": "6", "c6": "6", "c7": "6 ", "c8": "foo", "C 1": "566"} - Wed Mar 18 00:00:00 1970 | {"c3": "00576"} | {"c2": "6", "c6": "6", "c7": "6 ", "c8": "foo", "C 1": "576"} | Wed Mar 18 00:00:00 1970 | {"c3": "00576"} | {"c2": "6", "c6": "6", "c7": "6 ", "c8": "foo", "C 1": "576"} - Sat Mar 28 00:00:00 1970 | {"c3": "00586"} | {"c2": "6", "c6": "6", "c7": "6 ", "c8": "foo", "C 1": "586"} | Sat Mar 28 00:00:00 1970 | {"c3": "00586"} | {"c2": "6", "c6": "6", "c7": "6 ", "c8": "foo", "C 1": "586"} - Tue Apr 07 00:00:00 1970 | {"c3": "00596"} | {"c2": "6", "c6": "6", "c7": "6 ", "c8": "foo", "C 1": "596"} | Tue Apr 07 00:00:00 1970 | {"c3": "00596"} | {"c2": "6", "c6": "6", "c7": "6 ", "c8": "foo", "C 1": "596"} - Wed Jan 07 00:00:00 1970 | {"c3": "00606"} | {"c2": "6", "c6": "6", "c7": "6 ", "c8": "foo", "C 1": "606"} | Wed Jan 07 00:00:00 1970 | {"c3": "00606"} | {"c2": "6", "c6": "6", "c7": "6 ", "c8": "foo", "C 1": "606"} - Sat Jan 17 00:00:00 1970 | {"c3": "00616"} | {"c2": "6", "c6": "6", "c7": "6 ", "c8": "foo", "C 1": "616"} | Sat Jan 17 00:00:00 1970 | {"c3": "00616"} | {"c2": "6", "c6": "6", "c7": "6 ", "c8": "foo", "C 1": "616"} - Tue Jan 27 00:00:00 1970 | {"c3": "00626"} | {"c2": "6", "c6": "6", "c7": "6 ", "c8": "foo", "C 1": "626"} | Tue Jan 27 00:00:00 1970 | {"c3": "00626"} | {"c2": "6", "c6": "6", "c7": "6 ", "c8": "foo", "C 1": "626"} - Fri Feb 06 00:00:00 1970 | {"c3": "00636"} | {"c2": "6", "c6": "6", "c7": "6 ", "c8": "foo", "C 1": "636"} | Fri Feb 06 00:00:00 1970 | {"c3": "00636"} | {"c2": "6", "c6": "6", "c7": "6 ", "c8": "foo", "C 1": "636"} - Mon Feb 16 00:00:00 1970 | {"c3": "00646"} | {"c2": "6", "c6": "6", "c7": "6 ", "c8": "foo", "C 1": "646"} | Mon Feb 16 00:00:00 1970 | {"c3": "00646"} | {"c2": "6", "c6": "6", "c7": "6 ", "c8": "foo", "C 1": "646"} - Thu Feb 26 00:00:00 1970 | {"c3": "00656"} | {"c2": "6", "c6": "6", "c7": "6 ", "c8": "foo", "C 1": "656"} | Thu Feb 26 00:00:00 1970 | {"c3": "00656"} | {"c2": "6", "c6": "6", "c7": "6 ", "c8": "foo", "C 1": "656"} - Sun Mar 08 00:00:00 1970 | {"c3": "00666"} | {"c2": "6", "c6": "6", "c7": "6 ", "c8": "foo", "C 1": "666"} | Sun Mar 08 00:00:00 1970 | {"c3": "00666"} | {"c2": "6", "c6": "6", "c7": "6 ", "c8": "foo", "C 1": "666"} - Wed Mar 18 00:00:00 1970 | {"c3": "00676"} | {"c2": "6", "c6": "6", "c7": "6 ", "c8": "foo", "C 1": "676"} | Wed Mar 18 00:00:00 1970 | {"c3": "00676"} | {"c2": "6", "c6": "6", "c7": "6 ", "c8": "foo", "C 1": "676"} - Sat Mar 28 00:00:00 1970 | {"c3": "00686"} | {"c2": "6", "c6": "6", "c7": "6 ", "c8": "foo", "C 1": "686"} | Sat Mar 28 00:00:00 1970 | {"c3": "00686"} | {"c2": "6", "c6": "6", "c7": "6 ", "c8": "foo", "C 1": "686"} - Tue Apr 07 00:00:00 1970 | {"c3": "00696"} | {"c2": "6", "c6": "6", "c7": "6 ", "c8": "foo", "C 1": "696"} | Tue Apr 07 00:00:00 1970 | {"c3": "00696"} | {"c2": "6", "c6": "6", "c7": "6 ", "c8": "foo", "C 1": "696"} - Wed Jan 07 00:00:00 1970 | {"c3": "00706"} | {"c2": "6", "c6": "6", "c7": "6 ", "c8": "foo", "C 1": "706"} | Wed Jan 07 00:00:00 1970 | {"c3": "00706"} | {"c2": "6", "c6": "6", "c7": "6 ", "c8": "foo", "C 1": "706"} - Sat Jan 17 00:00:00 1970 | {"c3": "00716"} | {"c2": "6", "c6": "6", "c7": "6 ", "c8": "foo", "C 1": "716"} | Sat Jan 17 00:00:00 1970 | {"c3": "00716"} | {"c2": "6", "c6": "6", "c7": "6 ", "c8": "foo", "C 1": "716"} - Tue Jan 27 00:00:00 1970 | {"c3": "00726"} | {"c2": "6", "c6": "6", "c7": "6 ", "c8": "foo", "C 1": "726"} | Tue Jan 27 00:00:00 1970 | {"c3": "00726"} | {"c2": "6", "c6": "6", "c7": "6 ", "c8": "foo", "C 1": "726"} - Fri Feb 06 00:00:00 1970 | {"c3": "00736"} | {"c2": "6", "c6": "6", "c7": "6 ", "c8": "foo", "C 1": "736"} | Fri Feb 06 00:00:00 1970 | {"c3": "00736"} | {"c2": "6", "c6": "6", "c7": "6 ", "c8": "foo", "C 1": "736"} - Mon Feb 16 00:00:00 1970 | {"c3": "00746"} | {"c2": "6", "c6": "6", "c7": "6 ", "c8": "foo", "C 1": "746"} | Mon Feb 16 00:00:00 1970 | {"c3": "00746"} | {"c2": "6", "c6": "6", "c7": "6 ", "c8": "foo", "C 1": "746"} - Thu Feb 26 00:00:00 1970 | {"c3": "00756"} | {"c2": "6", "c6": "6", "c7": "6 ", "c8": "foo", "C 1": "756"} | Thu Feb 26 00:00:00 1970 | {"c3": "00756"} | {"c2": "6", "c6": "6", "c7": "6 ", "c8": "foo", "C 1": "756"} - Sun Mar 08 00:00:00 1970 | {"c3": "00766"} | {"c2": "6", "c6": "6", "c7": "6 ", "c8": "foo", "C 1": "766"} | Sun Mar 08 00:00:00 1970 | {"c3": "00766"} | {"c2": "6", "c6": "6", "c7": "6 ", "c8": "foo", "C 1": "766"} - Wed Mar 18 00:00:00 1970 | {"c3": "00776"} | {"c2": "6", "c6": "6", "c7": "6 ", "c8": "foo", "C 1": "776"} | Wed Mar 18 00:00:00 1970 | {"c3": "00776"} | {"c2": "6", "c6": "6", "c7": "6 ", "c8": "foo", "C 1": "776"} - Sat Mar 28 00:00:00 1970 | {"c3": "00786"} | {"c2": "6", "c6": "6", "c7": "6 ", "c8": "foo", "C 1": "786"} | Sat Mar 28 00:00:00 1970 | {"c3": "00786"} | {"c2": "6", "c6": "6", "c7": "6 ", "c8": "foo", "C 1": "786"} - Tue Apr 07 00:00:00 1970 | {"c3": "00796"} | {"c2": "6", "c6": "6", "c7": "6 ", "c8": "foo", "C 1": "796"} | Tue Apr 07 00:00:00 1970 | {"c3": "00796"} | {"c2": "6", "c6": "6", "c7": "6 ", "c8": "foo", "C 1": "796"} - Wed Jan 07 00:00:00 1970 | {"c3": "00806"} | {"c2": "6", "c6": "6", "c7": "6 ", "c8": "foo", "C 1": "806"} | Wed Jan 07 00:00:00 1970 | {"c3": "00806"} | {"c2": "6", "c6": "6", "c7": "6 ", "c8": "foo", "C 1": "806"} - Sat Jan 17 00:00:00 1970 | {"c3": "00816"} | {"c2": "6", "c6": "6", "c7": "6 ", "c8": "foo", "C 1": "816"} | Sat Jan 17 00:00:00 1970 | {"c3": "00816"} | {"c2": "6", "c6": "6", "c7": "6 ", "c8": "foo", "C 1": "816"} - Tue Jan 27 00:00:00 1970 | {"c3": "00826"} | {"c2": "6", "c6": "6", "c7": "6 ", "c8": "foo", "C 1": "826"} | Tue Jan 27 00:00:00 1970 | {"c3": "00826"} | {"c2": "6", "c6": "6", "c7": "6 ", "c8": "foo", "C 1": "826"} - Fri Feb 06 00:00:00 1970 | {"c3": "00836"} | {"c2": "6", "c6": "6", "c7": "6 ", "c8": "foo", "C 1": "836"} | Fri Feb 06 00:00:00 1970 | {"c3": "00836"} | {"c2": "6", "c6": "6", "c7": "6 ", "c8": "foo", "C 1": "836"} - Mon Feb 16 00:00:00 1970 | {"c3": "00846"} | {"c2": "6", "c6": "6", "c7": "6 ", "c8": "foo", "C 1": "846"} | Mon Feb 16 00:00:00 1970 | {"c3": "00846"} | {"c2": "6", "c6": "6", "c7": "6 ", "c8": "foo", "C 1": "846"} - Thu Feb 26 00:00:00 1970 | {"c3": "00856"} | {"c2": "6", "c6": "6", "c7": "6 ", "c8": "foo", "C 1": "856"} | Thu Feb 26 00:00:00 1970 | {"c3": "00856"} | {"c2": "6", "c6": "6", "c7": "6 ", "c8": "foo", "C 1": "856"} - Sun Mar 08 00:00:00 1970 | {"c3": "00866"} | {"c2": "6", "c6": "6", "c7": "6 ", "c8": "foo", "C 1": "866"} | Sun Mar 08 00:00:00 1970 | {"c3": "00866"} | {"c2": "6", "c6": "6", "c7": "6 ", "c8": "foo", "C 1": "866"} - Wed Mar 18 00:00:00 1970 | {"c3": "00876"} | {"c2": "6", "c6": "6", "c7": "6 ", "c8": "foo", "C 1": "876"} | Wed Mar 18 00:00:00 1970 | {"c3": "00876"} | {"c2": "6", "c6": "6", "c7": "6 ", "c8": "foo", "C 1": "876"} - Sat Mar 28 00:00:00 1970 | {"c3": "00886"} | {"c2": "6", "c6": "6", "c7": "6 ", "c8": "foo", "C 1": "886"} | Sat Mar 28 00:00:00 1970 | {"c3": "00886"} | {"c2": "6", "c6": "6", "c7": "6 ", "c8": "foo", "C 1": "886"} - Tue Apr 07 00:00:00 1970 | {"c3": "00896"} | {"c2": "6", "c6": "6", "c7": "6 ", "c8": "foo", "C 1": "896"} | Tue Apr 07 00:00:00 1970 | {"c3": "00896"} | {"c2": "6", "c6": "6", "c7": "6 ", "c8": "foo", "C 1": "896"} - Wed Jan 07 00:00:00 1970 | {"c3": "00906"} | {"c2": "6", "c6": "6", "c7": "6 ", "c8": "foo", "C 1": "906"} | Wed Jan 07 00:00:00 1970 | {"c3": "00906"} | {"c2": "6", "c6": "6", "c7": "6 ", "c8": "foo", "C 1": "906"} - Sat Jan 17 00:00:00 1970 | {"c3": "00916"} | {"c2": "6", "c6": "6", "c7": "6 ", "c8": "foo", "C 1": "916"} | Sat Jan 17 00:00:00 1970 | {"c3": "00916"} | {"c2": "6", "c6": "6", "c7": "6 ", "c8": "foo", "C 1": "916"} - Tue Jan 27 00:00:00 1970 | {"c3": "00926"} | {"c2": "6", "c6": "6", "c7": "6 ", "c8": "foo", "C 1": "926"} | Tue Jan 27 00:00:00 1970 | {"c3": "00926"} | {"c2": "6", "c6": "6", "c7": "6 ", "c8": "foo", "C 1": "926"} - Fri Feb 06 00:00:00 1970 | {"c3": "00936"} | {"c2": "6", "c6": "6", "c7": "6 ", "c8": "foo", "C 1": "936"} | Fri Feb 06 00:00:00 1970 | {"c3": "00936"} | {"c2": "6", "c6": "6", "c7": "6 ", "c8": "foo", "C 1": "936"} - Mon Feb 16 00:00:00 1970 | {"c3": "00946"} | {"c2": "6", "c6": "6", "c7": "6 ", "c8": "foo", "C 1": "946"} | Mon Feb 16 00:00:00 1970 | {"c3": "00946"} | {"c2": "6", "c6": "6", "c7": "6 ", "c8": "foo", "C 1": "946"} - Thu Feb 26 00:00:00 1970 | {"c3": "00956"} | {"c2": "6", "c6": "6", "c7": "6 ", "c8": "foo", "C 1": "956"} | Thu Feb 26 00:00:00 1970 | {"c3": "00956"} | {"c2": "6", "c6": "6", "c7": "6 ", "c8": "foo", "C 1": "956"} - Sun Mar 08 00:00:00 1970 | {"c3": "00966"} | {"c2": "6", "c6": "6", "c7": "6 ", "c8": "foo", "C 1": "966"} | Sun Mar 08 00:00:00 1970 | {"c3": "00966"} | {"c2": "6", "c6": "6", "c7": "6 ", "c8": "foo", "C 1": "966"} - Wed Mar 18 00:00:00 1970 | {"c3": "00976"} | {"c2": "6", "c6": "6", "c7": "6 ", "c8": "foo", "C 1": "976"} | Wed Mar 18 00:00:00 1970 | {"c3": "00976"} | {"c2": "6", "c6": "6", "c7": "6 ", "c8": "foo", "C 1": "976"} - Sat Mar 28 00:00:00 1970 | {"c3": "00986"} | {"c2": "6", "c6": "6", "c7": "6 ", "c8": "foo", "C 1": "986"} | Sat Mar 28 00:00:00 1970 | {"c3": "00986"} | {"c2": "6", "c6": "6", "c7": "6 ", "c8": "foo", "C 1": "986"} - Tue Apr 07 00:00:00 1970 | {"c3": "00996"} | {"c2": "6", "c6": "6", "c7": "6 ", "c8": "foo", "C 1": "996"} | Tue Apr 07 00:00:00 1970 | {"c3": "00996"} | {"c2": "6", "c6": "6", "c7": "6 ", "c8": "foo", "C 1": "996"} -(100 rows) - --- bug before 9.3.5 due to sloppy handling of remote-estimate parameters ---Testcase 74: -SELECT * FROM ft1 WHERE (fields->>'C 1')::int = ANY (ARRAY(SELECT (fields->>'C 1')::int FROM ft2 WHERE (fields->>'C 1')::int < 5)); - time | tags | fields ---------------------------+-----------------+--------------------------------------------------------------------- - Fri Jan 02 00:00:00 1970 | {"c3": "00001"} | {"c2": "1", "c6": "1", "c7": "1 ", "c8": "foo", "C 1": "1"} - Sat Jan 03 00:00:00 1970 | {"c3": "00002"} | {"c2": "2", "c6": "2", "c7": "2 ", "c8": "foo", "C 1": "2"} - Sun Jan 04 00:00:00 1970 | {"c3": "00003"} | {"c2": "3", "c6": "3", "c7": "3 ", "c8": "foo", "C 1": "3"} - Mon Jan 05 00:00:00 1970 | {"c3": "00004"} | {"c2": "4", "c6": "4", "c7": "4 ", "c8": "foo", "C 1": "4"} -(4 rows) - ---Testcase 75: -SELECT * FROM ft2 WHERE (fields->>'C 1')::int = ANY (ARRAY(SELECT (fields->>'C 1')::int FROM ft1 WHERE (fields->>'C 1')::int < 5)); - time | tags | fields ---------------------------+-----------------+--------------------------------------------------------------------- - Fri Jan 02 00:00:00 1970 | {"c3": "00001"} | {"c2": "1", "c6": "1", "c7": "1 ", "c8": "foo", "C 1": "1"} - Sat Jan 03 00:00:00 1970 | {"c3": "00002"} | {"c2": "2", "c6": "2", "c7": "2 ", "c8": "foo", "C 1": "2"} - Sun Jan 04 00:00:00 1970 | {"c3": "00003"} | {"c2": "3", "c6": "3", "c7": "3 ", "c8": "foo", "C 1": "3"} - Mon Jan 05 00:00:00 1970 | {"c3": "00004"} | {"c2": "4", "c6": "4", "c7": "4 ", "c8": "foo", "C 1": "4"} -(4 rows) - --- we should not push order by clause with volatile expressions or unsafe --- collations ---Testcase 76: -EXPLAIN (VERBOSE, COSTS OFF) - SELECT * FROM ft2 ORDER BY (ft2.fields->>'C 1')::int, random(); - QUERY PLAN -------------------------------------------------------------------------------------- - Sort - Output: "time", tags, fields, (((fields ->> 'C 1'::text))::integer), (random()) - Sort Key: (((ft2.fields ->> 'C 1'::text))::integer), (random()) - -> Foreign Scan on public.ft2 - Output: "time", tags, fields, ((fields ->> 'C 1'::text))::integer, random() - InfluxDB query: SELECT * FROM "T1" -(6 rows) - ---Testcase 77: -EXPLAIN (VERBOSE, COSTS OFF) - SELECT * FROM ft2 ORDER BY (ft2.fields->>'C 1')::int, ft2.tags->>'c3' collate "C"; - QUERY PLAN --------------------------------------------------------------------------------------------------------------- - Sort - Output: "time", tags, fields, (((fields ->> 'C 1'::text))::integer), ((tags ->> 'c3'::text COLLATE "C")) - Sort Key: (((ft2.fields ->> 'C 1'::text))::integer), ((ft2.tags ->> 'c3'::text COLLATE "C")) COLLATE "C" - -> Foreign Scan on public.ft2 - Output: "time", tags, fields, ((fields ->> 'C 1'::text))::integer, (tags ->> 'c3'::text COLLATE "C") - InfluxDB query: SELECT * FROM "T1" -(6 rows) - --- user-defined operator/function ---Testcase 78: -CREATE FUNCTION influxdb_fdw_abs(int) RETURNS int AS $$ -BEGIN -RETURN abs($1); -END -$$ LANGUAGE plpgsql IMMUTABLE; ---Testcase 79: -CREATE OPERATOR === ( - LEFTARG = int, - RIGHTARG = int, - PROCEDURE = int4eq, - COMMUTATOR = === -); --- built-in operators and functions can be shipped for remote execution ---Testcase 80: -EXPLAIN (VERBOSE, COSTS OFF) - SELECT count(tags->>'c3') FROM ft1 t1 WHERE (t1.fields->>'C 1')::int = abs((t1.fields->>'c2')::int); - QUERY PLAN ------------------------------------------------------------------------- - Aggregate - Output: count((tags ->> 'c3'::text)) - -> Foreign Scan on public.ft1 t1 - Output: "time", tags, fields - InfluxDB query: SELECT * FROM "T1" WHERE (("C 1" = abs("c2"))) -(5 rows) - ---Testcase 81: -SELECT count(tags->>'c3') FROM ft1 t1 WHERE (t1.fields->>'C 1')::int = abs((t1.fields->>'c2')::int); - count -------- - 9 -(1 row) - ---Testcase 82: -EXPLAIN (VERBOSE, COSTS OFF) - SELECT count(tags->>'c3') FROM ft1 t1 WHERE (t1.fields->>'C 1')::int = (t1.fields->>'c2')::int; - QUERY PLAN -------------------------------------------------------------------- - Aggregate - Output: count((tags ->> 'c3'::text)) - -> Foreign Scan on public.ft1 t1 - Output: "time", tags, fields - InfluxDB query: SELECT * FROM "T1" WHERE (("C 1" = "c2")) -(5 rows) - ---Testcase 83: -SELECT count(tags->>'c3') FROM ft1 t1 WHERE (t1.fields->>'C 1')::int = (t1.fields->>'c2')::int; - count -------- - 9 -(1 row) - --- by default, user-defined ones cannot ---Testcase 84: -EXPLAIN (VERBOSE, COSTS OFF) - SELECT count(tags->>'c3') FROM ft1 t1 WHERE (t1.fields->>'C 1')::int = influxdb_fdw_abs((t1.fields->>'c2')::int); - QUERY PLAN --------------------------------------------------------------------------------------------------------------------- - Aggregate - Output: count((tags ->> 'c3'::text)) - -> Foreign Scan on public.ft1 t1 - Output: "time", tags, fields - Filter: (((t1.fields ->> 'C 1'::text))::integer = influxdb_fdw_abs(((t1.fields ->> 'c2'::text))::integer)) - InfluxDB query: SELECT * FROM "T1" -(6 rows) - ---Testcase 85: -SELECT count(tags->>'c3') FROM ft1 t1 WHERE (t1.fields->>'C 1')::int = influxdb_fdw_abs((t1.fields->>'c2')::int); - count -------- - 9 -(1 row) - ---Testcase 86: -EXPLAIN (VERBOSE, COSTS OFF) - SELECT count(tags->>'c3') FROM ft1 t1 WHERE (t1.fields->>'C 1')::int === (t1.fields->>'c2')::int; - QUERY PLAN ----------------------------------------------------------------------------------------------------- - Aggregate - Output: count((tags ->> 'c3'::text)) - -> Foreign Scan on public.ft1 t1 - Output: "time", tags, fields - Filter: (((t1.fields ->> 'C 1'::text))::integer === ((t1.fields ->> 'c2'::text))::integer) - InfluxDB query: SELECT * FROM "T1" -(6 rows) - ---Testcase 87: -SELECT count(tags->>'c3') FROM ft1 t1 WHERE (t1.fields->>'C 1')::int === (t1.fields->>'c2')::int; - count -------- - 9 -(1 row) - --- ORDER BY can be shipped, though ---Testcase 88: -EXPLAIN (VERBOSE, COSTS OFF) - SELECT * FROM ft1 t1 WHERE (t1.fields->>'C 1')::int === (t1.fields->>'c2')::int order by (t1.fields->>'c2')::int limit 1; - QUERY PLAN ----------------------------------------------------------------------------------------------------------- - Limit - Output: "time", tags, fields, (((fields ->> 'c2'::text))::integer) - -> Sort - Output: "time", tags, fields, (((fields ->> 'c2'::text))::integer) - Sort Key: (((t1.fields ->> 'c2'::text))::integer) - -> Foreign Scan on public.ft1 t1 - Output: "time", tags, fields, ((fields ->> 'c2'::text))::integer - Filter: (((t1.fields ->> 'C 1'::text))::integer === ((t1.fields ->> 'c2'::text))::integer) - InfluxDB query: SELECT * FROM "T1" -(9 rows) - ---Testcase 89: -SELECT * FROM ft1 t1 WHERE (t1.fields->>'C 1')::int === (t1.fields->>'c2')::int order by (t1.fields->>'c2')::int limit 1; - time | tags | fields ---------------------------+-----------------+--------------------------------------------------------------------- - Fri Jan 02 00:00:00 1970 | {"c3": "00001"} | {"c2": "1", "c6": "1", "c7": "1 ", "c8": "foo", "C 1": "1"} -(1 row) - --- but let's put them in an extension ... -ALTER EXTENSION influxdb_fdw ADD FUNCTION influxdb_fdw_abs(int); -ALTER EXTENSION influxdb_fdw ADD OPERATOR === (int, int); --- ALTER SERVER loopback OPTIONS (ADD extensions 'influxdb_fdw'); --- ... now they can be shipped ---Testcase 90: -EXPLAIN (VERBOSE, COSTS OFF) - SELECT count(tags->>'c3') FROM ft1 t1 WHERE (t1.fields->>'C 1')::int = influxdb_fdw_abs((t1.fields->>'c2')::int); - QUERY PLAN --------------------------------------------------------------------------------------------------------------------- - Aggregate - Output: count((tags ->> 'c3'::text)) - -> Foreign Scan on public.ft1 t1 - Output: "time", tags, fields - Filter: (((t1.fields ->> 'C 1'::text))::integer = influxdb_fdw_abs(((t1.fields ->> 'c2'::text))::integer)) - InfluxDB query: SELECT * FROM "T1" -(6 rows) - ---Testcase 91: -SELECT count(tags->>'c3') FROM ft1 t1 WHERE (t1.fields->>'C 1')::int = influxdb_fdw_abs((t1.fields->>'c2')::int); - count -------- - 9 -(1 row) - ---Testcase 92: -EXPLAIN (VERBOSE, COSTS OFF) - SELECT count(tags->>'c3') FROM ft1 t1 WHERE (t1.fields->>'C 1')::int === (t1.fields->>'c2')::int; - QUERY PLAN ----------------------------------------------------------------------------------------------------- - Aggregate - Output: count((tags ->> 'c3'::text)) - -> Foreign Scan on public.ft1 t1 - Output: "time", tags, fields - Filter: (((t1.fields ->> 'C 1'::text))::integer === ((t1.fields ->> 'c2'::text))::integer) - InfluxDB query: SELECT * FROM "T1" -(6 rows) - ---Testcase 93: -SELECT count(tags->>'c3') FROM ft1 t1 WHERE (t1.fields->>'C 1')::int === (t1.fields->>'c2')::int; - count -------- - 9 -(1 row) - --- and both ORDER BY and LIMIT can be shipped ---Testcase 94: -EXPLAIN (VERBOSE, COSTS OFF) - SELECT * FROM ft1 t1 WHERE (t1.fields->>'C 1')::int === (t1.fields->>'c2')::int order by (t1.fields->>'c2')::int limit 1; - QUERY PLAN ----------------------------------------------------------------------------------------------------------- - Limit - Output: "time", tags, fields, (((fields ->> 'c2'::text))::integer) - -> Sort - Output: "time", tags, fields, (((fields ->> 'c2'::text))::integer) - Sort Key: (((t1.fields ->> 'c2'::text))::integer) - -> Foreign Scan on public.ft1 t1 - Output: "time", tags, fields, ((fields ->> 'c2'::text))::integer - Filter: (((t1.fields ->> 'C 1'::text))::integer === ((t1.fields ->> 'c2'::text))::integer) - InfluxDB query: SELECT * FROM "T1" -(9 rows) - ---Testcase 95: -SELECT * FROM ft1 t1 WHERE (t1.fields->>'C 1')::int === (t1.fields->>'c2')::int order by (t1.fields->>'c2')::int limit 1; - time | tags | fields ---------------------------+-----------------+--------------------------------------------------------------------- - Fri Jan 02 00:00:00 1970 | {"c3": "00001"} | {"c2": "1", "c6": "1", "c7": "1 ", "c8": "foo", "C 1": "1"} -(1 row) - --- This test case drop configuration when execute non-schemaless before -DROP TEXT SEARCH CONFIGURATION IF EXISTS public.custom_search; -NOTICE: text search configuration "public.custom_search" does not exist, skipping --- check schema-qualification of regconfig constant -CREATE TEXT SEARCH CONFIGURATION public.custom_search - (COPY = pg_catalog.english); -EXPLAIN (VERBOSE, COSTS OFF) -SELECT (fields->>'C 1')::int c1, to_tsvector('custom_search'::regconfig, tags->>'c3') FROM ft1 -WHERE (fields->>'C 1')::int = 642 AND length(to_tsvector('custom_search'::regconfig, tags->>'c3')) > 0; - QUERY PLAN ---------------------------------------------------------------------------------------------------------------- - Foreign Scan on public.ft1 - Output: ((fields ->> 'C 1'::text))::integer, to_tsvector('custom_search'::regconfig, (tags ->> 'c3'::text)) - Filter: (length(to_tsvector('custom_search'::regconfig, (ft1.tags ->> 'c3'::text))) > 0) - InfluxDB query: SELECT "C 1", "c3" FROM "T1" WHERE (("C 1" = 642)) -(4 rows) - -SELECT (fields->>'C 1')::int c1, to_tsvector('custom_search'::regconfig, tags->>'c3') FROM ft1 -WHERE (fields->>'C 1')::int = 642 AND length(to_tsvector('custom_search'::regconfig, tags->>'c3')) > 0; - c1 | to_tsvector ------+------------- - 642 | '00642':1 -(1 row) - --- =================================================================== --- JOIN queries --- =================================================================== --- join two tables ---Testcase 96: -EXPLAIN (VERBOSE, COSTS OFF) -SELECT t1.c1, t2.c1 FROM (SELECT (fields->>'C 1')::int c1, (fields->>'c2')::int c2, tags->>'c3' c3, fields->>'c4' c4, fields->>'c5' c5, fields->>'c6' c6, fields->>'c7' c7, fields->>'c8' c8 FROM ft1 t1) t1 JOIN (SELECT (fields->>'C 1')::int c1, (fields->>'c2')::int c2, tags->>'c3' c3, fields->>'c4' c4, fields->>'c5' c5, fields->>'c6' c6, fields->>'c7' c7, fields->>'c8' c8 FROM ft2 t2) t2 ON ((t1.c1)::int = (t2.c1)::int) ORDER BY t1.c3, (t1.c1)::int OFFSET 100 LIMIT 10; - QUERY PLAN ------------------------------------------------------------------------------------------------------------------------------------- - Limit - Output: (((t1.fields ->> 'C 1'::text))::integer), (((t2.fields ->> 'C 1'::text))::integer), ((t1.tags ->> 'c3'::text)) - -> Sort - Output: (((t1.fields ->> 'C 1'::text))::integer), (((t2.fields ->> 'C 1'::text))::integer), ((t1.tags ->> 'c3'::text)) - Sort Key: ((t1.tags ->> 'c3'::text)), (((t1.fields ->> 'C 1'::text))::integer) - -> Merge Join - Output: (((t1.fields ->> 'C 1'::text))::integer), (((t2.fields ->> 'C 1'::text))::integer), (t1.tags ->> 'c3'::text) - Merge Cond: ((((t1.fields ->> 'C 1'::text))::integer) = (((t2.fields ->> 'C 1'::text))::integer)) - -> Sort - Output: t1.fields, t1.tags, (((t1.fields ->> 'C 1'::text))::integer) - Sort Key: (((t1.fields ->> 'C 1'::text))::integer) - -> Foreign Scan on public.ft1 t1 - Output: t1.fields, t1.tags, ((t1.fields ->> 'C 1'::text))::integer - InfluxDB query: SELECT * FROM "T1" - -> Sort - Output: t2.fields, (((t2.fields ->> 'C 1'::text))::integer) - Sort Key: (((t2.fields ->> 'C 1'::text))::integer) - -> Foreign Scan on public.ft2 t2 - Output: t2.fields, ((t2.fields ->> 'C 1'::text))::integer - InfluxDB query: SELECT * FROM "T1" -(20 rows) - ---Testcase 97: -SELECT t1.c1, t2.c1 FROM (SELECT (fields->>'C 1')::int c1, (fields->>'c2')::int c2, tags->>'c3' c3, fields->>'c4' c4, fields->>'c5' c5, fields->>'c6' c6, fields->>'c7' c7, fields->>'c8' c8 FROM ft1 t1) t1 JOIN (SELECT (fields->>'C 1')::int c1, (fields->>'c2')::int c2, tags->>'c3' c3, fields->>'c4' c4, fields->>'c5' c5, fields->>'c6' c6, fields->>'c7' c7, fields->>'c8' c8 FROM ft2 t2) t2 ON ((t1.c1)::int = (t2.c1)::int) ORDER BY t1.c3, (t1.c1)::int OFFSET 100 LIMIT 10; - c1 | c1 ------+----- - 101 | 101 - 102 | 102 - 103 | 103 - 104 | 104 - 105 | 105 - 106 | 106 - 107 | 107 - 108 | 108 - 109 | 109 - 110 | 110 -(10 rows) - --- join three tables ---Testcase 98: -EXPLAIN (VERBOSE, COSTS OFF) -SELECT t1.c1, t2.c2, t3.c3 FROM (SELECT (fields->>'C 1')::int c1, (fields->>'c2')::int c2, tags->>'c3' c3, fields->>'c4' c4, fields->>'c5' c5, fields->>'c6' c6, fields->>'c7' c7, fields->>'c8' c8 FROM ft1 t1) t1 JOIN (SELECT (fields->>'C 1')::int c1, (fields->>'c2')::int c2, tags->>'c3' c3, fields->>'c4' c4, fields->>'c5' c5, fields->>'c6' c6, fields->>'c7' c7, fields->>'c8' c8 FROM ft2 t2) t2 ON ((t1.c1)::int = (t2.c1)::int) JOIN (SELECT (fields->>'c1')::int c1, (fields->>'c2')::int c2, tags->>'c3' c3 FROM ft4 t3) t3 ON ((t3.c1)::int = (t1.c1)::int) ORDER BY t1.c3, (t1.c1)::int OFFSET 10 LIMIT 10; - QUERY PLAN ------------------------------------------------------------------------------------------------------------------------------------------------------------ - Limit - Output: (((t1.fields ->> 'C 1'::text))::integer), (((t2.fields ->> 'c2'::text))::integer), ((t3.tags ->> 'c3'::text)), ((t1.tags ->> 'c3'::text)) - -> Sort - Output: (((t1.fields ->> 'C 1'::text))::integer), (((t2.fields ->> 'c2'::text))::integer), ((t3.tags ->> 'c3'::text)), ((t1.tags ->> 'c3'::text)) - Sort Key: ((t1.tags ->> 'c3'::text)), (((t1.fields ->> 'C 1'::text))::integer) - -> Merge Join - Output: ((t1.fields ->> 'C 1'::text))::integer, ((t2.fields ->> 'c2'::text))::integer, (t3.tags ->> 'c3'::text), (t1.tags ->> 'c3'::text) - Merge Cond: ((((t2.fields ->> 'C 1'::text))::integer) = ((t1.fields ->> 'C 1'::text))::integer) - -> Sort - Output: t2.fields, (((t2.fields ->> 'C 1'::text))::integer) - Sort Key: (((t2.fields ->> 'C 1'::text))::integer) - -> Foreign Scan on public.ft2 t2 - Output: t2.fields, ((t2.fields ->> 'C 1'::text))::integer - InfluxDB query: SELECT * FROM "T1" - -> Materialize - Output: t1.fields, t1.tags, t3.tags, t3.fields - -> Merge Join - Output: t1.fields, t1.tags, t3.tags, t3.fields - Merge Cond: ((((t1.fields ->> 'C 1'::text))::integer) = (((t3.fields ->> 'c1'::text))::integer)) - -> Sort - Output: t1.fields, t1.tags, (((t1.fields ->> 'C 1'::text))::integer) - Sort Key: (((t1.fields ->> 'C 1'::text))::integer) - -> Foreign Scan on public.ft1 t1 - Output: t1.fields, t1.tags, ((t1.fields ->> 'C 1'::text))::integer - InfluxDB query: SELECT * FROM "T1" - -> Sort - Output: t3.tags, t3.fields, (((t3.fields ->> 'c1'::text))::integer) - Sort Key: (((t3.fields ->> 'c1'::text))::integer) - -> Foreign Scan on public.ft4 t3 - Output: t3.tags, t3.fields, ((t3.fields ->> 'c1'::text))::integer - InfluxDB query: SELECT * FROM "T3" -(31 rows) - ---Testcase 99: -SELECT t1.c1, t2.c2, t3.c3 FROM (SELECT (fields->>'C 1')::int c1, (fields->>'c2')::int c2, tags->>'c3' c3, fields->>'c4' c4, fields->>'c5' c5, fields->>'c6' c6, fields->>'c7' c7, fields->>'c8' c8 FROM ft1 t1) t1 JOIN (SELECT (fields->>'C 1')::int c1, (fields->>'c2')::int c2, tags->>'c3' c3, fields->>'c4' c4, fields->>'c5' c5, fields->>'c6' c6, fields->>'c7' c7, fields->>'c8' c8 FROM ft2 t2) t2 ON ((t1.c1)::int = (t2.c1)::int) JOIN (SELECT (fields->>'c1')::int c1, (fields->>'c2')::int c2, tags->>'c3' c3 FROM ft4 t3) t3 ON ((t3.c1)::int = (t1.c1)::int) ORDER BY t1.c3, (t1.c1)::int OFFSET 10 LIMIT 10; - c1 | c2 | c3 -----+----+-------- - 22 | 2 | AAA022 - 24 | 4 | AAA024 - 26 | 6 | AAA026 - 28 | 8 | AAA028 - 30 | 0 | AAA030 - 32 | 2 | AAA032 - 34 | 4 | AAA034 - 36 | 6 | AAA036 - 38 | 8 | AAA038 - 40 | 0 | AAA040 -(10 rows) - --- left outer join ---Testcase 100: -EXPLAIN (VERBOSE, COSTS OFF) -SELECT t1.c1, t2.c1 FROM (SELECT (fields->>'c1')::int c1, (fields->>'c2')::int c2, tags->>'c3' c3 FROM ft4 t1) t1 LEFT JOIN (SELECT (fields->>'c1')::int c1, (fields->>'c2')::int c2, tags->>'c3' c3 FROM ft5 t2) t2 ON ((t1.c1)::int = (t2.c1)::int) ORDER BY (t1.c1)::int, (t2.c1)::int OFFSET 10 LIMIT 10; - QUERY PLAN ---------------------------------------------------------------------------------------------------------------- - Limit - Output: (((t1.fields ->> 'c1'::text))::integer), (((t2.fields ->> 'c1'::text))::integer) - -> Sort - Output: (((t1.fields ->> 'c1'::text))::integer), (((t2.fields ->> 'c1'::text))::integer) - Sort Key: (((t1.fields ->> 'c1'::text))::integer), (((t2.fields ->> 'c1'::text))::integer) - -> Merge Left Join - Output: (((t1.fields ->> 'c1'::text))::integer), ((t2.fields ->> 'c1'::text))::integer - Merge Cond: ((((t1.fields ->> 'c1'::text))::integer) = (((t2.fields ->> 'c1'::text))::integer)) - -> Sort - Output: t1.fields, (((t1.fields ->> 'c1'::text))::integer) - Sort Key: (((t1.fields ->> 'c1'::text))::integer) - -> Foreign Scan on public.ft4 t1 - Output: t1.fields, ((t1.fields ->> 'c1'::text))::integer - InfluxDB query: SELECT * FROM "T3" - -> Sort - Output: t2.fields, (((t2.fields ->> 'c1'::text))::integer) - Sort Key: (((t2.fields ->> 'c1'::text))::integer) - -> Foreign Scan on public.ft5 t2 - Output: t2.fields, ((t2.fields ->> 'c1'::text))::integer - InfluxDB query: SELECT * FROM "T4" -(20 rows) - ---Testcase 101: -SELECT t1.c1, t2.c1 FROM (SELECT (fields->>'c1')::int c1, (fields->>'c2')::int c2, tags->>'c3' c3 FROM ft4 t1) t1 LEFT JOIN (SELECT (fields->>'c1')::int c1, (fields->>'c2')::int c2, tags->>'c3' c3 FROM ft5 t2) t2 ON ((t1.c1)::int = (t2.c1)::int) ORDER BY (t1.c1)::int, (t2.c1)::int OFFSET 10 LIMIT 10; - c1 | c1 -----+---- - 22 | - 24 | 24 - 26 | - 28 | - 30 | 30 - 32 | - 34 | - 36 | 36 - 38 | - 40 | -(10 rows) - --- left outer join three tables ---Testcase 102: -EXPLAIN (VERBOSE, COSTS OFF) -SELECT t1.c1, t2.c2, t3.c3 FROM (SELECT (fields->>'C 1')::int c1, (fields->>'c2')::int c2, tags->>'c3' c3, fields->>'c4' c4, fields->>'c5' c5, fields->>'c6' c6, fields->>'c7' c7, fields->>'c8' c8 FROM ft2 t1) t1 LEFT JOIN (SELECT (fields->>'C 1')::int c1, (fields->>'c2')::int c2, tags->>'c3' c3, fields->>'c4' c4, fields->>'c5' c5, fields->>'c6' c6, fields->>'c7' c7, fields->>'c8' c8 FROM ft2 t2) t2 ON ((t1.c1)::int = (t2.c1)::int) LEFT JOIN (SELECT (fields->>'c1')::int c1, (fields->>'c2')::int c2, tags->>'c3' c3 FROM ft4 t3) t3 ON ((t2.c1)::int = (t3.c1)::int) OFFSET 10 LIMIT 10; - QUERY PLAN -------------------------------------------------------------------------------------------------------------------------- - Limit - Output: (((t1.fields ->> 'C 1'::text))::integer), (((t2.fields ->> 'c2'::text))::integer), ((t3.tags ->> 'c3'::text)) - -> Nested Loop Left Join - Output: ((t1.fields ->> 'C 1'::text))::integer, ((t2.fields ->> 'c2'::text))::integer, (t3.tags ->> 'c3'::text) - Join Filter: (((t2.fields ->> 'C 1'::text))::integer = ((t3.fields ->> 'c1'::text))::integer) - -> Nested Loop Left Join - Output: t1.fields, t2.fields - Join Filter: (((t1.fields ->> 'C 1'::text))::integer = ((t2.fields ->> 'C 1'::text))::integer) - -> Foreign Scan on public.ft2 t1 - Output: t1."time", t1.tags, t1.fields - InfluxDB query: SELECT * FROM "T1" - -> Materialize - Output: t2.fields - -> Foreign Scan on public.ft2 t2 - Output: t2.fields - InfluxDB query: SELECT * FROM "T1" - -> Materialize - Output: t3.tags, t3.fields - -> Foreign Scan on public.ft4 t3 - Output: t3.tags, t3.fields - InfluxDB query: SELECT * FROM "T3" -(21 rows) - ---Testcase 103: -SELECT t1.c1, t2.c2, t3.c3 FROM (SELECT (fields->>'C 1')::int c1, (fields->>'c2')::int c2, tags->>'c3' c3, fields->>'c4' c4, fields->>'c5' c5, fields->>'c6' c6, fields->>'c7' c7, fields->>'c8' c8 FROM ft2 t1) t1 LEFT JOIN (SELECT (fields->>'C 1')::int c1, (fields->>'c2')::int c2, tags->>'c3' c3, fields->>'c4' c4, fields->>'c5' c5, fields->>'c6' c6, fields->>'c7' c7, fields->>'c8' c8 FROM ft2 t2) t2 ON ((t1.c1)::int = (t2.c1)::int) LEFT JOIN (SELECT (fields->>'c1')::int c1, (fields->>'c2')::int c2, tags->>'c3' c3 FROM ft4 t3) t3 ON ((t2.c1)::int = (t3.c1)::int) ORDER BY (t1.c1)::int OFFSET 10 LIMIT 10; - c1 | c2 | c3 -----+----+-------- - 11 | 1 | - 12 | 2 | AAA012 - 13 | 3 | - 14 | 4 | AAA014 - 15 | 5 | - 16 | 6 | AAA016 - 17 | 7 | - 18 | 8 | AAA018 - 19 | 9 | - 20 | 0 | AAA020 -(10 rows) - --- left outer join + placement of clauses. --- clauses within the nullable side are not pulled up, but top level clause on --- non-nullable side is pushed into non-nullable side ---Testcase 104: -EXPLAIN (VERBOSE, COSTS OFF) -SELECT t1.c1, t1.c2, (t2.fields->>'c1')::int c1, (t2.fields->>'c2')::int c2 FROM (SELECT (fields->>'c1')::int c1, (fields->>'c2')::int c2, tags->>'c3' c3 FROM ft4 t1) t1 LEFT JOIN (SELECT * FROM ft5 t2 WHERE (fields->>'c1')::int < 10) t2 ON ((t1.c1)::int = (t2.fields->>'c1')::int) WHERE (t1.c1)::int < 10; - QUERY PLAN ------------------------------------------------------------------------------------------------------------------------------------------------------------------------- - Merge Left Join - Output: (((t1.fields ->> 'c1'::text))::integer), ((t1.fields ->> 'c2'::text))::integer, ((t2.fields ->> 'c1'::text))::integer, ((t2.fields ->> 'c2'::text))::integer - Merge Cond: ((((t1.fields ->> 'c1'::text))::integer) = (((t2.fields ->> 'c1'::text))::integer)) - -> Sort - Output: t1.fields, (((t1.fields ->> 'c1'::text))::integer) - Sort Key: (((t1.fields ->> 'c1'::text))::integer) - -> Foreign Scan on public.ft4 t1 - Output: t1.fields, ((t1.fields ->> 'c1'::text))::integer - InfluxDB query: SELECT * FROM "T3" WHERE (("c1" < 10)) - -> Sort - Output: t2.fields, (((t2.fields ->> 'c1'::text))::integer) - Sort Key: (((t2.fields ->> 'c1'::text))::integer) - -> Foreign Scan on public.ft5 t2 - Output: t2.fields, ((t2.fields ->> 'c1'::text))::integer - InfluxDB query: SELECT * FROM "T4" WHERE (("c1" < 10)) -(15 rows) - ---Testcase 105: -SELECT t1.c1, t1.c2, (t2.fields->>'c1')::int c1, (t2.fields->>'c2')::int c2 FROM (SELECT (fields->>'c1')::int c1, (fields->>'c2')::int c2, tags->>'c3' c3 FROM ft4 t1) t1 LEFT JOIN (SELECT * FROM ft5 t2 WHERE (fields->>'c1')::int < 10) t2 ON ((t1.c1)::int = (t2.fields->>'c1')::int) WHERE (t1.c1)::int < 10; - c1 | c2 | c1 | c2 -----+----+----+---- - 2 | 3 | | - 4 | 5 | | - 6 | 7 | 6 | 7 - 8 | 9 | | -(4 rows) - --- clauses within the nullable side are not pulled up, but the top level clause --- on nullable side is not pushed down into nullable side ---Testcase 106: -EXPLAIN (VERBOSE, COSTS OFF) -SELECT t1.c1, t1.c2, (t2.fields->>'c1')::int c1, (t2.fields->>'c2')::int c2 FROM (SELECT (fields->>'c1')::int c1, (fields->>'c2')::int c2, tags->>'c3' c3 FROM ft4 t1) t1 LEFT JOIN (SELECT * FROM ft5 t2 WHERE (fields->>'c1')::int < 10) t2 ON ((t1.c1)::int = (t2.fields->>'c1')::int) - WHERE ((t2.fields->>'c1')::int < 10 OR (t2.fields->>'c1')::int IS NULL) AND (t1.c1)::int < 10; - QUERY PLAN ------------------------------------------------------------------------------------------------------------------------------------------------------------------------- - Merge Left Join - Output: (((t1.fields ->> 'c1'::text))::integer), ((t1.fields ->> 'c2'::text))::integer, ((t2.fields ->> 'c1'::text))::integer, ((t2.fields ->> 'c2'::text))::integer - Merge Cond: ((((t1.fields ->> 'c1'::text))::integer) = (((t2.fields ->> 'c1'::text))::integer)) - Filter: ((((t2.fields ->> 'c1'::text))::integer < 10) OR (((t2.fields ->> 'c1'::text))::integer IS NULL)) - -> Sort - Output: t1.fields, (((t1.fields ->> 'c1'::text))::integer) - Sort Key: (((t1.fields ->> 'c1'::text))::integer) - -> Foreign Scan on public.ft4 t1 - Output: t1.fields, ((t1.fields ->> 'c1'::text))::integer - InfluxDB query: SELECT * FROM "T3" WHERE (("c1" < 10)) - -> Sort - Output: t2.fields, (((t2.fields ->> 'c1'::text))::integer) - Sort Key: (((t2.fields ->> 'c1'::text))::integer) - -> Foreign Scan on public.ft5 t2 - Output: t2.fields, ((t2.fields ->> 'c1'::text))::integer - InfluxDB query: SELECT * FROM "T4" WHERE (("c1" < 10)) -(16 rows) - ---Testcase 107: -SELECT t1.c1, t1.c2, (t2.fields->>'c1')::int c1, (t2.fields->>'c2')::int c2 FROM (SELECT (fields->>'c1')::int c1, (fields->>'c2')::int c2, tags->>'c3' c3 FROM ft4 t1) t1 LEFT JOIN (SELECT * FROM ft5 t2 WHERE (fields->>'c1')::int < 10) t2 ON ((t1.c1)::int = (t2.fields->>'c1')::int) - WHERE ((t2.fields->>'c1')::int < 10 OR (t2.fields->>'c1')::int IS NULL) AND (t1.c1)::int < 10; - c1 | c2 | c1 | c2 -----+----+----+---- - 2 | 3 | | - 4 | 5 | | - 6 | 7 | 6 | 7 - 8 | 9 | | -(4 rows) - --- right outer join ---Testcase 108: -EXPLAIN (VERBOSE, COSTS OFF) -SELECT t1.c1, t2.c1 FROM (SELECT (fields->>'c1')::int c1, (fields->>'c2')::int c2, tags->>'c3' c3 FROM ft5 t1) t1 RIGHT JOIN (SELECT (fields->>'c1')::int c1, (fields->>'c2')::int c2, tags->>'c3' c3 FROM ft4 t2) t2 ON ((t1.c1)::int = (t2.c1)::int) ORDER BY (t2.c1)::int, (t1.c1)::int OFFSET 10 LIMIT 10; - QUERY PLAN ---------------------------------------------------------------------------------------------------------------- - Limit - Output: (((t1.fields ->> 'c1'::text))::integer), (((t2.fields ->> 'c1'::text))::integer) - -> Sort - Output: (((t1.fields ->> 'c1'::text))::integer), (((t2.fields ->> 'c1'::text))::integer) - Sort Key: (((t2.fields ->> 'c1'::text))::integer), (((t1.fields ->> 'c1'::text))::integer) - -> Merge Left Join - Output: ((t1.fields ->> 'c1'::text))::integer, (((t2.fields ->> 'c1'::text))::integer) - Merge Cond: ((((t2.fields ->> 'c1'::text))::integer) = (((t1.fields ->> 'c1'::text))::integer)) - -> Sort - Output: t2.fields, (((t2.fields ->> 'c1'::text))::integer) - Sort Key: (((t2.fields ->> 'c1'::text))::integer) - -> Foreign Scan on public.ft4 t2 - Output: t2.fields, ((t2.fields ->> 'c1'::text))::integer - InfluxDB query: SELECT * FROM "T3" - -> Sort - Output: t1.fields, (((t1.fields ->> 'c1'::text))::integer) - Sort Key: (((t1.fields ->> 'c1'::text))::integer) - -> Foreign Scan on public.ft5 t1 - Output: t1.fields, ((t1.fields ->> 'c1'::text))::integer - InfluxDB query: SELECT * FROM "T4" -(20 rows) - ---Testcase 109: -SELECT t1.c1, t2.c1 FROM (SELECT (fields->>'c1')::int c1, (fields->>'c2')::int c2, tags->>'c3' c3 FROM ft5 t1) t1 RIGHT JOIN (SELECT (fields->>'c1')::int c1, (fields->>'c2')::int c2, tags->>'c3' c3 FROM ft4 t2) t2 ON ((t1.c1)::int = (t2.c1)::int) ORDER BY (t2.c1)::int, (t1.c1)::int OFFSET 10 LIMIT 10; - c1 | c1 -----+---- - | 22 - 24 | 24 - | 26 - | 28 - 30 | 30 - | 32 - | 34 - 36 | 36 - | 38 - | 40 -(10 rows) - --- right outer join three tables ---Testcase 110: -EXPLAIN (VERBOSE, COSTS OFF) -SELECT t1.c1, t2.c2, t3.c3 FROM (SELECT (fields->>'C 1')::int c1, (fields->>'c2')::int c2, tags->>'c3' c3, fields->>'c4' c4, fields->>'c5' c5, fields->>'c6' c6, fields->>'c7' c7, fields->>'c8' c8 FROM ft2 t1) t1 RIGHT JOIN (SELECT (fields->>'C 1')::int c1, (fields->>'c2')::int c2, tags->>'c3' c3, fields->>'c4' c4, fields->>'c5' c5, fields->>'c6' c6, fields->>'c7' c7, fields->>'c8' c8 FROM ft2 t2) t2 ON ((t1.c1)::int = (t2.c1)::int) RIGHT JOIN (SELECT (fields->>'c1')::int c1, (fields->>'c2')::int c2, tags->>'c3' c3 FROM ft4 t3) t3 ON ((t2.c1)::int = (t3.c1)::int) OFFSET 10 LIMIT 10; - QUERY PLAN -------------------------------------------------------------------------------------------------------------------------- - Limit - Output: (((t1.fields ->> 'C 1'::text))::integer), (((t2.fields ->> 'c2'::text))::integer), ((t3.tags ->> 'c3'::text)) - -> Nested Loop Left Join - Output: ((t1.fields ->> 'C 1'::text))::integer, ((t2.fields ->> 'c2'::text))::integer, (t3.tags ->> 'c3'::text) - Join Filter: (((t1.fields ->> 'C 1'::text))::integer = ((t2.fields ->> 'C 1'::text))::integer) - -> Nested Loop Left Join - Output: t3.tags, t2.fields - Join Filter: (((t2.fields ->> 'C 1'::text))::integer = ((t3.fields ->> 'c1'::text))::integer) - -> Foreign Scan on public.ft4 t3 - Output: t3.tags, t3.fields - InfluxDB query: SELECT * FROM "T3" - -> Materialize - Output: t2.fields - -> Foreign Scan on public.ft2 t2 - Output: t2.fields - InfluxDB query: SELECT * FROM "T1" - -> Materialize - Output: t1.fields - -> Foreign Scan on public.ft2 t1 - Output: t1.fields - InfluxDB query: SELECT * FROM "T1" -(21 rows) - ---Testcase 111: -SELECT t1.c1, t2.c2, t3.c3 FROM (SELECT (fields->>'C 1')::int c1, (fields->>'c2')::int c2, tags->>'c3' c3, fields->>'c4' c4, fields->>'c5' c5, fields->>'c6' c6, fields->>'c7' c7, fields->>'c8' c8 FROM ft2 t1) t1 RIGHT JOIN (SELECT (fields->>'C 1')::int c1, (fields->>'c2')::int c2, tags->>'c3' c3, fields->>'c4' c4, fields->>'c5' c5, fields->>'c6' c6, fields->>'c7' c7, fields->>'c8' c8 FROM ft2 t2) t2 ON ((t1.c1)::int = (t2.c1)::int) RIGHT JOIN (SELECT (fields->>'c1')::int c1, (fields->>'c2')::int c2, tags->>'c3' c3 FROM ft4 t3) t3 ON ((t2.c1)::int = (t3.c1)::int) OFFSET 10 LIMIT 10; - c1 | c2 | c3 -----+----+-------- - 22 | 2 | AAA022 - 24 | 4 | AAA024 - 26 | 6 | AAA026 - 28 | 8 | AAA028 - 30 | 0 | AAA030 - 32 | 2 | AAA032 - 34 | 4 | AAA034 - 36 | 6 | AAA036 - 38 | 8 | AAA038 - 40 | 0 | AAA040 -(10 rows) - --- full outer join ---Testcase 112: -EXPLAIN (VERBOSE, COSTS OFF) -SELECT t1.c1, t2.c1 FROM (SELECT (fields->>'c1')::int c1, (fields->>'c2')::int c2, tags->>'c3' c3 FROM ft4 t1) t1 FULL JOIN (SELECT (fields->>'c1')::int c1, (fields->>'c2')::int c2, tags->>'c3' c3 FROM ft5 t2) t2 ON ((t1.c1)::int = (t2.c1)::int) ORDER BY (t1.c1)::int, (t2.c1)::int OFFSET 45 LIMIT 10; - QUERY PLAN ---------------------------------------------------------------------------------------------------------------- - Limit - Output: (((t1.fields ->> 'c1'::text))::integer), (((t2.fields ->> 'c1'::text))::integer) - -> Sort - Output: (((t1.fields ->> 'c1'::text))::integer), (((t2.fields ->> 'c1'::text))::integer) - Sort Key: (((t1.fields ->> 'c1'::text))::integer), (((t2.fields ->> 'c1'::text))::integer) - -> Merge Full Join - Output: ((t1.fields ->> 'c1'::text))::integer, ((t2.fields ->> 'c1'::text))::integer - Merge Cond: ((((t1.fields ->> 'c1'::text))::integer) = (((t2.fields ->> 'c1'::text))::integer)) - -> Sort - Output: t1.fields, (((t1.fields ->> 'c1'::text))::integer) - Sort Key: (((t1.fields ->> 'c1'::text))::integer) - -> Foreign Scan on public.ft4 t1 - Output: t1.fields, ((t1.fields ->> 'c1'::text))::integer - InfluxDB query: SELECT * FROM "T3" - -> Sort - Output: t2.fields, (((t2.fields ->> 'c1'::text))::integer) - Sort Key: (((t2.fields ->> 'c1'::text))::integer) - -> Foreign Scan on public.ft5 t2 - Output: t2.fields, ((t2.fields ->> 'c1'::text))::integer - InfluxDB query: SELECT * FROM "T4" -(20 rows) - ---Testcase 113: -SELECT t1.c1, t2.c1 FROM (SELECT (fields->>'c1')::int c1, (fields->>'c2')::int c2, tags->>'c3' c3 FROM ft4 t1) t1 FULL JOIN (SELECT (fields->>'c1')::int c1, (fields->>'c2')::int c2, tags->>'c3' c3 FROM ft5 t2) t2 ON ((t1.c1)::int = (t2.c1)::int) ORDER BY (t1.c1)::int, (t2.c1)::int OFFSET 45 LIMIT 10; - c1 | c1 ------+---- - 92 | - 94 | - 96 | 96 - 98 | - 100 | - | 3 - | 9 - | 15 - | 21 - | 27 -(10 rows) - --- full outer join with restrictions on the joining relations --- a. the joining relations are both base relations ---Testcase 114: -EXPLAIN (VERBOSE, COSTS OFF) -SELECT t1.c1, t2.c1 FROM (SELECT (fields->>'c1')::int c1 FROM ft4 t1 WHERE (fields->>'c1')::int between 50 and 60) t1 FULL JOIN (SELECT (fields->>'c1')::int c1 FROM ft5 t2 WHERE (fields->>'c1')::int between 50 and 60) t2 ON ((t1.c1)::int = (t2.c1)::int) ORDER BY (t1.c1)::int, (t2.c1)::int; - QUERY PLAN ----------------------------------------------------------------------------------------------------- - Sort - Output: (((t1.fields ->> 'c1'::text))::integer), (((t2.fields ->> 'c1'::text))::integer) - Sort Key: (((t1.fields ->> 'c1'::text))::integer), (((t2.fields ->> 'c1'::text))::integer) - -> Hash Full Join - Output: ((t1.fields ->> 'c1'::text))::integer, ((t2.fields ->> 'c1'::text))::integer - Hash Cond: (((t1.fields ->> 'c1'::text))::integer = ((t2.fields ->> 'c1'::text))::integer) - -> Foreign Scan on public.ft4 t1 - Output: t1.tags, t1.fields - InfluxDB query: SELECT * FROM "T3" WHERE (("c1" >= 50)) AND (("c1" <= 60)) - -> Hash - Output: t2.fields - -> Foreign Scan on public.ft5 t2 - Output: t2.fields - InfluxDB query: SELECT * FROM "T4" WHERE (("c1" >= 50)) AND (("c1" <= 60)) -(14 rows) - ---Testcase 115: -SELECT t1.c1, t2.c1 FROM (SELECT (fields->>'c1')::int c1 FROM ft4 t1 WHERE (fields->>'c1')::int between 50 and 60) t1 FULL JOIN (SELECT (fields->>'c1')::int c1 FROM ft5 t2 WHERE (fields->>'c1')::int between 50 and 60) t2 ON ((t1.c1)::int = (t2.c1)::int) ORDER BY (t1.c1)::int, (t2.c1)::int; - c1 | c1 -----+---- - 50 | - 52 | - 54 | 54 - 56 | - 58 | - 60 | 60 - | 51 - | 57 -(8 rows) - ---Testcase 116: -EXPLAIN (VERBOSE, COSTS OFF) -SELECT 1 FROM (SELECT (fields->>'c1')::int c1 FROM ft4 t1 WHERE (fields->>'c1')::int between 50 and 60) t1 FULL JOIN (SELECT (fields->>'c1')::int c1 FROM ft5 t2 WHERE (fields->>'c1')::int between 50 and 60) t2 ON (TRUE) OFFSET 10 LIMIT 10; - QUERY PLAN ------------------------------------------------------------------------------------------------- - Limit - Output: 1 - -> Merge Full Join - Output: 1 - -> Foreign Scan on public.ft4 t1 - Output: t1.tags, t1.fields - InfluxDB query: SELECT * FROM "T3" WHERE (("c1" >= 50)) AND (("c1" <= 60)) - -> Materialize - Output: t2.tags, t2.fields - -> Foreign Scan on public.ft5 t2 - Output: t2.tags, t2.fields - InfluxDB query: SELECT * FROM "T4" WHERE (("c1" >= 50)) AND (("c1" <= 60)) -(12 rows) - ---Testcase 117: -SELECT 1 FROM (SELECT (fields->>'c1')::int c1 FROM ft4 t1 WHERE (fields->>'c1')::int between 50 and 60) t1 FULL JOIN (SELECT (fields->>'c1')::int c1 FROM ft5 t2 WHERE (fields->>'c1')::int between 50 and 60) t2 ON (TRUE) OFFSET 10 LIMIT 10; - ?column? ----------- - 1 - 1 - 1 - 1 - 1 - 1 - 1 - 1 - 1 - 1 -(10 rows) - --- b. one of the joining relations is a base relation and the other is a join --- relation ---Testcase 118: -EXPLAIN (VERBOSE, COSTS OFF) -SELECT t1.c1, ss.a, ss.b FROM (SELECT (fields->>'c1')::int c1 FROM ft4 t1 WHERE (fields->>'c1')::int between 50 and 60) t1 FULL JOIN (SELECT (t2.c1)::int, (t3.c1)::int FROM (SELECT (fields->>'c1')::int c1, (fields->>'c2')::int c2, tags->>'c3' c3 FROM ft4 t2) t2 LEFT JOIN (SELECT fields->>'c1' c1, fields->>'c2' c2, tags->>'c3' c3 FROM ft5) t3 ON ((t2.c1)::int = (t3.c1)::int) WHERE ((t2.c1)::int between 50 and 60)) ss(a, b) ON ((t1.c1)::int = ss.a) ORDER BY (t1.c1)::int, ss.a, ss.b; - QUERY PLAN ----------------------------------------------------------------------------------------------------------------------------------------- - Sort - Output: (((t1.fields ->> 'c1'::text))::integer), (((t2.fields ->> 'c1'::text))::integer), (((ft5.fields ->> 'c1'::text))::integer) - Sort Key: (((t1.fields ->> 'c1'::text))::integer), (((t2.fields ->> 'c1'::text))::integer), (((ft5.fields ->> 'c1'::text))::integer) - -> Hash Full Join - Output: ((t1.fields ->> 'c1'::text))::integer, ((t2.fields ->> 'c1'::text))::integer, ((ft5.fields ->> 'c1'::text))::integer - Hash Cond: (((t2.fields ->> 'c1'::text))::integer = ((t1.fields ->> 'c1'::text))::integer) - -> Hash Right Join - Output: t2.fields, ft5.fields - Hash Cond: (((ft5.fields ->> 'c1'::text))::integer = ((t2.fields ->> 'c1'::text))::integer) - -> Foreign Scan on public.ft5 - Output: ft5.tags, ft5.fields - InfluxDB query: SELECT * FROM "T4" - -> Hash - Output: t2.fields - -> Foreign Scan on public.ft4 t2 - Output: t2.fields - InfluxDB query: SELECT * FROM "T3" WHERE (("c1" >= 50)) AND (("c1" <= 60)) - -> Hash - Output: t1.fields - -> Foreign Scan on public.ft4 t1 - Output: t1.fields - InfluxDB query: SELECT * FROM "T3" WHERE (("c1" >= 50)) AND (("c1" <= 60)) -(22 rows) - ---Testcase 119: -SELECT t1.c1, ss.a, ss.b FROM (SELECT (fields->>'c1')::int c1 FROM ft4 t1 WHERE (fields->>'c1')::int between 50 and 60) t1 FULL JOIN (SELECT (t2.c1)::int, (t3.c1)::int FROM (SELECT (fields->>'c1')::int c1, (fields->>'c2')::int c2, tags->>'c3' c3 FROM ft4 t2) t2 LEFT JOIN (SELECT fields->>'c1' c1, fields->>'c2' c2, tags->>'c3' c3 FROM ft5) t3 ON ((t2.c1)::int = (t3.c1)::int) WHERE ((t2.c1)::int between 50 and 60)) ss(a, b) ON ((t1.c1)::int = ss.a) ORDER BY (t1.c1)::int, ss.a, ss.b; - c1 | a | b -----+----+---- - 50 | 50 | - 52 | 52 | - 54 | 54 | 54 - 56 | 56 | - 58 | 58 | - 60 | 60 | 60 -(6 rows) - --- c. test deparsing the remote query as nested subqueries ---Testcase 120: -EXPLAIN (VERBOSE, COSTS OFF) -SELECT t1.c1, ss.a, ss.b FROM (SELECT (fields->>'c1')::int c1 FROM ft4 t1 WHERE (fields->>'c1')::int between 50 and 60) t1 FULL JOIN (SELECT (t2.c1)::int, (t3.c1)::int FROM (SELECT (fields->>'c1')::int c1 FROM ft4 t2 WHERE (fields->>'c1')::int between 50 and 60) t2 FULL JOIN (SELECT (fields->>'c1')::int c1 FROM ft5 t3 WHERE (fields->>'c1')::int between 50 and 60) t3 ON ((t2.c1)::int = (t3.c1)::int) WHERE (t2.c1)::int IS NULL OR (t2.c1)::int IS NOT NULL) ss(a, b) ON ((t1.c1)::int = ss.a) ORDER BY (t1.c1)::int, ss.a, ss.b; - QUERY PLAN ---------------------------------------------------------------------------------------------------------------------------------------- - Sort - Output: (((t1.fields ->> 'c1'::text))::integer), (((t2.fields ->> 'c1'::text))::integer), (((t3.fields ->> 'c1'::text))::integer) - Sort Key: (((t1.fields ->> 'c1'::text))::integer), (((t2.fields ->> 'c1'::text))::integer), (((t3.fields ->> 'c1'::text))::integer) - -> Hash Full Join - Output: ((t1.fields ->> 'c1'::text))::integer, ((t2.fields ->> 'c1'::text))::integer, ((t3.fields ->> 'c1'::text))::integer - Hash Cond: (((t2.fields ->> 'c1'::text))::integer = ((t1.fields ->> 'c1'::text))::integer) - -> Hash Full Join - Output: t2.fields, t3.fields - Hash Cond: (((t2.fields ->> 'c1'::text))::integer = ((t3.fields ->> 'c1'::text))::integer) - Filter: ((((t2.fields ->> 'c1'::text))::integer IS NULL) OR (((t2.fields ->> 'c1'::text))::integer IS NOT NULL)) - -> Foreign Scan on public.ft4 t2 - Output: t2.tags, t2.fields - InfluxDB query: SELECT * FROM "T3" WHERE (("c1" >= 50)) AND (("c1" <= 60)) - -> Hash - Output: t3.fields - -> Foreign Scan on public.ft5 t3 - Output: t3.fields - InfluxDB query: SELECT * FROM "T4" WHERE (("c1" >= 50)) AND (("c1" <= 60)) - -> Hash - Output: t1.fields - -> Foreign Scan on public.ft4 t1 - Output: t1.fields - InfluxDB query: SELECT * FROM "T3" WHERE (("c1" >= 50)) AND (("c1" <= 60)) -(23 rows) - ---Testcase 121: -SELECT t1.c1, ss.a, ss.b FROM (SELECT (fields->>'c1')::int c1 FROM ft4 t1 WHERE (fields->>'c1')::int between 50 and 60) t1 FULL JOIN (SELECT (t2.c1)::int, (t3.c1)::int FROM (SELECT (fields->>'c1')::int c1 FROM ft4 t2 WHERE (fields->>'c1')::int between 50 and 60) t2 FULL JOIN (SELECT (fields->>'c1')::int c1 FROM ft5 t3 WHERE (fields->>'c1')::int between 50 and 60) t3 ON ((t2.c1)::int = (t3.c1)::int) WHERE (t2.c1)::int IS NULL OR (t2.c1)::int IS NOT NULL) ss(a, b) ON ((t1.c1)::int = ss.a) ORDER BY (t1.c1)::int, ss.a, ss.b; - c1 | a | b -----+----+---- - 50 | 50 | - 52 | 52 | - 54 | 54 | 54 - 56 | 56 | - 58 | 58 | - 60 | 60 | 60 - | | 51 - | | 57 -(8 rows) - --- d. test deparsing rowmarked relations as subqueries ---Testcase 122: -EXPLAIN (VERBOSE, COSTS OFF) -SELECT t1.c1, ss.a, ss.b FROM (SELECT (fields->>'c1')::int c1 FROM "S 1"."T 3" t1 WHERE (fields->>'c1')::int = 50) t1 INNER JOIN (SELECT (t2.c1)::int, (t3.c1)::int FROM (SELECT (fields->>'c1')::int c1 FROM ft4 t2 WHERE (fields->>'c1')::int between 50 and 60) t2 FULL JOIN (SELECT (fields->>'c1')::int c1 FROM ft5 t3 WHERE (fields->>'c1')::int between 50 and 60) t3 ON ((t2.c1)::int = (t3.c1)::int) WHERE (t2.c1)::int IS NULL OR (t2.c1)::int IS NOT NULL) ss(a, b) ON (TRUE) ORDER BY (t1.c1)::int, ss.a, ss.b FOR UPDATE OF t1; - QUERY PLAN -------------------------------------------------------------------------------------------------------------------------------------------------------------- - LockRows - Output: (((t1.fields ->> 'c1'::text))::integer), (((t2.fields ->> 'c1'::text))::integer), (((t3.fields ->> 'c1'::text))::integer), t1.*, t2.*, t3.* - -> Sort - Output: (((t1.fields ->> 'c1'::text))::integer), (((t2.fields ->> 'c1'::text))::integer), (((t3.fields ->> 'c1'::text))::integer), t1.*, t2.*, t3.* - Sort Key: (((t2.fields ->> 'c1'::text))::integer), (((t3.fields ->> 'c1'::text))::integer) - -> Nested Loop - Output: ((t1.fields ->> 'c1'::text))::integer, ((t2.fields ->> 'c1'::text))::integer, ((t3.fields ->> 'c1'::text))::integer, t1.*, t2.*, t3.* - -> Foreign Scan on "S 1"."T 3" t1 - Output: t1.fields, t1.* - InfluxDB query: SELECT * FROM "T3" WHERE (("c1" = 50)) - -> Hash Full Join - Output: t2.fields, t2.*, t3.fields, t3.* - Hash Cond: (((t2.fields ->> 'c1'::text))::integer = ((t3.fields ->> 'c1'::text))::integer) - Filter: ((((t2.fields ->> 'c1'::text))::integer IS NULL) OR (((t2.fields ->> 'c1'::text))::integer IS NOT NULL)) - -> Foreign Scan on public.ft4 t2 - Output: t2.fields, t2.* - InfluxDB query: SELECT * FROM "T3" WHERE (("c1" >= 50)) AND (("c1" <= 60)) - -> Hash - Output: t3.fields, t3.* - -> Foreign Scan on public.ft5 t3 - Output: t3.fields, t3.* - InfluxDB query: SELECT * FROM "T4" WHERE (("c1" >= 50)) AND (("c1" <= 60)) -(22 rows) - ---Testcase 123: -SELECT t1.c1, ss.a, ss.b FROM (SELECT (fields->>'c1')::int c1 FROM "S 1"."T 3" t1 WHERE (fields->>'c1')::int = 50) t1 INNER JOIN (SELECT (t2.c1)::int, (t3.c1)::int FROM (SELECT (fields->>'c1')::int c1 FROM ft4 t2 WHERE (fields->>'c1')::int between 50 and 60) t2 FULL JOIN (SELECT (fields->>'c1')::int c1 FROM ft5 t3 WHERE (fields->>'c1')::int between 50 and 60) t3 ON ((t2.c1)::int = (t3.c1)::int) WHERE (t2.c1)::int IS NULL OR (t2.c1)::int IS NOT NULL) ss(a, b) ON (TRUE) ORDER BY (t1.c1)::int, ss.a, ss.b FOR UPDATE OF t1; - c1 | a | b -----+----+---- - 50 | 50 | - 50 | 52 | - 50 | 54 | 54 - 50 | 56 | - 50 | 58 | - 50 | 60 | 60 - 50 | | 51 - 50 | | 57 -(8 rows) - --- full outer join + inner join ---Testcase 124: -EXPLAIN (VERBOSE, COSTS OFF) -SELECT t1.c1, t2.c1, t3.c1 FROM (SELECT (fields->>'c1')::int c1, (fields->>'c2')::int c2, tags->>'c3' c3 FROM ft4 t1) t1 INNER JOIN (SELECT (fields->>'c1')::int c1, (fields->>'c2')::int c2, tags->>'c3' c3 FROM ft5 t2) t2 ON ((t1.c1)::int = (t2.c1)::int + 1 and (t1.c1)::int between 50 and 60) FULL JOIN (SELECT (fields->>'c1')::int c1, (fields->>'c2')::int c2, tags->>'c3' c3 FROM ft4 t3) t3 ON ((t2.c1)::int = (t3.c1)::int) ORDER BY (t1.c1)::int, (t2.c1)::int, (t3.c1)::int LIMIT 10; - QUERY PLAN ---------------------------------------------------------------------------------------------------------------------------------------------- - Limit - Output: (((t1.fields ->> 'c1'::text))::integer), (((t2.fields ->> 'c1'::text))::integer), (((t3.fields ->> 'c1'::text))::integer) - -> Sort - Output: (((t1.fields ->> 'c1'::text))::integer), (((t2.fields ->> 'c1'::text))::integer), (((t3.fields ->> 'c1'::text))::integer) - Sort Key: (((t1.fields ->> 'c1'::text))::integer), (((t2.fields ->> 'c1'::text))::integer), (((t3.fields ->> 'c1'::text))::integer) - -> Hash Full Join - Output: ((t1.fields ->> 'c1'::text))::integer, ((t2.fields ->> 'c1'::text))::integer, ((t3.fields ->> 'c1'::text))::integer - Hash Cond: (((t2.fields ->> 'c1'::text))::integer = ((t3.fields ->> 'c1'::text))::integer) - -> Hash Join - Output: t1.fields, t2.fields - Hash Cond: ((((t2.fields ->> 'c1'::text))::integer + 1) = ((t1.fields ->> 'c1'::text))::integer) - -> Foreign Scan on public.ft5 t2 - Output: t2.tags, t2.fields - InfluxDB query: SELECT * FROM "T4" - -> Hash - Output: t1.fields - -> Foreign Scan on public.ft4 t1 - Output: t1.fields - InfluxDB query: SELECT * FROM "T3" WHERE (("c1" >= 50)) AND (("c1" <= 60)) - -> Hash - Output: t3.fields - -> Foreign Scan on public.ft4 t3 - Output: t3.fields - InfluxDB query: SELECT * FROM "T3" -(24 rows) - ---Testcase 125: -SELECT t1.c1, t2.c1, t3.c1 FROM (SELECT (fields->>'c1')::int c1, (fields->>'c2')::int c2, tags->>'c3' c3 FROM ft4 t1) t1 INNER JOIN (SELECT (fields->>'c1')::int c1, (fields->>'c2')::int c2, tags->>'c3' c3 FROM ft5 t2) t2 ON ((t1.c1)::int = (t2.c1)::int + 1 and (t1.c1)::int between 50 and 60) FULL JOIN (SELECT (fields->>'c1')::int c1, (fields->>'c2')::int c2, tags->>'c3' c3 FROM ft4 t3) t3 ON ((t2.c1)::int = (t3.c1)::int) ORDER BY (t1.c1)::int, (t2.c1)::int, (t3.c1)::int LIMIT 10; - c1 | c1 | c1 -----+----+---- - 52 | 51 | - 58 | 57 | - | | 2 - | | 4 - | | 6 - | | 8 - | | 10 - | | 12 - | | 14 - | | 16 -(10 rows) - --- full outer join three tables ---Testcase 126: -EXPLAIN (VERBOSE, COSTS OFF) -SELECT t1.c1, t2.c2, t3.c3 FROM (SELECT (fields->>'C 1')::int c1, (fields->>'c2')::int c2, tags->>'c3' c3, fields->>'c4' c4, fields->>'c5' c5, fields->>'c6' c6, fields->>'c7' c7, fields->>'c8' c8 FROM ft2 t1) t1 FULL JOIN (SELECT (fields->>'C 1')::int c1, (fields->>'c2')::int c2, tags->>'c3' c3, fields->>'c4' c4, fields->>'c5' c5, fields->>'c6' c6, fields->>'c7' c7, fields->>'c8' c8 FROM ft2 t2) t2 ON ((t1.c1)::int = (t2.c1)::int) FULL JOIN (SELECT (fields->>'c1')::int c1, (fields->>'c2')::int c2, tags->>'c3' c3 FROM ft4 t3) t3 ON ((t2.c1)::int = (t3.c1)::int) OFFSET 10 LIMIT 10; - QUERY PLAN -------------------------------------------------------------------------------------------------------------------------- - Limit - Output: (((t1.fields ->> 'C 1'::text))::integer), (((t2.fields ->> 'c2'::text))::integer), ((t3.tags ->> 'c3'::text)) - -> Hash Full Join - Output: ((t1.fields ->> 'C 1'::text))::integer, ((t2.fields ->> 'c2'::text))::integer, (t3.tags ->> 'c3'::text) - Hash Cond: (((t2.fields ->> 'C 1'::text))::integer = ((t3.fields ->> 'c1'::text))::integer) - -> Hash Full Join - Output: t1.fields, t2.fields - Hash Cond: (((t1.fields ->> 'C 1'::text))::integer = ((t2.fields ->> 'C 1'::text))::integer) - -> Foreign Scan on public.ft2 t1 - Output: t1."time", t1.tags, t1.fields - InfluxDB query: SELECT * FROM "T1" - -> Hash - Output: t2.fields - -> Foreign Scan on public.ft2 t2 - Output: t2.fields - InfluxDB query: SELECT * FROM "T1" - -> Hash - Output: t3.tags, t3.fields - -> Foreign Scan on public.ft4 t3 - Output: t3.tags, t3.fields - InfluxDB query: SELECT * FROM "T3" -(21 rows) - ---Testcase 127: -SELECT t1.c1, t2.c2, t3.c3 FROM (SELECT (fields->>'C 1')::int c1, (fields->>'c2')::int c2, tags->>'c3' c3, fields->>'c4' c4, fields->>'c5' c5, fields->>'c6' c6, fields->>'c7' c7, fields->>'c8' c8 FROM ft2 t1) t1 FULL JOIN (SELECT (fields->>'C 1')::int c1, (fields->>'c2')::int c2, tags->>'c3' c3, fields->>'c4' c4, fields->>'c5' c5, fields->>'c6' c6, fields->>'c7' c7, fields->>'c8' c8 FROM ft2 t2) t2 ON ((t1.c1)::int = (t2.c1)::int) FULL JOIN (SELECT (fields->>'c1')::int c1, (fields->>'c2')::int c2, tags->>'c3' c3 FROM ft4 t3) t3 ON ((t2.c1)::int = (t3.c1)::int) ORDER BY (t1.c1)::int OFFSET 10 LIMIT 10; - c1 | c2 | c3 -----+----+-------- - 11 | 1 | - 12 | 2 | AAA012 - 13 | 3 | - 14 | 4 | AAA014 - 15 | 5 | - 16 | 6 | AAA016 - 17 | 7 | - 18 | 8 | AAA018 - 19 | 9 | - 20 | 0 | AAA020 -(10 rows) - --- full outer join + right outer join ---Testcase 128: -EXPLAIN (VERBOSE, COSTS OFF) -SELECT t1.c1, t2.c2, t3.c3 FROM (SELECT (fields->>'C 1')::int c1, (fields->>'c2')::int c2, tags->>'c3' c3, fields->>'c4' c4, fields->>'c5' c5, fields->>'c6' c6, fields->>'c7' c7, fields->>'c8' c8 FROM ft2 t1) t1 FULL JOIN (SELECT (fields->>'C 1')::int c1, (fields->>'c2')::int c2, tags->>'c3' c3, fields->>'c4' c4, fields->>'c5' c5, fields->>'c6' c6, fields->>'c7' c7, fields->>'c8' c8 FROM ft2 t2) t2 ON ((t1.c1)::int = (t2.c1)::int) RIGHT JOIN (SELECT (fields->>'c1')::int c1, (fields->>'c2')::int c2, tags->>'c3' c3 FROM ft4 t3) t3 ON ((t2.c1)::int = (t3.c1)::int) OFFSET 10 LIMIT 10; - QUERY PLAN -------------------------------------------------------------------------------------------------------------------------- - Limit - Output: (((t1.fields ->> 'C 1'::text))::integer), (((t2.fields ->> 'c2'::text))::integer), ((t3.tags ->> 'c3'::text)) - -> Nested Loop Left Join - Output: ((t1.fields ->> 'C 1'::text))::integer, ((t2.fields ->> 'c2'::text))::integer, (t3.tags ->> 'c3'::text) - Join Filter: (((t1.fields ->> 'C 1'::text))::integer = ((t2.fields ->> 'C 1'::text))::integer) - -> Nested Loop Left Join - Output: t3.tags, t2.fields - Join Filter: (((t2.fields ->> 'C 1'::text))::integer = ((t3.fields ->> 'c1'::text))::integer) - -> Foreign Scan on public.ft4 t3 - Output: t3.tags, t3.fields - InfluxDB query: SELECT * FROM "T3" - -> Materialize - Output: t2.fields - -> Foreign Scan on public.ft2 t2 - Output: t2.fields - InfluxDB query: SELECT * FROM "T1" - -> Materialize - Output: t1.fields - -> Foreign Scan on public.ft2 t1 - Output: t1.fields - InfluxDB query: SELECT * FROM "T1" -(21 rows) - ---Testcase 129: -SELECT t1.c1, t2.c2, t3.c3 FROM (SELECT (fields->>'C 1')::int c1, (fields->>'c2')::int c2, tags->>'c3' c3, fields->>'c4' c4, fields->>'c5' c5, fields->>'c6' c6, fields->>'c7' c7, fields->>'c8' c8 FROM ft2 t1) t1 FULL JOIN (SELECT (fields->>'C 1')::int c1, (fields->>'c2')::int c2, tags->>'c3' c3, fields->>'c4' c4, fields->>'c5' c5, fields->>'c6' c6, fields->>'c7' c7, fields->>'c8' c8 FROM ft2 t2) t2 ON ((t1.c1)::int = (t2.c1)::int) RIGHT JOIN (SELECT (fields->>'c1')::int c1, (fields->>'c2')::int c2, tags->>'c3' c3 FROM ft4 t3) t3 ON ((t2.c1)::int = (t3.c1)::int) OFFSET 10 LIMIT 10; - c1 | c2 | c3 -----+----+-------- - 22 | 2 | AAA022 - 24 | 4 | AAA024 - 26 | 6 | AAA026 - 28 | 8 | AAA028 - 30 | 0 | AAA030 - 32 | 2 | AAA032 - 34 | 4 | AAA034 - 36 | 6 | AAA036 - 38 | 8 | AAA038 - 40 | 0 | AAA040 -(10 rows) - --- right outer join + full outer join ---Testcase 130: -EXPLAIN (VERBOSE, COSTS OFF) -SELECT t1.c1, t2.c2, t3.c3 FROM (SELECT (fields->>'C 1')::int c1, (fields->>'c2')::int c2, tags->>'c3' c3, fields->>'c4' c4, fields->>'c5' c5, fields->>'c6' c6, fields->>'c7' c7, fields->>'c8' c8 FROM ft2 t1) t1 RIGHT JOIN (SELECT (fields->>'C 1')::int c1, (fields->>'c2')::int c2, tags->>'c3' c3, fields->>'c4' c4, fields->>'c5' c5, fields->>'c6' c6, fields->>'c7' c7, fields->>'c8' c8 FROM ft2 t2) t2 ON ((t1.c1)::int = (t2.c1)::int) FULL JOIN (SELECT (fields->>'c1')::int c1, (fields->>'c2')::int c2, tags->>'c3' c3 FROM ft4 t3) t3 ON ((t2.c1)::int = (t3.c1)::int) OFFSET 10 LIMIT 10; - QUERY PLAN -------------------------------------------------------------------------------------------------------------------------- - Limit - Output: (((t1.fields ->> 'C 1'::text))::integer), (((t2.fields ->> 'c2'::text))::integer), ((t3.tags ->> 'c3'::text)) - -> Hash Full Join - Output: ((t1.fields ->> 'C 1'::text))::integer, ((t2.fields ->> 'c2'::text))::integer, (t3.tags ->> 'c3'::text) - Hash Cond: (((t2.fields ->> 'C 1'::text))::integer = ((t3.fields ->> 'c1'::text))::integer) - -> Nested Loop Left Join - Output: t2.fields, t1.fields - Join Filter: (((t1.fields ->> 'C 1'::text))::integer = ((t2.fields ->> 'C 1'::text))::integer) - -> Foreign Scan on public.ft2 t2 - Output: t2."time", t2.tags, t2.fields - InfluxDB query: SELECT * FROM "T1" - -> Materialize - Output: t1.fields - -> Foreign Scan on public.ft2 t1 - Output: t1.fields - InfluxDB query: SELECT * FROM "T1" - -> Hash - Output: t3.tags, t3.fields - -> Foreign Scan on public.ft4 t3 - Output: t3.tags, t3.fields - InfluxDB query: SELECT * FROM "T3" -(21 rows) - ---Testcase 131: -SELECT t1.c1, t2.c2, t3.c3 FROM (SELECT (fields->>'C 1')::int c1, (fields->>'c2')::int c2, tags->>'c3' c3, fields->>'c4' c4, fields->>'c5' c5, fields->>'c6' c6, fields->>'c7' c7, fields->>'c8' c8 FROM ft2 t1) t1 RIGHT JOIN (SELECT (fields->>'C 1')::int c1, (fields->>'c2')::int c2, tags->>'c3' c3, fields->>'c4' c4, fields->>'c5' c5, fields->>'c6' c6, fields->>'c7' c7, fields->>'c8' c8 FROM ft2 t2) t2 ON ((t1.c1)::int = (t2.c1)::int) FULL JOIN (SELECT (fields->>'c1')::int c1, (fields->>'c2')::int c2, tags->>'c3' c3 FROM ft4 t3) t3 ON ((t2.c1)::int = (t3.c1)::int) ORDER BY (t1.c1)::int OFFSET 10 LIMIT 10; - c1 | c2 | c3 -----+----+-------- - 11 | 1 | - 12 | 2 | AAA012 - 13 | 3 | - 14 | 4 | AAA014 - 15 | 5 | - 16 | 6 | AAA016 - 17 | 7 | - 18 | 8 | AAA018 - 19 | 9 | - 20 | 0 | AAA020 -(10 rows) - --- full outer join + left outer join ---Testcase 132: -EXPLAIN (VERBOSE, COSTS OFF) -SELECT t1.c1, t2.c2, t3.c3 FROM (SELECT (fields->>'C 1')::int c1, (fields->>'c2')::int c2, tags->>'c3' c3, fields->>'c4' c4, fields->>'c5' c5, fields->>'c6' c6, fields->>'c7' c7, fields->>'c8' c8 FROM ft2 t1) t1 FULL JOIN (SELECT (fields->>'C 1')::int c1, (fields->>'c2')::int c2, tags->>'c3' c3, fields->>'c4' c4, fields->>'c5' c5, fields->>'c6' c6, fields->>'c7' c7, fields->>'c8' c8 FROM ft2 t2) t2 ON ((t1.c1)::int = (t2.c1)::int) LEFT JOIN (SELECT (fields->>'c1')::int c1, (fields->>'c2')::int c2, tags->>'c3' c3 FROM ft4 t3) t3 ON ((t2.c1)::int = (t3.c1)::int) OFFSET 10 LIMIT 10; - QUERY PLAN -------------------------------------------------------------------------------------------------------------------------- - Limit - Output: (((t1.fields ->> 'C 1'::text))::integer), (((t2.fields ->> 'c2'::text))::integer), ((t3.tags ->> 'c3'::text)) - -> Nested Loop Left Join - Output: ((t1.fields ->> 'C 1'::text))::integer, ((t2.fields ->> 'c2'::text))::integer, (t3.tags ->> 'c3'::text) - Join Filter: (((t2.fields ->> 'C 1'::text))::integer = ((t3.fields ->> 'c1'::text))::integer) - -> Hash Full Join - Output: t1.fields, t2.fields - Hash Cond: (((t1.fields ->> 'C 1'::text))::integer = ((t2.fields ->> 'C 1'::text))::integer) - -> Foreign Scan on public.ft2 t1 - Output: t1."time", t1.tags, t1.fields - InfluxDB query: SELECT * FROM "T1" - -> Hash - Output: t2.fields - -> Foreign Scan on public.ft2 t2 - Output: t2.fields - InfluxDB query: SELECT * FROM "T1" - -> Materialize - Output: t3.tags, t3.fields - -> Foreign Scan on public.ft4 t3 - Output: t3.tags, t3.fields - InfluxDB query: SELECT * FROM "T3" -(21 rows) - ---Testcase 133: -SELECT t1.c1, t2.c2, t3.c3 FROM (SELECT (fields->>'C 1')::int c1, (fields->>'c2')::int c2, tags->>'c3' c3, fields->>'c4' c4, fields->>'c5' c5, fields->>'c6' c6, fields->>'c7' c7, fields->>'c8' c8 FROM ft2 t1) t1 FULL JOIN (SELECT (fields->>'C 1')::int c1, (fields->>'c2')::int c2, tags->>'c3' c3, fields->>'c4' c4, fields->>'c5' c5, fields->>'c6' c6, fields->>'c7' c7, fields->>'c8' c8 FROM ft2 t2) t2 ON ((t1.c1)::int = (t2.c1)::int) LEFT JOIN (SELECT (fields->>'c1')::int c1, (fields->>'c2')::int c2, tags->>'c3' c3 FROM ft4 t3) t3 ON ((t2.c1)::int = (t3.c1)::int) ORDER BY (t1.c1)::int OFFSET 10 LIMIT 10; - c1 | c2 | c3 -----+----+-------- - 11 | 1 | - 12 | 2 | AAA012 - 13 | 3 | - 14 | 4 | AAA014 - 15 | 5 | - 16 | 6 | AAA016 - 17 | 7 | - 18 | 8 | AAA018 - 19 | 9 | - 20 | 0 | AAA020 -(10 rows) - --- left outer join + full outer join ---Testcase 134: -EXPLAIN (VERBOSE, COSTS OFF) -SELECT t1.c1, t2.c2, t3.c3 FROM (SELECT (fields->>'C 1')::int c1, (fields->>'c2')::int c2, tags->>'c3' c3, fields->>'c4' c4, fields->>'c5' c5, fields->>'c6' c6, fields->>'c7' c7, fields->>'c8' c8 FROM ft2 t1) t1 LEFT JOIN (SELECT (fields->>'C 1')::int c1, (fields->>'c2')::int c2, tags->>'c3' c3, fields->>'c4' c4, fields->>'c5' c5, fields->>'c6' c6, fields->>'c7' c7, fields->>'c8' c8 FROM ft2 t2) t2 ON ((t1.c1)::int = (t2.c1)::int) FULL JOIN (SELECT (fields->>'c1')::int c1, (fields->>'c2')::int c2, tags->>'c3' c3 FROM ft4 t3) t3 ON ((t2.c1)::int = (t3.c1)::int) OFFSET 10 LIMIT 10; - QUERY PLAN -------------------------------------------------------------------------------------------------------------------------- - Limit - Output: (((t1.fields ->> 'C 1'::text))::integer), (((t2.fields ->> 'c2'::text))::integer), ((t3.tags ->> 'c3'::text)) - -> Hash Full Join - Output: ((t1.fields ->> 'C 1'::text))::integer, ((t2.fields ->> 'c2'::text))::integer, (t3.tags ->> 'c3'::text) - Hash Cond: (((t2.fields ->> 'C 1'::text))::integer = ((t3.fields ->> 'c1'::text))::integer) - -> Nested Loop Left Join - Output: t1.fields, t2.fields - Join Filter: (((t1.fields ->> 'C 1'::text))::integer = ((t2.fields ->> 'C 1'::text))::integer) - -> Foreign Scan on public.ft2 t1 - Output: t1."time", t1.tags, t1.fields - InfluxDB query: SELECT * FROM "T1" - -> Materialize - Output: t2.fields - -> Foreign Scan on public.ft2 t2 - Output: t2.fields - InfluxDB query: SELECT * FROM "T1" - -> Hash - Output: t3.tags, t3.fields - -> Foreign Scan on public.ft4 t3 - Output: t3.tags, t3.fields - InfluxDB query: SELECT * FROM "T3" -(21 rows) - ---Testcase 135: -SELECT t1.c1, t2.c2, t3.c3 FROM (SELECT (fields->>'C 1')::int c1, (fields->>'c2')::int c2, tags->>'c3' c3, fields->>'c4' c4, fields->>'c5' c5, fields->>'c6' c6, fields->>'c7' c7, fields->>'c8' c8 FROM ft2 t1) t1 LEFT JOIN (SELECT (fields->>'C 1')::int c1, (fields->>'c2')::int c2, tags->>'c3' c3, fields->>'c4' c4, fields->>'c5' c5, fields->>'c6' c6, fields->>'c7' c7, fields->>'c8' c8 FROM ft2 t2) t2 ON ((t1.c1)::int = (t2.c1)::int) FULL JOIN (SELECT (fields->>'c1')::int c1, (fields->>'c2')::int c2, tags->>'c3' c3 FROM ft4 t3) t3 ON ((t2.c1)::int = (t3.c1)::int) ORDER BY (t1.c1)::int OFFSET 10 LIMIT 10; - c1 | c2 | c3 -----+----+-------- - 11 | 1 | - 12 | 2 | AAA012 - 13 | 3 | - 14 | 4 | AAA014 - 15 | 5 | - 16 | 6 | AAA016 - 17 | 7 | - 18 | 8 | AAA018 - 19 | 9 | - 20 | 0 | AAA020 -(10 rows) - --- right outer join + left outer join ---Testcase 136: -EXPLAIN (VERBOSE, COSTS OFF) -SELECT t1.c1, t2.c2, t3.c3 FROM (SELECT (fields->>'C 1')::int c1, (fields->>'c2')::int c2, tags->>'c3' c3, fields->>'c4' c4, fields->>'c5' c5, fields->>'c6' c6, fields->>'c7' c7, fields->>'c8' c8 FROM ft2 t1) t1 RIGHT JOIN (SELECT (fields->>'C 1')::int c1, (fields->>'c2')::int c2, tags->>'c3' c3, fields->>'c4' c4, fields->>'c5' c5, fields->>'c6' c6, fields->>'c7' c7, fields->>'c8' c8 FROM ft2 t2) t2 ON ((t1.c1)::int = (t2.c1)::int) LEFT JOIN (SELECT (fields->>'c1')::int c1, (fields->>'c2')::int c2, tags->>'c3' c3 FROM ft4 t3) t3 ON ((t2.c1)::int = (t3.c1)::int) OFFSET 10 LIMIT 10; - QUERY PLAN -------------------------------------------------------------------------------------------------------------------------- - Limit - Output: (((t1.fields ->> 'C 1'::text))::integer), (((t2.fields ->> 'c2'::text))::integer), ((t3.tags ->> 'c3'::text)) - -> Nested Loop Left Join - Output: ((t1.fields ->> 'C 1'::text))::integer, ((t2.fields ->> 'c2'::text))::integer, (t3.tags ->> 'c3'::text) - Join Filter: (((t1.fields ->> 'C 1'::text))::integer = ((t2.fields ->> 'C 1'::text))::integer) - -> Nested Loop Left Join - Output: t2.fields, t3.tags - Join Filter: (((t2.fields ->> 'C 1'::text))::integer = ((t3.fields ->> 'c1'::text))::integer) - -> Foreign Scan on public.ft2 t2 - Output: t2."time", t2.tags, t2.fields - InfluxDB query: SELECT * FROM "T1" - -> Materialize - Output: t3.tags, t3.fields - -> Foreign Scan on public.ft4 t3 - Output: t3.tags, t3.fields - InfluxDB query: SELECT * FROM "T3" - -> Materialize - Output: t1.fields - -> Foreign Scan on public.ft2 t1 - Output: t1.fields - InfluxDB query: SELECT * FROM "T1" -(21 rows) - ---Testcase 137: -SELECT t1.c1, t2.c2, t3.c3 FROM (SELECT (fields->>'C 1')::int c1, (fields->>'c2')::int c2, tags->>'c3' c3, fields->>'c4' c4, fields->>'c5' c5, fields->>'c6' c6, fields->>'c7' c7, fields->>'c8' c8 FROM ft2 t1) t1 RIGHT JOIN (SELECT (fields->>'C 1')::int c1, (fields->>'c2')::int c2, tags->>'c3' c3, fields->>'c4' c4, fields->>'c5' c5, fields->>'c6' c6, fields->>'c7' c7, fields->>'c8' c8 FROM ft2 t2) t2 ON ((t1.c1)::int = (t2.c1)::int) LEFT JOIN (SELECT (fields->>'c1')::int c1, (fields->>'c2')::int c2, tags->>'c3' c3 FROM ft4 t3) t3 ON ((t2.c1)::int = (t3.c1)::int) ORDER BY (t1.c1)::int OFFSET 10 LIMIT 10; - c1 | c2 | c3 -----+----+-------- - 11 | 1 | - 12 | 2 | AAA012 - 13 | 3 | - 14 | 4 | AAA014 - 15 | 5 | - 16 | 6 | AAA016 - 17 | 7 | - 18 | 8 | AAA018 - 19 | 9 | - 20 | 0 | AAA020 -(10 rows) - --- left outer join + right outer join ---Testcase 138: -EXPLAIN (VERBOSE, COSTS OFF) -SELECT t1.c1, t2.c2, t3.c3 FROM (SELECT (fields->>'C 1')::int c1, (fields->>'c2')::int c2, tags->>'c3' c3, fields->>'c4' c4, fields->>'c5' c5, fields->>'c6' c6, fields->>'c7' c7, fields->>'c8' c8 FROM ft2 t1) t1 LEFT JOIN (SELECT (fields->>'C 1')::int c1, (fields->>'c2')::int c2, tags->>'c3' c3, fields->>'c4' c4, fields->>'c5' c5, fields->>'c6' c6, fields->>'c7' c7, fields->>'c8' c8 FROM ft2 t2) t2 ON ((t1.c1)::int = (t2.c1)::int) RIGHT JOIN (SELECT (fields->>'c1')::int c1, (fields->>'c2')::int c2, tags->>'c3' c3 FROM ft4 t3) t3 ON ((t2.c1)::int = (t3.c1)::int) OFFSET 10 LIMIT 10; - QUERY PLAN -------------------------------------------------------------------------------------------------------------------------- - Limit - Output: (((t1.fields ->> 'C 1'::text))::integer), (((t2.fields ->> 'c2'::text))::integer), ((t3.tags ->> 'c3'::text)) - -> Hash Right Join - Output: ((t1.fields ->> 'C 1'::text))::integer, ((t2.fields ->> 'c2'::text))::integer, (t3.tags ->> 'c3'::text) - Hash Cond: (((t2.fields ->> 'C 1'::text))::integer = ((t3.fields ->> 'c1'::text))::integer) - -> Nested Loop - Output: t1.fields, t2.fields - Join Filter: (((t1.fields ->> 'C 1'::text))::integer = ((t2.fields ->> 'C 1'::text))::integer) - -> Foreign Scan on public.ft2 t1 - Output: t1."time", t1.tags, t1.fields - InfluxDB query: SELECT * FROM "T1" - -> Materialize - Output: t2.fields - -> Foreign Scan on public.ft2 t2 - Output: t2.fields - InfluxDB query: SELECT * FROM "T1" - -> Hash - Output: t3.tags, t3.fields - -> Foreign Scan on public.ft4 t3 - Output: t3.tags, t3.fields - InfluxDB query: SELECT * FROM "T3" -(21 rows) - ---Testcase 139: -SELECT t1.c1, t2.c2, t3.c3 FROM (SELECT (fields->>'C 1')::int c1, (fields->>'c2')::int c2, tags->>'c3' c3, fields->>'c4' c4, fields->>'c5' c5, fields->>'c6' c6, fields->>'c7' c7, fields->>'c8' c8 FROM ft2 t1) t1 LEFT JOIN (SELECT (fields->>'C 1')::int c1, (fields->>'c2')::int c2, tags->>'c3' c3, fields->>'c4' c4, fields->>'c5' c5, fields->>'c6' c6, fields->>'c7' c7, fields->>'c8' c8 FROM ft2 t2) t2 ON ((t1.c1)::int = (t2.c1)::int) RIGHT JOIN (SELECT (fields->>'c1')::int c1, (fields->>'c2')::int c2, tags->>'c3' c3 FROM ft4 t3) t3 ON ((t2.c1)::int = (t3.c1)::int) ORDER BY (t1.c1)::int OFFSET 10 LIMIT 10; - c1 | c2 | c3 -----+----+-------- - 22 | 2 | AAA022 - 24 | 4 | AAA024 - 26 | 6 | AAA026 - 28 | 8 | AAA028 - 30 | 0 | AAA030 - 32 | 2 | AAA032 - 34 | 4 | AAA034 - 36 | 6 | AAA036 - 38 | 8 | AAA038 - 40 | 0 | AAA040 -(10 rows) - --- full outer join + WHERE clause, only matched rows ---Testcase 140: -EXPLAIN (VERBOSE, COSTS OFF) -SELECT t1.c1, t2.c1 FROM (SELECT (fields->>'c1')::int c1, (fields->>'c2')::int c2, tags->>'c3' c3 FROM ft4 t1) t1 FULL JOIN (SELECT (fields->>'c1')::int c1, (fields->>'c2')::int c2, tags->>'c3' c3 FROM ft5 t2) t2 ON ((t1.c1)::int = (t2.c1)::int) WHERE ((t1.c1)::int = (t2.c1)::int OR (t1.c1)::int IS NULL) ORDER BY (t1.c1)::int, (t2.c1)::int OFFSET 10 LIMIT 10; - QUERY PLAN ------------------------------------------------------------------------------------------------------------------------------------------------------------- - Limit - Output: (((t1.fields ->> 'c1'::text))::integer), (((t2.fields ->> 'c1'::text))::integer) - -> Sort - Output: (((t1.fields ->> 'c1'::text))::integer), (((t2.fields ->> 'c1'::text))::integer) - Sort Key: (((t1.fields ->> 'c1'::text))::integer), (((t2.fields ->> 'c1'::text))::integer) - -> Merge Full Join - Output: ((t1.fields ->> 'c1'::text))::integer, ((t2.fields ->> 'c1'::text))::integer - Merge Cond: ((((t1.fields ->> 'c1'::text))::integer) = (((t2.fields ->> 'c1'::text))::integer)) - Filter: ((((t1.fields ->> 'c1'::text))::integer = ((t2.fields ->> 'c1'::text))::integer) OR (((t1.fields ->> 'c1'::text))::integer IS NULL)) - -> Sort - Output: t1.fields, (((t1.fields ->> 'c1'::text))::integer) - Sort Key: (((t1.fields ->> 'c1'::text))::integer) - -> Foreign Scan on public.ft4 t1 - Output: t1.fields, ((t1.fields ->> 'c1'::text))::integer - InfluxDB query: SELECT * FROM "T3" - -> Sort - Output: t2.fields, (((t2.fields ->> 'c1'::text))::integer) - Sort Key: (((t2.fields ->> 'c1'::text))::integer) - -> Foreign Scan on public.ft5 t2 - Output: t2.fields, ((t2.fields ->> 'c1'::text))::integer - InfluxDB query: SELECT * FROM "T4" -(21 rows) - ---Testcase 141: -SELECT t1.c1, t2.c1 FROM (SELECT (fields->>'c1')::int c1, (fields->>'c2')::int c2, tags->>'c3' c3 FROM ft4 t1) t1 FULL JOIN (SELECT (fields->>'c1')::int c1, (fields->>'c2')::int c2, tags->>'c3' c3 FROM ft5 t2) t2 ON ((t1.c1)::int = (t2.c1)::int) WHERE ((t1.c1)::int = (t2.c1)::int OR (t1.c1)::int IS NULL) ORDER BY (t1.c1)::int, (t2.c1)::int OFFSET 10 LIMIT 10; - c1 | c1 -----+---- - 66 | 66 - 72 | 72 - 78 | 78 - 84 | 84 - 90 | 90 - 96 | 96 - | 3 - | 9 - | 15 - | 21 -(10 rows) - --- full outer join + WHERE clause with shippable extensions set ---Testcase 142: -EXPLAIN (VERBOSE, COSTS OFF) -SELECT t1.c1, t2.c2, t1.c3 FROM (SELECT (fields->>'C 1')::int c1, (fields->>'c2')::int c2, tags->>'c3' c3, fields->>'c4' c4, fields->>'c5' c5, fields->>'c6' c6, fields->>'c7' c7, fields->>'c8' c8 FROM ft1 t1) t1 FULL JOIN (SELECT (fields->>'C 1')::int c1, (fields->>'c2')::int c2, tags->>'c3' c3, fields->>'c4' c4, fields->>'c5' c5, fields->>'c6' c6, fields->>'c7' c7, fields->>'c8' c8 FROM ft2 t2) t2 ON ((t1.c1)::int = (t2.c1)::int) WHERE influxdb_fdw_abs((t1.c1)::int) > 0 OFFSET 10 LIMIT 10; - QUERY PLAN -------------------------------------------------------------------------------------------------------------------------- - Limit - Output: (((t1.fields ->> 'C 1'::text))::integer), (((t2.fields ->> 'c2'::text))::integer), ((t1.tags ->> 'c3'::text)) - -> Hash Full Join - Output: ((t1.fields ->> 'C 1'::text))::integer, ((t2.fields ->> 'c2'::text))::integer, (t1.tags ->> 'c3'::text) - Hash Cond: (((t2.fields ->> 'C 1'::text))::integer = ((t1.fields ->> 'C 1'::text))::integer) - Filter: (influxdb_fdw_abs(((t1.fields ->> 'C 1'::text))::integer) > 0) - -> Foreign Scan on public.ft2 t2 - Output: t2."time", t2.tags, t2.fields - InfluxDB query: SELECT * FROM "T1" - -> Hash - Output: t1.fields, t1.tags - -> Foreign Scan on public.ft1 t1 - Output: t1.fields, t1.tags - InfluxDB query: SELECT * FROM "T1" -(14 rows) - --- skip, influxdb does not have option 'extensions' --- ALTER SERVER influxdb_svr OPTIONS (DROP extensions); --- full outer join + WHERE clause with shippable extensions not set --- EXPLAIN (VERBOSE, COSTS OFF) --- SELECT t1.c1, t2.c2, t1.c3 FROM ft1 t1 FULL JOIN ft2 t2 ON (t1.c1 = t2.c1) WHERE influxdb_fdw_abs(t1.c1) > 0 OFFSET 10 LIMIT 10; --- ALTER SERVER loopback OPTIONS (ADD extensions 'influxdb_fdw'); --- join two tables with FOR UPDATE clause --- tests whole-row reference for row marks ---Testcase 143: -EXPLAIN (VERBOSE, COSTS OFF) -SELECT t1.c1, t2.c1 FROM (SELECT (fields->>'C 1')::int c1, (fields->>'c2')::int c2, tags->>'c3' c3, fields->>'c4' c4, fields->>'c5' c5, fields->>'c6' c6, fields->>'c7' c7, fields->>'c8' c8 FROM ft1 t1) t1 JOIN (SELECT (fields->>'C 1')::int c1, (fields->>'c2')::int c2, tags->>'c3' c3, fields->>'c4' c4, fields->>'c5' c5, fields->>'c6' c6, fields->>'c7' c7, fields->>'c8' c8 FROM ft2 t2) t2 ON ((t1.c1)::int = (t2.c1)::int) ORDER BY t1.c3, (t1.c1)::int OFFSET 100 LIMIT 10 FOR UPDATE OF t1; - QUERY PLAN ------------------------------------------------------------------------------------------------------------------------------------------------------- - Limit - Output: (((t1.fields ->> 'C 1'::text))::integer), (((t2.fields ->> 'C 1'::text))::integer), ((t1.tags ->> 'c3'::text)), t1.*, t2.* - -> LockRows - Output: (((t1.fields ->> 'C 1'::text))::integer), (((t2.fields ->> 'C 1'::text))::integer), ((t1.tags ->> 'c3'::text)), t1.*, t2.* - -> Sort - Output: (((t1.fields ->> 'C 1'::text))::integer), (((t2.fields ->> 'C 1'::text))::integer), ((t1.tags ->> 'c3'::text)), t1.*, t2.* - Sort Key: ((t1.tags ->> 'c3'::text)), (((t1.fields ->> 'C 1'::text))::integer) - -> Merge Join - Output: (((t1.fields ->> 'C 1'::text))::integer), (((t2.fields ->> 'C 1'::text))::integer), (t1.tags ->> 'c3'::text), t1.*, t2.* - Merge Cond: ((((t1.fields ->> 'C 1'::text))::integer) = (((t2.fields ->> 'C 1'::text))::integer)) - -> Sort - Output: t1.fields, t1.tags, t1.*, (((t1.fields ->> 'C 1'::text))::integer) - Sort Key: (((t1.fields ->> 'C 1'::text))::integer) - -> Foreign Scan on public.ft1 t1 - Output: t1.fields, t1.tags, t1.*, ((t1.fields ->> 'C 1'::text))::integer - InfluxDB query: SELECT * FROM "T1" - -> Sort - Output: t2.fields, t2.*, (((t2.fields ->> 'C 1'::text))::integer) - Sort Key: (((t2.fields ->> 'C 1'::text))::integer) - -> Foreign Scan on public.ft2 t2 - Output: t2.fields, t2.*, ((t2.fields ->> 'C 1'::text))::integer - InfluxDB query: SELECT * FROM "T1" -(22 rows) - ---Testcase 144: -SELECT t1.c1, t2.c1 FROM (SELECT (fields->>'C 1')::int c1, (fields->>'c2')::int c2, tags->>'c3' c3, fields->>'c4' c4, fields->>'c5' c5, fields->>'c6' c6, fields->>'c7' c7, fields->>'c8' c8 FROM ft1 t1) t1 JOIN (SELECT (fields->>'C 1')::int c1, (fields->>'c2')::int c2, tags->>'c3' c3, fields->>'c4' c4, fields->>'c5' c5, fields->>'c6' c6, fields->>'c7' c7, fields->>'c8' c8 FROM ft2 t2) t2 ON ((t1.c1)::int = (t2.c1)::int) ORDER BY t1.c3, (t1.c1)::int OFFSET 100 LIMIT 10 FOR UPDATE OF t1; - c1 | c1 ------+----- - 101 | 101 - 102 | 102 - 103 | 103 - 104 | 104 - 105 | 105 - 106 | 106 - 107 | 107 - 108 | 108 - 109 | 109 - 110 | 110 -(10 rows) - ---Testcase 145: -EXPLAIN (VERBOSE, COSTS OFF) -SELECT t1.c1, t2.c1 FROM (SELECT (fields->>'C 1')::int c1, (fields->>'c2')::int c2, tags->>'c3' c3, fields->>'c4' c4, fields->>'c5' c5, fields->>'c6' c6, fields->>'c7' c7, fields->>'c8' c8 FROM ft1 t1) t1 JOIN (SELECT (fields->>'C 1')::int c1, (fields->>'c2')::int c2, tags->>'c3' c3, fields->>'c4' c4, fields->>'c5' c5, fields->>'c6' c6, fields->>'c7' c7, fields->>'c8' c8 FROM ft2 t2) t2 ON ((t1.c1)::int = (t2.c1)::int) ORDER BY t1.c3, (t1.c1)::int OFFSET 100 LIMIT 10 FOR UPDATE; - QUERY PLAN ------------------------------------------------------------------------------------------------------------------------------------------------------- - Limit - Output: (((t1.fields ->> 'C 1'::text))::integer), (((t2.fields ->> 'C 1'::text))::integer), ((t1.tags ->> 'c3'::text)), t1.*, t2.* - -> LockRows - Output: (((t1.fields ->> 'C 1'::text))::integer), (((t2.fields ->> 'C 1'::text))::integer), ((t1.tags ->> 'c3'::text)), t1.*, t2.* - -> Sort - Output: (((t1.fields ->> 'C 1'::text))::integer), (((t2.fields ->> 'C 1'::text))::integer), ((t1.tags ->> 'c3'::text)), t1.*, t2.* - Sort Key: ((t1.tags ->> 'c3'::text)), (((t1.fields ->> 'C 1'::text))::integer) - -> Merge Join - Output: (((t1.fields ->> 'C 1'::text))::integer), (((t2.fields ->> 'C 1'::text))::integer), (t1.tags ->> 'c3'::text), t1.*, t2.* - Merge Cond: ((((t1.fields ->> 'C 1'::text))::integer) = (((t2.fields ->> 'C 1'::text))::integer)) - -> Sort - Output: t1.fields, t1.tags, t1.*, (((t1.fields ->> 'C 1'::text))::integer) - Sort Key: (((t1.fields ->> 'C 1'::text))::integer) - -> Foreign Scan on public.ft1 t1 - Output: t1.fields, t1.tags, t1.*, ((t1.fields ->> 'C 1'::text))::integer - InfluxDB query: SELECT * FROM "T1" - -> Sort - Output: t2.fields, t2.*, (((t2.fields ->> 'C 1'::text))::integer) - Sort Key: (((t2.fields ->> 'C 1'::text))::integer) - -> Foreign Scan on public.ft2 t2 - Output: t2.fields, t2.*, ((t2.fields ->> 'C 1'::text))::integer - InfluxDB query: SELECT * FROM "T1" -(22 rows) - ---Testcase 146: -SELECT t1.c1, t2.c1 FROM (SELECT (fields->>'C 1')::int c1, (fields->>'c2')::int c2, tags->>'c3' c3, fields->>'c4' c4, fields->>'c5' c5, fields->>'c6' c6, fields->>'c7' c7, fields->>'c8' c8 FROM ft1 t1) t1 JOIN (SELECT (fields->>'C 1')::int c1, (fields->>'c2')::int c2, tags->>'c3' c3, fields->>'c4' c4, fields->>'c5' c5, fields->>'c6' c6, fields->>'c7' c7, fields->>'c8' c8 FROM ft2 t2) t2 ON ((t1.c1)::int = (t2.c1)::int) ORDER BY t1.c3, (t1.c1)::int OFFSET 100 LIMIT 10 FOR UPDATE; - c1 | c1 ------+----- - 101 | 101 - 102 | 102 - 103 | 103 - 104 | 104 - 105 | 105 - 106 | 106 - 107 | 107 - 108 | 108 - 109 | 109 - 110 | 110 -(10 rows) - --- join two tables with FOR SHARE clause ---Testcase 147: -EXPLAIN (VERBOSE, COSTS OFF) -SELECT t1.c1, t2.c1 FROM (SELECT (fields->>'C 1')::int c1, (fields->>'c2')::int c2, tags->>'c3' c3, fields->>'c4' c4, fields->>'c5' c5, fields->>'c6' c6, fields->>'c7' c7, fields->>'c8' c8 FROM ft1 t1) t1 JOIN (SELECT (fields->>'C 1')::int c1, (fields->>'c2')::int c2, tags->>'c3' c3, fields->>'c4' c4, fields->>'c5' c5, fields->>'c6' c6, fields->>'c7' c7, fields->>'c8' c8 FROM ft2 t2) t2 ON ((t1.c1)::int = (t2.c1)::int) ORDER BY t1.c3, (t1.c1)::int OFFSET 100 LIMIT 10 FOR SHARE OF t1; - QUERY PLAN ------------------------------------------------------------------------------------------------------------------------------------------------------- - Limit - Output: (((t1.fields ->> 'C 1'::text))::integer), (((t2.fields ->> 'C 1'::text))::integer), ((t1.tags ->> 'c3'::text)), t1.*, t2.* - -> LockRows - Output: (((t1.fields ->> 'C 1'::text))::integer), (((t2.fields ->> 'C 1'::text))::integer), ((t1.tags ->> 'c3'::text)), t1.*, t2.* - -> Sort - Output: (((t1.fields ->> 'C 1'::text))::integer), (((t2.fields ->> 'C 1'::text))::integer), ((t1.tags ->> 'c3'::text)), t1.*, t2.* - Sort Key: ((t1.tags ->> 'c3'::text)), (((t1.fields ->> 'C 1'::text))::integer) - -> Merge Join - Output: (((t1.fields ->> 'C 1'::text))::integer), (((t2.fields ->> 'C 1'::text))::integer), (t1.tags ->> 'c3'::text), t1.*, t2.* - Merge Cond: ((((t1.fields ->> 'C 1'::text))::integer) = (((t2.fields ->> 'C 1'::text))::integer)) - -> Sort - Output: t1.fields, t1.tags, t1.*, (((t1.fields ->> 'C 1'::text))::integer) - Sort Key: (((t1.fields ->> 'C 1'::text))::integer) - -> Foreign Scan on public.ft1 t1 - Output: t1.fields, t1.tags, t1.*, ((t1.fields ->> 'C 1'::text))::integer - InfluxDB query: SELECT * FROM "T1" - -> Sort - Output: t2.fields, t2.*, (((t2.fields ->> 'C 1'::text))::integer) - Sort Key: (((t2.fields ->> 'C 1'::text))::integer) - -> Foreign Scan on public.ft2 t2 - Output: t2.fields, t2.*, ((t2.fields ->> 'C 1'::text))::integer - InfluxDB query: SELECT * FROM "T1" -(22 rows) - ---Testcase 148: -SELECT t1.c1, t2.c1 FROM (SELECT (fields->>'C 1')::int c1, (fields->>'c2')::int c2, tags->>'c3' c3, fields->>'c4' c4, fields->>'c5' c5, fields->>'c6' c6, fields->>'c7' c7, fields->>'c8' c8 FROM ft1 t1) t1 JOIN (SELECT (fields->>'C 1')::int c1, (fields->>'c2')::int c2, tags->>'c3' c3, fields->>'c4' c4, fields->>'c5' c5, fields->>'c6' c6, fields->>'c7' c7, fields->>'c8' c8 FROM ft2 t2) t2 ON ((t1.c1)::int = (t2.c1)::int) ORDER BY t1.c3, (t1.c1)::int OFFSET 100 LIMIT 10 FOR SHARE OF t1; - c1 | c1 ------+----- - 101 | 101 - 102 | 102 - 103 | 103 - 104 | 104 - 105 | 105 - 106 | 106 - 107 | 107 - 108 | 108 - 109 | 109 - 110 | 110 -(10 rows) - ---Testcase 149: -EXPLAIN (VERBOSE, COSTS OFF) -SELECT t1.c1, t2.c1 FROM (SELECT (fields->>'C 1')::int c1, (fields->>'c2')::int c2, tags->>'c3' c3, fields->>'c4' c4, fields->>'c5' c5, fields->>'c6' c6, fields->>'c7' c7, fields->>'c8' c8 FROM ft1 t1) t1 JOIN (SELECT (fields->>'C 1')::int c1, (fields->>'c2')::int c2, tags->>'c3' c3, fields->>'c4' c4, fields->>'c5' c5, fields->>'c6' c6, fields->>'c7' c7, fields->>'c8' c8 FROM ft2 t2) t2 ON ((t1.c1)::int = (t2.c1)::int) ORDER BY t1.c3, (t1.c1)::int OFFSET 100 LIMIT 10 FOR SHARE; - QUERY PLAN ------------------------------------------------------------------------------------------------------------------------------------------------------- - Limit - Output: (((t1.fields ->> 'C 1'::text))::integer), (((t2.fields ->> 'C 1'::text))::integer), ((t1.tags ->> 'c3'::text)), t1.*, t2.* - -> LockRows - Output: (((t1.fields ->> 'C 1'::text))::integer), (((t2.fields ->> 'C 1'::text))::integer), ((t1.tags ->> 'c3'::text)), t1.*, t2.* - -> Sort - Output: (((t1.fields ->> 'C 1'::text))::integer), (((t2.fields ->> 'C 1'::text))::integer), ((t1.tags ->> 'c3'::text)), t1.*, t2.* - Sort Key: ((t1.tags ->> 'c3'::text)), (((t1.fields ->> 'C 1'::text))::integer) - -> Merge Join - Output: (((t1.fields ->> 'C 1'::text))::integer), (((t2.fields ->> 'C 1'::text))::integer), (t1.tags ->> 'c3'::text), t1.*, t2.* - Merge Cond: ((((t1.fields ->> 'C 1'::text))::integer) = (((t2.fields ->> 'C 1'::text))::integer)) - -> Sort - Output: t1.fields, t1.tags, t1.*, (((t1.fields ->> 'C 1'::text))::integer) - Sort Key: (((t1.fields ->> 'C 1'::text))::integer) - -> Foreign Scan on public.ft1 t1 - Output: t1.fields, t1.tags, t1.*, ((t1.fields ->> 'C 1'::text))::integer - InfluxDB query: SELECT * FROM "T1" - -> Sort - Output: t2.fields, t2.*, (((t2.fields ->> 'C 1'::text))::integer) - Sort Key: (((t2.fields ->> 'C 1'::text))::integer) - -> Foreign Scan on public.ft2 t2 - Output: t2.fields, t2.*, ((t2.fields ->> 'C 1'::text))::integer - InfluxDB query: SELECT * FROM "T1" -(22 rows) - ---Testcase 150: -SELECT t1.c1, t2.c1 FROM (SELECT (fields->>'C 1')::int c1, (fields->>'c2')::int c2, tags->>'c3' c3, fields->>'c4' c4, fields->>'c5' c5, fields->>'c6' c6, fields->>'c7' c7, fields->>'c8' c8 FROM ft1 t1) t1 JOIN (SELECT (fields->>'C 1')::int c1, (fields->>'c2')::int c2, tags->>'c3' c3, fields->>'c4' c4, fields->>'c5' c5, fields->>'c6' c6, fields->>'c7' c7, fields->>'c8' c8 FROM ft2 t2) t2 ON ((t1.c1)::int = (t2.c1)::int) ORDER BY t1.c3, (t1.c1)::int OFFSET 100 LIMIT 10 FOR SHARE; - c1 | c1 ------+----- - 101 | 101 - 102 | 102 - 103 | 103 - 104 | 104 - 105 | 105 - 106 | 106 - 107 | 107 - 108 | 108 - 109 | 109 - 110 | 110 -(10 rows) - --- join in CTE ---Testcase 151: -EXPLAIN (VERBOSE, COSTS OFF) -WITH t (c1_1, c1_3, c2_1) AS MATERIALIZED (SELECT t1.c1, t1.c3, t2.c1 FROM (SELECT (fields->>'C 1')::int c1, (fields->>'c2')::int c2, tags->>'c3' c3, fields->>'c4' c4, fields->>'c5' c5, fields->>'c6' c6, fields->>'c7' c7, fields->>'c8' c8 FROM ft1 t1) t1 JOIN (SELECT (fields->>'C 1')::int c1, (fields->>'c2')::int c2, tags->>'c3' c3, fields->>'c4' c4, fields->>'c5' c5, fields->>'c6' c6, fields->>'c7' c7, fields->>'c8' c8 FROM ft2 t2) t2 ON ((t1.c1)::int = (t2.c1)::int)) SELECT c1_1, c2_1 FROM t ORDER BY c1_3, c1_1 OFFSET 100 LIMIT 10; -ERROR: syntax error at or near "MATERIALIZED" -LINE 2: WITH t (c1_1, c1_3, c2_1) AS MATERIALIZED (SELECT t1.c1, t1.... - ^ ---Testcase 152: -WITH t (c1_1, c1_3, c2_1) AS MATERIALIZED (SELECT t1.c1, t1.c3, t2.c1 FROM (SELECT (fields->>'C 1')::int c1, (fields->>'c2')::int c2, tags->>'c3' c3, fields->>'c4' c4, fields->>'c5' c5, fields->>'c6' c6, fields->>'c7' c7, fields->>'c8' c8 FROM ft1 t1) t1 JOIN (SELECT (fields->>'C 1')::int c1, (fields->>'c2')::int c2, tags->>'c3' c3, fields->>'c4' c4, fields->>'c5' c5, fields->>'c6' c6, fields->>'c7' c7, fields->>'c8' c8 FROM ft2 t2) t2 ON ((t1.c1)::int = (t2.c1)::int)) SELECT c1_1, c2_1 FROM t ORDER BY c1_3, c1_1 OFFSET 100 LIMIT 10; -ERROR: syntax error at or near "MATERIALIZED" -LINE 1: WITH t (c1_1, c1_3, c2_1) AS MATERIALIZED (SELECT t1.c1, t1.... - ^ --- ctid with whole-row reference ---Testcase 153: -EXPLAIN (VERBOSE, COSTS OFF) -SELECT t1.ctid, t1, t2, t1.c1 FROM (SELECT ctid, fields->>'C 1' c1, fields->>'c2' c2, tags->>'c3' c3, fields->>'c4' c4, fields->>'c5' c5, fields->>'c6' c6, fields->>'c7' c7, fields->>'c8' c8 FROM ft1 t1) t1 JOIN (SELECT (fields->>'C 1')::int c1, (fields->>'c2')::int c2, tags->>'c3' c3, fields->>'c4' c4, fields->>'c5' c5, fields->>'c6' c6, fields->>'c7' c7, fields->>'c8' c8 FROM ft2 t2) t2 ON ((t1.c1)::int = (t2.c1)::int) ORDER BY t1.c3, (t1.c1)::int OFFSET 100 LIMIT 10; - QUERY PLAN ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- - Limit - Output: t1.ctid, (ROW(t1.ctid, (t1.fields ->> 'C 1'::text), (t1.fields ->> 'c2'::text), (t1.tags ->> 'c3'::text), (t1.fields ->> 'c4'::text), (t1.fields ->> 'c5'::text), (t1.fields ->> 'c6'::text), (t1.fields ->> 'c7'::text), (t1.fields ->> 'c8'::text))), (ROW(((t2.fields ->> 'C 1'::text))::integer, ((t2.fields ->> 'c2'::text))::integer, (t2.tags ->> 'c3'::text), (t2.fields ->> 'c4'::text), (t2.fields ->> 'c5'::text), (t2.fields ->> 'c6'::text), (t2.fields ->> 'c7'::text), (t2.fields ->> 'c8'::text))), ((t1.fields ->> 'C 1'::text)), ((t1.tags ->> 'c3'::text)), (((t1.fields ->> 'C 1'::text))::integer) - -> Result - Output: t1.ctid, (ROW(t1.ctid, (t1.fields ->> 'C 1'::text), (t1.fields ->> 'c2'::text), (t1.tags ->> 'c3'::text), (t1.fields ->> 'c4'::text), (t1.fields ->> 'c5'::text), (t1.fields ->> 'c6'::text), (t1.fields ->> 'c7'::text), (t1.fields ->> 'c8'::text))), ROW(((t2.fields ->> 'C 1'::text))::integer, ((t2.fields ->> 'c2'::text))::integer, (t2.tags ->> 'c3'::text), (t2.fields ->> 'c4'::text), (t2.fields ->> 'c5'::text), (t2.fields ->> 'c6'::text), (t2.fields ->> 'c7'::text), (t2.fields ->> 'c8'::text)), ((t1.fields ->> 'C 1'::text)), ((t1.tags ->> 'c3'::text)), (((t1.fields ->> 'C 1'::text))::integer) - -> Sort - Output: t1.ctid, (ROW(t1.ctid, (t1.fields ->> 'C 1'::text), (t1.fields ->> 'c2'::text), (t1.tags ->> 'c3'::text), (t1.fields ->> 'c4'::text), (t1.fields ->> 'c5'::text), (t1.fields ->> 'c6'::text), (t1.fields ->> 'c7'::text), (t1.fields ->> 'c8'::text))), ((t1.fields ->> 'C 1'::text)), ((t1.tags ->> 'c3'::text)), (((t1.fields ->> 'C 1'::text))::integer), t2.fields, t2.tags - Sort Key: ((t1.tags ->> 'c3'::text)), (((t1.fields ->> 'C 1'::text))::integer) - -> Merge Join - Output: t1.ctid, ROW(t1.ctid, (t1.fields ->> 'C 1'::text), (t1.fields ->> 'c2'::text), (t1.tags ->> 'c3'::text), (t1.fields ->> 'c4'::text), (t1.fields ->> 'c5'::text), (t1.fields ->> 'c6'::text), (t1.fields ->> 'c7'::text), (t1.fields ->> 'c8'::text)), (t1.fields ->> 'C 1'::text), (t1.tags ->> 'c3'::text), (((t1.fields ->> 'C 1'::text))::integer), t2.fields, t2.tags - Merge Cond: ((((t1.fields ->> 'C 1'::text))::integer) = (((t2.fields ->> 'C 1'::text))::integer)) - -> Sort - Output: t1.ctid, t1.fields, t1.tags, (((t1.fields ->> 'C 1'::text))::integer) - Sort Key: (((t1.fields ->> 'C 1'::text))::integer) - -> Foreign Scan on public.ft1 t1 - Output: t1.ctid, t1.fields, t1.tags, ((t1.fields ->> 'C 1'::text))::integer - InfluxDB query: SELECT * FROM "T1" - -> Sort - Output: t2.fields, t2.tags, (((t2.fields ->> 'C 1'::text))::integer) - Sort Key: (((t2.fields ->> 'C 1'::text))::integer) - -> Foreign Scan on public.ft2 t2 - Output: t2.fields, t2.tags, ((t2.fields ->> 'C 1'::text))::integer - InfluxDB query: SELECT * FROM "T1" -(22 rows) - --- SEMI JOIN, not pushed down ---Testcase 154: -EXPLAIN (VERBOSE, COSTS OFF) -SELECT (t1.fields->>'C 1')::int c1 FROM ft1 t1 WHERE EXISTS (SELECT 1 FROM ft2 t2 WHERE (t1.fields->>'C 1')::int = (t2.fields->>'C 1')::int) ORDER BY (t1.fields->>'C 1')::int OFFSET 100 LIMIT 10; - QUERY PLAN ------------------------------------------------------------------------------------------------------------- - Limit - Output: (((t1.fields ->> 'C 1'::text))::integer) - -> Sort - Output: (((t1.fields ->> 'C 1'::text))::integer) - Sort Key: (((t1.fields ->> 'C 1'::text))::integer) - -> Hash Join - Output: ((t1.fields ->> 'C 1'::text))::integer - Inner Unique: true - Hash Cond: (((t1.fields ->> 'C 1'::text))::integer = ((t2.fields ->> 'C 1'::text))::integer) - -> Foreign Scan on public.ft1 t1 - Output: t1."time", t1.tags, t1.fields - InfluxDB query: SELECT * FROM "T1" - -> Hash - Output: t2.fields - -> HashAggregate - Output: t2.fields - Group Key: ((t2.fields ->> 'C 1'::text))::integer - -> Foreign Scan on public.ft2 t2 - Output: t2.fields, ((t2.fields ->> 'C 1'::text))::integer - InfluxDB query: SELECT * FROM "T1" -(20 rows) - ---Testcase 155: -SELECT (t1.fields->>'C 1')::int c1 FROM ft1 t1 WHERE EXISTS (SELECT 1 FROM ft2 t2 WHERE (t1.fields->>'C 1')::int = (t2.fields->>'C 1')::int) ORDER BY (t1.fields->>'C 1')::int OFFSET 100 LIMIT 10; - c1 ------ - 101 - 102 - 103 - 104 - 105 - 106 - 107 - 108 - 109 - 110 -(10 rows) - --- ANTI JOIN, not pushed down ---Testcase 156: -EXPLAIN (VERBOSE, COSTS OFF) -SELECT (t1.fields->>'C 1')::int c1 FROM ft1 t1 WHERE NOT EXISTS (SELECT 1 FROM ft2 t2 WHERE (t1.fields->>'C 1')::int = (t2.fields->>'c2')::int) ORDER BY (t1.fields->>'C 1')::int OFFSET 100 LIMIT 10; - QUERY PLAN ----------------------------------------------------------------------------------------------------------- - Limit - Output: (((t1.fields ->> 'C 1'::text))::integer) - -> Merge Anti Join - Output: (((t1.fields ->> 'C 1'::text))::integer) - Merge Cond: ((((t1.fields ->> 'C 1'::text))::integer) = (((t2.fields ->> 'c2'::text))::integer)) - -> Sort - Output: t1.fields, (((t1.fields ->> 'C 1'::text))::integer) - Sort Key: (((t1.fields ->> 'C 1'::text))::integer) - -> Foreign Scan on public.ft1 t1 - Output: t1.fields, ((t1.fields ->> 'C 1'::text))::integer - InfluxDB query: SELECT * FROM "T1" - -> Sort - Output: t2.fields, (((t2.fields ->> 'c2'::text))::integer) - Sort Key: (((t2.fields ->> 'c2'::text))::integer) - -> Foreign Scan on public.ft2 t2 - Output: t2.fields, ((t2.fields ->> 'c2'::text))::integer - InfluxDB query: SELECT * FROM "T1" -(17 rows) - ---Testcase 157: -SELECT (t1.fields->>'C 1')::int c1 FROM ft1 t1 WHERE NOT EXISTS (SELECT 1 FROM ft2 t2 WHERE (t1.fields->>'C 1')::int = (t2.fields->>'c2')::int) ORDER BY (t1.fields->>'C 1')::int OFFSET 100 LIMIT 10; - c1 ------ - 110 - 111 - 112 - 113 - 114 - 115 - 116 - 117 - 118 - 119 -(10 rows) - --- CROSS JOIN can be pushed down ---Testcase 158: -EXPLAIN (VERBOSE, COSTS OFF) -SELECT t1.c1, t2.c1 FROM (SELECT (fields->>'C 1')::int c1, (fields->>'c2')::int c2, tags->>'c3' c3, fields->>'c4' c4, fields->>'c5' c5, fields->>'c6' c6, fields->>'c7' c7, fields->>'c8' c8 FROM ft1 t1) t1 CROSS JOIN (SELECT (fields->>'C 1')::int c1, (fields->>'c2')::int c2, tags->>'c3' c3, fields->>'c4' c4, fields->>'c5' c5, fields->>'c6' c6, fields->>'c7' c7, fields->>'c8' c8 FROM ft2 t2) t2 ORDER BY (t1.c1)::int, (t2.c1)::int OFFSET 100 LIMIT 10; - QUERY PLAN ------------------------------------------------------------------------------------------------------- - Limit - Output: (((t1.fields ->> 'C 1'::text))::integer), (((t2.fields ->> 'C 1'::text))::integer) - -> Sort - Output: (((t1.fields ->> 'C 1'::text))::integer), (((t2.fields ->> 'C 1'::text))::integer) - Sort Key: (((t1.fields ->> 'C 1'::text))::integer), (((t2.fields ->> 'C 1'::text))::integer) - -> Nested Loop - Output: ((t1.fields ->> 'C 1'::text))::integer, ((t2.fields ->> 'C 1'::text))::integer - -> Foreign Scan on public.ft1 t1 - Output: t1."time", t1.tags, t1.fields - InfluxDB query: SELECT * FROM "T1" - -> Materialize - Output: t2.fields - -> Foreign Scan on public.ft2 t2 - Output: t2.fields - InfluxDB query: SELECT * FROM "T1" -(15 rows) - ---Testcase 159: -SELECT t1.c1, t2.c1 FROM (SELECT (fields->>'C 1')::int c1, (fields->>'c2')::int c2, tags->>'c3' c3, fields->>'c4' c4, fields->>'c5' c5, fields->>'c6' c6, fields->>'c7' c7, fields->>'c8' c8 FROM ft1 t1) t1 CROSS JOIN (SELECT (fields->>'C 1')::int c1, (fields->>'c2')::int c2, tags->>'c3' c3, fields->>'c4' c4, fields->>'c5' c5, fields->>'c6' c6, fields->>'c7' c7, fields->>'c8' c8 FROM ft2 t2) t2 ORDER BY (t1.c1)::int, (t2.c1)::int OFFSET 100 LIMIT 10; - c1 | c1 -----+----- - 1 | 101 - 1 | 102 - 1 | 103 - 1 | 104 - 1 | 105 - 1 | 106 - 1 | 107 - 1 | 108 - 1 | 109 - 1 | 110 -(10 rows) - --- different server, not pushed down. No result expected. ---Testcase 160: -EXPLAIN (VERBOSE, COSTS OFF) -SELECT t1.c1, t2.c1 FROM (SELECT (fields->>'c1')::int c1, (fields->>'c2')::int c2, tags->>'c3' c3 FROM ft5 t1) t1 JOIN (SELECT (fields->>'c1')::int c1, (fields->>'c2')::int c2, tags->>'c3' c3 FROM ft6 t2) t2 ON ((t1.c1)::int = (t2.c1)::int) ORDER BY (t1.c1)::int, (t2.c1)::int OFFSET 100 LIMIT 10; - QUERY PLAN ---------------------------------------------------------------------------------------------------------- - Limit - Output: (((t1.fields ->> 'c1'::text))::integer), (((t2.fields ->> 'c1'::text))::integer) - -> Merge Join - Output: (((t1.fields ->> 'c1'::text))::integer), (((t2.fields ->> 'c1'::text))::integer) - Merge Cond: ((((t1.fields ->> 'c1'::text))::integer) = (((t2.fields ->> 'c1'::text))::integer)) - -> Sort - Output: t1.fields, (((t1.fields ->> 'c1'::text))::integer) - Sort Key: (((t1.fields ->> 'c1'::text))::integer) - -> Foreign Scan on public.ft5 t1 - Output: t1.fields, ((t1.fields ->> 'c1'::text))::integer - InfluxDB query: SELECT * FROM "T4" - -> Sort - Output: t2.fields, (((t2.fields ->> 'c1'::text))::integer) - Sort Key: (((t2.fields ->> 'c1'::text))::integer) - -> Foreign Scan on public.ft6 t2 - Output: t2.fields, ((t2.fields ->> 'c1'::text))::integer - InfluxDB query: SELECT * FROM "T4" -(17 rows) - ---Testcase 161: -SELECT t1.c1, t2.c1 FROM (SELECT (fields->>'c1')::int c1, (fields->>'c2')::int c2, tags->>'c3' c3 FROM ft5 t1) t1 JOIN (SELECT (fields->>'c1')::int c1, (fields->>'c2')::int c2, tags->>'c3' c3 FROM ft6 t2) t2 ON ((t1.c1)::int = (t2.c1)::int) ORDER BY (t1.c1)::int, (t2.c1)::int OFFSET 100 LIMIT 10; - c1 | c1 -----+---- -(0 rows) - --- unsafe join conditions (c8 has a UDT), not pushed down. Practically a CROSS --- JOIN since c8 in both tables has same value. ---Testcase 162: -EXPLAIN (VERBOSE, COSTS OFF) -SELECT t1.c1, t2.c1 FROM (SELECT (fields->>'C 1')::int c1, (fields->>'c2')::int c2, tags->>'c3' c3, fields->>'c4' c4, fields->>'c5' c5, fields->>'c6' c6, fields->>'c7' c7, fields->>'c8' c8 FROM ft1 t1) t1 LEFT JOIN (SELECT (fields->>'C 1')::int c1, (fields->>'c2')::int c2, tags->>'c3' c3, fields->>'c4' c4, fields->>'c5' c5, fields->>'c6' c6, fields->>'c7' c7, fields->>'c8' c8 FROM ft2 t2) t2 ON (t1.c8 = t2.c8) ORDER BY (t1.c1)::int, (t2.c1)::int OFFSET 100 LIMIT 10; - QUERY PLAN ------------------------------------------------------------------------------------------------------- - Limit - Output: (((t1.fields ->> 'C 1'::text))::integer), (((t2.fields ->> 'C 1'::text))::integer) - -> Sort - Output: (((t1.fields ->> 'C 1'::text))::integer), (((t2.fields ->> 'C 1'::text))::integer) - Sort Key: (((t1.fields ->> 'C 1'::text))::integer), (((t2.fields ->> 'C 1'::text))::integer) - -> Merge Left Join - Output: ((t1.fields ->> 'C 1'::text))::integer, ((t2.fields ->> 'C 1'::text))::integer - Merge Cond: (((t1.fields ->> 'c8'::text)) = ((t2.fields ->> 'c8'::text))) - -> Sort - Output: t1.fields, ((t1.fields ->> 'c8'::text)) - Sort Key: ((t1.fields ->> 'c8'::text)) - -> Foreign Scan on public.ft1 t1 - Output: t1.fields, (t1.fields ->> 'c8'::text) - InfluxDB query: SELECT * FROM "T1" - -> Sort - Output: t2.fields, ((t2.fields ->> 'c8'::text)) - Sort Key: ((t2.fields ->> 'c8'::text)) - -> Foreign Scan on public.ft2 t2 - Output: t2.fields, (t2.fields ->> 'c8'::text) - InfluxDB query: SELECT * FROM "T1" -(20 rows) - ---Testcase 163: -SELECT t1.c1, t2.c1 FROM (SELECT (fields->>'C 1')::int c1, (fields->>'c2')::int c2, tags->>'c3' c3, fields->>'c4' c4, fields->>'c5' c5, fields->>'c6' c6, fields->>'c7' c7, fields->>'c8' c8 FROM ft1 t1) t1 LEFT JOIN (SELECT (fields->>'C 1')::int c1, (fields->>'c2')::int c2, tags->>'c3' c3, fields->>'c4' c4, fields->>'c5' c5, fields->>'c6' c6, fields->>'c7' c7, fields->>'c8' c8 FROM ft2 t2) t2 ON (t1.c8 = t2.c8) ORDER BY (t1.c1)::int, (t2.c1)::int OFFSET 100 LIMIT 10; - c1 | c1 -----+----- - 1 | 101 - 1 | 102 - 1 | 103 - 1 | 104 - 1 | 105 - 1 | 106 - 1 | 107 - 1 | 108 - 1 | 109 - 1 | 110 -(10 rows) - --- unsafe conditions on one side (c8 has a UDT), not pushed down. ---Testcase 164: -EXPLAIN (VERBOSE, COSTS OFF) -SELECT t1.c1, t2.c1 FROM (SELECT (fields->>'C 1')::int c1, (fields->>'c2')::int c2, tags->>'c3' c3, fields->>'c4' c4, fields->>'c5' c5, fields->>'c6' c6, fields->>'c7' c7, fields->>'c8' c8 FROM ft1 t1) t1 LEFT JOIN (SELECT (fields->>'C 1')::int c1, (fields->>'c2')::int c2, tags->>'c3' c3, fields->>'c4' c4, fields->>'c5' c5, fields->>'c6' c6, fields->>'c7' c7, fields->>'c8' c8 FROM ft2 t2) t2 ON ((t1.c1)::int = (t2.c1)::int) WHERE t1.c8 = 'foo' ORDER BY t1.c3, (t1.c1)::int OFFSET 100 LIMIT 10; - QUERY PLAN --------------------------------------------------------------------------------------------------------------------------------- - Limit - Output: (((t1.fields ->> 'C 1'::text))::integer), (((t2.fields ->> 'C 1'::text))::integer), ((t1.tags ->> 'c3'::text)) - -> Sort - Output: (((t1.fields ->> 'C 1'::text))::integer), (((t2.fields ->> 'C 1'::text))::integer), ((t1.tags ->> 'c3'::text)) - Sort Key: ((t1.tags ->> 'c3'::text)), (((t1.fields ->> 'C 1'::text))::integer) - -> Hash Right Join - Output: ((t1.fields ->> 'C 1'::text))::integer, ((t2.fields ->> 'C 1'::text))::integer, (t1.tags ->> 'c3'::text) - Hash Cond: (((t2.fields ->> 'C 1'::text))::integer = ((t1.fields ->> 'C 1'::text))::integer) - -> Foreign Scan on public.ft2 t2 - Output: t2."time", t2.tags, t2.fields - InfluxDB query: SELECT * FROM "T1" - -> Hash - Output: t1.fields, t1.tags - -> Foreign Scan on public.ft1 t1 - Output: t1.fields, t1.tags - InfluxDB query: SELECT * FROM "T1" WHERE (("c8" = 'foo')) -(16 rows) - ---Testcase 165: -SELECT t1.c1, t2.c1 FROM (SELECT (fields->>'C 1')::int c1, (fields->>'c2')::int c2, tags->>'c3' c3, fields->>'c4' c4, fields->>'c5' c5, fields->>'c6' c6, fields->>'c7' c7, fields->>'c8' c8 FROM ft1 t1) t1 LEFT JOIN (SELECT (fields->>'C 1')::int c1, (fields->>'c2')::int c2, tags->>'c3' c3, fields->>'c4' c4, fields->>'c5' c5, fields->>'c6' c6, fields->>'c7' c7, fields->>'c8' c8 FROM ft2 t2) t2 ON ((t1.c1)::int = (t2.c1)::int) WHERE t1.c8 = 'foo' ORDER BY t1.c3, (t1.c1)::int OFFSET 100 LIMIT 10; - c1 | c1 ------+----- - 101 | 101 - 102 | 102 - 103 | 103 - 104 | 104 - 105 | 105 - 106 | 106 - 107 | 107 - 108 | 108 - 109 | 109 - 110 | 110 -(10 rows) - --- join where unsafe to pushdown condition in WHERE clause has a column not --- in the SELECT clause. In this test unsafe clause needs to have column --- references from both joining sides so that the clause is not pushed down --- into one of the joining sides. ---Testcase 166: -EXPLAIN (VERBOSE, COSTS OFF) -SELECT t1.c1, t2.c1 FROM (SELECT (fields->>'C 1')::int c1, (fields->>'c2')::int c2, tags->>'c3' c3, fields->>'c4' c4, fields->>'c5' c5, fields->>'c6' c6, fields->>'c7' c7, fields->>'c8' c8 FROM ft1 t1) t1 JOIN (SELECT (fields->>'C 1')::int c1, (fields->>'c2')::int c2, tags->>'c3' c3, fields->>'c4' c4, fields->>'c5' c5, fields->>'c6' c6, fields->>'c7' c7, fields->>'c8' c8 FROM ft2 t2) t2 ON ((t1.c1)::int = (t2.c1)::int) WHERE t1.c8 = t2.c8 ORDER BY t1.c3, (t1.c1)::int OFFSET 100 LIMIT 10; - QUERY PLAN -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- - Limit - Output: (((t1.fields ->> 'C 1'::text))::integer), (((t2.fields ->> 'C 1'::text))::integer), ((t1.tags ->> 'c3'::text)) - -> Sort - Output: (((t1.fields ->> 'C 1'::text))::integer), (((t2.fields ->> 'C 1'::text))::integer), ((t1.tags ->> 'c3'::text)) - Sort Key: ((t1.tags ->> 'c3'::text)), (((t1.fields ->> 'C 1'::text))::integer) - -> Merge Join - Output: (((t1.fields ->> 'C 1'::text))::integer), (((t2.fields ->> 'C 1'::text))::integer), (t1.tags ->> 'c3'::text) - Merge Cond: (((((t1.fields ->> 'C 1'::text))::integer) = (((t2.fields ->> 'C 1'::text))::integer)) AND (((t1.fields ->> 'c8'::text)) = ((t2.fields ->> 'c8'::text)))) - -> Sort - Output: t1.fields, t1.tags, (((t1.fields ->> 'C 1'::text))::integer), ((t1.fields ->> 'c8'::text)) - Sort Key: (((t1.fields ->> 'C 1'::text))::integer), ((t1.fields ->> 'c8'::text)) - -> Foreign Scan on public.ft1 t1 - Output: t1.fields, t1.tags, ((t1.fields ->> 'C 1'::text))::integer, (t1.fields ->> 'c8'::text) - InfluxDB query: SELECT * FROM "T1" - -> Sort - Output: t2.fields, (((t2.fields ->> 'C 1'::text))::integer), ((t2.fields ->> 'c8'::text)) - Sort Key: (((t2.fields ->> 'C 1'::text))::integer), ((t2.fields ->> 'c8'::text)) - -> Foreign Scan on public.ft2 t2 - Output: t2.fields, ((t2.fields ->> 'C 1'::text))::integer, (t2.fields ->> 'c8'::text) - InfluxDB query: SELECT * FROM "T1" -(20 rows) - ---Testcase 167: -SELECT t1.c1, t2.c1 FROM (SELECT (fields->>'C 1')::int c1, (fields->>'c2')::int c2, tags->>'c3' c3, fields->>'c4' c4, fields->>'c5' c5, fields->>'c6' c6, fields->>'c7' c7, fields->>'c8' c8 FROM ft1 t1) t1 JOIN (SELECT (fields->>'C 1')::int c1, (fields->>'c2')::int c2, tags->>'c3' c3, fields->>'c4' c4, fields->>'c5' c5, fields->>'c6' c6, fields->>'c7' c7, fields->>'c8' c8 FROM ft2 t2) t2 ON ((t1.c1)::int = (t2.c1)::int) WHERE t1.c8 = t2.c8 ORDER BY t1.c3, (t1.c1)::int OFFSET 100 LIMIT 10; - c1 | c1 ------+----- - 101 | 101 - 102 | 102 - 103 | 103 - 104 | 104 - 105 | 105 - 106 | 106 - 107 | 107 - 108 | 108 - 109 | 109 - 110 | 110 -(10 rows) - --- Aggregate after UNION, for testing setrefs ---Testcase 168: -EXPLAIN (VERBOSE, COSTS OFF) -SELECT t1c1, avg(t1c1 + t2c1) FROM (SELECT (t1.c1)::int, (t2.c1)::int FROM (SELECT (fields->>'C 1')::int c1, (fields->>'c2')::int c2, tags->>'c3' c3, fields->>'c4' c4, fields->>'c5' c5, fields->>'c6' c6, fields->>'c7' c7, fields->>'c8' c8 FROM ft1 t1) t1 JOIN (SELECT (fields->>'C 1')::int c1, (fields->>'c2')::int c2, tags->>'c3' c3, fields->>'c4' c4, fields->>'c5' c5, fields->>'c6' c6, fields->>'c7' c7, fields->>'c8' c8 FROM ft2 t2) t2 ON ((t1.c1)::int = (t2.c1)::int) UNION SELECT (t1.c1)::int, (t2.c1)::int FROM (SELECT (fields->>'C 1')::int c1, (fields->>'c2')::int c2, tags->>'c3' c3, fields->>'c4' c4, fields->>'c5' c5, fields->>'c6' c6, fields->>'c7' c7, fields->>'c8' c8 FROM ft1 t1) t1 JOIN (SELECT (fields->>'C 1')::int c1, (fields->>'c2')::int c2, tags->>'c3' c3, fields->>'c4' c4, fields->>'c5' c5, fields->>'c6' c6, fields->>'c7' c7, fields->>'c8' c8 FROM ft2 t2) t2 ON ((t1.c1)::int = (t2.c1)::int)) AS t (t1c1, t2c1) GROUP BY t1c1 ORDER BY t1c1 OFFSET 100 LIMIT 10; - QUERY PLAN ------------------------------------------------------------------------------------------------------------------------------------------------------------- - Limit - Output: (((t1.fields ->> 'C 1'::text))::integer), (avg(((((t1.fields ->> 'C 1'::text))::integer) + (((t2.fields ->> 'C 1'::text))::integer)))) - -> Sort - Output: (((t1.fields ->> 'C 1'::text))::integer), (avg(((((t1.fields ->> 'C 1'::text))::integer) + (((t2.fields ->> 'C 1'::text))::integer)))) - Sort Key: (((t1.fields ->> 'C 1'::text))::integer) - -> HashAggregate - Output: (((t1.fields ->> 'C 1'::text))::integer), avg(((((t1.fields ->> 'C 1'::text))::integer) + (((t2.fields ->> 'C 1'::text))::integer))) - Group Key: (((t1.fields ->> 'C 1'::text))::integer) - -> HashAggregate - Output: (((t1.fields ->> 'C 1'::text))::integer), (((t2.fields ->> 'C 1'::text))::integer) - Group Key: (((t1.fields ->> 'C 1'::text))::integer), (((t2.fields ->> 'C 1'::text))::integer) - -> Append - -> Merge Join - Output: (((t1.fields ->> 'C 1'::text))::integer), (((t2.fields ->> 'C 1'::text))::integer) - Merge Cond: ((((t1.fields ->> 'C 1'::text))::integer) = (((t2.fields ->> 'C 1'::text))::integer)) - -> Sort - Output: t1.fields, (((t1.fields ->> 'C 1'::text))::integer) - Sort Key: (((t1.fields ->> 'C 1'::text))::integer) - -> Foreign Scan on public.ft1 t1 - Output: t1.fields, ((t1.fields ->> 'C 1'::text))::integer - InfluxDB query: SELECT * FROM "T1" - -> Sort - Output: t2.fields, (((t2.fields ->> 'C 1'::text))::integer) - Sort Key: (((t2.fields ->> 'C 1'::text))::integer) - -> Foreign Scan on public.ft2 t2 - Output: t2.fields, ((t2.fields ->> 'C 1'::text))::integer - InfluxDB query: SELECT * FROM "T1" - -> Merge Join - Output: (((t1_1.fields ->> 'C 1'::text))::integer), (((t2_1.fields ->> 'C 1'::text))::integer) - Merge Cond: ((((t1_1.fields ->> 'C 1'::text))::integer) = (((t2_1.fields ->> 'C 1'::text))::integer)) - -> Sort - Output: t1_1.fields, (((t1_1.fields ->> 'C 1'::text))::integer) - Sort Key: (((t1_1.fields ->> 'C 1'::text))::integer) - -> Foreign Scan on public.ft1 t1_1 - Output: t1_1.fields, ((t1_1.fields ->> 'C 1'::text))::integer - InfluxDB query: SELECT * FROM "T1" - -> Sort - Output: t2_1.fields, (((t2_1.fields ->> 'C 1'::text))::integer) - Sort Key: (((t2_1.fields ->> 'C 1'::text))::integer) - -> Foreign Scan on public.ft2 t2_1 - Output: t2_1.fields, ((t2_1.fields ->> 'C 1'::text))::integer - InfluxDB query: SELECT * FROM "T1" -(42 rows) - ---Testcase 169: -SELECT t1c1, avg(t1c1 + t2c1) FROM (SELECT (t1.c1)::int, (t2.c1)::int FROM (SELECT (fields->>'C 1')::int c1, (fields->>'c2')::int c2, tags->>'c3' c3, fields->>'c4' c4, fields->>'c5' c5, fields->>'c6' c6, fields->>'c7' c7, fields->>'c8' c8 FROM ft1 t1) t1 JOIN (SELECT (fields->>'C 1')::int c1, (fields->>'c2')::int c2, tags->>'c3' c3, fields->>'c4' c4, fields->>'c5' c5, fields->>'c6' c6, fields->>'c7' c7, fields->>'c8' c8 FROM ft2 t2) t2 ON ((t1.c1)::int = (t2.c1)::int) UNION SELECT (t1.c1)::int, (t2.c1)::int FROM (SELECT (fields->>'C 1')::int c1, (fields->>'c2')::int c2, tags->>'c3' c3, fields->>'c4' c4, fields->>'c5' c5, fields->>'c6' c6, fields->>'c7' c7, fields->>'c8' c8 FROM ft1 t1) t1 JOIN (SELECT (fields->>'C 1')::int c1, (fields->>'c2')::int c2, tags->>'c3' c3, fields->>'c4' c4, fields->>'c5' c5, fields->>'c6' c6, fields->>'c7' c7, fields->>'c8' c8 FROM ft2 t2) t2 ON ((t1.c1)::int = (t2.c1)::int)) AS t (t1c1, t2c1) GROUP BY t1c1 ORDER BY t1c1 OFFSET 100 LIMIT 10; - t1c1 | avg -------+---------------------- - 101 | 202.0000000000000000 - 102 | 204.0000000000000000 - 103 | 206.0000000000000000 - 104 | 208.0000000000000000 - 105 | 210.0000000000000000 - 106 | 212.0000000000000000 - 107 | 214.0000000000000000 - 108 | 216.0000000000000000 - 109 | 218.0000000000000000 - 110 | 220.0000000000000000 -(10 rows) - --- join with lateral reference ---Testcase 170: -EXPLAIN (VERBOSE, COSTS OFF) -SELECT t1."C 1" FROM (SELECT (fields->>'C 1')::int "C 1", (fields->>'c2')::int c2, tags->>'c3' c3, fields->>'c4' c4, fields->>'c5' c5, fields->>'c6' c6, fields->>'c7' c7, fields->>'c8' c8 FROM "S 1"."T 1" t1) t1, LATERAL (SELECT DISTINCT t2.fields->>'C 1', t3.fields->>'C 1' FROM ft1 t2, ft2 t3 WHERE (t2.fields->>'C 1')::int = (t3.fields->>'C 1')::int AND (t2.fields->>'c2')::int = (t1.c2)::int) q ORDER BY (t1."C 1")::int OFFSET 10 LIMIT 10; - QUERY PLAN ------------------------------------------------------------------------------------------------------------------------------- - Limit - Output: (((t1.fields ->> 'C 1'::text))::integer) - -> Sort - Output: (((t1.fields ->> 'C 1'::text))::integer) - Sort Key: (((t1.fields ->> 'C 1'::text))::integer) - -> Nested Loop - Output: ((t1.fields ->> 'C 1'::text))::integer - -> Foreign Scan on "S 1"."T 1" t1 - Output: t1."time", t1.tags, t1.fields - InfluxDB query: SELECT * FROM "T1" - -> Unique - Output: ((t2.fields ->> 'C 1'::text)), ((t3.fields ->> 'C 1'::text)) - -> Sort - Output: ((t2.fields ->> 'C 1'::text)), ((t3.fields ->> 'C 1'::text)) - Sort Key: ((t2.fields ->> 'C 1'::text)), ((t3.fields ->> 'C 1'::text)) - -> Hash Join - Output: (t2.fields ->> 'C 1'::text), (t3.fields ->> 'C 1'::text) - Hash Cond: (((t3.fields ->> 'C 1'::text))::integer = ((t2.fields ->> 'C 1'::text))::integer) - -> Foreign Scan on public.ft2 t3 - Output: t3."time", t3.tags, t3.fields - InfluxDB query: SELECT * FROM "T1" - -> Hash - Output: t2.fields - -> Foreign Scan on public.ft1 t2 - Output: t2.fields - InfluxDB query: SELECT * FROM "T1" WHERE (("c2" = $1)) -(26 rows) - ---Testcase 171: -SELECT t1."C 1" FROM (SELECT (fields->>'C 1')::int "C 1", (fields->>'c2')::int c2, tags->>'c3' c3, fields->>'c4' c4, fields->>'c5' c5, fields->>'c6' c6, fields->>'c7' c7, fields->>'c8' c8 FROM "S 1"."T 1" t1) t1, LATERAL (SELECT DISTINCT t2.fields->>'C 1', t3.fields->>'C 1' FROM ft1 t2, ft2 t3 WHERE (t2.fields->>'C 1')::int = (t3.fields->>'C 1')::int AND (t2.fields->>'c2')::int = (t1.c2)::int) q ORDER BY (t1."C 1")::int OFFSET 10 LIMIT 10; - C 1 ------ - 1 - 1 - 1 - 1 - 1 - 1 - 1 - 1 - 1 - 1 -(10 rows) - --- non-Var items in targetlist of the nullable rel of a join preventing --- push-down in some cases --- unable to push {ft1, ft2} ---Testcase 172: -EXPLAIN (VERBOSE, COSTS OFF) -SELECT q.a, (ft2.fields->>'C 1')::int c1 FROM (SELECT 13 FROM ft1 WHERE (fields->>'C 1')::int = 13) q(a) RIGHT JOIN ft2 ON (q.a = (ft2.fields->>'C 1')::int) WHERE (ft2.fields->>'C 1')::int BETWEEN 10 AND 15; - QUERY PLAN --------------------------------------------------------------------------------------- - Nested Loop Left Join - Output: (13), ((ft2.fields ->> 'C 1'::text))::integer - Join Filter: (13 = ((ft2.fields ->> 'C 1'::text))::integer) - -> Foreign Scan on public.ft2 - Output: ft2."time", ft2.tags, ft2.fields - InfluxDB query: SELECT * FROM "T1" WHERE (("C 1" >= 10)) AND (("C 1" <= 15)) - -> Materialize - Output: (13) - -> Foreign Scan on public.ft1 - Output: 13 - InfluxDB query: SELECT * FROM "T1" WHERE (("C 1" = 13)) -(11 rows) - ---Testcase 173: -SELECT q.a, (ft2.fields->>'C 1')::int c1 FROM (SELECT 13 FROM ft1 WHERE (fields->>'C 1')::int = 13) q(a) RIGHT JOIN ft2 ON (q.a = (ft2.fields->>'C 1')::int) WHERE (ft2.fields->>'C 1')::int BETWEEN 10 AND 15; - a | c1 -----+---- - | 10 - | 11 - | 12 - 13 | 13 - | 14 - | 15 -(6 rows) - --- ok to push {ft1, ft2} but not {ft1, ft2, ft4} ---Testcase 174: -EXPLAIN (VERBOSE, COSTS OFF) -SELECT (ft4.fields->>'c1')::int c1, q.* FROM ft4 LEFT JOIN (SELECT 13, (ft1.fields->>'C 1')::int, (ft2.fields->>'C 1')::int FROM ft1 RIGHT JOIN ft2 ON ((ft1.fields->>'C 1')::int = (ft2.fields->>'C 1')::int) WHERE (ft1.fields->>'C 1')::int = 12) q(a, b, c) ON ((ft4.fields->>'c1')::int = q.b) WHERE (ft4.fields->>'c1')::int BETWEEN 10 AND 15; - QUERY PLAN ------------------------------------------------------------------------------------------------------------------------------------------- - Hash Right Join - Output: ((ft4.fields ->> 'c1'::text))::integer, (13), ((ft1.fields ->> 'C 1'::text))::integer, ((ft2.fields ->> 'C 1'::text))::integer - Hash Cond: (((ft1.fields ->> 'C 1'::text))::integer = ((ft4.fields ->> 'c1'::text))::integer) - -> Nested Loop - Output: ft1.fields, ft2.fields, 13 - -> Foreign Scan on public.ft1 - Output: ft1."time", ft1.tags, ft1.fields - InfluxDB query: SELECT * FROM "T1" WHERE (("C 1" = 12)) - -> Materialize - Output: ft2.fields - -> Foreign Scan on public.ft2 - Output: ft2.fields - InfluxDB query: SELECT * FROM "T1" WHERE (("C 1" = 12)) - -> Hash - Output: ft4.fields - -> Foreign Scan on public.ft4 - Output: ft4.fields - InfluxDB query: SELECT * FROM "T3" WHERE (("c1" >= 10)) AND (("c1" <= 15)) -(18 rows) - ---Testcase 175: -SELECT (ft4.fields->>'c1')::int c1, q.* FROM ft4 LEFT JOIN (SELECT 13, (ft1.fields->>'C 1')::int, (ft2.fields->>'C 1')::int FROM ft1 RIGHT JOIN ft2 ON ((ft1.fields->>'C 1')::int = (ft2.fields->>'C 1')::int) WHERE (ft1.fields->>'C 1')::int = 12) q(a, b, c) ON ((ft4.fields->>'c1')::int = q.b) WHERE (ft4.fields->>'c1')::int BETWEEN 10 AND 15 ORDER BY (ft4.fields->>'c1')::int; - c1 | a | b | c -----+----+----+---- - 10 | | | - 12 | 13 | 12 | 12 - 14 | | | -(3 rows) - --- join with nullable side with some columns with null values --- influxdb_fdw does not support UPDATE --- UPDATE ft5 SET c3 = null where c1 % 9 = 0; ---Testcase 176: -EXPLAIN (VERBOSE, COSTS OFF) -SELECT ft5, (ft5.fields->>'c1')::int c1, (ft5.fields->>'c2')::int c2, ft5.tags->>'c3' c3, (ft4.fields->>'c1')::int c1, (ft4.fields->>'c2')::int c2 FROM ft5 left join ft4 on (ft5.fields->>'c1')::int = (ft4.fields->>'c1')::int WHERE (ft4.fields->>'c1')::int BETWEEN 10 and 30 ORDER BY (ft5.fields->>'c1')::int, (ft4.fields->>'c1')::int; - QUERY PLAN ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- - Sort - Output: ft5.*, (((ft5.fields ->> 'c1'::text))::integer), (((ft5.fields ->> 'c2'::text))::integer), ((ft5.tags ->> 'c3'::text)), (((ft4.fields ->> 'c1'::text))::integer), (((ft4.fields ->> 'c2'::text))::integer) - Sort Key: (((ft5.fields ->> 'c1'::text))::integer) - -> Hash Join - Output: ft5.*, ((ft5.fields ->> 'c1'::text))::integer, ((ft5.fields ->> 'c2'::text))::integer, (ft5.tags ->> 'c3'::text), ((ft4.fields ->> 'c1'::text))::integer, ((ft4.fields ->> 'c2'::text))::integer - Hash Cond: (((ft5.fields ->> 'c1'::text))::integer = ((ft4.fields ->> 'c1'::text))::integer) - -> Foreign Scan on public.ft5 - Output: ft5.*, ft5.fields, ft5.tags - InfluxDB query: SELECT * FROM "T4" - -> Hash - Output: ft4.fields - -> Foreign Scan on public.ft4 - Output: ft4.fields - InfluxDB query: SELECT * FROM "T3" WHERE (("c1" >= 10)) AND (("c1" <= 30)) -(14 rows) - ---Testcase 177: -SELECT ft5, (ft5.fields->>'c1')::int c1, (ft5.fields->>'c2')::int c2, ft5.tags->>'c3' c3, (ft4.fields->>'c1')::int c1, (ft4.fields->>'c2')::int c2 FROM ft5 left join ft4 on (ft5.fields->>'c1')::int = (ft4.fields->>'c1')::int WHERE (ft4.fields->>'c1')::int BETWEEN 10 and 30 ORDER BY (ft5.fields->>'c1')::int, (ft4.fields->>'c1')::int; - ft5 | c1 | c2 | c3 | c1 | c2 --------------------------------------------------------------+----+----+--------+----+---- - ("{""c3"": ""AAA012""}","{""c1"": ""12"", ""c2"": ""13""}") | 12 | 13 | AAA012 | 12 | 13 - ("{""c3"": ""AAA018""}","{""c1"": ""18"", ""c2"": ""19""}") | 18 | 19 | AAA018 | 18 | 19 - ("{""c3"": ""AAA024""}","{""c1"": ""24"", ""c2"": ""25""}") | 24 | 25 | AAA024 | 24 | 25 - ("{""c3"": ""AAA030""}","{""c1"": ""30"", ""c2"": ""31""}") | 30 | 31 | AAA030 | 30 | 31 -(4 rows) - --- multi-way join involving multiple merge joins --- (this case used to have EPQ-related planning problems) ---Testcase 178: -CREATE FOREIGN TABLE local_tbl (fields jsonb OPTIONS(fields 'true')) SERVER influxdb_svr OPTIONS (table 'local_tbl', schemaless 'true'); -CREATE FOREIGN TABLE local_tbl_nsc (c1 int NOT NULL, c2 int NOT NULL, c3 text) SERVER influxdb_svr OPTIONS (table 'local_tbl'); ---Testcase 179: -INSERT INTO local_tbl_nsc SELECT id, id % 10, to_char(id, 'FM0000') FROM generate_series(1, 1000) id; ---ANALYZE local_tbl; -SET enable_nestloop TO false; -SET enable_hashjoin TO false; ---Testcase 180: -EXPLAIN (VERBOSE, COSTS OFF) -SELECT * FROM ft1, ft2, ft4, ft5, local_tbl WHERE (ft1.fields->>'C 1')::int = (ft2.fields->>'C 1')::int AND (ft1.fields->>'c2')::int = (ft4.fields->>'c1')::int - AND (ft1.fields->>'c2')::int = (ft5.fields->>'c1')::int AND (ft1.fields->>'c2')::int = (local_tbl.fields->>'c1')::int AND (ft1.fields->>'C 1')::int < 100 AND (ft2.fields->>'C 1')::int < 100 ORDER BY (ft1.fields->>'C 1')::int FOR UPDATE; - QUERY PLAN ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- - LockRows - Output: ft1."time", ft1.tags, ft1.fields, ft2."time", ft2.tags, ft2.fields, ft4.tags, ft4.fields, ft5.tags, ft5.fields, local_tbl.fields, (((ft1.fields ->> 'C 1'::text))::integer), ft1.*, ft2.*, ft4.*, ft5.*, local_tbl.* - -> Sort - Output: ft1."time", ft1.tags, ft1.fields, ft2."time", ft2.tags, ft2.fields, ft4.tags, ft4.fields, ft5.tags, ft5.fields, local_tbl.fields, (((ft1.fields ->> 'C 1'::text))::integer), ft1.*, ft2.*, ft4.*, ft5.*, local_tbl.* - Sort Key: (((ft1.fields ->> 'C 1'::text))::integer) - -> Merge Join - Output: ft1."time", ft1.tags, ft1.fields, ft2."time", ft2.tags, ft2.fields, ft4.tags, ft4.fields, ft5.tags, ft5.fields, local_tbl.fields, ((ft1.fields ->> 'C 1'::text))::integer, ft1.*, ft2.*, ft4.*, ft5.*, local_tbl.* - Merge Cond: (((ft1.fields ->> 'c2'::text))::integer = (((local_tbl.fields ->> 'c1'::text))::integer)) - -> Merge Join - Output: ft1."time", ft1.tags, ft1.fields, ft1.*, ft2."time", ft2.tags, ft2.fields, ft2.*, ft4.tags, ft4.fields, ft4.*, ft5.tags, ft5.fields, ft5.* - Merge Cond: (((ft1.fields ->> 'c2'::text))::integer = (((ft5.fields ->> 'c1'::text))::integer)) - -> Merge Join - Output: ft1."time", ft1.tags, ft1.fields, ft1.*, ft2."time", ft2.tags, ft2.fields, ft2.*, ft4.tags, ft4.fields, ft4.* - Merge Cond: ((((ft1.fields ->> 'c2'::text))::integer) = (((ft4.fields ->> 'c1'::text))::integer)) - -> Sort - Output: ft1."time", ft1.tags, ft1.fields, ft1.*, ft2."time", ft2.tags, ft2.fields, ft2.*, (((ft1.fields ->> 'c2'::text))::integer) - Sort Key: (((ft1.fields ->> 'c2'::text))::integer) - -> Merge Join - Output: ft1."time", ft1.tags, ft1.fields, ft1.*, ft2."time", ft2.tags, ft2.fields, ft2.*, ((ft1.fields ->> 'c2'::text))::integer - Merge Cond: ((((ft1.fields ->> 'C 1'::text))::integer) = (((ft2.fields ->> 'C 1'::text))::integer)) - -> Sort - Output: ft1."time", ft1.tags, ft1.fields, ft1.*, (((ft1.fields ->> 'C 1'::text))::integer) - Sort Key: (((ft1.fields ->> 'C 1'::text))::integer) - -> Foreign Scan on public.ft1 - Output: ft1."time", ft1.tags, ft1.fields, ft1.*, ((ft1.fields ->> 'C 1'::text))::integer - InfluxDB query: SELECT * FROM "T1" WHERE (("C 1" < 100)) - -> Sort - Output: ft2."time", ft2.tags, ft2.fields, ft2.*, (((ft2.fields ->> 'C 1'::text))::integer) - Sort Key: (((ft2.fields ->> 'C 1'::text))::integer) - -> Foreign Scan on public.ft2 - Output: ft2."time", ft2.tags, ft2.fields, ft2.*, ((ft2.fields ->> 'C 1'::text))::integer - InfluxDB query: SELECT * FROM "T1" WHERE (("C 1" < 100)) - -> Sort - Output: ft4.tags, ft4.fields, ft4.*, (((ft4.fields ->> 'c1'::text))::integer) - Sort Key: (((ft4.fields ->> 'c1'::text))::integer) - -> Foreign Scan on public.ft4 - Output: ft4.tags, ft4.fields, ft4.*, ((ft4.fields ->> 'c1'::text))::integer - InfluxDB query: SELECT * FROM "T3" - -> Sort - Output: ft5.tags, ft5.fields, ft5.*, (((ft5.fields ->> 'c1'::text))::integer) - Sort Key: (((ft5.fields ->> 'c1'::text))::integer) - -> Foreign Scan on public.ft5 - Output: ft5.tags, ft5.fields, ft5.*, ((ft5.fields ->> 'c1'::text))::integer - InfluxDB query: SELECT * FROM "T4" - -> Sort - Output: local_tbl.fields, local_tbl.*, (((local_tbl.fields ->> 'c1'::text))::integer) - Sort Key: (((local_tbl.fields ->> 'c1'::text))::integer) - -> Foreign Scan on public.local_tbl - Output: local_tbl.fields, local_tbl.*, ((local_tbl.fields ->> 'c1'::text))::integer - InfluxDB query: SELECT * FROM "local_tbl" -(50 rows) - ---Testcase 181: -SELECT * FROM ft1, ft2, ft4, ft5, local_tbl WHERE (ft1.fields->>'C 1')::int = (ft2.fields->>'C 1')::int AND (ft1.fields->>'c2')::int = (ft4.fields->>'c1')::int - AND (ft1.fields->>'c2')::int = (ft5.fields->>'c1')::int AND (ft1.fields->>'c2')::int = (local_tbl.fields->>'c1')::int AND (ft1.fields->>'C 1')::int < 100 AND (ft2.fields->>'C 1')::int < 100 ORDER BY (ft1.fields->>'C 1')::int FOR UPDATE; - time | tags | fields | time | tags | fields | tags | fields | tags | fields | fields ---------------------------+-----------------+----------------------------------------------------------------------+--------------------------+-----------------+----------------------------------------------------------------------+------------------+------------------------+------------------+------------------------+-------------------------------------- - Wed Jan 07 00:00:00 1970 | {"c3": "00006"} | {"c2": "6", "c6": "6", "c7": "6 ", "c8": "foo", "C 1": "6"} | Wed Jan 07 00:00:00 1970 | {"c3": "00006"} | {"c2": "6", "c6": "6", "c7": "6 ", "c8": "foo", "C 1": "6"} | {"c3": "AAA006"} | {"c1": "6", "c2": "7"} | {"c3": "AAA006"} | {"c1": "6", "c2": "7"} | {"c1": "6", "c2": "6", "c3": "0006"} - Sat Jan 17 00:00:00 1970 | {"c3": "00016"} | {"c2": "6", "c6": "6", "c7": "6 ", "c8": "foo", "C 1": "16"} | Sat Jan 17 00:00:00 1970 | {"c3": "00016"} | {"c2": "6", "c6": "6", "c7": "6 ", "c8": "foo", "C 1": "16"} | {"c3": "AAA006"} | {"c1": "6", "c2": "7"} | {"c3": "AAA006"} | {"c1": "6", "c2": "7"} | {"c1": "6", "c2": "6", "c3": "0006"} - Tue Jan 27 00:00:00 1970 | {"c3": "00026"} | {"c2": "6", "c6": "6", "c7": "6 ", "c8": "foo", "C 1": "26"} | Tue Jan 27 00:00:00 1970 | {"c3": "00026"} | {"c2": "6", "c6": "6", "c7": "6 ", "c8": "foo", "C 1": "26"} | {"c3": "AAA006"} | {"c1": "6", "c2": "7"} | {"c3": "AAA006"} | {"c1": "6", "c2": "7"} | {"c1": "6", "c2": "6", "c3": "0006"} - Fri Feb 06 00:00:00 1970 | {"c3": "00036"} | {"c2": "6", "c6": "6", "c7": "6 ", "c8": "foo", "C 1": "36"} | Fri Feb 06 00:00:00 1970 | {"c3": "00036"} | {"c2": "6", "c6": "6", "c7": "6 ", "c8": "foo", "C 1": "36"} | {"c3": "AAA006"} | {"c1": "6", "c2": "7"} | {"c3": "AAA006"} | {"c1": "6", "c2": "7"} | {"c1": "6", "c2": "6", "c3": "0006"} - Mon Feb 16 00:00:00 1970 | {"c3": "00046"} | {"c2": "6", "c6": "6", "c7": "6 ", "c8": "foo", "C 1": "46"} | Mon Feb 16 00:00:00 1970 | {"c3": "00046"} | {"c2": "6", "c6": "6", "c7": "6 ", "c8": "foo", "C 1": "46"} | {"c3": "AAA006"} | {"c1": "6", "c2": "7"} | {"c3": "AAA006"} | {"c1": "6", "c2": "7"} | {"c1": "6", "c2": "6", "c3": "0006"} - Thu Feb 26 00:00:00 1970 | {"c3": "00056"} | {"c2": "6", "c6": "6", "c7": "6 ", "c8": "foo", "C 1": "56"} | Thu Feb 26 00:00:00 1970 | {"c3": "00056"} | {"c2": "6", "c6": "6", "c7": "6 ", "c8": "foo", "C 1": "56"} | {"c3": "AAA006"} | {"c1": "6", "c2": "7"} | {"c3": "AAA006"} | {"c1": "6", "c2": "7"} | {"c1": "6", "c2": "6", "c3": "0006"} - Sun Mar 08 00:00:00 1970 | {"c3": "00066"} | {"c2": "6", "c6": "6", "c7": "6 ", "c8": "foo", "C 1": "66"} | Sun Mar 08 00:00:00 1970 | {"c3": "00066"} | {"c2": "6", "c6": "6", "c7": "6 ", "c8": "foo", "C 1": "66"} | {"c3": "AAA006"} | {"c1": "6", "c2": "7"} | {"c3": "AAA006"} | {"c1": "6", "c2": "7"} | {"c1": "6", "c2": "6", "c3": "0006"} - Wed Mar 18 00:00:00 1970 | {"c3": "00076"} | {"c2": "6", "c6": "6", "c7": "6 ", "c8": "foo", "C 1": "76"} | Wed Mar 18 00:00:00 1970 | {"c3": "00076"} | {"c2": "6", "c6": "6", "c7": "6 ", "c8": "foo", "C 1": "76"} | {"c3": "AAA006"} | {"c1": "6", "c2": "7"} | {"c3": "AAA006"} | {"c1": "6", "c2": "7"} | {"c1": "6", "c2": "6", "c3": "0006"} - Sat Mar 28 00:00:00 1970 | {"c3": "00086"} | {"c2": "6", "c6": "6", "c7": "6 ", "c8": "foo", "C 1": "86"} | Sat Mar 28 00:00:00 1970 | {"c3": "00086"} | {"c2": "6", "c6": "6", "c7": "6 ", "c8": "foo", "C 1": "86"} | {"c3": "AAA006"} | {"c1": "6", "c2": "7"} | {"c3": "AAA006"} | {"c1": "6", "c2": "7"} | {"c1": "6", "c2": "6", "c3": "0006"} - Tue Apr 07 00:00:00 1970 | {"c3": "00096"} | {"c2": "6", "c6": "6", "c7": "6 ", "c8": "foo", "C 1": "96"} | Tue Apr 07 00:00:00 1970 | {"c3": "00096"} | {"c2": "6", "c6": "6", "c7": "6 ", "c8": "foo", "C 1": "96"} | {"c3": "AAA006"} | {"c1": "6", "c2": "7"} | {"c3": "AAA006"} | {"c1": "6", "c2": "7"} | {"c1": "6", "c2": "6", "c3": "0006"} -(10 rows) - -RESET enable_nestloop; -RESET enable_hashjoin; ---Testcase 182: -DELETE FROM local_tbl_nsc; -DROP FOREIGN TABLE local_tbl; -DROP FOREIGN TABLE local_tbl_nsc; --- check join pushdown in situations where multiple userids are involved ---Testcase 183: -CREATE ROLE regress_view_owner SUPERUSER; ---Testcase 184: -CREATE USER MAPPING FOR regress_view_owner SERVER influxdb_svr OPTIONS (:AUTHENTICATION); -GRANT SELECT ON ft4 TO regress_view_owner; -GRANT SELECT ON ft5 TO regress_view_owner; ---Testcase 185: -CREATE VIEW v4 AS SELECT * FROM ft4; ---Testcase 186: -CREATE VIEW v5 AS SELECT * FROM ft5; -ALTER VIEW v5 OWNER TO regress_view_owner; ---Testcase 187: -EXPLAIN (VERBOSE, COSTS OFF) -SELECT t1.c1, t2.c2 FROM (SELECT (fields->>'c1')::int c1, (fields->>'c2')::int c2, tags->>'c3' c3 FROM v4 t1) t1 LEFT JOIN (SELECT (fields->>'c1')::int c1, (fields->>'c2')::int c2, tags->>'c3' c3 FROM v5 t2) t2 ON ((t1.c1)::int = (t2.c1)::int) ORDER BY (t1.c1)::int, (t2.c1)::int OFFSET 10 LIMIT 10; -- can't be pushed down, different view owners - QUERY PLAN ------------------------------------------------------------------------------------------------------------------------------------------------- - Limit - Output: (((ft4.fields ->> 'c1'::text))::integer), (((ft5.fields ->> 'c2'::text))::integer), (((ft5.fields ->> 'c1'::text))::integer) - -> Sort - Output: (((ft4.fields ->> 'c1'::text))::integer), (((ft5.fields ->> 'c2'::text))::integer), (((ft5.fields ->> 'c1'::text))::integer) - Sort Key: (((ft4.fields ->> 'c1'::text))::integer), (((ft5.fields ->> 'c1'::text))::integer) - -> Merge Left Join - Output: (((ft4.fields ->> 'c1'::text))::integer), ((ft5.fields ->> 'c2'::text))::integer, ((ft5.fields ->> 'c1'::text))::integer - Merge Cond: ((((ft4.fields ->> 'c1'::text))::integer) = (((ft5.fields ->> 'c1'::text))::integer)) - -> Sort - Output: ft4.fields, (((ft4.fields ->> 'c1'::text))::integer) - Sort Key: (((ft4.fields ->> 'c1'::text))::integer) - -> Foreign Scan on public.ft4 - Output: ft4.fields, ((ft4.fields ->> 'c1'::text))::integer - InfluxDB query: SELECT * FROM "T3" - -> Sort - Output: ft5.fields, (((ft5.fields ->> 'c1'::text))::integer) - Sort Key: (((ft5.fields ->> 'c1'::text))::integer) - -> Foreign Scan on public.ft5 - Output: ft5.fields, ((ft5.fields ->> 'c1'::text))::integer - InfluxDB query: SELECT * FROM "T4" -(20 rows) - ---Testcase 188: -SELECT t1.c1, t2.c2 FROM (SELECT (fields->>'c1')::int c1, (fields->>'c2')::int c2, tags->>'c3' c3 FROM v4 t1) t1 LEFT JOIN (SELECT (fields->>'c1')::int c1, (fields->>'c2')::int c2, tags->>'c3' c3 FROM v5 t2) t2 ON ((t1.c1)::int = (t2.c1)::int) ORDER BY (t1.c1)::int, (t2.c1)::int OFFSET 10 LIMIT 10; - c1 | c2 -----+---- - 22 | - 24 | 25 - 26 | - 28 | - 30 | 31 - 32 | - 34 | - 36 | 37 - 38 | - 40 | -(10 rows) - -ALTER VIEW v4 OWNER TO regress_view_owner; ---Testcase 189: -EXPLAIN (VERBOSE, COSTS OFF) -SELECT t1.c1, t2.c2 FROM (SELECT (fields->>'c1')::int c1, (fields->>'c2')::int c2, tags->>'c3' c3 FROM v4 t1) t1 LEFT JOIN (SELECT (fields->>'c1')::int c1, (fields->>'c2')::int c2, tags->>'c3' c3 FROM v5 t2) t2 ON ((t1.c1)::int = (t2.c1)::int) ORDER BY (t1.c1)::int, (t2.c1)::int OFFSET 10 LIMIT 10; -- can be pushed down - QUERY PLAN ------------------------------------------------------------------------------------------------------------------------------------------------- - Limit - Output: (((ft4.fields ->> 'c1'::text))::integer), (((ft5.fields ->> 'c2'::text))::integer), (((ft5.fields ->> 'c1'::text))::integer) - -> Sort - Output: (((ft4.fields ->> 'c1'::text))::integer), (((ft5.fields ->> 'c2'::text))::integer), (((ft5.fields ->> 'c1'::text))::integer) - Sort Key: (((ft4.fields ->> 'c1'::text))::integer), (((ft5.fields ->> 'c1'::text))::integer) - -> Merge Left Join - Output: (((ft4.fields ->> 'c1'::text))::integer), ((ft5.fields ->> 'c2'::text))::integer, ((ft5.fields ->> 'c1'::text))::integer - Merge Cond: ((((ft4.fields ->> 'c1'::text))::integer) = (((ft5.fields ->> 'c1'::text))::integer)) - -> Sort - Output: ft4.fields, (((ft4.fields ->> 'c1'::text))::integer) - Sort Key: (((ft4.fields ->> 'c1'::text))::integer) - -> Foreign Scan on public.ft4 - Output: ft4.fields, ((ft4.fields ->> 'c1'::text))::integer - InfluxDB query: SELECT * FROM "T3" - -> Sort - Output: ft5.fields, (((ft5.fields ->> 'c1'::text))::integer) - Sort Key: (((ft5.fields ->> 'c1'::text))::integer) - -> Foreign Scan on public.ft5 - Output: ft5.fields, ((ft5.fields ->> 'c1'::text))::integer - InfluxDB query: SELECT * FROM "T4" -(20 rows) - ---Testcase 190: -SELECT t1.c1, t2.c2 FROM (SELECT (fields->>'c1')::int c1, (fields->>'c2')::int c2, tags->>'c3' c3 FROM v4 t1) t1 LEFT JOIN (SELECT (fields->>'c1')::int c1, (fields->>'c2')::int c2, tags->>'c3' c3 FROM v5 t2) t2 ON ((t1.c1)::int = (t2.c1)::int) ORDER BY (t1.c1)::int, (t2.c1)::int OFFSET 10 LIMIT 10; - c1 | c2 -----+---- - 22 | - 24 | 25 - 26 | - 28 | - 30 | 31 - 32 | - 34 | - 36 | 37 - 38 | - 40 | -(10 rows) - ---Testcase 191: -EXPLAIN (VERBOSE, COSTS OFF) -SELECT t1.c1, t2.c2 FROM (SELECT (fields->>'c1')::int c1, (fields->>'c2')::int c2, tags->>'c3' c3 FROM v4 t1) t1 LEFT JOIN (SELECT (fields->>'c1')::int c1, (fields->>'c2')::int c2, tags->>'c3' c3 FROM ft5 t2) t2 ON ((t1.c1)::int = (t2.c1)::int) ORDER BY (t1.c1)::int, (t2.c1)::int OFFSET 10 LIMIT 10; -- can't be pushed down, view owner not current user - QUERY PLAN ----------------------------------------------------------------------------------------------------------------------------------------------- - Limit - Output: (((ft4.fields ->> 'c1'::text))::integer), (((t2.fields ->> 'c2'::text))::integer), (((t2.fields ->> 'c1'::text))::integer) - -> Sort - Output: (((ft4.fields ->> 'c1'::text))::integer), (((t2.fields ->> 'c2'::text))::integer), (((t2.fields ->> 'c1'::text))::integer) - Sort Key: (((ft4.fields ->> 'c1'::text))::integer), (((t2.fields ->> 'c1'::text))::integer) - -> Merge Left Join - Output: (((ft4.fields ->> 'c1'::text))::integer), ((t2.fields ->> 'c2'::text))::integer, ((t2.fields ->> 'c1'::text))::integer - Merge Cond: ((((ft4.fields ->> 'c1'::text))::integer) = (((t2.fields ->> 'c1'::text))::integer)) - -> Sort - Output: ft4.fields, (((ft4.fields ->> 'c1'::text))::integer) - Sort Key: (((ft4.fields ->> 'c1'::text))::integer) - -> Foreign Scan on public.ft4 - Output: ft4.fields, ((ft4.fields ->> 'c1'::text))::integer - InfluxDB query: SELECT * FROM "T3" - -> Sort - Output: t2.fields, (((t2.fields ->> 'c1'::text))::integer) - Sort Key: (((t2.fields ->> 'c1'::text))::integer) - -> Foreign Scan on public.ft5 t2 - Output: t2.fields, ((t2.fields ->> 'c1'::text))::integer - InfluxDB query: SELECT * FROM "T4" -(20 rows) - ---Testcase 192: -SELECT t1.c1, t2.c2 FROM (SELECT (fields->>'c1')::int c1, (fields->>'c2')::int c2, tags->>'c3' c3 FROM v4 t1) t1 LEFT JOIN (SELECT (fields->>'c1')::int c1, (fields->>'c2')::int c2, tags->>'c3' c3 FROM ft5 t2) t2 ON ((t1.c1)::int = (t2.c1)::int) ORDER BY (t1.c1)::int, (t2.c1)::int OFFSET 10 LIMIT 10; - c1 | c2 -----+---- - 22 | - 24 | 25 - 26 | - 28 | - 30 | 31 - 32 | - 34 | - 36 | 37 - 38 | - 40 | -(10 rows) - -ALTER VIEW v4 OWNER TO CURRENT_USER; ---Testcase 193: -EXPLAIN (VERBOSE, COSTS OFF) -SELECT t1.c1, t2.c2 FROM (SELECT (fields->>'c1')::int c1, (fields->>'c2')::int c2, tags->>'c3' c3 FROM v4 t1) t1 LEFT JOIN (SELECT (fields->>'c1')::int c1, (fields->>'c2')::int c2, tags->>'c3' c3 FROM ft5 t2) t2 ON ((t1.c1)::int = (t2.c1)::int) ORDER BY (t1.c1)::int, (t2.c1)::int OFFSET 10 LIMIT 10; -- can be pushed down - QUERY PLAN ----------------------------------------------------------------------------------------------------------------------------------------------- - Limit - Output: (((ft4.fields ->> 'c1'::text))::integer), (((t2.fields ->> 'c2'::text))::integer), (((t2.fields ->> 'c1'::text))::integer) - -> Sort - Output: (((ft4.fields ->> 'c1'::text))::integer), (((t2.fields ->> 'c2'::text))::integer), (((t2.fields ->> 'c1'::text))::integer) - Sort Key: (((ft4.fields ->> 'c1'::text))::integer), (((t2.fields ->> 'c1'::text))::integer) - -> Merge Left Join - Output: (((ft4.fields ->> 'c1'::text))::integer), ((t2.fields ->> 'c2'::text))::integer, ((t2.fields ->> 'c1'::text))::integer - Merge Cond: ((((ft4.fields ->> 'c1'::text))::integer) = (((t2.fields ->> 'c1'::text))::integer)) - -> Sort - Output: ft4.fields, (((ft4.fields ->> 'c1'::text))::integer) - Sort Key: (((ft4.fields ->> 'c1'::text))::integer) - -> Foreign Scan on public.ft4 - Output: ft4.fields, ((ft4.fields ->> 'c1'::text))::integer - InfluxDB query: SELECT * FROM "T3" - -> Sort - Output: t2.fields, (((t2.fields ->> 'c1'::text))::integer) - Sort Key: (((t2.fields ->> 'c1'::text))::integer) - -> Foreign Scan on public.ft5 t2 - Output: t2.fields, ((t2.fields ->> 'c1'::text))::integer - InfluxDB query: SELECT * FROM "T4" -(20 rows) - ---Testcase 194: -SELECT t1.c1, t2.c2 FROM (SELECT (fields->>'c1')::int c1, (fields->>'c2')::int c2, tags->>'c3' c3 FROM v4 t1) t1 LEFT JOIN (SELECT (fields->>'c1')::int c1, (fields->>'c2')::int c2, tags->>'c3' c3 FROM ft5 t2) t2 ON ((t1.c1)::int = (t2.c1)::int) ORDER BY (t1.c1)::int, (t2.c1)::int OFFSET 10 LIMIT 10; - c1 | c2 -----+---- - 22 | - 24 | 25 - 26 | - 28 | - 30 | 31 - 32 | - 34 | - 36 | 37 - 38 | - 40 | -(10 rows) - -ALTER VIEW v4 OWNER TO regress_view_owner; --- cleanup ---Testcase 195: -DROP OWNED BY regress_view_owner; ---Testcase 196: -DROP ROLE regress_view_owner; --- =================================================================== --- Aggregate and grouping queries --- =================================================================== --- Simple aggregates ---Testcase 197: -explain (verbose, costs off) -select count(fields->>'c6'), sum((fields->>'C 1')::int), avg((fields->>'C 1')::int), min((fields->>'c2')::int), max((fields->>'C 1')::int), stddev((fields->>'c2')::int), sum((fields->>'C 1')::int) * (random() <= 1)::int as sum2 from ft1 where (fields->>'c2')::int < 5 group by fields->>'c2' order by 1, 2; - QUERY PLAN -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- - Result - Output: (count((fields ->> 'c6'::text))), (sum(((fields ->> 'C 1'::text))::integer)), (avg(((fields ->> 'C 1'::text))::integer)), (min((((fields ->> 'c2'::text)))::integer)), (max(((fields ->> 'C 1'::text))::integer)), (stddev((((fields ->> 'c2'::text)))::integer)), ((sum(((fields ->> 'C 1'::text))::integer)) * ((random() <= '1'::double precision))::integer), ((fields ->> 'c2'::text)) - -> Sort - Output: (count((fields ->> 'c6'::text))), (sum(((fields ->> 'C 1'::text))::integer)), (avg(((fields ->> 'C 1'::text))::integer)), (min((((fields ->> 'c2'::text)))::integer)), (max(((fields ->> 'C 1'::text))::integer)), (stddev((((fields ->> 'c2'::text)))::integer)), ((fields ->> 'c2'::text)) - Sort Key: (count((ft1.fields ->> 'c6'::text))), (sum(((ft1.fields ->> 'C 1'::text))::integer)) - -> HashAggregate - Output: count((fields ->> 'c6'::text)), sum(((fields ->> 'C 1'::text))::integer), avg(((fields ->> 'C 1'::text))::integer), min((((fields ->> 'c2'::text)))::integer), max(((fields ->> 'C 1'::text))::integer), stddev((((fields ->> 'c2'::text)))::integer), ((fields ->> 'c2'::text)) - Group Key: (ft1.fields ->> 'c2'::text) - -> Foreign Scan on public.ft1 - Output: (fields ->> 'c2'::text), fields - InfluxDB query: SELECT * FROM "T1" WHERE (("c2" < 5)) -(11 rows) - ---Testcase 198: -select count(fields->>'c6'), sum((fields->>'C 1')::int), avg((fields->>'C 1')::int), min((fields->>'c2')::int), max((fields->>'C 1')::int), stddev((fields->>'c2')::int), sum((fields->>'C 1')::int) * (random() <= 1)::int as sum2 from ft1 where (fields->>'c2')::int < 5 group by fields->>'c2' order by 1, 2; - count | sum | avg | min | max | stddev | sum2 --------+-------+----------------------+-----+------+--------+------- - 100 | 49600 | 496.0000000000000000 | 1 | 991 | 0 | 49600 - 100 | 49700 | 497.0000000000000000 | 2 | 992 | 0 | 49700 - 100 | 49800 | 498.0000000000000000 | 3 | 993 | 0 | 49800 - 100 | 49900 | 499.0000000000000000 | 4 | 994 | 0 | 49900 - 100 | 50500 | 505.0000000000000000 | 0 | 1000 | 0 | 50500 -(5 rows) - ---Testcase 199: -explain (verbose, costs off) -select count(fields->>'c6'), sum((fields->>'C 1')::int), avg((fields->>'C 1')::int), min((fields->>'c2')::int), max((fields->>'C 1')::int), stddev((fields->>'c2')::int), sum((fields->>'C 1')::int) * (random() <= 1)::int as sum2 from ft1 where (fields->>'c2')::int < 5 group by fields->>'c2' order by 1, 2 limit 1; - QUERY PLAN -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- - Limit - Output: (count((fields ->> 'c6'::text))), (sum(((fields ->> 'C 1'::text))::integer)), (avg(((fields ->> 'C 1'::text))::integer)), (min((((fields ->> 'c2'::text)))::integer)), (max(((fields ->> 'C 1'::text))::integer)), (stddev((((fields ->> 'c2'::text)))::integer)), (((sum(((fields ->> 'C 1'::text))::integer)) * ((random() <= '1'::double precision))::integer)), ((fields ->> 'c2'::text)) - -> Result - Output: (count((fields ->> 'c6'::text))), (sum(((fields ->> 'C 1'::text))::integer)), (avg(((fields ->> 'C 1'::text))::integer)), (min((((fields ->> 'c2'::text)))::integer)), (max(((fields ->> 'C 1'::text))::integer)), (stddev((((fields ->> 'c2'::text)))::integer)), ((sum(((fields ->> 'C 1'::text))::integer)) * ((random() <= '1'::double precision))::integer), ((fields ->> 'c2'::text)) - -> Sort - Output: (count((fields ->> 'c6'::text))), (sum(((fields ->> 'C 1'::text))::integer)), (avg(((fields ->> 'C 1'::text))::integer)), (min((((fields ->> 'c2'::text)))::integer)), (max(((fields ->> 'C 1'::text))::integer)), (stddev((((fields ->> 'c2'::text)))::integer)), ((fields ->> 'c2'::text)) - Sort Key: (count((ft1.fields ->> 'c6'::text))), (sum(((ft1.fields ->> 'C 1'::text))::integer)) - -> HashAggregate - Output: count((fields ->> 'c6'::text)), sum(((fields ->> 'C 1'::text))::integer), avg(((fields ->> 'C 1'::text))::integer), min((((fields ->> 'c2'::text)))::integer), max(((fields ->> 'C 1'::text))::integer), stddev((((fields ->> 'c2'::text)))::integer), ((fields ->> 'c2'::text)) - Group Key: (ft1.fields ->> 'c2'::text) - -> Foreign Scan on public.ft1 - Output: (fields ->> 'c2'::text), fields - InfluxDB query: SELECT * FROM "T1" WHERE (("c2" < 5)) -(13 rows) - ---Testcase 200: -select count(fields->>'c6'), sum((fields->>'C 1')::int), avg((fields->>'C 1')::int), min((fields->>'c2')::int), max((fields->>'C 1')::int), stddev((fields->>'c2')::int), sum((fields->>'C 1')::int) * (random() <= 1)::int as sum2 from ft1 where (fields->>'c2')::int < 5 group by fields->>'c2' order by 1, 2 limit 1; - count | sum | avg | min | max | stddev | sum2 --------+-------+----------------------+-----+-----+--------+------- - 100 | 49600 | 496.0000000000000000 | 1 | 991 | 0 | 49600 -(1 row) - --- Aggregate is not pushed down as aggregation contains random() ---Testcase 201: -explain (verbose, costs off) -select sum((fields->>'C 1')::int * (random() <= 1)::int) as sum, avg((fields->>'C 1')::int) from ft1; - QUERY PLAN -------------------------------------------------------------------------------------------------------------------------------------------------- - Aggregate - Output: sum((((fields ->> 'C 1'::text))::integer * ((random() <= '1'::double precision))::integer)), avg(((fields ->> 'C 1'::text))::integer) - -> Foreign Scan on public.ft1 - Output: "time", tags, fields - InfluxDB query: SELECT * FROM "T1" -(5 rows) - --- Aggregate over join query ---Testcase 202: -explain (verbose, costs off) -select count(*), sum((t1.c1)::int), avg((t2.c1)::int) from (SELECT (fields->>'C 1')::int c1, (fields->>'c2')::int c2, tags->>'c3' c3, fields->>'c4' c4, fields->>'c5' c5, fields->>'c6' c6, fields->>'c7' c7, fields->>'c8' c8 FROM ft1 t1) t1 inner join (SELECT (fields->>'C 1')::int c1, (fields->>'c2')::int c2, tags->>'c3' c3, fields->>'c4' c4, fields->>'c5' c5, fields->>'c6' c6, fields->>'c7' c7, fields->>'c8' c8 FROM ft1 t2) t2 on ((t1.c2)::int = (t2.c2)::int) where (t1.c2)::int = 6; - QUERY PLAN --------------------------------------------------------------------------------------------------------------- - Aggregate - Output: count(*), sum(((t1.fields ->> 'C 1'::text))::integer), avg(((t2.fields ->> 'C 1'::text))::integer) - -> Nested Loop - Output: t1.fields, t2.fields - -> Foreign Scan on public.ft1 t1 - Output: t1."time", t1.tags, t1.fields - InfluxDB query: SELECT * FROM "T1" WHERE (("c2" = 6)) - -> Materialize - Output: t2.fields - -> Foreign Scan on public.ft1 t2 - Output: t2.fields - InfluxDB query: SELECT * FROM "T1" WHERE (("c2" = 6)) -(12 rows) - ---Testcase 203: -select count(*), sum((t1.c1)::int), avg((t2.c1)::int) from (SELECT (fields->>'C 1')::int c1, (fields->>'c2')::int c2, tags->>'c3' c3, fields->>'c4' c4, fields->>'c5' c5, fields->>'c6' c6, fields->>'c7' c7, fields->>'c8' c8 FROM ft1 t1) t1 inner join (SELECT (fields->>'C 1')::int c1, (fields->>'c2')::int c2, tags->>'c3' c3, fields->>'c4' c4, fields->>'c5' c5, fields->>'c6' c6, fields->>'c7' c7, fields->>'c8' c8 FROM ft1 t2) t2 on ((t1.c2)::int = (t2.c2)::int) where (t1.c2)::int = 6; - count | sum | avg --------+---------+---------------------- - 10000 | 5010000 | 501.0000000000000000 -(1 row) - --- Not pushed down due to local conditions present in underneath input rel ---Testcase 204: -explain (verbose, costs off) -select sum((t1.c1)::int), count((t2.c1)::int) from (SELECT (fields->>'C 1')::int c1, (fields->>'c2')::int c2, tags->>'c3' c3, fields->>'c4' c4, fields->>'c5' c5, fields->>'c6' c6, fields->>'c7' c7, fields->>'c8' c8 FROM ft1 t1) t1 inner join (SELECT (fields->>'C 1')::int c1, (fields->>'c2')::int c2, tags->>'c3' c3, fields->>'c4' c4, fields->>'c5' c5, fields->>'c6' c6, fields->>'c7' c7, fields->>'c8' c8 FROM ft2 t2) t2 on ((t1.c1)::int = (t2.c1)::int) where (((t1.c1)::int * (t2.c1)::int)/((t1.c1)::int * (t2.c1)::int)) * random() <= 1; - QUERY PLAN ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- - Aggregate - Output: sum(((t1.fields ->> 'C 1'::text))::integer), count(((t2.fields ->> 'C 1'::text))::integer) - -> Merge Join - Output: t1.fields, t2.fields - Merge Cond: ((((t1.fields ->> 'C 1'::text))::integer) = (((t2.fields ->> 'C 1'::text))::integer)) - Join Filter: ((((((((t1.fields ->> 'C 1'::text))::integer) * (((t2.fields ->> 'C 1'::text))::integer)) / ((((t1.fields ->> 'C 1'::text))::integer) * (((t2.fields ->> 'C 1'::text))::integer))))::double precision * random()) <= '1'::double precision) - -> Sort - Output: t1.fields, (((t1.fields ->> 'C 1'::text))::integer) - Sort Key: (((t1.fields ->> 'C 1'::text))::integer) - -> Foreign Scan on public.ft1 t1 - Output: t1.fields, ((t1.fields ->> 'C 1'::text))::integer - InfluxDB query: SELECT * FROM "T1" - -> Sort - Output: t2.fields, (((t2.fields ->> 'C 1'::text))::integer) - Sort Key: (((t2.fields ->> 'C 1'::text))::integer) - -> Foreign Scan on public.ft2 t2 - Output: t2.fields, ((t2.fields ->> 'C 1'::text))::integer - InfluxDB query: SELECT * FROM "T1" -(18 rows) - --- GROUP BY clause having expressions ---Testcase 205: -explain (verbose, costs off) -select (fields->>'c2')::int/2, sum((fields->>'c2')::int) * ((fields->>'c2')::int/2) from ft1 group by (fields->>'c2')::int/2 order by (fields->>'c2')::int/2; - QUERY PLAN ----------------------------------------------------------------------------------------------------------------------------------------------------- - Sort - Output: ((((fields ->> 'c2'::text))::integer / 2)), ((sum(((fields ->> 'c2'::text))::integer) * ((((fields ->> 'c2'::text))::integer / 2)))) - Sort Key: ((((ft1.fields ->> 'c2'::text))::integer / 2)) - -> HashAggregate - Output: ((((fields ->> 'c2'::text))::integer / 2)), (sum(((fields ->> 'c2'::text))::integer) * ((((fields ->> 'c2'::text))::integer / 2))) - Group Key: (((ft1.fields ->> 'c2'::text))::integer / 2) - -> Foreign Scan on public.ft1 - Output: (((fields ->> 'c2'::text))::integer / 2), fields - InfluxDB query: SELECT * FROM "T1" -(9 rows) - ---Testcase 206: -select (fields->>'c2')::int/2, sum((fields->>'c2')::int) * ((fields->>'c2')::int/2) from ft1 group by (fields->>'c2')::int/2 order by (fields->>'c2')::int/2; - ?column? | ?column? -----------+---------- - 0 | 0 - 1 | 500 - 2 | 1800 - 3 | 3900 - 4 | 6800 -(5 rows) - --- Aggregates in subquery are pushed down. ---Testcase 207: -explain (verbose, costs off) -select count(x.a), sum(x.a) from (select (fields->>'c2')::int a, sum((fields->>'C 1')::int) b from ft1 group by fields->>'c2', sqrt((fields->>'C 1')::int) order by 1, 2) x; - QUERY PLAN ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- - Aggregate - Output: count(((((ft1.fields ->> 'c2'::text)))::integer)), sum(((((ft1.fields ->> 'c2'::text)))::integer)) - -> Sort - Output: ((((ft1.fields ->> 'c2'::text)))::integer), (sum(((ft1.fields ->> 'C 1'::text))::integer)), ((ft1.fields ->> 'c2'::text)), (sqrt((((ft1.fields ->> 'C 1'::text))::integer)::double precision)) - Sort Key: ((((ft1.fields ->> 'c2'::text)))::integer), (sum(((ft1.fields ->> 'C 1'::text))::integer)) - -> HashAggregate - Output: (((ft1.fields ->> 'c2'::text)))::integer, sum(((ft1.fields ->> 'C 1'::text))::integer), ((ft1.fields ->> 'c2'::text)), (sqrt((((ft1.fields ->> 'C 1'::text))::integer)::double precision)) - Group Key: (ft1.fields ->> 'c2'::text), sqrt((((ft1.fields ->> 'C 1'::text))::integer)::double precision) - -> Foreign Scan on public.ft1 - Output: (ft1.fields ->> 'c2'::text), sqrt((((ft1.fields ->> 'C 1'::text))::integer)::double precision), ft1.fields - InfluxDB query: SELECT * FROM "T1" -(11 rows) - ---Testcase 208: -select count(x.a), sum(x.a) from (select (fields->>'c2')::int a, sum((fields->>'C 1')::int) b from ft1 group by fields->>'c2', sqrt((fields->>'C 1')::int) order by 1, 2) x; - count | sum --------+------ - 1000 | 4500 -(1 row) - --- Aggregate is still pushed down by taking unshippable expression out ---Testcase 209: -explain (verbose, costs off) -select (fields->>'c2')::int * (random() <= 1)::int as sum1, sum((fields->>'C 1')::int) * (fields->>'c2')::int as sum2 from ft1 group by fields->>'c2' order by 1, 2; - QUERY PLAN ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ - Sort - Output: (((((fields ->> 'c2'::text)))::integer * ((random() <= '1'::double precision))::integer)), ((sum(((fields ->> 'C 1'::text))::integer) * (((fields ->> 'c2'::text)))::integer)), ((fields ->> 'c2'::text)) - Sort Key: (((((ft1.fields ->> 'c2'::text)))::integer * ((random() <= '1'::double precision))::integer)), ((sum(((ft1.fields ->> 'C 1'::text))::integer) * (((ft1.fields ->> 'c2'::text)))::integer)) - -> HashAggregate - Output: ((((fields ->> 'c2'::text)))::integer * ((random() <= '1'::double precision))::integer), (sum(((fields ->> 'C 1'::text))::integer) * (((fields ->> 'c2'::text)))::integer), ((fields ->> 'c2'::text)) - Group Key: (ft1.fields ->> 'c2'::text) - -> Foreign Scan on public.ft1 - Output: (fields ->> 'c2'::text), fields - InfluxDB query: SELECT * FROM "T1" -(9 rows) - ---Testcase 210: -select (fields->>'c2')::int * (random() <= 1)::int as sum1, sum((fields->>'C 1')::int) * (fields->>'c2')::int as sum2 from ft1 group by fields->>'c2' order by 1, 2; - sum1 | sum2 -------+-------- - 0 | 0 - 1 | 49600 - 2 | 99400 - 3 | 149400 - 4 | 199600 - 5 | 250000 - 6 | 300600 - 7 | 351400 - 8 | 402400 - 9 | 453600 -(10 rows) - --- Aggregate with unshippable GROUP BY clause are not pushed ---Testcase 211: -explain (verbose, costs off) -select (fields->>'c2')::int * (random() <= 1)::int as c2 from ft2 group by (fields->>'c2')::int * (random() <= 1)::int order by 1; - QUERY PLAN --------------------------------------------------------------------------------------------------------------- - Sort - Output: ((((fields ->> 'c2'::text))::integer * ((random() <= '1'::double precision))::integer)) - Sort Key: ((((ft2.fields ->> 'c2'::text))::integer * ((random() <= '1'::double precision))::integer)) - -> HashAggregate - Output: ((((fields ->> 'c2'::text))::integer * ((random() <= '1'::double precision))::integer)) - Group Key: (((ft2.fields ->> 'c2'::text))::integer * ((random() <= '1'::double precision))::integer) - -> Foreign Scan on public.ft2 - Output: (((fields ->> 'c2'::text))::integer * ((random() <= '1'::double precision))::integer) - InfluxDB query: SELECT "c2" FROM "T1" -(9 rows) - --- GROUP BY clause in various forms, cardinal, alias and constant expression ---Testcase 212: -explain (verbose, costs off) -select count(fields->>'c2') w, fields->>'c2' x, 5 y, 7.0 z from ft1 group by 2, y, 9.0::int order by 2; - QUERY PLAN --------------------------------------------------------------------------------------------- - Sort - Output: (count(((fields ->> 'c2'::text)))), ((fields ->> 'c2'::text)), 5, 7.0, 9 - Sort Key: ((ft1.fields ->> 'c2'::text)) - -> HashAggregate - Output: count(((fields ->> 'c2'::text))), ((fields ->> 'c2'::text)), (5), 7.0, (9) - Group Key: (ft1.fields ->> 'c2'::text), 5, 9 - -> Foreign Scan on public.ft1 - Output: (fields ->> 'c2'::text), 5, 9, fields - InfluxDB query: SELECT * FROM "T1" -(9 rows) - ---Testcase 213: -select count(fields->>'c2') w, fields->>'c2' x, 5 y, 7.0 z from ft1 group by 2, y, 9.0::int order by 2; - w | x | y | z ------+---+---+----- - 100 | 0 | 5 | 7.0 - 100 | 1 | 5 | 7.0 - 100 | 2 | 5 | 7.0 - 100 | 3 | 5 | 7.0 - 100 | 4 | 5 | 7.0 - 100 | 5 | 5 | 7.0 - 100 | 6 | 5 | 7.0 - 100 | 7 | 5 | 7.0 - 100 | 8 | 5 | 7.0 - 100 | 9 | 5 | 7.0 -(10 rows) - --- GROUP BY clause referring to same column multiple times --- Also, ORDER BY contains an aggregate function ---Testcase 214: -explain (verbose, costs off) -select (fields->>'c2')::int c2, (fields->>'c2')::int c2 from ft1 where (fields->>'c2')::int > 6 group by 1, 2 order by sum((fields->>'C 1')::int); - QUERY PLAN --------------------------------------------------------------------------------------------------------------------------------------- - Sort - Output: (((fields ->> 'c2'::text))::integer), (((fields ->> 'c2'::text))::integer), (sum(((fields ->> 'C 1'::text))::integer)) - Sort Key: (sum(((ft1.fields ->> 'C 1'::text))::integer)) - -> HashAggregate - Output: (((fields ->> 'c2'::text))::integer), (((fields ->> 'c2'::text))::integer), sum(((fields ->> 'C 1'::text))::integer) - Group Key: ((ft1.fields ->> 'c2'::text))::integer, ((ft1.fields ->> 'c2'::text))::integer - -> Foreign Scan on public.ft1 - Output: ((fields ->> 'c2'::text))::integer, ((fields ->> 'c2'::text))::integer, fields - InfluxDB query: SELECT * FROM "T1" WHERE (("c2" > 6)) -(9 rows) - ---Testcase 215: -select (fields->>'c2')::int c2, (fields->>'c2')::int c2 from ft1 where (fields->>'c2')::int > 6 group by 1, 2 order by sum((fields->>'C 1')::int); - c2 | c2 -----+---- - 7 | 7 - 8 | 8 - 9 | 9 -(3 rows) - --- Testing HAVING clause shippability ---Testcase 216: -explain (verbose, costs off) -select(fields->>'c2')::int c2, sum((fields->>'C 1')::int) from ft2 group by fields->>'c2' having avg((fields->>'C 1')::int) < 500 and sum((fields->>'C 1')::int) < 49800 order by (fields->>'c2')::int; - QUERY PLAN ----------------------------------------------------------------------------------------------------------------------------------------------- - Sort - Output: ((((fields ->> 'c2'::text)))::integer), (sum(((fields ->> 'C 1'::text))::integer)), ((fields ->> 'c2'::text)) - Sort Key: ((((ft2.fields ->> 'c2'::text)))::integer) - -> HashAggregate - Output: (((fields ->> 'c2'::text)))::integer, sum(((fields ->> 'C 1'::text))::integer), ((fields ->> 'c2'::text)) - Group Key: (ft2.fields ->> 'c2'::text) - Filter: ((avg(((ft2.fields ->> 'C 1'::text))::integer) < '500'::numeric) AND (sum(((ft2.fields ->> 'C 1'::text))::integer) < 49800)) - -> Foreign Scan on public.ft2 - Output: (fields ->> 'c2'::text), fields - InfluxDB query: SELECT * FROM "T1" -(10 rows) - ---Testcase 217: -select(fields->>'c2')::int c2, sum((fields->>'C 1')::int) from ft2 group by fields->>'c2' having avg((fields->>'C 1')::int) < 500 and sum((fields->>'C 1')::int) < 49800 order by (fields->>'c2')::int; - c2 | sum -----+------- - 1 | 49600 - 2 | 49700 -(2 rows) - --- Unshippable HAVING clause will be evaluated locally, and other qual in HAVING clause is pushed down ---Testcase 218: -explain (verbose, costs off) -select count(*) from (select time, count((fields->>'C 1')::int) from ft1 group by time, sqrt((fields->>'c2')::int) having (avg((fields->>'C 1')::int) / avg((fields->>'C 1')::int)) * random() <= 1 and avg((fields->>'C 1')::int) < 500) x; - QUERY PLAN -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- - Aggregate - Output: count(*) - -> HashAggregate - Output: ft1."time", NULL::bigint, (sqrt((((ft1.fields ->> 'c2'::text))::integer)::double precision)) - Group Key: ft1."time", sqrt((((ft1.fields ->> 'c2'::text))::integer)::double precision) - Filter: ((avg(((ft1.fields ->> 'C 1'::text))::integer) < '500'::numeric) AND ((((avg(((ft1.fields ->> 'C 1'::text))::integer) / avg(((ft1.fields ->> 'C 1'::text))::integer)))::double precision * random()) <= '1'::double precision)) - -> Foreign Scan on public.ft1 - Output: ft1."time", sqrt((((ft1.fields ->> 'c2'::text))::integer)::double precision), ft1.fields - InfluxDB query: SELECT * FROM "T1" -(9 rows) - ---Testcase 219: -select count(*) from (select time, count((fields->>'C 1')::int) from ft1 group by time, sqrt((fields->>'c2')::int) having (avg((fields->>'C 1')::int) / avg((fields->>'C 1')::int)) * random() <= 1 and avg((fields->>'C 1')::int) < 500) x; - count -------- - 49 -(1 row) - --- Aggregate in HAVING clause is not pushable, and thus aggregation is not pushed down ---Testcase 220: -explain (verbose, costs off) -select sum((fields->>'C 1')::int) from ft1 group by fields->>'c2' having avg((fields->>'C 1')::int * (random() <= 1)::int) > 100 order by 1; - QUERY PLAN ------------------------------------------------------------------------------------------------------------------------------------- - Sort - Output: (sum(((fields ->> 'C 1'::text))::integer)), ((fields ->> 'c2'::text)) - Sort Key: (sum(((ft1.fields ->> 'C 1'::text))::integer)) - -> HashAggregate - Output: sum(((fields ->> 'C 1'::text))::integer), ((fields ->> 'c2'::text)) - Group Key: (ft1.fields ->> 'c2'::text) - Filter: (avg((((ft1.fields ->> 'C 1'::text))::integer * ((random() <= '1'::double precision))::integer)) > '100'::numeric) - -> Foreign Scan on public.ft1 - Output: (fields ->> 'c2'::text), fields - InfluxDB query: SELECT * FROM "T1" -(10 rows) - --- Remote aggregate in combination with a local Param (for the output --- of an initplan) can be trouble, per bug #15781 ---Testcase 221: -explain (verbose, costs off) -select exists(select 1 from pg_enum), sum((fields->>'C 1')::int) from ft1; - QUERY PLAN --------------------------------------------------------------- - Foreign Scan - Output: $0, (sum(((ft1.fields ->> 'C 1'::text))::integer)) - InfluxDB query: SELECT sum("C 1") FROM "T1" - InitPlan 1 (returns $0) - -> Seq Scan on pg_catalog.pg_enum -(5 rows) - ---Testcase 222: -select exists(select 1 from pg_enum), sum((fields->>'C 1')::int) from ft1; - exists | sum ---------+-------- - t | 500500 -(1 row) - ---Testcase 223: -explain (verbose, costs off) -select exists(select 1 from pg_enum), sum((fields->>'C 1')::int) from ft1 group by 1; - QUERY PLAN --------------------------------------------------------------- - GroupAggregate - Output: ($0), sum(((ft1.fields ->> 'C 1'::text))::integer) - Group Key: $0 - InitPlan 1 (returns $0) - -> Seq Scan on pg_catalog.pg_enum - -> Foreign Scan on public.ft1 - Output: $0, ft1.fields - InfluxDB query: SELECT * FROM "T1" -(8 rows) - ---Testcase 224: -select exists(select 1 from pg_enum), sum((fields->>'C 1')::int) from ft1 group by 1; - exists | sum ---------+-------- - t | 500500 -(1 row) - --- Testing ORDER BY, DISTINCT, FILTER, Ordered-sets and VARIADIC within aggregates --- ORDER BY within aggregate, same column used to order ---Testcase 225: -explain (verbose, costs off) -select array_agg((fields->>'C 1')::int order by (fields->>'C 1')::int) from ft1 where (fields->>'C 1')::int < 100 group by fields->>'c2' order by 1; - QUERY PLAN ----------------------------------------------------------------------------------------------------------------------------------------- - Sort - Output: (array_agg(((fields ->> 'C 1'::text))::integer ORDER BY ((fields ->> 'C 1'::text))::integer)), ((fields ->> 'c2'::text)) - Sort Key: (array_agg(((ft1.fields ->> 'C 1'::text))::integer ORDER BY ((ft1.fields ->> 'C 1'::text))::integer)) - -> GroupAggregate - Output: array_agg(((fields ->> 'C 1'::text))::integer ORDER BY ((fields ->> 'C 1'::text))::integer), ((fields ->> 'c2'::text)) - Group Key: ((ft1.fields ->> 'c2'::text)) - -> Sort - Output: ((fields ->> 'c2'::text)), fields - Sort Key: ((ft1.fields ->> 'c2'::text)) - -> Foreign Scan on public.ft1 - Output: (fields ->> 'c2'::text), fields - InfluxDB query: SELECT * FROM "T1" WHERE (("C 1" < 100)) -(12 rows) - ---Testcase 226: -select array_agg((fields->>'C 1')::int order by (fields->>'C 1')::int) from ft1 where (fields->>'C 1')::int < 100 group by fields->>'c2' order by 1; - array_agg --------------------------------- - {1,11,21,31,41,51,61,71,81,91} - {2,12,22,32,42,52,62,72,82,92} - {3,13,23,33,43,53,63,73,83,93} - {4,14,24,34,44,54,64,74,84,94} - {5,15,25,35,45,55,65,75,85,95} - {6,16,26,36,46,56,66,76,86,96} - {7,17,27,37,47,57,67,77,87,97} - {8,18,28,38,48,58,68,78,88,98} - {9,19,29,39,49,59,69,79,89,99} - {10,20,30,40,50,60,70,80,90} -(10 rows) - --- ORDER BY within aggregate, different column used to order also using DESC ---Testcase 227: -explain (verbose, costs off) -select array_agg(time order by (fields->>'C 1')::int desc) from ft2 where (fields->>'c2')::int = 6 and (fields->>'C 1')::int < 50; - QUERY PLAN ----------------------------------------------------------------------------------- - Aggregate - Output: array_agg("time" ORDER BY ((fields ->> 'C 1'::text))::integer DESC) - -> Foreign Scan on public.ft2 - Output: "time", tags, fields - InfluxDB query: SELECT * FROM "T1" WHERE (("C 1" < 50)) AND (("c2" = 6)) -(5 rows) - ---Testcase 228: -select array_agg(time order by (fields->>'C 1')::int desc) from ft2 where (fields->>'c2')::int = 6 and (fields->>'C 1')::int < 50; - array_agg ------------------------------------------------------------------------------------------------------------------------------------------- - {"Mon Feb 16 00:00:00 1970","Fri Feb 06 00:00:00 1970","Tue Jan 27 00:00:00 1970","Sat Jan 17 00:00:00 1970","Wed Jan 07 00:00:00 1970"} -(1 row) - --- DISTINCT within aggregate ---Testcase 229: -explain (verbose, costs off) -select array_agg(distinct ((t1.c1)::int)%5) from (SELECT (fields->>'c1')::int c1, (fields->>'c2')::int c2, tags->>'c3' c3 FROM ft4 t1) t1 full join (SELECT (fields->>'c1')::int c1, (fields->>'c2')::int c2, tags->>'c3' c3 FROM ft5 t2) t2 on ((t1.c1)::int = (t2.c1)::int) where (t1.c1)::int < 20 or ((t1.c1)::int is null and (t2.c1)::int < 5) group by ((t2.c1)::int)%3 order by 1; - QUERY PLAN ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- - Sort - Output: (array_agg(DISTINCT (((t1.fields ->> 'c1'::text))::integer % 5))), ((((t2.fields ->> 'c1'::text))::integer % 3)) - Sort Key: (array_agg(DISTINCT (((t1.fields ->> 'c1'::text))::integer % 5))) - -> GroupAggregate - Output: array_agg(DISTINCT (((t1.fields ->> 'c1'::text))::integer % 5)), ((((t2.fields ->> 'c1'::text))::integer % 3)) - Group Key: ((((t2.fields ->> 'c1'::text))::integer % 3)) - -> Sort - Output: ((((t2.fields ->> 'c1'::text))::integer % 3)), t1.fields - Sort Key: ((((t2.fields ->> 'c1'::text))::integer % 3)) - -> Merge Full Join - Output: (((t2.fields ->> 'c1'::text))::integer % 3), t1.fields - Merge Cond: ((((t1.fields ->> 'c1'::text))::integer) = (((t2.fields ->> 'c1'::text))::integer)) - Filter: ((((t1.fields ->> 'c1'::text))::integer < 20) OR ((((t1.fields ->> 'c1'::text))::integer IS NULL) AND (((t2.fields ->> 'c1'::text))::integer < 5))) - -> Sort - Output: t1.fields, (((t1.fields ->> 'c1'::text))::integer) - Sort Key: (((t1.fields ->> 'c1'::text))::integer) - -> Foreign Scan on public.ft4 t1 - Output: t1.fields, ((t1.fields ->> 'c1'::text))::integer - InfluxDB query: SELECT * FROM "T3" - -> Sort - Output: t2.fields, (((t2.fields ->> 'c1'::text))::integer) - Sort Key: (((t2.fields ->> 'c1'::text))::integer) - -> Foreign Scan on public.ft5 t2 - Output: t2.fields, ((t2.fields ->> 'c1'::text))::integer - InfluxDB query: SELECT * FROM "T4" -(25 rows) - ---Testcase 230: -select array_agg(distinct ((t1.c1)::int)%5) from (SELECT (fields->>'c1')::int c1, (fields->>'c2')::int c2, tags->>'c3' c3 FROM ft4 t1) t1 full join (SELECT (fields->>'c1')::int c1, (fields->>'c2')::int c2, tags->>'c3' c3 FROM ft5 t2) t2 on ((t1.c1)::int = (t2.c1)::int) where (t1.c1)::int < 20 or ((t1.c1)::int is null and (t2.c1)::int < 5) group by ((t2.c1)::int)%3 order by 1; - array_agg --------------- - {0,1,2,3,4} - {1,2,3,NULL} -(2 rows) - --- DISTINCT combined with ORDER BY within aggregate ---Testcase 231: -explain (verbose, costs off) -select array_agg(distinct ((t1.c1)::int)%5 order by ((t1.c1)::int)%5) from (SELECT (fields->>'c1')::int c1, (fields->>'c2')::int c2, tags->>'c3' c3 FROM ft4 t1) t1 full join (SELECT (fields->>'c1')::int c1, (fields->>'c2')::int c2, tags->>'c3' c3 FROM ft5 t2) t2 on ((t1.c1)::int = (t2.c1)::int) where (t1.c1)::int < 20 or ((t1.c1)::int is null and (t2.c1)::int < 5) group by ((t2.c1)::int)%3 order by 1; - QUERY PLAN -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- - Sort - Output: (array_agg(DISTINCT (((t1.fields ->> 'c1'::text))::integer % 5) ORDER BY (((t1.fields ->> 'c1'::text))::integer % 5))), ((((t2.fields ->> 'c1'::text))::integer % 3)) - Sort Key: (array_agg(DISTINCT (((t1.fields ->> 'c1'::text))::integer % 5) ORDER BY (((t1.fields ->> 'c1'::text))::integer % 5))) - -> GroupAggregate - Output: array_agg(DISTINCT (((t1.fields ->> 'c1'::text))::integer % 5) ORDER BY (((t1.fields ->> 'c1'::text))::integer % 5)), ((((t2.fields ->> 'c1'::text))::integer % 3)) - Group Key: ((((t2.fields ->> 'c1'::text))::integer % 3)) - -> Sort - Output: ((((t2.fields ->> 'c1'::text))::integer % 3)), t1.fields - Sort Key: ((((t2.fields ->> 'c1'::text))::integer % 3)) - -> Merge Full Join - Output: (((t2.fields ->> 'c1'::text))::integer % 3), t1.fields - Merge Cond: ((((t1.fields ->> 'c1'::text))::integer) = (((t2.fields ->> 'c1'::text))::integer)) - Filter: ((((t1.fields ->> 'c1'::text))::integer < 20) OR ((((t1.fields ->> 'c1'::text))::integer IS NULL) AND (((t2.fields ->> 'c1'::text))::integer < 5))) - -> Sort - Output: t1.fields, (((t1.fields ->> 'c1'::text))::integer) - Sort Key: (((t1.fields ->> 'c1'::text))::integer) - -> Foreign Scan on public.ft4 t1 - Output: t1.fields, ((t1.fields ->> 'c1'::text))::integer - InfluxDB query: SELECT * FROM "T3" - -> Sort - Output: t2.fields, (((t2.fields ->> 'c1'::text))::integer) - Sort Key: (((t2.fields ->> 'c1'::text))::integer) - -> Foreign Scan on public.ft5 t2 - Output: t2.fields, ((t2.fields ->> 'c1'::text))::integer - InfluxDB query: SELECT * FROM "T4" -(25 rows) - ---Testcase 232: -select array_agg(distinct ((t1.c1)::int)%5 order by ((t1.c1)::int)%5) from (SELECT (fields->>'c1')::int c1, (fields->>'c2')::int c2, tags->>'c3' c3 FROM ft4 t1) t1 full join (SELECT (fields->>'c1')::int c1, (fields->>'c2')::int c2, tags->>'c3' c3 FROM ft5 t2) t2 on ((t1.c1)::int = (t2.c1)::int) where (t1.c1)::int < 20 or ((t1.c1)::int is null and (t2.c1)::int < 5) group by ((t2.c1)::int)%3 order by 1; - array_agg --------------- - {0,1,2,3,4} - {1,2,3,NULL} -(2 rows) - ---Testcase 233: -explain (verbose, costs off) -select array_agg(distinct ((t1.c1)::int)%5 order by ((t1.c1)::int)%5 desc nulls last) from (SELECT (fields->>'c1')::int c1, (fields->>'c2')::int c2, tags->>'c3' c3 FROM ft4 t1) t1 full join (SELECT (fields->>'c1')::int c1, (fields->>'c2')::int c2, tags->>'c3' c3 FROM ft5 t2) t2 on ((t1.c1)::int = (t2.c1)::int) where (t1.c1)::int < 20 or ((t1.c1)::int is null and (t2.c1)::int < 5) group by ((t2.c1)::int)%3 order by 1; - QUERY PLAN ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ - Sort - Output: (array_agg(DISTINCT (((t1.fields ->> 'c1'::text))::integer % 5) ORDER BY (((t1.fields ->> 'c1'::text))::integer % 5) DESC NULLS LAST)), ((((t2.fields ->> 'c1'::text))::integer % 3)) - Sort Key: (array_agg(DISTINCT (((t1.fields ->> 'c1'::text))::integer % 5) ORDER BY (((t1.fields ->> 'c1'::text))::integer % 5) DESC NULLS LAST)) - -> GroupAggregate - Output: array_agg(DISTINCT (((t1.fields ->> 'c1'::text))::integer % 5) ORDER BY (((t1.fields ->> 'c1'::text))::integer % 5) DESC NULLS LAST), ((((t2.fields ->> 'c1'::text))::integer % 3)) - Group Key: ((((t2.fields ->> 'c1'::text))::integer % 3)) - -> Sort - Output: ((((t2.fields ->> 'c1'::text))::integer % 3)), t1.fields - Sort Key: ((((t2.fields ->> 'c1'::text))::integer % 3)) - -> Merge Full Join - Output: (((t2.fields ->> 'c1'::text))::integer % 3), t1.fields - Merge Cond: ((((t1.fields ->> 'c1'::text))::integer) = (((t2.fields ->> 'c1'::text))::integer)) - Filter: ((((t1.fields ->> 'c1'::text))::integer < 20) OR ((((t1.fields ->> 'c1'::text))::integer IS NULL) AND (((t2.fields ->> 'c1'::text))::integer < 5))) - -> Sort - Output: t1.fields, (((t1.fields ->> 'c1'::text))::integer) - Sort Key: (((t1.fields ->> 'c1'::text))::integer) - -> Foreign Scan on public.ft4 t1 - Output: t1.fields, ((t1.fields ->> 'c1'::text))::integer - InfluxDB query: SELECT * FROM "T3" - -> Sort - Output: t2.fields, (((t2.fields ->> 'c1'::text))::integer) - Sort Key: (((t2.fields ->> 'c1'::text))::integer) - -> Foreign Scan on public.ft5 t2 - Output: t2.fields, ((t2.fields ->> 'c1'::text))::integer - InfluxDB query: SELECT * FROM "T4" -(25 rows) - ---Testcase 234: -select array_agg(distinct ((t1.c1)::int)%5 order by ((t1.c1)::int)%5 desc nulls last) from (SELECT (fields->>'c1')::int c1, (fields->>'c2')::int c2, tags->>'c3' c3 FROM ft4 t1) t1 full join (SELECT (fields->>'c1')::int c1, (fields->>'c2')::int c2, tags->>'c3' c3 FROM ft5 t2) t2 on ((t1.c1)::int = (t2.c1)::int) where (t1.c1)::int < 20 or ((t1.c1)::int is null and (t2.c1)::int < 5) group by ((t2.c1)::int)%3 order by 1; - array_agg --------------- - {3,2,1,NULL} - {4,3,2,1,0} -(2 rows) - --- FILTER within aggregate ---Testcase 235: -explain (verbose, costs off) -select sum((fields->>'C 1')::int) filter (where (fields->>'C 1')::int < 100 and (fields->>'c2')::int > 5) from ft1 group by fields->>'c2' order by 1 nulls last; - QUERY PLAN -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- - Sort - Output: (sum(((fields ->> 'C 1'::text))::integer) FILTER (WHERE ((((fields ->> 'C 1'::text))::integer < 100) AND ((((fields ->> 'c2'::text)))::integer > 5)))), ((fields ->> 'c2'::text)) - Sort Key: (sum(((ft1.fields ->> 'C 1'::text))::integer) FILTER (WHERE ((((ft1.fields ->> 'C 1'::text))::integer < 100) AND ((((ft1.fields ->> 'c2'::text)))::integer > 5)))) - -> HashAggregate - Output: sum(((fields ->> 'C 1'::text))::integer) FILTER (WHERE ((((fields ->> 'C 1'::text))::integer < 100) AND ((((fields ->> 'c2'::text)))::integer > 5))), ((fields ->> 'c2'::text)) - Group Key: (ft1.fields ->> 'c2'::text) - -> Foreign Scan on public.ft1 - Output: (fields ->> 'c2'::text), fields - InfluxDB query: SELECT * FROM "T1" -(9 rows) - ---Testcase 236: -select sum((fields->>'C 1')::int) filter (where (fields->>'C 1')::int < 100 and (fields->>'c2')::int > 5) from ft1 group by fields->>'c2' order by 1 nulls last; - sum ------ - 510 - 520 - 530 - 540 - - - - - - -(10 rows) - --- DISTINCT, ORDER BY and FILTER within aggregate ---Testcase 237: -explain (verbose, costs off) -select sum((fields->>'C 1')::int%3), sum(distinct (fields->>'C 1')::int%3 order by (fields->>'C 1')::int%3) filter (where (fields->>'C 1')::int%3 < 2), (fields->>'c2')::int c2 from ft1 where (fields->>'c2')::int = 6 group by fields->>'c2'; - QUERY PLAN ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- - GroupAggregate - Output: sum((((fields ->> 'C 1'::text))::integer % 3)), sum(DISTINCT (((fields ->> 'C 1'::text))::integer % 3) ORDER BY (((fields ->> 'C 1'::text))::integer % 3)) FILTER (WHERE ((((fields ->> 'C 1'::text))::integer % 3) < 2)), (((fields ->> 'c2'::text)))::integer, ((fields ->> 'c2'::text)) - Group Key: ((ft1.fields ->> 'c2'::text)) - -> Sort - Output: ((fields ->> 'c2'::text)), fields - Sort Key: ((ft1.fields ->> 'c2'::text)) - -> Foreign Scan on public.ft1 - Output: (fields ->> 'c2'::text), fields - InfluxDB query: SELECT * FROM "T1" WHERE (("c2" = 6)) -(9 rows) - ---Testcase 238: -select sum((fields->>'C 1')::int%3), sum(distinct (fields->>'C 1')::int%3 order by (fields->>'C 1')::int%3) filter (where (fields->>'C 1')::int%3 < 2), (fields->>'c2')::int c2 from ft1 where (fields->>'c2')::int = 6 group by fields->>'c2'; - sum | sum | c2 ------+-----+---- - 99 | 1 | 6 -(1 row) - --- Outer query is aggregation query ---Testcase 239: -explain (verbose, costs off) -select distinct (select count(*) filter (where (t2.fields->>'c2')::int = 6 and (t2.fields->>'C 1')::int < 10) from ft1 t1 where (t1.fields->>'C 1')::int = 6) from ft2 t2 where (t2.fields->>'c2')::int % 6 = 0 order by 1; - QUERY PLAN -------------------------------------------------------------------------------------------------------------------------------------------------------- - Unique - Output: ((SubPlan 1)) - -> Sort - Output: ((SubPlan 1)) - Sort Key: ((SubPlan 1)) - -> Aggregate - Output: (SubPlan 1) - -> Foreign Scan on public.ft2 t2 - Output: t2."time", t2.tags, t2.fields - InfluxDB query: SELECT * FROM "T1" WHERE ((("c2" % 6) = 0)) - SubPlan 1 - -> Foreign Scan on public.ft1 t1 - Output: count(*) FILTER (WHERE ((((t2.fields ->> 'c2'::text))::integer = 6) AND (((t2.fields ->> 'C 1'::text))::integer < 10))) - InfluxDB query: SELECT * FROM "T1" WHERE (("C 1" = 6)) -(14 rows) - ---Testcase 240: -select distinct (select count(*) filter (where (t2.fields->>'c2')::int = 6 and (t2.fields->>'C 1')::int < 10) from ft1 t1 where (t1.fields->>'C 1')::int = 6) from ft2 t2 where (t2.fields->>'c2')::int % 6 = 0 order by 1; - count -------- - 1 -(1 row) - --- Inner query is aggregation query ---Testcase 241: -explain (verbose, costs off) -select distinct (select count(t1.fields->>'C 1') filter (where (t2.fields->>'c2')::int = 6 and (t2.fields->>'C 1')::int < 10) from ft1 t1 where (t1.fields->>'C 1')::int = 6) from ft2 t2 where (t2.fields->>'c2')::int % 6 = 0 order by 1; - QUERY PLAN ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- - Unique - Output: ((SubPlan 1)) - -> Sort - Output: ((SubPlan 1)) - Sort Key: ((SubPlan 1)) - -> Foreign Scan on public.ft2 t2 - Output: (SubPlan 1) - InfluxDB query: SELECT * FROM "T1" WHERE ((("c2" % 6) = 0)) - SubPlan 1 - -> Aggregate - Output: count((t1.fields ->> 'C 1'::text)) FILTER (WHERE ((((t2.fields ->> 'c2'::text))::integer = 6) AND (((t2.fields ->> 'C 1'::text))::integer < 10))) - -> Foreign Scan on public.ft1 t1 - Output: t1."time", t1.tags, t1.fields - InfluxDB query: SELECT * FROM "T1" WHERE (("C 1" = 6)) -(14 rows) - ---Testcase 242: -select distinct (select count(t1.fields->>'C 1') filter (where (t2.fields->>'c2')::int = 6 and (t2.fields->>'C 1')::int < 10) from ft1 t1 where (t1.fields->>'C 1')::int = 6) from ft2 t2 where (t2.fields->>'c2')::int % 6 = 0 order by 1; - count -------- - 0 - 1 -(2 rows) - --- Aggregate not pushed down as FILTER condition is not pushable ---Testcase 243: -explain (verbose, costs off) -select sum((fields->>'C 1')::int) filter (where ((fields->>'C 1')::int / (fields->>'C 1')::int) * random() <= 1) from ft1 group by fields->>'c2' order by 1; - QUERY PLAN --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- - Sort - Output: (sum(((fields ->> 'C 1'::text))::integer) FILTER (WHERE ((((((fields ->> 'C 1'::text))::integer / ((fields ->> 'C 1'::text))::integer))::double precision * random()) <= '1'::double precision))), ((fields ->> 'c2'::text)) - Sort Key: (sum(((ft1.fields ->> 'C 1'::text))::integer) FILTER (WHERE ((((((ft1.fields ->> 'C 1'::text))::integer / ((ft1.fields ->> 'C 1'::text))::integer))::double precision * random()) <= '1'::double precision))) - -> HashAggregate - Output: sum(((fields ->> 'C 1'::text))::integer) FILTER (WHERE ((((((fields ->> 'C 1'::text))::integer / ((fields ->> 'C 1'::text))::integer))::double precision * random()) <= '1'::double precision)), ((fields ->> 'c2'::text)) - Group Key: (ft1.fields ->> 'c2'::text) - -> Foreign Scan on public.ft1 - Output: (fields ->> 'c2'::text), fields - InfluxDB query: SELECT * FROM "T1" -(9 rows) - ---Testcase 244: -explain (verbose, costs off) -select sum((fields->>'c2')::int) filter (where (fields->>'c2')::int in (select (fields->>'c2')::int from ft1 where (fields->>'c2')::int < 5)) from ft1; - QUERY PLAN ------------------------------------------------------------------------------------------ - Aggregate - Output: sum(((ft1.fields ->> 'c2'::text))::integer) FILTER (WHERE (hashed SubPlan 1)) - -> Foreign Scan on public.ft1 - Output: ft1."time", ft1.tags, ft1.fields - InfluxDB query: SELECT * FROM "T1" - SubPlan 1 - -> Foreign Scan on public.ft1 ft1_1 - Output: ((ft1_1.fields ->> 'c2'::text))::integer - InfluxDB query: SELECT "c2" FROM "T1" WHERE (("c2" < 5)) -(9 rows) - --- Ordered-sets within aggregate ---Testcase 245: -explain (verbose, costs off) -select (fields->>'c2')::int c2, rank('10'::varchar) within group (order by fields->>'c6'), percentile_cont((fields->>'c2')::int/10::numeric) within group (order by (fields->>'C 1')::int) from ft1 where (fields->>'c2')::int < 10 group by fields->>'c2' having percentile_cont((fields->>'c2')::int/10::numeric) within group (order by (fields->>'C 1')::int) < 500 order by (fields->>'c2')::int; - QUERY PLAN ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- - Sort - Output: ((((fields ->> 'c2'::text)))::integer), (rank('10'::text) WITHIN GROUP (ORDER BY (fields ->> 'c6'::text))), (percentile_cont(((((((fields ->> 'c2'::text)))::integer)::numeric / '10'::numeric))::double precision) WITHIN GROUP (ORDER BY ((((fields ->> 'C 1'::text))::integer)::double precision))), ((fields ->> 'c2'::text)) - Sort Key: ((((ft1.fields ->> 'c2'::text)))::integer) - -> GroupAggregate - Output: (((fields ->> 'c2'::text)))::integer, rank('10'::text) WITHIN GROUP (ORDER BY (fields ->> 'c6'::text)), percentile_cont(((((((fields ->> 'c2'::text)))::integer)::numeric / '10'::numeric))::double precision) WITHIN GROUP (ORDER BY ((((fields ->> 'C 1'::text))::integer)::double precision)), ((fields ->> 'c2'::text)) - Group Key: ((ft1.fields ->> 'c2'::text)) - Filter: (percentile_cont(((((((ft1.fields ->> 'c2'::text)))::integer)::numeric / '10'::numeric))::double precision) WITHIN GROUP (ORDER BY ((((ft1.fields ->> 'C 1'::text))::integer)::double precision)) < '500'::double precision) - -> Sort - Output: ((fields ->> 'c2'::text)), fields - Sort Key: ((ft1.fields ->> 'c2'::text)) - -> Foreign Scan on public.ft1 - Output: (fields ->> 'c2'::text), fields - InfluxDB query: SELECT * FROM "T1" WHERE (("c2" < 10)) -(13 rows) - ---Testcase 246: -select (fields->>'c2')::int c2, rank('10'::varchar) within group (order by fields->>'c6'), percentile_cont((fields->>'c2')::int/10::numeric) within group (order by (fields->>'C 1')::int) from ft1 where (fields->>'c2')::int < 10 group by fields->>'c2' having percentile_cont((fields->>'c2')::int/10::numeric) within group (order by (fields->>'C 1')::int) < 500 order by (fields->>'c2')::int; - c2 | rank | percentile_cont -----+------+----------------- - 0 | 101 | 10 - 1 | 101 | 100 - 2 | 1 | 200 - 3 | 1 | 300 - 4 | 1 | 400 -(5 rows) - --- Using multiple arguments within aggregates ---Testcase 247: -explain (verbose, costs off) -select (fields->>'C 1')::int c1, rank(fields->>'C 1', fields->>'c2') within group (order by fields->>'C 1', fields->>'c2') from ft1 group by fields->>'C 1', fields->>'c2' having (fields->>'C 1')::int = 6 order by 1; - QUERY PLAN ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- - GroupAggregate - Output: (((fields ->> 'C 1'::text)))::integer, rank(((fields ->> 'C 1'::text)), ((fields ->> 'c2'::text))) WITHIN GROUP (ORDER BY ((fields ->> 'C 1'::text)), ((fields ->> 'c2'::text))), ((fields ->> 'C 1'::text)), ((fields ->> 'c2'::text)) - Group Key: ((ft1.fields ->> 'C 1'::text)), ((ft1.fields ->> 'c2'::text)) - -> Sort - Output: ((fields ->> 'C 1'::text)), ((fields ->> 'c2'::text)), fields - Sort Key: ((ft1.fields ->> 'C 1'::text)), ((ft1.fields ->> 'c2'::text)) - -> Foreign Scan on public.ft1 - Output: (fields ->> 'C 1'::text), (fields ->> 'c2'::text), fields - InfluxDB query: SELECT * FROM "T1" WHERE (("C 1" = 6)) -(9 rows) - ---Testcase 248: -select (fields->>'C 1')::int c1, rank(fields->>'C 1', fields->>'c2') within group (order by fields->>'C 1', fields->>'c2') from ft1 group by fields->>'C 1', fields->>'c2' having (fields->>'C 1')::int = 6 order by 1; - c1 | rank -----+------ - 6 | 1 -(1 row) - --- User defined function for user defined aggregate, VARIADIC ---Testcase 249: -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)'; ---Testcase 250: -create aggregate least_agg(variadic items anyarray) ( - stype = anyelement, sfunc = least_accum -); --- Disable hash aggregation for plan stability. -set enable_hashagg to false; --- Not pushed down due to user defined aggregate ---Testcase 251: -explain (verbose, costs off) -select (fields->>'c2')::int c2, least_agg((fields->>'C 1')::int) from ft1 group by fields->>'c2' order by (fields->>'c2')::int; - QUERY PLAN -------------------------------------------------------------------------------------------------------------------------------------------------- - Sort - Output: ((((fields ->> 'c2'::text)))::integer), (least_agg(VARIADIC ARRAY[((fields ->> 'C 1'::text))::integer])), ((fields ->> 'c2'::text)) - Sort Key: ((((ft1.fields ->> 'c2'::text)))::integer) - -> GroupAggregate - Output: (((fields ->> 'c2'::text)))::integer, least_agg(VARIADIC ARRAY[((fields ->> 'C 1'::text))::integer]), ((fields ->> 'c2'::text)) - Group Key: ((ft1.fields ->> 'c2'::text)) - -> Sort - Output: ((fields ->> 'c2'::text)), fields - Sort Key: ((ft1.fields ->> 'c2'::text)) - -> Foreign Scan on public.ft1 - Output: (fields ->> 'c2'::text), fields - InfluxDB query: SELECT * FROM "T1" -(12 rows) - --- Add function and aggregate into extension -alter extension influxdb_fdw add function least_accum(anyelement, variadic anyarray); -alter extension influxdb_fdw add aggregate least_agg(variadic items anyarray); --- Now aggregate will be pushed. Aggregate will display VARIADIC argument. ---Testcase 252: -explain (verbose, costs off) -select (fields->>'c2')::int c2, least_agg((fields->>'C 1')::int) from ft1 where (fields->>'c2')::int < 100 group by fields->>'c2' order by (fields->>'c2')::int; - QUERY PLAN -------------------------------------------------------------------------------------------------------------------------------------------------- - Sort - Output: ((((fields ->> 'c2'::text)))::integer), (least_agg(VARIADIC ARRAY[((fields ->> 'C 1'::text))::integer])), ((fields ->> 'c2'::text)) - Sort Key: ((((ft1.fields ->> 'c2'::text)))::integer) - -> GroupAggregate - Output: (((fields ->> 'c2'::text)))::integer, least_agg(VARIADIC ARRAY[((fields ->> 'C 1'::text))::integer]), ((fields ->> 'c2'::text)) - Group Key: ((ft1.fields ->> 'c2'::text)) - -> Sort - Output: ((fields ->> 'c2'::text)), fields - Sort Key: ((ft1.fields ->> 'c2'::text)) - -> Foreign Scan on public.ft1 - Output: (fields ->> 'c2'::text), fields - InfluxDB query: SELECT * FROM "T1" WHERE (("c2" < 100)) -(12 rows) - ---Testcase 253: -select (fields->>'c2')::int c2, least_agg((fields->>'C 1')::int) from ft1 where (fields->>'c2')::int < 100 group by fields->>'c2' order by (fields->>'c2')::int; - c2 | least_agg -----+----------- - 0 | 10 - 1 | 1 - 2 | 2 - 3 | 3 - 4 | 4 - 5 | 5 - 6 | 6 - 7 | 7 - 8 | 8 - 9 | 9 -(10 rows) - --- Remove function and aggregate from extension -alter extension influxdb_fdw drop function least_accum(anyelement, variadic anyarray); -alter extension influxdb_fdw drop aggregate least_agg(variadic items anyarray); --- Not pushed down as we have dropped objects from extension. ---Testcase 254: -explain (verbose, costs off) -select (fields->>'c2')::int c2, least_agg((fields->>'C 1')::int) from ft1 group by fields->>'c2' order by (fields->>'c2')::int; - QUERY PLAN -------------------------------------------------------------------------------------------------------------------------------------------------- - Sort - Output: ((((fields ->> 'c2'::text)))::integer), (least_agg(VARIADIC ARRAY[((fields ->> 'C 1'::text))::integer])), ((fields ->> 'c2'::text)) - Sort Key: ((((ft1.fields ->> 'c2'::text)))::integer) - -> GroupAggregate - Output: (((fields ->> 'c2'::text)))::integer, least_agg(VARIADIC ARRAY[((fields ->> 'C 1'::text))::integer]), ((fields ->> 'c2'::text)) - Group Key: ((ft1.fields ->> 'c2'::text)) - -> Sort - Output: ((fields ->> 'c2'::text)), fields - Sort Key: ((ft1.fields ->> 'c2'::text)) - -> Foreign Scan on public.ft1 - Output: (fields ->> 'c2'::text), fields - InfluxDB query: SELECT * FROM "T1" -(12 rows) - --- Cleanup -reset enable_hashagg; ---Testcase 255: -drop aggregate least_agg(variadic items anyarray); ---Testcase 256: -drop function least_accum(anyelement, variadic anyarray); --- Testing USING OPERATOR() in ORDER BY within aggregate. --- For this, we need user defined operators along with operator family and --- operator class. Create those and then add them in extension. Note that --- user defined objects are considered unshippable unless they are part of --- the extension. ---Testcase 257: -create operator public.<^ ( - leftarg = int4, - rightarg = int4, - procedure = int4eq -); ---Testcase 258: -create operator public.=^ ( - leftarg = int4, - rightarg = int4, - procedure = int4lt -); ---Testcase 259: -create operator public.>^ ( - leftarg = int4, - rightarg = int4, - procedure = int4gt -); ---Testcase 260: -create operator family my_op_family using btree; ---Testcase 261: -create function my_op_cmp(a int, b int) returns int as - $$begin return btint4cmp(a, b); end $$ language plpgsql; ---Testcase 262: -create operator class my_op_class for type int using btree family my_op_family as - operator 1 public.<^, - operator 3 public.=^, - operator 5 public.>^, - function 1 my_op_cmp(int, int); --- This will not be pushed as user defined sort operator is not part of the --- extension yet. ---Testcase 263: -explain (verbose, costs off) -select array_agg((fields->>'C 1')::int order by (fields->>'C 1')::int using operator(public.<^)) from ft2 where (fields->>'c2')::int = 6 and (fields->>'C 1')::int < 100 group by fields->>'c2'; - QUERY PLAN ------------------------------------------------------------------------------------------------------------------------------------------------------- - GroupAggregate - Output: array_agg(((fields ->> 'C 1'::text))::integer ORDER BY ((fields ->> 'C 1'::text))::integer USING <^ NULLS LAST), ((fields ->> 'c2'::text)) - Group Key: ((ft2.fields ->> 'c2'::text)) - -> Sort - Output: ((fields ->> 'c2'::text)), fields - Sort Key: ((ft2.fields ->> 'c2'::text)) - -> Foreign Scan on public.ft2 - Output: (fields ->> 'c2'::text), fields - InfluxDB query: SELECT * FROM "T1" WHERE (("C 1" < 100)) AND (("c2" = 6)) -(9 rows) - --- Update local stats on ft2 ---ANALYZE ft2; --- Add into extension -alter extension influxdb_fdw add operator class my_op_class using btree; -alter extension influxdb_fdw add function my_op_cmp(a int, b int); -alter extension influxdb_fdw add operator family my_op_family using btree; -alter extension influxdb_fdw add operator public.<^(int, int); -alter extension influxdb_fdw add operator public.=^(int, int); -alter extension influxdb_fdw add operator public.>^(int, int); --- Now this will be pushed as sort operator is part of the extension. ---Testcase 264: -explain (verbose, costs off) -select array_agg((fields->>'C 1')::int order by (fields->>'C 1')::int using operator(public.<^)) from ft2 where (fields->>'c2')::int = 6 and (fields->>'C 1')::int < 100 group by fields->>'c2'; - QUERY PLAN ------------------------------------------------------------------------------------------------------------------------------------------------------- - GroupAggregate - Output: array_agg(((fields ->> 'C 1'::text))::integer ORDER BY ((fields ->> 'C 1'::text))::integer USING <^ NULLS LAST), ((fields ->> 'c2'::text)) - Group Key: ((ft2.fields ->> 'c2'::text)) - -> Sort - Output: ((fields ->> 'c2'::text)), fields - Sort Key: ((ft2.fields ->> 'c2'::text)) - -> Foreign Scan on public.ft2 - Output: (fields ->> 'c2'::text), fields - InfluxDB query: SELECT * FROM "T1" WHERE (("C 1" < 100)) AND (("c2" = 6)) -(9 rows) - ---Testcase 265: -select array_agg((fields->>'C 1')::int order by (fields->>'C 1')::int using operator(public.<^)) from ft2 where (fields->>'c2')::int = 6 and (fields->>'C 1')::int < 100 group by fields->>'c2'; - array_agg --------------------------------- - {6,16,26,36,46,56,66,76,86,96} -(1 row) - --- Remove from extension -alter extension influxdb_fdw drop operator class my_op_class using btree; -alter extension influxdb_fdw drop function my_op_cmp(a int, b int); -alter extension influxdb_fdw drop operator family my_op_family using btree; -alter extension influxdb_fdw drop operator public.<^(int, int); -alter extension influxdb_fdw drop operator public.=^(int, int); -alter extension influxdb_fdw drop operator public.>^(int, int); --- This will not be pushed as sort operator is now removed from the extension. ---Testcase 266: -explain (verbose, costs off) -select array_agg((fields->>'C 1')::int order by (fields->>'C 1')::int using operator(public.<^)) from ft2 where (fields->>'c2')::int = 6 and (fields->>'C 1')::int < 100 group by fields->>'c2'; - QUERY PLAN ------------------------------------------------------------------------------------------------------------------------------------------------------- - GroupAggregate - Output: array_agg(((fields ->> 'C 1'::text))::integer ORDER BY ((fields ->> 'C 1'::text))::integer USING <^ NULLS LAST), ((fields ->> 'c2'::text)) - Group Key: ((ft2.fields ->> 'c2'::text)) - -> Sort - Output: ((fields ->> 'c2'::text)), fields - Sort Key: ((ft2.fields ->> 'c2'::text)) - -> Foreign Scan on public.ft2 - Output: (fields ->> 'c2'::text), fields - InfluxDB query: SELECT * FROM "T1" WHERE (("C 1" < 100)) AND (("c2" = 6)) -(9 rows) - --- Cleanup ---Testcase 267: -drop operator class my_op_class using btree; ---Testcase 268: -drop function my_op_cmp(a int, b int); ---Testcase 269: -drop operator family my_op_family using btree; ---Testcase 270: -drop operator public.>^(int, int); ---Testcase 271: -drop operator public.=^(int, int); ---Testcase 272: -drop operator public.<^(int, int); --- Input relation to aggregate push down hook is not safe to pushdown and thus --- the aggregate cannot be pushed down to foreign server. ---Testcase 273: -explain (verbose, costs off) -select count(t1.c3) from ((SELECT fields->>'C 1' c1, fields->>'c2' c2, tags->>'c3' c3, fields->>'c4' c4, fields->>'c5' c5, fields->>'c6' c6, fields->>'c7' c7, fields->>'c8' c8 FROM ft2)) t1 left join ((SELECT fields->>'C 1' c1, fields->>'c2' c2, tags->>'c3' c3, fields->>'c4' c4, fields->>'c5' c5, fields->>'c6' c6, fields->>'c7' c7, fields->>'c8' c8 FROM ft2)) t2 on ((t1.c1)::int = random() * (t2.c2)::int); - QUERY PLAN ----------------------------------------------------------------------------------------------------------------------------------------------------------------- - Aggregate - Output: count((ft2.tags ->> 'c3'::text)) - -> Nested Loop Left Join - Output: ft2.tags - Join Filter: ((((ft2.fields ->> 'C 1'::text))::integer)::double precision = (random() * (((ft2_1.fields ->> 'c2'::text))::integer)::double precision)) - -> Foreign Scan on public.ft2 - Output: ft2."time", ft2.tags, ft2.fields - InfluxDB query: SELECT * FROM "T1" - -> Materialize - Output: ft2_1.fields - -> Foreign Scan on public.ft2 ft2_1 - Output: ft2_1.fields - InfluxDB query: SELECT * FROM "T1" -(13 rows) - --- Subquery in FROM clause having aggregate ---Testcase 274: -explain (verbose, costs off) -select count(*), x.b from ft1, (select (fields->>'c2')::int a, sum((fields->>'C 1')::int) b from ft1 group by fields->>'c2') x where (ft1.fields->>'c2')::int = x.a group by x.b order by 1, 2; - QUERY PLAN ---------------------------------------------------------------------------------------------------------------------------------------------------------------------- - Sort - Output: (count(*)), x.b - Sort Key: (count(*)), x.b - -> HashAggregate - Output: count(*), x.b - Group Key: x.b - -> Merge Join - Output: x.b - Merge Cond: (x.a = (((ft1.fields ->> 'c2'::text))::integer)) - -> Sort - Output: x.b, x.a - Sort Key: x.a - -> Subquery Scan on x - Output: x.b, x.a - -> HashAggregate - Output: (((ft1_1.fields ->> 'c2'::text)))::integer, sum(((ft1_1.fields ->> 'C 1'::text))::integer), ((ft1_1.fields ->> 'c2'::text)) - Group Key: (ft1_1.fields ->> 'c2'::text) - -> Foreign Scan on public.ft1 ft1_1 - Output: (ft1_1.fields ->> 'c2'::text), ft1_1.fields - InfluxDB query: SELECT * FROM "T1" - -> Sort - Output: ft1.fields, (((ft1.fields ->> 'c2'::text))::integer) - Sort Key: (((ft1.fields ->> 'c2'::text))::integer) - -> Foreign Scan on public.ft1 - Output: ft1.fields, ((ft1.fields ->> 'c2'::text))::integer - InfluxDB query: SELECT * FROM "T1" -(26 rows) - ---Testcase 275: -select count(*), x.b from ft1, (select (fields->>'c2')::int a, sum((fields->>'C 1')::int) b from ft1 group by fields->>'c2') x where (ft1.fields->>'c2')::int = x.a group by x.b order by 1, 2; - count | b --------+------- - 100 | 49600 - 100 | 49700 - 100 | 49800 - 100 | 49900 - 100 | 50000 - 100 | 50100 - 100 | 50200 - 100 | 50300 - 100 | 50400 - 100 | 50500 -(10 rows) - --- FULL join with IS NULL check in HAVING ---Testcase 276: -explain (verbose, costs off) -select avg((t1.c1)::int), sum((t2.c1)::int) from (SELECT (fields->>'c1')::int c1, (fields->>'c2')::int c2, tags->>'c3' c3 FROM ft4 t1) t1 full join (SELECT (fields->>'c1')::int c1, (fields->>'c2')::int c2, tags->>'c3' c3 FROM ft5 t2) t2 on ((t1.c1)::int = (t2.c1)::int) group by t2.c1 having (avg((t1.c1)::int) is null and sum((t2.c1)::int) < 10) or sum((t2.c1)::int) is null order by 1 nulls last, 2; - QUERY PLAN --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- - Sort - Output: (avg(((t1.fields ->> 'c1'::text))::integer)), (sum((((t2.fields ->> 'c1'::text))::integer))), (((t2.fields ->> 'c1'::text))::integer) - Sort Key: (avg(((t1.fields ->> 'c1'::text))::integer)), (sum((((t2.fields ->> 'c1'::text))::integer))) - -> HashAggregate - Output: avg(((t1.fields ->> 'c1'::text))::integer), sum((((t2.fields ->> 'c1'::text))::integer)), (((t2.fields ->> 'c1'::text))::integer) - Group Key: ((t2.fields ->> 'c1'::text))::integer - Filter: (((avg(((t1.fields ->> 'c1'::text))::integer) IS NULL) AND (sum((((t2.fields ->> 'c1'::text))::integer)) < 10)) OR (sum((((t2.fields ->> 'c1'::text))::integer)) IS NULL)) - -> Merge Full Join - Output: ((t2.fields ->> 'c1'::text))::integer, t1.fields, t2.fields - Merge Cond: ((((t1.fields ->> 'c1'::text))::integer) = (((t2.fields ->> 'c1'::text))::integer)) - -> Sort - Output: t1.fields, (((t1.fields ->> 'c1'::text))::integer) - Sort Key: (((t1.fields ->> 'c1'::text))::integer) - -> Foreign Scan on public.ft4 t1 - Output: t1.fields, ((t1.fields ->> 'c1'::text))::integer - InfluxDB query: SELECT * FROM "T3" - -> Sort - Output: t2.fields, (((t2.fields ->> 'c1'::text))::integer) - Sort Key: (((t2.fields ->> 'c1'::text))::integer) - -> Foreign Scan on public.ft5 t2 - Output: t2.fields, ((t2.fields ->> 'c1'::text))::integer - InfluxDB query: SELECT * FROM "T4" -(22 rows) - ---Testcase 277: -select avg((t1.c1)::int), sum((t2.c1)::int) from (SELECT (fields->>'c1')::int c1, (fields->>'c2')::int c2, tags->>'c3' c3 FROM ft4 t1) t1 full join (SELECT (fields->>'c1')::int c1, (fields->>'c2')::int c2, tags->>'c3' c3 FROM ft5 t2) t2 on ((t1.c1)::int = (t2.c1)::int) group by t2.c1 having (avg((t1.c1)::int) is null and sum((t2.c1)::int) < 10) or sum((t2.c1)::int) is null order by 1 nulls last, 2; - avg | sum ----------------------+----- - 51.0000000000000000 | - | 3 - | 9 -(3 rows) - --- Aggregate over FULL join needing to deparse the joining relations as --- subqueries. ---Testcase 278: -explain (verbose, costs off) -select count(*), sum((t1.c1)::int), avg((t2.c1)::int) from (SELECT (fields->>'c1')::int c1 FROM ft4 t1 WHERE (fields->>'c1')::int between 50 and 60) t1 full join (SELECT (fields->>'c1')::int c1 FROM ft5 t2 WHERE (fields->>'c1')::int between 50 and 60) t2 on ((t1.c1)::int = (t2.c1)::int); - QUERY PLAN ------------------------------------------------------------------------------------------------------------- - Aggregate - Output: count(*), sum(((t1.fields ->> 'c1'::text))::integer), avg(((t2.fields ->> 'c1'::text))::integer) - -> Hash Full Join - Output: t1.fields, t2.fields - Hash Cond: (((t1.fields ->> 'c1'::text))::integer = ((t2.fields ->> 'c1'::text))::integer) - -> Foreign Scan on public.ft4 t1 - Output: t1.tags, t1.fields - InfluxDB query: SELECT * FROM "T3" WHERE (("c1" >= 50)) AND (("c1" <= 60)) - -> Hash - Output: t2.fields - -> Foreign Scan on public.ft5 t2 - Output: t2.fields - InfluxDB query: SELECT * FROM "T4" WHERE (("c1" >= 50)) AND (("c1" <= 60)) -(13 rows) - ---Testcase 279: -select count(*), sum((t1.c1)::int), avg((t2.c1)::int) from (SELECT (fields->>'c1')::int c1 FROM ft4 t1 WHERE (fields->>'c1')::int between 50 and 60) t1 full join (SELECT (fields->>'c1')::int c1 FROM ft5 t2 WHERE (fields->>'c1')::int between 50 and 60) t2 on ((t1.c1)::int = (t2.c1)::int); - count | sum | avg --------+-----+--------------------- - 8 | 330 | 55.5000000000000000 -(1 row) - --- ORDER BY expression is part of the target list but not pushed down to --- foreign server. ---Testcase 280: -explain (verbose, costs off) -select sum((fields->>'c2')::int) * (random() <= 1)::int as sum from ft1 order by 1; - QUERY PLAN ----------------------------------------------------------------------------------------------------------------- - Sort - Output: (((sum(((fields ->> 'c2'::text))::integer)) * ((random() <= '1'::double precision))::integer)) - Sort Key: (((sum(((ft1.fields ->> 'c2'::text))::integer)) * ((random() <= '1'::double precision))::integer)) - -> Foreign Scan - Output: ((sum(((fields ->> 'c2'::text))::integer)) * ((random() <= '1'::double precision))::integer) - InfluxDB query: SELECT sum("c2") FROM "T1" -(6 rows) - ---Testcase 281: -select sum((fields->>'c2')::int) * (random() <= 1)::int as sum from ft1 order by 1; - sum ------- - 4500 -(1 row) - --- LATERAL join, with parameterization -set enable_hashagg to false; ---Testcase 282: -explain (verbose, costs off) -select (fields->>'c2')::int c2, sum from "S 1"."T 1" t1, lateral (select sum((t2.fields->>'C 1')::int + (t1.fields->>'C 1')::int) sum from ft2 t2 group by t2.fields->>'C 1') qry where (t1.fields->>'c2')::int * 2 = qry.sum and (t1.fields->>'c2')::int < 3 and (t1.fields->>'C 1')::int < 100 order by 1; - QUERY PLAN ------------------------------------------------------------------------------------------------------------------------------------------------------ - Sort - Output: (((t1.fields ->> 'c2'::text))::integer), qry.sum - Sort Key: (((t1.fields ->> 'c2'::text))::integer) - -> Nested Loop - Output: ((t1.fields ->> 'c2'::text))::integer, qry.sum - -> Foreign Scan on "S 1"."T 1" t1 - Output: t1."time", t1.tags, t1.fields - InfluxDB query: SELECT * FROM "T1" WHERE (("c2" < 3)) AND (("C 1" < 100)) - -> Subquery Scan on qry - Output: qry.sum, ((t2.fields ->> 'C 1'::text)) - Filter: ((((t1.fields ->> 'c2'::text))::integer * 2) = qry.sum) - -> GroupAggregate - Output: sum(((((t2.fields ->> 'C 1'::text)))::integer + ((t1.fields ->> 'C 1'::text))::integer)), ((t2.fields ->> 'C 1'::text)) - Group Key: ((t2.fields ->> 'C 1'::text)) - -> Sort - Output: ((t2.fields ->> 'C 1'::text)), t2.fields - Sort Key: ((t2.fields ->> 'C 1'::text)) - -> Foreign Scan on public.ft2 t2 - Output: (t2.fields ->> 'C 1'::text), t2.fields - InfluxDB query: SELECT * FROM "T1" -(20 rows) - ---Testcase 283: -select (fields->>'c2')::int c2, sum from "S 1"."T 1" t1, lateral (select sum((t2.fields->>'C 1')::int + (t1.fields->>'C 1')::int) sum from ft2 t2 group by t2.fields->>'C 1') qry where (t1.fields->>'c2')::int * 2 = qry.sum and (t1.fields->>'c2')::int < 3 and (t1.fields->>'C 1')::int < 100 order by 1; - c2 | sum -----+----- - 1 | 2 - 2 | 4 -(2 rows) - -reset enable_hashagg; --- bug #15613: bad plan for foreign table scan with lateral reference ---Testcase 284: -EXPLAIN (VERBOSE, COSTS OFF) -SELECT (ref_0.fields->>'c2')::int c2, subq_1.* -FROM - "S 1"."T 1" AS ref_0, - LATERAL ( - SELECT (ref_0.fields->>'C 1')::int c1, subq_0.* - FROM (SELECT (ref_0.fields->>'c2')::int c2, ref_1.tags->>'c3' c3 - FROM ft1 AS ref_1) AS subq_0 - RIGHT JOIN ft2 AS ref_3 ON (subq_0.c3 = ref_3.tags->>'c3') - ) AS subq_1 -WHERE (ref_0.fields->>'C 1')::int < 10 AND subq_1.c3 = '00001' -ORDER BY (ref_0.fields->>'C 1')::int; - QUERY PLAN ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- - Sort - Output: (((ref_0.fields ->> 'c2'::text))::integer), (((ref_0.fields ->> 'C 1'::text))::integer), (((ref_0.fields ->> 'c2'::text))::integer), ((ref_1.tags ->> 'c3'::text)), (((ref_0.fields ->> 'C 1'::text))::integer) - Sort Key: (((ref_0.fields ->> 'C 1'::text))::integer) - -> Nested Loop - Output: ((ref_0.fields ->> 'c2'::text))::integer, ((ref_0.fields ->> 'C 1'::text))::integer, (((ref_0.fields ->> 'c2'::text))::integer), (ref_1.tags ->> 'c3'::text), ((ref_0.fields ->> 'C 1'::text))::integer - -> Nested Loop - Output: ref_0.fields, ref_1.tags, (((ref_0.fields ->> 'c2'::text))::integer) - -> Foreign Scan on "S 1"."T 1" ref_0 - Output: ref_0."time", ref_0.tags, ref_0.fields - InfluxDB query: SELECT * FROM "T1" WHERE (("C 1" < 10)) - -> Foreign Scan on public.ft1 ref_1 - Output: ref_1.tags, ((ref_0.fields ->> 'c2'::text))::integer - InfluxDB query: SELECT * FROM "T1" WHERE (("c3" = '00001')) - -> Materialize - Output: ref_3.tags - -> Foreign Scan on public.ft2 ref_3 - Output: ref_3.tags - InfluxDB query: SELECT * FROM "T1" WHERE (("c3" = '00001')) -(18 rows) - ---Testcase 285: -SELECT (ref_0.fields->>'c2')::int c2, subq_1.* -FROM - "S 1"."T 1" AS ref_0, - LATERAL ( - SELECT (ref_0.fields->>'C 1')::int c1, subq_0.* - FROM (SELECT (ref_0.fields->>'c2')::int c2, ref_1.tags->>'c3' c3 - FROM ft1 AS ref_1) AS subq_0 - RIGHT JOIN ft2 AS ref_3 ON (subq_0.c3 = ref_3.tags->>'c3') - ) AS subq_1 -WHERE (ref_0.fields->>'C 1')::int < 10 AND subq_1.c3 = '00001' -ORDER BY (ref_0.fields->>'C 1')::int; - c2 | c1 | c2 | c3 -----+----+----+------- - 1 | 1 | 1 | 00001 - 2 | 2 | 2 | 00001 - 3 | 3 | 3 | 00001 - 4 | 4 | 4 | 00001 - 5 | 5 | 5 | 00001 - 6 | 6 | 6 | 00001 - 7 | 7 | 7 | 00001 - 8 | 8 | 8 | 00001 - 9 | 9 | 9 | 00001 -(9 rows) - --- Check with placeHolderVars ---Testcase 286: -explain (verbose, costs off) -select sum(q.a), count(q.b) from ft4 left join (select 13, avg((ft1.fields->>'C 1')::int), sum((ft2.fields->>'C 1')::int) from ft1 right join ft2 on ((ft1.fields->>'C 1')::int = (ft2.fields->>'C 1')::int)) q(a, b, c) on ((ft4.fields->>'c1')::int <= q.b); - QUERY PLAN -------------------------------------------------------------------------------------------------------------------------------------- - Aggregate - Output: sum(q.a), count(q.b) - -> Nested Loop Left Join - Output: q.a, q.b - Inner Unique: true - Join Filter: ((((ft4.fields ->> 'c1'::text))::integer)::numeric <= q.b) - -> Foreign Scan on public.ft4 - Output: ft4.tags, ft4.fields - InfluxDB query: SELECT * FROM "T3" - -> Materialize - Output: q.a, q.b - -> Subquery Scan on q - Output: q.a, q.b - -> Aggregate - Output: 13, avg(((ft1.fields ->> 'C 1'::text))::integer), NULL::bigint - -> Merge Left Join - Output: ft1.fields - Merge Cond: ((((ft2.fields ->> 'C 1'::text))::integer) = (((ft1.fields ->> 'C 1'::text))::integer)) - -> Sort - Output: ft2.fields, (((ft2.fields ->> 'C 1'::text))::integer) - Sort Key: (((ft2.fields ->> 'C 1'::text))::integer) - -> Foreign Scan on public.ft2 - Output: ft2.fields, ((ft2.fields ->> 'C 1'::text))::integer - InfluxDB query: SELECT * FROM "T1" - -> Sort - Output: ft1.fields, (((ft1.fields ->> 'C 1'::text))::integer) - Sort Key: (((ft1.fields ->> 'C 1'::text))::integer) - -> Foreign Scan on public.ft1 - Output: ft1.fields, ((ft1.fields ->> 'C 1'::text))::integer - InfluxDB query: SELECT * FROM "T1" -(30 rows) - ---Testcase 287: -select sum(q.a), count(q.b) from ft4 left join (select 13, avg((ft1.fields->>'C 1')::int), sum((ft2.fields->>'C 1')::int) from ft1 right join ft2 on ((ft1.fields->>'C 1')::int = (ft2.fields->>'C 1')::int)) q(a, b, c) on ((ft4.fields->>'c1')::int <= q.b); - sum | count ------+------- - 650 | 50 -(1 row) - --- Not supported cases --- Grouping sets ---Testcase 288: -explain (verbose, costs off) -select (fields->>'c2')::int c2, sum((fields->>'C 1')::int) from ft1 where (fields->>'c2')::int < 3 group by rollup((fields->>'c2')::int) order by 1 nulls last; - QUERY PLAN ------------------------------------------------------------------------------------------------- - Sort - Output: (((fields ->> 'c2'::text))::integer), (sum(((fields ->> 'C 1'::text))::integer)) - Sort Key: (((ft1.fields ->> 'c2'::text))::integer) - -> MixedAggregate - Output: (((fields ->> 'c2'::text))::integer), sum(((fields ->> 'C 1'::text))::integer) - Hash Key: ((ft1.fields ->> 'c2'::text))::integer - Group Key: () - -> Foreign Scan on public.ft1 - Output: ((fields ->> 'c2'::text))::integer, fields - InfluxDB query: SELECT * FROM "T1" WHERE (("c2" < 3)) -(10 rows) - ---Testcase 289: -select (fields->>'c2')::int c2, sum((fields->>'C 1')::int) from ft1 where (fields->>'c2')::int < 3 group by rollup((fields->>'c2')::int) order by 1 nulls last; - c2 | sum -----+-------- - 0 | 50500 - 1 | 49600 - 2 | 49700 - | 149800 -(4 rows) - ---Testcase 290: -explain (verbose, costs off) -select (fields->>'c2')::int c2, sum((fields->>'C 1')::int) from ft1 where (fields->>'c2')::int < 3 group by cube((fields->>'c2')::int) order by 1 nulls last; - QUERY PLAN ------------------------------------------------------------------------------------------------- - Sort - Output: (((fields ->> 'c2'::text))::integer), (sum(((fields ->> 'C 1'::text))::integer)) - Sort Key: (((ft1.fields ->> 'c2'::text))::integer) - -> MixedAggregate - Output: (((fields ->> 'c2'::text))::integer), sum(((fields ->> 'C 1'::text))::integer) - Hash Key: ((ft1.fields ->> 'c2'::text))::integer - Group Key: () - -> Foreign Scan on public.ft1 - Output: ((fields ->> 'c2'::text))::integer, fields - InfluxDB query: SELECT * FROM "T1" WHERE (("c2" < 3)) -(10 rows) - ---Testcase 291: -select (fields->>'c2')::int c2, sum((fields->>'C 1')::int) from ft1 where (fields->>'c2')::int < 3 group by cube((fields->>'c2')::int) order by 1 nulls last; - c2 | sum -----+-------- - 0 | 50500 - 1 | 49600 - 2 | 49700 - | 149800 -(4 rows) - ---Testcase 292: -explain (verbose, costs off) -select (fields->>'c2')::int c2, fields->>'c6' c6, sum((fields->>'C 1')::int) from ft1 where (fields->>'c2')::int < 3 group by grouping sets(fields->>'c2', fields->>'c6') order by 1 nulls last, 2 nulls last; - QUERY PLAN ------------------------------------------------------------------------------------------------------------------------------------------------------- - Sort - Output: ((((fields ->> 'c2'::text)))::integer), ((fields ->> 'c6'::text)), (sum(((fields ->> 'C 1'::text))::integer)), ((fields ->> 'c2'::text)) - Sort Key: ((((ft1.fields ->> 'c2'::text)))::integer), ((ft1.fields ->> 'c6'::text)) - -> HashAggregate - Output: (((fields ->> 'c2'::text)))::integer, ((fields ->> 'c6'::text)), sum(((fields ->> 'C 1'::text))::integer), ((fields ->> 'c2'::text)) - Hash Key: (ft1.fields ->> 'c2'::text) - Hash Key: (ft1.fields ->> 'c6'::text) - -> Foreign Scan on public.ft1 - Output: (fields ->> 'c6'::text), (fields ->> 'c2'::text), fields - InfluxDB query: SELECT * FROM "T1" WHERE (("c2" < 3)) -(10 rows) - ---Testcase 293: -select (fields->>'c2')::int c2, fields->>'c6' c6, sum((fields->>'C 1')::int) from ft1 where (fields->>'c2')::int < 3 group by grouping sets(fields->>'c2', fields->>'c6') order by 1 nulls last, 2 nulls last; - c2 | c6 | sum -----+----+------- - 0 | | 50500 - 1 | | 49600 - 2 | | 49700 - | 0 | 50500 - | 1 | 49600 - | 2 | 49700 -(6 rows) - ---Testcase 294: -explain (verbose, costs off) -select (fields->>'c2')::int c2, sum((fields->>'C 1')::int), grouping(fields->>'c2') from ft1 where (fields->>'c2')::int < 3 group by fields->>'c2' order by 1 nulls last; - QUERY PLAN ----------------------------------------------------------------------------------------------------------------------------------------------------------------- - Sort - Output: ((((fields ->> 'c2'::text)))::integer), (sum(((fields ->> 'C 1'::text))::integer)), (GROUPING(((fields ->> 'c2'::text)))), ((fields ->> 'c2'::text)) - Sort Key: ((((ft1.fields ->> 'c2'::text)))::integer) - -> HashAggregate - Output: (((fields ->> 'c2'::text)))::integer, sum(((fields ->> 'C 1'::text))::integer), GROUPING(((fields ->> 'c2'::text))), ((fields ->> 'c2'::text)) - Group Key: (ft1.fields ->> 'c2'::text) - -> Foreign Scan on public.ft1 - Output: (fields ->> 'c2'::text), fields - InfluxDB query: SELECT * FROM "T1" WHERE (("c2" < 3)) -(9 rows) - ---Testcase 295: -select (fields->>'c2')::int c2, sum((fields->>'C 1')::int), grouping(fields->>'c2') from ft1 where (fields->>'c2')::int < 3 group by fields->>'c2' order by 1 nulls last; - c2 | sum | grouping -----+-------+---------- - 0 | 50500 | 0 - 1 | 49600 | 0 - 2 | 49700 | 0 -(3 rows) - --- DISTINCT itself is not pushed down, whereas underneath aggregate is pushed ---Testcase 296: -explain (verbose, costs off) -select distinct sum((fields->>'C 1')::int)/1000 s from ft2 where (fields->>'c2')::int < 6 group by fields->>'c2' order by 1; - QUERY PLAN ----------------------------------------------------------------------------------------------------- - Unique - Output: ((sum(((fields ->> 'C 1'::text))::integer) / 1000)), ((fields ->> 'c2'::text)) - -> Sort - Output: ((sum(((fields ->> 'C 1'::text))::integer) / 1000)), ((fields ->> 'c2'::text)) - Sort Key: ((sum(((ft2.fields ->> 'C 1'::text))::integer) / 1000)) - -> HashAggregate - Output: (sum(((fields ->> 'C 1'::text))::integer) / 1000), ((fields ->> 'c2'::text)) - Group Key: (ft2.fields ->> 'c2'::text) - -> Foreign Scan on public.ft2 - Output: (fields ->> 'c2'::text), fields - InfluxDB query: SELECT * FROM "T1" WHERE (("c2" < 6)) -(11 rows) - ---Testcase 297: -select distinct sum((fields->>'C 1')::int)/1000 s from ft2 where (fields->>'c2')::int < 6 group by fields->>'c2' order by 1; - s ----- - 49 - 50 -(2 rows) - --- WindowAgg ---Testcase 298: -explain (verbose, costs off) -select (fields->>'c2')::int c2, sum((fields->>'c2')::int), count((fields->>'c2')::int) over (partition by (fields->>'c2')::int%2) from ft2 where (fields->>'c2')::int < 10 group by fields->>'c2' order by 1; - QUERY PLAN ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- - Sort - Output: ((((fields ->> 'c2'::text)))::integer), (sum((((fields ->> 'c2'::text)))::integer)), (count((((fields ->> 'c2'::text)))::integer) OVER (?)), ((fields ->> 'c2'::text)), (((((fields ->> 'c2'::text)))::integer % 2)) - Sort Key: ((((ft2.fields ->> 'c2'::text)))::integer) - -> WindowAgg - Output: (((fields ->> 'c2'::text)))::integer, (sum((((fields ->> 'c2'::text)))::integer)), count((((fields ->> 'c2'::text)))::integer) OVER (?), ((fields ->> 'c2'::text)), (((((fields ->> 'c2'::text)))::integer % 2)) - -> Sort - Output: ((fields ->> 'c2'::text)), (((((fields ->> 'c2'::text)))::integer % 2)), fields, (sum((((fields ->> 'c2'::text)))::integer)) - Sort Key: (((((ft2.fields ->> 'c2'::text)))::integer % 2)) - -> HashAggregate - Output: ((fields ->> 'c2'::text)), ((((fields ->> 'c2'::text)))::integer % 2), fields, sum((((fields ->> 'c2'::text)))::integer) - Group Key: (ft2.fields ->> 'c2'::text) - -> Foreign Scan on public.ft2 - Output: (fields ->> 'c2'::text), fields - InfluxDB query: SELECT * FROM "T1" WHERE (("c2" < 10)) -(14 rows) - ---Testcase 299: -select (fields->>'c2')::int c2, sum((fields->>'c2')::int), count((fields->>'c2')::int) over (partition by (fields->>'c2')::int%2) from ft2 where (fields->>'c2')::int < 10 group by fields->>'c2' order by 1; - c2 | sum | count -----+-----+------- - 0 | 0 | 5 - 1 | 100 | 5 - 2 | 200 | 5 - 3 | 300 | 5 - 4 | 400 | 5 - 5 | 500 | 5 - 6 | 600 | 5 - 7 | 700 | 5 - 8 | 800 | 5 - 9 | 900 | 5 -(10 rows) - ---Testcase 300: -explain (verbose, costs off) -select (fields->>'c2')::int c2, array_agg((fields->>'c2')::int) over (partition by (fields->>'c2')::int%2 order by (fields->>'c2')::int desc) from ft1 where (fields->>'c2')::int < 10 group by fields->>'c2' order by 1; - QUERY PLAN ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- - Sort - Output: ((((fields ->> 'c2'::text)))::integer), (array_agg(((((fields ->> 'c2'::text)))::integer)) OVER (?)), ((fields ->> 'c2'::text)), (((((fields ->> 'c2'::text)))::integer % 2)) - Sort Key: ((((ft1.fields ->> 'c2'::text)))::integer) - -> WindowAgg - Output: ((((fields ->> 'c2'::text)))::integer), array_agg(((((fields ->> 'c2'::text)))::integer)) OVER (?), ((fields ->> 'c2'::text)), (((((fields ->> 'c2'::text)))::integer % 2)) - -> Sort - Output: ((((fields ->> 'c2'::text)))::integer), ((fields ->> 'c2'::text)), (((((fields ->> 'c2'::text)))::integer % 2)), fields - Sort Key: (((((ft1.fields ->> 'c2'::text)))::integer % 2)), ((((ft1.fields ->> 'c2'::text)))::integer) DESC - -> HashAggregate - Output: (((fields ->> 'c2'::text)))::integer, ((fields ->> 'c2'::text)), ((((fields ->> 'c2'::text)))::integer % 2), fields - Group Key: (ft1.fields ->> 'c2'::text) - -> Foreign Scan on public.ft1 - Output: (fields ->> 'c2'::text), fields - InfluxDB query: SELECT * FROM "T1" WHERE (("c2" < 10)) -(14 rows) - ---Testcase 301: -select (fields->>'c2')::int c2, array_agg((fields->>'c2')::int) over (partition by (fields->>'c2')::int%2 order by (fields->>'c2')::int desc) from ft1 where (fields->>'c2')::int < 10 group by fields->>'c2' order by 1; - c2 | array_agg -----+------------- - 0 | {8,6,4,2,0} - 1 | {9,7,5,3,1} - 2 | {8,6,4,2} - 3 | {9,7,5,3} - 4 | {8,6,4} - 5 | {9,7,5} - 6 | {8,6} - 7 | {9,7} - 8 | {8} - 9 | {9} -(10 rows) - ---Testcase 302: -explain (verbose, costs off) -select (fields->>'c2')::int c2, array_agg((fields->>'c2')::int) over (partition by (fields->>'c2')::int%2 order by (fields->>'c2')::int range between current row and unbounded following) from ft1 where (fields->>'c2')::int < 10 group by fields->>'c2' order by 1; - QUERY PLAN ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- - Sort - Output: ((((fields ->> 'c2'::text)))::integer), (array_agg(((((fields ->> 'c2'::text)))::integer)) OVER (?)), ((fields ->> 'c2'::text)), (((((fields ->> 'c2'::text)))::integer % 2)) - Sort Key: ((((ft1.fields ->> 'c2'::text)))::integer) - -> WindowAgg - Output: ((((fields ->> 'c2'::text)))::integer), array_agg(((((fields ->> 'c2'::text)))::integer)) OVER (?), ((fields ->> 'c2'::text)), (((((fields ->> 'c2'::text)))::integer % 2)) - -> Sort - Output: ((((fields ->> 'c2'::text)))::integer), ((fields ->> 'c2'::text)), (((((fields ->> 'c2'::text)))::integer % 2)), fields - Sort Key: (((((ft1.fields ->> 'c2'::text)))::integer % 2)), ((((ft1.fields ->> 'c2'::text)))::integer) - -> HashAggregate - Output: (((fields ->> 'c2'::text)))::integer, ((fields ->> 'c2'::text)), ((((fields ->> 'c2'::text)))::integer % 2), fields - Group Key: (ft1.fields ->> 'c2'::text) - -> Foreign Scan on public.ft1 - Output: (fields ->> 'c2'::text), fields - InfluxDB query: SELECT * FROM "T1" WHERE (("c2" < 10)) -(14 rows) - ---Testcase 303: -select (fields->>'c2')::int c2, array_agg((fields->>'c2')::int) over (partition by (fields->>'c2')::int%2 order by (fields->>'c2')::int range between current row and unbounded following) from ft1 where (fields->>'c2')::int < 10 group by fields->>'c2' order by 1; - c2 | array_agg -----+------------- - 0 | {0,2,4,6,8} - 1 | {1,3,5,7,9} - 2 | {2,4,6,8} - 3 | {3,5,7,9} - 4 | {4,6,8} - 5 | {5,7,9} - 6 | {6,8} - 7 | {7,9} - 8 | {8} - 9 | {9} -(10 rows) - --- =================================================================== --- parameterized queries --- =================================================================== --- simple join ---Testcase 304: -PREPARE st1(int, int) AS SELECT t1.tags->>'c3' c3, t2.tags->>'c3' c3 FROM ft1 t1, ft2 t2 WHERE (t1.fields->>'C 1')::int = $1 AND (t2.fields->>'C 1')::int = $2; ---Testcase 305: -EXPLAIN (VERBOSE, COSTS OFF) EXECUTE st1(1, 2); - QUERY PLAN ----------------------------------------------------------------------- - Nested Loop - Output: (t1.tags ->> 'c3'::text), (t2.tags ->> 'c3'::text) - -> Foreign Scan on public.ft1 t1 - Output: t1."time", t1.tags, t1.fields - InfluxDB query: SELECT * FROM "T1" WHERE (("C 1" = 1)) - -> Materialize - Output: t2.tags - -> Foreign Scan on public.ft2 t2 - Output: t2.tags - InfluxDB query: SELECT * FROM "T1" WHERE (("C 1" = 2)) -(10 rows) - ---Testcase 306: -EXECUTE st1(1, 1); - c3 | c3 --------+------- - 00001 | 00001 -(1 row) - ---Testcase 307: -EXECUTE st1(101, 101); - c3 | c3 --------+------- - 00101 | 00101 -(1 row) - --- subquery using stable function (can't be sent to remote) ---Testcase 308: -PREPARE st2(int) AS SELECT * FROM ft1 t1 WHERE (t1.fields->>'C 1')::int < $2 AND t1.tags->>'c3' IN (SELECT tags->>'c3' FROM ft2 t2 WHERE (fields->>'C 1')::int > $1 AND date(time) = '1970-01-17'::date) ORDER BY (fields->>'C 1')::int; ---Testcase 309: -EXPLAIN (VERBOSE, COSTS OFF) EXECUTE st2(10, 20); - QUERY PLAN ---------------------------------------------------------------------------------------- - Sort - Output: t1."time", t1.tags, t1.fields, (((t1.fields ->> 'C 1'::text))::integer) - Sort Key: (((t1.fields ->> 'C 1'::text))::integer) - -> Hash Semi Join - Output: t1."time", t1.tags, t1.fields, ((t1.fields ->> 'C 1'::text))::integer - Hash Cond: ((t1.tags ->> 'c3'::text) = (t2.tags ->> 'c3'::text)) - -> Foreign Scan on public.ft1 t1 - Output: t1."time", t1.tags, t1.fields - InfluxDB query: SELECT * FROM "T1" WHERE (("C 1" < 20)) - -> Hash - Output: t2.tags - -> Foreign Scan on public.ft2 t2 - Output: t2.tags - Filter: (date(t2."time") = '01-17-1970'::date) - InfluxDB query: SELECT * FROM "T1" WHERE (("C 1" > 10)) -(15 rows) - ---Testcase 310: -EXECUTE st2(10, 20); - time | tags | fields ---------------------------+-----------------+---------------------------------------------------------------------- - Sat Jan 17 00:00:00 1970 | {"c3": "00016"} | {"c2": "6", "c6": "6", "c7": "6 ", "c8": "foo", "C 1": "16"} -(1 row) - ---Testcase 311: -EXECUTE st2(101, 121); - time | tags | fields ---------------------------+-----------------+----------------------------------------------------------------------- - Sat Jan 17 00:00:00 1970 | {"c3": "00116"} | {"c2": "6", "c6": "6", "c7": "6 ", "c8": "foo", "C 1": "116"} -(1 row) - --- subquery using immutable function (can be sent to remote) ---Testcase 312: -PREPARE st3(int) AS SELECT * FROM ft1 t1 WHERE (t1.fields->>'C 1')::int < $2 AND t1.tags->>'c3' IN (SELECT tags->>'c3' FROM ft2 t2 WHERE (fields->>'C 1')::int > $1 AND date(time) = '1970-01-17'::date) ORDER BY (fields->>'C 1')::int; ---Testcase 313: -EXPLAIN (VERBOSE, COSTS OFF) EXECUTE st3(10, 20); - QUERY PLAN ---------------------------------------------------------------------------------------- - Sort - Output: t1."time", t1.tags, t1.fields, (((t1.fields ->> 'C 1'::text))::integer) - Sort Key: (((t1.fields ->> 'C 1'::text))::integer) - -> Hash Semi Join - Output: t1."time", t1.tags, t1.fields, ((t1.fields ->> 'C 1'::text))::integer - Hash Cond: ((t1.tags ->> 'c3'::text) = (t2.tags ->> 'c3'::text)) - -> Foreign Scan on public.ft1 t1 - Output: t1."time", t1.tags, t1.fields - InfluxDB query: SELECT * FROM "T1" WHERE (("C 1" < 20)) - -> Hash - Output: t2.tags - -> Foreign Scan on public.ft2 t2 - Output: t2.tags - Filter: (date(t2."time") = '01-17-1970'::date) - InfluxDB query: SELECT * FROM "T1" WHERE (("C 1" > 10)) -(15 rows) - ---Testcase 314: -EXECUTE st3(10, 20); - time | tags | fields ---------------------------+-----------------+---------------------------------------------------------------------- - Sat Jan 17 00:00:00 1970 | {"c3": "00016"} | {"c2": "6", "c6": "6", "c7": "6 ", "c8": "foo", "C 1": "16"} -(1 row) - ---Testcase 315: -EXECUTE st3(20, 30); - time | tags | fields -------+------+-------- -(0 rows) - --- custom plan should be chosen initially ---Testcase 316: -PREPARE st4(int) AS SELECT * FROM ft1 t1 WHERE (t1.fields->>'C 1')::int = $1; ---Testcase 317: -EXPLAIN (VERBOSE, COSTS OFF) EXECUTE st4(1); - QUERY PLAN ----------------------------------------------------------- - Foreign Scan on public.ft1 t1 - Output: "time", tags, fields - InfluxDB query: SELECT * FROM "T1" WHERE (("C 1" = 1)) -(3 rows) - ---Testcase 318: -EXPLAIN (VERBOSE, COSTS OFF) EXECUTE st4(1); - QUERY PLAN ----------------------------------------------------------- - Foreign Scan on public.ft1 t1 - Output: "time", tags, fields - InfluxDB query: SELECT * FROM "T1" WHERE (("C 1" = 1)) -(3 rows) - ---Testcase 319: -EXPLAIN (VERBOSE, COSTS OFF) EXECUTE st4(1); - QUERY PLAN ----------------------------------------------------------- - Foreign Scan on public.ft1 t1 - Output: "time", tags, fields - InfluxDB query: SELECT * FROM "T1" WHERE (("C 1" = 1)) -(3 rows) - ---Testcase 320: -EXPLAIN (VERBOSE, COSTS OFF) EXECUTE st4(1); - QUERY PLAN ----------------------------------------------------------- - Foreign Scan on public.ft1 t1 - Output: "time", tags, fields - InfluxDB query: SELECT * FROM "T1" WHERE (("C 1" = 1)) -(3 rows) - ---Testcase 321: -EXPLAIN (VERBOSE, COSTS OFF) EXECUTE st4(1); - QUERY PLAN ----------------------------------------------------------- - Foreign Scan on public.ft1 t1 - Output: "time", tags, fields - InfluxDB query: SELECT * FROM "T1" WHERE (("C 1" = 1)) -(3 rows) - --- once we try it enough times, should switch to generic plan ---Testcase 322: -EXPLAIN (VERBOSE, COSTS OFF) EXECUTE st4(1); - QUERY PLAN ------------------------------------------------------------ - Foreign Scan on public.ft1 t1 - Output: "time", tags, fields - InfluxDB query: SELECT * FROM "T1" WHERE (("C 1" = $1)) -(3 rows) - --- value of $1 should not be sent to remote ---Testcase 323: -PREPARE st5(text,int) AS SELECT * FROM ft1 t1 WHERE fields->>'c8' = $1 and (fields->>'C 1')::int = $2; ---Testcase 324: -EXPLAIN (VERBOSE, COSTS OFF) EXECUTE st5('foo', 1); - QUERY PLAN -------------------------------------------------------------------------------- - Foreign Scan on public.ft1 t1 - Output: "time", tags, fields - InfluxDB query: SELECT * FROM "T1" WHERE (("c8" = 'foo')) AND (("C 1" = 1)) -(3 rows) - ---Testcase 325: -EXPLAIN (VERBOSE, COSTS OFF) EXECUTE st5('foo', 1); - QUERY PLAN -------------------------------------------------------------------------------- - Foreign Scan on public.ft1 t1 - Output: "time", tags, fields - InfluxDB query: SELECT * FROM "T1" WHERE (("c8" = 'foo')) AND (("C 1" = 1)) -(3 rows) - ---Testcase 326: -EXPLAIN (VERBOSE, COSTS OFF) EXECUTE st5('foo', 1); - QUERY PLAN -------------------------------------------------------------------------------- - Foreign Scan on public.ft1 t1 - Output: "time", tags, fields - InfluxDB query: SELECT * FROM "T1" WHERE (("c8" = 'foo')) AND (("C 1" = 1)) -(3 rows) - ---Testcase 327: -EXPLAIN (VERBOSE, COSTS OFF) EXECUTE st5('foo', 1); - QUERY PLAN -------------------------------------------------------------------------------- - Foreign Scan on public.ft1 t1 - Output: "time", tags, fields - InfluxDB query: SELECT * FROM "T1" WHERE (("c8" = 'foo')) AND (("C 1" = 1)) -(3 rows) - ---Testcase 328: -EXPLAIN (VERBOSE, COSTS OFF) EXECUTE st5('foo', 1); - QUERY PLAN -------------------------------------------------------------------------------- - Foreign Scan on public.ft1 t1 - Output: "time", tags, fields - InfluxDB query: SELECT * FROM "T1" WHERE (("c8" = 'foo')) AND (("C 1" = 1)) -(3 rows) - ---Testcase 329: -EXPLAIN (VERBOSE, COSTS OFF) EXECUTE st5('foo', 1); - QUERY PLAN ------------------------------------------------------------------------------ - Foreign Scan on public.ft1 t1 - Output: "time", tags, fields - InfluxDB query: SELECT * FROM "T1" WHERE (("c8" = $1)) AND (("C 1" = $2)) -(3 rows) - ---Testcase 330: -EXECUTE st5('foo', 1); - time | tags | fields ---------------------------+-----------------+--------------------------------------------------------------------- - Fri Jan 02 00:00:00 1970 | {"c3": "00001"} | {"c2": "1", "c6": "1", "c7": "1 ", "c8": "foo", "C 1": "1"} -(1 row) - --- altering FDW options requires replanning ---Testcase 331: -PREPARE st6 AS SELECT * FROM ft1 t1 WHERE (t1.fields->>'C 1')::int = (t1.fields->>'c2')::int; ---Testcase 332: -EXPLAIN (VERBOSE, COSTS OFF) EXECUTE st6; - QUERY PLAN -------------------------------------------------------------- - Foreign Scan on public.ft1 t1 - Output: "time", tags, fields - InfluxDB query: SELECT * FROM "T1" WHERE (("C 1" = "c2")) -(3 rows) - ---Testcase 333: -PREPARE st7 AS INSERT INTO ft1_nsc (c1,c2,c3) VALUES (1001,101,'foo'); ---Testcase 334: -EXPLAIN (VERBOSE, COSTS OFF) EXECUTE st7; - QUERY PLAN ------------------------------------------------------------------------------------------------------------------------------------------------------------- - Insert on public.ft1_nsc - -> Result - Output: NULL::integer, 1001, 101, 'foo'::text, NULL::timestamp without time zone, NULL::character varying, 'ft1 '::character(10), NULL::text -(3 rows) - ---Testcase 335: -INSERT INTO "S 1".s1t0 SELECT * FROM "S 1".s1t1; -ALTER FOREIGN TABLE ft1 OPTIONS (SET table 'T0'); ---Testcase 336: -EXPLAIN (VERBOSE, COSTS OFF) EXECUTE st6; - QUERY PLAN -------------------------------------------------------------- - Foreign Scan on public.ft1 t1 - Output: "time", tags, fields - InfluxDB query: SELECT * FROM "T0" WHERE (("C 1" = "c2")) -(3 rows) - ---Testcase 337: -EXECUTE st6; - time | tags | fields ---------------------------+-----------------+--------------------------------------------------------------------- - Fri Jan 02 00:00:00 1970 | {"c3": "00001"} | {"c2": "1", "c6": "1", "c7": "1 ", "c8": "foo", "C 1": "1"} - Sat Jan 03 00:00:00 1970 | {"c3": "00002"} | {"c2": "2", "c6": "2", "c7": "2 ", "c8": "foo", "C 1": "2"} - Sun Jan 04 00:00:00 1970 | {"c3": "00003"} | {"c2": "3", "c6": "3", "c7": "3 ", "c8": "foo", "C 1": "3"} - Mon Jan 05 00:00:00 1970 | {"c3": "00004"} | {"c2": "4", "c6": "4", "c7": "4 ", "c8": "foo", "C 1": "4"} - Tue Jan 06 00:00:00 1970 | {"c3": "00005"} | {"c2": "5", "c6": "5", "c7": "5 ", "c8": "foo", "C 1": "5"} - Wed Jan 07 00:00:00 1970 | {"c3": "00006"} | {"c2": "6", "c6": "6", "c7": "6 ", "c8": "foo", "C 1": "6"} - Thu Jan 08 00:00:00 1970 | {"c3": "00007"} | {"c2": "7", "c6": "7", "c7": "7 ", "c8": "foo", "C 1": "7"} - Fri Jan 09 00:00:00 1970 | {"c3": "00008"} | {"c2": "8", "c6": "8", "c7": "8 ", "c8": "foo", "C 1": "8"} - Sat Jan 10 00:00:00 1970 | {"c3": "00009"} | {"c2": "9", "c6": "9", "c7": "9 ", "c8": "foo", "C 1": "9"} -(9 rows) - ---Testcase 338: -EXPLAIN (VERBOSE, COSTS OFF) EXECUTE st7; - QUERY PLAN ------------------------------------------------------------------------------------------------------------------------------------------------------------- - Insert on public.ft1_nsc - -> Result - Output: NULL::integer, 1001, 101, 'foo'::text, NULL::timestamp without time zone, NULL::character varying, 'ft1 '::character(10), NULL::text -(3 rows) - ---Testcase 339: -DELETE FROM "S 1".s1t0; -ALTER FOREIGN TABLE ft1 OPTIONS (SET table 'T1'); ---Testcase 340: -PREPARE st8 AS SELECT count(tags->>'c3') FROM ft1 t1 WHERE (t1.fields->>'C 1')::int === (t1.fields->>'c2')::int; ---Testcase 341: -EXPLAIN (VERBOSE, COSTS OFF) EXECUTE st8; - QUERY PLAN ----------------------------------------------------------------------------------------------------- - Aggregate - Output: count((tags ->> 'c3'::text)) - -> Foreign Scan on public.ft1 t1 - Output: "time", tags, fields - Filter: (((t1.fields ->> 'C 1'::text))::integer === ((t1.fields ->> 'c2'::text))::integer) - InfluxDB query: SELECT * FROM "T1" -(6 rows) - --- Skip, influxdb_fdw does not support extensions --- ALTER SERVER loopback OPTIONS (DROP extensions); ---Testcase 342: -EXPLAIN (VERBOSE, COSTS OFF) EXECUTE st8; - QUERY PLAN ----------------------------------------------------------------------------------------------------- - Aggregate - Output: count((tags ->> 'c3'::text)) - -> Foreign Scan on public.ft1 t1 - Output: "time", tags, fields - Filter: (((t1.fields ->> 'C 1'::text))::integer === ((t1.fields ->> 'c2'::text))::integer) - InfluxDB query: SELECT * FROM "T1" -(6 rows) - ---Testcase 343: -EXECUTE st8; - count -------- - 9 -(1 row) - --- ALTER SERVER loopback OPTIONS (ADD extensions 'influxdb_fdw'); --- cleanup -DEALLOCATE st1; -DEALLOCATE st2; -DEALLOCATE st3; -DEALLOCATE st4; -DEALLOCATE st5; -DEALLOCATE st6; -DEALLOCATE st7; -DEALLOCATE st8; --- System columns, except ctid and oid, should not be sent to remote ---Testcase 344: -EXPLAIN (VERBOSE, COSTS OFF) -SELECT * FROM ft1 t1 WHERE t1.tableoid = 'pg_class'::regclass LIMIT 1; - QUERY PLAN ---------------------------------------------- - Limit - Output: "time", tags, fields - -> Foreign Scan on public.ft1 t1 - Output: "time", tags, fields - Filter: (t1.tableoid = '1259'::oid) - InfluxDB query: SELECT * FROM "T1" -(6 rows) - ---Testcase 345: -SELECT * FROM ft1 t1 WHERE t1.tableoid = 'ft1'::regclass ORDER BY (fields->>'C 1')::int LIMIT 1; - time | tags | fields ---------------------------+-----------------+--------------------------------------------------------------------- - Fri Jan 02 00:00:00 1970 | {"c3": "00001"} | {"c2": "1", "c6": "1", "c7": "1 ", "c8": "foo", "C 1": "1"} -(1 row) - ---Testcase 346: -EXPLAIN (VERBOSE, COSTS OFF) -SELECT tableoid::regclass, * FROM ft1 t1 LIMIT 1; - QUERY PLAN ------------------------------------------------------------- - Limit - Output: ((tableoid)::regclass), "time", tags, fields - -> Foreign Scan on public.ft1 t1 - Output: (tableoid)::regclass, "time", tags, fields - InfluxDB query: SELECT * FROM "T1" -(5 rows) - ---Testcase 347: -SELECT tableoid::regclass, * FROM ft1 t1 ORDER BY (fields->>'C 1')::int LIMIT 1; - tableoid | time | tags | fields -----------+--------------------------+-----------------+--------------------------------------------------------------------- - ft1 | Fri Jan 02 00:00:00 1970 | {"c3": "00001"} | {"c2": "1", "c6": "1", "c7": "1 ", "c8": "foo", "C 1": "1"} -(1 row) - ---Testcase 348: -EXPLAIN (VERBOSE, COSTS OFF) -SELECT * FROM ft1 t1 WHERE t1.ctid = '(0,2)'; - QUERY PLAN --------------------------------------- - Foreign Scan on public.ft1 t1 - Output: "time", tags, fields - Filter: (t1.ctid = '(0,2)'::tid) - InfluxDB query: SELECT * FROM "T1" -(4 rows) - ---Testcase 349: -SELECT * FROM ft1 t1 WHERE t1.ctid = '(0,2)'; - time | tags | fields -------+------+-------- -(0 rows) - ---Testcase 350: -EXPLAIN (VERBOSE, COSTS OFF) -SELECT ctid, * FROM ft1 t1 LIMIT 1; - QUERY PLAN --------------------------------------------- - Limit - Output: ctid, "time", tags, fields - -> Foreign Scan on public.ft1 t1 - Output: ctid, "time", tags, fields - InfluxDB query: SELECT * FROM "T1" -(5 rows) - ---Testcase 351: -SELECT ctid, * FROM ft1 t1 ORDER BY (fields->>'C 1')::int LIMIT 1; - ctid | time | tags | fields -----------------+--------------------------+-----------------+--------------------------------------------------------------------- - (4294967295,0) | Fri Jan 02 00:00:00 1970 | {"c3": "00001"} | {"c2": "1", "c6": "1", "c7": "1 ", "c8": "foo", "C 1": "1"} -(1 row) - --- =================================================================== --- used in PL/pgSQL function --- =================================================================== ---Testcase 352: -CREATE OR REPLACE FUNCTION f_test(p_c1 int) RETURNS int AS $$ -DECLARE - v_c1 int; -BEGIN ---Testcase 353: - SELECT fields->>'C 1' INTO v_c1 FROM ft1 WHERE (fields->>'C 1')::int = p_c1 LIMIT 1; - PERFORM fields->>'C 1' FROM ft1 WHERE (fields->>'C 1')::int = p_c1 AND p_c1 = v_c1 LIMIT 1; - RETURN v_c1; -END; -$$ LANGUAGE plpgsql; ---Testcase 354: -SELECT f_test(100); - f_test --------- - 100 -(1 row) - ---Testcase 355: -DROP FUNCTION f_test(int); --- =================================================================== --- conversion error --- =================================================================== ---ALTER FOREIGN TABLE ft1 ALTER COLUMN c8 TYPE int; ---Testcase 356: ---SELECT * FROM ft1 WHERE c1 = 1; -- ERROR ---Testcase 357: ---SELECT ft1.c1, ft2.c2, ft1.c8 FROM ft1, ft2 WHERE ft1.c1 = ft2.c1 AND ft1.c1 = 1; -- ERROR ---Testcase 358: ---SELECT ft1.c1, ft2.c2, ft1 FROM ft1, ft2 WHERE ft1.c1 = ft2.c1 AND ft1.c1 = 1; -- ERROR ---Testcase 359: ---SELECT sum(c2), array_agg(c8) FROM ft1 GROUP BY c8; -- ERROR ---ALTER FOREIGN TABLE ft1 ALTER COLUMN c8 TYPE text; -/* --- influxdb_fdw does not support transactions --- =================================================================== --- subtransaction --- + local/remote error doesn't break cursor --- =================================================================== -BEGIN; -DECLARE c CURSOR FOR SELECT * FROM ft1 ORDER BY c1; -FETCH c; -SAVEPOINT s; -ERROR OUT; -- ERROR -ROLLBACK TO s; -FETCH c; -SAVEPOINT s; -SELECT * FROM ft1 WHERE 1 / (c1 - 1) > 0; -- ERROR -ROLLBACK TO s; -FETCH c; -SELECT * FROM ft1 ORDER BY c1 LIMIT 1; -COMMIT; -*/ --- =================================================================== --- test handling of collations --- =================================================================== ---Testcase 360: -create foreign table loct3 (fields jsonb OPTIONS(fields 'true')) SERVER influxdb_svr OPTIONS (table 'loct3', schemaless 'true'); ---Testcase 361: -create foreign table ft3 (fields jsonb OPTIONS(fields 'true')) SERVER influxdb_svr OPTIONS (table 'loct3', schemaless 'true'); --- can be sent to remote ---Testcase 362: -explain (verbose, costs off) select * from ft3 where fields->>'f1' = 'foo'; - QUERY PLAN ----------------------------------------------------------------- - Foreign Scan on public.ft3 - Output: fields - InfluxDB query: SELECT * FROM "loct3" WHERE (("f1" = 'foo')) -(3 rows) - ---Testcase 363: -explain (verbose, costs off) select * from ft3 where fields->>'f1' COLLATE "C" = 'foo'; - QUERY PLAN ----------------------------------------------------------------- - Foreign Scan on public.ft3 - Output: fields - InfluxDB query: SELECT * FROM "loct3" WHERE (("f1" = 'foo')) -(3 rows) - ---Testcase 364: -explain (verbose, costs off) select * from ft3 where fields->>'f2' = 'foo'; - QUERY PLAN ----------------------------------------------------------------- - Foreign Scan on public.ft3 - Output: fields - InfluxDB query: SELECT * FROM "loct3" WHERE (("f2" = 'foo')) -(3 rows) - ---Testcase 365: -explain (verbose, costs off) select * from ft3 where fields->>'f3' = 'foo'; - QUERY PLAN ----------------------------------------------------------------- - Foreign Scan on public.ft3 - Output: fields - InfluxDB query: SELECT * FROM "loct3" WHERE (("f3" = 'foo')) -(3 rows) - ---Testcase 366: -explain (verbose, costs off) select * from ft3 f, loct3 l - where f.fields->>'f3' = l.fields->>'f3' and l.fields->>'f1' = 'foo'; - QUERY PLAN ----------------------------------------------------------------------------- - Hash Join - Output: f.fields, l.fields - Hash Cond: ((f.fields ->> 'f3'::text) = (l.fields ->> 'f3'::text)) - -> Foreign Scan on public.ft3 f - Output: f.fields - InfluxDB query: SELECT * FROM "loct3" - -> Hash - Output: l.fields - -> Foreign Scan on public.loct3 l - Output: l.fields - InfluxDB query: SELECT * FROM "loct3" WHERE (("f1" = 'foo')) -(11 rows) - --- can't be sent to remote ---Testcase 367: -explain (verbose, costs off) select * from ft3 where fields->>'f1' COLLATE "POSIX" = 'foo'; - QUERY PLAN ----------------------------------------------------------------- - Foreign Scan on public.ft3 - Output: fields - InfluxDB query: SELECT * FROM "loct3" WHERE (("f1" = 'foo')) -(3 rows) - ---Testcase 368: -explain (verbose, costs off) select * from ft3 where fields->>'f1' = 'foo' COLLATE "C"; - QUERY PLAN -------------------------------------------------------------------- - Foreign Scan on public.ft3 - Output: fields - Filter: ((ft3.fields ->> 'f1'::text) = 'foo'::text COLLATE "C") - InfluxDB query: SELECT * FROM "loct3" -(4 rows) - ---Testcase 369: -explain (verbose, costs off) select * from ft3 where fields->>'f2' COLLATE "C" = 'foo'; - QUERY PLAN ----------------------------------------------------------------- - Foreign Scan on public.ft3 - Output: fields - InfluxDB query: SELECT * FROM "loct3" WHERE (("f2" = 'foo')) -(3 rows) - ---Testcase 370: -explain (verbose, costs off) select * from ft3 where fields->>'f2' = 'foo' COLLATE "C"; - QUERY PLAN -------------------------------------------------------------------- - Foreign Scan on public.ft3 - Output: fields - Filter: ((ft3.fields ->> 'f2'::text) = 'foo'::text COLLATE "C") - InfluxDB query: SELECT * FROM "loct3" -(4 rows) - ---Testcase 371: -explain (verbose, costs off) select * from ft3 f, loct3 l - where f.fields->>'f3' = l.fields->>'f3' COLLATE "POSIX" and l.fields->>'f1' = 'foo'; - QUERY PLAN ----------------------------------------------------------------------------------------------- - Hash Join - Output: f.fields, l.fields - Hash Cond: (((f.fields ->> 'f3'::text))::text = (l.fields ->> 'f3'::text COLLATE "POSIX")) - -> Foreign Scan on public.ft3 f - Output: f.fields - InfluxDB query: SELECT * FROM "loct3" - -> Hash - Output: l.fields - -> Foreign Scan on public.loct3 l - Output: l.fields - InfluxDB query: SELECT * FROM "loct3" WHERE (("f1" = 'foo')) -(11 rows) - --- influxdb_fdw does not support UPDATE --- =================================================================== --- test writable foreign table stuff --- =================================================================== ---Testcase 372: -EXPLAIN (verbose, costs off) -INSERT INTO ft2_nsc (c1,c2,c3) SELECT c1+1000,c2+100, c3 || c3 FROM ft2_nsc ORDER BY c1 LIMIT 20; - QUERY PLAN -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- - Insert on public.ft2_nsc - -> Subquery Scan on "*SELECT*" - Output: "*SELECT*"."?column?", "*SELECT*"."?column?_1", NULL::integer, "*SELECT*"."?column?_2", NULL::timestamp without time zone, NULL::character varying, 'ft2 '::character(10), NULL::text - -> Limit - Output: ((ft2_nsc_1.c1 + 1000)), ((ft2_nsc_1.c2 + 100)), ((ft2_nsc_1.c3 || ft2_nsc_1.c3)), ft2_nsc_1.c1 - -> Sort - Output: ((ft2_nsc_1.c1 + 1000)), ((ft2_nsc_1.c2 + 100)), ((ft2_nsc_1.c3 || ft2_nsc_1.c3)), ft2_nsc_1.c1 - Sort Key: ft2_nsc_1.c1 - -> Foreign Scan on public.ft2_nsc ft2_nsc_1 - Output: (ft2_nsc_1.c1 + 1000), (ft2_nsc_1.c2 + 100), (ft2_nsc_1.c3 || ft2_nsc_1.c3), ft2_nsc_1.c1 - InfluxDB query: SELECT "C 1", "c2", "c3" FROM "T1" -(11 rows) - ---Testcase 373: -INSERT INTO ft2_nsc (c1,c2,c3) SELECT c1+1000,c2+100, c3 || c3 FROM ft2_nsc ORDER BY c1 LIMIT 20; ---Testcase 374: -INSERT INTO ft2_nsc (c1,c2,c3) VALUES (1101,201,'aaa'), (1102,202,'bbb'), (1103,203,'ccc'); ---Testcase 375: -SELECT (fields->>'C 1')::int c1, (fields->>'c2')::int c2, tags->>'c3' c3, fields->>'c6' c6, fields->>'c7' c7, fields->>'c8' c8 FROM ft2 WHERE (fields->>'c2')::int > 200; - c1 | c2 | c3 | c6 | c7 | c8 -------+-----+-----+----+------------+---- - 1101 | 201 | aaa | | ft2 | - 1102 | 202 | bbb | | ft2 | - 1103 | 203 | ccc | | ft2 | -(3 rows) - ---Testcase 376: -INSERT INTO ft2_nsc (c1,c2,c3) VALUES (1104,204,'ddd'), (1105,205,'eee'); ---EXPLAIN (verbose, costs off) ---UPDATE ft2 SET c2 = c2 + 300, c3 = c3 || '_update3' WHERE c1 % 10 = 3; -- can be pushed down ---UPDATE ft2 SET c2 = c2 + 300, c3 = c3 || '_update3' WHERE c1 % 10 = 3; ---EXPLAIN (verbose, costs off) ---UPDATE ft2 SET c2 = c2 + 400, c3 = c3 || '_update7' WHERE c1 % 10 = 7 RETURNING *; -- can be pushed down ---UPDATE ft2 SET c2 = c2 + 400, c3 = c3 || '_update7' WHERE c1 % 10 = 7 RETURNING *; ---EXPLAIN (verbose, costs off) ---UPDATE ft2 SET c2 = ft2.c2 + 500, c3 = ft2.c3 || '_update9', c7 = DEFAULT --- FROM ft1 WHERE ft1.c1 = ft2.c2 AND ft1.c1 % 10 = 9; -- can be pushed down ---UPDATE ft2 SET c2 = ft2.c2 + 500, c3 = ft2.c3 || '_update9', c7 = DEFAULT --- FROM ft1 WHERE ft1.c1 = ft2.c2 AND ft1.c1 % 10 = 9; ---Testcase 377: -EXPLAIN (verbose, costs off) - DELETE FROM ft2_nsc WHERE c1 % 10 = 5; -- can be pushed down - QUERY PLAN ---------------------------------------------------------------------------------- - Delete on public.ft2_nsc - -> Foreign Scan on public.ft2_nsc - Output: c3, "time" - InfluxDB query: SELECT "c3", "C 1" FROM "T1" WHERE ((("C 1" % 10) = 5)) -(4 rows) - ---Testcase 378: -SELECT (fields->>'C 1')::int c1 FROM ft2 WHERE (fields->>'C 1')::int % 10 = 5 ORDER BY (fields->>'C 1')::int; - c1 ------- - 5 - 15 - 25 - 35 - 45 - 55 - 65 - 75 - 85 - 95 - 105 - 115 - 125 - 135 - 145 - 155 - 165 - 175 - 185 - 195 - 205 - 215 - 225 - 235 - 245 - 255 - 265 - 275 - 285 - 295 - 305 - 315 - 325 - 335 - 345 - 355 - 365 - 375 - 385 - 395 - 405 - 415 - 425 - 435 - 445 - 455 - 465 - 475 - 485 - 495 - 505 - 515 - 525 - 535 - 545 - 555 - 565 - 575 - 585 - 595 - 605 - 615 - 625 - 635 - 645 - 655 - 665 - 675 - 685 - 695 - 705 - 715 - 725 - 735 - 745 - 755 - 765 - 775 - 785 - 795 - 805 - 815 - 825 - 835 - 845 - 855 - 865 - 875 - 885 - 895 - 905 - 915 - 925 - 935 - 945 - 955 - 965 - 975 - 985 - 995 - 1005 - 1015 - 1105 -(103 rows) - ---Testcase 379: -DELETE FROM ft2_nsc WHERE c1 % 10 = 5; ---Testcase 380: -SELECT (fields->>'C 1')::int c1 FROM ft2 WHERE (fields->>'C 1')::int % 10 = 5; - c1 ----- -(0 rows) - ---Testcase 381: -EXPLAIN (verbose, costs off) -DELETE FROM ft2_nsc USING ft1_nsc WHERE ft1_nsc.c1 = ft2_nsc.c2 AND ft1_nsc.c1 % 10 = 2; - QUERY PLAN ---------------------------------------------------------------------------------------------------------------------- - Delete on public.ft2_nsc - -> Hash Join - Output: ft2_nsc.c3, ft2_nsc."time", ft1_nsc.* - Hash Cond: (ft2_nsc.c2 = ft1_nsc.c1) - -> Foreign Scan on public.ft2_nsc - Output: ft2_nsc.c3, ft2_nsc."time", ft2_nsc.c2 - InfluxDB query: SELECT "c2", "c3" FROM "T1" - -> Hash - Output: ft1_nsc.*, ft1_nsc.c1 - -> Foreign Scan on public.ft1_nsc - Output: ft1_nsc.*, ft1_nsc.c1 - InfluxDB query: SELECT "C 1", "c2", "c3", "c6", "c7", "c8" FROM "T1" WHERE ((("C 1" % 10) = 2)) -(12 rows) - ---Testcase 382: -DELETE FROM ft2_nsc USING ft1_nsc WHERE ft1_nsc.c1 = ft2_nsc.c2 AND ft1_nsc.c1 % 10 = 2; ---Testcase 383: -SELECT (fields->>'C 1')::int c1, (fields->>'c2')::int c2, tags->>'c3' c3 FROM ft2 ORDER BY (fields->>'C 1')::int; - c1 | c2 | c3 -------+-----+------------ - 1 | 1 | 00001 - 3 | 3 | 00003 - 4 | 4 | 00004 - 6 | 6 | 00006 - 7 | 7 | 00007 - 8 | 8 | 00008 - 9 | 9 | 00009 - 10 | 0 | 00010 - 11 | 1 | 00011 - 13 | 3 | 00013 - 14 | 4 | 00014 - 16 | 6 | 00016 - 17 | 7 | 00017 - 18 | 8 | 00018 - 19 | 9 | 00019 - 20 | 0 | 00020 - 21 | 1 | 00021 - 23 | 3 | 00023 - 24 | 4 | 00024 - 26 | 6 | 00026 - 27 | 7 | 00027 - 28 | 8 | 00028 - 29 | 9 | 00029 - 30 | 0 | 00030 - 31 | 1 | 00031 - 33 | 3 | 00033 - 34 | 4 | 00034 - 36 | 6 | 00036 - 37 | 7 | 00037 - 38 | 8 | 00038 - 39 | 9 | 00039 - 40 | 0 | 00040 - 41 | 1 | 00041 - 43 | 3 | 00043 - 44 | 4 | 00044 - 46 | 6 | 00046 - 47 | 7 | 00047 - 48 | 8 | 00048 - 49 | 9 | 00049 - 50 | 0 | 00050 - 51 | 1 | 00051 - 53 | 3 | 00053 - 54 | 4 | 00054 - 56 | 6 | 00056 - 57 | 7 | 00057 - 58 | 8 | 00058 - 59 | 9 | 00059 - 60 | 0 | 00060 - 61 | 1 | 00061 - 63 | 3 | 00063 - 64 | 4 | 00064 - 66 | 6 | 00066 - 67 | 7 | 00067 - 68 | 8 | 00068 - 69 | 9 | 00069 - 70 | 0 | 00070 - 71 | 1 | 00071 - 73 | 3 | 00073 - 74 | 4 | 00074 - 76 | 6 | 00076 - 77 | 7 | 00077 - 78 | 8 | 00078 - 79 | 9 | 00079 - 80 | 0 | 00080 - 81 | 1 | 00081 - 83 | 3 | 00083 - 84 | 4 | 00084 - 86 | 6 | 00086 - 87 | 7 | 00087 - 88 | 8 | 00088 - 89 | 9 | 00089 - 90 | 0 | 00090 - 91 | 1 | 00091 - 93 | 3 | 00093 - 94 | 4 | 00094 - 96 | 6 | 00096 - 97 | 7 | 00097 - 98 | 8 | 00098 - 99 | 9 | 00099 - 100 | 0 | 00100 - 101 | 1 | 00101 - 103 | 3 | 00103 - 104 | 4 | 00104 - 106 | 6 | 00106 - 107 | 7 | 00107 - 108 | 8 | 00108 - 109 | 9 | 00109 - 110 | 0 | 00110 - 111 | 1 | 00111 - 113 | 3 | 00113 - 114 | 4 | 00114 - 116 | 6 | 00116 - 117 | 7 | 00117 - 118 | 8 | 00118 - 119 | 9 | 00119 - 120 | 0 | 00120 - 121 | 1 | 00121 - 123 | 3 | 00123 - 124 | 4 | 00124 - 126 | 6 | 00126 - 127 | 7 | 00127 - 128 | 8 | 00128 - 129 | 9 | 00129 - 130 | 0 | 00130 - 131 | 1 | 00131 - 133 | 3 | 00133 - 134 | 4 | 00134 - 136 | 6 | 00136 - 137 | 7 | 00137 - 138 | 8 | 00138 - 139 | 9 | 00139 - 140 | 0 | 00140 - 141 | 1 | 00141 - 143 | 3 | 00143 - 144 | 4 | 00144 - 146 | 6 | 00146 - 147 | 7 | 00147 - 148 | 8 | 00148 - 149 | 9 | 00149 - 150 | 0 | 00150 - 151 | 1 | 00151 - 153 | 3 | 00153 - 154 | 4 | 00154 - 156 | 6 | 00156 - 157 | 7 | 00157 - 158 | 8 | 00158 - 159 | 9 | 00159 - 160 | 0 | 00160 - 161 | 1 | 00161 - 163 | 3 | 00163 - 164 | 4 | 00164 - 166 | 6 | 00166 - 167 | 7 | 00167 - 168 | 8 | 00168 - 169 | 9 | 00169 - 170 | 0 | 00170 - 171 | 1 | 00171 - 173 | 3 | 00173 - 174 | 4 | 00174 - 176 | 6 | 00176 - 177 | 7 | 00177 - 178 | 8 | 00178 - 179 | 9 | 00179 - 180 | 0 | 00180 - 181 | 1 | 00181 - 183 | 3 | 00183 - 184 | 4 | 00184 - 186 | 6 | 00186 - 187 | 7 | 00187 - 188 | 8 | 00188 - 189 | 9 | 00189 - 190 | 0 | 00190 - 191 | 1 | 00191 - 193 | 3 | 00193 - 194 | 4 | 00194 - 196 | 6 | 00196 - 197 | 7 | 00197 - 198 | 8 | 00198 - 199 | 9 | 00199 - 200 | 0 | 00200 - 201 | 1 | 00201 - 203 | 3 | 00203 - 204 | 4 | 00204 - 206 | 6 | 00206 - 207 | 7 | 00207 - 208 | 8 | 00208 - 209 | 9 | 00209 - 210 | 0 | 00210 - 211 | 1 | 00211 - 213 | 3 | 00213 - 214 | 4 | 00214 - 216 | 6 | 00216 - 217 | 7 | 00217 - 218 | 8 | 00218 - 219 | 9 | 00219 - 220 | 0 | 00220 - 221 | 1 | 00221 - 223 | 3 | 00223 - 224 | 4 | 00224 - 226 | 6 | 00226 - 227 | 7 | 00227 - 228 | 8 | 00228 - 229 | 9 | 00229 - 230 | 0 | 00230 - 231 | 1 | 00231 - 233 | 3 | 00233 - 234 | 4 | 00234 - 236 | 6 | 00236 - 237 | 7 | 00237 - 238 | 8 | 00238 - 239 | 9 | 00239 - 240 | 0 | 00240 - 241 | 1 | 00241 - 243 | 3 | 00243 - 244 | 4 | 00244 - 246 | 6 | 00246 - 247 | 7 | 00247 - 248 | 8 | 00248 - 249 | 9 | 00249 - 250 | 0 | 00250 - 251 | 1 | 00251 - 253 | 3 | 00253 - 254 | 4 | 00254 - 256 | 6 | 00256 - 257 | 7 | 00257 - 258 | 8 | 00258 - 259 | 9 | 00259 - 260 | 0 | 00260 - 261 | 1 | 00261 - 263 | 3 | 00263 - 264 | 4 | 00264 - 266 | 6 | 00266 - 267 | 7 | 00267 - 268 | 8 | 00268 - 269 | 9 | 00269 - 270 | 0 | 00270 - 271 | 1 | 00271 - 273 | 3 | 00273 - 274 | 4 | 00274 - 276 | 6 | 00276 - 277 | 7 | 00277 - 278 | 8 | 00278 - 279 | 9 | 00279 - 280 | 0 | 00280 - 281 | 1 | 00281 - 283 | 3 | 00283 - 284 | 4 | 00284 - 286 | 6 | 00286 - 287 | 7 | 00287 - 288 | 8 | 00288 - 289 | 9 | 00289 - 290 | 0 | 00290 - 291 | 1 | 00291 - 293 | 3 | 00293 - 294 | 4 | 00294 - 296 | 6 | 00296 - 297 | 7 | 00297 - 298 | 8 | 00298 - 299 | 9 | 00299 - 300 | 0 | 00300 - 301 | 1 | 00301 - 303 | 3 | 00303 - 304 | 4 | 00304 - 306 | 6 | 00306 - 307 | 7 | 00307 - 308 | 8 | 00308 - 309 | 9 | 00309 - 310 | 0 | 00310 - 311 | 1 | 00311 - 313 | 3 | 00313 - 314 | 4 | 00314 - 316 | 6 | 00316 - 317 | 7 | 00317 - 318 | 8 | 00318 - 319 | 9 | 00319 - 320 | 0 | 00320 - 321 | 1 | 00321 - 323 | 3 | 00323 - 324 | 4 | 00324 - 326 | 6 | 00326 - 327 | 7 | 00327 - 328 | 8 | 00328 - 329 | 9 | 00329 - 330 | 0 | 00330 - 331 | 1 | 00331 - 333 | 3 | 00333 - 334 | 4 | 00334 - 336 | 6 | 00336 - 337 | 7 | 00337 - 338 | 8 | 00338 - 339 | 9 | 00339 - 340 | 0 | 00340 - 341 | 1 | 00341 - 343 | 3 | 00343 - 344 | 4 | 00344 - 346 | 6 | 00346 - 347 | 7 | 00347 - 348 | 8 | 00348 - 349 | 9 | 00349 - 350 | 0 | 00350 - 351 | 1 | 00351 - 353 | 3 | 00353 - 354 | 4 | 00354 - 356 | 6 | 00356 - 357 | 7 | 00357 - 358 | 8 | 00358 - 359 | 9 | 00359 - 360 | 0 | 00360 - 361 | 1 | 00361 - 363 | 3 | 00363 - 364 | 4 | 00364 - 366 | 6 | 00366 - 367 | 7 | 00367 - 368 | 8 | 00368 - 369 | 9 | 00369 - 370 | 0 | 00370 - 371 | 1 | 00371 - 373 | 3 | 00373 - 374 | 4 | 00374 - 376 | 6 | 00376 - 377 | 7 | 00377 - 378 | 8 | 00378 - 379 | 9 | 00379 - 380 | 0 | 00380 - 381 | 1 | 00381 - 383 | 3 | 00383 - 384 | 4 | 00384 - 386 | 6 | 00386 - 387 | 7 | 00387 - 388 | 8 | 00388 - 389 | 9 | 00389 - 390 | 0 | 00390 - 391 | 1 | 00391 - 393 | 3 | 00393 - 394 | 4 | 00394 - 396 | 6 | 00396 - 397 | 7 | 00397 - 398 | 8 | 00398 - 399 | 9 | 00399 - 400 | 0 | 00400 - 401 | 1 | 00401 - 403 | 3 | 00403 - 404 | 4 | 00404 - 406 | 6 | 00406 - 407 | 7 | 00407 - 408 | 8 | 00408 - 409 | 9 | 00409 - 410 | 0 | 00410 - 411 | 1 | 00411 - 413 | 3 | 00413 - 414 | 4 | 00414 - 416 | 6 | 00416 - 417 | 7 | 00417 - 418 | 8 | 00418 - 419 | 9 | 00419 - 420 | 0 | 00420 - 421 | 1 | 00421 - 423 | 3 | 00423 - 424 | 4 | 00424 - 426 | 6 | 00426 - 427 | 7 | 00427 - 428 | 8 | 00428 - 429 | 9 | 00429 - 430 | 0 | 00430 - 431 | 1 | 00431 - 433 | 3 | 00433 - 434 | 4 | 00434 - 436 | 6 | 00436 - 437 | 7 | 00437 - 438 | 8 | 00438 - 439 | 9 | 00439 - 440 | 0 | 00440 - 441 | 1 | 00441 - 443 | 3 | 00443 - 444 | 4 | 00444 - 446 | 6 | 00446 - 447 | 7 | 00447 - 448 | 8 | 00448 - 449 | 9 | 00449 - 450 | 0 | 00450 - 451 | 1 | 00451 - 453 | 3 | 00453 - 454 | 4 | 00454 - 456 | 6 | 00456 - 457 | 7 | 00457 - 458 | 8 | 00458 - 459 | 9 | 00459 - 460 | 0 | 00460 - 461 | 1 | 00461 - 463 | 3 | 00463 - 464 | 4 | 00464 - 466 | 6 | 00466 - 467 | 7 | 00467 - 468 | 8 | 00468 - 469 | 9 | 00469 - 470 | 0 | 00470 - 471 | 1 | 00471 - 473 | 3 | 00473 - 474 | 4 | 00474 - 476 | 6 | 00476 - 477 | 7 | 00477 - 478 | 8 | 00478 - 479 | 9 | 00479 - 480 | 0 | 00480 - 481 | 1 | 00481 - 483 | 3 | 00483 - 484 | 4 | 00484 - 486 | 6 | 00486 - 487 | 7 | 00487 - 488 | 8 | 00488 - 489 | 9 | 00489 - 490 | 0 | 00490 - 491 | 1 | 00491 - 493 | 3 | 00493 - 494 | 4 | 00494 - 496 | 6 | 00496 - 497 | 7 | 00497 - 498 | 8 | 00498 - 499 | 9 | 00499 - 500 | 0 | 00500 - 501 | 1 | 00501 - 503 | 3 | 00503 - 504 | 4 | 00504 - 506 | 6 | 00506 - 507 | 7 | 00507 - 508 | 8 | 00508 - 509 | 9 | 00509 - 510 | 0 | 00510 - 511 | 1 | 00511 - 513 | 3 | 00513 - 514 | 4 | 00514 - 516 | 6 | 00516 - 517 | 7 | 00517 - 518 | 8 | 00518 - 519 | 9 | 00519 - 520 | 0 | 00520 - 521 | 1 | 00521 - 523 | 3 | 00523 - 524 | 4 | 00524 - 526 | 6 | 00526 - 527 | 7 | 00527 - 528 | 8 | 00528 - 529 | 9 | 00529 - 530 | 0 | 00530 - 531 | 1 | 00531 - 533 | 3 | 00533 - 534 | 4 | 00534 - 536 | 6 | 00536 - 537 | 7 | 00537 - 538 | 8 | 00538 - 539 | 9 | 00539 - 540 | 0 | 00540 - 541 | 1 | 00541 - 543 | 3 | 00543 - 544 | 4 | 00544 - 546 | 6 | 00546 - 547 | 7 | 00547 - 548 | 8 | 00548 - 549 | 9 | 00549 - 550 | 0 | 00550 - 551 | 1 | 00551 - 553 | 3 | 00553 - 554 | 4 | 00554 - 556 | 6 | 00556 - 557 | 7 | 00557 - 558 | 8 | 00558 - 559 | 9 | 00559 - 560 | 0 | 00560 - 561 | 1 | 00561 - 563 | 3 | 00563 - 564 | 4 | 00564 - 566 | 6 | 00566 - 567 | 7 | 00567 - 568 | 8 | 00568 - 569 | 9 | 00569 - 570 | 0 | 00570 - 571 | 1 | 00571 - 573 | 3 | 00573 - 574 | 4 | 00574 - 576 | 6 | 00576 - 577 | 7 | 00577 - 578 | 8 | 00578 - 579 | 9 | 00579 - 580 | 0 | 00580 - 581 | 1 | 00581 - 583 | 3 | 00583 - 584 | 4 | 00584 - 586 | 6 | 00586 - 587 | 7 | 00587 - 588 | 8 | 00588 - 589 | 9 | 00589 - 590 | 0 | 00590 - 591 | 1 | 00591 - 593 | 3 | 00593 - 594 | 4 | 00594 - 596 | 6 | 00596 - 597 | 7 | 00597 - 598 | 8 | 00598 - 599 | 9 | 00599 - 600 | 0 | 00600 - 601 | 1 | 00601 - 603 | 3 | 00603 - 604 | 4 | 00604 - 606 | 6 | 00606 - 607 | 7 | 00607 - 608 | 8 | 00608 - 609 | 9 | 00609 - 610 | 0 | 00610 - 611 | 1 | 00611 - 613 | 3 | 00613 - 614 | 4 | 00614 - 616 | 6 | 00616 - 617 | 7 | 00617 - 618 | 8 | 00618 - 619 | 9 | 00619 - 620 | 0 | 00620 - 621 | 1 | 00621 - 623 | 3 | 00623 - 624 | 4 | 00624 - 626 | 6 | 00626 - 627 | 7 | 00627 - 628 | 8 | 00628 - 629 | 9 | 00629 - 630 | 0 | 00630 - 631 | 1 | 00631 - 633 | 3 | 00633 - 634 | 4 | 00634 - 636 | 6 | 00636 - 637 | 7 | 00637 - 638 | 8 | 00638 - 639 | 9 | 00639 - 640 | 0 | 00640 - 641 | 1 | 00641 - 643 | 3 | 00643 - 644 | 4 | 00644 - 646 | 6 | 00646 - 647 | 7 | 00647 - 648 | 8 | 00648 - 649 | 9 | 00649 - 650 | 0 | 00650 - 651 | 1 | 00651 - 653 | 3 | 00653 - 654 | 4 | 00654 - 656 | 6 | 00656 - 657 | 7 | 00657 - 658 | 8 | 00658 - 659 | 9 | 00659 - 660 | 0 | 00660 - 661 | 1 | 00661 - 663 | 3 | 00663 - 664 | 4 | 00664 - 666 | 6 | 00666 - 667 | 7 | 00667 - 668 | 8 | 00668 - 669 | 9 | 00669 - 670 | 0 | 00670 - 671 | 1 | 00671 - 673 | 3 | 00673 - 674 | 4 | 00674 - 676 | 6 | 00676 - 677 | 7 | 00677 - 678 | 8 | 00678 - 679 | 9 | 00679 - 680 | 0 | 00680 - 681 | 1 | 00681 - 683 | 3 | 00683 - 684 | 4 | 00684 - 686 | 6 | 00686 - 687 | 7 | 00687 - 688 | 8 | 00688 - 689 | 9 | 00689 - 690 | 0 | 00690 - 691 | 1 | 00691 - 693 | 3 | 00693 - 694 | 4 | 00694 - 696 | 6 | 00696 - 697 | 7 | 00697 - 698 | 8 | 00698 - 699 | 9 | 00699 - 700 | 0 | 00700 - 701 | 1 | 00701 - 703 | 3 | 00703 - 704 | 4 | 00704 - 706 | 6 | 00706 - 707 | 7 | 00707 - 708 | 8 | 00708 - 709 | 9 | 00709 - 710 | 0 | 00710 - 711 | 1 | 00711 - 713 | 3 | 00713 - 714 | 4 | 00714 - 716 | 6 | 00716 - 717 | 7 | 00717 - 718 | 8 | 00718 - 719 | 9 | 00719 - 720 | 0 | 00720 - 721 | 1 | 00721 - 723 | 3 | 00723 - 724 | 4 | 00724 - 726 | 6 | 00726 - 727 | 7 | 00727 - 728 | 8 | 00728 - 729 | 9 | 00729 - 730 | 0 | 00730 - 731 | 1 | 00731 - 733 | 3 | 00733 - 734 | 4 | 00734 - 736 | 6 | 00736 - 737 | 7 | 00737 - 738 | 8 | 00738 - 739 | 9 | 00739 - 740 | 0 | 00740 - 741 | 1 | 00741 - 743 | 3 | 00743 - 744 | 4 | 00744 - 746 | 6 | 00746 - 747 | 7 | 00747 - 748 | 8 | 00748 - 749 | 9 | 00749 - 750 | 0 | 00750 - 751 | 1 | 00751 - 753 | 3 | 00753 - 754 | 4 | 00754 - 756 | 6 | 00756 - 757 | 7 | 00757 - 758 | 8 | 00758 - 759 | 9 | 00759 - 760 | 0 | 00760 - 761 | 1 | 00761 - 763 | 3 | 00763 - 764 | 4 | 00764 - 766 | 6 | 00766 - 767 | 7 | 00767 - 768 | 8 | 00768 - 769 | 9 | 00769 - 770 | 0 | 00770 - 771 | 1 | 00771 - 773 | 3 | 00773 - 774 | 4 | 00774 - 776 | 6 | 00776 - 777 | 7 | 00777 - 778 | 8 | 00778 - 779 | 9 | 00779 - 780 | 0 | 00780 - 781 | 1 | 00781 - 783 | 3 | 00783 - 784 | 4 | 00784 - 786 | 6 | 00786 - 787 | 7 | 00787 - 788 | 8 | 00788 - 789 | 9 | 00789 - 790 | 0 | 00790 - 791 | 1 | 00791 - 793 | 3 | 00793 - 794 | 4 | 00794 - 796 | 6 | 00796 - 797 | 7 | 00797 - 798 | 8 | 00798 - 799 | 9 | 00799 - 800 | 0 | 00800 - 801 | 1 | 00801 - 803 | 3 | 00803 - 804 | 4 | 00804 - 806 | 6 | 00806 - 807 | 7 | 00807 - 808 | 8 | 00808 - 809 | 9 | 00809 - 810 | 0 | 00810 - 811 | 1 | 00811 - 813 | 3 | 00813 - 814 | 4 | 00814 - 816 | 6 | 00816 - 817 | 7 | 00817 - 818 | 8 | 00818 - 819 | 9 | 00819 - 820 | 0 | 00820 - 821 | 1 | 00821 - 823 | 3 | 00823 - 824 | 4 | 00824 - 826 | 6 | 00826 - 827 | 7 | 00827 - 828 | 8 | 00828 - 829 | 9 | 00829 - 830 | 0 | 00830 - 831 | 1 | 00831 - 833 | 3 | 00833 - 834 | 4 | 00834 - 836 | 6 | 00836 - 837 | 7 | 00837 - 838 | 8 | 00838 - 839 | 9 | 00839 - 840 | 0 | 00840 - 841 | 1 | 00841 - 843 | 3 | 00843 - 844 | 4 | 00844 - 846 | 6 | 00846 - 847 | 7 | 00847 - 848 | 8 | 00848 - 849 | 9 | 00849 - 850 | 0 | 00850 - 851 | 1 | 00851 - 853 | 3 | 00853 - 854 | 4 | 00854 - 856 | 6 | 00856 - 857 | 7 | 00857 - 858 | 8 | 00858 - 859 | 9 | 00859 - 860 | 0 | 00860 - 861 | 1 | 00861 - 863 | 3 | 00863 - 864 | 4 | 00864 - 866 | 6 | 00866 - 867 | 7 | 00867 - 868 | 8 | 00868 - 869 | 9 | 00869 - 870 | 0 | 00870 - 871 | 1 | 00871 - 873 | 3 | 00873 - 874 | 4 | 00874 - 876 | 6 | 00876 - 877 | 7 | 00877 - 878 | 8 | 00878 - 879 | 9 | 00879 - 880 | 0 | 00880 - 881 | 1 | 00881 - 883 | 3 | 00883 - 884 | 4 | 00884 - 886 | 6 | 00886 - 887 | 7 | 00887 - 888 | 8 | 00888 - 889 | 9 | 00889 - 890 | 0 | 00890 - 891 | 1 | 00891 - 893 | 3 | 00893 - 894 | 4 | 00894 - 896 | 6 | 00896 - 897 | 7 | 00897 - 898 | 8 | 00898 - 899 | 9 | 00899 - 900 | 0 | 00900 - 901 | 1 | 00901 - 903 | 3 | 00903 - 904 | 4 | 00904 - 906 | 6 | 00906 - 907 | 7 | 00907 - 908 | 8 | 00908 - 909 | 9 | 00909 - 910 | 0 | 00910 - 911 | 1 | 00911 - 913 | 3 | 00913 - 914 | 4 | 00914 - 916 | 6 | 00916 - 917 | 7 | 00917 - 918 | 8 | 00918 - 919 | 9 | 00919 - 920 | 0 | 00920 - 921 | 1 | 00921 - 923 | 3 | 00923 - 924 | 4 | 00924 - 926 | 6 | 00926 - 927 | 7 | 00927 - 928 | 8 | 00928 - 929 | 9 | 00929 - 930 | 0 | 00930 - 931 | 1 | 00931 - 933 | 3 | 00933 - 934 | 4 | 00934 - 936 | 6 | 00936 - 937 | 7 | 00937 - 938 | 8 | 00938 - 939 | 9 | 00939 - 940 | 0 | 00940 - 941 | 1 | 00941 - 943 | 3 | 00943 - 944 | 4 | 00944 - 946 | 6 | 00946 - 947 | 7 | 00947 - 948 | 8 | 00948 - 949 | 9 | 00949 - 950 | 0 | 00950 - 951 | 1 | 00951 - 953 | 3 | 00953 - 954 | 4 | 00954 - 956 | 6 | 00956 - 957 | 7 | 00957 - 958 | 8 | 00958 - 959 | 9 | 00959 - 960 | 0 | 00960 - 961 | 1 | 00961 - 963 | 3 | 00963 - 964 | 4 | 00964 - 966 | 6 | 00966 - 967 | 7 | 00967 - 968 | 8 | 00968 - 969 | 9 | 00969 - 970 | 0 | 00970 - 971 | 1 | 00971 - 973 | 3 | 00973 - 974 | 4 | 00974 - 976 | 6 | 00976 - 977 | 7 | 00977 - 978 | 8 | 00978 - 979 | 9 | 00979 - 980 | 0 | 00980 - 981 | 1 | 00981 - 983 | 3 | 00983 - 984 | 4 | 00984 - 986 | 6 | 00986 - 987 | 7 | 00987 - 988 | 8 | 00988 - 989 | 9 | 00989 - 990 | 0 | 00990 - 991 | 1 | 00991 - 993 | 3 | 00993 - 994 | 4 | 00994 - 996 | 6 | 00996 - 997 | 7 | 00997 - 998 | 8 | 00998 - 999 | 9 | 00999 - 1000 | 0 | 01000 - 1001 | 101 | 0000100001 - 1003 | 103 | 0000300003 - 1004 | 104 | 0000400004 - 1006 | 106 | 0000600006 - 1007 | 107 | 0000700007 - 1008 | 108 | 0000800008 - 1009 | 109 | 0000900009 - 1010 | 100 | 0001000010 - 1011 | 101 | 0001100011 - 1013 | 103 | 0001300013 - 1014 | 104 | 0001400014 - 1016 | 106 | 0001600016 - 1017 | 107 | 0001700017 - 1018 | 108 | 0001800018 - 1019 | 109 | 0001900019 - 1020 | 100 | 0002000020 - 1101 | 201 | aaa - 1103 | 203 | ccc - 1104 | 204 | ddd -(819 rows) - ---Testcase 384: -EXPLAIN (verbose, costs off) -INSERT INTO ft2_nsc (c1,c2,c3) VALUES (1200,999,'foo'); - QUERY PLAN ------------------------------------------------------------------------------------------------------------------------------------------------------------- - Insert on public.ft2_nsc - -> Result - Output: 1200, 999, NULL::integer, 'foo'::text, NULL::timestamp without time zone, NULL::character varying, 'ft2 '::character(10), NULL::text -(3 rows) - ---Testcase 385: -INSERT INTO ft2_nsc (c1,c2,c3) VALUES (1200,999,'foo'); ---Testcase 386: -SELECT (fields->>'C 1')::int c1 FROM ft2 WHERE (fields->>'C 1')::int = 1200 AND (fields->>'c2')::int = 999; - c1 ------- - 1200 -(1 row) - ---EXPLAIN (verbose, costs off) ---UPDATE ft2 SET c3 = 'bar' WHERE c1 = 1200 RETURNING tableoid::regclass; -- can be pushed down ---UPDATE ft2 SET c3 = 'bar' WHERE c1 = 1200 RETURNING tableoid::regclass; ---Testcase 387: -EXPLAIN (verbose, costs off) -DELETE FROM ft2_nsc WHERE c1 = 1200; - QUERY PLAN ------------------------------------------------------------------------------ - Delete on public.ft2_nsc - -> Foreign Scan on public.ft2_nsc - Output: c3, "time" - InfluxDB query: SELECT "c3", "C 1" FROM "T1" WHERE (("C 1" = 1200)) -(4 rows) - ---Testcase 388: -SELECT (fields->>'C 1')::int c1 FROM ft2 WHERE (fields->>'C 1')::int = 1200; - c1 ------- - 1200 -(1 row) - ---Testcase 389: -DELETE FROM ft2_nsc WHERE c1 = 1200; ---Testcase 390: -SELECT (fields->>'C 1')::int c1 FROM ft2 WHERE (fields->>'C 1')::int = 1200; - c1 ----- -(0 rows) - --- Test UPDATE/DELETE with RETURNING on a three-table join ---Testcase 391: -INSERT INTO ft2_nsc (c1,c2,c3) - SELECT id, id - 1200, to_char(id, 'FM00000') FROM generate_series(1201, 1300) id; ---EXPLAIN (verbose, costs off) ---UPDATE ft2 SET c3 = 'foo' --- FROM ft4 INNER JOIN ft5 ON (ft4.c1 = ft5.c1) --- WHERE ft2.c1 > 1200 AND ft2.c2 = ft4.c1 --- RETURNING ft2, ft2.*, ft4, ft4.*; -- can be pushed down ---UPDATE ft2 SET c3 = 'foo' --- FROM ft4 INNER JOIN ft5 ON (ft4.c1 = ft5.c1) --- WHERE ft2.c1 > 1200 AND ft2.c2 = ft4.c1 --- RETURNING ft2, ft2.*, ft4, ft4.*; ---Testcase 392: -EXPLAIN (verbose, costs off) -DELETE FROM ft2_nsc - USING ft4_nsc LEFT JOIN ft5_nsc ON (ft4_nsc.c1 = ft5_nsc.c1) - WHERE ft2_nsc.c1 > 1200 AND ft2_nsc.c1 % 10 = 0 AND ft2_nsc.c2 = ft4_nsc.c1; -- can be pushed down - QUERY PLAN ------------------------------------------------------------------------------------------------------------------------------ - Delete on public.ft2_nsc - -> Hash Right Join - Output: ft2_nsc.c3, ft2_nsc."time", ft4_nsc.*, ft5_nsc.* - Hash Cond: (ft5_nsc.c1 = ft4_nsc.c1) - -> Foreign Scan on public.ft5_nsc - Output: ft5_nsc.*, ft5_nsc.c1 - InfluxDB query: SELECT "c1", "c2", "c3" FROM "T4" - -> Hash - Output: ft2_nsc.c3, ft2_nsc."time", ft4_nsc.*, ft4_nsc.c1 - -> Hash Join - Output: ft2_nsc.c3, ft2_nsc."time", ft4_nsc.*, ft4_nsc.c1 - Hash Cond: (ft4_nsc.c1 = ft2_nsc.c2) - -> Foreign Scan on public.ft4_nsc - Output: ft4_nsc.*, ft4_nsc.c1 - InfluxDB query: SELECT "c1", "c2", "c3" FROM "T3" - -> Hash - Output: ft2_nsc.c3, ft2_nsc."time", ft2_nsc.c2 - -> Foreign Scan on public.ft2_nsc - Output: ft2_nsc.c3, ft2_nsc."time", ft2_nsc.c2 - InfluxDB query: SELECT "c2", "c3" FROM "T1" WHERE (("C 1" > 1200)) AND ((("C 1" % 10) = 0)) -(20 rows) - ---Testcase 393: -SELECT 100 FROM ft2, - ft4 LEFT JOIN ft5 ON ((ft4.fields->>'c1')::int = (ft5.fields->>'c1')::int) - WHERE (ft2.fields->>'C 1')::int > 1200 AND (ft2.fields->>'C 1')::int % 10 = 0 AND (ft2.fields->>'c2')::int = (ft4.fields->>'c1')::int; - ?column? ----------- - 100 - 100 - 100 - 100 - 100 - 100 - 100 - 100 - 100 - 100 -(10 rows) - ---Testcase 394: -DELETE FROM ft2_nsc - USING ft4_nsc LEFT JOIN ft5_nsc ON (ft4_nsc.c1 = ft5_nsc.c1) - WHERE ft2_nsc.c1 > 1200 AND ft2_nsc.c1 % 10 = 0 AND ft2_nsc.c2 = ft4_nsc.c1; ---Testcase 395: -SELECT 100 FROM ft2, - ft4 LEFT JOIN ft5 ON ((ft4.fields->>'c1')::int = (ft5.fields->>'c1')::int) - WHERE (ft2.fields->>'C 1')::int > 1200 AND (ft2.fields->>'C 1')::int % 10 = 0 AND (ft2.fields->>'c2')::int = (ft4.fields->>'c1')::int; - ?column? ----------- -(0 rows) - ---Testcase 396: -DELETE FROM ft2_nsc WHERE ft2_nsc.c1 > 1200; --- Test UPDATE with a MULTIEXPR sub-select --- (maybe someday this'll be remotely executable, but not today) ---EXPLAIN (verbose, costs off) ---UPDATE ft2 AS target SET (c2, c7) = ( --- SELECT c2 * 10, c7 --- FROM ft2 AS src --- WHERE target.c1 = src.c1 ---) WHERE c1 > 1100; ---UPDATE ft2 AS target SET (c2, c7) = ( --- SELECT c2 * 10, c7 --- FROM ft2 AS src --- WHERE targ--et.c1 = src.c1 ---) WHERE c1 > 1100; ---UPDATE ft2 AS target SET (c2) = ( --- SELECT c2 / 10 --- FROM ft2 AS src --- WHERE targ--et.c1 = src.c1 ---) WHERE c1 > 1100; --- Test UPDATE/DELETE with WHERE or JOIN/ON conditions containing --- user-defined operators/functions ---Testcase 397: -INSERT INTO ft2_nsc (c1,c2,c3) - SELECT id, id % 10, to_char(id, 'FM00000') FROM generate_series(2001, 2010) id; ---EXPLAIN (verbose, costs off) ---UPDATE ft2 SET c3 = 'bar' WHERE influxdb_fdw_abs(c1) > 2000 RETURNING *; -- can't be pushed down ---UPDATE ft2 SET c3 = 'bar' WHERE influxdb_fdw_abs(c1) > 2000 RETURNING *; ---EXPLAIN (verbose, costs off) ---UPDATE ft2 SET c3 = 'baz' --- FROM ft4 INNER JOIN ft5 ON (ft4.c1 = ft5.c1) --- WHERE ft2.c1 > 2000 AND ft2.c2 === ft4.c1 --- RETURNING ft2.*, ft4.*, ft5.*; -- can't be pushed down ---UPDATE ft2 SET c3 = 'baz' --- FROM ft4 INNER JOIN ft5 ON (ft4.c1 = ft5.c1) --- WHERE ft2.c1 > 2000 AND ft2.c2 === ft4.c1 --- RETURNING ft2.*, ft4.*, ft5.*; ---Testcase 398: -EXPLAIN (verbose, costs off) -DELETE FROM ft2_nsc - USING ft4_nsc INNER JOIN ft5_nsc ON (ft4_nsc.c1 === ft5_nsc.c1) - WHERE ft2_nsc.c1 > 2000 AND ft2_nsc.c2 = ft4_nsc.c1; -- can't be pushed down - QUERY PLAN ----------------------------------------------------------------------------------------------- - Delete on public.ft2_nsc - -> Nested Loop - Output: ft2_nsc.c3, ft2_nsc."time", ft4_nsc.*, ft5_nsc.* - Join Filter: (ft4_nsc.c1 === ft5_nsc.c1) - -> Hash Join - Output: ft2_nsc.c3, ft2_nsc."time", ft4_nsc.*, ft4_nsc.c1 - Hash Cond: (ft4_nsc.c1 = ft2_nsc.c2) - -> Foreign Scan on public.ft4_nsc - Output: ft4_nsc.*, ft4_nsc.c1 - InfluxDB query: SELECT "c1", "c2", "c3" FROM "T3" - -> Hash - Output: ft2_nsc.c3, ft2_nsc."time", ft2_nsc.c2 - -> Foreign Scan on public.ft2_nsc - Output: ft2_nsc.c3, ft2_nsc."time", ft2_nsc.c2 - InfluxDB query: SELECT "c2", "c3" FROM "T1" WHERE (("C 1" > 2000)) - -> Materialize - Output: ft5_nsc.*, ft5_nsc.c1 - -> Foreign Scan on public.ft5_nsc - Output: ft5_nsc.*, ft5_nsc.c1 - InfluxDB query: SELECT "c1", "c2", "c3" FROM "T4" -(20 rows) - ---Testcase 399: -SELECT (ft2.fields->>'C 1')::int c1, (ft2.fields->>'c2')::int c2, ft2.tags->>'c3' c3 - FROM ft2, ft4 INNER JOIN ft5 ON ((ft4.fields->>'c1')::int === (ft5.fields->>'c1')::int) - WHERE (ft2.fields->>'C 1')::int > 2000 AND (ft2.fields->>'c2')::int = (ft4.fields->>'c1')::int; - c1 | c2 | c3 -------+----+------- - 2006 | 6 | 02006 -(1 row) - ---Testcase 400: -DELETE FROM ft2_nsc - USING ft4_nsc INNER JOIN ft5_nsc ON (ft4_nsc.c1 === ft5_nsc.c1) - WHERE ft2_nsc.c1 > 2000 AND ft2_nsc.c2 = ft4_nsc.c1; ---Testcase 401: -SELECT (ft2.fields->>'C 1')::int c1, (ft2.fields->>'c2')::int c2, ft2.tags->>'c3' c3 - FROM ft2, ft4 INNER JOIN ft5 ON ((ft4.fields->>'c1')::int === (ft5.fields->>'c1')::int) - WHERE (ft2.fields->>'C 1')::int > 2000 AND (ft2.fields->>'c2')::int = (ft4.fields->>'c1')::int; - c1 | c2 | c3 -----+----+---- -(0 rows) - ---Testcase 402: -DELETE FROM ft2_nsc WHERE ft2_nsc.c1 > 2000; --- Test that trigger on remote table works as expected ---Testcase 403: -CREATE OR REPLACE FUNCTION "S 1".F_BRTRIG() RETURNS trigger AS $$ -BEGIN - NEW.c3 = NEW.c3 || '_trig_update'; - RETURN NEW; -END; -$$ LANGUAGE plpgsql; ---Testcase 404: -CREATE TRIGGER t1_br_insert BEFORE INSERT OR UPDATE - ON "S 1".s1t1 FOR EACH ROW EXECUTE PROCEDURE "S 1".F_BRTRIG(); ---Testcase 405: -INSERT INTO ft2_nsc (c1,c2,c3) VALUES (1208, 818, 'fff'); ---Testcase 406: -SELECT (fields->>'C 1')::int c1, (fields->>'c2')::int c2, tags->>'c3' c3, fields->>'c6' c6, fields->>'c7' c7, fields->>'c8' c8 FROM ft2 WHERE (fields->>'C 1')::int = 1208; - c1 | c2 | c3 | c6 | c7 | c8 -------+-----+-----+----+------------+---- - 1208 | 818 | fff | | ft2 | -(1 row) - ---Testcase 407: -INSERT INTO ft2_nsc (c1,c2,c3,c6) VALUES (1218, 818, 'ggg', '(--;'); ---Testcase 408: -SELECT (fields->>'C 1')::int c1, (fields->>'c2')::int c2, tags->>'c3' c3, fields->>'c6' c6, fields->>'c7' c7, fields->>'c8' c8 FROM ft2 WHERE (fields->>'C 1')::int = 1218; - c1 | c2 | c3 | c6 | c7 | c8 -------+-----+-----+------+------------+---- - 1218 | 818 | ggg | (--; | ft2 | -(1 row) - ---UPDATE ft2 SET c2 = c2 + 600 WHERE c1 % 10 = 8 AND c1 < 1200 RETURNING *; --- Test errors thrown on remote side during update -ALTER TABLE "S 1"."T 1" ADD CONSTRAINT c2positive CHECK ((fields->>'c2')::int >= 0); --- influxdb_fdw does not support key, ON CONFLICT ---INSERT INTO ft1(c1, c2) VALUES(11, 12); -- duplicate key ---Testcase 409: -INSERT INTO ft1_nsc(c1, c2) VALUES(11, 12) ON CONFLICT DO NOTHING; -- works -ERROR: ON CONFLICT is not supported ---Testcase 410: -INSERT INTO ft1_nsc(c1, c2) VALUES(11, 12) ON CONFLICT (c1, c2) DO NOTHING; -- unsupported -ERROR: there is no unique or exclusion constraint matching the ON CONFLICT specification ---Testcase 411: -INSERT INTO ft1_nsc(c1, c2) VALUES(11, 12) ON CONFLICT (c1, c2) DO UPDATE SET c3 = 'ffg'; -- unsupported -ERROR: there is no unique or exclusion constraint matching the ON CONFLICT specification ---INSERT INTO ft1(c1, c2) VALUES(1111, -2); -- c2positive ---UPDATE ft1 SET c2 = -c2 WHERE c1 = 1; -- c2positive -/* --- influxdb_fdw does not support transactions --- Test savepoint/rollback behavior -select c2, count(*) from ft2 where c2 < 500 group by 1 order by 1; -select c2, count(*) from "S 1"."T 1" where c2 < 500 group by 1 order by 1; -begin; -update ft2 set c2 = 42 where c2 = 0; -select c2, count(*) from ft2 where c2 < 500 group by 1 order by 1; -savepoint s1; -update ft2 set c2 = 44 where c2 = 4; -select c2, count(*) from ft2 where c2 < 500 group by 1 order by 1; -release savepoint s1; -select c2, count(*) from ft2 where c2 < 500 group by 1 order by 1; -savepoint s2; -update ft2 set c2 = 46 where c2 = 6; -select c2, count(*) from ft2 where c2 < 500 group by 1 order by 1; -rollback to savepoint s2; -select c2, count(*) from ft2 where c2 < 500 group by 1 order by 1; -release savepoint s2; -select c2, count(*) from ft2 where c2 < 500 group by 1 order by 1; -savepoint s3; -update ft2 set c2 = -2 where c2 = 42 and c1 = 10; -- fail on remote side -rollback to savepoint s3; -select c2, count(*) from ft2 where c2 < 500 group by 1 order by 1; -release savepoint s3; -select c2, count(*) from ft2 where c2 < 500 group by 1 order by 1; --- none of the above is committed yet remotely -select c2, count(*) from "S 1"."T 1" where c2 < 500 group by 1 order by 1; -commit; -select c2, count(*) from ft2 where c2 < 500 group by 1 order by 1; -select c2, count(*) from "S 1"."T 1" where c2 < 500 group by 1 order by 1; -*/ --- Above DMLs add data with c6 as NULL in ft1, so test ORDER BY NULLS LAST and NULLs --- FIRST behavior here. --- ORDER BY DESC NULLS LAST options ---Testcase 412: -EXPLAIN (VERBOSE, COSTS OFF) SELECT * FROM ft1 ORDER BY fields->>'c6' DESC NULLS LAST, (fields->>'C 1')::int OFFSET 795 LIMIT 10; - QUERY PLAN ------------------------------------------------------------------------------------------------------------- - Limit - Output: "time", tags, fields, ((fields ->> 'c6'::text)), (((fields ->> 'C 1'::text))::integer) - -> Sort - Output: "time", tags, fields, ((fields ->> 'c6'::text)), (((fields ->> 'C 1'::text))::integer) - Sort Key: ((ft1.fields ->> 'c6'::text)) DESC NULLS LAST, (((ft1.fields ->> 'C 1'::text))::integer) - -> Foreign Scan on public.ft1 - Output: "time", tags, fields, (fields ->> 'c6'::text), ((fields ->> 'C 1'::text))::integer - InfluxDB query: SELECT * FROM "T1" -(8 rows) - ---Testcase 413: -SELECT (fields->>'C 1')::int c1, (fields->>'c2')::int c2, tags->>'c3' c3, fields->>'c6' c6, fields->>'c7' c7, fields->>'c8' c8 FROM ft1 ORDER BY fields->>'c6' DESC NULLS LAST, (fields->>'C 1')::int OFFSET 795 LIMIT 10; - c1 | c2 | c3 | c6 | c7 | c8 -------+-----+------------+------+------------+----- - 960 | 0 | 00960 | 0 | 0 | foo - 970 | 0 | 00970 | 0 | 0 | foo - 980 | 0 | 00980 | 0 | 0 | foo - 990 | 0 | 00990 | 0 | 0 | foo - 1000 | 0 | 01000 | 0 | 0 | foo - 1218 | 818 | ggg | (--; | ft2 | - 1001 | 101 | 0000100001 | | ft2 | - 1003 | 103 | 0000300003 | | ft2 | - 1004 | 104 | 0000400004 | | ft2 | - 1006 | 106 | 0000600006 | | ft2 | -(10 rows) - --- ORDER BY DESC NULLS FIRST options ---Testcase 414: -EXPLAIN (VERBOSE, COSTS OFF) SELECT * FROM ft1 ORDER BY fields->>'c6' DESC NULLS FIRST, (fields->>'C 1')::int OFFSET 15 LIMIT 10; - QUERY PLAN ----------------------------------------------------------------------------------------------------------- - Limit - Output: "time", tags, fields, ((fields ->> 'c6'::text)), (((fields ->> 'C 1'::text))::integer) - -> Sort - Output: "time", tags, fields, ((fields ->> 'c6'::text)), (((fields ->> 'C 1'::text))::integer) - Sort Key: ((ft1.fields ->> 'c6'::text)) DESC, (((ft1.fields ->> 'C 1'::text))::integer) - -> Foreign Scan on public.ft1 - Output: "time", tags, fields, (fields ->> 'c6'::text), ((fields ->> 'C 1'::text))::integer - InfluxDB query: SELECT * FROM "T1" -(8 rows) - ---Testcase 415: -SELECT (fields->>'C 1')::int c1, (fields->>'c2')::int c2, tags->>'c3' c3, fields->>'c6' c6, fields->>'c7' c7, fields->>'c8' c8 FROM ft1 ORDER BY fields->>'c6' DESC NULLS FIRST, (fields->>'C 1')::int OFFSET 15 LIMIT 10; - c1 | c2 | c3 | c6 | c7 | c8 -------+-----+------------+----+------------+----- - 1020 | 100 | 0002000020 | | ft2 | - 1101 | 201 | aaa | | ft2 | - 1103 | 203 | ccc | | ft2 | - 1104 | 204 | ddd | | ft2 | - 1208 | 818 | fff | | ft2 | - 9 | 9 | 00009 | 9 | 9 | foo - 19 | 9 | 00019 | 9 | 9 | foo - 29 | 9 | 00029 | 9 | 9 | foo - 39 | 9 | 00039 | 9 | 9 | foo - 49 | 9 | 00049 | 9 | 9 | foo -(10 rows) - --- ORDER BY ASC NULLS FIRST options ---Testcase 416: -EXPLAIN (VERBOSE, COSTS OFF) SELECT * FROM ft1 ORDER BY fields->>'c6' ASC NULLS FIRST, (fields->>'C 1')::int OFFSET 15 LIMIT 10; - QUERY PLAN ----------------------------------------------------------------------------------------------------------- - Limit - Output: "time", tags, fields, ((fields ->> 'c6'::text)), (((fields ->> 'C 1'::text))::integer) - -> Sort - Output: "time", tags, fields, ((fields ->> 'c6'::text)), (((fields ->> 'C 1'::text))::integer) - Sort Key: ((ft1.fields ->> 'c6'::text)) NULLS FIRST, (((ft1.fields ->> 'C 1'::text))::integer) - -> Foreign Scan on public.ft1 - Output: "time", tags, fields, (fields ->> 'c6'::text), ((fields ->> 'C 1'::text))::integer - InfluxDB query: SELECT * FROM "T1" -(8 rows) - ---Testcase 417: -SELECT (fields->>'C 1')::int c1, (fields->>'c2')::int c2, tags->>'c3' c3, fields->>'c6' c6, fields->>'c7' c7, fields->>'c8' c8 FROM ft1 ORDER BY fields->>'c6' ASC NULLS FIRST, (fields->>'C 1')::int OFFSET 15 LIMIT 10; - c1 | c2 | c3 | c6 | c7 | c8 -------+-----+------------+------+------------+----- - 1020 | 100 | 0002000020 | | ft2 | - 1101 | 201 | aaa | | ft2 | - 1103 | 203 | ccc | | ft2 | - 1104 | 204 | ddd | | ft2 | - 1208 | 818 | fff | | ft2 | - 1218 | 818 | ggg | (--; | ft2 | - 10 | 0 | 00010 | 0 | 0 | foo - 20 | 0 | 00020 | 0 | 0 | foo - 30 | 0 | 00030 | 0 | 0 | foo - 40 | 0 | 00040 | 0 | 0 | foo -(10 rows) - --- =================================================================== --- test check constraints --- =================================================================== --- Consistent check constraints provide consistent results -ALTER FOREIGN TABLE ft1 ADD CONSTRAINT ft1_c2positive CHECK ((fields->>'c2')::int >= 0); ---Testcase 418: -EXPLAIN (VERBOSE, COSTS OFF) SELECT count(*) FROM ft1 WHERE (fields->>'c2')::int < 0; - QUERY PLAN ----------------------------------------------------------------- - Foreign Scan - Output: (count(*)) - InfluxDB query: SELECT count(*) FROM "T1" WHERE (("c2" < 0)) -(3 rows) - --- InfluxDB return null value because it does not have any record. ---Testcase 419: -SELECT count(*) FROM ft1 WHERE (fields->>'c2')::int < 0; - count -------- -(0 rows) - -SET constraint_exclusion = 'on'; ---Testcase 420: -EXPLAIN (VERBOSE, COSTS OFF) SELECT count(*) FROM ft1 WHERE (fields->>'c2')::int < 0; - QUERY PLAN --------------------------------- - Aggregate - Output: count(*) - -> Result - One-Time Filter: false -(4 rows) - ---Testcase 421: -SELECT count(*) FROM ft1 WHERE (fields->>'c2')::int < 0; - count -------- - 0 -(1 row) - -RESET constraint_exclusion; --- check constraint is enforced on the remote side, not locally --- INSERT INTO ft1(c1, c2) VALUES(1111, -2); -- c2positive --- UPDATE ft1 SET c2 = -c2 WHERE c1 = 1; -- c2positive -ALTER FOREIGN TABLE ft1 DROP CONSTRAINT ft1_c2positive; --- But inconsistent check constraints provide inconsistent results -ALTER FOREIGN TABLE ft1 ADD CONSTRAINT ft1_c2negative CHECK ((fields->>'c2')::int < 0); ---Testcase 422: -EXPLAIN (VERBOSE, COSTS OFF) SELECT count(*) FROM ft1 WHERE (fields->>'c2')::int >= 0; - QUERY PLAN ------------------------------------------------------------------ - Foreign Scan - Output: (count(*)) - InfluxDB query: SELECT count(*) FROM "T1" WHERE (("c2" >= 0)) -(3 rows) - ---Testcase 423: -SELECT count(*) FROM ft1 WHERE (fields->>'c2')::int >= 0; - count -------- - 821 -(1 row) - -SET constraint_exclusion = 'on'; ---Testcase 424: -EXPLAIN (VERBOSE, COSTS OFF) SELECT count(*) FROM ft1 WHERE (fields->>'c2')::int >= 0; - QUERY PLAN --------------------------------- - Aggregate - Output: count(*) - -> Result - One-Time Filter: false -(4 rows) - ---Testcase 425: -SELECT count(*) FROM ft1 WHERE (fields->>'c2')::int >= 0; - count -------- - 0 -(1 row) - -RESET constraint_exclusion; --- local check constraint is not actually enforced ---Testcase 426: -INSERT INTO ft1_nsc(c1, c2) VALUES(1111, 2); --- UPDATE ft1 SET c2 = c2 + 1 WHERE c1 = 1; -ALTER FOREIGN TABLE ft1 DROP CONSTRAINT ft1_c2negative; --- influxdb_fdw does not support this feature --- =================================================================== --- test WITH CHECK OPTION constraints --- =================================================================== ---Testcase 427: -CREATE FUNCTION row_before_insupd_trigfunc() RETURNS trigger AS $$BEGIN NEW.a := NEW.a + 10; RETURN NEW; END$$ LANGUAGE plpgsql; ---Testcase 428: -CREATE FOREIGN TABLE base_tbl (fields jsonb OPTIONS(fields 'true')) SERVER influxdb_svr OPTIONS (table 'base_tbl', schemaless 'true'); ---ALTER FOREIGN TABLE base_tbl SET (autovacuum_enabled = 'false'); -CREATE FOREIGN TABLE base_tbl_nsc (a int, b int) SERVER influxdb_svr OPTIONS (table 'base_tbl'); ---Testcase 429: -CREATE TRIGGER row_before_insupd_trigger BEFORE INSERT OR UPDATE ON base_tbl_nsc FOR EACH ROW EXECUTE PROCEDURE row_before_insupd_trigfunc(); ---Testcase 430: -CREATE FOREIGN TABLE foreign_tbl (fields jsonb OPTIONS(fields 'true')) SERVER influxdb_svr OPTIONS (table 'base_tbl', schemaless 'true'); ---Testcase 431: -CREATE VIEW rw_view AS SELECT * FROM base_tbl - WHERE (fields->>'a')::int < (fields->>'b')::int WITH CHECK OPTION; -CREATE VIEW rw_view_nsc AS SELECT * FROM base_tbl_nsc - WHERE a < b WITH CHECK OPTION; ---Testcase 432: -\d+ rw_view - View "public.rw_view" - Column | Type | Collation | Nullable | Default | Storage | Description ---------+-------+-----------+----------+---------+----------+------------- - fields | jsonb | | | | extended | -View definition: - SELECT base_tbl.fields - FROM base_tbl - WHERE ((base_tbl.fields ->> 'a'::text)::integer) < ((base_tbl.fields ->> 'b'::text)::integer); -Options: check_option=cascaded - ---Testcase 433: -EXPLAIN (VERBOSE, COSTS OFF) -INSERT INTO rw_view_nsc VALUES (0, 5); - QUERY PLAN -------------------------------- - Insert on public.base_tbl_nsc - -> Result - Output: 0, 5 -(3 rows) - ---Testcase 434: -INSERT INTO rw_view_nsc VALUES (0, 5); -- should fail -ERROR: new row violates check option for view "rw_view_nsc" -DETAIL: Failing row contains (10, 5). ---Testcase 435: -EXPLAIN (VERBOSE, COSTS OFF) -INSERT INTO rw_view_nsc VALUES (0, 15); - QUERY PLAN -------------------------------- - Insert on public.base_tbl_nsc - -> Result - Output: 0, 15 -(3 rows) - ---Testcase 436: -INSERT INTO rw_view_nsc VALUES (0, 15); -- ok ---Testcase 437: -SELECT * FROM foreign_tbl; - fields ------------------------- - {"a": "10", "b": "5"} - {"a": "10", "b": "15"} -(2 rows) - ---EXPLAIN (VERBOSE, COSTS OFF) ---UPDATE rw_view SET b = b + 5; ---UPDATE rw_view SET b = b + 5; -- should fail ---EXPLAIN (VERBOSE, COSTS OFF) ---UPDATE rw_view SET b = b + 15; ---UPDATE rw_view SET b = b + 15; -- ok ---SELECT * FROM foreign_tbl; ---Testcase 438: -DELETE FROM foreign_tbl; -DROP FOREIGN TABLE foreign_tbl CASCADE; ---Testcase 439: -DROP TRIGGER row_before_insupd_trigger ON base_tbl_nsc; ---Testcase 440: -DROP FOREIGN TABLE base_tbl CASCADE; -NOTICE: drop cascades to view rw_view -DROP FOREIGN TABLE base_tbl_nsc CASCADE; -NOTICE: drop cascades to view rw_view_nsc --- influxdb_fdw does not support partitions --- test WCO for partitions ---Testcase 441: -CREATE FOREIGN TABLE child_tbl (fields jsonb OPTIONS(fields 'true')) SERVER influxdb_svr OPTIONS (table 'child_tbl', schemaless 'true'); ---ALTER FOREIGN TABLE child_tbl SET (autovacuum_enabled = 'false'); -CREATE FOREIGN TABLE child_tbl_nsc (a int, b int) SERVER influxdb_svr OPTIONS (table 'child_tbl'); ---Testcase 442: -CREATE TRIGGER row_before_insupd_trigger BEFORE INSERT OR UPDATE ON child_tbl_nsc FOR EACH ROW EXECUTE PROCEDURE row_before_insupd_trigfunc(); ---Testcase 443: -CREATE FOREIGN TABLE foreign_tbl (fields jsonb OPTIONS(fields 'true')) SERVER influxdb_svr OPTIONS (table 'child_tbl', schemaless 'true'); ---Testcase 444: -CREATE TABLE parent_tbl (a int, b int) PARTITION BY RANGE(a); -ALTER TABLE parent_tbl ATTACH PARTITION child_tbl_nsc FOR VALUES FROM (0) TO (100); ---Testcase 445: -CREATE VIEW rw_view AS SELECT * FROM parent_tbl - WHERE a < b WITH CHECK OPTION; ---Testcase 446: -\d+ rw_view - View "public.rw_view" - Column | Type | Collation | Nullable | Default | Storage | Description ---------+---------+-----------+----------+---------+---------+------------- - a | integer | | | | plain | - b | integer | | | | plain | -View definition: - SELECT parent_tbl.a, - parent_tbl.b - FROM parent_tbl - WHERE parent_tbl.a < parent_tbl.b; -Options: check_option=cascaded - ---Testcase 447: -EXPLAIN (VERBOSE, COSTS OFF) -INSERT INTO rw_view VALUES (0, 5); - QUERY PLAN ------------------------------ - Insert on public.parent_tbl - -> Result - Output: 0, 5 -(3 rows) - ---Testcase 448: -INSERT INTO rw_view VALUES (0, 5); -- should fail -ERROR: Not support partition insert ---Testcase 449: -EXPLAIN (VERBOSE, COSTS OFF) -INSERT INTO rw_view VALUES (0, 15); - QUERY PLAN ------------------------------ - Insert on public.parent_tbl - -> Result - Output: 0, 15 -(3 rows) - ---Testcase 450: -INSERT INTO rw_view VALUES (0, 15); -- ok -ERROR: Not support partition insert ---Testcase 451: -SELECT * FROM foreign_tbl; - fields --------- -(0 rows) - ---EXPLAIN (VERBOSE, COSTS OFF) ---UPDATE rw_view SET b = b + 5; ---UPDATE rw_view SET b = b + 5; -- should fail ---EXPLAIN (VERBOSE, COSTS OFF) ---UPDATE rw_view SET b = b + 15; ---UPDATE rw_view SET b = b + 15; -- ok ---SELECT * FROM foreign_tbl; ---Testcase 452: -DROP FOREIGN TABLE foreign_tbl CASCADE; ---Testcase 453: -DROP TRIGGER row_before_insupd_trigger ON child_tbl_nsc; ---Testcase 454: -DROP FOREIGN TABLE child_tbl CASCADE; -DROP FOREIGN TABLE child_tbl_nsc CASCADE; ---Testcase 455: -DROP TABLE parent_tbl CASCADE; -NOTICE: drop cascades to view rw_view ---Testcase 456: -DROP FUNCTION row_before_insupd_trigfunc; --- =================================================================== --- test serial columns (ie, sequence-based defaults) --- =================================================================== ---Testcase 457: -create foreign table loc1 (fields jsonb OPTIONS(fields 'true')) SERVER influxdb_svr OPTIONS (table 'loc1', schemaless 'true'); ---alter foreign table loc1 set (autovacuum_enabled = 'false'); -create foreign table loc1_nsc (f1 serial, f2 text) - server influxdb_svr options(table 'loc1'); ---Testcase 458: -create foreign table rem1 (fields jsonb OPTIONS(fields 'true')) SERVER influxdb_svr OPTIONS (table 'loc1', schemaless 'true'); -create foreign table rem1_nsc (f1 serial, f2 text) - server influxdb_svr options(table 'loc1'); ---Testcase 459: -select pg_catalog.setval('rem1_nsc_f1_seq', 10, false); - setval --------- - 10 -(1 row) - ---Testcase 460: -insert into loc1_nsc(f2) values('hi'); ---Testcase 461: -insert into rem1_nsc(f2) values('hi remote'); ---Testcase 462: -insert into loc1_nsc(f2) values('bye'); ---Testcase 463: -insert into rem1_nsc(f2) values('bye remote'); ---Testcase 464: -select * from loc1; - fields ----------------------------------- - {"f1": "1", "f2": "hi"} - {"f1": "10", "f2": "hi remote"} - {"f1": "2", "f2": "bye"} - {"f1": "11", "f2": "bye remote"} -(4 rows) - ---Testcase 465: -select * from rem1; - fields ----------------------------------- - {"f1": "1", "f2": "hi"} - {"f1": "10", "f2": "hi remote"} - {"f1": "2", "f2": "bye"} - {"f1": "11", "f2": "bye remote"} -(4 rows) - --- =================================================================== --- test generated columns --- =================================================================== ---Testcase 466: -create foreign table gloc1 (fields jsonb OPTIONS(fields 'true')) SERVER influxdb_svr OPTIONS (table 'gloc1', schemaless 'true'); ---alter foreign table gloc1 set (autovacuum_enabled = 'false'); -create foreign table gloc1_nsc (a int, b int generated always as (a * 2) stored) - server influxdb_svr options(table 'gloc1'); -ERROR: syntax error at or near "(" -LINE 1: ...table gloc1_nsc (a int, b int generated always as (a * 2) st... - ^ ---Testcase 467: -create foreign table grem1 (fields jsonb OPTIONS(fields 'true')) SERVER influxdb_svr OPTIONS (table 'gloc1', schemaless 'true'); -create foreign table grem1_nsc ( - a int, - b int generated always as (a * 2) stored) - server influxdb_svr options(table 'gloc1'); -ERROR: syntax error at or near "(" -LINE 3: b int generated always as (a * 2) stored) - ^ ---Testcase 468: -insert into grem1_nsc (a) values (1), (22); -ERROR: relation "grem1_nsc" does not exist -LINE 1: insert into grem1_nsc (a) values (1), (22); - ^ ---update grem1 set a = 22 where a = 2; ---Testcase 469: -select * from gloc1; - fields --------- -(0 rows) - ---Testcase 470: -select * from grem1; - fields --------- -(0 rows) - --- Clean up: -delete from grem1_nsc; -ERROR: relation "grem1_nsc" does not exist -LINE 1: delete from grem1_nsc; - ^ --- =================================================================== --- test local triggers --- =================================================================== --- Trigger functions "borrowed" from triggers regress test. ---Testcase 471: -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;$$; ---Testcase 472: -CREATE TRIGGER trig_stmt_before BEFORE DELETE OR INSERT OR UPDATE ON rem1_nsc - FOR EACH STATEMENT EXECUTE PROCEDURE trigger_func(); ---Testcase 473: -CREATE TRIGGER trig_stmt_after AFTER DELETE OR INSERT OR UPDATE ON rem1_nsc - FOR EACH STATEMENT EXECUTE PROCEDURE trigger_func(); ---Testcase 474: -CREATE OR REPLACE FUNCTION trigger_data() RETURNS trigger -LANGUAGE plpgsql AS $$ - -declare - oldnew text[]; - relid text; - argstr text; -begin - - relid := TG_relid::regclass; - argstr := ''; - 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 '%(%) % % % ON %', - tg_name, argstr, TG_when, TG_level, TG_OP, relid; - oldnew := '{}'::text[]; - if TG_OP != 'INSERT' then - oldnew := array_append(oldnew, format('OLD: %s', OLD)); - end if; - - if TG_OP != 'DELETE' then - oldnew := array_append(oldnew, format('NEW: %s', NEW)); - end if; - - RAISE NOTICE '%', array_to_string(oldnew, ','); - - if TG_OP = 'DELETE' then - return OLD; - else - return NEW; - end if; -end; -$$; --- Test basic functionality ---Testcase 475: -CREATE TRIGGER trig_row_before -BEFORE INSERT OR UPDATE OR DELETE ON rem1_nsc -FOR EACH ROW EXECUTE PROCEDURE trigger_data(23,'skidoo'); ---Testcase 476: -CREATE TRIGGER trig_row_after -AFTER INSERT OR UPDATE OR DELETE ON rem1_nsc -FOR EACH ROW EXECUTE PROCEDURE trigger_data(23,'skidoo'); ---Testcase 477: -delete from rem1_nsc; -NOTICE: trigger_func() called: action = DELETE, when = BEFORE, level = STATEMENT -NOTICE: trig_row_before(23, skidoo) BEFORE ROW DELETE ON rem1_nsc -NOTICE: OLD: (1,hi) -NOTICE: trig_row_before(23, skidoo) BEFORE ROW DELETE ON rem1_nsc -NOTICE: OLD: (10,"hi remote") -NOTICE: trig_row_before(23, skidoo) BEFORE ROW DELETE ON rem1_nsc -NOTICE: OLD: (2,bye) -NOTICE: trig_row_before(23, skidoo) BEFORE ROW DELETE ON rem1_nsc -NOTICE: OLD: (11,"bye remote") -NOTICE: trig_row_after(23, skidoo) AFTER ROW DELETE ON rem1_nsc -NOTICE: OLD: (1,hi) -NOTICE: trig_row_after(23, skidoo) AFTER ROW DELETE ON rem1_nsc -NOTICE: OLD: (10,"hi remote") -NOTICE: trig_row_after(23, skidoo) AFTER ROW DELETE ON rem1_nsc -NOTICE: OLD: (2,bye) -NOTICE: trig_row_after(23, skidoo) AFTER ROW DELETE ON rem1_nsc -NOTICE: OLD: (11,"bye remote") -NOTICE: trigger_func() called: action = DELETE, when = AFTER, level = STATEMENT ---Testcase 478: -insert into rem1_nsc values(1,'insert'); -NOTICE: trigger_func() called: action = INSERT, when = BEFORE, level = STATEMENT -NOTICE: trig_row_before(23, skidoo) BEFORE ROW INSERT ON rem1_nsc -NOTICE: NEW: (1,insert) -NOTICE: trig_row_after(23, skidoo) AFTER ROW INSERT ON rem1_nsc -NOTICE: NEW: (1,insert) -NOTICE: trigger_func() called: action = INSERT, when = AFTER, level = STATEMENT ---update rem1 set f2 = 'update' where f1 = 1; ---update rem1 set f2 = f2 || f2; --- cleanup ---Testcase 479: -DROP TRIGGER trig_row_before ON rem1_nsc; ---Testcase 480: -DROP TRIGGER trig_row_after ON rem1_nsc; ---Testcase 481: -DROP TRIGGER trig_stmt_before ON rem1_nsc; ---Testcase 482: -DROP TRIGGER trig_stmt_after ON rem1_nsc; ---Testcase 483: -DELETE from rem1_nsc; --- Test multiple AFTER ROW triggers on a foreign table ---Testcase 484: -CREATE TRIGGER trig_row_after1 -AFTER INSERT OR UPDATE OR DELETE ON rem1_nsc -FOR EACH ROW EXECUTE PROCEDURE trigger_data(23,'skidoo'); ---Testcase 485: -CREATE TRIGGER trig_row_after2 -AFTER INSERT OR UPDATE OR DELETE ON rem1_nsc -FOR EACH ROW EXECUTE PROCEDURE trigger_data(23,'skidoo'); ---Testcase 486: -insert into rem1_nsc values(1,'insert'); -NOTICE: trig_row_after1(23, skidoo) AFTER ROW INSERT ON rem1_nsc -NOTICE: NEW: (1,insert) -NOTICE: trig_row_after2(23, skidoo) AFTER ROW INSERT ON rem1_nsc -NOTICE: NEW: (1,insert) ---update rem1 set f2 = 'update' where f1 = 1; ---update rem1 set f2 = f2 || f2; ---Testcase 487: -delete from rem1_nsc; -NOTICE: trig_row_after1(23, skidoo) AFTER ROW DELETE ON rem1_nsc -NOTICE: OLD: (1,insert) -NOTICE: trig_row_after2(23, skidoo) AFTER ROW DELETE ON rem1_nsc -NOTICE: OLD: (1,insert) --- cleanup ---Testcase 488: -DROP TRIGGER trig_row_after1 ON rem1_nsc; ---Testcase 489: -DROP TRIGGER trig_row_after2 ON rem1_nsc; --- Test WHEN conditions ---Testcase 490: -CREATE TRIGGER trig_row_before_insupd -BEFORE INSERT OR UPDATE ON rem1_nsc -FOR EACH ROW -WHEN (NEW.f2 like '%update%') -EXECUTE PROCEDURE trigger_data(23,'skidoo'); ---Testcase 491: -CREATE TRIGGER trig_row_after_insupd -AFTER INSERT OR UPDATE ON rem1_nsc -FOR EACH ROW -WHEN (NEW.f2 like '%update%') -EXECUTE PROCEDURE trigger_data(23,'skidoo'); --- Insert or update not matching: nothing happens ---Testcase 492: -INSERT INTO rem1_nsc values(1, 'insert'); ---UPDATE rem1 set f2 = 'test'; --- Insert or update matching: triggers are fired ---Testcase 493: -INSERT INTO rem1_nsc values(2, 'update'); -NOTICE: trig_row_before_insupd(23, skidoo) BEFORE ROW INSERT ON rem1_nsc -NOTICE: NEW: (2,update) -NOTICE: trig_row_after_insupd(23, skidoo) AFTER ROW INSERT ON rem1_nsc -NOTICE: NEW: (2,update) ---UPDATE rem1 set f2 = 'update update' where f1 = '2'; ---Testcase 494: -CREATE TRIGGER trig_row_before_delete -BEFORE DELETE ON rem1_nsc -FOR EACH ROW -WHEN (OLD.f2 like '%update%') -EXECUTE PROCEDURE trigger_data(23,'skidoo'); ---Testcase 495: -CREATE TRIGGER trig_row_after_delete -AFTER DELETE ON rem1_nsc -FOR EACH ROW -WHEN (OLD.f2 like '%update%') -EXECUTE PROCEDURE trigger_data(23,'skidoo'); --- Trigger is fired for f1=2, not for f1=1 ---Testcase 496: -DELETE FROM rem1_nsc; -NOTICE: trig_row_before_delete(23, skidoo) BEFORE ROW DELETE ON rem1_nsc -NOTICE: OLD: (2,update) -NOTICE: trig_row_after_delete(23, skidoo) AFTER ROW DELETE ON rem1_nsc -NOTICE: OLD: (2,update) --- cleanup ---Testcase 497: -DROP TRIGGER trig_row_before_insupd ON rem1_nsc; ---Testcase 498: -DROP TRIGGER trig_row_after_insupd ON rem1_nsc; ---Testcase 499: -DROP TRIGGER trig_row_before_delete ON rem1_nsc; ---Testcase 500: -DROP TRIGGER trig_row_after_delete ON rem1_nsc; --- Test various RETURN statements in BEFORE triggers. ---Testcase 501: -CREATE FUNCTION trig_row_before_insupdate() RETURNS TRIGGER AS $$ - BEGIN - NEW.f2 := NEW.f2 || ' triggered !'; - RETURN NEW; - END -$$ language plpgsql; ---Testcase 502: -CREATE TRIGGER trig_row_before_insupd -BEFORE INSERT OR UPDATE ON rem1_nsc -FOR EACH ROW EXECUTE PROCEDURE trig_row_before_insupdate(); --- The new values should have 'triggered' appended ---Testcase 503: -INSERT INTO rem1_nsc values(1, 'insert'); ---Testcase 504: -SELECT * from loc1; - fields ------------------------------------------ - {"f1": "1", "f2": "insert triggered !"} -(1 row) - ---Testcase 505: -INSERT INTO rem1_nsc values(2, 'insert'); ---Testcase 506: -SELECT fields->>'f2' f2 FROM rem1 WHERE (fields->>'f1')::int = 2; - f2 --------------------- - insert triggered ! -(1 row) - ---Testcase 507: -SELECT * from loc1; - fields ------------------------------------------ - {"f1": "1", "f2": "insert triggered !"} - {"f1": "2", "f2": "insert triggered !"} -(2 rows) - ---UPDATE rem1 set f2 = ''; ---SELECT * from loc1; ---UPDATE rem1 set f2 = 'skidoo' RETURNING f2; ---SELECT * from loc1; ---EXPLAIN (verbose, costs off) ---UPDATE rem1 set f1 = 10; -- all columns should be transmitted ---UPDATE rem1 set f1 = 10; ---SELECT * from loc1; ---Testcase 508: -DELETE FROM rem1_nsc; --- Add a second trigger, to check that the changes are propagated correctly --- from trigger to trigger ---Testcase 509: -CREATE TRIGGER trig_row_before_insupd2 -BEFORE INSERT OR UPDATE ON rem1_nsc -FOR EACH ROW EXECUTE PROCEDURE trig_row_before_insupdate(); ---Testcase 510: -INSERT INTO rem1_nsc values(1, 'insert'); ---Testcase 511: -SELECT * from loc1; - fields ------------------------------------------------------ - {"f1": "1", "f2": "insert triggered ! triggered !"} -(1 row) - ---Testcase 512: -INSERT INTO rem1_nsc values(2, 'insert'); ---Testcase 513: -SELECT fields->>'f2' f2 FROM rem1 WHERE (fields->>'f1')::int = 2; - f2 --------------------------------- - insert triggered ! triggered ! -(1 row) - ---Testcase 514: -SELECT * from loc1; - fields ------------------------------------------------------ - {"f1": "1", "f2": "insert triggered ! triggered !"} - {"f1": "2", "f2": "insert triggered ! triggered !"} -(2 rows) - ---UPDATE rem1 set f2 = ''; ---SELECT * from loc1; ---UPDATE rem1 set f2 = 'skidoo' RETURNING f2; ---SELECT * from loc1; ---Testcase 515: -DROP TRIGGER trig_row_before_insupd ON rem1_nsc; ---Testcase 516: -DROP TRIGGER trig_row_before_insupd2 ON rem1_nsc; ---Testcase 517: -DELETE from rem1_nsc; ---Testcase 518: -INSERT INTO rem1_nsc VALUES (1, 'test'); --- Test with a trigger returning NULL ---Testcase 519: -CREATE FUNCTION trig_null() RETURNS TRIGGER AS $$ - BEGIN - RETURN NULL; - END -$$ language plpgsql; ---Testcase 520: -CREATE TRIGGER trig_null -BEFORE INSERT OR UPDATE OR DELETE ON rem1_nsc -FOR EACH ROW EXECUTE PROCEDURE trig_null(); --- Nothing should have changed. ---Testcase 521: -INSERT INTO rem1_nsc VALUES (2, 'test2'); ---Testcase 522: -SELECT * from loc1; - fields ---------------------------- - {"f1": "1", "f2": "test"} -(1 row) - ---UPDATE rem1 SET f2 = 'test2'; ---SELECT * from loc1; ---Testcase 523: -DELETE from rem1_nsc; ---Testcase 524: -SELECT * from loc1; - fields ---------------------------- - {"f1": "1", "f2": "test"} -(1 row) - ---Testcase 525: -DROP TRIGGER trig_null ON rem1_nsc; ---Testcase 526: -DELETE from rem1_nsc; --- Test a combination of local and remote triggers ---Testcase 527: -CREATE TRIGGER trig_row_before -BEFORE INSERT OR UPDATE OR DELETE ON rem1_nsc -FOR EACH ROW EXECUTE PROCEDURE trigger_data(23,'skidoo'); ---Testcase 528: -CREATE TRIGGER trig_row_after -AFTER INSERT OR UPDATE OR DELETE ON rem1_nsc -FOR EACH ROW EXECUTE PROCEDURE trigger_data(23,'skidoo'); ---Testcase 529: -CREATE TRIGGER trig_local_before BEFORE INSERT OR UPDATE ON loc1_nsc -FOR EACH ROW EXECUTE PROCEDURE trig_row_before_insupdate(); ---Testcase 530: -INSERT INTO rem1_nsc(f2) VALUES ('test'); -NOTICE: trig_row_before(23, skidoo) BEFORE ROW INSERT ON rem1_nsc -NOTICE: NEW: (12,test) -NOTICE: trig_row_after(23, skidoo) AFTER ROW INSERT ON rem1_nsc -NOTICE: NEW: (12,test) ---UPDATE rem1 SET f2 = 'testo'; --- Test returning a system attribute ---Testcase 531: -INSERT INTO rem1_nsc(f2) VALUES ('test'); -NOTICE: trig_row_before(23, skidoo) BEFORE ROW INSERT ON rem1_nsc -NOTICE: NEW: (13,test) -NOTICE: trig_row_after(23, skidoo) AFTER ROW INSERT ON rem1_nsc -NOTICE: NEW: (13,test) ---Testcase 532: -SELECT * FROM rem1 WHERE fields->>'f2' = 'test'; - fields ----------------------------- - {"f1": "12", "f2": "test"} - {"f1": "13", "f2": "test"} -(2 rows) - --- cleanup ---Testcase 533: -DROP TRIGGER trig_row_before ON rem1_nsc; ---Testcase 534: -DROP TRIGGER trig_row_after ON rem1_nsc; ---Testcase 535: -DROP TRIGGER trig_local_before ON loc1_nsc; --- Test direct foreign table modification functionality --- Test with statement-level triggers ---Testcase 536: -CREATE TRIGGER trig_stmt_before - BEFORE DELETE OR INSERT OR UPDATE ON rem1_nsc - FOR EACH STATEMENT EXECUTE PROCEDURE trigger_func(); ---EXPLAIN (verbose, costs off) ---UPDATE rem1 set f2 = ''; -- can be pushed down ---Testcase 537: -EXPLAIN (verbose, costs off) -DELETE FROM rem1_nsc; -- can be pushed down - QUERY PLAN --------------------------------------------- - Delete on public.rem1_nsc - -> Foreign Delete on public.rem1_nsc - InfluxDB query: DELETE FROM "loc1" -(3 rows) - ---Testcase 538: -DROP TRIGGER trig_stmt_before ON rem1_nsc; ---Testcase 539: -CREATE TRIGGER trig_stmt_after - AFTER DELETE OR INSERT OR UPDATE ON rem1_nsc - FOR EACH STATEMENT EXECUTE PROCEDURE trigger_func(); ---EXPLAIN (verbose, costs off) ---UPDATE rem1 set f2 = ''; -- can be pushed down ---Testcase 540: -EXPLAIN (verbose, costs off) -DELETE FROM rem1_nsc; -- can be pushed down - QUERY PLAN --------------------------------------------- - Delete on public.rem1_nsc - -> Foreign Delete on public.rem1_nsc - InfluxDB query: DELETE FROM "loc1" -(3 rows) - ---Testcase 541: -DROP TRIGGER trig_stmt_after ON rem1_nsc; --- Test with row-level ON INSERT triggers ---Testcase 542: -CREATE TRIGGER trig_row_before_insert -BEFORE INSERT ON rem1_nsc -FOR EACH ROW EXECUTE PROCEDURE trigger_data(23,'skidoo'); ---EXPLAIN (verbose, costs off) ---UPDATE rem1 set f2 = ''; -- can be pushed down ---Testcase 543: -EXPLAIN (verbose, costs off) -DELETE FROM rem1_nsc; -- can be pushed down - QUERY PLAN --------------------------------------------- - Delete on public.rem1_nsc - -> Foreign Delete on public.rem1_nsc - InfluxDB query: DELETE FROM "loc1" -(3 rows) - ---Testcase 544: -DROP TRIGGER trig_row_before_insert ON rem1_nsc; ---Testcase 545: -CREATE TRIGGER trig_row_after_insert -AFTER INSERT ON rem1_nsc -FOR EACH ROW EXECUTE PROCEDURE trigger_data(23,'skidoo'); ---EXPLAIN (verbose, costs off) ---UPDATE rem1 set f2 = ''; -- can be pushed down ---Testcase 546: -EXPLAIN (verbose, costs off) -DELETE FROM rem1_nsc; -- can be pushed down - QUERY PLAN --------------------------------------------- - Delete on public.rem1_nsc - -> Foreign Delete on public.rem1_nsc - InfluxDB query: DELETE FROM "loc1" -(3 rows) - ---Testcase 547: -DROP TRIGGER trig_row_after_insert ON rem1_nsc; --- Test with row-level ON UPDATE triggers ---Testcase 548: -CREATE TRIGGER trig_row_before_update -BEFORE UPDATE ON rem1_nsc -FOR EACH ROW EXECUTE PROCEDURE trigger_data(23,'skidoo'); ---EXPLAIN (verbose, costs off) ---UPDATE rem1 set f2 = ''; -- can't be pushed down ---Testcase 549: -EXPLAIN (verbose, costs off) -DELETE FROM rem1_nsc; -- can be pushed down - QUERY PLAN --------------------------------------------- - Delete on public.rem1_nsc - -> Foreign Delete on public.rem1_nsc - InfluxDB query: DELETE FROM "loc1" -(3 rows) - ---Testcase 550: -DROP TRIGGER trig_row_before_update ON rem1_nsc; ---Testcase 551: -CREATE TRIGGER trig_row_after_update -AFTER UPDATE ON rem1_nsc -FOR EACH ROW EXECUTE PROCEDURE trigger_data(23,'skidoo'); ---EXPLAIN (verbose, costs off) ---UPDATE rem1 set f2 = ''; -- can't be pushed down ---Testcase 552: -EXPLAIN (verbose, costs off) -DELETE FROM rem1_nsc; -- can be pushed down - QUERY PLAN --------------------------------------------- - Delete on public.rem1_nsc - -> Foreign Delete on public.rem1_nsc - InfluxDB query: DELETE FROM "loc1" -(3 rows) - ---Testcase 553: -DROP TRIGGER trig_row_after_update ON rem1_nsc; --- Test with row-level ON DELETE triggers ---Testcase 554: -CREATE TRIGGER trig_row_before_delete -BEFORE DELETE ON rem1_nsc -FOR EACH ROW EXECUTE PROCEDURE trigger_data(23,'skidoo'); ---EXPLAIN (verbose, costs off) ---UPDATE rem1 set f2 = ''; -- can be pushed down ---Testcase 555: -EXPLAIN (verbose, costs off) -DELETE FROM rem1_nsc; -- can't be pushed down - QUERY PLAN -------------------------------------------------------- - Delete on public.rem1_nsc - -> Foreign Scan on public.rem1_nsc - Output: rem1_nsc.* - InfluxDB query: SELECT "f1", "f2" FROM "loc1" -(4 rows) - ---Testcase 556: -DROP TRIGGER trig_row_before_delete ON rem1_nsc; ---Testcase 557: -CREATE TRIGGER trig_row_after_delete -AFTER DELETE ON rem1_nsc -FOR EACH ROW EXECUTE PROCEDURE trigger_data(23,'skidoo'); ---EXPLAIN (verbose, costs off) ---UPDATE rem1 set f2 = ''; -- can be pushed down ---Testcase 558: -EXPLAIN (verbose, costs off) -DELETE FROM rem1_nsc; -- can't be pushed down - QUERY PLAN -------------------------------------------------------- - Delete on public.rem1_nsc - -> Foreign Scan on public.rem1_nsc - Output: rem1_nsc.* - InfluxDB query: SELECT "f1", "f2" FROM "loc1" -(4 rows) - ---Testcase 559: -DROP TRIGGER trig_row_after_delete ON rem1_nsc; --- =================================================================== --- test inheritance features --- =================================================================== ---Testcase 560: -CREATE TABLE a (aa TEXT); ---CREATE TABLE loct (aa TEXT, bb TEXT); -ALTER TABLE a SET (autovacuum_enabled = 'false'); ---ALTER TABLE loct SET (autovacuum_enabled = 'false'); --- Because influxdb_fdw does not support UPDATE, to test locally --- we create local table. ---Testcase 561: -CREATE TABLE b (bb TEXT) INHERITS (a); ---Testcase 562: -INSERT INTO a(aa) VALUES('aaa'); ---Testcase 563: -INSERT INTO a(aa) VALUES('aaaa'); ---Testcase 564: -INSERT INTO a(aa) VALUES('aaaaa'); ---Testcase 565: -INSERT INTO b(aa) VALUES('bbb'); ---Testcase 566: -INSERT INTO b(aa) VALUES('bbbb'); ---Testcase 567: -INSERT INTO b(aa) VALUES('bbbbb'); ---Testcase 568: -SELECT tableoid::regclass, * FROM a; - tableoid | aa -----------+------- - a | aaa - a | aaaa - a | aaaaa - b | bbb - b | bbbb - b | bbbbb -(6 rows) - ---Testcase 569: -SELECT tableoid::regclass, * FROM b; - tableoid | aa | bb -----------+-------+---- - b | bbb | - b | bbbb | - b | bbbbb | -(3 rows) - ---Testcase 570: -SELECT tableoid::regclass, * FROM ONLY a; - tableoid | aa -----------+------- - a | aaa - a | aaaa - a | aaaaa -(3 rows) - ---Testcase 571: -UPDATE a SET aa = 'zzzzzz' WHERE aa LIKE 'aaaa%'; ---Testcase 572: -SELECT tableoid::regclass, * FROM a; - tableoid | aa -----------+-------- - a | aaa - a | zzzzzz - a | zzzzzz - b | bbb - b | bbbb - b | bbbbb -(6 rows) - ---Testcase 573: -SELECT tableoid::regclass, * FROM b; - tableoid | aa | bb -----------+-------+---- - b | bbb | - b | bbbb | - b | bbbbb | -(3 rows) - ---Testcase 574: -SELECT tableoid::regclass, * FROM ONLY a; - tableoid | aa -----------+-------- - a | aaa - a | zzzzzz - a | zzzzzz -(3 rows) - ---Testcase 575: -UPDATE b SET aa = 'new'; ---Testcase 576: -SELECT tableoid::regclass, * FROM a; - tableoid | aa -----------+-------- - a | aaa - a | zzzzzz - a | zzzzzz - b | new - b | new - b | new -(6 rows) - ---Testcase 577: -SELECT tableoid::regclass, * FROM b; - tableoid | aa | bb -----------+-----+---- - b | new | - b | new | - b | new | -(3 rows) - ---Testcase 578: -SELECT tableoid::regclass, * FROM ONLY a; - tableoid | aa -----------+-------- - a | aaa - a | zzzzzz - a | zzzzzz -(3 rows) - ---Testcase 579: -UPDATE a SET aa = 'newtoo'; ---Testcase 580: -SELECT tableoid::regclass, * FROM a; - tableoid | aa -----------+-------- - a | newtoo - a | newtoo - a | newtoo - b | newtoo - b | newtoo - b | newtoo -(6 rows) - ---Testcase 581: -SELECT tableoid::regclass, * FROM b; - tableoid | aa | bb -----------+--------+---- - b | newtoo | - b | newtoo | - b | newtoo | -(3 rows) - ---Testcase 582: -SELECT tableoid::regclass, * FROM ONLY a; - tableoid | aa -----------+-------- - a | newtoo - a | newtoo - a | newtoo -(3 rows) - ---Testcase 583: -DELETE FROM a; ---Testcase 584: -SELECT tableoid::regclass, * FROM a; - tableoid | aa -----------+---- -(0 rows) - ---Testcase 585: -SELECT tableoid::regclass, * FROM b; - tableoid | aa | bb -----------+----+---- -(0 rows) - ---Testcase 586: -SELECT tableoid::regclass, * FROM ONLY a; - tableoid | aa -----------+---- -(0 rows) - ---Testcase 587: -DROP TABLE a CASCADE; -NOTICE: drop cascades to table b ---DROP TABLE loct; --- Check SELECT FOR UPDATE/SHARE with an inherited source table ---Testcase 588: -create foreign table loct1 (fields jsonb OPTIONS(fields 'true')) SERVER influxdb_svr OPTIONS (table 'loct1', schemaless 'true'); -create foreign table loct1_nsc (f1 int, f2 int, f3 int) server influxdb_svr options(table 'loct1'); ---Testcase 589: -create foreign table loct2 (fields jsonb OPTIONS(fields 'true')) SERVER influxdb_svr OPTIONS (table 'loct2', schemaless 'true'); -create foreign table loct2_nsc (f1 int, f2 int, f3 int) server influxdb_svr options(table 'loct2'); ---alter table loct1 set (autovacuum_enabled = 'false'); ---alter table loct2 set (autovacuum_enabled = 'false'); ---Testcase 590: -create foreign table foo (fields jsonb OPTIONS(fields 'true')) SERVER influxdb_svr OPTIONS (table 'foo', schemaless 'true'); -create foreign table foo_nsc (f1 int, f2 int) - server influxdb_svr options (table 'foo'); ---Testcase 591: -create foreign table foo2 (fields jsonb OPTIONS(fields 'true')) inherits (foo) - server influxdb_svr options (table 'loct1', schemaless 'true'); -NOTICE: merging column "fields" with inherited definition -create foreign table foo2_nsc (f3 int) inherits (foo_nsc) - server influxdb_svr options (table 'loct1'); ---Testcase 592: -create foreign table bar (fields jsonb OPTIONS(fields 'true')) - server influxdb_svr options (table 'bar', schemaless 'true'); -create foreign table bar_nsc (f1 int, f2 int) - server influxdb_svr options (table 'bar'); ---Testcase 593: -create foreign table bar2 (fields jsonb OPTIONS(fields 'true')) inherits (bar) - server influxdb_svr options (table 'loct2', schemaless 'true'); -NOTICE: merging column "fields" with inherited definition -create foreign table bar2_nsc (f3 int) inherits (bar_nsc) - server influxdb_svr options (table 'loct2'); ---alter table foo set (autovacuum_enabled = 'false'); ---alter table bar set (autovacuum_enabled = 'false'); ---Testcase 594: -insert into foo_nsc values(1,1); ---Testcase 595: -insert into foo_nsc values(3,3); ---Testcase 596: -insert into foo2_nsc values(2,2,2); ---Testcase 597: -insert into foo2_nsc values(4,4,4); ---Testcase 598: -insert into bar_nsc values(1,11); ---Testcase 599: -insert into bar_nsc values(2,22); ---Testcase 600: -insert into bar_nsc values(6,66); ---Testcase 601: -insert into bar2_nsc values(3,33,33); ---Testcase 602: -insert into bar2_nsc values(4,44,44); ---Testcase 603: -insert into bar2_nsc values(7,77,77); ---Testcase 604: -explain (verbose, costs off) -select * from bar where fields->>'f1' in (select fields->>'f1' from foo); - QUERY PLAN --------------------------------------------------------------------------- - Hash Join - Output: bar.fields - Inner Unique: true - Hash Cond: ((bar.fields ->> 'f1'::text) = (foo.fields ->> 'f1'::text)) - -> Append - -> Foreign Scan on public.bar - Output: bar.fields - InfluxDB query: SELECT * FROM "bar" - -> Foreign Scan on public.bar2 - Output: bar2.fields - InfluxDB query: SELECT * FROM "loct2" - -> Hash - Output: foo.fields - -> HashAggregate - Output: foo.fields - Group Key: (foo.fields ->> 'f1'::text) - -> Result - Output: foo.fields, (foo.fields ->> 'f1'::text) - -> Append - -> Foreign Scan on public.foo - Output: foo.fields - InfluxDB query: SELECT * FROM "foo" - -> Foreign Scan on public.foo2 - Output: foo2.fields - InfluxDB query: SELECT * FROM "loct1" -(25 rows) - ---Testcase 605: -select * from bar where fields->>'f1' in (select fields->>'f1' from foo); - fields -------------------------------------- - {"f1": "1", "f2": "11"} - {"f1": "2", "f2": "22"} - {"f1": "3", "f2": "33", "f3": "33"} - {"f1": "4", "f2": "44", "f3": "44"} -(4 rows) - ---Testcase 606: -explain (verbose, costs off) -select * from bar where fields->>'f1' in (select fields->>'f1' from foo); - QUERY PLAN --------------------------------------------------------------------------- - Hash Join - Output: bar.fields - Inner Unique: true - Hash Cond: ((bar.fields ->> 'f1'::text) = (foo.fields ->> 'f1'::text)) - -> Append - -> Foreign Scan on public.bar - Output: bar.fields - InfluxDB query: SELECT * FROM "bar" - -> Foreign Scan on public.bar2 - Output: bar2.fields - InfluxDB query: SELECT * FROM "loct2" - -> Hash - Output: foo.fields - -> HashAggregate - Output: foo.fields - Group Key: (foo.fields ->> 'f1'::text) - -> Result - Output: foo.fields, (foo.fields ->> 'f1'::text) - -> Append - -> Foreign Scan on public.foo - Output: foo.fields - InfluxDB query: SELECT * FROM "foo" - -> Foreign Scan on public.foo2 - Output: foo2.fields - InfluxDB query: SELECT * FROM "loct1" -(25 rows) - ---Testcase 607: -select * from bar where fields->>'f1' in (select fields->>'f1' from foo); - fields -------------------------------------- - {"f1": "1", "f2": "11"} - {"f1": "2", "f2": "22"} - {"f1": "3", "f2": "33", "f3": "33"} - {"f1": "4", "f2": "44", "f3": "44"} -(4 rows) - -/* --- influxdb_fdw does not support UPDATE --- Check UPDATE with inherited target and an inherited source table -explain (verbose, costs off) -update bar set f2 = f2 + 100 where f1 in (select f1 from foo); -update bar set f2 = f2 + 100 where f1 in (select f1 from foo); - -select tableoid::regclass, * from bar order by 1,2; - --- Check UPDATE with inherited target and an appendrel subquery -explain (verbose, costs off) -update bar set f2 = f2 + 100 -from - ( select f1 from foo union all select f1+3 from foo ) ss -where bar.f1 = ss.f1; -update bar set f2 = f2 + 100 -from - ( select f1 from foo union all select f1+3 from foo ) ss -where bar.f1 = ss.f1; - -select tableoid::regclass, * from bar order by 1,2; - --- Test forcing the remote server to produce sorted data for a merge join, --- but the foreign table is an inheritance child. -truncate table loct1; -truncate table only foo; -\set num_rows_foo 2000 -insert into loct1 select generate_series(0, :num_rows_foo, 2), generate_series(0, :num_rows_foo, 2), generate_series(0, :num_rows_foo, 2); -insert into foo select generate_series(1, :num_rows_foo, 2), generate_series(1, :num_rows_foo, 2); -SET enable_hashjoin to false; -SET enable_nestloop to false; -alter foreign table foo2 options (use_remote_estimate 'true'); -create index i_loct1_f1 on loct1(f1); -create index i_foo_f1 on foo(f1); -analyze foo; -analyze loct1; --- inner join; expressions in the clauses appear in the equivalence class list -explain (verbose, costs off) - select foo.f1, loct1.f1 from foo join loct1 on (foo.f1 = loct1.f1) order by foo.f2 offset 10 limit 10; -select foo.f1, loct1.f1 from foo join loct1 on (foo.f1 = loct1.f1) order by foo.f2 offset 10 limit 10; --- outer join; expressions in the clauses do not appear in equivalence class --- list but no output change as compared to the previous query -explain (verbose, costs off) - select foo.f1, loct1.f1 from foo left join loct1 on (foo.f1 = loct1.f1) order by foo.f2 offset 10 limit 10; -select foo.f1, loct1.f1 from foo left join loct1 on (foo.f1 = loct1.f1) order by foo.f2 offset 10 limit 10; -RESET enable_hashjoin; -RESET enable_nestloop; - --- Test that WHERE CURRENT OF is not supported -begin; -declare c cursor for select * from bar where f1 = 7; -fetch from c; -update bar set f2 = null where current of c; -rollback; - -explain (verbose, costs off) -delete from foo where f1 < 5 returning *; -delete from foo where f1 < 5 returning *; -explain (verbose, costs off) -update bar set f2 = f2 + 100 returning *; -update bar set f2 = f2 + 100 returning *; - --- Test that UPDATE/DELETE with inherited target works with row-level triggers -CREATE TRIGGER trig_row_before -BEFORE UPDATE OR DELETE ON bar2 -FOR EACH ROW EXECUTE PROCEDURE trigger_data(23,'skidoo'); - -CREATE TRIGGER trig_row_after -AFTER UPDATE OR DELETE ON bar2 -FOR EACH ROW EXECUTE PROCEDURE trigger_data(23,'skidoo'); - -explain (verbose, costs off) -update bar set f2 = f2 + 100; -update bar set f2 = f2 + 100; - -explain (verbose, costs off) -delete from bar where f2 < 400; -delete from bar where f2 < 400; - --- cleanup -drop table foo cascade; -drop table bar cascade; -drop table loct1; -drop table loct2; - --- Test pushing down UPDATE/DELETE joins to the remote server -create table parent (a int, b text); -create table loct1 (a int, b text); -create table loct2 (a int, b text); -create foreign table remt1 (a int, b text) - server influxdb_svr options (table 'loct1'); -create foreign table remt2 (a int, b text) - server influxdb_svr options (table 'loct2'); -alter foreign table remt1 inherit parent; - -insert into remt1 values (1, 'foo'); -insert into remt1 values (2, 'bar'); -insert into remt2 values (1, 'foo'); -insert into remt2 values (2, 'bar'); - -analyze remt1; -analyze remt2; - -explain (verbose, costs off) -update parent set b = parent.b || remt2.b from remt2 where parent.a = remt2.a returning *; -update parent set b = parent.b || remt2.b from remt2 where parent.a = remt2.a returning *; -explain (verbose, costs off) -delete from parent using remt2 where parent.a = remt2.a returning parent; -delete from parent using remt2 where parent.a = remt2.a returning parent; - --- cleanup -drop foreign table remt1; -drop foreign table remt2; -drop table loct1; -drop table loct2; -drop table parent; -*/ -/* --- Skip test because influxdb does not support partitions table, COPY --- =================================================================== --- test tuple routing for foreign-table partitions --- =================================================================== - --- Test insert tuple routing -create table itrtest (a int, b text) partition by list (a); -create table loct1 (a int check (a in (1)), b text); -create foreign table remp1 (a int check (a in (1)), b text) server loopback options (table_name 'loct1'); -create table loct2 (a int check (a in (2)), b text); -create foreign table remp2 (b text, a int check (a in (2))) server loopback options (table_name 'loct2'); -alter table itrtest attach partition remp1 for values in (1); -alter table itrtest attach partition remp2 for values in (2); - -insert into itrtest values (1, 'foo'); -insert into itrtest values (1, 'bar') returning *; -insert into itrtest values (2, 'baz'); -insert into itrtest values (2, 'qux') returning *; -insert into itrtest values (1, 'test1'), (2, 'test2') returning *; - -select tableoid::regclass, * FROM itrtest; -select tableoid::regclass, * FROM remp1; -select tableoid::regclass, * FROM remp2; - -delete from itrtest; - -create unique index loct1_idx on loct1 (a); - --- DO NOTHING without an inference specification is supported -insert into itrtest values (1, 'foo') on conflict do nothing returning *; -insert into itrtest values (1, 'foo') on conflict do nothing returning *; - --- But other cases are not supported -insert into itrtest values (1, 'bar') on conflict (a) do nothing; -insert into itrtest values (1, 'bar') on conflict (a) do update set b = excluded.b; - -select tableoid::regclass, * FROM itrtest; - -delete from itrtest; - -drop index loct1_idx; - --- Test that remote triggers work with insert tuple routing -create function br_insert_trigfunc() returns trigger as $$ -begin - new.b := new.b || ' triggered !'; - return new; -end -$$ language plpgsql; -create trigger loct1_br_insert_trigger before insert on loct1 - for each row execute procedure br_insert_trigfunc(); -create trigger loct2_br_insert_trigger before insert on loct2 - for each row execute procedure br_insert_trigfunc(); - --- The new values are concatenated with ' triggered !' -insert into itrtest values (1, 'foo') returning *; -insert into itrtest values (2, 'qux') returning *; -insert into itrtest values (1, 'test1'), (2, 'test2') returning *; -with result as (insert into itrtest values (1, 'test1'), (2, 'test2') returning *) select * from result; - -drop trigger loct1_br_insert_trigger on loct1; -drop trigger loct2_br_insert_trigger on loct2; - -drop table itrtest; -drop table loct1; -drop table loct2; - --- Test update tuple routing -create table utrtest (a int, b text) partition by list (a); -create table loct (a int check (a in (1)), b text); -create foreign table remp (a int check (a in (1)), b text) server loopback options (table_name 'loct'); -create table locp (a int check (a in (2)), b text); -alter table utrtest attach partition remp for values in (1); -alter table utrtest attach partition locp for values in (2); - -insert into utrtest values (1, 'foo'); -insert into utrtest values (2, 'qux'); - -select tableoid::regclass, * FROM utrtest; -select tableoid::regclass, * FROM remp; -select tableoid::regclass, * FROM locp; - --- It's not allowed to move a row from a partition that is foreign to another -update utrtest set a = 2 where b = 'foo' returning *; - --- But the reverse is allowed -update utrtest set a = 1 where b = 'qux' returning *; - -select tableoid::regclass, * FROM utrtest; -select tableoid::regclass, * FROM remp; -select tableoid::regclass, * FROM locp; - --- The executor should not let unexercised FDWs shut down -update utrtest set a = 1 where b = 'foo'; - --- Test that remote triggers work with update tuple routing -create trigger loct_br_insert_trigger before insert on loct - for each row execute procedure br_insert_trigfunc(); - -delete from utrtest; -insert into utrtest values (2, 'qux'); - --- Check case where the foreign partition is a subplan target rel -explain (verbose, costs off) -update utrtest set a = 1 where a = 1 or a = 2 returning *; --- The new values are concatenated with ' triggered !' -update utrtest set a = 1 where a = 1 or a = 2 returning *; - -delete from utrtest; -insert into utrtest values (2, 'qux'); - --- Check case where the foreign partition isn't a subplan target rel -explain (verbose, costs off) -update utrtest set a = 1 where a = 2 returning *; --- The new values are concatenated with ' triggered !' -update utrtest set a = 1 where a = 2 returning *; - -drop trigger loct_br_insert_trigger on loct; - --- We can move rows to a foreign partition that has been updated already, --- but can't move rows to a foreign partition that hasn't been updated yet - -delete from utrtest; -insert into utrtest values (1, 'foo'); -insert into utrtest values (2, 'qux'); - --- Test the former case: --- with a direct modification plan -explain (verbose, costs off) -update utrtest set a = 1 returning *; -update utrtest set a = 1 returning *; - -delete from utrtest; -insert into utrtest values (1, 'foo'); -insert into utrtest values (2, 'qux'); - --- with a non-direct modification plan -explain (verbose, costs off) -update utrtest set a = 1 from (values (1), (2)) s(x) where a = s.x returning *; -update utrtest set a = 1 from (values (1), (2)) s(x) where a = s.x returning *; - --- Change the definition of utrtest so that the foreign partition get updated --- after the local partition -delete from utrtest; -alter table utrtest detach partition remp; -drop foreign table remp; -alter table loct drop constraint loct_a_check; -alter table loct add check (a in (3)); -create foreign table remp (a int check (a in (3)), b text) server loopback options (table_name 'loct'); -alter table utrtest attach partition remp for values in (3); -insert into utrtest values (2, 'qux'); -insert into utrtest values (3, 'xyzzy'); - --- Test the latter case: --- with a direct modification plan -explain (verbose, costs off) -update utrtest set a = 3 returning *; -update utrtest set a = 3 returning *; -- ERROR - --- with a non-direct modification plan -explain (verbose, costs off) -update utrtest set a = 3 from (values (2), (3)) s(x) where a = s.x returning *; -update utrtest set a = 3 from (values (2), (3)) s(x) where a = s.x returning *; -- ERROR - -drop table utrtest; -drop table loct; - --- Test copy tuple routing -create table ctrtest (a int, b text) partition by list (a); -create table loct1 (a int check (a in (1)), b text); -create foreign table remp1 (a int check (a in (1)), b text) server loopback options (table_name 'loct1'); -create table loct2 (a int check (a in (2)), b text); -create foreign table remp2 (b text, a int check (a in (2))) server loopback options (table_name 'loct2'); -alter table ctrtest attach partition remp1 for values in (1); -alter table ctrtest attach partition remp2 for values in (2); - -copy ctrtest from stdin; -1 foo -2 qux -\. - -select tableoid::regclass, * FROM ctrtest; -select tableoid::regclass, * FROM remp1; -select tableoid::regclass, * FROM remp2; - --- Copying into foreign partitions directly should work as well -copy remp1 from stdin; -1 bar -\. - -select tableoid::regclass, * FROM remp1; - -drop table ctrtest; -drop table loct1; -drop table loct2; - --- =================================================================== --- test COPY FROM --- =================================================================== - -create table loc2 (f1 int, f2 text); -alter table loc2 set (autovacuum_enabled = 'false'); -create foreign table rem2 (f1 int, f2 text) server loopback options(table_name 'loc2'); - --- Test basic functionality -copy rem2 from stdin; -1 foo -2 bar -\. -select * from rem2; - -delete from rem2; - --- Test check constraints -alter table loc2 add constraint loc2_f1positive check (f1 >= 0); -alter foreign table rem2 add constraint rem2_f1positive check (f1 >= 0); - --- check constraint is enforced on the remote side, not locally -copy rem2 from stdin; -1 foo -2 bar -\. -copy rem2 from stdin; -- ERROR --1 xyzzy -\. -select * from rem2; - -alter foreign table rem2 drop constraint rem2_f1positive; -alter table loc2 drop constraint loc2_f1positive; - -delete from rem2; - --- Test local triggers -create trigger trig_stmt_before before insert on rem2 - for each statement execute procedure trigger_func(); -create trigger trig_stmt_after after insert on rem2 - for each statement execute procedure trigger_func(); -create trigger trig_row_before before insert on rem2 - for each row execute procedure trigger_data(23,'skidoo'); -create trigger trig_row_after after insert on rem2 - for each row execute procedure trigger_data(23,'skidoo'); - -copy rem2 from stdin; -1 foo -2 bar -\. -select * from rem2; - -drop trigger trig_row_before on rem2; -drop trigger trig_row_after on rem2; -drop trigger trig_stmt_before on rem2; -drop trigger trig_stmt_after on rem2; - -delete from rem2; - -create trigger trig_row_before_insert before insert on rem2 - for each row execute procedure trig_row_before_insupdate(); - --- The new values are concatenated with ' triggered !' -copy rem2 from stdin; -1 foo -2 bar -\. -select * from rem2; - -drop trigger trig_row_before_insert on rem2; - -delete from rem2; - -create trigger trig_null before insert on rem2 - for each row execute procedure trig_null(); - --- Nothing happens -copy rem2 from stdin; -1 foo -2 bar -\. -select * from rem2; - -drop trigger trig_null on rem2; - -delete from rem2; - --- Test remote triggers -create trigger trig_row_before_insert before insert on loc2 - for each row execute procedure trig_row_before_insupdate(); - --- The new values are concatenated with ' triggered !' -copy rem2 from stdin; -1 foo -2 bar -\. -select * from rem2; - -drop trigger trig_row_before_insert on loc2; - -delete from rem2; - -create trigger trig_null before insert on loc2 - for each row execute procedure trig_null(); - --- Nothing happens -copy rem2 from stdin; -1 foo -2 bar -\. -select * from rem2; - -drop trigger trig_null on loc2; - -delete from rem2; - --- Test a combination of local and remote triggers -create trigger rem2_trig_row_before before insert on rem2 - for each row execute procedure trigger_data(23,'skidoo'); -create trigger rem2_trig_row_after after insert on rem2 - for each row execute procedure trigger_data(23,'skidoo'); -create trigger loc2_trig_row_before_insert before insert on loc2 - for each row execute procedure trig_row_before_insupdate(); - -copy rem2 from stdin; -1 foo -2 bar -\. -select * from rem2; - -drop trigger rem2_trig_row_before on rem2; -drop trigger rem2_trig_row_after on rem2; -drop trigger loc2_trig_row_before_insert on loc2; - -delete from rem2; - --- test COPY FROM with foreign table created in the same transaction -create table loc3 (f1 int, f2 text); -begin; -create foreign table rem3 (f1 int, f2 text) - server loopback options(table_name 'loc3'); -copy rem3 from stdin; -1 foo -2 bar -\. -commit; -select * from rem3; -drop foreign table rem3; -drop table loc3; -*/ --- =================================================================== --- test IMPORT FOREIGN SCHEMA --- =================================================================== ---Testcase 608: -CREATE SCHEMA import_influx1; -IMPORT FOREIGN SCHEMA public FROM SERVER influxdb_svr INTO import_influx1 OPTIONS (schemaless 'true'); ---Testcase 609: -\det+ import_influx1.* - List of foreign tables - Schema | Table | Server | FDW options | Description -----------------+-------+--------------+----------------------------------------------+------------- - import_influx1 | T1 | influxdb_svr | ("table" 'T1', schemaless 'true', tags 'c3') | - import_influx1 | T2 | influxdb_svr | ("table" 'T2', schemaless 'true', tags 'c2') | - import_influx1 | T3 | influxdb_svr | ("table" 'T3', schemaless 'true', tags 'c3') | - import_influx1 | T4 | influxdb_svr | ("table" 'T4', schemaless 'true', tags 'c3') | - import_influx1 | bar | influxdb_svr | ("table" 'bar', schemaless 'true') | - import_influx1 | foo | influxdb_svr | ("table" 'foo', schemaless 'true') | - import_influx1 | loc1 | influxdb_svr | ("table" 'loc1', schemaless 'true') | - import_influx1 | loct1 | influxdb_svr | ("table" 'loct1', schemaless 'true') | - import_influx1 | loct2 | influxdb_svr | ("table" 'loct2', schemaless 'true') | -(9 rows) - ---Testcase 610: -\d import_influx1.* - Foreign table "import_influx1.T1" - Column | Type | Collation | Nullable | Default | FDW options ---------+--------------------------+-----------+----------+---------+----------------- - time | timestamp with time zone | | | | - tags | jsonb | | | | (tags 'true') - fields | jsonb | | | | (fields 'true') -Server: influxdb_svr -FDW options: ("table" 'T1', schemaless 'true', tags 'c3') - - Foreign table "import_influx1.T2" - Column | Type | Collation | Nullable | Default | FDW options ---------+--------------------------+-----------+----------+---------+----------------- - time | timestamp with time zone | | | | - tags | jsonb | | | | (tags 'true') - fields | jsonb | | | | (fields 'true') -Server: influxdb_svr -FDW options: ("table" 'T2', schemaless 'true', tags 'c2') - - Foreign table "import_influx1.T3" - Column | Type | Collation | Nullable | Default | FDW options ---------+--------------------------+-----------+----------+---------+----------------- - time | timestamp with time zone | | | | - tags | jsonb | | | | (tags 'true') - fields | jsonb | | | | (fields 'true') -Server: influxdb_svr -FDW options: ("table" 'T3', schemaless 'true', tags 'c3') - - Foreign table "import_influx1.T4" - Column | Type | Collation | Nullable | Default | FDW options ---------+--------------------------+-----------+----------+---------+----------------- - time | timestamp with time zone | | | | - tags | jsonb | | | | (tags 'true') - fields | jsonb | | | | (fields 'true') -Server: influxdb_svr -FDW options: ("table" 'T4', schemaless 'true', tags 'c3') - - Foreign table "import_influx1.bar" - Column | Type | Collation | Nullable | Default | FDW options ---------+--------------------------+-----------+----------+---------+----------------- - time | timestamp with time zone | | | | - tags | jsonb | | | | (tags 'true') - fields | jsonb | | | | (fields 'true') -Server: influxdb_svr -FDW options: ("table" 'bar', schemaless 'true') - - Foreign table "import_influx1.foo" - Column | Type | Collation | Nullable | Default | FDW options ---------+--------------------------+-----------+----------+---------+----------------- - time | timestamp with time zone | | | | - tags | jsonb | | | | (tags 'true') - fields | jsonb | | | | (fields 'true') -Server: influxdb_svr -FDW options: ("table" 'foo', schemaless 'true') - - Foreign table "import_influx1.loc1" - Column | Type | Collation | Nullable | Default | FDW options ---------+--------------------------+-----------+----------+---------+----------------- - time | timestamp with time zone | | | | - tags | jsonb | | | | (tags 'true') - fields | jsonb | | | | (fields 'true') -Server: influxdb_svr -FDW options: ("table" 'loc1', schemaless 'true') - - Foreign table "import_influx1.loct1" - Column | Type | Collation | Nullable | Default | FDW options ---------+--------------------------+-----------+----------+---------+----------------- - time | timestamp with time zone | | | | - tags | jsonb | | | | (tags 'true') - fields | jsonb | | | | (fields 'true') -Server: influxdb_svr -FDW options: ("table" 'loct1', schemaless 'true') - - Foreign table "import_influx1.loct2" - Column | Type | Collation | Nullable | Default | FDW options ---------+--------------------------+-----------+----------+---------+----------------- - time | timestamp with time zone | | | | - tags | jsonb | | | | (tags 'true') - fields | jsonb | | | | (fields 'true') -Server: influxdb_svr -FDW options: ("table" 'loct2', schemaless 'true') - --- Options ---Testcase 611: -CREATE SCHEMA import_influx2; -IMPORT FOREIGN SCHEMA public FROM SERVER influxdb_svr INTO import_influx2 - OPTIONS (import_default 'true', schemaless 'true'); -ERROR: invalid option "import_default" ---Testcase 612: -\det+ import_influx2.* - List of foreign tables - Schema | Table | Server | FDW options | Description ---------+-------+--------+-------------+------------- -(0 rows) - ---Testcase 613: -\d import_influx2.* ---Testcase 614: -CREATE SCHEMA import_influx3; -IMPORT FOREIGN SCHEMA public FROM SERVER influxdb_svr INTO import_influx3 - OPTIONS (import_collate 'false', import_not_null 'false', schemaless 'true'); -ERROR: invalid option "import_collate" ---Testcase 615: -\det+ import_influx3.* - List of foreign tables - Schema | Table | Server | FDW options | Description ---------+-------+--------+-------------+------------- -(0 rows) - ---Testcase 616: -\d import_influx3.* --- Check LIMIT TO and EXCEPT ---Testcase 617: -CREATE SCHEMA import_influx4; -IMPORT FOREIGN SCHEMA public LIMIT TO ("T1", loct, nonesuch) - FROM SERVER influxdb_svr INTO import_influx4 OPTIONS (schemaless 'true'); ---Testcase 618: -\det+ import_influx4.* - List of foreign tables - Schema | Table | Server | FDW options | Description -----------------+-------+--------------+----------------------------------------------+------------- - import_influx4 | T1 | influxdb_svr | ("table" 'T1', schemaless 'true', tags 'c3') | -(1 row) - -IMPORT FOREIGN SCHEMA public EXCEPT ("T1", loct, nonesuch) - FROM SERVER influxdb_svr INTO import_influx4 OPTIONS (schemaless 'true'); ---Testcase 619: -\det+ import_influx4.* - List of foreign tables - Schema | Table | Server | FDW options | Description -----------------+-------+--------------+----------------------------------------------+------------- - import_influx4 | T1 | influxdb_svr | ("table" 'T1', schemaless 'true', tags 'c3') | - import_influx4 | T2 | influxdb_svr | ("table" 'T2', schemaless 'true', tags 'c2') | - import_influx4 | T3 | influxdb_svr | ("table" 'T3', schemaless 'true', tags 'c3') | - import_influx4 | T4 | influxdb_svr | ("table" 'T4', schemaless 'true', tags 'c3') | - import_influx4 | bar | influxdb_svr | ("table" 'bar', schemaless 'true') | - import_influx4 | foo | influxdb_svr | ("table" 'foo', schemaless 'true') | - import_influx4 | loc1 | influxdb_svr | ("table" 'loc1', schemaless 'true') | - import_influx4 | loct1 | influxdb_svr | ("table" 'loct1', schemaless 'true') | - import_influx4 | loct2 | influxdb_svr | ("table" 'loct2', schemaless 'true') | -(9 rows) - --- Assorted error cases -IMPORT FOREIGN SCHEMA public FROM SERVER influxdb_svr INTO import_influx4 OPTIONS (schemaless 'true'); -ERROR: relation "T1" already exists -CONTEXT: importing foreign table "T1" -IMPORT FOREIGN SCHEMA nonesuch FROM SERVER influxdb_svr INTO import_influx4 OPTIONS (schemaless 'true'); -ERROR: relation "T1" already exists -CONTEXT: importing foreign table "T1" -IMPORT FOREIGN SCHEMA nonesuch FROM SERVER influxdb_svr INTO notthere OPTIONS (schemaless 'true'); -ERROR: schema "notthere" does not exist -IMPORT FOREIGN SCHEMA nonesuch FROM SERVER nowhere INTO notthere OPTIONS (schemaless 'true'); -ERROR: server "nowhere" does not exist -/* --- Skip these test, influxdb_fdw does not support fetch_size option, partition table --- Check case of a type present only on the remote server. --- We can fake this by dropping the type locally in our transaction. -CREATE TYPE "Colors" AS ENUM ('red', 'green', 'blue'); -CREATE TABLE import_source.t5 (c1 int, c2 text collate "C", "Col" "Colors"); - -CREATE SCHEMA import_dest5; -BEGIN; -DROP TYPE "Colors" CASCADE; -IMPORT FOREIGN SCHEMA import_source LIMIT TO (t5) - FROM SERVER loopback INTO import_dest5; -- ERROR - -ROLLBACK; - -BEGIN; - - -CREATE SERVER fetch101 FOREIGN DATA WRAPPER postgres_fdw OPTIONS( fetch_size '101' ); - -SELECT count(*) -FROM pg_foreign_server -WHERE srvname = 'fetch101' -AND srvoptions @> array['fetch_size=101']; - -ALTER SERVER fetch101 OPTIONS( SET fetch_size '202' ); - -SELECT count(*) -FROM pg_foreign_server -WHERE srvname = 'fetch101' -AND srvoptions @> array['fetch_size=101']; - -SELECT count(*) -FROM pg_foreign_server -WHERE srvname = 'fetch101' -AND srvoptions @> array['fetch_size=202']; - -CREATE FOREIGN TABLE table30000 ( x int ) SERVER fetch101 OPTIONS ( fetch_size '30000' ); - -SELECT COUNT(*) -FROM pg_foreign_table -WHERE ftrelid = 'table30000'::regclass -AND ftoptions @> array['fetch_size=30000']; - -ALTER FOREIGN TABLE table30000 OPTIONS ( SET fetch_size '60000'); - -SELECT COUNT(*) -FROM pg_foreign_table -WHERE ftrelid = 'table30000'::regclass -AND ftoptions @> array['fetch_size=30000']; - -SELECT COUNT(*) -FROM pg_foreign_table -WHERE ftrelid = 'table30000'::regclass -AND ftoptions @> array['fetch_size=60000']; - -ROLLBACK; - --- =================================================================== --- test partitionwise joins --- =================================================================== -SET enable_partitionwise_join=on; - -CREATE TABLE fprt1 (a int, b int, c varchar) PARTITION BY RANGE(a); -CREATE TABLE fprt1_p1 (LIKE fprt1); -CREATE TABLE fprt1_p2 (LIKE fprt1); -ALTER TABLE fprt1_p1 SET (autovacuum_enabled = 'false'); -ALTER TABLE fprt1_p2 SET (autovacuum_enabled = 'false'); -INSERT INTO fprt1_p1 SELECT i, i, to_char(i/50, 'FM0000') FROM generate_series(0, 249, 2) i; -INSERT INTO fprt1_p2 SELECT i, i, to_char(i/50, 'FM0000') FROM generate_series(250, 499, 2) i; -CREATE FOREIGN TABLE ftprt1_p1 PARTITION OF fprt1 FOR VALUES FROM (0) TO (250) - SERVER loopback OPTIONS (table_name 'fprt1_p1', use_remote_estimate 'true'); -CREATE FOREIGN TABLE ftprt1_p2 PARTITION OF fprt1 FOR VALUES FROM (250) TO (500) - SERVER loopback OPTIONS (TABLE_NAME 'fprt1_p2'); -ANALYZE fprt1; -ANALYZE fprt1_p1; -ANALYZE fprt1_p2; - -CREATE TABLE fprt2 (a int, b int, c varchar) PARTITION BY RANGE(b); -CREATE TABLE fprt2_p1 (LIKE fprt2); -CREATE TABLE fprt2_p2 (LIKE fprt2); -ALTER TABLE fprt2_p1 SET (autovacuum_enabled = 'false'); -ALTER TABLE fprt2_p2 SET (autovacuum_enabled = 'false'); -INSERT INTO fprt2_p1 SELECT i, i, to_char(i/50, 'FM0000') FROM generate_series(0, 249, 3) i; -INSERT INTO fprt2_p2 SELECT i, i, to_char(i/50, 'FM0000') FROM generate_series(250, 499, 3) i; -CREATE FOREIGN TABLE ftprt2_p1 (b int, c varchar, a int) - SERVER loopback OPTIONS (table_name 'fprt2_p1', use_remote_estimate 'true'); -ALTER TABLE fprt2 ATTACH PARTITION ftprt2_p1 FOR VALUES FROM (0) TO (250); -CREATE FOREIGN TABLE ftprt2_p2 PARTITION OF fprt2 FOR VALUES FROM (250) TO (500) - SERVER loopback OPTIONS (table_name 'fprt2_p2', use_remote_estimate 'true'); -ANALYZE fprt2; -ANALYZE fprt2_p1; -ANALYZE fprt2_p2; - --- inner join three tables -EXPLAIN (COSTS OFF) -SELECT t1.a,t2.b,t3.c FROM fprt1 t1 INNER JOIN fprt2 t2 ON (t1.a = t2.b) INNER JOIN fprt1 t3 ON (t2.b = t3.a) WHERE t1.a % 25 =0 ORDER BY 1,2,3; -SELECT t1.a,t2.b,t3.c FROM fprt1 t1 INNER JOIN fprt2 t2 ON (t1.a = t2.b) INNER JOIN fprt1 t3 ON (t2.b = t3.a) WHERE t1.a % 25 =0 ORDER BY 1,2,3; - --- left outer join + nullable clause -EXPLAIN (VERBOSE, COSTS OFF) -SELECT t1.a,t2.b,t2.c FROM fprt1 t1 LEFT JOIN (SELECT * FROM fprt2 WHERE a < 10) t2 ON (t1.a = t2.b and t1.b = t2.a) WHERE t1.a < 10 ORDER BY 1,2,3; -SELECT t1.a,t2.b,t2.c FROM fprt1 t1 LEFT JOIN (SELECT * FROM fprt2 WHERE a < 10) t2 ON (t1.a = t2.b and t1.b = t2.a) WHERE t1.a < 10 ORDER BY 1,2,3; - --- with whole-row reference; partitionwise join does not apply -EXPLAIN (COSTS OFF) -SELECT t1.wr, t2.wr FROM (SELECT t1 wr, a FROM fprt1 t1 WHERE t1.a % 25 = 0) t1 FULL JOIN (SELECT t2 wr, b FROM fprt2 t2 WHERE t2.b % 25 = 0) t2 ON (t1.a = t2.b) ORDER BY 1,2; -SELECT t1.wr, t2.wr FROM (SELECT t1 wr, a FROM fprt1 t1 WHERE t1.a % 25 = 0) t1 FULL JOIN (SELECT t2 wr, b FROM fprt2 t2 WHERE t2.b % 25 = 0) t2 ON (t1.a = t2.b) ORDER BY 1,2; - --- join with lateral reference -EXPLAIN (COSTS OFF) -SELECT t1.a,t1.b FROM fprt1 t1, LATERAL (SELECT t2.a, t2.b FROM fprt2 t2 WHERE t1.a = t2.b AND t1.b = t2.a) q WHERE t1.a%25 = 0 ORDER BY 1,2; -SELECT t1.a,t1.b FROM fprt1 t1, LATERAL (SELECT t2.a, t2.b FROM fprt2 t2 WHERE t1.a = t2.b AND t1.b = t2.a) q WHERE t1.a%25 = 0 ORDER BY 1,2; - --- with PHVs, partitionwise join selected but no join pushdown -EXPLAIN (COSTS OFF) -SELECT t1.a, t1.phv, t2.b, t2.phv FROM (SELECT 't1_phv' phv, * FROM fprt1 WHERE a % 25 = 0) t1 FULL JOIN (SELECT 't2_phv' phv, * FROM fprt2 WHERE b % 25 = 0) t2 ON (t1.a = t2.b) ORDER BY t1.a, t2.b; -SELECT t1.a, t1.phv, t2.b, t2.phv FROM (SELECT 't1_phv' phv, * FROM fprt1 WHERE a % 25 = 0) t1 FULL JOIN (SELECT 't2_phv' phv, * FROM fprt2 WHERE b % 25 = 0) t2 ON (t1.a = t2.b) ORDER BY t1.a, t2.b; - --- test FOR UPDATE; partitionwise join does not apply -EXPLAIN (COSTS OFF) -SELECT t1.a, t2.b FROM fprt1 t1 INNER JOIN fprt2 t2 ON (t1.a = t2.b) WHERE t1.a % 25 = 0 ORDER BY 1,2 FOR UPDATE OF t1; -SELECT t1.a, t2.b FROM fprt1 t1 INNER JOIN fprt2 t2 ON (t1.a = t2.b) WHERE t1.a % 25 = 0 ORDER BY 1,2 FOR UPDATE OF t1; - -RESET enable_partitionwise_join; - - --- =================================================================== --- test partitionwise aggregates --- =================================================================== - -CREATE TABLE pagg_tab (a int, b int, c text) PARTITION BY RANGE(a); - -CREATE TABLE pagg_tab_p1 (LIKE pagg_tab); -CREATE TABLE pagg_tab_p2 (LIKE pagg_tab); -CREATE TABLE pagg_tab_p3 (LIKE pagg_tab); - -INSERT INTO pagg_tab_p1 SELECT i % 30, i % 50, to_char(i/30, 'FM0000') FROM generate_series(1, 3000) i WHERE (i % 30) < 10; -INSERT INTO pagg_tab_p2 SELECT i % 30, i % 50, to_char(i/30, 'FM0000') FROM generate_series(1, 3000) i WHERE (i % 30) < 20 and (i % 30) >= 10; -INSERT INTO pagg_tab_p3 SELECT i % 30, i % 50, to_char(i/30, 'FM0000') FROM generate_series(1, 3000) i WHERE (i % 30) < 30 and (i % 30) >= 20; - --- Create foreign partitions -CREATE FOREIGN TABLE fpagg_tab_p1 PARTITION OF pagg_tab FOR VALUES FROM (0) TO (10) SERVER loopback OPTIONS (table_name 'pagg_tab_p1'); -CREATE FOREIGN TABLE fpagg_tab_p2 PARTITION OF pagg_tab FOR VALUES FROM (10) TO (20) SERVER loopback OPTIONS (table_name 'pagg_tab_p2'); -CREATE FOREIGN TABLE fpagg_tab_p3 PARTITION OF pagg_tab FOR VALUES FROM (20) TO (30) SERVER loopback OPTIONS (table_name 'pagg_tab_p3'); - -ANALYZE pagg_tab; -ANALYZE fpagg_tab_p1; -ANALYZE fpagg_tab_p2; -ANALYZE fpagg_tab_p3; - --- When GROUP BY clause matches with PARTITION KEY. --- Plan with partitionwise aggregates is disabled -SET enable_partitionwise_aggregate TO false; -EXPLAIN (COSTS OFF) -SELECT a, sum(b), min(b), count(*) FROM pagg_tab GROUP BY a HAVING avg(b) < 22 ORDER BY 1; - --- Plan with partitionwise aggregates is enabled -SET enable_partitionwise_aggregate TO true; -EXPLAIN (COSTS OFF) -SELECT a, sum(b), min(b), count(*) FROM pagg_tab GROUP BY a HAVING avg(b) < 22 ORDER BY 1; -SELECT a, sum(b), min(b), count(*) FROM pagg_tab GROUP BY a HAVING avg(b) < 22 ORDER BY 1; - --- Check with whole-row reference --- Should have all the columns in the target list for the given relation -EXPLAIN (VERBOSE, COSTS OFF) -SELECT a, count(t1) FROM pagg_tab t1 GROUP BY a HAVING avg(b) < 22 ORDER BY 1; -SELECT a, count(t1) FROM pagg_tab t1 GROUP BY a HAVING avg(b) < 22 ORDER BY 1; - --- When GROUP BY clause does not match with PARTITION KEY. -EXPLAIN (COSTS OFF) -SELECT b, avg(a), max(a), count(*) FROM pagg_tab GROUP BY b HAVING sum(a) < 700 ORDER BY 1; -*/ -/* --- Skip test, influxdb_fdw does not support nosuperuser --- =================================================================== --- access rights and superuser --- =================================================================== - --- Non-superuser cannot create a FDW without a password in the connstr -CREATE ROLE regress_nosuper NOSUPERUSER; - -GRANT USAGE ON FOREIGN DATA WRAPPER influxdb_fdw TO regress_nosuper; - -SET ROLE regress_nosuper; - -SHOW is_superuser; - --- This will be OK, we can create the FDW -DO $d$ - BEGIN - EXECUTE $$CREATE SERVER loopback_nopw FOREIGN DATA WRAPPER influxdb_fdw - OPTIONS (dbname '$$||current_database()||$$', - port '$$||current_setting('port')||$$' - )$$; - END; -$d$; - --- But creation of user mappings for non-superusers should fail -CREATE USER MAPPING FOR public SERVER loopback_nopw; -CREATE USER MAPPING FOR CURRENT_USER SERVER loopback_nopw; - -CREATE FOREIGN TABLE ft1_nopw ( - c1 int NOT NULL, - c2 int NOT NULL, - c3 text, - c4 timestamptz, - c5 timestamp, - c6 varchar(10), - c7 char(10) default 'ft1', - c8 user_enum -) SERVER loopback_nopw OPTIONS (schema_name 'public', table_name 'ft1'); - -SELECT * FROM ft1_nopw LIMIT 1; - --- If we add a password to the connstr it'll fail, because we don't allow passwords --- in connstrs only in user mappings. - -DO $d$ - BEGIN - EXECUTE $$ALTER SERVER loopback_nopw OPTIONS (ADD password 'dummypw')$$; - END; -$d$; - --- If we add a password for our user mapping instead, we should get a different --- error because the password wasn't actually *used* when we run with trust auth. --- --- This won't work with installcheck, but neither will most of the FDW checks. - -ALTER USER MAPPING FOR CURRENT_USER SERVER loopback_nopw OPTIONS (ADD password 'dummypw'); - -SELECT * FROM ft1_nopw LIMIT 1; - --- Unpriv user cannot make the mapping passwordless -ALTER USER MAPPING FOR CURRENT_USER SERVER loopback_nopw OPTIONS (ADD password_required 'false'); - - -SELECT * FROM ft1_nopw LIMIT 1; - -RESET ROLE; - --- But the superuser can -ALTER USER MAPPING FOR regress_nosuper SERVER loopback_nopw OPTIONS (ADD password_required 'false'); - -SET ROLE regress_nosuper; - --- Should finally work now -SELECT * FROM ft1_nopw LIMIT 1; - --- unpriv user also cannot set sslcert / sslkey on the user mapping --- first set password_required so we see the right error messages -ALTER USER MAPPING FOR CURRENT_USER SERVER loopback_nopw OPTIONS (SET password_required 'true'); -ALTER USER MAPPING FOR CURRENT_USER SERVER loopback_nopw OPTIONS (ADD sslcert 'foo.crt'); -ALTER USER MAPPING FOR CURRENT_USER SERVER loopback_nopw OPTIONS (ADD sslkey 'foo.key'); - --- We're done with the role named after a specific user and need to check the --- changes to the public mapping. -DROP USER MAPPING FOR CURRENT_USER SERVER loopback_nopw; - --- This will fail again as it'll resolve the user mapping for public, which --- lacks password_required=false -SELECT * FROM ft1_nopw LIMIT 1; - -RESET ROLE; - --- The user mapping for public is passwordless and lacks the password_required=false --- mapping option, but will work because the current user is a superuser. -SELECT * FROM ft1_nopw LIMIT 1; - --- cleanup -DROP USER MAPPING FOR public SERVER loopback_nopw; -DROP OWNED BY regress_nosuper; -DROP ROLE regress_nosuper; -*/ --- influxdb_fdw does not support transactions --- Two-phase transactions are not supported. ---BEGIN; ---Testcase 620: -SELECT count(*) FROM ft1; - count -------- - 822 -(1 row) - --- error here ---PREPARE TRANSACTION 'fdw_tpc'; ---ROLLBACK; --- Clean-up -DELETE FROM ft1_nsc; -DELETE FROM ft2_nsc; -DELETE FROM ft4_nsc; -DELETE FROM ft5_nsc; -DELETE FROM foo_nsc; -DELETE FROM bar_nsc; -DELETE FROM loct1_nsc; -DELETE FROM loct2_nsc; -DELETE FROM rem1_nsc; -DROP FOREIGN TABLE foo_nsc cascade; -NOTICE: drop cascades to foreign table foo2_nsc -DROP FOREIGN TABLE bar_nsc cascade; -NOTICE: drop cascades to foreign table bar2_nsc -DROP FOREIGN TABLE loct1_nsc; -DROP FOREIGN TABLE loct2_nsc; -DROP FOREIGN TABLE "S 1".s1t0; -DROP FOREIGN TABLE "S 1".s1t1; -DROP FOREIGN TABLE "S 1".s1t2; -DROP FOREIGN TABLE "S 1".s1t3; -DROP FOREIGN TABLE "S 1".s1t4; -DROP FOREIGN TABLE ft1_nsc; -DROP FOREIGN TABLE ft2_nsc; -DROP FOREIGN TABLE ft4_nsc; -DROP FOREIGN TABLE ft5_nsc; -DROP TYPE IF EXISTS user_enum; -DROP SCHEMA IF EXISTS "S 1" CASCADE; -NOTICE: drop cascades to 6 other objects -DETAIL: drop cascades to foreign table "S 1"."T 0" -drop cascades to foreign table "S 1"."T 1" -drop cascades to foreign table "S 1"."T 2" -drop cascades to foreign table "S 1"."T 3" -drop cascades to foreign table "S 1"."T 4" -drop cascades to function "S 1".f_brtrig() -DROP FUNCTION IF EXISTS trigger_func(); -DROP FUNCTION IF EXISTS trig_row_before_insupdate(); -DROP FUNCTION IF EXISTS trig_null(); -DROP SCHEMA IF EXISTS import_influx1 CASCADE; -NOTICE: drop cascades to 9 other objects -DETAIL: drop cascades to foreign table import_influx1."T1" -drop cascades to foreign table import_influx1."T2" -drop cascades to foreign table import_influx1."T3" -drop cascades to foreign table import_influx1."T4" -drop cascades to foreign table import_influx1.bar -drop cascades to foreign table import_influx1.foo -drop cascades to foreign table import_influx1.loc1 -drop cascades to foreign table import_influx1.loct1 -drop cascades to foreign table import_influx1.loct2 -DROP SCHEMA IF EXISTS import_influx2 CASCADE; -DROP SCHEMA IF EXISTS import_influx3 CASCADE; -DROP SCHEMA IF EXISTS import_influx4 CASCADE; -NOTICE: drop cascades to 9 other objects -DETAIL: drop cascades to foreign table import_influx4."T1" -drop cascades to foreign table import_influx4."T2" -drop cascades to foreign table import_influx4."T3" -drop cascades to foreign table import_influx4."T4" -drop cascades to foreign table import_influx4.bar -drop cascades to foreign table import_influx4.foo -drop cascades to foreign table import_influx4.loc1 -drop cascades to foreign table import_influx4.loct1 -drop cascades to foreign table import_influx4.loct2 ---Testcase 621: -DROP USER MAPPING FOR public SERVER testserver1; ---Testcase 622: -DROP USER MAPPING FOR CURRENT_USER SERVER influxdb_svr; ---Testcase 623: -DROP USER MAPPING FOR CURRENT_USER SERVER influxdb_svr2; ---Testcase 624: -DROP SERVER testserver1 CASCADE; ---Testcase 625: -DROP SERVER influxdb_svr CASCADE; -NOTICE: drop cascades to 18 other objects -DETAIL: drop cascades to foreign table ft1 -drop cascades to foreign table ft2 -drop cascades to foreign table ft4 -drop cascades to foreign table ft5 -drop cascades to foreign table loct3 -drop cascades to foreign table ft3 -drop cascades to foreign table loc1 -drop cascades to foreign table loc1_nsc -drop cascades to foreign table rem1 -drop cascades to foreign table rem1_nsc -drop cascades to foreign table gloc1 -drop cascades to foreign table grem1 -drop cascades to foreign table loct1 -drop cascades to foreign table loct2 -drop cascades to foreign table foo -drop cascades to foreign table foo2 -drop cascades to foreign table bar -drop cascades to foreign table bar2 ---Testcase 626: -DROP SERVER influxdb_svr2 CASCADE; -NOTICE: drop cascades to foreign table ft6 ---Testcase 627: -DROP EXTENSION influxdb_fdw; diff --git a/expected/11.17/schemaless/influxdb_fdw.out b/expected/11.17/schemaless/influxdb_fdw.out deleted file mode 100644 index f4d4140..0000000 --- a/expected/11.17/schemaless/influxdb_fdw.out +++ /dev/null @@ -1,1613 +0,0 @@ ---SET log_min_messages=debug1; ---SET client_min_messages=debug1; ---Testcase 1: -SET datestyle=ISO; --- timestamp with time zone differs based on this ---Testcase 2: -SET timezone='Japan'; -\set ECHO none ---Testcase 3: -CREATE EXTENSION influxdb_fdw; ---Testcase 4: -CREATE SERVER server1 FOREIGN DATA WRAPPER influxdb_fdw OPTIONS -(dbname 'mydb', :SERVER); ---Testcase 5: -CREATE USER MAPPING FOR CURRENT_USER SERVER server1 OPTIONS (:AUTHENTICATION); --- import time column as timestamp and text type -IMPORT FOREIGN SCHEMA public FROM SERVER server1 INTO public OPTIONS(import_time_text 'true', schemaless 'true'); ---Testcase 6: -SELECT * FROM cpu; - time | time_text | tags | fields -------------------------+----------------------+--------------------------------------+----------------------------------------------------------------------- - 2015-08-18 09:00:00+09 | 2015-08-18T00:00:00Z | {"tag1": "tag1_A", "tag2": "tag2_A"} | {"value1": "100", "value2": "0.5", "value3": "str", "value4": "true"} - 2015-08-18 09:00:00+09 | 2015-08-18T00:00:00Z | {"tag1": "tag1_B", "tag2": null} | {"value1": "100", "value2": "2", "value3": null, "value4": "false"} - 2015-08-18 09:48:08+09 | 2015-08-18T00:48:08Z | {"tag1": null, "tag2": "tag2_A"} | {"value1": null, "value2": "2", "value3": null, "value4": null} -(3 rows) - ---Testcase 7: -SELECT tags->>'tag1' tag1, (fields->>'value1')::bigint value1 FROM cpu; - tag1 | value1 ---------+-------- - tag1_A | 100 - tag1_B | 100 -(2 rows) - ---Testcase 8: -SELECT (fields->>'value1')::bigint value1, time, (fields->>'value2')::double precision value2 FROM cpu; - value1 | time | value2 ---------+------------------------+-------- - 100 | 2015-08-18 09:00:00+09 | 0.5 - 100 | 2015-08-18 09:00:00+09 | 2 - | 2015-08-18 09:48:08+09 | 2 -(3 rows) - ---Testcase 9: -SELECT (fields->>'value1')::bigint value1, time_text, (fields->>'value2')::double precision value2 FROM cpu; - value1 | time_text | value2 ---------+----------------------+-------- - 100 | 2015-08-18T00:00:00Z | 0.5 - 100 | 2015-08-18T00:00:00Z | 2 - | 2015-08-18T00:48:08Z | 2 -(3 rows) - ---Testcase 10: -DROP FOREIGN TABLE cpu; ---Testcase 11: -DROP FOREIGN TABLE t3; ---Testcase 12: -DROP FOREIGN TABLE t4; ---Testcase 13: -DROP FOREIGN TABLE tx; ---Testcase 14: -DROP FOREIGN TABLE numbers; --- test EXECPT -IMPORT FOREIGN SCHEMA public EXCEPT (cpu, t3, t4, tx, numbers) FROM SERVER server1 INTO public OPTIONS(schemaless 'true'); ---Testcase 15: -SELECT ftoptions FROM pg_foreign_table; - ftoptions ------------ -(0 rows) - --- test LIMIT TO -IMPORT FOREIGN SCHEMA public LIMIT TO (cpu) FROM SERVER server1 INTO public OPTIONS(schemaless 'true'); ---Testcase 16: -SELECT ftoptions FROM pg_foreign_table; - ftoptions ----------------------------------------------- - {table=cpu,schemaless=true,"tags=tag1,tag2"} -(1 row) - ---Testcase 17: -DROP FOREIGN TABLE cpu; -IMPORT FOREIGN SCHEMA public FROM SERVER server1 INTO public OPTIONS(import_time_text 'false', schemaless 'true'); ---Testcase 18: -SELECT * FROM cpu; - time | tags | fields -------------------------+--------------------------------------+----------------------------------------------------------------------- - 2015-08-18 09:00:00+09 | {"tag1": "tag1_A", "tag2": "tag2_A"} | {"value1": "100", "value2": "0.5", "value3": "str", "value4": "true"} - 2015-08-18 09:00:00+09 | {"tag1": "tag1_B", "tag2": null} | {"value1": "100", "value2": "2", "value3": null, "value4": "false"} - 2015-08-18 09:48:08+09 | {"tag1": null, "tag2": "tag2_A"} | {"value1": null, "value2": "2", "value3": null, "value4": null} -(3 rows) - ---Testcase 19: -SELECT tags->>'tag1' tag1, (fields->>'value1')::int value1 FROM cpu; - tag1 | value1 ---------+-------- - tag1_A | 100 - tag1_B | 100 -(2 rows) - ---Testcase 20: -SELECT (fields->>'value1')::int value1, time, (fields->>'value2')::double precision value2 FROM cpu; - value1 | time | value2 ---------+------------------------+-------- - 100 | 2015-08-18 09:00:00+09 | 0.5 - 100 | 2015-08-18 09:00:00+09 | 2 - | 2015-08-18 09:48:08+09 | 2 -(3 rows) - ---Testcase 21: -SELECT tags->>'tag1' tag1 FROM cpu; - tag1 --------- - tag1_A - tag1_B - -(3 rows) - ---Testcase 22: -SELECT * FROM numbers; - time | tags | fields -------------------------+---------------+------------------------ - 1970-01-01 09:00:00+09 | {"tag1": "a"} | {"a": "1", "b": "One"} - 1970-01-01 09:00:01+09 | {"tag1": "a"} | {"a": "2", "b": "Two"} -(2 rows) - ---Testcase 23: -\d cpu; - Foreign table "public.cpu" - Column | Type | Collation | Nullable | Default | FDW options ---------+--------------------------+-----------+----------+---------+----------------- - time | timestamp with time zone | | | | - tags | jsonb | | | | (tags 'true') - fields | jsonb | | | | (fields 'true') -Server: server1 -FDW options: ("table" 'cpu', schemaless 'true', tags 'tag1,tag2') - ---Testcase 24: -SELECT * FROM cpu WHERE (fields->>'value1')::int=100; - time | tags | fields -------------------------+--------------------------------------+----------------------------------------------------------------------- - 2015-08-18 09:00:00+09 | {"tag1": "tag1_A", "tag2": "tag2_A"} | {"value1": "100", "value2": "0.5", "value3": "str", "value4": "true"} - 2015-08-18 09:00:00+09 | {"tag1": "tag1_B", "tag2": null} | {"value1": "100", "value2": "2", "value3": null, "value4": "false"} -(2 rows) - ---Testcase 25: -SELECT * FROM cpu WHERE (fields->>'value2')::double precision=0.5; - time | tags | fields -------------------------+--------------------------------------+----------------------------------------------------------------------- - 2015-08-18 09:00:00+09 | {"tag1": "tag1_A", "tag2": "tag2_A"} | {"value1": "100", "value2": "0.5", "value3": "str", "value4": "true"} -(1 row) - ---Testcase 26: -SELECT * FROM cpu WHERE fields->>'value3'='str'; - time | tags | fields -------------------------+--------------------------------------+----------------------------------------------------------------------- - 2015-08-18 09:00:00+09 | {"tag1": "tag1_A", "tag2": "tag2_A"} | {"value1": "100", "value2": "0.5", "value3": "str", "value4": "true"} -(1 row) - ---Testcase 27: -SELECT * FROM cpu WHERE (fields->>'value4')::boolean=true; - time | tags | fields -------------------------+--------------------------------------+----------------------------------------------------------------------- - 2015-08-18 09:00:00+09 | {"tag1": "tag1_A", "tag2": "tag2_A"} | {"value1": "100", "value2": "0.5", "value3": "str", "value4": "true"} -(1 row) - ---Testcase 28: -SELECT * FROM cpu WHERE NOT ((fields->>'value4')::boolean AND (fields->>'value1')::int=100); - time | tags | fields -------------------------+----------------------------------+--------------------------------------------------------------------- - 2015-08-18 09:00:00+09 | {"tag1": "tag1_B", "tag2": null} | {"value1": "100", "value2": "2", "value3": null, "value4": "false"} -(1 row) - ---Testcase 29: -SELECT * FROM cpu WHERE tags->>'tag1'='tag1_A'; - time | tags | fields -------------------------+--------------------------------------+----------------------------------------------------------------------- - 2015-08-18 09:00:00+09 | {"tag1": "tag1_A", "tag2": "tag2_A"} | {"value1": "100", "value2": "0.5", "value3": "str", "value4": "true"} -(1 row) - ---Testcase 30: -EXPLAIN (VERBOSE, COSTS OFF) -SELECT * FROM cpu WHERE fields->>'value3' IS NULL; - QUERY PLAN ------------------------------------------------------ - Foreign Scan on public.cpu - Output: "time", tags, fields - Filter: ((cpu.fields ->> 'value3'::text) IS NULL) - InfluxDB query: SELECT * FROM "cpu" -(4 rows) - ---Testcase 31: -SELECT * FROM cpu WHERE fields->>'value3' IS NULL; - time | tags | fields -------------------------+----------------------------------+--------------------------------------------------------------------- - 2015-08-18 09:00:00+09 | {"tag1": "tag1_B", "tag2": null} | {"value1": "100", "value2": "2", "value3": null, "value4": "false"} - 2015-08-18 09:48:08+09 | {"tag1": null, "tag2": "tag2_A"} | {"value1": null, "value2": "2", "value3": null, "value4": null} -(2 rows) - ---Testcase 32: -SELECT * FROM cpu WHERE tags->>'tag2' IS NULL; - time | tags | fields -------------------------+----------------------------------+--------------------------------------------------------------------- - 2015-08-18 09:00:00+09 | {"tag1": "tag1_B", "tag2": null} | {"value1": "100", "value2": "2", "value3": null, "value4": "false"} -(1 row) - ---Testcase 33: -SELECT * FROM cpu WHERE fields->>'value3' IS NOT NULL; - time | tags | fields -------------------------+--------------------------------------+----------------------------------------------------------------------- - 2015-08-18 09:00:00+09 | {"tag1": "tag1_A", "tag2": "tag2_A"} | {"value1": "100", "value2": "0.5", "value3": "str", "value4": "true"} -(1 row) - ---Testcase 34: -SELECT * FROM cpu WHERE tags->>'tag2' IS NOT NULL; - time | tags | fields -------------------------+--------------------------------------+----------------------------------------------------------------------- - 2015-08-18 09:00:00+09 | {"tag1": "tag1_A", "tag2": "tag2_A"} | {"value1": "100", "value2": "0.5", "value3": "str", "value4": "true"} - 2015-08-18 09:48:08+09 | {"tag1": null, "tag2": "tag2_A"} | {"value1": null, "value2": "2", "value3": null, "value4": null} -(2 rows) - --- InfluxDB not support compare timestamp with OR condition ---Testcase 35: -SELECT * FROM cpu WHERE time = '2015-08-18 09:48:08+09' OR (fields->>'value2')::double precision = 0.5; - time | tags | fields -------------------------+--------------------------------------+----------------------------------------------------------------------- - 2015-08-18 09:00:00+09 | {"tag1": "tag1_A", "tag2": "tag2_A"} | {"value1": "100", "value2": "0.5", "value3": "str", "value4": "true"} - 2015-08-18 09:48:08+09 | {"tag1": null, "tag2": "tag2_A"} | {"value1": null, "value2": "2", "value3": null, "value4": null} -(2 rows) - --- InfluxDB not support compare timestamp with != or <> ---Testcase 36: -SELECT * FROM cpu WHERE time != '2015-08-18 09:48:08+09'; - time | tags | fields -------------------------+--------------------------------------+----------------------------------------------------------------------- - 2015-08-18 09:00:00+09 | {"tag1": "tag1_A", "tag2": "tag2_A"} | {"value1": "100", "value2": "0.5", "value3": "str", "value4": "true"} - 2015-08-18 09:00:00+09 | {"tag1": "tag1_B", "tag2": null} | {"value1": "100", "value2": "2", "value3": null, "value4": "false"} -(2 rows) - ---Testcase 37: -SELECT * FROM cpu WHERE time <> '2015-08-18 09:48:08+09'; - time | tags | fields -------------------------+--------------------------------------+----------------------------------------------------------------------- - 2015-08-18 09:00:00+09 | {"tag1": "tag1_A", "tag2": "tag2_A"} | {"value1": "100", "value2": "0.5", "value3": "str", "value4": "true"} - 2015-08-18 09:00:00+09 | {"tag1": "tag1_B", "tag2": null} | {"value1": "100", "value2": "2", "value3": null, "value4": "false"} -(2 rows) - ---Testcase 38: -SELECT * FROM cpu WHERE time = '2015-08-18 09:48:08+09' OR (fields->>'value2')::double precision = 0.5; - time | tags | fields -------------------------+--------------------------------------+----------------------------------------------------------------------- - 2015-08-18 09:00:00+09 | {"tag1": "tag1_A", "tag2": "tag2_A"} | {"value1": "100", "value2": "0.5", "value3": "str", "value4": "true"} - 2015-08-18 09:48:08+09 | {"tag1": null, "tag2": "tag2_A"} | {"value1": null, "value2": "2", "value3": null, "value4": null} -(2 rows) - --- There is inconsitency for search of missing values between tag and field ---Testcase 39: -EXPLAIN (VERBOSE, COSTS OFF) -SELECT * FROM cpu WHERE fields->>'value3' = ''; - QUERY PLAN ---------------------------------------------------------------- - Foreign Scan on public.cpu - Output: "time", tags, fields - InfluxDB query: SELECT * FROM "cpu" WHERE (("value3" = '')) -(3 rows) - ---Testcase 40: -SELECT * FROM cpu WHERE fields->>'value3' = ''; - time | tags | fields -------+------+-------- -(0 rows) - ---Testcase 41: -EXPLAIN (VERBOSE, COSTS OFF) -SELECT * FROM cpu WHERE tags->>'tag2' = ''; - QUERY PLAN -------------------------------------------------------------- - Foreign Scan on public.cpu - Output: "time", tags, fields - InfluxDB query: SELECT * FROM "cpu" WHERE (("tag2" = '')) -(3 rows) - ---Testcase 42: -SELECT * FROM cpu WHERE tags->>'tag2' = ''; - time | tags | fields -------------------------+----------------------------------+--------------------------------------------------------------------- - 2015-08-18 09:00:00+09 | {"tag1": "tag1_B", "tag2": null} | {"value1": "100", "value2": "2", "value3": null, "value4": "false"} -(1 row) - ---Testcase 43: -SELECT * FROM cpu WHERE tags->>'tag1' IN ('tag1_A', 'tag1_B'); - time | tags | fields -------------------------+--------------------------------------+----------------------------------------------------------------------- - 2015-08-18 09:00:00+09 | {"tag1": "tag1_A", "tag2": "tag2_A"} | {"value1": "100", "value2": "0.5", "value3": "str", "value4": "true"} - 2015-08-18 09:00:00+09 | {"tag1": "tag1_B", "tag2": null} | {"value1": "100", "value2": "2", "value3": null, "value4": "false"} -(2 rows) - ---Testcase 44: -EXPLAIN VERBOSE -SELECT * FROM cpu WHERE tags->>'tag1' IN ('tag1_A', 'tag1_B'); - QUERY PLAN --------------------------------------------------------------------------------------- - Foreign Scan on public.cpu (cost=10.00..9.00 rows=9 width=72) - Output: "time", tags, fields - InfluxDB query: SELECT * FROM "cpu" WHERE ("tag1" = 'tag1_A' OR "tag1" = 'tag1_B') -(3 rows) - --- Rows which have no tag are considered to have empty string ---Testcase 45: -SELECT * FROM cpu WHERE tags->>'tag1' NOT IN ('tag1_A', 'tag1_B'); - time | tags | fields -------------------------+----------------------------------+----------------------------------------------------------------- - 2015-08-18 09:48:08+09 | {"tag1": null, "tag2": "tag2_A"} | {"value1": null, "value2": "2", "value3": null, "value4": null} -(1 row) - ---Testcase 46: -EXPLAIN VERBOSE -SELECT * FROM cpu WHERE tags->>'tag1' NOT IN ('tag1_A', 'tag1_B'); - QUERY PLAN ------------------------------------------------------------------------------------------ - Foreign Scan on public.cpu (cost=10.00..844.00 rows=844 width=72) - Output: "time", tags, fields - InfluxDB query: SELECT * FROM "cpu" WHERE ("tag1" <> 'tag1_A' AND "tag1" <> 'tag1_B') -(3 rows) - --- test IN/NOT IN ---Testcase 47: -SELECT * FROM cpu WHERE time IN ('2015-08-18 09:48:08+09','2016-08-28 07:44:00+07'); - time | tags | fields -------------------------+----------------------------------+----------------------------------------------------------------- - 2015-08-18 09:48:08+09 | {"tag1": null, "tag2": "tag2_A"} | {"value1": null, "value2": "2", "value3": null, "value4": null} -(1 row) - ---Testcase 48: -SELECT * FROM cpu WHERE time NOT IN ('2015-08-18 09:48:08+09','2016-08-28 07:44:00+07'); - time | tags | fields -------------------------+--------------------------------------+----------------------------------------------------------------------- - 2015-08-18 09:00:00+09 | {"tag1": "tag1_A", "tag2": "tag2_A"} | {"value1": "100", "value2": "0.5", "value3": "str", "value4": "true"} - 2015-08-18 09:00:00+09 | {"tag1": "tag1_B", "tag2": null} | {"value1": "100", "value2": "2", "value3": null, "value4": "false"} -(2 rows) - ---Testcase 49: -SELECT * FROM cpu WHERE (fields->>'value1')::int NOT IN (100, 97); - time | tags | fields -------+------+-------- -(0 rows) - ---Testcase 50: -SELECT * FROM cpu WHERE (fields->>'value1')::int IN (100, 97); - time | tags | fields -------------------------+--------------------------------------+----------------------------------------------------------------------- - 2015-08-18 09:00:00+09 | {"tag1": "tag1_A", "tag2": "tag2_A"} | {"value1": "100", "value2": "0.5", "value3": "str", "value4": "true"} - 2015-08-18 09:00:00+09 | {"tag1": "tag1_B", "tag2": null} | {"value1": "100", "value2": "2", "value3": null, "value4": "false"} -(2 rows) - ---Testcase 51: -SELECT * FROM cpu WHERE (fields->>'value2')::double precision IN (0.5, 10.9); - time | tags | fields -------------------------+--------------------------------------+----------------------------------------------------------------------- - 2015-08-18 09:00:00+09 | {"tag1": "tag1_A", "tag2": "tag2_A"} | {"value1": "100", "value2": "0.5", "value3": "str", "value4": "true"} -(1 row) - ---Testcase 52: -SELECT * FROM cpu WHERE (fields->>'value2')::double precision NOT IN (2, 9.7); - time | tags | fields -------------------------+--------------------------------------+----------------------------------------------------------------------- - 2015-08-18 09:00:00+09 | {"tag1": "tag1_A", "tag2": "tag2_A"} | {"value1": "100", "value2": "0.5", "value3": "str", "value4": "true"} -(1 row) - ---Testcase 53: -SELECT * FROM cpu WHERE (fields->>'value4')::boolean NOT IN ('true', 'true'); - time | tags | fields -------------------------+----------------------------------+--------------------------------------------------------------------- - 2015-08-18 09:00:00+09 | {"tag1": "tag1_B", "tag2": null} | {"value1": "100", "value2": "2", "value3": null, "value4": "false"} -(1 row) - ---Testcase 54: -SELECT * FROM cpu WHERE time IN ('2015-08-18 09:48:08+09','2016-08-28 07:44:00+07'); - time | tags | fields -------------------------+----------------------------------+----------------------------------------------------------------- - 2015-08-18 09:48:08+09 | {"tag1": null, "tag2": "tag2_A"} | {"value1": null, "value2": "2", "value3": null, "value4": null} -(1 row) - ---Testcase 55: -SELECT * FROM cpu WHERE time NOT IN ('2015-08-18 09:48:08+09','2016-08-28 07:44:00+07'); - time | tags | fields -------------------------+--------------------------------------+----------------------------------------------------------------------- - 2015-08-18 09:00:00+09 | {"tag1": "tag1_A", "tag2": "tag2_A"} | {"value1": "100", "value2": "0.5", "value3": "str", "value4": "true"} - 2015-08-18 09:00:00+09 | {"tag1": "tag1_B", "tag2": null} | {"value1": "100", "value2": "2", "value3": null, "value4": "false"} -(2 rows) - ---Testcase 56: -SELECT * FROM cpu WHERE (fields->>'value1')::int NOT IN (100, 97); - time | tags | fields -------+------+-------- -(0 rows) - ---Testcase 57: -SELECT * FROM cpu WHERE (fields->>'value1')::int IN (100, 97); - time | tags | fields -------------------------+--------------------------------------+----------------------------------------------------------------------- - 2015-08-18 09:00:00+09 | {"tag1": "tag1_A", "tag2": "tag2_A"} | {"value1": "100", "value2": "0.5", "value3": "str", "value4": "true"} - 2015-08-18 09:00:00+09 | {"tag1": "tag1_B", "tag2": null} | {"value1": "100", "value2": "2", "value3": null, "value4": "false"} -(2 rows) - ---Testcase 58: -SELECT * FROM cpu WHERE (fields->>'value2')::double precision IN (0.5, 10.9); - time | tags | fields -------------------------+--------------------------------------+----------------------------------------------------------------------- - 2015-08-18 09:00:00+09 | {"tag1": "tag1_A", "tag2": "tag2_A"} | {"value1": "100", "value2": "0.5", "value3": "str", "value4": "true"} -(1 row) - ---Testcase 59: -SELECT * FROM cpu WHERE (fields->>'value2')::double precision NOT IN (2, 9.7); - time | tags | fields -------------------------+--------------------------------------+----------------------------------------------------------------------- - 2015-08-18 09:00:00+09 | {"tag1": "tag1_A", "tag2": "tag2_A"} | {"value1": "100", "value2": "0.5", "value3": "str", "value4": "true"} -(1 row) - ---Testcase 60: -SELECT * FROM cpu WHERE (fields->>'value4')::boolean NOT IN ('true', 'true'); - time | tags | fields -------------------------+----------------------------------+--------------------------------------------------------------------- - 2015-08-18 09:00:00+09 | {"tag1": "tag1_B", "tag2": null} | {"value1": "100", "value2": "2", "value3": null, "value4": "false"} -(1 row) - ---Testcase 61: -SELECT * FROM cpu WHERE (fields->>'value4')::boolean IN ('f', 't'); - time | tags | fields -------------------------+--------------------------------------+----------------------------------------------------------------------- - 2015-08-18 09:00:00+09 | {"tag1": "tag1_A", "tag2": "tag2_A"} | {"value1": "100", "value2": "0.5", "value3": "str", "value4": "true"} - 2015-08-18 09:00:00+09 | {"tag1": "tag1_B", "tag2": null} | {"value1": "100", "value2": "2", "value3": null, "value4": "false"} -(2 rows) - ---Testcase 62: -CREATE FOREIGN TABLE t1(time timestamp with time zone ,tags jsonb OPTIONS(tags 'true'), fields jsonb OPTIONS (fields 'true')) SERVER server1 OPTIONS (table 'cpu', schemaless 'true', tags 'tag1'); ---Testcase 63: -CREATE FOREIGN TABLE t2(time timestamp ,tags jsonb OPTIONS(tags 'true'), fields jsonb OPTIONS (fields 'true')) SERVER server1 OPTIONS (table 'cpu', schemaless 'true', tags 'tag1'); ---Testcase 64: -SELECT * FROM t1; - time | tags | fields -------------------------+--------------------+----------------------------------------------------------------------------------------- - 2015-08-18 09:00:00+09 | {"tag1": "tag1_A"} | {"tag2": "tag2_A", "value1": "100", "value2": "0.5", "value3": "str", "value4": "true"} - 2015-08-18 09:00:00+09 | {"tag1": "tag1_B"} | {"tag2": null, "value1": "100", "value2": "2", "value3": null, "value4": "false"} - 2015-08-18 09:48:08+09 | {"tag1": null} | {"tag2": "tag2_A", "value1": null, "value2": "2", "value3": null, "value4": null} -(3 rows) - ---Testcase 65: -SELECT * FROM t2; - time | tags | fields ----------------------+--------------------+----------------------------------------------------------------------------------------- - 2015-08-18 00:00:00 | {"tag1": "tag1_A"} | {"tag2": "tag2_A", "value1": "100", "value2": "0.5", "value3": "str", "value4": "true"} - 2015-08-18 00:00:00 | {"tag1": "tag1_B"} | {"tag2": null, "value1": "100", "value2": "2", "value3": null, "value4": "false"} - 2015-08-18 00:48:08 | {"tag1": null} | {"tag2": "tag2_A", "value1": null, "value2": "2", "value3": null, "value4": null} -(3 rows) - --- In following four queries, timestamp condition is added to InfluxQL as "time = '2015-08-18 00:00:00'" ---Testcase 66: -SELECT * FROM t1 WHERE time = TIMESTAMP WITH TIME ZONE '2015-08-18 09:00:00+09'; - time | tags | fields -------------------------+--------------------+----------------------------------------------------------------------------------------- - 2015-08-18 09:00:00+09 | {"tag1": "tag1_A"} | {"tag2": "tag2_A", "value1": "100", "value2": "0.5", "value3": "str", "value4": "true"} - 2015-08-18 09:00:00+09 | {"tag1": "tag1_B"} | {"tag2": null, "value1": "100", "value2": "2", "value3": null, "value4": "false"} -(2 rows) - ---Testcase 67: -SELECT * FROM t1 WHERE time = TIMESTAMP '2015-08-18 00:00:00'; - time | tags | fields -------------------------+--------------------+----------------------------------------------------------------------------------------- - 2015-08-18 09:00:00+09 | {"tag1": "tag1_A"} | {"tag2": "tag2_A", "value1": "100", "value2": "0.5", "value3": "str", "value4": "true"} - 2015-08-18 09:00:00+09 | {"tag1": "tag1_B"} | {"tag2": null, "value1": "100", "value2": "2", "value3": null, "value4": "false"} -(2 rows) - ---Testcase 68: -SELECT * FROM t2 WHERE time = TIMESTAMP WITH TIME ZONE '2015-08-18 09:00:00+09'; - time | tags | fields ----------------------+--------------------+----------------------------------------------------------------------------------------- - 2015-08-18 00:00:00 | {"tag1": "tag1_A"} | {"tag2": "tag2_A", "value1": "100", "value2": "0.5", "value3": "str", "value4": "true"} - 2015-08-18 00:00:00 | {"tag1": "tag1_B"} | {"tag2": null, "value1": "100", "value2": "2", "value3": null, "value4": "false"} -(2 rows) - ---Testcase 69: -SELECT * FROM t2 WHERE time = TIMESTAMP '2015-08-18 00:00:00'; - time | tags | fields ----------------------+--------------------+----------------------------------------------------------------------------------------- - 2015-08-18 00:00:00 | {"tag1": "tag1_A"} | {"tag2": "tag2_A", "value1": "100", "value2": "0.5", "value3": "str", "value4": "true"} - 2015-08-18 00:00:00 | {"tag1": "tag1_B"} | {"tag2": null, "value1": "100", "value2": "2", "value3": null, "value4": "false"} -(2 rows) - --- pushdown now() ---Testcase 70: -SELECT * FROM t2 WHERE now() > time; - time | tags | fields ----------------------+--------------------+----------------------------------------------------------------------------------------- - 2015-08-18 00:00:00 | {"tag1": "tag1_A"} | {"tag2": "tag2_A", "value1": "100", "value2": "0.5", "value3": "str", "value4": "true"} - 2015-08-18 00:00:00 | {"tag1": "tag1_B"} | {"tag2": null, "value1": "100", "value2": "2", "value3": null, "value4": "false"} - 2015-08-18 00:48:08 | {"tag1": null} | {"tag2": "tag2_A", "value1": null, "value2": "2", "value3": null, "value4": null} -(3 rows) - ---Testcase 71: -EXPLAIN VERBOSE -SELECT * FROM t2 WHERE now() > time; - QUERY PLAN -------------------------------------------------------------------- - Foreign Scan on public.t2 (cost=10.00..284.00 rows=284 width=72) - Output: "time", tags, fields - InfluxDB query: SELECT * FROM "cpu" WHERE ((now() > time)) -(3 rows) - ---Testcase 72: -SELECT * FROM t2 WHERE time = TIMESTAMP WITH TIME ZONE '2015-08-26 05:43:21.1+00' - interval '1 week 1 day 5 hour 43 minute 21 second 100 millisecond'; - time | tags | fields ----------------------+--------------------+----------------------------------------------------------------------------------------- - 2015-08-18 00:00:00 | {"tag1": "tag1_A"} | {"tag2": "tag2_A", "value1": "100", "value2": "0.5", "value3": "str", "value4": "true"} - 2015-08-18 00:00:00 | {"tag1": "tag1_B"} | {"tag2": null, "value1": "100", "value2": "2", "value3": null, "value4": "false"} -(2 rows) - ---Testcase 73: -EXPLAIN VERBOSE -SELECT * FROM t2 WHERE time = TIMESTAMP WITH TIME ZONE '2015-08-26 05:43:21.1+00' - interval '1 week 1 day 5 hour 43 minute 21 second 100 millisecond'; - QUERY PLAN ------------------------------------------------------------------------------------------------------- - Foreign Scan on public.t2 (cost=10.00..4.00 rows=4 width=72) - Output: "time", tags, fields - InfluxDB query: SELECT * FROM "cpu" WHERE ((time = ('2015-08-26 05:43:21.1' - 8d5h43m21s100000u))) -(3 rows) - --- InfluxDB does not seem to support time column + interval, so below query returns empty result --- SELECT * FROM t2 WHERE time + interval '1 week 1 day 5 hour 43 minute 21 second 100 millisecond' = TIMESTAMP WITH TIME ZONE '2015-08-26 05:43:21.1+00'; --- EXPLAIN (VERBOSE, COSTS OFF) --- SELECT * FROM t2 WHERE time + interval '1 week 1 day 5 hour 43 minute 21 second 100 millisecond' = TIMESTAMP WITH TIME ZONE '2015-08-26 05:43:21.1+00'; --- InfluxDB does not support month or year interval, so not push down ---Testcase 74: -SELECT * FROM t2 WHERE time = TIMESTAMP '2015-09-18 00:00:00' - interval '1 months'; - time | tags | fields ----------------------+--------------------+----------------------------------------------------------------------------------------- - 2015-08-18 00:00:00 | {"tag1": "tag1_A"} | {"tag2": "tag2_A", "value1": "100", "value2": "0.5", "value3": "str", "value4": "true"} - 2015-08-18 00:00:00 | {"tag1": "tag1_B"} | {"tag2": null, "value1": "100", "value2": "2", "value3": null, "value4": "false"} -(2 rows) - ---Testcase 75: -EXPLAIN VERBOSE -SELECT * FROM t2 WHERE time = TIMESTAMP '2015-09-18 00:00:00' - interval '1 months'; - QUERY PLAN ------------------------------------------------------------------------------- - Foreign Scan on public.t2 (cost=10.00..4.00 rows=4 width=72) - Output: "time", tags, fields - InfluxDB query: SELECT * FROM "cpu" WHERE ((time = '2015-08-18 00:00:00')) -(3 rows) - ---Testcase 76: -SELECT * FROM t2 WHERE (fields->>'value1')::int = ANY (ARRAY(SELECT (fields->>'value1')::int FROM t1 WHERE (fields->>'value1')::int < 1000)); - time | tags | fields ----------------------+--------------------+----------------------------------------------------------------------------------------- - 2015-08-18 00:00:00 | {"tag1": "tag1_A"} | {"tag2": "tag2_A", "value1": "100", "value2": "0.5", "value3": "str", "value4": "true"} - 2015-08-18 00:00:00 | {"tag1": "tag1_B"} | {"tag2": null, "value1": "100", "value2": "2", "value3": null, "value4": "false"} -(2 rows) - --- ANY with ARRAY expression ---Testcase 77: -EXPLAIN VERBOSE -SELECT (fields->>'a')::int a, fields->>'b' b FROM numbers WHERE (fields->>'a')::int = ANY(ARRAY[1, (fields->>'a')::int + 1]); - QUERY PLAN ------------------------------------------------------------------------------------------ - Foreign Scan on public.numbers (cost=10.00..15.15 rows=15 width=36) - Output: ((fields ->> 'a'::text))::integer, (fields ->> 'b'::text) - InfluxDB query: SELECT "a", "b" FROM "numbers" WHERE (("a" = 1) OR ("a" = ("a" + 1))) -(3 rows) - ---Testcase 78: -SELECT (fields->>'a')::int a, fields->>'b' b FROM numbers WHERE (fields->>'a')::int = ANY(ARRAY[1, (fields->>'a')::int + 1]); - a | b ----+----- - 1 | One -(1 row) - ---Testcase 79: -EXPLAIN VERBOSE -SELECT (fields->>'a')::int a, fields->>'b' b FROM numbers WHERE (fields->>'a')::int <> ANY(ARRAY[1, (fields->>'a')::int + 1]); - QUERY PLAN -------------------------------------------------------------------------------------------- - Foreign Scan on public.numbers (cost=10.00..1476.62 rows=1462 width=36) - Output: ((fields ->> 'a'::text))::integer, (fields ->> 'b'::text) - InfluxDB query: SELECT "a", "b" FROM "numbers" WHERE (("a" <> 1) OR ("a" <> ("a" + 1))) -(3 rows) - ---Testcase 80: -SELECT (fields->>'a')::int a, fields->>'b' b FROM numbers WHERE (fields->>'a')::int <> ANY(ARRAY[1, (fields->>'a')::int + 1]); - a | b ----+----- - 1 | One - 2 | Two -(2 rows) - ---Testcase 81: -EXPLAIN VERBOSE -SELECT (fields->>'a')::int a, fields->>'b' b FROM numbers WHERE (fields->>'a')::int >= ANY(ARRAY[1, (fields->>'a')::int + 1]); - QUERY PLAN -------------------------------------------------------------------------------------------- - Foreign Scan on public.numbers (cost=10.00..820.12 rows=812 width=36) - Output: ((fields ->> 'a'::text))::integer, (fields ->> 'b'::text) - InfluxDB query: SELECT "a", "b" FROM "numbers" WHERE (("a" >= 1) OR ("a" >= ("a" + 1))) -(3 rows) - ---Testcase 82: -SELECT (fields->>'a')::int a, fields->>'b' b FROM numbers WHERE (fields->>'a')::int >= ANY(ARRAY[1, (fields->>'a')::int + 1]); - a | b ----+----- - 1 | One - 2 | Two -(2 rows) - ---Testcase 83: -EXPLAIN VERBOSE -SELECT (fields->>'a')::int a, fields->>'b' b FROM numbers WHERE (fields->>'a')::int <= ANY(ARRAY[1, (fields->>'a')::int + 1]); - QUERY PLAN -------------------------------------------------------------------------------------------- - Foreign Scan on public.numbers (cost=10.00..820.12 rows=812 width=36) - Output: ((fields ->> 'a'::text))::integer, (fields ->> 'b'::text) - InfluxDB query: SELECT "a", "b" FROM "numbers" WHERE (("a" <= 1) OR ("a" <= ("a" + 1))) -(3 rows) - ---Testcase 84: -SELECT (fields->>'a')::int a, fields->>'b' b FROM numbers WHERE (fields->>'a')::int <= ANY(ARRAY[1, (fields->>'a')::int + 1]); - a | b ----+----- - 1 | One - 2 | Two -(2 rows) - ---Testcase 85: -EXPLAIN VERBOSE -SELECT (fields->>'a')::int a, fields->>'b' b FROM numbers WHERE (fields->>'a')::int > ANY(ARRAY[1, (fields->>'a')::int + 1]); - QUERY PLAN ------------------------------------------------------------------------------------------ - Foreign Scan on public.numbers (cost=10.00..820.12 rows=812 width=36) - Output: ((fields ->> 'a'::text))::integer, (fields ->> 'b'::text) - InfluxDB query: SELECT "a", "b" FROM "numbers" WHERE (("a" > 1) OR ("a" > ("a" + 1))) -(3 rows) - ---Testcase 86: -SELECT (fields->>'a')::int a, fields->>'b' b FROM numbers WHERE (fields->>'a')::int > ANY(ARRAY[1, (fields->>'a')::int + 1]); - a | b ----+----- - 2 | Two -(1 row) - ---Testcase 87: -EXPLAIN VERBOSE -SELECT (fields->>'a')::int a, fields->>'b' b FROM numbers WHERE (fields->>'a')::int < ANY(ARRAY[1, (fields->>'a')::int + 1]); - QUERY PLAN ------------------------------------------------------------------------------------------ - Foreign Scan on public.numbers (cost=10.00..820.12 rows=812 width=36) - Output: ((fields ->> 'a'::text))::integer, (fields ->> 'b'::text) - InfluxDB query: SELECT "a", "b" FROM "numbers" WHERE (("a" < 1) OR ("a" < ("a" + 1))) -(3 rows) - ---Testcase 88: -SELECT (fields->>'a')::int a, fields->>'b' b FROM numbers WHERE (fields->>'a')::int < ANY(ARRAY[1, (fields->>'a')::int + 1]); - a | b ----+----- - 1 | One - 2 | Two -(2 rows) - --- ANY with ARRAY const ---Testcase 89: -EXPLAIN VERBOSE -SELECT (fields->>'a')::int a, fields->>'b' b FROM numbers WHERE (fields->>'a')::int = ANY(ARRAY[1, 2]); - QUERY PLAN ------------------------------------------------------------------------------ - Foreign Scan on public.numbers (cost=10.00..15.15 rows=15 width=36) - Output: ((fields ->> 'a'::text))::integer, (fields ->> 'b'::text) - InfluxDB query: SELECT "a", "b" FROM "numbers" WHERE ("a" = 1 OR "a" = 2) -(3 rows) - ---Testcase 90: -SELECT (fields->>'a')::int a, fields->>'b' b FROM numbers WHERE (fields->>'a')::int = ANY(ARRAY[1, 2]); - a | b ----+----- - 1 | One - 2 | Two -(2 rows) - ---Testcase 91: -EXPLAIN VERBOSE -SELECT (fields->>'a')::int a, fields->>'b' b FROM numbers WHERE (fields->>'a')::int <> ANY(ARRAY[1, 2]); - QUERY PLAN -------------------------------------------------------------------------------- - Foreign Scan on public.numbers (cost=10.00..1476.62 rows=1462 width=36) - Output: ((fields ->> 'a'::text))::integer, (fields ->> 'b'::text) - InfluxDB query: SELECT "a", "b" FROM "numbers" WHERE ("a" <> 1 OR "a" <> 2) -(3 rows) - ---Testcase 92: -SELECT (fields->>'a')::int a, fields->>'b' b FROM numbers WHERE (fields->>'a')::int <> ANY(ARRAY[1, 2]); - a | b ----+----- - 1 | One - 2 | Two -(2 rows) - ---Testcase 93: -EXPLAIN VERBOSE -SELECT (fields->>'a')::int a, fields->>'b' b FROM numbers WHERE (fields->>'a')::int >= ANY(ARRAY[1, 2]); - QUERY PLAN -------------------------------------------------------------------------------- - Foreign Scan on public.numbers (cost=10.00..820.12 rows=812 width=36) - Output: ((fields ->> 'a'::text))::integer, (fields ->> 'b'::text) - InfluxDB query: SELECT "a", "b" FROM "numbers" WHERE ("a" >= 1 OR "a" >= 2) -(3 rows) - ---Testcase 94: -SELECT (fields->>'a')::int a, fields->>'b' b FROM numbers WHERE (fields->>'a')::int >= ANY(ARRAY[1, 2]); - a | b ----+----- - 1 | One - 2 | Two -(2 rows) - ---Testcase 95: -EXPLAIN VERBOSE -SELECT (fields->>'a')::int a, fields->>'b' b FROM numbers WHERE (fields->>'a')::int <= ANY(ARRAY[1, 2]); - QUERY PLAN -------------------------------------------------------------------------------- - Foreign Scan on public.numbers (cost=10.00..820.12 rows=812 width=36) - Output: ((fields ->> 'a'::text))::integer, (fields ->> 'b'::text) - InfluxDB query: SELECT "a", "b" FROM "numbers" WHERE ("a" <= 1 OR "a" <= 2) -(3 rows) - ---Testcase 96: -SELECT (fields->>'a')::int a, fields->>'b' b FROM numbers WHERE (fields->>'a')::int <= ANY(ARRAY[1, 2]); - a | b ----+----- - 1 | One - 2 | Two -(2 rows) - ---Testcase 97: -EXPLAIN VERBOSE -SELECT (fields->>'a')::int a, fields->>'b' b FROM numbers WHERE (fields->>'a')::int > ANY(ARRAY[1, 2]); - QUERY PLAN ------------------------------------------------------------------------------ - Foreign Scan on public.numbers (cost=10.00..820.12 rows=812 width=36) - Output: ((fields ->> 'a'::text))::integer, (fields ->> 'b'::text) - InfluxDB query: SELECT "a", "b" FROM "numbers" WHERE ("a" > 1 OR "a" > 2) -(3 rows) - ---Testcase 98: -SELECT (fields->>'a')::int a, fields->>'b' b FROM numbers WHERE (fields->>'a')::int > ANY(ARRAY[1, 2]); - a | b ----+----- - 2 | Two -(1 row) - ---Testcase 99: -EXPLAIN VERBOSE -SELECT (fields->>'a')::int a, fields->>'b' b FROM numbers WHERE (fields->>'a')::int < ANY(ARRAY[1, 2]); - QUERY PLAN ------------------------------------------------------------------------------ - Foreign Scan on public.numbers (cost=10.00..820.12 rows=812 width=36) - Output: ((fields ->> 'a'::text))::integer, (fields ->> 'b'::text) - InfluxDB query: SELECT "a", "b" FROM "numbers" WHERE ("a" < 1 OR "a" < 2) -(3 rows) - ---Testcase 100: -SELECT (fields->>'a')::int a, fields->>'b' b FROM numbers WHERE (fields->>'a')::int < ANY(ARRAY[1, 2]); - a | b ----+----- - 1 | One -(1 row) - ---Testcase 101: -EXPLAIN VERBOSE -SELECT (fields->>'a')::int a, fields->>'b' b FROM numbers WHERE (fields->>'a')::int = ANY('{1, 2, 3}'); - QUERY PLAN ----------------------------------------------------------------------------------------- - Foreign Scan on public.numbers (cost=10.00..22.22 rows=22 width=36) - Output: ((fields ->> 'a'::text))::integer, (fields ->> 'b'::text) - InfluxDB query: SELECT "a", "b" FROM "numbers" WHERE ("a" = 1 OR "a" = 2 OR "a" = 3) -(3 rows) - ---Testcase 102: -SELECT (fields->>'a')::int a, fields->>'b' b FROM numbers WHERE (fields->>'a')::int = ANY('{1, 2, 3}'); - a | b ----+----- - 1 | One - 2 | Two -(2 rows) - ---Testcase 103: -EXPLAIN VERBOSE -SELECT (fields->>'a')::int a, fields->>'b' b FROM numbers WHERE (fields->>'a')::int <> ANY('{1, 2, 3}'); - QUERY PLAN -------------------------------------------------------------------------------------------- - Foreign Scan on public.numbers (cost=10.00..1476.62 rows=1462 width=36) - Output: ((fields ->> 'a'::text))::integer, (fields ->> 'b'::text) - InfluxDB query: SELECT "a", "b" FROM "numbers" WHERE ("a" <> 1 OR "a" <> 2 OR "a" <> 3) -(3 rows) - ---Testcase 104: -SELECT (fields->>'a')::int a, fields->>'b' b FROM numbers WHERE (fields->>'a')::int <> ANY('{1, 2, 3}'); - a | b ----+----- - 1 | One - 2 | Two -(2 rows) - --- ALL with ARRAY expression ---Testcase 105: -EXPLAIN VERBOSE -SELECT (fields->>'a')::int a, fields->>'b' b FROM numbers WHERE (fields->>'a')::int = ALL(ARRAY[1, (fields->>'a')::int * 1]); - QUERY PLAN ------------------------------------------------------------------------------------------- - Foreign Scan on public.numbers (cost=10.00..1.01 rows=1 width=36) - Output: ((fields ->> 'a'::text))::integer, (fields ->> 'b'::text) - InfluxDB query: SELECT "a", "b" FROM "numbers" WHERE (("a" = 1) AND ("a" = ("a" * 1))) -(3 rows) - ---Testcase 106: -SELECT (fields->>'a')::int a, fields->>'b' b FROM numbers WHERE (fields->>'a')::int = ALL(ARRAY[1, (fields->>'a')::int * 1]); - a | b ----+----- - 1 | One -(1 row) - ---Testcase 107: -EXPLAIN VERBOSE -SELECT (fields->>'a')::int a, fields->>'b' b FROM numbers WHERE (fields->>'a')::int <> ALL(ARRAY[1, (fields->>'a')::int + 1]); - QUERY PLAN --------------------------------------------------------------------------------------------- - Foreign Scan on public.numbers (cost=10.00..1461.47 rows=1447 width=36) - Output: ((fields ->> 'a'::text))::integer, (fields ->> 'b'::text) - InfluxDB query: SELECT "a", "b" FROM "numbers" WHERE (("a" <> 1) AND ("a" <> ("a" + 1))) -(3 rows) - ---Testcase 108: -SELECT (fields->>'a')::int a, fields->>'b' b FROM numbers WHERE (fields->>'a')::int <> ALL(ARRAY[1, (fields->>'a')::int + 1]); - a | b ----+----- - 2 | Two -(1 row) - ---Testcase 109: -EXPLAIN VERBOSE -SELECT (fields->>'a')::int a, fields->>'b' b FROM numbers WHERE (fields->>'a')::int >= ALL(ARRAY[1, (fields->>'a')::int / 1]); - QUERY PLAN --------------------------------------------------------------------------------------------- - Foreign Scan on public.numbers (cost=10.00..163.62 rows=162 width=36) - Output: ((fields ->> 'a'::text))::integer, (fields ->> 'b'::text) - InfluxDB query: SELECT "a", "b" FROM "numbers" WHERE (("a" >= 1) AND ("a" >= ("a" / 1))) -(3 rows) - ---Testcase 110: -SELECT (fields->>'a')::int a, fields->>'b' b FROM numbers WHERE (fields->>'a')::int >= ALL(ARRAY[1, (fields->>'a')::int / 1]); - a | b ----+----- - 1 | One - 2 | Two -(2 rows) - ---Testcase 111: -EXPLAIN VERBOSE -SELECT (fields->>'a')::int a, fields->>'b' b FROM numbers WHERE (fields->>'a')::int <= ALL(ARRAY[1, (fields->>'a')::int + 1]); - QUERY PLAN --------------------------------------------------------------------------------------------- - Foreign Scan on public.numbers (cost=10.00..163.62 rows=162 width=36) - Output: ((fields ->> 'a'::text))::integer, (fields ->> 'b'::text) - InfluxDB query: SELECT "a", "b" FROM "numbers" WHERE (("a" <= 1) AND ("a" <= ("a" + 1))) -(3 rows) - ---Testcase 112: -SELECT (fields->>'a')::int a, fields->>'b' b FROM numbers WHERE (fields->>'a')::int <= ALL(ARRAY[1, (fields->>'a')::int + 1]); - a | b ----+----- - 1 | One -(1 row) - ---Testcase 113: -EXPLAIN VERBOSE -SELECT (fields->>'a')::int a, fields->>'b' b FROM numbers WHERE (fields->>'a')::int > ALL(ARRAY[1, (fields->>'a')::int - 1]); - QUERY PLAN ------------------------------------------------------------------------------------------- - Foreign Scan on public.numbers (cost=10.00..163.62 rows=162 width=36) - Output: ((fields ->> 'a'::text))::integer, (fields ->> 'b'::text) - InfluxDB query: SELECT "a", "b" FROM "numbers" WHERE (("a" > 1) AND ("a" > ("a" - 1))) -(3 rows) - ---Testcase 114: -SELECT (fields->>'a')::int a, fields->>'b' b FROM numbers WHERE (fields->>'a')::int > ALL(ARRAY[1, (fields->>'a')::int - 1]); - a | b ----+----- - 2 | Two -(1 row) - ---Testcase 115: -EXPLAIN VERBOSE -SELECT (fields->>'a')::int a, fields->>'b' b FROM numbers WHERE (fields->>'a')::int < ALL(ARRAY[2, (fields->>'a')::int + 1]); - QUERY PLAN ------------------------------------------------------------------------------------------- - Foreign Scan on public.numbers (cost=10.00..163.62 rows=162 width=36) - Output: ((fields ->> 'a'::text))::integer, (fields ->> 'b'::text) - InfluxDB query: SELECT "a", "b" FROM "numbers" WHERE (("a" < 2) AND ("a" < ("a" + 1))) -(3 rows) - ---Testcase 116: -SELECT (fields->>'a')::int a, fields->>'b' b FROM numbers WHERE (fields->>'a')::int < ALL(ARRAY[2, (fields->>'a')::int + 1]); - a | b ----+----- - 1 | One -(1 row) - --- ALL with ARRAY const ---Testcase 117: -EXPLAIN VERBOSE -SELECT (fields->>'a')::int a, fields->>'b' b FROM numbers WHERE (fields->>'a')::int = ALL(ARRAY[1, 1]); - QUERY PLAN ------------------------------------------------------------------------------- - Foreign Scan on public.numbers (cost=10.00..1.01 rows=1 width=36) - Output: ((fields ->> 'a'::text))::integer, (fields ->> 'b'::text) - InfluxDB query: SELECT "a", "b" FROM "numbers" WHERE ("a" = 1 AND "a" = 1) -(3 rows) - ---Testcase 118: -SELECT (fields->>'a')::int a, fields->>'b' b FROM numbers WHERE (fields->>'a')::int = ALL(ARRAY[1, 1]); - a | b ----+----- - 1 | One -(1 row) - ---Testcase 119: -EXPLAIN VERBOSE -SELECT (fields->>'a')::int a, fields->>'b' b FROM numbers WHERE (fields->>'a')::int <> ALL(ARRAY[1, 3]); - QUERY PLAN --------------------------------------------------------------------------------- - Foreign Scan on public.numbers (cost=10.00..1461.47 rows=1447 width=36) - Output: ((fields ->> 'a'::text))::integer, (fields ->> 'b'::text) - InfluxDB query: SELECT "a", "b" FROM "numbers" WHERE ("a" <> 1 AND "a" <> 3) -(3 rows) - ---Testcase 120: -SELECT (fields->>'a')::int a, fields->>'b' b FROM numbers WHERE (fields->>'a')::int <> ALL(ARRAY[1, 3]); - a | b ----+----- - 2 | Two -(1 row) - ---Testcase 121: -EXPLAIN VERBOSE -SELECT (fields->>'a')::int a, fields->>'b' b FROM numbers WHERE (fields->>'a')::int >= ALL(ARRAY[1, 2]); - QUERY PLAN --------------------------------------------------------------------------------- - Foreign Scan on public.numbers (cost=10.00..163.62 rows=162 width=36) - Output: ((fields ->> 'a'::text))::integer, (fields ->> 'b'::text) - InfluxDB query: SELECT "a", "b" FROM "numbers" WHERE ("a" >= 1 AND "a" >= 2) -(3 rows) - ---Testcase 122: -SELECT (fields->>'a')::int a, fields->>'b' b FROM numbers WHERE (fields->>'a')::int >= ALL(ARRAY[1, 2]); - a | b ----+----- - 2 | Two -(1 row) - ---Testcase 123: -EXPLAIN VERBOSE -SELECT (fields->>'a')::int a, fields->>'b' b FROM numbers WHERE (fields->>'a')::int <= ALL(ARRAY[1, 2]); - QUERY PLAN --------------------------------------------------------------------------------- - Foreign Scan on public.numbers (cost=10.00..163.62 rows=162 width=36) - Output: ((fields ->> 'a'::text))::integer, (fields ->> 'b'::text) - InfluxDB query: SELECT "a", "b" FROM "numbers" WHERE ("a" <= 1 AND "a" <= 2) -(3 rows) - ---Testcase 124: -SELECT (fields->>'a')::int a, fields->>'b' b FROM numbers WHERE (fields->>'a')::int <= ALL(ARRAY[1, 2]); - a | b ----+----- - 1 | One -(1 row) - ---Testcase 125: -EXPLAIN VERBOSE -SELECT (fields->>'a')::int a, fields->>'b' b FROM numbers WHERE (fields->>'a')::int > ALL(ARRAY[0, 1]); - QUERY PLAN ------------------------------------------------------------------------------- - Foreign Scan on public.numbers (cost=10.00..163.62 rows=162 width=36) - Output: ((fields ->> 'a'::text))::integer, (fields ->> 'b'::text) - InfluxDB query: SELECT "a", "b" FROM "numbers" WHERE ("a" > 0 AND "a" > 1) -(3 rows) - ---Testcase 126: -SELECT (fields->>'a')::int a, fields->>'b' b FROM numbers WHERE (fields->>'a')::int > ALL(ARRAY[0, 1]); - a | b ----+----- - 2 | Two -(1 row) - ---Testcase 127: -EXPLAIN VERBOSE -SELECT (fields->>'a')::int a, fields->>'b' b FROM numbers WHERE (fields->>'a')::int < ALL(ARRAY[2, 3]); - QUERY PLAN ------------------------------------------------------------------------------- - Foreign Scan on public.numbers (cost=10.00..163.62 rows=162 width=36) - Output: ((fields ->> 'a'::text))::integer, (fields ->> 'b'::text) - InfluxDB query: SELECT "a", "b" FROM "numbers" WHERE ("a" < 2 AND "a" < 3) -(3 rows) - ---Testcase 128: -SELECT (fields->>'a')::int a, fields->>'b' b FROM numbers WHERE (fields->>'a')::int < ALL(ARRAY[2, 3]); - a | b ----+----- - 1 | One -(1 row) - --- ANY/ALL with TEXT ARRAY const ---Testcase 129: -EXPLAIN VERBOSE -SELECT (fields->>'a')::int a, fields->>'b' b FROM numbers WHERE fields->>'b' = ANY(ARRAY['One', 'Two']); - QUERY PLAN -------------------------------------------------------------------------------------- - Foreign Scan on public.numbers (cost=10.00..15.15 rows=15 width=36) - Output: ((fields ->> 'a'::text))::integer, (fields ->> 'b'::text) - InfluxDB query: SELECT "a", "b" FROM "numbers" WHERE ("b" = 'One' OR "b" = 'Two') -(3 rows) - ---Testcase 130: -SELECT (fields->>'a')::int a, fields->>'b' b FROM numbers WHERE fields->>'b' = ANY(ARRAY['One', 'Two']); - a | b ----+----- - 1 | One - 2 | Two -(2 rows) - ---Testcase 131: -EXPLAIN VERBOSE -SELECT (fields->>'a')::int a, fields->>'b' b FROM numbers WHERE fields->>'b' <> ALL(ARRAY['One', 'Four']); - QUERY PLAN ------------------------------------------------------------------------------------------ - Foreign Scan on public.numbers (cost=10.00..1461.47 rows=1447 width=36) - Output: ((fields ->> 'a'::text))::integer, (fields ->> 'b'::text) - InfluxDB query: SELECT "a", "b" FROM "numbers" WHERE ("b" <> 'One' AND "b" <> 'Four') -(3 rows) - ---Testcase 132: -SELECT (fields->>'a')::int a, fields->>'b' b FROM numbers WHERE fields->>'b' <> ALL(ARRAY['One', 'Four']); - a | b ----+----- - 2 | Two -(1 row) - ---Testcase 133: -EXPLAIN VERBOSE -SELECT (fields->>'a')::int a, fields->>'b' b FROM numbers WHERE fields->>'b' > ANY(ARRAY['One', 'Two']); - QUERY PLAN ------------------------------------------------------------------------- - Foreign Scan on public.numbers (cost=10.00..820.12 rows=812 width=36) - Output: ((fields ->> 'a'::text))::integer, (fields ->> 'b'::text) - Filter: ((numbers.fields ->> 'b'::text) > ANY ('{One,Two}'::text[])) - InfluxDB query: SELECT "a", "b" FROM "numbers" -(4 rows) - ---Testcase 134: -SELECT (fields->>'a')::int a, fields->>'b' b FROM numbers WHERE fields->>'b' > ANY(ARRAY['One', 'Two']); - a | b ----+----- - 2 | Two -(1 row) - ---Testcase 135: -EXPLAIN VERBOSE -SELECT * FROM numbers WHERE fields->>'b' > ALL(ARRAY['Four', 'Five']); - QUERY PLAN --------------------------------------------------------------------------- - Foreign Scan on public.numbers (cost=10.00..95.00 rows=95 width=72) - Output: "time", tags, fields - Filter: ((numbers.fields ->> 'b'::text) > ALL ('{Four,Five}'::text[])) - InfluxDB query: SELECT * FROM "numbers" -(4 rows) - ---Testcase 136: -SELECT (fields->>'a')::int a, fields->>'b' b FROM numbers WHERE fields->>'b' > ALL(ARRAY['Four', 'Five']); - a | b ----+----- - 1 | One - 2 | Two -(2 rows) - ---Testcase 137: -DROP FOREIGN TABLE numbers; ---Testcase 138: -ALTER SERVER server1 OPTIONS (SET dbname 'no such database'); ---Testcase 139: -SELECT * FROM t1; -ERROR: influxdb_fdw : database not found: no such database ---Testcase 140: -ALTER SERVER server1 OPTIONS (SET dbname 'mydb'); ---Testcase 141: -SELECT * FROM t1; - time | tags | fields -------------------------+--------------------+----------------------------------------------------------------------------------------- - 2015-08-18 09:00:00+09 | {"tag1": "tag1_A"} | {"tag2": "tag2_A", "value1": "100", "value2": "0.5", "value3": "str", "value4": "true"} - 2015-08-18 09:00:00+09 | {"tag1": "tag1_B"} | {"tag2": null, "value1": "100", "value2": "2", "value3": null, "value4": "false"} - 2015-08-18 09:48:08+09 | {"tag1": null} | {"tag2": "tag2_A", "value1": null, "value2": "2", "value3": null, "value4": null} -(3 rows) - --- map time column to both timestamp and text ---Testcase 142: -CREATE FOREIGN TABLE t5(t timestamp OPTIONS (column_name 'time'), tag1 text OPTIONS (column_name 'time'), fields jsonb OPTIONS (fields 'true')) SERVER server1 OPTIONS (table 'cpu', schemaless 'true'); ---Testcase 143: -SELECT * FROM t5; - t | tag1 | fields ----------------------+----------------------+----------------------------------------------------------------------------------------------------------- - 2015-08-18 00:00:00 | 2015-08-18T00:00:00Z | {"tag1": "tag1_A", "tag2": "tag2_A", "value1": "100", "value2": "0.5", "value3": "str", "value4": "true"} - 2015-08-18 00:00:00 | 2015-08-18T00:00:00Z | {"tag1": "tag1_B", "tag2": null, "value1": "100", "value2": "2", "value3": null, "value4": "false"} - 2015-08-18 00:48:08 | 2015-08-18T00:48:08Z | {"tag1": null, "tag2": "tag2_A", "value1": null, "value2": "2", "value3": null, "value4": null} -(3 rows) - ---get version ---Testcase 144: -\df influxdb_fdw* - List of functions - Schema | Name | Result data type | Argument data types | Type ---------+------------------------+------------------+---------------------+------ - public | influxdb_fdw_handler | fdw_handler | | func - public | influxdb_fdw_validator | void | text[], oid | func - public | influxdb_fdw_version | integer | | func -(3 rows) - ---Testcase 145: -SELECT * FROM public.influxdb_fdw_version(); - influxdb_fdw_version ----------------------- - 20000 -(1 row) - ---Testcase 146: -SELECT influxdb_fdw_version(); - influxdb_fdw_version ----------------------- - 20000 -(1 row) - ---Test pushdown LIMIT...OFFSET ---Testcase 147: -EXPLAIN (VERBOSE, COSTS OFF) -SELECT tableoid::regclass, * FROM t1 LIMIT 1 OFFSET 0; - QUERY PLAN ------------------------------------------------------------- - Limit - Output: ((tableoid)::regclass), "time", tags, fields - -> Foreign Scan on public.t1 - Output: (tableoid)::regclass, "time", tags, fields - InfluxDB query: SELECT * FROM "cpu" -(5 rows) - ---Testcase 148: -SELECT tableoid::regclass, * FROM t1 LIMIT 1 OFFSET 0; - tableoid | time | tags | fields -----------+------------------------+--------------------+----------------------------------------------------------------------------------------- - t1 | 2015-08-18 09:00:00+09 | {"tag1": "tag1_A"} | {"tag2": "tag2_A", "value1": "100", "value2": "0.5", "value3": "str", "value4": "true"} -(1 row) - ---Testcase 149: -EXPLAIN (VERBOSE, COSTS OFF) -SELECT tableoid::regclass, * FROM t1 LIMIT 1 OFFSET 1; - QUERY PLAN ------------------------------------------------------------- - Limit - Output: ((tableoid)::regclass), "time", tags, fields - -> Foreign Scan on public.t1 - Output: (tableoid)::regclass, "time", tags, fields - InfluxDB query: SELECT * FROM "cpu" -(5 rows) - ---Testcase 150: -SELECT tableoid::regclass, * FROM t1 LIMIT 1 OFFSET 1; - tableoid | time | tags | fields -----------+------------------------+--------------------+----------------------------------------------------------------------------------- - t1 | 2015-08-18 09:00:00+09 | {"tag1": "tag1_B"} | {"tag2": null, "value1": "100", "value2": "2", "value3": null, "value4": "false"} -(1 row) - ---Testcase 151: -EXPLAIN (VERBOSE, COSTS OFF) -SELECT ctid, * FROM t1 LIMIT 1 OFFSET 0; - QUERY PLAN ---------------------------------------------- - Limit - Output: ctid, "time", tags, fields - -> Foreign Scan on public.t1 - Output: ctid, "time", tags, fields - InfluxDB query: SELECT * FROM "cpu" -(5 rows) - ---Testcase 152: -SELECT ctid, * FROM t1 LIMIT 1 OFFSET 0; - ctid | time | tags | fields -----------------+------------------------+--------------------+----------------------------------------------------------------------------------------- - (4294967295,0) | 2015-08-18 09:00:00+09 | {"tag1": "tag1_A"} | {"tag2": "tag2_A", "value1": "100", "value2": "0.5", "value3": "str", "value4": "true"} -(1 row) - ---Testcase 153: -EXPLAIN (VERBOSE, COSTS OFF) -SELECT ctid, * FROM t2 LIMIT 10 OFFSET 20; - QUERY PLAN ---------------------------------------------- - Limit - Output: ctid, "time", tags, fields - -> Foreign Scan on public.t2 - Output: ctid, "time", tags, fields - InfluxDB query: SELECT * FROM "cpu" -(5 rows) - ---Testcase 154: -SELECT ctid, * FROM t2 LIMIT 10 OFFSET 20; - ctid | time | tags | fields -------+------+------+-------- -(0 rows) - ---Testcase 155: -EXPLAIN (VERBOSE, COSTS OFF) -SELECT * FROM - t1 - LEFT JOIN t2 - ON (t2.fields->>'value1')::int = 123, - LATERAL (SELECT (t2.fields->>'value1')::int value1, t1.tags->>'tag1' tag1 FROM t1 LIMIT 1 OFFSET 0) AS ss -WHERE (t1.fields->>'value1')::int = ss.value1; - QUERY PLAN ------------------------------------------------------------------------------------------------------------------------------------------------------ - Nested Loop - Output: t1."time", t1.tags, t1.fields, t2."time", t2.tags, t2.fields, (((t2.fields ->> 'value1'::text))::integer), ((t1_1.tags ->> 'tag1'::text)) - Join Filter: (((t1.fields ->> 'value1'::text))::integer = (((t2.fields ->> 'value1'::text))::integer)) - -> Nested Loop Left Join - Output: t1."time", t1.tags, t1.fields, t2."time", t2.tags, t2.fields - -> Foreign Scan on public.t1 - Output: t1."time", t1.tags, t1.fields - InfluxDB query: SELECT * FROM "cpu" - -> Materialize - Output: t2."time", t2.tags, t2.fields - -> Foreign Scan on public.t2 - Output: t2."time", t2.tags, t2.fields - InfluxDB query: SELECT * FROM "cpu" WHERE (("value1" = 123)) - -> Limit - Output: (((t2.fields ->> 'value1'::text))::integer), ((t1_1.tags ->> 'tag1'::text)) - -> Foreign Scan on public.t1 t1_1 - Output: ((t2.fields ->> 'value1'::text))::integer, (t1_1.tags ->> 'tag1'::text) - InfluxDB query: SELECT * FROM "cpu" -(18 rows) - ---Testcase 156: -EXPLAIN (VERBOSE, COSTS OFF) -SELECT * FROM - t1 - LEFT JOIN t2 - ON (t2.fields->>'value1')::int = 123, - LATERAL (SELECT (t2.fields->>'value1')::int value1, t1.tags->>'tag1' tag1 FROM t1 LIMIT 1 OFFSET 0) AS ss1, - LATERAL (SELECT ss1.* from t3 LIMIT 1 OFFSET 20) AS ss2 -WHERE (t1.fields->>'value1')::int = ss2.value1; - QUERY PLAN --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- - Nested Loop - Output: t1."time", t1.tags, t1.fields, t2."time", t2.tags, t2.fields, (((t2.fields ->> 'value1'::text))::integer), ((t1_1.tags ->> 'tag1'::text)), ((((t2.fields ->> 'value1'::text))::integer)), (((t1_1.tags ->> 'tag1'::text))) - Join Filter: (((t1.fields ->> 'value1'::text))::integer = ((((t2.fields ->> 'value1'::text))::integer))) - -> Nested Loop - Output: t1."time", t1.tags, t1.fields, t2."time", t2.tags, t2.fields, (((t2.fields ->> 'value1'::text))::integer), ((t1_1.tags ->> 'tag1'::text)) - -> Nested Loop Left Join - Output: t1."time", t1.tags, t1.fields, t2."time", t2.tags, t2.fields - -> Foreign Scan on public.t1 - Output: t1."time", t1.tags, t1.fields - InfluxDB query: SELECT * FROM "cpu" - -> Materialize - Output: t2."time", t2.tags, t2.fields - -> Foreign Scan on public.t2 - Output: t2."time", t2.tags, t2.fields - InfluxDB query: SELECT * FROM "cpu" WHERE (("value1" = 123)) - -> Limit - Output: (((t2.fields ->> 'value1'::text))::integer), ((t1_1.tags ->> 'tag1'::text)) - -> Foreign Scan on public.t1 t1_1 - Output: ((t2.fields ->> 'value1'::text))::integer, (t1_1.tags ->> 'tag1'::text) - InfluxDB query: SELECT * FROM "cpu" - -> Limit - Output: ((((t2.fields ->> 'value1'::text))::integer)), (((t1_1.tags ->> 'tag1'::text))) - -> Foreign Scan on public.t3 - Output: (((t2.fields ->> 'value1'::text))::integer), ((t1_1.tags ->> 'tag1'::text)) - InfluxDB query: SELECT * FROM "t3" -(25 rows) - ---Testcase 157: -DROP FOREIGN TABLE cpu; ---Testcase 158: -DROP FOREIGN TABLE t1; ---Testcase 159: -DROP FOREIGN TABLE t2; ---Testcase 160: -DROP FOREIGN TABLE t3; ---Testcase 161: -DROP FOREIGN TABLE t4; ---Testcase 162: -DROP FOREIGN TABLE t5; ---Testcase 163: -DROP FOREIGN TABLE tx; --- test INSERT, DELETE -IMPORT FOREIGN SCHEMA public FROM SERVER server1 INTO public OPTIONS(import_time_text 'true', schemaless 'true'); -CREATE FOREIGN TABLE cpu_nsc (time timestamp with time zone, time_text text, tag1 text, tag2 text, value1 int, value2 float, value3 text, value4 boolean) SERVER server1 OPTIONS (table 'cpu', tags 'tag1, tag2'); ---Testcase 164: -SELECT * FROM cpu; - time | time_text | tags | fields -------------------------+----------------------+--------------------------------------+----------------------------------------------------------------------- - 2015-08-18 09:00:00+09 | 2015-08-18T00:00:00Z | {"tag1": "tag1_A", "tag2": "tag2_A"} | {"value1": "100", "value2": "0.5", "value3": "str", "value4": "true"} - 2015-08-18 09:00:00+09 | 2015-08-18T00:00:00Z | {"tag1": "tag1_B", "tag2": null} | {"value1": "100", "value2": "2", "value3": null, "value4": "false"} - 2015-08-18 09:48:08+09 | 2015-08-18T00:48:08Z | {"tag1": null, "tag2": "tag2_A"} | {"value1": null, "value2": "2", "value3": null, "value4": null} -(3 rows) - ---Testcase 165: -EXPLAIN VERBOSE -INSERT INTO cpu_nsc(time, tag1, tag2, value1, value2, value3, value4) VALUES('2021-01-01 00:00:01+09', 'tag1_K', 'tag2_H', 200, 5.5, 'test1', true); - QUERY PLAN -------------------------------------------------------------------------------------------------------------------------------------------------------------------- - Insert on public.cpu_nsc (cost=0.00..0.01 rows=1 width=149) - -> Result (cost=0.00..0.01 rows=1 width=149) - Output: '2021-01-01 00:00:01+09'::timestamp with time zone, NULL::text, 'tag1_K'::text, 'tag2_H'::text, 200, '5.5'::double precision, 'test1'::text, true -(3 rows) - ---Testcase 166: -INSERT INTO cpu_nsc(time, tag1, tag2, value1, value2, value3, value4) VALUES('2021-01-01 00:00:01+09', 'tag1_K', 'tag2_H', 200, 5.5, 'test', true); ---Testcase 167: -SELECT * FROM cpu; - time | time_text | tags | fields -------------------------+----------------------+--------------------------------------+------------------------------------------------------------------------ - 2015-08-18 09:00:00+09 | 2015-08-18T00:00:00Z | {"tag1": "tag1_A", "tag2": "tag2_A"} | {"value1": "100", "value2": "0.5", "value3": "str", "value4": "true"} - 2015-08-18 09:00:00+09 | 2015-08-18T00:00:00Z | {"tag1": "tag1_B", "tag2": null} | {"value1": "100", "value2": "2", "value3": null, "value4": "false"} - 2015-08-18 09:48:08+09 | 2015-08-18T00:48:08Z | {"tag1": null, "tag2": "tag2_A"} | {"value1": null, "value2": "2", "value3": null, "value4": null} - 2021-01-01 00:00:01+09 | 2020-12-31T15:00:01Z | {"tag1": "tag1_K", "tag2": "tag2_H"} | {"value1": "200", "value2": "5.5", "value3": "test", "value4": "true"} -(4 rows) - ---Testcase 168: -EXPLAIN VERBOSE -INSERT INTO cpu_nsc(time, tag1, tag2, value1, value2, value3, value4) VALUES('2021-01-02 00:00:02+05', 'tag1_I', 'tag2_E', 300, 15.5, 'test2', false), - ('2029-02-02 00:02:02+04', 'tag1_U', 'tag2_DZ', (SELECT 350), (SELECT i FROM (VALUES(6.9)) AS foo (i)), 'funny', true); - QUERY PLAN ------------------------------------------------------------------------------------------------------------------------------------------------------------------------- - Insert on public.cpu_nsc (cost=0.02..0.04 rows=2 width=149) - InitPlan 1 (returns $0) - -> Result (cost=0.00..0.01 rows=1 width=4) - Output: 350 - InitPlan 2 (returns $1) - -> Result (cost=0.00..0.01 rows=1 width=32) - Output: 6.9 - -> Values Scan on "*VALUES*" (cost=0.00..0.03 rows=2 width=149) - Output: "*VALUES*".column1, NULL::text, "*VALUES*".column2, "*VALUES*".column3, "*VALUES*".column4, "*VALUES*".column5, "*VALUES*".column6, "*VALUES*".column7 -(9 rows) - ---Testcase 169: -INSERT INTO cpu_nsc(time, tag1, tag2, value1, value2, value3, value4) VALUES('2021-01-02 00:00:02+05', 'tag1_I', 'tag2_E', 300, 15.5, 'test2', false), - ('2029-02-02 00:02:02+04', 'tag1_U', 'tag2_DZ', (SELECT 350), (SELECT i FROM (VALUES(6.9)) AS foo (i)), 'funny', true); ---Testcase 170: -SELECT * FROM cpu; - time | time_text | tags | fields -------------------------+----------------------+---------------------------------------+--------------------------------------------------------------------------- - 2015-08-18 09:00:00+09 | 2015-08-18T00:00:00Z | {"tag1": "tag1_A", "tag2": "tag2_A"} | {"value1": "100", "value2": "0.5", "value3": "str", "value4": "true"} - 2015-08-18 09:00:00+09 | 2015-08-18T00:00:00Z | {"tag1": "tag1_B", "tag2": null} | {"value1": "100", "value2": "2", "value3": null, "value4": "false"} - 2015-08-18 09:48:08+09 | 2015-08-18T00:48:08Z | {"tag1": null, "tag2": "tag2_A"} | {"value1": null, "value2": "2", "value3": null, "value4": null} - 2021-01-01 00:00:01+09 | 2020-12-31T15:00:01Z | {"tag1": "tag1_K", "tag2": "tag2_H"} | {"value1": "200", "value2": "5.5", "value3": "test", "value4": "true"} - 2021-01-02 04:00:02+09 | 2021-01-01T19:00:02Z | {"tag1": "tag1_I", "tag2": "tag2_E"} | {"value1": "300", "value2": "15.5", "value3": "test2", "value4": "false"} - 2029-02-02 05:02:02+09 | 2029-02-01T20:02:02Z | {"tag1": "tag1_U", "tag2": "tag2_DZ"} | {"value1": "350", "value2": "6.9", "value3": "funny", "value4": "true"} -(6 rows) - ---Testcase 171: -INSERT INTO cpu_nsc(tag2, value1) VALUES('tag2_KH', 400); ---Testcase 172: -SELECT tags->>'tag1' tag1, tags->>'tag2' tag2, (fields->>'value1')::bigint value1, (fields->>'value2')::double precision value2, fields->>'value3' value3, (fields->>'value4')::boolean value4 FROM cpu; - tag1 | tag2 | value1 | value2 | value3 | value4 ---------+---------+--------+--------+--------+-------- - tag1_A | tag2_A | 100 | 0.5 | str | t - tag1_B | | 100 | 2 | | f - | tag2_A | | 2 | | - tag1_K | tag2_H | 200 | 5.5 | test | t - tag1_I | tag2_E | 300 | 15.5 | test2 | f - | tag2_KH | 400 | | | - tag1_U | tag2_DZ | 350 | 6.9 | funny | t -(7 rows) - ---Testcase 173: -EXPLAIN VERBOSE -DELETE FROM cpu_nsc WHERE tag2 = 'tag2_KH'; - QUERY PLAN ------------------------------------------------------------------------------ - Delete on public.cpu_nsc (cost=10.00..3.00 rows=3 width=104) - -> Foreign Delete on public.cpu_nsc (cost=10.00..3.00 rows=3 width=104) - InfluxDB query: DELETE FROM "cpu" WHERE (("tag2" = 'tag2_KH')) -(3 rows) - ---Testcase 174: -DELETE FROM cpu_nsc WHERE tag2 = 'tag2_KH'; ---Testcase 175: -SELECT tags->>'tag1' tag1, tags->>'tag2' tag2, (fields->>'value1')::bigint value1, (fields->>'value2')::double precision value2, fields->>'value3' value3, (fields->>'value4')::boolean value4 FROM cpu; - tag1 | tag2 | value1 | value2 | value3 | value4 ---------+---------+--------+--------+--------+-------- - tag1_A | tag2_A | 100 | 0.5 | str | t - tag1_B | | 100 | 2 | | f - | tag2_A | | 2 | | - tag1_K | tag2_H | 200 | 5.5 | test | t - tag1_I | tag2_E | 300 | 15.5 | test2 | f - tag1_U | tag2_DZ | 350 | 6.9 | funny | t -(6 rows) - ---Testcase 176: -EXPLAIN VERBOSE -DELETE FROM cpu WHERE time = '2021-01-02 04:00:02+09'; - QUERY PLAN ----------------------------------------------------------------------------------- - Delete on public.cpu (cost=10.00..6.00 rows=6 width=40) - -> Foreign Delete on public.cpu (cost=10.00..6.00 rows=6 width=40) - InfluxDB query: DELETE FROM "cpu" WHERE ((time = '2021-01-01 19:00:02')) -(3 rows) - ---Testcase 177: -DELETE FROM cpu WHERE time = '2021-01-02 04:00:02+09'; ---Testcase 178: -SELECT * FROM cpu; - time | time_text | tags | fields -------------------------+----------------------+---------------------------------------+------------------------------------------------------------------------- - 2015-08-18 09:00:00+09 | 2015-08-18T00:00:00Z | {"tag1": "tag1_A", "tag2": "tag2_A"} | {"value1": "100", "value2": "0.5", "value3": "str", "value4": "true"} - 2015-08-18 09:00:00+09 | 2015-08-18T00:00:00Z | {"tag1": "tag1_B", "tag2": null} | {"value1": "100", "value2": "2", "value3": null, "value4": "false"} - 2015-08-18 09:48:08+09 | 2015-08-18T00:48:08Z | {"tag1": null, "tag2": "tag2_A"} | {"value1": null, "value2": "2", "value3": null, "value4": null} - 2021-01-01 00:00:01+09 | 2020-12-31T15:00:01Z | {"tag1": "tag1_K", "tag2": "tag2_H"} | {"value1": "200", "value2": "5.5", "value3": "test", "value4": "true"} - 2029-02-02 05:02:02+09 | 2029-02-01T20:02:02Z | {"tag1": "tag1_U", "tag2": "tag2_DZ"} | {"value1": "350", "value2": "6.9", "value3": "funny", "value4": "true"} -(5 rows) - ---Testcase 179: -EXPLAIN VERBOSE -DELETE FROM cpu_nsc WHERE time < '2018-07-07' AND tag1 != 'tag1_B'; - QUERY PLAN -------------------------------------------------------------------------------------------------------------- - Delete on public.cpu_nsc (cost=10.00..212.00 rows=212 width=104) - -> Foreign Delete on public.cpu_nsc (cost=10.00..212.00 rows=212 width=104) - InfluxDB query: DELETE FROM "cpu" WHERE ((time < '2018-07-06 15:00:00')) AND (("tag1" <> 'tag1_B')) -(3 rows) - ---Testcase 180: -DELETE FROM cpu_nsc WHERE time < '2018-07-07' AND tag1 != 'tag1_B'; ---Testcase 181: -SELECT * FROM cpu; - time | time_text | tags | fields -------------------------+----------------------+---------------------------------------+------------------------------------------------------------------------- - 2015-08-18 09:00:00+09 | 2015-08-18T00:00:00Z | {"tag1": "tag1_B", "tag2": null} | {"value1": "100", "value2": "2", "value3": null, "value4": "false"} - 2021-01-01 00:00:01+09 | 2020-12-31T15:00:01Z | {"tag1": "tag1_K", "tag2": "tag2_H"} | {"value1": "200", "value2": "5.5", "value3": "test", "value4": "true"} - 2029-02-02 05:02:02+09 | 2029-02-01T20:02:02Z | {"tag1": "tag1_U", "tag2": "tag2_DZ"} | {"value1": "350", "value2": "6.9", "value3": "funny", "value4": "true"} -(3 rows) - --- Test INSERT, DELETE with time_text column ---Testcase 182: -INSERT INTO cpu_nsc(time_text, tag1, tag2, value1, value2, value3, value4) VALUES('2021-02-02T00:00:00Z', 'tag1_D', 'tag2_E', 600, 20.2, 'test3', true); ---Testcase 183: -SELECT * FROM cpu; - time | time_text | tags | fields -------------------------+----------------------+---------------------------------------+-------------------------------------------------------------------------- - 2015-08-18 09:00:00+09 | 2015-08-18T00:00:00Z | {"tag1": "tag1_B", "tag2": null} | {"value1": "100", "value2": "2", "value3": null, "value4": "false"} - 2021-01-01 00:00:01+09 | 2020-12-31T15:00:01Z | {"tag1": "tag1_K", "tag2": "tag2_H"} | {"value1": "200", "value2": "5.5", "value3": "test", "value4": "true"} - 2021-02-02 09:00:00+09 | 2021-02-02T00:00:00Z | {"tag1": "tag1_D", "tag2": "tag2_E"} | {"value1": "600", "value2": "20.2", "value3": "test3", "value4": "true"} - 2029-02-02 05:02:02+09 | 2029-02-01T20:02:02Z | {"tag1": "tag1_U", "tag2": "tag2_DZ"} | {"value1": "350", "value2": "6.9", "value3": "funny", "value4": "true"} -(4 rows) - ---Testcase 184: -INSERT INTO cpu_nsc(time_text, tag1, value2) VALUES('2021-02-02T00:00:00.123456789Z', 'tag1_P', 25.8); ---Testcase 185: -SELECT * FROM cpu; - time | time_text | tags | fields --------------------------------+--------------------------------+---------------------------------------+-------------------------------------------------------------------------- - 2015-08-18 09:00:00+09 | 2015-08-18T00:00:00Z | {"tag1": "tag1_B", "tag2": null} | {"value1": "100", "value2": "2", "value3": null, "value4": "false"} - 2021-01-01 00:00:01+09 | 2020-12-31T15:00:01Z | {"tag1": "tag1_K", "tag2": "tag2_H"} | {"value1": "200", "value2": "5.5", "value3": "test", "value4": "true"} - 2021-02-02 09:00:00+09 | 2021-02-02T00:00:00Z | {"tag1": "tag1_D", "tag2": "tag2_E"} | {"value1": "600", "value2": "20.2", "value3": "test3", "value4": "true"} - 2021-02-02 09:00:00.123457+09 | 2021-02-02T00:00:00.123456789Z | {"tag1": "tag1_P", "tag2": null} | {"value1": null, "value2": "25.8", "value3": null, "value4": null} - 2029-02-02 05:02:02+09 | 2029-02-01T20:02:02Z | {"tag1": "tag1_U", "tag2": "tag2_DZ"} | {"value1": "350", "value2": "6.9", "value3": "funny", "value4": "true"} -(5 rows) - ---Testcase 186: -INSERT INTO cpu_nsc(time_text, tag1, value2) VALUES('2021-02-02 00:00:01', 'tag1_J', 37.1); ---Testcase 187: -SELECT * FROM cpu; - time | time_text | tags | fields --------------------------------+--------------------------------+---------------------------------------+-------------------------------------------------------------------------- - 2015-08-18 09:00:00+09 | 2015-08-18T00:00:00Z | {"tag1": "tag1_B", "tag2": null} | {"value1": "100", "value2": "2", "value3": null, "value4": "false"} - 2021-01-01 00:00:01+09 | 2020-12-31T15:00:01Z | {"tag1": "tag1_K", "tag2": "tag2_H"} | {"value1": "200", "value2": "5.5", "value3": "test", "value4": "true"} - 2021-02-02 09:00:00+09 | 2021-02-02T00:00:00Z | {"tag1": "tag1_D", "tag2": "tag2_E"} | {"value1": "600", "value2": "20.2", "value3": "test3", "value4": "true"} - 2021-02-02 09:00:00.123457+09 | 2021-02-02T00:00:00.123456789Z | {"tag1": "tag1_P", "tag2": null} | {"value1": null, "value2": "25.8", "value3": null, "value4": null} - 2021-02-02 09:00:01+09 | 2021-02-02T00:00:01Z | {"tag1": "tag1_J", "tag2": null} | {"value1": null, "value2": "37.1", "value3": null, "value4": null} - 2029-02-02 05:02:02+09 | 2029-02-01T20:02:02Z | {"tag1": "tag1_U", "tag2": "tag2_DZ"} | {"value1": "350", "value2": "6.9", "value3": "funny", "value4": "true"} -(6 rows) - ---Testcase 188: -INSERT INTO cpu_nsc(time, time_text, tag1, tag2, value1, value2, value3, value4) VALUES('2021-02-02 00:00:01+05', '2021-02-02T00:00:02.123456789Z', 'tag1_A', 'tag2_B', 200, 5.5, 'test', true); -WARNING: Inserting value has both 'time_text' and 'time' columns specified. The 'time' will be ignored. ---Testcase 189: -SELECT * FROM cpu; - time | time_text | tags | fields --------------------------------+--------------------------------+---------------------------------------+-------------------------------------------------------------------------- - 2015-08-18 09:00:00+09 | 2015-08-18T00:00:00Z | {"tag1": "tag1_B", "tag2": null} | {"value1": "100", "value2": "2", "value3": null, "value4": "false"} - 2021-01-01 00:00:01+09 | 2020-12-31T15:00:01Z | {"tag1": "tag1_K", "tag2": "tag2_H"} | {"value1": "200", "value2": "5.5", "value3": "test", "value4": "true"} - 2021-02-02 09:00:00+09 | 2021-02-02T00:00:00Z | {"tag1": "tag1_D", "tag2": "tag2_E"} | {"value1": "600", "value2": "20.2", "value3": "test3", "value4": "true"} - 2021-02-02 09:00:00.123457+09 | 2021-02-02T00:00:00.123456789Z | {"tag1": "tag1_P", "tag2": null} | {"value1": null, "value2": "25.8", "value3": null, "value4": null} - 2021-02-02 09:00:01+09 | 2021-02-02T00:00:01Z | {"tag1": "tag1_J", "tag2": null} | {"value1": null, "value2": "37.1", "value3": null, "value4": null} - 2021-02-02 09:00:02.123457+09 | 2021-02-02T00:00:02.123456789Z | {"tag1": "tag1_A", "tag2": "tag2_B"} | {"value1": "200", "value2": "5.5", "value3": "test", "value4": "true"} - 2029-02-02 05:02:02+09 | 2029-02-01T20:02:02Z | {"tag1": "tag1_U", "tag2": "tag2_DZ"} | {"value1": "350", "value2": "6.9", "value3": "funny", "value4": "true"} -(7 rows) - ---Testcase 190: -INSERT INTO cpu_nsc(time_text, time, tag1, tag2, value1, value2, value3, value4) VALUES('2021-02-03T00:00:03.123456789Z', '2021-03-03 00:00:01+07', 'tag1_C', 'tag2_D', 200, 5.5, 'test', true); -WARNING: Inserting value has both 'time_text' and 'time' columns specified. The 'time' will be ignored. ---Testcase 191: -SELECT * FROM cpu; - time | time_text | tags | fields --------------------------------+--------------------------------+---------------------------------------+-------------------------------------------------------------------------- - 2015-08-18 09:00:00+09 | 2015-08-18T00:00:00Z | {"tag1": "tag1_B", "tag2": null} | {"value1": "100", "value2": "2", "value3": null, "value4": "false"} - 2021-01-01 00:00:01+09 | 2020-12-31T15:00:01Z | {"tag1": "tag1_K", "tag2": "tag2_H"} | {"value1": "200", "value2": "5.5", "value3": "test", "value4": "true"} - 2021-02-02 09:00:00+09 | 2021-02-02T00:00:00Z | {"tag1": "tag1_D", "tag2": "tag2_E"} | {"value1": "600", "value2": "20.2", "value3": "test3", "value4": "true"} - 2021-02-02 09:00:00.123457+09 | 2021-02-02T00:00:00.123456789Z | {"tag1": "tag1_P", "tag2": null} | {"value1": null, "value2": "25.8", "value3": null, "value4": null} - 2021-02-02 09:00:01+09 | 2021-02-02T00:00:01Z | {"tag1": "tag1_J", "tag2": null} | {"value1": null, "value2": "37.1", "value3": null, "value4": null} - 2021-02-02 09:00:02.123457+09 | 2021-02-02T00:00:02.123456789Z | {"tag1": "tag1_A", "tag2": "tag2_B"} | {"value1": "200", "value2": "5.5", "value3": "test", "value4": "true"} - 2021-02-03 09:00:03.123457+09 | 2021-02-03T00:00:03.123456789Z | {"tag1": "tag1_C", "tag2": "tag2_D"} | {"value1": "200", "value2": "5.5", "value3": "test", "value4": "true"} - 2029-02-02 05:02:02+09 | 2029-02-01T20:02:02Z | {"tag1": "tag1_U", "tag2": "tag2_DZ"} | {"value1": "350", "value2": "6.9", "value3": "funny", "value4": "true"} -(8 rows) - ---Testcase 192: -EXPLAIN VERBOSE -DELETE FROM cpu_nsc WHERE time_text = '2021-02-02T00:00:00.123456789Z'; - QUERY PLAN ---------------------------------------------------------------------------------------------- - Delete on public.cpu_nsc (cost=10.00..3.00 rows=3 width=104) - -> Foreign Delete on public.cpu_nsc (cost=10.00..3.00 rows=3 width=104) - InfluxDB query: DELETE FROM "cpu" WHERE ((time = '2021-02-02T00:00:00.123456789Z')) -(3 rows) - ---Testcase 193: -DELETE FROM cpu_nsc WHERE time_text = '2021-02-02T00:00:00.123456789Z'; ---Testcase 194: -SELECT * FROM cpu; - time | time_text | tags | fields --------------------------------+--------------------------------+---------------------------------------+-------------------------------------------------------------------------- - 2015-08-18 09:00:00+09 | 2015-08-18T00:00:00Z | {"tag1": "tag1_B", "tag2": null} | {"value1": "100", "value2": "2", "value3": null, "value4": "false"} - 2021-01-01 00:00:01+09 | 2020-12-31T15:00:01Z | {"tag1": "tag1_K", "tag2": "tag2_H"} | {"value1": "200", "value2": "5.5", "value3": "test", "value4": "true"} - 2021-02-02 09:00:00+09 | 2021-02-02T00:00:00Z | {"tag1": "tag1_D", "tag2": "tag2_E"} | {"value1": "600", "value2": "20.2", "value3": "test3", "value4": "true"} - 2021-02-02 09:00:01+09 | 2021-02-02T00:00:01Z | {"tag1": "tag1_J", "tag2": null} | {"value1": null, "value2": "37.1", "value3": null, "value4": null} - 2021-02-02 09:00:02.123457+09 | 2021-02-02T00:00:02.123456789Z | {"tag1": "tag1_A", "tag2": "tag2_B"} | {"value1": "200", "value2": "5.5", "value3": "test", "value4": "true"} - 2021-02-03 09:00:03.123457+09 | 2021-02-03T00:00:03.123456789Z | {"tag1": "tag1_C", "tag2": "tag2_D"} | {"value1": "200", "value2": "5.5", "value3": "test", "value4": "true"} - 2029-02-02 05:02:02+09 | 2029-02-01T20:02:02Z | {"tag1": "tag1_U", "tag2": "tag2_DZ"} | {"value1": "350", "value2": "6.9", "value3": "funny", "value4": "true"} -(7 rows) - ---Testcase 195: -EXPLAIN VERBOSE -DELETE FROM cpu_nsc WHERE time_text = '2021-02-02T00:00:01Z' AND tag1 = 'tag1_J'; - QUERY PLAN -------------------------------------------------------------------------------------------------------------- - Delete on public.cpu_nsc (cost=10.00..1.00 rows=1 width=104) - -> Foreign Delete on public.cpu_nsc (cost=10.00..1.00 rows=1 width=104) - InfluxDB query: DELETE FROM "cpu" WHERE ((time = '2021-02-02T00:00:01Z')) AND (("tag1" = 'tag1_J')) -(3 rows) - ---Testcase 196: -DELETE FROM cpu_nsc WHERE time_text = '2021-02-02T00:00:01Z' AND tag1 = 'tag1_J'; ---Testcase 197: -SELECT * FROM cpu; - time | time_text | tags | fields --------------------------------+--------------------------------+---------------------------------------+-------------------------------------------------------------------------- - 2015-08-18 09:00:00+09 | 2015-08-18T00:00:00Z | {"tag1": "tag1_B", "tag2": null} | {"value1": "100", "value2": "2", "value3": null, "value4": "false"} - 2021-01-01 00:00:01+09 | 2020-12-31T15:00:01Z | {"tag1": "tag1_K", "tag2": "tag2_H"} | {"value1": "200", "value2": "5.5", "value3": "test", "value4": "true"} - 2021-02-02 09:00:00+09 | 2021-02-02T00:00:00Z | {"tag1": "tag1_D", "tag2": "tag2_E"} | {"value1": "600", "value2": "20.2", "value3": "test3", "value4": "true"} - 2021-02-02 09:00:02.123457+09 | 2021-02-02T00:00:02.123456789Z | {"tag1": "tag1_A", "tag2": "tag2_B"} | {"value1": "200", "value2": "5.5", "value3": "test", "value4": "true"} - 2021-02-03 09:00:03.123457+09 | 2021-02-03T00:00:03.123456789Z | {"tag1": "tag1_C", "tag2": "tag2_D"} | {"value1": "200", "value2": "5.5", "value3": "test", "value4": "true"} - 2029-02-02 05:02:02+09 | 2029-02-01T20:02:02Z | {"tag1": "tag1_U", "tag2": "tag2_DZ"} | {"value1": "350", "value2": "6.9", "value3": "funny", "value4": "true"} -(6 rows) - ---Testcase 198: -EXPLAIN VERBOSE -DELETE FROM cpu_nsc WHERE time_text = '2021-02-02 00:00:00' OR time ='2029-02-02 05:02:02+09'; - QUERY PLAN ----------------------------------------------------------------------------------------------------------------------------------------------- - Delete on public.cpu_nsc (cost=10.00..6.00 rows=6 width=104) - -> Foreign Scan on public.cpu_nsc (cost=10.00..6.00 rows=6 width=104) - Output: "time", time_text, tag1, tag2 - Filter: ((cpu_nsc.time_text = '2021-02-02 00:00:00'::text) OR (cpu_nsc."time" = '2029-02-02 05:02:02+09'::timestamp with time zone)) - InfluxDB query: SELECT "tag1", "tag2", "value1" FROM "cpu" -(5 rows) - ---Testcase 199: -DELETE FROM cpu_nsc WHERE time_text = '2021-02-02 00:00:00' OR time ='2029-02-02 05:02:02+09'; ---Testcase 200: -SELECT * FROM cpu; - time | time_text | tags | fields --------------------------------+--------------------------------+--------------------------------------+-------------------------------------------------------------------------- - 2015-08-18 09:00:00+09 | 2015-08-18T00:00:00Z | {"tag1": "tag1_B", "tag2": null} | {"value1": "100", "value2": "2", "value3": null, "value4": "false"} - 2021-01-01 00:00:01+09 | 2020-12-31T15:00:01Z | {"tag1": "tag1_K", "tag2": "tag2_H"} | {"value1": "200", "value2": "5.5", "value3": "test", "value4": "true"} - 2021-02-02 09:00:00+09 | 2021-02-02T00:00:00Z | {"tag1": "tag1_D", "tag2": "tag2_E"} | {"value1": "600", "value2": "20.2", "value3": "test3", "value4": "true"} - 2021-02-02 09:00:02.123457+09 | 2021-02-02T00:00:02.123456789Z | {"tag1": "tag1_A", "tag2": "tag2_B"} | {"value1": "200", "value2": "5.5", "value3": "test", "value4": "true"} - 2021-02-03 09:00:03.123457+09 | 2021-02-03T00:00:03.123456789Z | {"tag1": "tag1_C", "tag2": "tag2_D"} | {"value1": "200", "value2": "5.5", "value3": "test", "value4": "true"} -(5 rows) - --- Recover data -:RECOVER_INIT_TXT_DROP_BUCKET; -:RECOVER_INIT_TXT_CREATE_BUCKET; -:RECOVER_INIT_TXT; ---Testcase 201: -DROP FOREIGN TABLE cpu_nsc; -DROP USER MAPPING FOR CURRENT_USER SERVER server1; ---Testcase 202: -DROP SERVER server1 CASCADE; -NOTICE: drop cascades to 5 other objects -DETAIL: drop cascades to foreign table cpu -drop cascades to foreign table numbers -drop cascades to foreign table t3 -drop cascades to foreign table t4 -drop cascades to foreign table tx ---Testcase 203: -DROP EXTENSION influxdb_fdw; diff --git a/expected/11.17/aggregate.out b/expected/12.16/aggregate.out similarity index 100% rename from expected/11.17/aggregate.out rename to expected/12.16/aggregate.out diff --git a/expected/12.12/extra/aggregates.out b/expected/12.16/extra/aggregates.out similarity index 100% rename from expected/12.12/extra/aggregates.out rename to expected/12.16/extra/aggregates.out diff --git a/expected/12.12/extra/influxdb_fdw_post.out b/expected/12.16/extra/influxdb_fdw_post.out similarity index 91% rename from expected/12.12/extra/influxdb_fdw_post.out rename to expected/12.16/extra/influxdb_fdw_post.out index d8909a5..8662f08 100644 --- a/expected/12.12/extra/influxdb_fdw_post.out +++ b/expected/12.16/extra/influxdb_fdw_post.out @@ -30,7 +30,7 @@ CREATE FOREIGN TABLE "S 1"."T 0" ( "C 1" int NOT NULL, c2 int NOT NULL, c3 text, - time timestamp, + time timestamptz, c6 varchar(10), c7 char(10), c8 text @@ -40,7 +40,7 @@ CREATE FOREIGN TABLE "S 1"."T 1" ( "C 1" int NOT NULL, c2 int NOT NULL, c3 text, - time timestamp, + time timestamptz, c6 varchar(10), c7 char(10), c8 text @@ -72,7 +72,7 @@ INSERT INTO "S 1"."T 1" SELECT id, id % 10, to_char(id, 'FM00000'), - '1970-01-01'::timestamp + ((id % 100) || ' days')::interval, + '1970-01-01'::timestamptz + ((id % 100) || ' days')::interval, id % 10, id % 10, 'foo'::text @@ -111,7 +111,7 @@ CREATE FOREIGN TABLE ft1 ( c1 int NOT NULL, c2 int NOT NULL, c3 text, - time timestamp, + time timestamptz, c6 varchar(10), c7 char(10) default 'ft1', c8 text @@ -123,7 +123,7 @@ CREATE FOREIGN TABLE ft2 ( c2 int NOT NULL, cx int, c3 text, - time timestamp, + time timestamptz, c6 varchar(10), c7 char(10) default 'ft2', c8 text @@ -221,9 +221,9 @@ ALTER FOREIGN TABLE ft2 ALTER COLUMN c1 OPTIONS (column_name 'C 1'); \set VERBOSITY terse --Testcase 27: SELECT c3, time FROM ft1 ORDER BY c3, c1 LIMIT 1; -- should work - c3 | time --------+-------------------------- - 00001 | Fri Jan 02 00:00:00 1970 + c3 | time +-------+------------------------------ + 00001 | Fri Jan 02 00:00:00 1970 PST (1 row) ALTER SERVER influxdb_svr OPTIONS (SET dbname 'no such database'); @@ -238,9 +238,9 @@ DO $d$ $d$; --Testcase 29: SELECT c3, time FROM ft1 ORDER BY c3, c1 LIMIT 1; -- should work again - c3 | time --------+-------------------------- - 00001 | Fri Jan 02 00:00:00 1970 + c3 | time +-------+------------------------------ + 00001 | Fri Jan 02 00:00:00 1970 PST (1 row) \set VERBOSITY default @@ -260,18 +260,18 @@ EXPLAIN (COSTS OFF) SELECT * FROM ft1 ORDER BY c3, c1 OFFSET 100 LIMIT 10; --Testcase 31: SELECT * FROM ft1 ORDER BY c3, c1 OFFSET 100 LIMIT 10; - c1 | c2 | c3 | time | c6 | c7 | c8 ------+----+-------+--------------------------+----+------------+----- - 101 | 1 | 00101 | Fri Jan 02 00:00:00 1970 | 1 | 1 | foo - 102 | 2 | 00102 | Sat Jan 03 00:00:00 1970 | 2 | 2 | foo - 103 | 3 | 00103 | Sun Jan 04 00:00:00 1970 | 3 | 3 | foo - 104 | 4 | 00104 | Mon Jan 05 00:00:00 1970 | 4 | 4 | foo - 105 | 5 | 00105 | Tue Jan 06 00:00:00 1970 | 5 | 5 | foo - 106 | 6 | 00106 | Wed Jan 07 00:00:00 1970 | 6 | 6 | foo - 107 | 7 | 00107 | Thu Jan 08 00:00:00 1970 | 7 | 7 | foo - 108 | 8 | 00108 | Fri Jan 09 00:00:00 1970 | 8 | 8 | foo - 109 | 9 | 00109 | Sat Jan 10 00:00:00 1970 | 9 | 9 | foo - 110 | 0 | 00110 | Sun Jan 11 00:00:00 1970 | 0 | 0 | foo + c1 | c2 | c3 | time | c6 | c7 | c8 +-----+----+-------+------------------------------+----+------------+----- + 101 | 1 | 00101 | Fri Jan 02 00:00:00 1970 PST | 1 | 1 | foo + 102 | 2 | 00102 | Sat Jan 03 00:00:00 1970 PST | 2 | 2 | foo + 103 | 3 | 00103 | Sun Jan 04 00:00:00 1970 PST | 3 | 3 | foo + 104 | 4 | 00104 | Mon Jan 05 00:00:00 1970 PST | 4 | 4 | foo + 105 | 5 | 00105 | Tue Jan 06 00:00:00 1970 PST | 5 | 5 | foo + 106 | 6 | 00106 | Wed Jan 07 00:00:00 1970 PST | 6 | 6 | foo + 107 | 7 | 00107 | Thu Jan 08 00:00:00 1970 PST | 7 | 7 | foo + 108 | 8 | 00108 | Fri Jan 09 00:00:00 1970 PST | 8 | 8 | foo + 109 | 9 | 00109 | Sat Jan 10 00:00:00 1970 PST | 9 | 9 | foo + 110 | 0 | 00110 | Sun Jan 11 00:00:00 1970 PST | 0 | 0 | foo (10 rows) -- single table with alias - also test that tableoid sort is not pushed to remote side @@ -291,18 +291,18 @@ EXPLAIN (VERBOSE, COSTS OFF) SELECT * FROM ft1 t1 ORDER BY t1.c3, t1.c1, t1.tabl --Testcase 33: SELECT * FROM ft1 t1 ORDER BY t1.c3, t1.c1, t1.tableoid OFFSET 100 LIMIT 10; - c1 | c2 | c3 | time | c6 | c7 | c8 ------+----+-------+--------------------------+----+------------+----- - 101 | 1 | 00101 | Fri Jan 02 00:00:00 1970 | 1 | 1 | foo - 102 | 2 | 00102 | Sat Jan 03 00:00:00 1970 | 2 | 2 | foo - 103 | 3 | 00103 | Sun Jan 04 00:00:00 1970 | 3 | 3 | foo - 104 | 4 | 00104 | Mon Jan 05 00:00:00 1970 | 4 | 4 | foo - 105 | 5 | 00105 | Tue Jan 06 00:00:00 1970 | 5 | 5 | foo - 106 | 6 | 00106 | Wed Jan 07 00:00:00 1970 | 6 | 6 | foo - 107 | 7 | 00107 | Thu Jan 08 00:00:00 1970 | 7 | 7 | foo - 108 | 8 | 00108 | Fri Jan 09 00:00:00 1970 | 8 | 8 | foo - 109 | 9 | 00109 | Sat Jan 10 00:00:00 1970 | 9 | 9 | foo - 110 | 0 | 00110 | Sun Jan 11 00:00:00 1970 | 0 | 0 | foo + c1 | c2 | c3 | time | c6 | c7 | c8 +-----+----+-------+------------------------------+----+------------+----- + 101 | 1 | 00101 | Fri Jan 02 00:00:00 1970 PST | 1 | 1 | foo + 102 | 2 | 00102 | Sat Jan 03 00:00:00 1970 PST | 2 | 2 | foo + 103 | 3 | 00103 | Sun Jan 04 00:00:00 1970 PST | 3 | 3 | foo + 104 | 4 | 00104 | Mon Jan 05 00:00:00 1970 PST | 4 | 4 | foo + 105 | 5 | 00105 | Tue Jan 06 00:00:00 1970 PST | 5 | 5 | foo + 106 | 6 | 00106 | Wed Jan 07 00:00:00 1970 PST | 6 | 6 | foo + 107 | 7 | 00107 | Thu Jan 08 00:00:00 1970 PST | 7 | 7 | foo + 108 | 8 | 00108 | Fri Jan 09 00:00:00 1970 PST | 8 | 8 | foo + 109 | 9 | 00109 | Sat Jan 10 00:00:00 1970 PST | 9 | 9 | foo + 110 | 0 | 00110 | Sun Jan 11 00:00:00 1970 PST | 0 | 0 | foo (10 rows) -- whole-row reference @@ -322,18 +322,18 @@ EXPLAIN (VERBOSE, COSTS OFF) SELECT t1 FROM ft1 t1 ORDER BY t1.c3, t1.c1 OFFSET --Testcase 35: SELECT t1 FROM ft1 t1 ORDER BY t1.c3, t1.c1 OFFSET 100 LIMIT 10; - t1 -------------------------------------------------------------- - (101,1,00101,"Fri Jan 02 00:00:00 1970",1,"1 ",foo) - (102,2,00102,"Sat Jan 03 00:00:00 1970",2,"2 ",foo) - (103,3,00103,"Sun Jan 04 00:00:00 1970",3,"3 ",foo) - (104,4,00104,"Mon Jan 05 00:00:00 1970",4,"4 ",foo) - (105,5,00105,"Tue Jan 06 00:00:00 1970",5,"5 ",foo) - (106,6,00106,"Wed Jan 07 00:00:00 1970",6,"6 ",foo) - (107,7,00107,"Thu Jan 08 00:00:00 1970",7,"7 ",foo) - (108,8,00108,"Fri Jan 09 00:00:00 1970",8,"8 ",foo) - (109,9,00109,"Sat Jan 10 00:00:00 1970",9,"9 ",foo) - (110,0,00110,"Sun Jan 11 00:00:00 1970",0,"0 ",foo) + t1 +----------------------------------------------------------------- + (101,1,00101,"Fri Jan 02 00:00:00 1970 PST",1,"1 ",foo) + (102,2,00102,"Sat Jan 03 00:00:00 1970 PST",2,"2 ",foo) + (103,3,00103,"Sun Jan 04 00:00:00 1970 PST",3,"3 ",foo) + (104,4,00104,"Mon Jan 05 00:00:00 1970 PST",4,"4 ",foo) + (105,5,00105,"Tue Jan 06 00:00:00 1970 PST",5,"5 ",foo) + (106,6,00106,"Wed Jan 07 00:00:00 1970 PST",6,"6 ",foo) + (107,7,00107,"Thu Jan 08 00:00:00 1970 PST",7,"7 ",foo) + (108,8,00108,"Fri Jan 09 00:00:00 1970 PST",8,"8 ",foo) + (109,9,00109,"Sat Jan 10 00:00:00 1970 PST",9,"9 ",foo) + (110,0,00110,"Sun Jan 11 00:00:00 1970 PST",0,"0 ",foo) (10 rows) -- empty result @@ -356,9 +356,9 @@ EXPLAIN (VERBOSE, COSTS OFF) SELECT * FROM ft1 t1 WHERE t1.c1 = 101 AND t1.c6 = --Testcase 38: SELECT * FROM ft1 t1 WHERE t1.c1 = 101 AND t1.c6 = '1' AND t1.c7 >= '1'; - c1 | c2 | c3 | time | c6 | c7 | c8 ------+----+-------+--------------------------+----+------------+----- - 101 | 1 | 00101 | Fri Jan 02 00:00:00 1970 | 1 | 1 | foo + c1 | c2 | c3 | time | c6 | c7 | c8 +-----+----+-------+------------------------------+----+------------+----- + 101 | 1 | 00101 | Fri Jan 02 00:00:00 1970 PST | 1 | 1 | foo (1 row) -- with FOR UPDATE/SHARE @@ -375,9 +375,9 @@ EXPLAIN (VERBOSE, COSTS OFF) SELECT * FROM ft1 t1 WHERE c1 = 101 FOR UPDATE; --Testcase 40: SELECT * FROM ft1 t1 WHERE c1 = 101 FOR UPDATE; - c1 | c2 | c3 | time | c6 | c7 | c8 ------+----+-------+--------------------------+----+------------+----- - 101 | 1 | 00101 | Fri Jan 02 00:00:00 1970 | 1 | 1 | foo + c1 | c2 | c3 | time | c6 | c7 | c8 +-----+----+-------+------------------------------+----+------------+----- + 101 | 1 | 00101 | Fri Jan 02 00:00:00 1970 PST | 1 | 1 | foo (1 row) --Testcase 41: @@ -393,9 +393,9 @@ EXPLAIN (VERBOSE, COSTS OFF) SELECT * FROM ft1 t1 WHERE c1 = 102 FOR SHARE; --Testcase 42: SELECT * FROM ft1 t1 WHERE c1 = 102 FOR SHARE; - c1 | c2 | c3 | time | c6 | c7 | c8 ------+----+-------+--------------------------+----+------------+----- - 102 | 2 | 00102 | Sat Jan 03 00:00:00 1970 | 2 | 2 | foo + c1 | c2 | c3 | time | c6 | c7 | c8 +-----+----+-------+------------------------------+----+------------+----- + 102 | 2 | 00102 | Sat Jan 03 00:00:00 1970 PST | 2 | 2 | foo (1 row) -- aggregate @@ -409,43 +409,43 @@ SELECT COUNT(*) FROM ft1 t1; -- subquery --Testcase 44: SELECT * FROM ft1 t1 WHERE t1.c3 IN (SELECT c3 FROM ft2 t2 WHERE c1 <= 10) ORDER BY c1; - c1 | c2 | c3 | time | c6 | c7 | c8 -----+----+-------+--------------------------+----+------------+----- - 1 | 1 | 00001 | Fri Jan 02 00:00:00 1970 | 1 | 1 | foo - 2 | 2 | 00002 | Sat Jan 03 00:00:00 1970 | 2 | 2 | foo - 3 | 3 | 00003 | Sun Jan 04 00:00:00 1970 | 3 | 3 | foo - 4 | 4 | 00004 | Mon Jan 05 00:00:00 1970 | 4 | 4 | foo - 5 | 5 | 00005 | Tue Jan 06 00:00:00 1970 | 5 | 5 | foo - 6 | 6 | 00006 | Wed Jan 07 00:00:00 1970 | 6 | 6 | foo - 7 | 7 | 00007 | Thu Jan 08 00:00:00 1970 | 7 | 7 | foo - 8 | 8 | 00008 | Fri Jan 09 00:00:00 1970 | 8 | 8 | foo - 9 | 9 | 00009 | Sat Jan 10 00:00:00 1970 | 9 | 9 | foo - 10 | 0 | 00010 | Sun Jan 11 00:00:00 1970 | 0 | 0 | foo + c1 | c2 | c3 | time | c6 | c7 | c8 +----+----+-------+------------------------------+----+------------+----- + 1 | 1 | 00001 | Fri Jan 02 00:00:00 1970 PST | 1 | 1 | foo + 2 | 2 | 00002 | Sat Jan 03 00:00:00 1970 PST | 2 | 2 | foo + 3 | 3 | 00003 | Sun Jan 04 00:00:00 1970 PST | 3 | 3 | foo + 4 | 4 | 00004 | Mon Jan 05 00:00:00 1970 PST | 4 | 4 | foo + 5 | 5 | 00005 | Tue Jan 06 00:00:00 1970 PST | 5 | 5 | foo + 6 | 6 | 00006 | Wed Jan 07 00:00:00 1970 PST | 6 | 6 | foo + 7 | 7 | 00007 | Thu Jan 08 00:00:00 1970 PST | 7 | 7 | foo + 8 | 8 | 00008 | Fri Jan 09 00:00:00 1970 PST | 8 | 8 | foo + 9 | 9 | 00009 | Sat Jan 10 00:00:00 1970 PST | 9 | 9 | foo + 10 | 0 | 00010 | Sun Jan 11 00:00:00 1970 PST | 0 | 0 | foo (10 rows) -- subquery+MAX --Testcase 45: SELECT * FROM ft1 t1 WHERE t1.c3 = (SELECT MAX(c3) FROM ft2 t2) ORDER BY c1; - c1 | c2 | c3 | time | c6 | c7 | c8 -------+----+-------+--------------------------+----+------------+----- - 1000 | 0 | 01000 | Thu Jan 01 00:00:00 1970 | 0 | 0 | foo + c1 | c2 | c3 | time | c6 | c7 | c8 +------+----+-------+------------------------------+----+------------+----- + 1000 | 0 | 01000 | Thu Jan 01 00:00:00 1970 PST | 0 | 0 | foo (1 row) -- used in CTE --Testcase 46: WITH t1 AS (SELECT * FROM ft1 WHERE c1 <= 10) SELECT t2.c1, t2.c2, t2.c3, t2.time FROM t1, ft2 t2 WHERE t1.c1 = t2.c1 ORDER BY t1.c1; - c1 | c2 | c3 | time -----+----+-------+-------------------------- - 1 | 1 | 00001 | Fri Jan 02 00:00:00 1970 - 2 | 2 | 00002 | Sat Jan 03 00:00:00 1970 - 3 | 3 | 00003 | Sun Jan 04 00:00:00 1970 - 4 | 4 | 00004 | Mon Jan 05 00:00:00 1970 - 5 | 5 | 00005 | Tue Jan 06 00:00:00 1970 - 6 | 6 | 00006 | Wed Jan 07 00:00:00 1970 - 7 | 7 | 00007 | Thu Jan 08 00:00:00 1970 - 8 | 8 | 00008 | Fri Jan 09 00:00:00 1970 - 9 | 9 | 00009 | Sat Jan 10 00:00:00 1970 - 10 | 0 | 00010 | Sun Jan 11 00:00:00 1970 + c1 | c2 | c3 | time +----+----+-------+------------------------------ + 1 | 1 | 00001 | Fri Jan 02 00:00:00 1970 PST + 2 | 2 | 00002 | Sat Jan 03 00:00:00 1970 PST + 3 | 3 | 00003 | Sun Jan 04 00:00:00 1970 PST + 4 | 4 | 00004 | Mon Jan 05 00:00:00 1970 PST + 5 | 5 | 00005 | Tue Jan 06 00:00:00 1970 PST + 6 | 6 | 00006 | Wed Jan 07 00:00:00 1970 PST + 7 | 7 | 00007 | Thu Jan 08 00:00:00 1970 PST + 8 | 8 | 00008 | Fri Jan 09 00:00:00 1970 PST + 9 | 9 | 00009 | Sat Jan 10 00:00:00 1970 PST + 10 | 0 | 00010 | Sun Jan 11 00:00:00 1970 PST (10 rows) -- fixed values @@ -842,9 +842,9 @@ EXPLAIN (VERBOSE, COSTS OFF) --Testcase 71: SELECT * FROM ft2 a, ft2 b WHERE a.c1 = 47 AND b.c1 = a.c2; - c1 | c2 | c3 | time | c6 | c7 | c8 | c1 | c2 | c3 | time | c6 | c7 | c8 -----+----+-------+--------------------------+----+------------+-----+----+----+-------+--------------------------+----+------------+----- - 47 | 7 | 00047 | Tue Feb 17 00:00:00 1970 | 7 | 7 | foo | 7 | 7 | 00007 | Thu Jan 08 00:00:00 1970 | 7 | 7 | foo + c1 | c2 | c3 | time | c6 | c7 | c8 | c1 | c2 | c3 | time | c6 | c7 | c8 +----+----+-------+------------------------------+----+------------+-----+----+----+-------+------------------------------+----+------------+----- + 47 | 7 | 00047 | Tue Feb 17 00:00:00 1970 PST | 7 | 7 | foo | 7 | 7 | 00007 | Thu Jan 08 00:00:00 1970 PST | 7 | 7 | foo (1 row) -- check both safe and unsafe join conditions @@ -870,129 +870,129 @@ EXPLAIN (VERBOSE, COSTS OFF) --Testcase 73: SELECT * FROM ft2 a, ft2 b WHERE a.c2 = 6 AND b.c1 = a.c1 AND a.c8 = 'foo' AND b.c7 = upper(a.c7) ORDER BY a.c1; - c1 | c2 | c3 | time | c6 | c7 | c8 | c1 | c2 | c3 | time | c6 | c7 | c8 ------+----+-------+--------------------------+----+------------+-----+-----+----+-------+--------------------------+----+------------+----- - 6 | 6 | 00006 | Wed Jan 07 00:00:00 1970 | 6 | 6 | foo | 6 | 6 | 00006 | Wed Jan 07 00:00:00 1970 | 6 | 6 | foo - 16 | 6 | 00016 | Sat Jan 17 00:00:00 1970 | 6 | 6 | foo | 16 | 6 | 00016 | Sat Jan 17 00:00:00 1970 | 6 | 6 | foo - 26 | 6 | 00026 | Tue Jan 27 00:00:00 1970 | 6 | 6 | foo | 26 | 6 | 00026 | Tue Jan 27 00:00:00 1970 | 6 | 6 | foo - 36 | 6 | 00036 | Fri Feb 06 00:00:00 1970 | 6 | 6 | foo | 36 | 6 | 00036 | Fri Feb 06 00:00:00 1970 | 6 | 6 | foo - 46 | 6 | 00046 | Mon Feb 16 00:00:00 1970 | 6 | 6 | foo | 46 | 6 | 00046 | Mon Feb 16 00:00:00 1970 | 6 | 6 | foo - 56 | 6 | 00056 | Thu Feb 26 00:00:00 1970 | 6 | 6 | foo | 56 | 6 | 00056 | Thu Feb 26 00:00:00 1970 | 6 | 6 | foo - 66 | 6 | 00066 | Sun Mar 08 00:00:00 1970 | 6 | 6 | foo | 66 | 6 | 00066 | Sun Mar 08 00:00:00 1970 | 6 | 6 | foo - 76 | 6 | 00076 | Wed Mar 18 00:00:00 1970 | 6 | 6 | foo | 76 | 6 | 00076 | Wed Mar 18 00:00:00 1970 | 6 | 6 | foo - 86 | 6 | 00086 | Sat Mar 28 00:00:00 1970 | 6 | 6 | foo | 86 | 6 | 00086 | Sat Mar 28 00:00:00 1970 | 6 | 6 | foo - 96 | 6 | 00096 | Tue Apr 07 00:00:00 1970 | 6 | 6 | foo | 96 | 6 | 00096 | Tue Apr 07 00:00:00 1970 | 6 | 6 | foo - 106 | 6 | 00106 | Wed Jan 07 00:00:00 1970 | 6 | 6 | foo | 106 | 6 | 00106 | Wed Jan 07 00:00:00 1970 | 6 | 6 | foo - 116 | 6 | 00116 | Sat Jan 17 00:00:00 1970 | 6 | 6 | foo | 116 | 6 | 00116 | Sat Jan 17 00:00:00 1970 | 6 | 6 | foo - 126 | 6 | 00126 | Tue Jan 27 00:00:00 1970 | 6 | 6 | foo | 126 | 6 | 00126 | Tue Jan 27 00:00:00 1970 | 6 | 6 | foo - 136 | 6 | 00136 | Fri Feb 06 00:00:00 1970 | 6 | 6 | foo | 136 | 6 | 00136 | Fri Feb 06 00:00:00 1970 | 6 | 6 | foo - 146 | 6 | 00146 | Mon Feb 16 00:00:00 1970 | 6 | 6 | foo | 146 | 6 | 00146 | Mon Feb 16 00:00:00 1970 | 6 | 6 | foo - 156 | 6 | 00156 | Thu Feb 26 00:00:00 1970 | 6 | 6 | foo | 156 | 6 | 00156 | Thu Feb 26 00:00:00 1970 | 6 | 6 | foo - 166 | 6 | 00166 | Sun Mar 08 00:00:00 1970 | 6 | 6 | foo | 166 | 6 | 00166 | Sun Mar 08 00:00:00 1970 | 6 | 6 | foo - 176 | 6 | 00176 | Wed Mar 18 00:00:00 1970 | 6 | 6 | foo | 176 | 6 | 00176 | Wed Mar 18 00:00:00 1970 | 6 | 6 | foo - 186 | 6 | 00186 | Sat Mar 28 00:00:00 1970 | 6 | 6 | foo | 186 | 6 | 00186 | Sat Mar 28 00:00:00 1970 | 6 | 6 | foo - 196 | 6 | 00196 | Tue Apr 07 00:00:00 1970 | 6 | 6 | foo | 196 | 6 | 00196 | Tue Apr 07 00:00:00 1970 | 6 | 6 | foo - 206 | 6 | 00206 | Wed Jan 07 00:00:00 1970 | 6 | 6 | foo | 206 | 6 | 00206 | Wed Jan 07 00:00:00 1970 | 6 | 6 | foo - 216 | 6 | 00216 | Sat Jan 17 00:00:00 1970 | 6 | 6 | foo | 216 | 6 | 00216 | Sat Jan 17 00:00:00 1970 | 6 | 6 | foo - 226 | 6 | 00226 | Tue Jan 27 00:00:00 1970 | 6 | 6 | foo | 226 | 6 | 00226 | Tue Jan 27 00:00:00 1970 | 6 | 6 | foo - 236 | 6 | 00236 | Fri Feb 06 00:00:00 1970 | 6 | 6 | foo | 236 | 6 | 00236 | Fri Feb 06 00:00:00 1970 | 6 | 6 | foo - 246 | 6 | 00246 | Mon Feb 16 00:00:00 1970 | 6 | 6 | foo | 246 | 6 | 00246 | Mon Feb 16 00:00:00 1970 | 6 | 6 | foo - 256 | 6 | 00256 | Thu Feb 26 00:00:00 1970 | 6 | 6 | foo | 256 | 6 | 00256 | Thu Feb 26 00:00:00 1970 | 6 | 6 | foo - 266 | 6 | 00266 | Sun Mar 08 00:00:00 1970 | 6 | 6 | foo | 266 | 6 | 00266 | Sun Mar 08 00:00:00 1970 | 6 | 6 | foo - 276 | 6 | 00276 | Wed Mar 18 00:00:00 1970 | 6 | 6 | foo | 276 | 6 | 00276 | Wed Mar 18 00:00:00 1970 | 6 | 6 | foo - 286 | 6 | 00286 | Sat Mar 28 00:00:00 1970 | 6 | 6 | foo | 286 | 6 | 00286 | Sat Mar 28 00:00:00 1970 | 6 | 6 | foo - 296 | 6 | 00296 | Tue Apr 07 00:00:00 1970 | 6 | 6 | foo | 296 | 6 | 00296 | Tue Apr 07 00:00:00 1970 | 6 | 6 | foo - 306 | 6 | 00306 | Wed Jan 07 00:00:00 1970 | 6 | 6 | foo | 306 | 6 | 00306 | Wed Jan 07 00:00:00 1970 | 6 | 6 | foo - 316 | 6 | 00316 | Sat Jan 17 00:00:00 1970 | 6 | 6 | foo | 316 | 6 | 00316 | Sat Jan 17 00:00:00 1970 | 6 | 6 | foo - 326 | 6 | 00326 | Tue Jan 27 00:00:00 1970 | 6 | 6 | foo | 326 | 6 | 00326 | Tue Jan 27 00:00:00 1970 | 6 | 6 | foo - 336 | 6 | 00336 | Fri Feb 06 00:00:00 1970 | 6 | 6 | foo | 336 | 6 | 00336 | Fri Feb 06 00:00:00 1970 | 6 | 6 | foo - 346 | 6 | 00346 | Mon Feb 16 00:00:00 1970 | 6 | 6 | foo | 346 | 6 | 00346 | Mon Feb 16 00:00:00 1970 | 6 | 6 | foo - 356 | 6 | 00356 | Thu Feb 26 00:00:00 1970 | 6 | 6 | foo | 356 | 6 | 00356 | Thu Feb 26 00:00:00 1970 | 6 | 6 | foo - 366 | 6 | 00366 | Sun Mar 08 00:00:00 1970 | 6 | 6 | foo | 366 | 6 | 00366 | Sun Mar 08 00:00:00 1970 | 6 | 6 | foo - 376 | 6 | 00376 | Wed Mar 18 00:00:00 1970 | 6 | 6 | foo | 376 | 6 | 00376 | Wed Mar 18 00:00:00 1970 | 6 | 6 | foo - 386 | 6 | 00386 | Sat Mar 28 00:00:00 1970 | 6 | 6 | foo | 386 | 6 | 00386 | Sat Mar 28 00:00:00 1970 | 6 | 6 | foo - 396 | 6 | 00396 | Tue Apr 07 00:00:00 1970 | 6 | 6 | foo | 396 | 6 | 00396 | Tue Apr 07 00:00:00 1970 | 6 | 6 | foo - 406 | 6 | 00406 | Wed Jan 07 00:00:00 1970 | 6 | 6 | foo | 406 | 6 | 00406 | Wed Jan 07 00:00:00 1970 | 6 | 6 | foo - 416 | 6 | 00416 | Sat Jan 17 00:00:00 1970 | 6 | 6 | foo | 416 | 6 | 00416 | Sat Jan 17 00:00:00 1970 | 6 | 6 | foo - 426 | 6 | 00426 | Tue Jan 27 00:00:00 1970 | 6 | 6 | foo | 426 | 6 | 00426 | Tue Jan 27 00:00:00 1970 | 6 | 6 | foo - 436 | 6 | 00436 | Fri Feb 06 00:00:00 1970 | 6 | 6 | foo | 436 | 6 | 00436 | Fri Feb 06 00:00:00 1970 | 6 | 6 | foo - 446 | 6 | 00446 | Mon Feb 16 00:00:00 1970 | 6 | 6 | foo | 446 | 6 | 00446 | Mon Feb 16 00:00:00 1970 | 6 | 6 | foo - 456 | 6 | 00456 | Thu Feb 26 00:00:00 1970 | 6 | 6 | foo | 456 | 6 | 00456 | Thu Feb 26 00:00:00 1970 | 6 | 6 | foo - 466 | 6 | 00466 | Sun Mar 08 00:00:00 1970 | 6 | 6 | foo | 466 | 6 | 00466 | Sun Mar 08 00:00:00 1970 | 6 | 6 | foo - 476 | 6 | 00476 | Wed Mar 18 00:00:00 1970 | 6 | 6 | foo | 476 | 6 | 00476 | Wed Mar 18 00:00:00 1970 | 6 | 6 | foo - 486 | 6 | 00486 | Sat Mar 28 00:00:00 1970 | 6 | 6 | foo | 486 | 6 | 00486 | Sat Mar 28 00:00:00 1970 | 6 | 6 | foo - 496 | 6 | 00496 | Tue Apr 07 00:00:00 1970 | 6 | 6 | foo | 496 | 6 | 00496 | Tue Apr 07 00:00:00 1970 | 6 | 6 | foo - 506 | 6 | 00506 | Wed Jan 07 00:00:00 1970 | 6 | 6 | foo | 506 | 6 | 00506 | Wed Jan 07 00:00:00 1970 | 6 | 6 | foo - 516 | 6 | 00516 | Sat Jan 17 00:00:00 1970 | 6 | 6 | foo | 516 | 6 | 00516 | Sat Jan 17 00:00:00 1970 | 6 | 6 | foo - 526 | 6 | 00526 | Tue Jan 27 00:00:00 1970 | 6 | 6 | foo | 526 | 6 | 00526 | Tue Jan 27 00:00:00 1970 | 6 | 6 | foo - 536 | 6 | 00536 | Fri Feb 06 00:00:00 1970 | 6 | 6 | foo | 536 | 6 | 00536 | Fri Feb 06 00:00:00 1970 | 6 | 6 | foo - 546 | 6 | 00546 | Mon Feb 16 00:00:00 1970 | 6 | 6 | foo | 546 | 6 | 00546 | Mon Feb 16 00:00:00 1970 | 6 | 6 | foo - 556 | 6 | 00556 | Thu Feb 26 00:00:00 1970 | 6 | 6 | foo | 556 | 6 | 00556 | Thu Feb 26 00:00:00 1970 | 6 | 6 | foo - 566 | 6 | 00566 | Sun Mar 08 00:00:00 1970 | 6 | 6 | foo | 566 | 6 | 00566 | Sun Mar 08 00:00:00 1970 | 6 | 6 | foo - 576 | 6 | 00576 | Wed Mar 18 00:00:00 1970 | 6 | 6 | foo | 576 | 6 | 00576 | Wed Mar 18 00:00:00 1970 | 6 | 6 | foo - 586 | 6 | 00586 | Sat Mar 28 00:00:00 1970 | 6 | 6 | foo | 586 | 6 | 00586 | Sat Mar 28 00:00:00 1970 | 6 | 6 | foo - 596 | 6 | 00596 | Tue Apr 07 00:00:00 1970 | 6 | 6 | foo | 596 | 6 | 00596 | Tue Apr 07 00:00:00 1970 | 6 | 6 | foo - 606 | 6 | 00606 | Wed Jan 07 00:00:00 1970 | 6 | 6 | foo | 606 | 6 | 00606 | Wed Jan 07 00:00:00 1970 | 6 | 6 | foo - 616 | 6 | 00616 | Sat Jan 17 00:00:00 1970 | 6 | 6 | foo | 616 | 6 | 00616 | Sat Jan 17 00:00:00 1970 | 6 | 6 | foo - 626 | 6 | 00626 | Tue Jan 27 00:00:00 1970 | 6 | 6 | foo | 626 | 6 | 00626 | Tue Jan 27 00:00:00 1970 | 6 | 6 | foo - 636 | 6 | 00636 | Fri Feb 06 00:00:00 1970 | 6 | 6 | foo | 636 | 6 | 00636 | Fri Feb 06 00:00:00 1970 | 6 | 6 | foo - 646 | 6 | 00646 | Mon Feb 16 00:00:00 1970 | 6 | 6 | foo | 646 | 6 | 00646 | Mon Feb 16 00:00:00 1970 | 6 | 6 | foo - 656 | 6 | 00656 | Thu Feb 26 00:00:00 1970 | 6 | 6 | foo | 656 | 6 | 00656 | Thu Feb 26 00:00:00 1970 | 6 | 6 | foo - 666 | 6 | 00666 | Sun Mar 08 00:00:00 1970 | 6 | 6 | foo | 666 | 6 | 00666 | Sun Mar 08 00:00:00 1970 | 6 | 6 | foo - 676 | 6 | 00676 | Wed Mar 18 00:00:00 1970 | 6 | 6 | foo | 676 | 6 | 00676 | Wed Mar 18 00:00:00 1970 | 6 | 6 | foo - 686 | 6 | 00686 | Sat Mar 28 00:00:00 1970 | 6 | 6 | foo | 686 | 6 | 00686 | Sat Mar 28 00:00:00 1970 | 6 | 6 | foo - 696 | 6 | 00696 | Tue Apr 07 00:00:00 1970 | 6 | 6 | foo | 696 | 6 | 00696 | Tue Apr 07 00:00:00 1970 | 6 | 6 | foo - 706 | 6 | 00706 | Wed Jan 07 00:00:00 1970 | 6 | 6 | foo | 706 | 6 | 00706 | Wed Jan 07 00:00:00 1970 | 6 | 6 | foo - 716 | 6 | 00716 | Sat Jan 17 00:00:00 1970 | 6 | 6 | foo | 716 | 6 | 00716 | Sat Jan 17 00:00:00 1970 | 6 | 6 | foo - 726 | 6 | 00726 | Tue Jan 27 00:00:00 1970 | 6 | 6 | foo | 726 | 6 | 00726 | Tue Jan 27 00:00:00 1970 | 6 | 6 | foo - 736 | 6 | 00736 | Fri Feb 06 00:00:00 1970 | 6 | 6 | foo | 736 | 6 | 00736 | Fri Feb 06 00:00:00 1970 | 6 | 6 | foo - 746 | 6 | 00746 | Mon Feb 16 00:00:00 1970 | 6 | 6 | foo | 746 | 6 | 00746 | Mon Feb 16 00:00:00 1970 | 6 | 6 | foo - 756 | 6 | 00756 | Thu Feb 26 00:00:00 1970 | 6 | 6 | foo | 756 | 6 | 00756 | Thu Feb 26 00:00:00 1970 | 6 | 6 | foo - 766 | 6 | 00766 | Sun Mar 08 00:00:00 1970 | 6 | 6 | foo | 766 | 6 | 00766 | Sun Mar 08 00:00:00 1970 | 6 | 6 | foo - 776 | 6 | 00776 | Wed Mar 18 00:00:00 1970 | 6 | 6 | foo | 776 | 6 | 00776 | Wed Mar 18 00:00:00 1970 | 6 | 6 | foo - 786 | 6 | 00786 | Sat Mar 28 00:00:00 1970 | 6 | 6 | foo | 786 | 6 | 00786 | Sat Mar 28 00:00:00 1970 | 6 | 6 | foo - 796 | 6 | 00796 | Tue Apr 07 00:00:00 1970 | 6 | 6 | foo | 796 | 6 | 00796 | Tue Apr 07 00:00:00 1970 | 6 | 6 | foo - 806 | 6 | 00806 | Wed Jan 07 00:00:00 1970 | 6 | 6 | foo | 806 | 6 | 00806 | Wed Jan 07 00:00:00 1970 | 6 | 6 | foo - 816 | 6 | 00816 | Sat Jan 17 00:00:00 1970 | 6 | 6 | foo | 816 | 6 | 00816 | Sat Jan 17 00:00:00 1970 | 6 | 6 | foo - 826 | 6 | 00826 | Tue Jan 27 00:00:00 1970 | 6 | 6 | foo | 826 | 6 | 00826 | Tue Jan 27 00:00:00 1970 | 6 | 6 | foo - 836 | 6 | 00836 | Fri Feb 06 00:00:00 1970 | 6 | 6 | foo | 836 | 6 | 00836 | Fri Feb 06 00:00:00 1970 | 6 | 6 | foo - 846 | 6 | 00846 | Mon Feb 16 00:00:00 1970 | 6 | 6 | foo | 846 | 6 | 00846 | Mon Feb 16 00:00:00 1970 | 6 | 6 | foo - 856 | 6 | 00856 | Thu Feb 26 00:00:00 1970 | 6 | 6 | foo | 856 | 6 | 00856 | Thu Feb 26 00:00:00 1970 | 6 | 6 | foo - 866 | 6 | 00866 | Sun Mar 08 00:00:00 1970 | 6 | 6 | foo | 866 | 6 | 00866 | Sun Mar 08 00:00:00 1970 | 6 | 6 | foo - 876 | 6 | 00876 | Wed Mar 18 00:00:00 1970 | 6 | 6 | foo | 876 | 6 | 00876 | Wed Mar 18 00:00:00 1970 | 6 | 6 | foo - 886 | 6 | 00886 | Sat Mar 28 00:00:00 1970 | 6 | 6 | foo | 886 | 6 | 00886 | Sat Mar 28 00:00:00 1970 | 6 | 6 | foo - 896 | 6 | 00896 | Tue Apr 07 00:00:00 1970 | 6 | 6 | foo | 896 | 6 | 00896 | Tue Apr 07 00:00:00 1970 | 6 | 6 | foo - 906 | 6 | 00906 | Wed Jan 07 00:00:00 1970 | 6 | 6 | foo | 906 | 6 | 00906 | Wed Jan 07 00:00:00 1970 | 6 | 6 | foo - 916 | 6 | 00916 | Sat Jan 17 00:00:00 1970 | 6 | 6 | foo | 916 | 6 | 00916 | Sat Jan 17 00:00:00 1970 | 6 | 6 | foo - 926 | 6 | 00926 | Tue Jan 27 00:00:00 1970 | 6 | 6 | foo | 926 | 6 | 00926 | Tue Jan 27 00:00:00 1970 | 6 | 6 | foo - 936 | 6 | 00936 | Fri Feb 06 00:00:00 1970 | 6 | 6 | foo | 936 | 6 | 00936 | Fri Feb 06 00:00:00 1970 | 6 | 6 | foo - 946 | 6 | 00946 | Mon Feb 16 00:00:00 1970 | 6 | 6 | foo | 946 | 6 | 00946 | Mon Feb 16 00:00:00 1970 | 6 | 6 | foo - 956 | 6 | 00956 | Thu Feb 26 00:00:00 1970 | 6 | 6 | foo | 956 | 6 | 00956 | Thu Feb 26 00:00:00 1970 | 6 | 6 | foo - 966 | 6 | 00966 | Sun Mar 08 00:00:00 1970 | 6 | 6 | foo | 966 | 6 | 00966 | Sun Mar 08 00:00:00 1970 | 6 | 6 | foo - 976 | 6 | 00976 | Wed Mar 18 00:00:00 1970 | 6 | 6 | foo | 976 | 6 | 00976 | Wed Mar 18 00:00:00 1970 | 6 | 6 | foo - 986 | 6 | 00986 | Sat Mar 28 00:00:00 1970 | 6 | 6 | foo | 986 | 6 | 00986 | Sat Mar 28 00:00:00 1970 | 6 | 6 | foo - 996 | 6 | 00996 | Tue Apr 07 00:00:00 1970 | 6 | 6 | foo | 996 | 6 | 00996 | Tue Apr 07 00:00:00 1970 | 6 | 6 | foo + c1 | c2 | c3 | time | c6 | c7 | c8 | c1 | c2 | c3 | time | c6 | c7 | c8 +-----+----+-------+------------------------------+----+------------+-----+-----+----+-------+------------------------------+----+------------+----- + 6 | 6 | 00006 | Wed Jan 07 00:00:00 1970 PST | 6 | 6 | foo | 6 | 6 | 00006 | Wed Jan 07 00:00:00 1970 PST | 6 | 6 | foo + 16 | 6 | 00016 | Sat Jan 17 00:00:00 1970 PST | 6 | 6 | foo | 16 | 6 | 00016 | Sat Jan 17 00:00:00 1970 PST | 6 | 6 | foo + 26 | 6 | 00026 | Tue Jan 27 00:00:00 1970 PST | 6 | 6 | foo | 26 | 6 | 00026 | Tue Jan 27 00:00:00 1970 PST | 6 | 6 | foo + 36 | 6 | 00036 | Fri Feb 06 00:00:00 1970 PST | 6 | 6 | foo | 36 | 6 | 00036 | Fri Feb 06 00:00:00 1970 PST | 6 | 6 | foo + 46 | 6 | 00046 | Mon Feb 16 00:00:00 1970 PST | 6 | 6 | foo | 46 | 6 | 00046 | Mon Feb 16 00:00:00 1970 PST | 6 | 6 | foo + 56 | 6 | 00056 | Thu Feb 26 00:00:00 1970 PST | 6 | 6 | foo | 56 | 6 | 00056 | Thu Feb 26 00:00:00 1970 PST | 6 | 6 | foo + 66 | 6 | 00066 | Sun Mar 08 00:00:00 1970 PST | 6 | 6 | foo | 66 | 6 | 00066 | Sun Mar 08 00:00:00 1970 PST | 6 | 6 | foo + 76 | 6 | 00076 | Wed Mar 18 00:00:00 1970 PST | 6 | 6 | foo | 76 | 6 | 00076 | Wed Mar 18 00:00:00 1970 PST | 6 | 6 | foo + 86 | 6 | 00086 | Sat Mar 28 00:00:00 1970 PST | 6 | 6 | foo | 86 | 6 | 00086 | Sat Mar 28 00:00:00 1970 PST | 6 | 6 | foo + 96 | 6 | 00096 | Tue Apr 07 00:00:00 1970 PST | 6 | 6 | foo | 96 | 6 | 00096 | Tue Apr 07 00:00:00 1970 PST | 6 | 6 | foo + 106 | 6 | 00106 | Wed Jan 07 00:00:00 1970 PST | 6 | 6 | foo | 106 | 6 | 00106 | Wed Jan 07 00:00:00 1970 PST | 6 | 6 | foo + 116 | 6 | 00116 | Sat Jan 17 00:00:00 1970 PST | 6 | 6 | foo | 116 | 6 | 00116 | Sat Jan 17 00:00:00 1970 PST | 6 | 6 | foo + 126 | 6 | 00126 | Tue Jan 27 00:00:00 1970 PST | 6 | 6 | foo | 126 | 6 | 00126 | Tue Jan 27 00:00:00 1970 PST | 6 | 6 | foo + 136 | 6 | 00136 | Fri Feb 06 00:00:00 1970 PST | 6 | 6 | foo | 136 | 6 | 00136 | Fri Feb 06 00:00:00 1970 PST | 6 | 6 | foo + 146 | 6 | 00146 | Mon Feb 16 00:00:00 1970 PST | 6 | 6 | foo | 146 | 6 | 00146 | Mon Feb 16 00:00:00 1970 PST | 6 | 6 | foo + 156 | 6 | 00156 | Thu Feb 26 00:00:00 1970 PST | 6 | 6 | foo | 156 | 6 | 00156 | Thu Feb 26 00:00:00 1970 PST | 6 | 6 | foo + 166 | 6 | 00166 | Sun Mar 08 00:00:00 1970 PST | 6 | 6 | foo | 166 | 6 | 00166 | Sun Mar 08 00:00:00 1970 PST | 6 | 6 | foo + 176 | 6 | 00176 | Wed Mar 18 00:00:00 1970 PST | 6 | 6 | foo | 176 | 6 | 00176 | Wed Mar 18 00:00:00 1970 PST | 6 | 6 | foo + 186 | 6 | 00186 | Sat Mar 28 00:00:00 1970 PST | 6 | 6 | foo | 186 | 6 | 00186 | Sat Mar 28 00:00:00 1970 PST | 6 | 6 | foo + 196 | 6 | 00196 | Tue Apr 07 00:00:00 1970 PST | 6 | 6 | foo | 196 | 6 | 00196 | Tue Apr 07 00:00:00 1970 PST | 6 | 6 | foo + 206 | 6 | 00206 | Wed Jan 07 00:00:00 1970 PST | 6 | 6 | foo | 206 | 6 | 00206 | Wed Jan 07 00:00:00 1970 PST | 6 | 6 | foo + 216 | 6 | 00216 | Sat Jan 17 00:00:00 1970 PST | 6 | 6 | foo | 216 | 6 | 00216 | Sat Jan 17 00:00:00 1970 PST | 6 | 6 | foo + 226 | 6 | 00226 | Tue Jan 27 00:00:00 1970 PST | 6 | 6 | foo | 226 | 6 | 00226 | Tue Jan 27 00:00:00 1970 PST | 6 | 6 | foo + 236 | 6 | 00236 | Fri Feb 06 00:00:00 1970 PST | 6 | 6 | foo | 236 | 6 | 00236 | Fri Feb 06 00:00:00 1970 PST | 6 | 6 | foo + 246 | 6 | 00246 | Mon Feb 16 00:00:00 1970 PST | 6 | 6 | foo | 246 | 6 | 00246 | Mon Feb 16 00:00:00 1970 PST | 6 | 6 | foo + 256 | 6 | 00256 | Thu Feb 26 00:00:00 1970 PST | 6 | 6 | foo | 256 | 6 | 00256 | Thu Feb 26 00:00:00 1970 PST | 6 | 6 | foo + 266 | 6 | 00266 | Sun Mar 08 00:00:00 1970 PST | 6 | 6 | foo | 266 | 6 | 00266 | Sun Mar 08 00:00:00 1970 PST | 6 | 6 | foo + 276 | 6 | 00276 | Wed Mar 18 00:00:00 1970 PST | 6 | 6 | foo | 276 | 6 | 00276 | Wed Mar 18 00:00:00 1970 PST | 6 | 6 | foo + 286 | 6 | 00286 | Sat Mar 28 00:00:00 1970 PST | 6 | 6 | foo | 286 | 6 | 00286 | Sat Mar 28 00:00:00 1970 PST | 6 | 6 | foo + 296 | 6 | 00296 | Tue Apr 07 00:00:00 1970 PST | 6 | 6 | foo | 296 | 6 | 00296 | Tue Apr 07 00:00:00 1970 PST | 6 | 6 | foo + 306 | 6 | 00306 | Wed Jan 07 00:00:00 1970 PST | 6 | 6 | foo | 306 | 6 | 00306 | Wed Jan 07 00:00:00 1970 PST | 6 | 6 | foo + 316 | 6 | 00316 | Sat Jan 17 00:00:00 1970 PST | 6 | 6 | foo | 316 | 6 | 00316 | Sat Jan 17 00:00:00 1970 PST | 6 | 6 | foo + 326 | 6 | 00326 | Tue Jan 27 00:00:00 1970 PST | 6 | 6 | foo | 326 | 6 | 00326 | Tue Jan 27 00:00:00 1970 PST | 6 | 6 | foo + 336 | 6 | 00336 | Fri Feb 06 00:00:00 1970 PST | 6 | 6 | foo | 336 | 6 | 00336 | Fri Feb 06 00:00:00 1970 PST | 6 | 6 | foo + 346 | 6 | 00346 | Mon Feb 16 00:00:00 1970 PST | 6 | 6 | foo | 346 | 6 | 00346 | Mon Feb 16 00:00:00 1970 PST | 6 | 6 | foo + 356 | 6 | 00356 | Thu Feb 26 00:00:00 1970 PST | 6 | 6 | foo | 356 | 6 | 00356 | Thu Feb 26 00:00:00 1970 PST | 6 | 6 | foo + 366 | 6 | 00366 | Sun Mar 08 00:00:00 1970 PST | 6 | 6 | foo | 366 | 6 | 00366 | Sun Mar 08 00:00:00 1970 PST | 6 | 6 | foo + 376 | 6 | 00376 | Wed Mar 18 00:00:00 1970 PST | 6 | 6 | foo | 376 | 6 | 00376 | Wed Mar 18 00:00:00 1970 PST | 6 | 6 | foo + 386 | 6 | 00386 | Sat Mar 28 00:00:00 1970 PST | 6 | 6 | foo | 386 | 6 | 00386 | Sat Mar 28 00:00:00 1970 PST | 6 | 6 | foo + 396 | 6 | 00396 | Tue Apr 07 00:00:00 1970 PST | 6 | 6 | foo | 396 | 6 | 00396 | Tue Apr 07 00:00:00 1970 PST | 6 | 6 | foo + 406 | 6 | 00406 | Wed Jan 07 00:00:00 1970 PST | 6 | 6 | foo | 406 | 6 | 00406 | Wed Jan 07 00:00:00 1970 PST | 6 | 6 | foo + 416 | 6 | 00416 | Sat Jan 17 00:00:00 1970 PST | 6 | 6 | foo | 416 | 6 | 00416 | Sat Jan 17 00:00:00 1970 PST | 6 | 6 | foo + 426 | 6 | 00426 | Tue Jan 27 00:00:00 1970 PST | 6 | 6 | foo | 426 | 6 | 00426 | Tue Jan 27 00:00:00 1970 PST | 6 | 6 | foo + 436 | 6 | 00436 | Fri Feb 06 00:00:00 1970 PST | 6 | 6 | foo | 436 | 6 | 00436 | Fri Feb 06 00:00:00 1970 PST | 6 | 6 | foo + 446 | 6 | 00446 | Mon Feb 16 00:00:00 1970 PST | 6 | 6 | foo | 446 | 6 | 00446 | Mon Feb 16 00:00:00 1970 PST | 6 | 6 | foo + 456 | 6 | 00456 | Thu Feb 26 00:00:00 1970 PST | 6 | 6 | foo | 456 | 6 | 00456 | Thu Feb 26 00:00:00 1970 PST | 6 | 6 | foo + 466 | 6 | 00466 | Sun Mar 08 00:00:00 1970 PST | 6 | 6 | foo | 466 | 6 | 00466 | Sun Mar 08 00:00:00 1970 PST | 6 | 6 | foo + 476 | 6 | 00476 | Wed Mar 18 00:00:00 1970 PST | 6 | 6 | foo | 476 | 6 | 00476 | Wed Mar 18 00:00:00 1970 PST | 6 | 6 | foo + 486 | 6 | 00486 | Sat Mar 28 00:00:00 1970 PST | 6 | 6 | foo | 486 | 6 | 00486 | Sat Mar 28 00:00:00 1970 PST | 6 | 6 | foo + 496 | 6 | 00496 | Tue Apr 07 00:00:00 1970 PST | 6 | 6 | foo | 496 | 6 | 00496 | Tue Apr 07 00:00:00 1970 PST | 6 | 6 | foo + 506 | 6 | 00506 | Wed Jan 07 00:00:00 1970 PST | 6 | 6 | foo | 506 | 6 | 00506 | Wed Jan 07 00:00:00 1970 PST | 6 | 6 | foo + 516 | 6 | 00516 | Sat Jan 17 00:00:00 1970 PST | 6 | 6 | foo | 516 | 6 | 00516 | Sat Jan 17 00:00:00 1970 PST | 6 | 6 | foo + 526 | 6 | 00526 | Tue Jan 27 00:00:00 1970 PST | 6 | 6 | foo | 526 | 6 | 00526 | Tue Jan 27 00:00:00 1970 PST | 6 | 6 | foo + 536 | 6 | 00536 | Fri Feb 06 00:00:00 1970 PST | 6 | 6 | foo | 536 | 6 | 00536 | Fri Feb 06 00:00:00 1970 PST | 6 | 6 | foo + 546 | 6 | 00546 | Mon Feb 16 00:00:00 1970 PST | 6 | 6 | foo | 546 | 6 | 00546 | Mon Feb 16 00:00:00 1970 PST | 6 | 6 | foo + 556 | 6 | 00556 | Thu Feb 26 00:00:00 1970 PST | 6 | 6 | foo | 556 | 6 | 00556 | Thu Feb 26 00:00:00 1970 PST | 6 | 6 | foo + 566 | 6 | 00566 | Sun Mar 08 00:00:00 1970 PST | 6 | 6 | foo | 566 | 6 | 00566 | Sun Mar 08 00:00:00 1970 PST | 6 | 6 | foo + 576 | 6 | 00576 | Wed Mar 18 00:00:00 1970 PST | 6 | 6 | foo | 576 | 6 | 00576 | Wed Mar 18 00:00:00 1970 PST | 6 | 6 | foo + 586 | 6 | 00586 | Sat Mar 28 00:00:00 1970 PST | 6 | 6 | foo | 586 | 6 | 00586 | Sat Mar 28 00:00:00 1970 PST | 6 | 6 | foo + 596 | 6 | 00596 | Tue Apr 07 00:00:00 1970 PST | 6 | 6 | foo | 596 | 6 | 00596 | Tue Apr 07 00:00:00 1970 PST | 6 | 6 | foo + 606 | 6 | 00606 | Wed Jan 07 00:00:00 1970 PST | 6 | 6 | foo | 606 | 6 | 00606 | Wed Jan 07 00:00:00 1970 PST | 6 | 6 | foo + 616 | 6 | 00616 | Sat Jan 17 00:00:00 1970 PST | 6 | 6 | foo | 616 | 6 | 00616 | Sat Jan 17 00:00:00 1970 PST | 6 | 6 | foo + 626 | 6 | 00626 | Tue Jan 27 00:00:00 1970 PST | 6 | 6 | foo | 626 | 6 | 00626 | Tue Jan 27 00:00:00 1970 PST | 6 | 6 | foo + 636 | 6 | 00636 | Fri Feb 06 00:00:00 1970 PST | 6 | 6 | foo | 636 | 6 | 00636 | Fri Feb 06 00:00:00 1970 PST | 6 | 6 | foo + 646 | 6 | 00646 | Mon Feb 16 00:00:00 1970 PST | 6 | 6 | foo | 646 | 6 | 00646 | Mon Feb 16 00:00:00 1970 PST | 6 | 6 | foo + 656 | 6 | 00656 | Thu Feb 26 00:00:00 1970 PST | 6 | 6 | foo | 656 | 6 | 00656 | Thu Feb 26 00:00:00 1970 PST | 6 | 6 | foo + 666 | 6 | 00666 | Sun Mar 08 00:00:00 1970 PST | 6 | 6 | foo | 666 | 6 | 00666 | Sun Mar 08 00:00:00 1970 PST | 6 | 6 | foo + 676 | 6 | 00676 | Wed Mar 18 00:00:00 1970 PST | 6 | 6 | foo | 676 | 6 | 00676 | Wed Mar 18 00:00:00 1970 PST | 6 | 6 | foo + 686 | 6 | 00686 | Sat Mar 28 00:00:00 1970 PST | 6 | 6 | foo | 686 | 6 | 00686 | Sat Mar 28 00:00:00 1970 PST | 6 | 6 | foo + 696 | 6 | 00696 | Tue Apr 07 00:00:00 1970 PST | 6 | 6 | foo | 696 | 6 | 00696 | Tue Apr 07 00:00:00 1970 PST | 6 | 6 | foo + 706 | 6 | 00706 | Wed Jan 07 00:00:00 1970 PST | 6 | 6 | foo | 706 | 6 | 00706 | Wed Jan 07 00:00:00 1970 PST | 6 | 6 | foo + 716 | 6 | 00716 | Sat Jan 17 00:00:00 1970 PST | 6 | 6 | foo | 716 | 6 | 00716 | Sat Jan 17 00:00:00 1970 PST | 6 | 6 | foo + 726 | 6 | 00726 | Tue Jan 27 00:00:00 1970 PST | 6 | 6 | foo | 726 | 6 | 00726 | Tue Jan 27 00:00:00 1970 PST | 6 | 6 | foo + 736 | 6 | 00736 | Fri Feb 06 00:00:00 1970 PST | 6 | 6 | foo | 736 | 6 | 00736 | Fri Feb 06 00:00:00 1970 PST | 6 | 6 | foo + 746 | 6 | 00746 | Mon Feb 16 00:00:00 1970 PST | 6 | 6 | foo | 746 | 6 | 00746 | Mon Feb 16 00:00:00 1970 PST | 6 | 6 | foo + 756 | 6 | 00756 | Thu Feb 26 00:00:00 1970 PST | 6 | 6 | foo | 756 | 6 | 00756 | Thu Feb 26 00:00:00 1970 PST | 6 | 6 | foo + 766 | 6 | 00766 | Sun Mar 08 00:00:00 1970 PST | 6 | 6 | foo | 766 | 6 | 00766 | Sun Mar 08 00:00:00 1970 PST | 6 | 6 | foo + 776 | 6 | 00776 | Wed Mar 18 00:00:00 1970 PST | 6 | 6 | foo | 776 | 6 | 00776 | Wed Mar 18 00:00:00 1970 PST | 6 | 6 | foo + 786 | 6 | 00786 | Sat Mar 28 00:00:00 1970 PST | 6 | 6 | foo | 786 | 6 | 00786 | Sat Mar 28 00:00:00 1970 PST | 6 | 6 | foo + 796 | 6 | 00796 | Tue Apr 07 00:00:00 1970 PST | 6 | 6 | foo | 796 | 6 | 00796 | Tue Apr 07 00:00:00 1970 PST | 6 | 6 | foo + 806 | 6 | 00806 | Wed Jan 07 00:00:00 1970 PST | 6 | 6 | foo | 806 | 6 | 00806 | Wed Jan 07 00:00:00 1970 PST | 6 | 6 | foo + 816 | 6 | 00816 | Sat Jan 17 00:00:00 1970 PST | 6 | 6 | foo | 816 | 6 | 00816 | Sat Jan 17 00:00:00 1970 PST | 6 | 6 | foo + 826 | 6 | 00826 | Tue Jan 27 00:00:00 1970 PST | 6 | 6 | foo | 826 | 6 | 00826 | Tue Jan 27 00:00:00 1970 PST | 6 | 6 | foo + 836 | 6 | 00836 | Fri Feb 06 00:00:00 1970 PST | 6 | 6 | foo | 836 | 6 | 00836 | Fri Feb 06 00:00:00 1970 PST | 6 | 6 | foo + 846 | 6 | 00846 | Mon Feb 16 00:00:00 1970 PST | 6 | 6 | foo | 846 | 6 | 00846 | Mon Feb 16 00:00:00 1970 PST | 6 | 6 | foo + 856 | 6 | 00856 | Thu Feb 26 00:00:00 1970 PST | 6 | 6 | foo | 856 | 6 | 00856 | Thu Feb 26 00:00:00 1970 PST | 6 | 6 | foo + 866 | 6 | 00866 | Sun Mar 08 00:00:00 1970 PST | 6 | 6 | foo | 866 | 6 | 00866 | Sun Mar 08 00:00:00 1970 PST | 6 | 6 | foo + 876 | 6 | 00876 | Wed Mar 18 00:00:00 1970 PST | 6 | 6 | foo | 876 | 6 | 00876 | Wed Mar 18 00:00:00 1970 PST | 6 | 6 | foo + 886 | 6 | 00886 | Sat Mar 28 00:00:00 1970 PST | 6 | 6 | foo | 886 | 6 | 00886 | Sat Mar 28 00:00:00 1970 PST | 6 | 6 | foo + 896 | 6 | 00896 | Tue Apr 07 00:00:00 1970 PST | 6 | 6 | foo | 896 | 6 | 00896 | Tue Apr 07 00:00:00 1970 PST | 6 | 6 | foo + 906 | 6 | 00906 | Wed Jan 07 00:00:00 1970 PST | 6 | 6 | foo | 906 | 6 | 00906 | Wed Jan 07 00:00:00 1970 PST | 6 | 6 | foo + 916 | 6 | 00916 | Sat Jan 17 00:00:00 1970 PST | 6 | 6 | foo | 916 | 6 | 00916 | Sat Jan 17 00:00:00 1970 PST | 6 | 6 | foo + 926 | 6 | 00926 | Tue Jan 27 00:00:00 1970 PST | 6 | 6 | foo | 926 | 6 | 00926 | Tue Jan 27 00:00:00 1970 PST | 6 | 6 | foo + 936 | 6 | 00936 | Fri Feb 06 00:00:00 1970 PST | 6 | 6 | foo | 936 | 6 | 00936 | Fri Feb 06 00:00:00 1970 PST | 6 | 6 | foo + 946 | 6 | 00946 | Mon Feb 16 00:00:00 1970 PST | 6 | 6 | foo | 946 | 6 | 00946 | Mon Feb 16 00:00:00 1970 PST | 6 | 6 | foo + 956 | 6 | 00956 | Thu Feb 26 00:00:00 1970 PST | 6 | 6 | foo | 956 | 6 | 00956 | Thu Feb 26 00:00:00 1970 PST | 6 | 6 | foo + 966 | 6 | 00966 | Sun Mar 08 00:00:00 1970 PST | 6 | 6 | foo | 966 | 6 | 00966 | Sun Mar 08 00:00:00 1970 PST | 6 | 6 | foo + 976 | 6 | 00976 | Wed Mar 18 00:00:00 1970 PST | 6 | 6 | foo | 976 | 6 | 00976 | Wed Mar 18 00:00:00 1970 PST | 6 | 6 | foo + 986 | 6 | 00986 | Sat Mar 28 00:00:00 1970 PST | 6 | 6 | foo | 986 | 6 | 00986 | Sat Mar 28 00:00:00 1970 PST | 6 | 6 | foo + 996 | 6 | 00996 | Tue Apr 07 00:00:00 1970 PST | 6 | 6 | foo | 996 | 6 | 00996 | Tue Apr 07 00:00:00 1970 PST | 6 | 6 | foo (100 rows) -- bug before 9.3.5 due to sloppy handling of remote-estimate parameters --Testcase 74: SELECT * FROM ft1 WHERE c1 = ANY (ARRAY(SELECT c1 FROM ft2 WHERE c1 < 5)); - c1 | c2 | c3 | time | c6 | c7 | c8 -----+----+-------+--------------------------+----+------------+----- - 1 | 1 | 00001 | Fri Jan 02 00:00:00 1970 | 1 | 1 | foo - 2 | 2 | 00002 | Sat Jan 03 00:00:00 1970 | 2 | 2 | foo - 3 | 3 | 00003 | Sun Jan 04 00:00:00 1970 | 3 | 3 | foo - 4 | 4 | 00004 | Mon Jan 05 00:00:00 1970 | 4 | 4 | foo + c1 | c2 | c3 | time | c6 | c7 | c8 +----+----+-------+------------------------------+----+------------+----- + 1 | 1 | 00001 | Fri Jan 02 00:00:00 1970 PST | 1 | 1 | foo + 2 | 2 | 00002 | Sat Jan 03 00:00:00 1970 PST | 2 | 2 | foo + 3 | 3 | 00003 | Sun Jan 04 00:00:00 1970 PST | 3 | 3 | foo + 4 | 4 | 00004 | Mon Jan 05 00:00:00 1970 PST | 4 | 4 | foo (4 rows) --Testcase 75: SELECT * FROM ft2 WHERE c1 = ANY (ARRAY(SELECT c1 FROM ft1 WHERE c1 < 5)); - c1 | c2 | c3 | time | c6 | c7 | c8 -----+----+-------+--------------------------+----+------------+----- - 1 | 1 | 00001 | Fri Jan 02 00:00:00 1970 | 1 | 1 | foo - 2 | 2 | 00002 | Sat Jan 03 00:00:00 1970 | 2 | 2 | foo - 3 | 3 | 00003 | Sun Jan 04 00:00:00 1970 | 3 | 3 | foo - 4 | 4 | 00004 | Mon Jan 05 00:00:00 1970 | 4 | 4 | foo + c1 | c2 | c3 | time | c6 | c7 | c8 +----+----+-------+------------------------------+----+------------+----- + 1 | 1 | 00001 | Fri Jan 02 00:00:00 1970 PST | 1 | 1 | foo + 2 | 2 | 00002 | Sat Jan 03 00:00:00 1970 PST | 2 | 2 | foo + 3 | 3 | 00003 | Sun Jan 04 00:00:00 1970 PST | 3 | 3 | foo + 4 | 4 | 00004 | Mon Jan 05 00:00:00 1970 PST | 4 | 4 | foo (4 rows) -- we should not push order by clause with volatile expressions or unsafe @@ -1136,9 +1136,9 @@ EXPLAIN (VERBOSE, COSTS OFF) --Testcase 89: SELECT * FROM ft1 t1 WHERE t1.c1 === t1.c2 order by t1.c2 limit 1; - c1 | c2 | c3 | time | c6 | c7 | c8 -----+----+-------+--------------------------+----+------------+----- - 1 | 1 | 00001 | Fri Jan 02 00:00:00 1970 | 1 | 1 | foo + c1 | c2 | c3 | time | c6 | c7 | c8 +----+----+-------+------------------------------+----+------------+----- + 1 | 1 | 00001 | Fri Jan 02 00:00:00 1970 PST | 1 | 1 | foo (1 row) -- but let's put them in an extension ... @@ -1205,9 +1205,9 @@ EXPLAIN (VERBOSE, COSTS OFF) --Testcase 95: SELECT * FROM ft1 t1 WHERE t1.c1 === t1.c2 order by t1.c2 limit 1; - c1 | c2 | c3 | time | c6 | c7 | c8 -----+----+-------+--------------------------+----+------------+----- - 1 | 1 | 00001 | Fri Jan 02 00:00:00 1970 | 1 | 1 | foo + c1 | c2 | c3 | time | c6 | c7 | c8 +----+----+-------+------------------------------+----+------------+----- + 1 | 1 | 00001 | Fri Jan 02 00:00:00 1970 PST | 1 | 1 | foo (1 row) -- =================================================================== @@ -3056,18 +3056,18 @@ SELECT * FROM ft1, ft2, ft4, ft5, local_tbl WHERE ft1.c1 = ft2.c1 AND ft1.c2 = f --Testcase 181: SELECT * FROM ft1, ft2, ft4, ft5, local_tbl WHERE ft1.c1 = ft2.c1 AND ft1.c2 = ft4.c1 AND ft1.c2 = ft5.c1 AND ft1.c2 = local_tbl.c1 AND ft1.c1 < 100 AND ft2.c1 < 100 ORDER BY ft1.c1 FOR UPDATE; - c1 | c2 | c3 | time | c6 | c7 | c8 | c1 | c2 | c3 | time | c6 | c7 | c8 | c1 | c2 | c3 | c1 | c2 | c3 | c1 | c2 | c3 -----+----+-------+--------------------------+----+------------+-----+----+----+-------+--------------------------+----+------------+-----+----+----+--------+----+----+--------+----+----+------ - 6 | 6 | 00006 | Wed Jan 07 00:00:00 1970 | 6 | 6 | foo | 6 | 6 | 00006 | Wed Jan 07 00:00:00 1970 | 6 | 6 | foo | 6 | 7 | AAA006 | 6 | 7 | AAA006 | 6 | 6 | 0006 - 16 | 6 | 00016 | Sat Jan 17 00:00:00 1970 | 6 | 6 | foo | 16 | 6 | 00016 | Sat Jan 17 00:00:00 1970 | 6 | 6 | foo | 6 | 7 | AAA006 | 6 | 7 | AAA006 | 6 | 6 | 0006 - 26 | 6 | 00026 | Tue Jan 27 00:00:00 1970 | 6 | 6 | foo | 26 | 6 | 00026 | Tue Jan 27 00:00:00 1970 | 6 | 6 | foo | 6 | 7 | AAA006 | 6 | 7 | AAA006 | 6 | 6 | 0006 - 36 | 6 | 00036 | Fri Feb 06 00:00:00 1970 | 6 | 6 | foo | 36 | 6 | 00036 | Fri Feb 06 00:00:00 1970 | 6 | 6 | foo | 6 | 7 | AAA006 | 6 | 7 | AAA006 | 6 | 6 | 0006 - 46 | 6 | 00046 | Mon Feb 16 00:00:00 1970 | 6 | 6 | foo | 46 | 6 | 00046 | Mon Feb 16 00:00:00 1970 | 6 | 6 | foo | 6 | 7 | AAA006 | 6 | 7 | AAA006 | 6 | 6 | 0006 - 56 | 6 | 00056 | Thu Feb 26 00:00:00 1970 | 6 | 6 | foo | 56 | 6 | 00056 | Thu Feb 26 00:00:00 1970 | 6 | 6 | foo | 6 | 7 | AAA006 | 6 | 7 | AAA006 | 6 | 6 | 0006 - 66 | 6 | 00066 | Sun Mar 08 00:00:00 1970 | 6 | 6 | foo | 66 | 6 | 00066 | Sun Mar 08 00:00:00 1970 | 6 | 6 | foo | 6 | 7 | AAA006 | 6 | 7 | AAA006 | 6 | 6 | 0006 - 76 | 6 | 00076 | Wed Mar 18 00:00:00 1970 | 6 | 6 | foo | 76 | 6 | 00076 | Wed Mar 18 00:00:00 1970 | 6 | 6 | foo | 6 | 7 | AAA006 | 6 | 7 | AAA006 | 6 | 6 | 0006 - 86 | 6 | 00086 | Sat Mar 28 00:00:00 1970 | 6 | 6 | foo | 86 | 6 | 00086 | Sat Mar 28 00:00:00 1970 | 6 | 6 | foo | 6 | 7 | AAA006 | 6 | 7 | AAA006 | 6 | 6 | 0006 - 96 | 6 | 00096 | Tue Apr 07 00:00:00 1970 | 6 | 6 | foo | 96 | 6 | 00096 | Tue Apr 07 00:00:00 1970 | 6 | 6 | foo | 6 | 7 | AAA006 | 6 | 7 | AAA006 | 6 | 6 | 0006 + c1 | c2 | c3 | time | c6 | c7 | c8 | c1 | c2 | c3 | time | c6 | c7 | c8 | c1 | c2 | c3 | c1 | c2 | c3 | c1 | c2 | c3 +----+----+-------+------------------------------+----+------------+-----+----+----+-------+------------------------------+----+------------+-----+----+----+--------+----+----+--------+----+----+------ + 6 | 6 | 00006 | Wed Jan 07 00:00:00 1970 PST | 6 | 6 | foo | 6 | 6 | 00006 | Wed Jan 07 00:00:00 1970 PST | 6 | 6 | foo | 6 | 7 | AAA006 | 6 | 7 | AAA006 | 6 | 6 | 0006 + 16 | 6 | 00016 | Sat Jan 17 00:00:00 1970 PST | 6 | 6 | foo | 16 | 6 | 00016 | Sat Jan 17 00:00:00 1970 PST | 6 | 6 | foo | 6 | 7 | AAA006 | 6 | 7 | AAA006 | 6 | 6 | 0006 + 26 | 6 | 00026 | Tue Jan 27 00:00:00 1970 PST | 6 | 6 | foo | 26 | 6 | 00026 | Tue Jan 27 00:00:00 1970 PST | 6 | 6 | foo | 6 | 7 | AAA006 | 6 | 7 | AAA006 | 6 | 6 | 0006 + 36 | 6 | 00036 | Fri Feb 06 00:00:00 1970 PST | 6 | 6 | foo | 36 | 6 | 00036 | Fri Feb 06 00:00:00 1970 PST | 6 | 6 | foo | 6 | 7 | AAA006 | 6 | 7 | AAA006 | 6 | 6 | 0006 + 46 | 6 | 00046 | Mon Feb 16 00:00:00 1970 PST | 6 | 6 | foo | 46 | 6 | 00046 | Mon Feb 16 00:00:00 1970 PST | 6 | 6 | foo | 6 | 7 | AAA006 | 6 | 7 | AAA006 | 6 | 6 | 0006 + 56 | 6 | 00056 | Thu Feb 26 00:00:00 1970 PST | 6 | 6 | foo | 56 | 6 | 00056 | Thu Feb 26 00:00:00 1970 PST | 6 | 6 | foo | 6 | 7 | AAA006 | 6 | 7 | AAA006 | 6 | 6 | 0006 + 66 | 6 | 00066 | Sun Mar 08 00:00:00 1970 PST | 6 | 6 | foo | 66 | 6 | 00066 | Sun Mar 08 00:00:00 1970 PST | 6 | 6 | foo | 6 | 7 | AAA006 | 6 | 7 | AAA006 | 6 | 6 | 0006 + 76 | 6 | 00076 | Wed Mar 18 00:00:00 1970 PST | 6 | 6 | foo | 76 | 6 | 00076 | Wed Mar 18 00:00:00 1970 PST | 6 | 6 | foo | 6 | 7 | AAA006 | 6 | 7 | AAA006 | 6 | 6 | 0006 + 86 | 6 | 00086 | Sat Mar 28 00:00:00 1970 PST | 6 | 6 | foo | 86 | 6 | 00086 | Sat Mar 28 00:00:00 1970 PST | 6 | 6 | foo | 6 | 7 | AAA006 | 6 | 7 | AAA006 | 6 | 6 | 0006 + 96 | 6 | 00096 | Tue Apr 07 00:00:00 1970 PST | 6 | 6 | foo | 96 | 6 | 00096 | Tue Apr 07 00:00:00 1970 PST | 6 | 6 | foo | 6 | 7 | AAA006 | 6 | 7 | AAA006 | 6 | 6 | 0006 (10 rows) RESET enable_nestloop; @@ -3720,9 +3720,9 @@ select array_agg(time order by c1 desc) from ft2 where c2 = 6 and c1 < 50; --Testcase 228: select array_agg(time order by c1 desc) from ft2 where c2 = 6 and c1 < 50; - array_agg ------------------------------------------------------------------------------------------------------------------------------------------- - {"Mon Feb 16 00:00:00 1970","Fri Feb 06 00:00:00 1970","Tue Jan 27 00:00:00 1970","Sat Jan 17 00:00:00 1970","Wed Jan 07 00:00:00 1970"} + array_agg +-------------------------------------------------------------------------------------------------------------------------------------------------------------- + {"Mon Feb 16 00:00:00 1970 PST","Fri Feb 06 00:00:00 1970 PST","Tue Jan 27 00:00:00 1970 PST","Sat Jan 17 00:00:00 1970 PST","Wed Jan 07 00:00:00 1970 PST"} (1 row) -- DISTINCT within aggregate @@ -4863,16 +4863,16 @@ EXPLAIN (VERBOSE, COSTS OFF) EXECUTE st2(10, 20); --Testcase 310: EXECUTE st2(10, 20); - c1 | c2 | c3 | time | c6 | c7 | c8 -----+----+-------+--------------------------+----+------------+----- - 16 | 6 | 00016 | Sat Jan 17 00:00:00 1970 | 6 | 6 | foo + c1 | c2 | c3 | time | c6 | c7 | c8 +----+----+-------+------------------------------+----+------------+----- + 16 | 6 | 00016 | Sat Jan 17 00:00:00 1970 PST | 6 | 6 | foo (1 row) --Testcase 311: EXECUTE st2(101, 121); - c1 | c2 | c3 | time | c6 | c7 | c8 ------+----+-------+--------------------------+----+------------+----- - 116 | 6 | 00116 | Sat Jan 17 00:00:00 1970 | 6 | 6 | foo + c1 | c2 | c3 | time | c6 | c7 | c8 +-----+----+-------+------------------------------+----+------------+----- + 116 | 6 | 00116 | Sat Jan 17 00:00:00 1970 PST | 6 | 6 | foo (1 row) -- subquery using immutable function (can be sent to remote) @@ -4901,9 +4901,9 @@ EXPLAIN (VERBOSE, COSTS OFF) EXECUTE st3(10, 20); --Testcase 314: EXECUTE st3(10, 20); - c1 | c2 | c3 | time | c6 | c7 | c8 -----+----+-------+--------------------------+----+------------+----- - 16 | 6 | 00016 | Sat Jan 17 00:00:00 1970 | 6 | 6 | foo + c1 | c2 | c3 | time | c6 | c7 | c8 +----+----+-------+------------------------------+----+------------+----- + 16 | 6 | 00016 | Sat Jan 17 00:00:00 1970 PST | 6 | 6 | foo (1 row) --Testcase 315: @@ -5029,9 +5029,9 @@ EXPLAIN (VERBOSE, COSTS OFF) EXECUTE st5('foo', 1); --Testcase 330: EXECUTE st5('foo', 1); - c1 | c2 | c3 | time | c6 | c7 | c8 -----+----+-------+--------------------------+----+------------+----- - 1 | 1 | 00001 | Fri Jan 02 00:00:00 1970 | 1 | 1 | foo + c1 | c2 | c3 | time | c6 | c7 | c8 +----+----+-------+------------------------------+----+------------+----- + 1 | 1 | 00001 | Fri Jan 02 00:00:00 1970 PST | 1 | 1 | foo (1 row) -- altering FDW options requires replanning @@ -5050,11 +5050,11 @@ EXPLAIN (VERBOSE, COSTS OFF) EXECUTE st6; PREPARE st7 AS INSERT INTO ft1 (c1,c2,c3) VALUES (1001,101,'foo'); --Testcase 334: EXPLAIN (VERBOSE, COSTS OFF) EXECUTE st7; - QUERY PLAN ------------------------------------------------------------------------------------------------------------------------------------------------------------- + QUERY PLAN +--------------------------------------------------------------------------------------------------------------------------------------------------------- Insert on public.ft1 -> Result - Output: NULL::integer, 1001, 101, 'foo'::text, NULL::timestamp without time zone, NULL::character varying, 'ft1 '::character(10), NULL::text + Output: NULL::integer, 1001, 101, 'foo'::text, NULL::timestamp with time zone, NULL::character varying, 'ft1 '::character(10), NULL::text (3 rows) --Testcase 335: @@ -5071,26 +5071,26 @@ EXPLAIN (VERBOSE, COSTS OFF) EXECUTE st6; --Testcase 337: EXECUTE st6; - c1 | c2 | c3 | time | c6 | c7 | c8 -----+----+-------+--------------------------+----+------------+----- - 1 | 1 | 00001 | Fri Jan 02 00:00:00 1970 | 1 | 1 | foo - 2 | 2 | 00002 | Sat Jan 03 00:00:00 1970 | 2 | 2 | foo - 3 | 3 | 00003 | Sun Jan 04 00:00:00 1970 | 3 | 3 | foo - 4 | 4 | 00004 | Mon Jan 05 00:00:00 1970 | 4 | 4 | foo - 5 | 5 | 00005 | Tue Jan 06 00:00:00 1970 | 5 | 5 | foo - 6 | 6 | 00006 | Wed Jan 07 00:00:00 1970 | 6 | 6 | foo - 7 | 7 | 00007 | Thu Jan 08 00:00:00 1970 | 7 | 7 | foo - 8 | 8 | 00008 | Fri Jan 09 00:00:00 1970 | 8 | 8 | foo - 9 | 9 | 00009 | Sat Jan 10 00:00:00 1970 | 9 | 9 | foo + c1 | c2 | c3 | time | c6 | c7 | c8 +----+----+-------+------------------------------+----+------------+----- + 1 | 1 | 00001 | Fri Jan 02 00:00:00 1970 PST | 1 | 1 | foo + 2 | 2 | 00002 | Sat Jan 03 00:00:00 1970 PST | 2 | 2 | foo + 3 | 3 | 00003 | Sun Jan 04 00:00:00 1970 PST | 3 | 3 | foo + 4 | 4 | 00004 | Mon Jan 05 00:00:00 1970 PST | 4 | 4 | foo + 5 | 5 | 00005 | Tue Jan 06 00:00:00 1970 PST | 5 | 5 | foo + 6 | 6 | 00006 | Wed Jan 07 00:00:00 1970 PST | 6 | 6 | foo + 7 | 7 | 00007 | Thu Jan 08 00:00:00 1970 PST | 7 | 7 | foo + 8 | 8 | 00008 | Fri Jan 09 00:00:00 1970 PST | 8 | 8 | foo + 9 | 9 | 00009 | Sat Jan 10 00:00:00 1970 PST | 9 | 9 | foo (9 rows) --Testcase 338: EXPLAIN (VERBOSE, COSTS OFF) EXECUTE st7; - QUERY PLAN ------------------------------------------------------------------------------------------------------------------------------------------------------------- + QUERY PLAN +--------------------------------------------------------------------------------------------------------------------------------------------------------- Insert on public.ft1 -> Result - Output: NULL::integer, 1001, 101, 'foo'::text, NULL::timestamp without time zone, NULL::character varying, 'ft1 '::character(10), NULL::text + Output: NULL::integer, 1001, 101, 'foo'::text, NULL::timestamp with time zone, NULL::character varying, 'ft1 '::character(10), NULL::text (3 rows) --Testcase 339: @@ -5157,9 +5157,9 @@ SELECT * FROM ft1 t1 WHERE t1.tableoid = 'pg_class'::regclass LIMIT 1; --Testcase 345: SELECT * FROM ft1 t1 WHERE t1.tableoid = 'ft1'::regclass ORDER BY c1 LIMIT 1; - c1 | c2 | c3 | time | c6 | c7 | c8 -----+----+-------+--------------------------+----+------------+----- - 1 | 1 | 00001 | Fri Jan 02 00:00:00 1970 | 1 | 1 | foo + c1 | c2 | c3 | time | c6 | c7 | c8 +----+----+-------+------------------------------+----+------------+----- + 1 | 1 | 00001 | Fri Jan 02 00:00:00 1970 PST | 1 | 1 | foo (1 row) --Testcase 346: @@ -5174,9 +5174,9 @@ SELECT tableoid::regclass, * FROM ft1 t1 LIMIT 1; --Testcase 347: SELECT tableoid::regclass, * FROM ft1 t1 ORDER BY c1 LIMIT 1; - tableoid | c1 | c2 | c3 | time | c6 | c7 | c8 -----------+----+----+-------+--------------------------+----+------------+----- - ft1 | 1 | 1 | 00001 | Fri Jan 02 00:00:00 1970 | 1 | 1 | foo + tableoid | c1 | c2 | c3 | time | c6 | c7 | c8 +----------+----+----+-------+------------------------------+----+------------+----- + ft1 | 1 | 1 | 00001 | Fri Jan 02 00:00:00 1970 PST | 1 | 1 | foo (1 row) --Testcase 348: @@ -5208,9 +5208,9 @@ SELECT ctid, * FROM ft1 t1 LIMIT 1; --Testcase 351: SELECT ctid, * FROM ft1 t1 ORDER BY c1 LIMIT 1; - ctid | c1 | c2 | c3 | time | c6 | c7 | c8 -----------------+----+----+-------+--------------------------+----+------------+----- - (4294967295,0) | 1 | 1 | 00001 | Fri Jan 02 00:00:00 1970 | 1 | 1 | foo + ctid | c1 | c2 | c3 | time | c6 | c7 | c8 +----------------+----+----+-------+------------------------------+----+------------+----- + (4294967295,0) | 1 | 1 | 00001 | Fri Jan 02 00:00:00 1970 PST | 1 | 1 | foo (1 row) -- =================================================================== @@ -5402,11 +5402,11 @@ explain (verbose, costs off) select * from ft3 f, loct3 l --Testcase 372: EXPLAIN (verbose, costs off) INSERT INTO ft2 (c1,c2,c3) SELECT c1+1000,c2+100, c3 || c3 FROM ft2 ORDER BY c1 LIMIT 20; - QUERY PLAN -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- + QUERY PLAN +---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- Insert on public.ft2 -> Subquery Scan on "*SELECT*" - Output: "*SELECT*"."?column?", "*SELECT*"."?column?_1", NULL::integer, "*SELECT*"."?column?_2", NULL::timestamp without time zone, NULL::character varying, 'ft2 '::character(10), NULL::text + Output: "*SELECT*"."?column?", "*SELECT*"."?column?_1", NULL::integer, "*SELECT*"."?column?_2", NULL::timestamp with time zone, NULL::character varying, 'ft2 '::character(10), NULL::text -> Limit Output: ((ft2_1.c1 + 1000)), ((ft2_1.c2 + 100)), ((ft2_1.c3 || ft2_1.c3)), ft2_1.c1 -> Sort @@ -6420,11 +6420,11 @@ SELECT c1,c2,c3 FROM ft2 ORDER BY c1; --Testcase 384: EXPLAIN (verbose, costs off) INSERT INTO ft2 (c1,c2,c3) VALUES (1200,999,'foo'); - QUERY PLAN ------------------------------------------------------------------------------------------------------------------------------------------------------------- + QUERY PLAN +--------------------------------------------------------------------------------------------------------------------------------------------------------- Insert on public.ft2 -> Result - Output: 1200, 999, NULL::integer, 'foo'::text, NULL::timestamp without time zone, NULL::character varying, 'ft2 '::character(10), NULL::text + Output: 1200, 999, NULL::integer, 'foo'::text, NULL::timestamp with time zone, NULL::character varying, 'ft2 '::character(10), NULL::text (3 rows) --Testcase 385: @@ -8780,7 +8780,7 @@ CREATE FOREIGN TABLE ft1_nopw ( c2 int NOT NULL, c3 text, c4 timestamptz, - c5 timestamp, + c5 timestamptz, c6 varchar(10), c7 char(10) default 'ft1', c8 user_enum diff --git a/expected/11.17/extra/insert.out b/expected/12.16/extra/insert.out similarity index 100% rename from expected/11.17/extra/insert.out rename to expected/12.16/extra/insert.out diff --git a/expected/12.12/extra/join.out b/expected/12.16/extra/join.out similarity index 100% rename from expected/12.12/extra/join.out rename to expected/12.16/extra/join.out diff --git a/expected/11.17/extra/limit.out b/expected/12.16/extra/limit.out similarity index 100% rename from expected/11.17/extra/limit.out rename to expected/12.16/extra/limit.out diff --git a/expected/11.17/extra/prepare.out b/expected/12.16/extra/prepare.out similarity index 100% rename from expected/11.17/extra/prepare.out rename to expected/12.16/extra/prepare.out diff --git a/expected/12.12/extra/select.out b/expected/12.16/extra/select.out similarity index 100% rename from expected/12.12/extra/select.out rename to expected/12.16/extra/select.out diff --git a/expected/11.17/extra/select_having.out b/expected/12.16/extra/select_having.out similarity index 100% rename from expected/11.17/extra/select_having.out rename to expected/12.16/extra/select_having.out diff --git a/expected/12.12/influxdb_fdw.out b/expected/12.16/influxdb_fdw.out similarity index 92% rename from expected/12.12/influxdb_fdw.out rename to expected/12.16/influxdb_fdw.out index de81a38..eba36bd 100644 --- a/expected/12.12/influxdb_fdw.out +++ b/expected/12.16/influxdb_fdw.out @@ -1128,14 +1128,14 @@ SELECT * FROM t5; SELECT * FROM public.influxdb_fdw_version(); influxdb_fdw_version ---------------------- - 20000 + 20100 (1 row) --Testcase 146: SELECT influxdb_fdw_version(); influxdb_fdw_version ---------------------- - 20000 + 20100 (1 row) --Test pushdown LIMIT...OFFSET @@ -1618,6 +1618,122 @@ SELECT * FROM tmp_time; 2100-01-01 01:01:01 | 04:05:06 | | (6 rows) +-- Type mis-match +--Testcase 212: +CREATE FOREIGN TABLE datatype_test ( + time timestamp with time zone, + tag1 text, + tag2 text, + value1 int, + value2 text +) SERVER server1 OPTIONS (table 'datatype_test', tags 'tag1,tag2'); +--Testcase 213: +INSERT INTO datatype_test (tag1, tag2, value1, value2) VALUES ('time', '2021-02-02T00:00:01Z', '1', '2021-02-05T00:00:00Z'); +--Testcase 214: +INSERT INTO datatype_test (tag1, tag2, value1, value2) VALUES ('time', '2022-02-02T00:00:01Z', '2', '2022-02-05T00:00:00Z'); +--Testcase 215: +SELECT tag1, tag2, value1, value2 FROM datatype_test; + tag1 | tag2 | value1 | value2 +------+----------------------+--------+---------------------- + time | 2021-02-02T00:00:01Z | 1 | 2021-02-05T00:00:00Z + time | 2022-02-02T00:00:01Z | 2 | 2022-02-05T00:00:00Z +(2 rows) + +-- Using text as timestamp +--Testcase 216: +ALTER FOREIGN TABLE datatype_test ALTER COLUMN tag2 TYPE timestamptz; +--Testcase 217: +ALTER FOREIGN TABLE datatype_test ALTER COLUMN value2 TYPE timestamptz; +-- SELECT OK without filter +--Testcase 218: +SELECT tag1, tag2, value1, value2 FROM datatype_test; + tag1 | tag2 | value1 | value2 +------+------------------------+--------+------------------------ + time | 2021-02-02 09:00:01+09 | 1 | 2021-02-05 09:00:00+09 + time | 2022-02-02 09:00:01+09 | 2 | 2022-02-05 09:00:00+09 +(2 rows) + +-- SELECT with timestamp filter, WHERE clause is pushed down +-- InfluxDB cannot compare correctly, 0 row returned +--Testcase 219: +EXPLAIN (VERBOSE, COSTS OFF) +SELECT tag1, tag2, value1, value2 FROM datatype_test WHERE tag2 > '2021-02-02 00:00:01+00'; + QUERY PLAN +--------------------------------------------------------------------------------------------------------------------------- + Foreign Scan on public.datatype_test + Output: tag1, tag2, value1, value2 + InfluxDB query: SELECT "tag1", "tag2", "value1", "value2" FROM "datatype_test" WHERE (("tag2" > '2021-02-02 00:00:01')) +(3 rows) + +--Testcase 220: +SELECT tag1, tag2, value1, value2 FROM datatype_test WHERE tag2 > '2021-02-02 00:00:01+00'; + tag1 | tag2 | value1 | value2 +------+------+--------+-------- +(0 rows) + +--Testcase 221: +EXPLAIN (VERBOSE, COSTS OFF) +SELECT tag1, tag2, value1, value2 FROM datatype_test WHERE value2 > '2021-02-05 00:00:00+00'; + QUERY PLAN +----------------------------------------------------------------------------------------------------------------------------- + Foreign Scan on public.datatype_test + Output: tag1, tag2, value1, value2 + InfluxDB query: SELECT "tag1", "tag2", "value1", "value2" FROM "datatype_test" WHERE (("value2" > '2021-02-05 00:00:00')) +(3 rows) + +--Testcase 222: +SELECT tag1, tag2, value1, value2 FROM datatype_test WHERE value2 > '2021-02-05 00:00:00+00'; + tag1 | tag2 | value1 | value2 +------+------+--------+-------- +(0 rows) + +--Testcase 223: +ALTER FOREIGN TABLE datatype_test ALTER COLUMN tag2 TYPE text; +--Testcase 224: +ALTER FOREIGN TABLE datatype_test ALTER COLUMN value2 TYPE text; +-- uses explicit cast, WHERE clause is not pushed down +-- compared correctly by postgres, 1 row returned +--Testcase 225: +EXPLAIN (VERBOSE, COSTS OFF) +SELECT tag1, tag2, value1, value2 FROM datatype_test WHERE tag2::timestamptz > '2021-02-02 00:00:01+00'; + QUERY PLAN +----------------------------------------------------------------------------------------------------------------- + Foreign Scan on public.datatype_test + Output: tag1, tag2, value1, value2 + Filter: ((datatype_test.tag2)::timestamp with time zone > '2021-02-02 09:00:01+09'::timestamp with time zone) + InfluxDB query: SELECT "tag1", "tag2", "value1", "value2" FROM "datatype_test" +(4 rows) + +--Testcase 226: +SELECT tag1, tag2, value1, value2 FROM datatype_test WHERE tag2::timestamptz > '2021-02-02 00:00:01+00'; + tag1 | tag2 | value1 | value2 +------+----------------------+--------+---------------------- + time | 2022-02-02T00:00:01Z | 2 | 2022-02-05T00:00:00Z +(1 row) + +--Testcase 227: +EXPLAIN (VERBOSE, COSTS OFF) +SELECT tag1, tag2, value1, value2 FROM datatype_test WHERE value2::timestamptz > '2021-02-05 00:00:00+00'; + QUERY PLAN +------------------------------------------------------------------------------------------------------------------- + Foreign Scan on public.datatype_test + Output: tag1, tag2, value1, value2 + Filter: ((datatype_test.value2)::timestamp with time zone > '2021-02-05 09:00:00+09'::timestamp with time zone) + InfluxDB query: SELECT "tag1", "tag2", "value1", "value2" FROM "datatype_test" +(4 rows) + +--Testcase 228: +SELECT tag1, tag2, value1, value2 FROM datatype_test WHERE value2::timestamptz > '2021-02-05 00:00:00+00'; + tag1 | tag2 | value1 | value2 +------+----------------------+--------+---------------------- + time | 2022-02-02T00:00:01Z | 2 | 2022-02-05T00:00:00Z +(1 row) + +-- clean-up +--Testcase 229: +DELETE FROM datatype_test; +--Testcase 230: +DROP FOREIGN TABLE datatype_test; -- Recover data :RECOVER_INIT_TXT_DROP_BUCKET; :RECOVER_INIT_TXT_CREATE_BUCKET; diff --git a/expected/11.17/option.out b/expected/12.16/option.out similarity index 100% rename from expected/11.17/option.out rename to expected/12.16/option.out diff --git a/expected/12.12/schemaless/add_fields.out b/expected/12.16/schemaless/add_fields.out similarity index 100% rename from expected/12.12/schemaless/add_fields.out rename to expected/12.16/schemaless/add_fields.out diff --git a/expected/12.12/schemaless/add_multi_key.out b/expected/12.16/schemaless/add_multi_key.out similarity index 100% rename from expected/12.12/schemaless/add_multi_key.out rename to expected/12.16/schemaless/add_multi_key.out diff --git a/expected/12.12/schemaless/add_tags.out b/expected/12.16/schemaless/add_tags.out similarity index 100% rename from expected/12.12/schemaless/add_tags.out rename to expected/12.16/schemaless/add_tags.out diff --git a/expected/11.17/schemaless/aggregate.out b/expected/12.16/schemaless/aggregate.out similarity index 100% rename from expected/11.17/schemaless/aggregate.out rename to expected/12.16/schemaless/aggregate.out diff --git a/expected/12.12/schemaless/extra/aggregates.out b/expected/12.16/schemaless/extra/aggregates.out similarity index 100% rename from expected/12.12/schemaless/extra/aggregates.out rename to expected/12.16/schemaless/extra/aggregates.out diff --git a/expected/12.12/schemaless/extra/influxdb_fdw_post.out b/expected/12.16/schemaless/extra/influxdb_fdw_post.out similarity index 90% rename from expected/12.12/schemaless/extra/influxdb_fdw_post.out rename to expected/12.16/schemaless/extra/influxdb_fdw_post.out index 5efb812..89ffd46 100644 --- a/expected/12.12/schemaless/extra/influxdb_fdw_post.out +++ b/expected/12.16/schemaless/extra/influxdb_fdw_post.out @@ -26,23 +26,23 @@ CREATE TYPE user_enum AS ENUM ('foo', 'bar', 'buz'); --Testcase 9: CREATE SCHEMA "S 1"; --Testcase 10: -CREATE FOREIGN TABLE "S 1"."T 0" (time timestamp, tags jsonb OPTIONS(tags 'true'), fields jsonb OPTIONS(fields 'true')) SERVER influxdb_svr OPTIONS (table 'T0', tags 'c3', schemaless 'true'); +CREATE FOREIGN TABLE "S 1"."T 0" (time timestamptz, tags jsonb OPTIONS(tags 'true'), fields jsonb OPTIONS(fields 'true')) SERVER influxdb_svr OPTIONS (table 'T0', tags 'c3', schemaless 'true'); CREATE FOREIGN TABLE "S 1".s1t0 ( "C 1" int NOT NULL, c2 int NOT NULL, c3 text, - time timestamp, + time timestamptz, c6 varchar(10), c7 char(10), c8 text ) SERVER influxdb_svr OPTIONS (table 'T0', tags 'c3'); --Testcase 11: -CREATE FOREIGN TABLE "S 1"."T 1" (time timestamp, tags jsonb OPTIONS(tags 'true'), fields jsonb OPTIONS(fields 'true')) SERVER influxdb_svr OPTIONS (table 'T1', tags 'c3', schemaless 'true'); +CREATE FOREIGN TABLE "S 1"."T 1" (time timestamptz, tags jsonb OPTIONS(tags 'true'), fields jsonb OPTIONS(fields 'true')) SERVER influxdb_svr OPTIONS (table 'T1', tags 'c3', schemaless 'true'); CREATE FOREIGN TABLE "S 1".s1t1 ( "C 1" int NOT NULL, c2 int NOT NULL, c3 text, - time timestamp, + time timestamptz, c6 varchar(10), c7 char(10), c8 text @@ -77,7 +77,7 @@ INSERT INTO "S 1".s1t1 SELECT id, id % 10, to_char(id, 'FM00000'), - '1970-01-01'::timestamp + ((id % 100) || ' days')::interval, + '1970-01-01'::timestamptz + ((id % 100) || ' days')::interval, id % 10, id % 10, 'foo'::text @@ -111,26 +111,26 @@ DELETE FROM "S 1".s1t4 WHERE c1 % 3 != 0; -- delete for outer join tests -- create foreign tables -- =================================================================== --Testcase 21: -CREATE FOREIGN TABLE ft1 (time timestamp, tags jsonb OPTIONS(tags 'true'), fields jsonb OPTIONS(fields 'true')) SERVER influxdb_svr OPTIONS (schemaless 'true'); +CREATE FOREIGN TABLE ft1 (time timestamptz, tags jsonb OPTIONS(tags 'true'), fields jsonb OPTIONS(fields 'true')) SERVER influxdb_svr OPTIONS (schemaless 'true'); CREATE FOREIGN TABLE ft1_nsc ( c0 int, c1 int NOT NULL, c2 int NOT NULL, c3 text, - time timestamp, + time timestamptz, c6 varchar(10), c7 char(10) default 'ft1', c8 text ) SERVER influxdb_svr; ALTER FOREIGN TABLE ft1_nsc DROP COLUMN c0; --Testcase 22: -CREATE FOREIGN TABLE ft2 (time timestamp, tags jsonb OPTIONS(tags 'true'), fields jsonb OPTIONS(fields 'true')) SERVER influxdb_svr OPTIONS (schemaless 'true'); +CREATE FOREIGN TABLE ft2 (time timestamptz, tags jsonb OPTIONS(tags 'true'), fields jsonb OPTIONS(fields 'true')) SERVER influxdb_svr OPTIONS (schemaless 'true'); CREATE FOREIGN TABLE ft2_nsc ( c1 int NOT NULL, c2 int NOT NULL, cx int, c3 text, - time timestamp, + time timestamptz, c6 varchar(10), c7 char(10) default 'ft2', c8 text @@ -232,9 +232,9 @@ ALTER FOREIGN TABLE ft2_nsc ALTER COLUMN c1 OPTIONS (column_name 'C 1'); \set VERBOSITY terse --Testcase 27: SELECT tags->>'c3' c3, time FROM ft1 ORDER BY tags->>'c3', (fields->>'C 1')::int LIMIT 1; -- should work - c3 | time --------+-------------------------- - 00001 | Fri Jan 02 00:00:00 1970 + c3 | time +-------+------------------------------ + 00001 | Fri Jan 02 00:00:00 1970 PST (1 row) ALTER SERVER influxdb_svr OPTIONS (SET dbname 'no such database'); @@ -249,9 +249,9 @@ DO $d$ $d$; --Testcase 29: SELECT tags->>'c3' c3, time FROM ft1 ORDER BY tags->>'c3', (fields->>'C 1')::int LIMIT 1; -- should work again - c3 | time --------+-------------------------- - 00001 | Fri Jan 02 00:00:00 1970 + c3 | time +-------+------------------------------ + 00001 | Fri Jan 02 00:00:00 1970 PST (1 row) \set VERBOSITY default @@ -271,18 +271,18 @@ EXPLAIN (COSTS OFF) SELECT * FROM ft1 ORDER BY tags->>'c3', (fields->>'C 1')::in --Testcase 31: SELECT * FROM ft1 ORDER BY tags->>'c3', (fields->>'C 1')::int OFFSET 100 LIMIT 10; - time | tags | fields ---------------------------+-----------------+----------------------------------------------------------------------- - Fri Jan 02 00:00:00 1970 | {"c3": "00101"} | {"c2": "1", "c6": "1", "c7": "1 ", "c8": "foo", "C 1": "101"} - Sat Jan 03 00:00:00 1970 | {"c3": "00102"} | {"c2": "2", "c6": "2", "c7": "2 ", "c8": "foo", "C 1": "102"} - Sun Jan 04 00:00:00 1970 | {"c3": "00103"} | {"c2": "3", "c6": "3", "c7": "3 ", "c8": "foo", "C 1": "103"} - Mon Jan 05 00:00:00 1970 | {"c3": "00104"} | {"c2": "4", "c6": "4", "c7": "4 ", "c8": "foo", "C 1": "104"} - Tue Jan 06 00:00:00 1970 | {"c3": "00105"} | {"c2": "5", "c6": "5", "c7": "5 ", "c8": "foo", "C 1": "105"} - Wed Jan 07 00:00:00 1970 | {"c3": "00106"} | {"c2": "6", "c6": "6", "c7": "6 ", "c8": "foo", "C 1": "106"} - Thu Jan 08 00:00:00 1970 | {"c3": "00107"} | {"c2": "7", "c6": "7", "c7": "7 ", "c8": "foo", "C 1": "107"} - Fri Jan 09 00:00:00 1970 | {"c3": "00108"} | {"c2": "8", "c6": "8", "c7": "8 ", "c8": "foo", "C 1": "108"} - Sat Jan 10 00:00:00 1970 | {"c3": "00109"} | {"c2": "9", "c6": "9", "c7": "9 ", "c8": "foo", "C 1": "109"} - Sun Jan 11 00:00:00 1970 | {"c3": "00110"} | {"c2": "0", "c6": "0", "c7": "0 ", "c8": "foo", "C 1": "110"} + time | tags | fields +------------------------------+-----------------+----------------------------------------------------------------------- + Fri Jan 02 00:00:00 1970 PST | {"c3": "00101"} | {"c2": "1", "c6": "1", "c7": "1 ", "c8": "foo", "C 1": "101"} + Sat Jan 03 00:00:00 1970 PST | {"c3": "00102"} | {"c2": "2", "c6": "2", "c7": "2 ", "c8": "foo", "C 1": "102"} + Sun Jan 04 00:00:00 1970 PST | {"c3": "00103"} | {"c2": "3", "c6": "3", "c7": "3 ", "c8": "foo", "C 1": "103"} + Mon Jan 05 00:00:00 1970 PST | {"c3": "00104"} | {"c2": "4", "c6": "4", "c7": "4 ", "c8": "foo", "C 1": "104"} + Tue Jan 06 00:00:00 1970 PST | {"c3": "00105"} | {"c2": "5", "c6": "5", "c7": "5 ", "c8": "foo", "C 1": "105"} + Wed Jan 07 00:00:00 1970 PST | {"c3": "00106"} | {"c2": "6", "c6": "6", "c7": "6 ", "c8": "foo", "C 1": "106"} + Thu Jan 08 00:00:00 1970 PST | {"c3": "00107"} | {"c2": "7", "c6": "7", "c7": "7 ", "c8": "foo", "C 1": "107"} + Fri Jan 09 00:00:00 1970 PST | {"c3": "00108"} | {"c2": "8", "c6": "8", "c7": "8 ", "c8": "foo", "C 1": "108"} + Sat Jan 10 00:00:00 1970 PST | {"c3": "00109"} | {"c2": "9", "c6": "9", "c7": "9 ", "c8": "foo", "C 1": "109"} + Sun Jan 11 00:00:00 1970 PST | {"c3": "00110"} | {"c2": "0", "c6": "0", "c7": "0 ", "c8": "foo", "C 1": "110"} (10 rows) -- single table with alias - also test that tableoid sort is not pushed to remote side @@ -302,18 +302,18 @@ EXPLAIN (VERBOSE, COSTS OFF) SELECT * FROM ft1 t1 ORDER BY t1.tags->>'c3', (t1.f --Testcase 33: SELECT * FROM ft1 t1 ORDER BY t1.tags->>'c3', (t1.fields->>'C 1')::int, t1.tableoid OFFSET 100 LIMIT 10; - time | tags | fields ---------------------------+-----------------+----------------------------------------------------------------------- - Fri Jan 02 00:00:00 1970 | {"c3": "00101"} | {"c2": "1", "c6": "1", "c7": "1 ", "c8": "foo", "C 1": "101"} - Sat Jan 03 00:00:00 1970 | {"c3": "00102"} | {"c2": "2", "c6": "2", "c7": "2 ", "c8": "foo", "C 1": "102"} - Sun Jan 04 00:00:00 1970 | {"c3": "00103"} | {"c2": "3", "c6": "3", "c7": "3 ", "c8": "foo", "C 1": "103"} - Mon Jan 05 00:00:00 1970 | {"c3": "00104"} | {"c2": "4", "c6": "4", "c7": "4 ", "c8": "foo", "C 1": "104"} - Tue Jan 06 00:00:00 1970 | {"c3": "00105"} | {"c2": "5", "c6": "5", "c7": "5 ", "c8": "foo", "C 1": "105"} - Wed Jan 07 00:00:00 1970 | {"c3": "00106"} | {"c2": "6", "c6": "6", "c7": "6 ", "c8": "foo", "C 1": "106"} - Thu Jan 08 00:00:00 1970 | {"c3": "00107"} | {"c2": "7", "c6": "7", "c7": "7 ", "c8": "foo", "C 1": "107"} - Fri Jan 09 00:00:00 1970 | {"c3": "00108"} | {"c2": "8", "c6": "8", "c7": "8 ", "c8": "foo", "C 1": "108"} - Sat Jan 10 00:00:00 1970 | {"c3": "00109"} | {"c2": "9", "c6": "9", "c7": "9 ", "c8": "foo", "C 1": "109"} - Sun Jan 11 00:00:00 1970 | {"c3": "00110"} | {"c2": "0", "c6": "0", "c7": "0 ", "c8": "foo", "C 1": "110"} + time | tags | fields +------------------------------+-----------------+----------------------------------------------------------------------- + Fri Jan 02 00:00:00 1970 PST | {"c3": "00101"} | {"c2": "1", "c6": "1", "c7": "1 ", "c8": "foo", "C 1": "101"} + Sat Jan 03 00:00:00 1970 PST | {"c3": "00102"} | {"c2": "2", "c6": "2", "c7": "2 ", "c8": "foo", "C 1": "102"} + Sun Jan 04 00:00:00 1970 PST | {"c3": "00103"} | {"c2": "3", "c6": "3", "c7": "3 ", "c8": "foo", "C 1": "103"} + Mon Jan 05 00:00:00 1970 PST | {"c3": "00104"} | {"c2": "4", "c6": "4", "c7": "4 ", "c8": "foo", "C 1": "104"} + Tue Jan 06 00:00:00 1970 PST | {"c3": "00105"} | {"c2": "5", "c6": "5", "c7": "5 ", "c8": "foo", "C 1": "105"} + Wed Jan 07 00:00:00 1970 PST | {"c3": "00106"} | {"c2": "6", "c6": "6", "c7": "6 ", "c8": "foo", "C 1": "106"} + Thu Jan 08 00:00:00 1970 PST | {"c3": "00107"} | {"c2": "7", "c6": "7", "c7": "7 ", "c8": "foo", "C 1": "107"} + Fri Jan 09 00:00:00 1970 PST | {"c3": "00108"} | {"c2": "8", "c6": "8", "c7": "8 ", "c8": "foo", "C 1": "108"} + Sat Jan 10 00:00:00 1970 PST | {"c3": "00109"} | {"c2": "9", "c6": "9", "c7": "9 ", "c8": "foo", "C 1": "109"} + Sun Jan 11 00:00:00 1970 PST | {"c3": "00110"} | {"c2": "0", "c6": "0", "c7": "0 ", "c8": "foo", "C 1": "110"} (10 rows) -- whole-row reference @@ -333,18 +333,18 @@ EXPLAIN (VERBOSE, COSTS OFF) SELECT t1 FROM ft1 t1 ORDER BY t1.tags->>'c3', (t1. --Testcase 35: SELECT t1 FROM ft1 t1 ORDER BY t1.tags->>'c3', (t1.fields->>'C 1')::int OFFSET 100 LIMIT 10; - t1 ------------------------------------------------------------------------------------------------------------------------------------------------- - ("Fri Jan 02 00:00:00 1970","{""c3"": ""00101""}","{""c2"": ""1"", ""c6"": ""1"", ""c7"": ""1 "", ""c8"": ""foo"", ""C 1"": ""101""}") - ("Sat Jan 03 00:00:00 1970","{""c3"": ""00102""}","{""c2"": ""2"", ""c6"": ""2"", ""c7"": ""2 "", ""c8"": ""foo"", ""C 1"": ""102""}") - ("Sun Jan 04 00:00:00 1970","{""c3"": ""00103""}","{""c2"": ""3"", ""c6"": ""3"", ""c7"": ""3 "", ""c8"": ""foo"", ""C 1"": ""103""}") - ("Mon Jan 05 00:00:00 1970","{""c3"": ""00104""}","{""c2"": ""4"", ""c6"": ""4"", ""c7"": ""4 "", ""c8"": ""foo"", ""C 1"": ""104""}") - ("Tue Jan 06 00:00:00 1970","{""c3"": ""00105""}","{""c2"": ""5"", ""c6"": ""5"", ""c7"": ""5 "", ""c8"": ""foo"", ""C 1"": ""105""}") - ("Wed Jan 07 00:00:00 1970","{""c3"": ""00106""}","{""c2"": ""6"", ""c6"": ""6"", ""c7"": ""6 "", ""c8"": ""foo"", ""C 1"": ""106""}") - ("Thu Jan 08 00:00:00 1970","{""c3"": ""00107""}","{""c2"": ""7"", ""c6"": ""7"", ""c7"": ""7 "", ""c8"": ""foo"", ""C 1"": ""107""}") - ("Fri Jan 09 00:00:00 1970","{""c3"": ""00108""}","{""c2"": ""8"", ""c6"": ""8"", ""c7"": ""8 "", ""c8"": ""foo"", ""C 1"": ""108""}") - ("Sat Jan 10 00:00:00 1970","{""c3"": ""00109""}","{""c2"": ""9"", ""c6"": ""9"", ""c7"": ""9 "", ""c8"": ""foo"", ""C 1"": ""109""}") - ("Sun Jan 11 00:00:00 1970","{""c3"": ""00110""}","{""c2"": ""0"", ""c6"": ""0"", ""c7"": ""0 "", ""c8"": ""foo"", ""C 1"": ""110""}") + t1 +---------------------------------------------------------------------------------------------------------------------------------------------------- + ("Fri Jan 02 00:00:00 1970 PST","{""c3"": ""00101""}","{""c2"": ""1"", ""c6"": ""1"", ""c7"": ""1 "", ""c8"": ""foo"", ""C 1"": ""101""}") + ("Sat Jan 03 00:00:00 1970 PST","{""c3"": ""00102""}","{""c2"": ""2"", ""c6"": ""2"", ""c7"": ""2 "", ""c8"": ""foo"", ""C 1"": ""102""}") + ("Sun Jan 04 00:00:00 1970 PST","{""c3"": ""00103""}","{""c2"": ""3"", ""c6"": ""3"", ""c7"": ""3 "", ""c8"": ""foo"", ""C 1"": ""103""}") + ("Mon Jan 05 00:00:00 1970 PST","{""c3"": ""00104""}","{""c2"": ""4"", ""c6"": ""4"", ""c7"": ""4 "", ""c8"": ""foo"", ""C 1"": ""104""}") + ("Tue Jan 06 00:00:00 1970 PST","{""c3"": ""00105""}","{""c2"": ""5"", ""c6"": ""5"", ""c7"": ""5 "", ""c8"": ""foo"", ""C 1"": ""105""}") + ("Wed Jan 07 00:00:00 1970 PST","{""c3"": ""00106""}","{""c2"": ""6"", ""c6"": ""6"", ""c7"": ""6 "", ""c8"": ""foo"", ""C 1"": ""106""}") + ("Thu Jan 08 00:00:00 1970 PST","{""c3"": ""00107""}","{""c2"": ""7"", ""c6"": ""7"", ""c7"": ""7 "", ""c8"": ""foo"", ""C 1"": ""107""}") + ("Fri Jan 09 00:00:00 1970 PST","{""c3"": ""00108""}","{""c2"": ""8"", ""c6"": ""8"", ""c7"": ""8 "", ""c8"": ""foo"", ""C 1"": ""108""}") + ("Sat Jan 10 00:00:00 1970 PST","{""c3"": ""00109""}","{""c2"": ""9"", ""c6"": ""9"", ""c7"": ""9 "", ""c8"": ""foo"", ""C 1"": ""109""}") + ("Sun Jan 11 00:00:00 1970 PST","{""c3"": ""00110""}","{""c2"": ""0"", ""c6"": ""0"", ""c7"": ""0 "", ""c8"": ""foo"", ""C 1"": ""110""}") (10 rows) -- empty result @@ -367,9 +367,9 @@ EXPLAIN (VERBOSE, COSTS OFF) SELECT * FROM ft1 t1 WHERE (t1.fields->>'C 1')::int --Testcase 38: SELECT * FROM ft1 t1 WHERE (t1.fields->>'C 1')::int = 101 AND t1.fields->>'c6' = '1' AND t1.fields->>'c7' >= '1'; - time | tags | fields ---------------------------+-----------------+----------------------------------------------------------------------- - Fri Jan 02 00:00:00 1970 | {"c3": "00101"} | {"c2": "1", "c6": "1", "c7": "1 ", "c8": "foo", "C 1": "101"} + time | tags | fields +------------------------------+-----------------+----------------------------------------------------------------------- + Fri Jan 02 00:00:00 1970 PST | {"c3": "00101"} | {"c2": "1", "c6": "1", "c7": "1 ", "c8": "foo", "C 1": "101"} (1 row) -- with FOR UPDATE/SHARE @@ -386,9 +386,9 @@ EXPLAIN (VERBOSE, COSTS OFF) SELECT * FROM ft1 t1 WHERE (fields->>'C 1')::int = --Testcase 40: SELECT * FROM ft1 t1 WHERE (fields->>'C 1')::int = 101 FOR UPDATE; - time | tags | fields ---------------------------+-----------------+----------------------------------------------------------------------- - Fri Jan 02 00:00:00 1970 | {"c3": "00101"} | {"c2": "1", "c6": "1", "c7": "1 ", "c8": "foo", "C 1": "101"} + time | tags | fields +------------------------------+-----------------+----------------------------------------------------------------------- + Fri Jan 02 00:00:00 1970 PST | {"c3": "00101"} | {"c2": "1", "c6": "1", "c7": "1 ", "c8": "foo", "C 1": "101"} (1 row) --Testcase 41: @@ -404,9 +404,9 @@ EXPLAIN (VERBOSE, COSTS OFF) SELECT * FROM ft1 t1 WHERE (fields->>'C 1')::int = --Testcase 42: SELECT * FROM ft1 t1 WHERE (fields->>'C 1')::int = 102 FOR SHARE; - time | tags | fields ---------------------------+-----------------+----------------------------------------------------------------------- - Sat Jan 03 00:00:00 1970 | {"c3": "00102"} | {"c2": "2", "c6": "2", "c7": "2 ", "c8": "foo", "C 1": "102"} + time | tags | fields +------------------------------+-----------------+----------------------------------------------------------------------- + Sat Jan 03 00:00:00 1970 PST | {"c3": "00102"} | {"c2": "2", "c6": "2", "c7": "2 ", "c8": "foo", "C 1": "102"} (1 row) -- aggregate @@ -420,43 +420,43 @@ SELECT COUNT(*) FROM ft1 t1; -- subquery --Testcase 44: SELECT * FROM ft1 t1 WHERE t1.tags->>'c3' IN (SELECT tags->>'c3' FROM ft2 t2 WHERE (fields->>'C 1')::int <= 10) ORDER BY (fields->>'C 1')::int; - time | tags | fields ---------------------------+-----------------+---------------------------------------------------------------------- - Fri Jan 02 00:00:00 1970 | {"c3": "00001"} | {"c2": "1", "c6": "1", "c7": "1 ", "c8": "foo", "C 1": "1"} - Sat Jan 03 00:00:00 1970 | {"c3": "00002"} | {"c2": "2", "c6": "2", "c7": "2 ", "c8": "foo", "C 1": "2"} - Sun Jan 04 00:00:00 1970 | {"c3": "00003"} | {"c2": "3", "c6": "3", "c7": "3 ", "c8": "foo", "C 1": "3"} - Mon Jan 05 00:00:00 1970 | {"c3": "00004"} | {"c2": "4", "c6": "4", "c7": "4 ", "c8": "foo", "C 1": "4"} - Tue Jan 06 00:00:00 1970 | {"c3": "00005"} | {"c2": "5", "c6": "5", "c7": "5 ", "c8": "foo", "C 1": "5"} - Wed Jan 07 00:00:00 1970 | {"c3": "00006"} | {"c2": "6", "c6": "6", "c7": "6 ", "c8": "foo", "C 1": "6"} - Thu Jan 08 00:00:00 1970 | {"c3": "00007"} | {"c2": "7", "c6": "7", "c7": "7 ", "c8": "foo", "C 1": "7"} - Fri Jan 09 00:00:00 1970 | {"c3": "00008"} | {"c2": "8", "c6": "8", "c7": "8 ", "c8": "foo", "C 1": "8"} - Sat Jan 10 00:00:00 1970 | {"c3": "00009"} | {"c2": "9", "c6": "9", "c7": "9 ", "c8": "foo", "C 1": "9"} - Sun Jan 11 00:00:00 1970 | {"c3": "00010"} | {"c2": "0", "c6": "0", "c7": "0 ", "c8": "foo", "C 1": "10"} + time | tags | fields +------------------------------+-----------------+---------------------------------------------------------------------- + Fri Jan 02 00:00:00 1970 PST | {"c3": "00001"} | {"c2": "1", "c6": "1", "c7": "1 ", "c8": "foo", "C 1": "1"} + Sat Jan 03 00:00:00 1970 PST | {"c3": "00002"} | {"c2": "2", "c6": "2", "c7": "2 ", "c8": "foo", "C 1": "2"} + Sun Jan 04 00:00:00 1970 PST | {"c3": "00003"} | {"c2": "3", "c6": "3", "c7": "3 ", "c8": "foo", "C 1": "3"} + Mon Jan 05 00:00:00 1970 PST | {"c3": "00004"} | {"c2": "4", "c6": "4", "c7": "4 ", "c8": "foo", "C 1": "4"} + Tue Jan 06 00:00:00 1970 PST | {"c3": "00005"} | {"c2": "5", "c6": "5", "c7": "5 ", "c8": "foo", "C 1": "5"} + Wed Jan 07 00:00:00 1970 PST | {"c3": "00006"} | {"c2": "6", "c6": "6", "c7": "6 ", "c8": "foo", "C 1": "6"} + Thu Jan 08 00:00:00 1970 PST | {"c3": "00007"} | {"c2": "7", "c6": "7", "c7": "7 ", "c8": "foo", "C 1": "7"} + Fri Jan 09 00:00:00 1970 PST | {"c3": "00008"} | {"c2": "8", "c6": "8", "c7": "8 ", "c8": "foo", "C 1": "8"} + Sat Jan 10 00:00:00 1970 PST | {"c3": "00009"} | {"c2": "9", "c6": "9", "c7": "9 ", "c8": "foo", "C 1": "9"} + Sun Jan 11 00:00:00 1970 PST | {"c3": "00010"} | {"c2": "0", "c6": "0", "c7": "0 ", "c8": "foo", "C 1": "10"} (10 rows) -- subquery+MAX --Testcase 45: SELECT * FROM ft1 t1 WHERE t1.tags->>'c3' = (SELECT MAX(tags->>'c3') FROM ft2 t2) ORDER BY (fields->>'C 1')::int; - time | tags | fields ---------------------------+-----------------+------------------------------------------------------------------------ - Thu Jan 01 00:00:00 1970 | {"c3": "01000"} | {"c2": "0", "c6": "0", "c7": "0 ", "c8": "foo", "C 1": "1000"} + time | tags | fields +------------------------------+-----------------+------------------------------------------------------------------------ + Thu Jan 01 00:00:00 1970 PST | {"c3": "01000"} | {"c2": "0", "c6": "0", "c7": "0 ", "c8": "foo", "C 1": "1000"} (1 row) -- used in CTE --Testcase 46: WITH t1 AS (SELECT * FROM ft1 WHERE (fields->>'C 1')::int <= 10) SELECT (t2.fields->>'C 1')::int c1, (t2.fields->>'c2')::int c2, t2.tags->>'c3' c3, t2.time FROM t1, ft2 t2 WHERE (t1.fields->>'C 1')::int = (t2.fields->>'C 1')::int ORDER BY (t1.fields->>'C 1')::int; - c1 | c2 | c3 | time -----+----+-------+-------------------------- - 1 | 1 | 00001 | Fri Jan 02 00:00:00 1970 - 2 | 2 | 00002 | Sat Jan 03 00:00:00 1970 - 3 | 3 | 00003 | Sun Jan 04 00:00:00 1970 - 4 | 4 | 00004 | Mon Jan 05 00:00:00 1970 - 5 | 5 | 00005 | Tue Jan 06 00:00:00 1970 - 6 | 6 | 00006 | Wed Jan 07 00:00:00 1970 - 7 | 7 | 00007 | Thu Jan 08 00:00:00 1970 - 8 | 8 | 00008 | Fri Jan 09 00:00:00 1970 - 9 | 9 | 00009 | Sat Jan 10 00:00:00 1970 - 10 | 0 | 00010 | Sun Jan 11 00:00:00 1970 + c1 | c2 | c3 | time +----+----+-------+------------------------------ + 1 | 1 | 00001 | Fri Jan 02 00:00:00 1970 PST + 2 | 2 | 00002 | Sat Jan 03 00:00:00 1970 PST + 3 | 3 | 00003 | Sun Jan 04 00:00:00 1970 PST + 4 | 4 | 00004 | Mon Jan 05 00:00:00 1970 PST + 5 | 5 | 00005 | Tue Jan 06 00:00:00 1970 PST + 6 | 6 | 00006 | Wed Jan 07 00:00:00 1970 PST + 7 | 7 | 00007 | Thu Jan 08 00:00:00 1970 PST + 8 | 8 | 00008 | Fri Jan 09 00:00:00 1970 PST + 9 | 9 | 00009 | Sat Jan 10 00:00:00 1970 PST + 10 | 0 | 00010 | Sun Jan 11 00:00:00 1970 PST (10 rows) -- fixed values @@ -853,9 +853,9 @@ EXPLAIN (VERBOSE, COSTS OFF) --Testcase 71: SELECT * FROM ft2 a, ft2 b WHERE (a.fields->>'C 1')::int = 47 AND (b.fields->>'C 1')::int = (a.fields->>'c2')::int; - time | tags | fields | time | tags | fields ---------------------------+-----------------+----------------------------------------------------------------------+--------------------------+-----------------+--------------------------------------------------------------------- - Tue Feb 17 00:00:00 1970 | {"c3": "00047"} | {"c2": "7", "c6": "7", "c7": "7 ", "c8": "foo", "C 1": "47"} | Thu Jan 08 00:00:00 1970 | {"c3": "00007"} | {"c2": "7", "c6": "7", "c7": "7 ", "c8": "foo", "C 1": "7"} + time | tags | fields | time | tags | fields +------------------------------+-----------------+----------------------------------------------------------------------+------------------------------+-----------------+--------------------------------------------------------------------- + Tue Feb 17 00:00:00 1970 PST | {"c3": "00047"} | {"c2": "7", "c6": "7", "c7": "7 ", "c8": "foo", "C 1": "47"} | Thu Jan 08 00:00:00 1970 PST | {"c3": "00007"} | {"c2": "7", "c6": "7", "c7": "7 ", "c8": "foo", "C 1": "7"} (1 row) -- check both safe and unsafe join conditions @@ -881,129 +881,129 @@ EXPLAIN (VERBOSE, COSTS OFF) --Testcase 73: SELECT * FROM ft2 a, ft2 b WHERE (a.fields->>'c2')::int = 6 AND (b.fields->>'C 1')::int = (a.fields->>'C 1')::int AND a.fields->>'c8' = 'foo' AND b.fields->>'c7' = upper(a.fields->>'c7') ORDER BY (a.fields->>'C 1')::int; - time | tags | fields | time | tags | fields ---------------------------+-----------------+-----------------------------------------------------------------------+--------------------------+-----------------+----------------------------------------------------------------------- - Wed Jan 07 00:00:00 1970 | {"c3": "00006"} | {"c2": "6", "c6": "6", "c7": "6 ", "c8": "foo", "C 1": "6"} | Wed Jan 07 00:00:00 1970 | {"c3": "00006"} | {"c2": "6", "c6": "6", "c7": "6 ", "c8": "foo", "C 1": "6"} - Sat Jan 17 00:00:00 1970 | {"c3": "00016"} | {"c2": "6", "c6": "6", "c7": "6 ", "c8": "foo", "C 1": "16"} | Sat Jan 17 00:00:00 1970 | {"c3": "00016"} | {"c2": "6", "c6": "6", "c7": "6 ", "c8": "foo", "C 1": "16"} - Tue Jan 27 00:00:00 1970 | {"c3": "00026"} | {"c2": "6", "c6": "6", "c7": "6 ", "c8": "foo", "C 1": "26"} | Tue Jan 27 00:00:00 1970 | {"c3": "00026"} | {"c2": "6", "c6": "6", "c7": "6 ", "c8": "foo", "C 1": "26"} - Fri Feb 06 00:00:00 1970 | {"c3": "00036"} | {"c2": "6", "c6": "6", "c7": "6 ", "c8": "foo", "C 1": "36"} | Fri Feb 06 00:00:00 1970 | {"c3": "00036"} | {"c2": "6", "c6": "6", "c7": "6 ", "c8": "foo", "C 1": "36"} - Mon Feb 16 00:00:00 1970 | {"c3": "00046"} | {"c2": "6", "c6": "6", "c7": "6 ", "c8": "foo", "C 1": "46"} | Mon Feb 16 00:00:00 1970 | {"c3": "00046"} | {"c2": "6", "c6": "6", "c7": "6 ", "c8": "foo", "C 1": "46"} - Thu Feb 26 00:00:00 1970 | {"c3": "00056"} | {"c2": "6", "c6": "6", "c7": "6 ", "c8": "foo", "C 1": "56"} | Thu Feb 26 00:00:00 1970 | {"c3": "00056"} | {"c2": "6", "c6": "6", "c7": "6 ", "c8": "foo", "C 1": "56"} - Sun Mar 08 00:00:00 1970 | {"c3": "00066"} | {"c2": "6", "c6": "6", "c7": "6 ", "c8": "foo", "C 1": "66"} | Sun Mar 08 00:00:00 1970 | {"c3": "00066"} | {"c2": "6", "c6": "6", "c7": "6 ", "c8": "foo", "C 1": "66"} - Wed Mar 18 00:00:00 1970 | {"c3": "00076"} | {"c2": "6", "c6": "6", "c7": "6 ", "c8": "foo", "C 1": "76"} | Wed Mar 18 00:00:00 1970 | {"c3": "00076"} | {"c2": "6", "c6": "6", "c7": "6 ", "c8": "foo", "C 1": "76"} - Sat Mar 28 00:00:00 1970 | {"c3": "00086"} | {"c2": "6", "c6": "6", "c7": "6 ", "c8": "foo", "C 1": "86"} | Sat Mar 28 00:00:00 1970 | {"c3": "00086"} | {"c2": "6", "c6": "6", "c7": "6 ", "c8": "foo", "C 1": "86"} - Tue Apr 07 00:00:00 1970 | {"c3": "00096"} | {"c2": "6", "c6": "6", "c7": "6 ", "c8": "foo", "C 1": "96"} | Tue Apr 07 00:00:00 1970 | {"c3": "00096"} | {"c2": "6", "c6": "6", "c7": "6 ", "c8": "foo", "C 1": "96"} - Wed Jan 07 00:00:00 1970 | {"c3": "00106"} | {"c2": "6", "c6": "6", "c7": "6 ", "c8": "foo", "C 1": "106"} | Wed Jan 07 00:00:00 1970 | {"c3": "00106"} | {"c2": "6", "c6": "6", "c7": "6 ", "c8": "foo", "C 1": "106"} - Sat Jan 17 00:00:00 1970 | {"c3": "00116"} | {"c2": "6", "c6": "6", "c7": "6 ", "c8": "foo", "C 1": "116"} | Sat Jan 17 00:00:00 1970 | {"c3": "00116"} | {"c2": "6", "c6": "6", "c7": "6 ", "c8": "foo", "C 1": "116"} - Tue Jan 27 00:00:00 1970 | {"c3": "00126"} | {"c2": "6", "c6": "6", "c7": "6 ", "c8": "foo", "C 1": "126"} | Tue Jan 27 00:00:00 1970 | {"c3": "00126"} | {"c2": "6", "c6": "6", "c7": "6 ", "c8": "foo", "C 1": "126"} - Fri Feb 06 00:00:00 1970 | {"c3": "00136"} | {"c2": "6", "c6": "6", "c7": "6 ", "c8": "foo", "C 1": "136"} | Fri Feb 06 00:00:00 1970 | {"c3": "00136"} | {"c2": "6", "c6": "6", "c7": "6 ", "c8": "foo", "C 1": "136"} - Mon Feb 16 00:00:00 1970 | {"c3": "00146"} | {"c2": "6", "c6": "6", "c7": "6 ", "c8": "foo", "C 1": "146"} | Mon Feb 16 00:00:00 1970 | {"c3": "00146"} | {"c2": "6", "c6": "6", "c7": "6 ", "c8": "foo", "C 1": "146"} - Thu Feb 26 00:00:00 1970 | {"c3": "00156"} | {"c2": "6", "c6": "6", "c7": "6 ", "c8": "foo", "C 1": "156"} | Thu Feb 26 00:00:00 1970 | {"c3": "00156"} | {"c2": "6", "c6": "6", "c7": "6 ", "c8": "foo", "C 1": "156"} - Sun Mar 08 00:00:00 1970 | {"c3": "00166"} | {"c2": "6", "c6": "6", "c7": "6 ", "c8": "foo", "C 1": "166"} | Sun Mar 08 00:00:00 1970 | {"c3": "00166"} | {"c2": "6", "c6": "6", "c7": "6 ", "c8": "foo", "C 1": "166"} - Wed Mar 18 00:00:00 1970 | {"c3": "00176"} | {"c2": "6", "c6": "6", "c7": "6 ", "c8": "foo", "C 1": "176"} | Wed Mar 18 00:00:00 1970 | {"c3": "00176"} | {"c2": "6", "c6": "6", "c7": "6 ", "c8": "foo", "C 1": "176"} - Sat Mar 28 00:00:00 1970 | {"c3": "00186"} | {"c2": "6", "c6": "6", "c7": "6 ", "c8": "foo", "C 1": "186"} | Sat Mar 28 00:00:00 1970 | {"c3": "00186"} | {"c2": "6", "c6": "6", "c7": "6 ", "c8": "foo", "C 1": "186"} - Tue Apr 07 00:00:00 1970 | {"c3": "00196"} | {"c2": "6", "c6": "6", "c7": "6 ", "c8": "foo", "C 1": "196"} | Tue Apr 07 00:00:00 1970 | {"c3": "00196"} | {"c2": "6", "c6": "6", "c7": "6 ", "c8": "foo", "C 1": "196"} - Wed Jan 07 00:00:00 1970 | {"c3": "00206"} | {"c2": "6", "c6": "6", "c7": "6 ", "c8": "foo", "C 1": "206"} | Wed Jan 07 00:00:00 1970 | {"c3": "00206"} | {"c2": "6", "c6": "6", "c7": "6 ", "c8": "foo", "C 1": "206"} - Sat Jan 17 00:00:00 1970 | {"c3": "00216"} | {"c2": "6", "c6": "6", "c7": "6 ", "c8": "foo", "C 1": "216"} | Sat Jan 17 00:00:00 1970 | {"c3": "00216"} | {"c2": "6", "c6": "6", "c7": "6 ", "c8": "foo", "C 1": "216"} - Tue Jan 27 00:00:00 1970 | {"c3": "00226"} | {"c2": "6", "c6": "6", "c7": "6 ", "c8": "foo", "C 1": "226"} | Tue Jan 27 00:00:00 1970 | {"c3": "00226"} | {"c2": "6", "c6": "6", "c7": "6 ", "c8": "foo", "C 1": "226"} - Fri Feb 06 00:00:00 1970 | {"c3": "00236"} | {"c2": "6", "c6": "6", "c7": "6 ", "c8": "foo", "C 1": "236"} | Fri Feb 06 00:00:00 1970 | {"c3": "00236"} | {"c2": "6", "c6": "6", "c7": "6 ", "c8": "foo", "C 1": "236"} - Mon Feb 16 00:00:00 1970 | {"c3": "00246"} | {"c2": "6", "c6": "6", "c7": "6 ", "c8": "foo", "C 1": "246"} | Mon Feb 16 00:00:00 1970 | {"c3": "00246"} | {"c2": "6", "c6": "6", "c7": "6 ", "c8": "foo", "C 1": "246"} - Thu Feb 26 00:00:00 1970 | {"c3": "00256"} | {"c2": "6", "c6": "6", "c7": "6 ", "c8": "foo", "C 1": "256"} | Thu Feb 26 00:00:00 1970 | {"c3": "00256"} | {"c2": "6", "c6": "6", "c7": "6 ", "c8": "foo", "C 1": "256"} - Sun Mar 08 00:00:00 1970 | {"c3": "00266"} | {"c2": "6", "c6": "6", "c7": "6 ", "c8": "foo", "C 1": "266"} | Sun Mar 08 00:00:00 1970 | {"c3": "00266"} | {"c2": "6", "c6": "6", "c7": "6 ", "c8": "foo", "C 1": "266"} - Wed Mar 18 00:00:00 1970 | {"c3": "00276"} | {"c2": "6", "c6": "6", "c7": "6 ", "c8": "foo", "C 1": "276"} | Wed Mar 18 00:00:00 1970 | {"c3": "00276"} | {"c2": "6", "c6": "6", "c7": "6 ", "c8": "foo", "C 1": "276"} - Sat Mar 28 00:00:00 1970 | {"c3": "00286"} | {"c2": "6", "c6": "6", "c7": "6 ", "c8": "foo", "C 1": "286"} | Sat Mar 28 00:00:00 1970 | {"c3": "00286"} | {"c2": "6", "c6": "6", "c7": "6 ", "c8": "foo", "C 1": "286"} - Tue Apr 07 00:00:00 1970 | {"c3": "00296"} | {"c2": "6", "c6": "6", "c7": "6 ", "c8": "foo", "C 1": "296"} | Tue Apr 07 00:00:00 1970 | {"c3": "00296"} | {"c2": "6", "c6": "6", "c7": "6 ", "c8": "foo", "C 1": "296"} - Wed Jan 07 00:00:00 1970 | {"c3": "00306"} | {"c2": "6", "c6": "6", "c7": "6 ", "c8": "foo", "C 1": "306"} | Wed Jan 07 00:00:00 1970 | {"c3": "00306"} | {"c2": "6", "c6": "6", "c7": "6 ", "c8": "foo", "C 1": "306"} - Sat Jan 17 00:00:00 1970 | {"c3": "00316"} | {"c2": "6", "c6": "6", "c7": "6 ", "c8": "foo", "C 1": "316"} | Sat Jan 17 00:00:00 1970 | {"c3": "00316"} | {"c2": "6", "c6": "6", "c7": "6 ", "c8": "foo", "C 1": "316"} - Tue Jan 27 00:00:00 1970 | {"c3": "00326"} | {"c2": "6", "c6": "6", "c7": "6 ", "c8": "foo", "C 1": "326"} | Tue Jan 27 00:00:00 1970 | {"c3": "00326"} | {"c2": "6", "c6": "6", "c7": "6 ", "c8": "foo", "C 1": "326"} - Fri Feb 06 00:00:00 1970 | {"c3": "00336"} | {"c2": "6", "c6": "6", "c7": "6 ", "c8": "foo", "C 1": "336"} | Fri Feb 06 00:00:00 1970 | {"c3": "00336"} | {"c2": "6", "c6": "6", "c7": "6 ", "c8": "foo", "C 1": "336"} - Mon Feb 16 00:00:00 1970 | {"c3": "00346"} | {"c2": "6", "c6": "6", "c7": "6 ", "c8": "foo", "C 1": "346"} | Mon Feb 16 00:00:00 1970 | {"c3": "00346"} | {"c2": "6", "c6": "6", "c7": "6 ", "c8": "foo", "C 1": "346"} - Thu Feb 26 00:00:00 1970 | {"c3": "00356"} | {"c2": "6", "c6": "6", "c7": "6 ", "c8": "foo", "C 1": "356"} | Thu Feb 26 00:00:00 1970 | {"c3": "00356"} | {"c2": "6", "c6": "6", "c7": "6 ", "c8": "foo", "C 1": "356"} - Sun Mar 08 00:00:00 1970 | {"c3": "00366"} | {"c2": "6", "c6": "6", "c7": "6 ", "c8": "foo", "C 1": "366"} | Sun Mar 08 00:00:00 1970 | {"c3": "00366"} | {"c2": "6", "c6": "6", "c7": "6 ", "c8": "foo", "C 1": "366"} - Wed Mar 18 00:00:00 1970 | {"c3": "00376"} | {"c2": "6", "c6": "6", "c7": "6 ", "c8": "foo", "C 1": "376"} | Wed Mar 18 00:00:00 1970 | {"c3": "00376"} | {"c2": "6", "c6": "6", "c7": "6 ", "c8": "foo", "C 1": "376"} - Sat Mar 28 00:00:00 1970 | {"c3": "00386"} | {"c2": "6", "c6": "6", "c7": "6 ", "c8": "foo", "C 1": "386"} | Sat Mar 28 00:00:00 1970 | {"c3": "00386"} | {"c2": "6", "c6": "6", "c7": "6 ", "c8": "foo", "C 1": "386"} - Tue Apr 07 00:00:00 1970 | {"c3": "00396"} | {"c2": "6", "c6": "6", "c7": "6 ", "c8": "foo", "C 1": "396"} | Tue Apr 07 00:00:00 1970 | {"c3": "00396"} | {"c2": "6", "c6": "6", "c7": "6 ", "c8": "foo", "C 1": "396"} - Wed Jan 07 00:00:00 1970 | {"c3": "00406"} | {"c2": "6", "c6": "6", "c7": "6 ", "c8": "foo", "C 1": "406"} | Wed Jan 07 00:00:00 1970 | {"c3": "00406"} | {"c2": "6", "c6": "6", "c7": "6 ", "c8": "foo", "C 1": "406"} - Sat Jan 17 00:00:00 1970 | {"c3": "00416"} | {"c2": "6", "c6": "6", "c7": "6 ", "c8": "foo", "C 1": "416"} | Sat Jan 17 00:00:00 1970 | {"c3": "00416"} | {"c2": "6", "c6": "6", "c7": "6 ", "c8": "foo", "C 1": "416"} - Tue Jan 27 00:00:00 1970 | {"c3": "00426"} | {"c2": "6", "c6": "6", "c7": "6 ", "c8": "foo", "C 1": "426"} | Tue Jan 27 00:00:00 1970 | {"c3": "00426"} | {"c2": "6", "c6": "6", "c7": "6 ", "c8": "foo", "C 1": "426"} - Fri Feb 06 00:00:00 1970 | {"c3": "00436"} | {"c2": "6", "c6": "6", "c7": "6 ", "c8": "foo", "C 1": "436"} | Fri Feb 06 00:00:00 1970 | {"c3": "00436"} | {"c2": "6", "c6": "6", "c7": "6 ", "c8": "foo", "C 1": "436"} - Mon Feb 16 00:00:00 1970 | {"c3": "00446"} | {"c2": "6", "c6": "6", "c7": "6 ", "c8": "foo", "C 1": "446"} | Mon Feb 16 00:00:00 1970 | {"c3": "00446"} | {"c2": "6", "c6": "6", "c7": "6 ", "c8": "foo", "C 1": "446"} - Thu Feb 26 00:00:00 1970 | {"c3": "00456"} | {"c2": "6", "c6": "6", "c7": "6 ", "c8": "foo", "C 1": "456"} | Thu Feb 26 00:00:00 1970 | {"c3": "00456"} | {"c2": "6", "c6": "6", "c7": "6 ", "c8": "foo", "C 1": "456"} - Sun Mar 08 00:00:00 1970 | {"c3": "00466"} | {"c2": "6", "c6": "6", "c7": "6 ", "c8": "foo", "C 1": "466"} | Sun Mar 08 00:00:00 1970 | {"c3": "00466"} | {"c2": "6", "c6": "6", "c7": "6 ", "c8": "foo", "C 1": "466"} - Wed Mar 18 00:00:00 1970 | {"c3": "00476"} | {"c2": "6", "c6": "6", "c7": "6 ", "c8": "foo", "C 1": "476"} | Wed Mar 18 00:00:00 1970 | {"c3": "00476"} | {"c2": "6", "c6": "6", "c7": "6 ", "c8": "foo", "C 1": "476"} - Sat Mar 28 00:00:00 1970 | {"c3": "00486"} | {"c2": "6", "c6": "6", "c7": "6 ", "c8": "foo", "C 1": "486"} | Sat Mar 28 00:00:00 1970 | {"c3": "00486"} | {"c2": "6", "c6": "6", "c7": "6 ", "c8": "foo", "C 1": "486"} - Tue Apr 07 00:00:00 1970 | {"c3": "00496"} | {"c2": "6", "c6": "6", "c7": "6 ", "c8": "foo", "C 1": "496"} | Tue Apr 07 00:00:00 1970 | {"c3": "00496"} | {"c2": "6", "c6": "6", "c7": "6 ", "c8": "foo", "C 1": "496"} - Wed Jan 07 00:00:00 1970 | {"c3": "00506"} | {"c2": "6", "c6": "6", "c7": "6 ", "c8": "foo", "C 1": "506"} | Wed Jan 07 00:00:00 1970 | {"c3": "00506"} | {"c2": "6", "c6": "6", "c7": "6 ", "c8": "foo", "C 1": "506"} - Sat Jan 17 00:00:00 1970 | {"c3": "00516"} | {"c2": "6", "c6": "6", "c7": "6 ", "c8": "foo", "C 1": "516"} | Sat Jan 17 00:00:00 1970 | {"c3": "00516"} | {"c2": "6", "c6": "6", "c7": "6 ", "c8": "foo", "C 1": "516"} - Tue Jan 27 00:00:00 1970 | {"c3": "00526"} | {"c2": "6", "c6": "6", "c7": "6 ", "c8": "foo", "C 1": "526"} | Tue Jan 27 00:00:00 1970 | {"c3": "00526"} | {"c2": "6", "c6": "6", "c7": "6 ", "c8": "foo", "C 1": "526"} - Fri Feb 06 00:00:00 1970 | {"c3": "00536"} | {"c2": "6", "c6": "6", "c7": "6 ", "c8": "foo", "C 1": "536"} | Fri Feb 06 00:00:00 1970 | {"c3": "00536"} | {"c2": "6", "c6": "6", "c7": "6 ", "c8": "foo", "C 1": "536"} - Mon Feb 16 00:00:00 1970 | {"c3": "00546"} | {"c2": "6", "c6": "6", "c7": "6 ", "c8": "foo", "C 1": "546"} | Mon Feb 16 00:00:00 1970 | {"c3": "00546"} | {"c2": "6", "c6": "6", "c7": "6 ", "c8": "foo", "C 1": "546"} - Thu Feb 26 00:00:00 1970 | {"c3": "00556"} | {"c2": "6", "c6": "6", "c7": "6 ", "c8": "foo", "C 1": "556"} | Thu Feb 26 00:00:00 1970 | {"c3": "00556"} | {"c2": "6", "c6": "6", "c7": "6 ", "c8": "foo", "C 1": "556"} - Sun Mar 08 00:00:00 1970 | {"c3": "00566"} | {"c2": "6", "c6": "6", "c7": "6 ", "c8": "foo", "C 1": "566"} | Sun Mar 08 00:00:00 1970 | {"c3": "00566"} | {"c2": "6", "c6": "6", "c7": "6 ", "c8": "foo", "C 1": "566"} - Wed Mar 18 00:00:00 1970 | {"c3": "00576"} | {"c2": "6", "c6": "6", "c7": "6 ", "c8": "foo", "C 1": "576"} | Wed Mar 18 00:00:00 1970 | {"c3": "00576"} | {"c2": "6", "c6": "6", "c7": "6 ", "c8": "foo", "C 1": "576"} - Sat Mar 28 00:00:00 1970 | {"c3": "00586"} | {"c2": "6", "c6": "6", "c7": "6 ", "c8": "foo", "C 1": "586"} | Sat Mar 28 00:00:00 1970 | {"c3": "00586"} | {"c2": "6", "c6": "6", "c7": "6 ", "c8": "foo", "C 1": "586"} - Tue Apr 07 00:00:00 1970 | {"c3": "00596"} | {"c2": "6", "c6": "6", "c7": "6 ", "c8": "foo", "C 1": "596"} | Tue Apr 07 00:00:00 1970 | {"c3": "00596"} | {"c2": "6", "c6": "6", "c7": "6 ", "c8": "foo", "C 1": "596"} - Wed Jan 07 00:00:00 1970 | {"c3": "00606"} | {"c2": "6", "c6": "6", "c7": "6 ", "c8": "foo", "C 1": "606"} | Wed Jan 07 00:00:00 1970 | {"c3": "00606"} | {"c2": "6", "c6": "6", "c7": "6 ", "c8": "foo", "C 1": "606"} - Sat Jan 17 00:00:00 1970 | {"c3": "00616"} | {"c2": "6", "c6": "6", "c7": "6 ", "c8": "foo", "C 1": "616"} | Sat Jan 17 00:00:00 1970 | {"c3": "00616"} | {"c2": "6", "c6": "6", "c7": "6 ", "c8": "foo", "C 1": "616"} - Tue Jan 27 00:00:00 1970 | {"c3": "00626"} | {"c2": "6", "c6": "6", "c7": "6 ", "c8": "foo", "C 1": "626"} | Tue Jan 27 00:00:00 1970 | {"c3": "00626"} | {"c2": "6", "c6": "6", "c7": "6 ", "c8": "foo", "C 1": "626"} - Fri Feb 06 00:00:00 1970 | {"c3": "00636"} | {"c2": "6", "c6": "6", "c7": "6 ", "c8": "foo", "C 1": "636"} | Fri Feb 06 00:00:00 1970 | {"c3": "00636"} | {"c2": "6", "c6": "6", "c7": "6 ", "c8": "foo", "C 1": "636"} - Mon Feb 16 00:00:00 1970 | {"c3": "00646"} | {"c2": "6", "c6": "6", "c7": "6 ", "c8": "foo", "C 1": "646"} | Mon Feb 16 00:00:00 1970 | {"c3": "00646"} | {"c2": "6", "c6": "6", "c7": "6 ", "c8": "foo", "C 1": "646"} - Thu Feb 26 00:00:00 1970 | {"c3": "00656"} | {"c2": "6", "c6": "6", "c7": "6 ", "c8": "foo", "C 1": "656"} | Thu Feb 26 00:00:00 1970 | {"c3": "00656"} | {"c2": "6", "c6": "6", "c7": "6 ", "c8": "foo", "C 1": "656"} - Sun Mar 08 00:00:00 1970 | {"c3": "00666"} | {"c2": "6", "c6": "6", "c7": "6 ", "c8": "foo", "C 1": "666"} | Sun Mar 08 00:00:00 1970 | {"c3": "00666"} | {"c2": "6", "c6": "6", "c7": "6 ", "c8": "foo", "C 1": "666"} - Wed Mar 18 00:00:00 1970 | {"c3": "00676"} | {"c2": "6", "c6": "6", "c7": "6 ", "c8": "foo", "C 1": "676"} | Wed Mar 18 00:00:00 1970 | {"c3": "00676"} | {"c2": "6", "c6": "6", "c7": "6 ", "c8": "foo", "C 1": "676"} - Sat Mar 28 00:00:00 1970 | {"c3": "00686"} | {"c2": "6", "c6": "6", "c7": "6 ", "c8": "foo", "C 1": "686"} | Sat Mar 28 00:00:00 1970 | {"c3": "00686"} | {"c2": "6", "c6": "6", "c7": "6 ", "c8": "foo", "C 1": "686"} - Tue Apr 07 00:00:00 1970 | {"c3": "00696"} | {"c2": "6", "c6": "6", "c7": "6 ", "c8": "foo", "C 1": "696"} | Tue Apr 07 00:00:00 1970 | {"c3": "00696"} | {"c2": "6", "c6": "6", "c7": "6 ", "c8": "foo", "C 1": "696"} - Wed Jan 07 00:00:00 1970 | {"c3": "00706"} | {"c2": "6", "c6": "6", "c7": "6 ", "c8": "foo", "C 1": "706"} | Wed Jan 07 00:00:00 1970 | {"c3": "00706"} | {"c2": "6", "c6": "6", "c7": "6 ", "c8": "foo", "C 1": "706"} - Sat Jan 17 00:00:00 1970 | {"c3": "00716"} | {"c2": "6", "c6": "6", "c7": "6 ", "c8": "foo", "C 1": "716"} | Sat Jan 17 00:00:00 1970 | {"c3": "00716"} | {"c2": "6", "c6": "6", "c7": "6 ", "c8": "foo", "C 1": "716"} - Tue Jan 27 00:00:00 1970 | {"c3": "00726"} | {"c2": "6", "c6": "6", "c7": "6 ", "c8": "foo", "C 1": "726"} | Tue Jan 27 00:00:00 1970 | {"c3": "00726"} | {"c2": "6", "c6": "6", "c7": "6 ", "c8": "foo", "C 1": "726"} - Fri Feb 06 00:00:00 1970 | {"c3": "00736"} | {"c2": "6", "c6": "6", "c7": "6 ", "c8": "foo", "C 1": "736"} | Fri Feb 06 00:00:00 1970 | {"c3": "00736"} | {"c2": "6", "c6": "6", "c7": "6 ", "c8": "foo", "C 1": "736"} - Mon Feb 16 00:00:00 1970 | {"c3": "00746"} | {"c2": "6", "c6": "6", "c7": "6 ", "c8": "foo", "C 1": "746"} | Mon Feb 16 00:00:00 1970 | {"c3": "00746"} | {"c2": "6", "c6": "6", "c7": "6 ", "c8": "foo", "C 1": "746"} - Thu Feb 26 00:00:00 1970 | {"c3": "00756"} | {"c2": "6", "c6": "6", "c7": "6 ", "c8": "foo", "C 1": "756"} | Thu Feb 26 00:00:00 1970 | {"c3": "00756"} | {"c2": "6", "c6": "6", "c7": "6 ", "c8": "foo", "C 1": "756"} - Sun Mar 08 00:00:00 1970 | {"c3": "00766"} | {"c2": "6", "c6": "6", "c7": "6 ", "c8": "foo", "C 1": "766"} | Sun Mar 08 00:00:00 1970 | {"c3": "00766"} | {"c2": "6", "c6": "6", "c7": "6 ", "c8": "foo", "C 1": "766"} - Wed Mar 18 00:00:00 1970 | {"c3": "00776"} | {"c2": "6", "c6": "6", "c7": "6 ", "c8": "foo", "C 1": "776"} | Wed Mar 18 00:00:00 1970 | {"c3": "00776"} | {"c2": "6", "c6": "6", "c7": "6 ", "c8": "foo", "C 1": "776"} - Sat Mar 28 00:00:00 1970 | {"c3": "00786"} | {"c2": "6", "c6": "6", "c7": "6 ", "c8": "foo", "C 1": "786"} | Sat Mar 28 00:00:00 1970 | {"c3": "00786"} | {"c2": "6", "c6": "6", "c7": "6 ", "c8": "foo", "C 1": "786"} - Tue Apr 07 00:00:00 1970 | {"c3": "00796"} | {"c2": "6", "c6": "6", "c7": "6 ", "c8": "foo", "C 1": "796"} | Tue Apr 07 00:00:00 1970 | {"c3": "00796"} | {"c2": "6", "c6": "6", "c7": "6 ", "c8": "foo", "C 1": "796"} - Wed Jan 07 00:00:00 1970 | {"c3": "00806"} | {"c2": "6", "c6": "6", "c7": "6 ", "c8": "foo", "C 1": "806"} | Wed Jan 07 00:00:00 1970 | {"c3": "00806"} | {"c2": "6", "c6": "6", "c7": "6 ", "c8": "foo", "C 1": "806"} - Sat Jan 17 00:00:00 1970 | {"c3": "00816"} | {"c2": "6", "c6": "6", "c7": "6 ", "c8": "foo", "C 1": "816"} | Sat Jan 17 00:00:00 1970 | {"c3": "00816"} | {"c2": "6", "c6": "6", "c7": "6 ", "c8": "foo", "C 1": "816"} - Tue Jan 27 00:00:00 1970 | {"c3": "00826"} | {"c2": "6", "c6": "6", "c7": "6 ", "c8": "foo", "C 1": "826"} | Tue Jan 27 00:00:00 1970 | {"c3": "00826"} | {"c2": "6", "c6": "6", "c7": "6 ", "c8": "foo", "C 1": "826"} - Fri Feb 06 00:00:00 1970 | {"c3": "00836"} | {"c2": "6", "c6": "6", "c7": "6 ", "c8": "foo", "C 1": "836"} | Fri Feb 06 00:00:00 1970 | {"c3": "00836"} | {"c2": "6", "c6": "6", "c7": "6 ", "c8": "foo", "C 1": "836"} - Mon Feb 16 00:00:00 1970 | {"c3": "00846"} | {"c2": "6", "c6": "6", "c7": "6 ", "c8": "foo", "C 1": "846"} | Mon Feb 16 00:00:00 1970 | {"c3": "00846"} | {"c2": "6", "c6": "6", "c7": "6 ", "c8": "foo", "C 1": "846"} - Thu Feb 26 00:00:00 1970 | {"c3": "00856"} | {"c2": "6", "c6": "6", "c7": "6 ", "c8": "foo", "C 1": "856"} | Thu Feb 26 00:00:00 1970 | {"c3": "00856"} | {"c2": "6", "c6": "6", "c7": "6 ", "c8": "foo", "C 1": "856"} - Sun Mar 08 00:00:00 1970 | {"c3": "00866"} | {"c2": "6", "c6": "6", "c7": "6 ", "c8": "foo", "C 1": "866"} | Sun Mar 08 00:00:00 1970 | {"c3": "00866"} | {"c2": "6", "c6": "6", "c7": "6 ", "c8": "foo", "C 1": "866"} - Wed Mar 18 00:00:00 1970 | {"c3": "00876"} | {"c2": "6", "c6": "6", "c7": "6 ", "c8": "foo", "C 1": "876"} | Wed Mar 18 00:00:00 1970 | {"c3": "00876"} | {"c2": "6", "c6": "6", "c7": "6 ", "c8": "foo", "C 1": "876"} - Sat Mar 28 00:00:00 1970 | {"c3": "00886"} | {"c2": "6", "c6": "6", "c7": "6 ", "c8": "foo", "C 1": "886"} | Sat Mar 28 00:00:00 1970 | {"c3": "00886"} | {"c2": "6", "c6": "6", "c7": "6 ", "c8": "foo", "C 1": "886"} - Tue Apr 07 00:00:00 1970 | {"c3": "00896"} | {"c2": "6", "c6": "6", "c7": "6 ", "c8": "foo", "C 1": "896"} | Tue Apr 07 00:00:00 1970 | {"c3": "00896"} | {"c2": "6", "c6": "6", "c7": "6 ", "c8": "foo", "C 1": "896"} - Wed Jan 07 00:00:00 1970 | {"c3": "00906"} | {"c2": "6", "c6": "6", "c7": "6 ", "c8": "foo", "C 1": "906"} | Wed Jan 07 00:00:00 1970 | {"c3": "00906"} | {"c2": "6", "c6": "6", "c7": "6 ", "c8": "foo", "C 1": "906"} - Sat Jan 17 00:00:00 1970 | {"c3": "00916"} | {"c2": "6", "c6": "6", "c7": "6 ", "c8": "foo", "C 1": "916"} | Sat Jan 17 00:00:00 1970 | {"c3": "00916"} | {"c2": "6", "c6": "6", "c7": "6 ", "c8": "foo", "C 1": "916"} - Tue Jan 27 00:00:00 1970 | {"c3": "00926"} | {"c2": "6", "c6": "6", "c7": "6 ", "c8": "foo", "C 1": "926"} | Tue Jan 27 00:00:00 1970 | {"c3": "00926"} | {"c2": "6", "c6": "6", "c7": "6 ", "c8": "foo", "C 1": "926"} - Fri Feb 06 00:00:00 1970 | {"c3": "00936"} | {"c2": "6", "c6": "6", "c7": "6 ", "c8": "foo", "C 1": "936"} | Fri Feb 06 00:00:00 1970 | {"c3": "00936"} | {"c2": "6", "c6": "6", "c7": "6 ", "c8": "foo", "C 1": "936"} - Mon Feb 16 00:00:00 1970 | {"c3": "00946"} | {"c2": "6", "c6": "6", "c7": "6 ", "c8": "foo", "C 1": "946"} | Mon Feb 16 00:00:00 1970 | {"c3": "00946"} | {"c2": "6", "c6": "6", "c7": "6 ", "c8": "foo", "C 1": "946"} - Thu Feb 26 00:00:00 1970 | {"c3": "00956"} | {"c2": "6", "c6": "6", "c7": "6 ", "c8": "foo", "C 1": "956"} | Thu Feb 26 00:00:00 1970 | {"c3": "00956"} | {"c2": "6", "c6": "6", "c7": "6 ", "c8": "foo", "C 1": "956"} - Sun Mar 08 00:00:00 1970 | {"c3": "00966"} | {"c2": "6", "c6": "6", "c7": "6 ", "c8": "foo", "C 1": "966"} | Sun Mar 08 00:00:00 1970 | {"c3": "00966"} | {"c2": "6", "c6": "6", "c7": "6 ", "c8": "foo", "C 1": "966"} - Wed Mar 18 00:00:00 1970 | {"c3": "00976"} | {"c2": "6", "c6": "6", "c7": "6 ", "c8": "foo", "C 1": "976"} | Wed Mar 18 00:00:00 1970 | {"c3": "00976"} | {"c2": "6", "c6": "6", "c7": "6 ", "c8": "foo", "C 1": "976"} - Sat Mar 28 00:00:00 1970 | {"c3": "00986"} | {"c2": "6", "c6": "6", "c7": "6 ", "c8": "foo", "C 1": "986"} | Sat Mar 28 00:00:00 1970 | {"c3": "00986"} | {"c2": "6", "c6": "6", "c7": "6 ", "c8": "foo", "C 1": "986"} - Tue Apr 07 00:00:00 1970 | {"c3": "00996"} | {"c2": "6", "c6": "6", "c7": "6 ", "c8": "foo", "C 1": "996"} | Tue Apr 07 00:00:00 1970 | {"c3": "00996"} | {"c2": "6", "c6": "6", "c7": "6 ", "c8": "foo", "C 1": "996"} + time | tags | fields | time | tags | fields +------------------------------+-----------------+-----------------------------------------------------------------------+------------------------------+-----------------+----------------------------------------------------------------------- + Wed Jan 07 00:00:00 1970 PST | {"c3": "00006"} | {"c2": "6", "c6": "6", "c7": "6 ", "c8": "foo", "C 1": "6"} | Wed Jan 07 00:00:00 1970 PST | {"c3": "00006"} | {"c2": "6", "c6": "6", "c7": "6 ", "c8": "foo", "C 1": "6"} + Sat Jan 17 00:00:00 1970 PST | {"c3": "00016"} | {"c2": "6", "c6": "6", "c7": "6 ", "c8": "foo", "C 1": "16"} | Sat Jan 17 00:00:00 1970 PST | {"c3": "00016"} | {"c2": "6", "c6": "6", "c7": "6 ", "c8": "foo", "C 1": "16"} + Tue Jan 27 00:00:00 1970 PST | {"c3": "00026"} | {"c2": "6", "c6": "6", "c7": "6 ", "c8": "foo", "C 1": "26"} | Tue Jan 27 00:00:00 1970 PST | {"c3": "00026"} | {"c2": "6", "c6": "6", "c7": "6 ", "c8": "foo", "C 1": "26"} + Fri Feb 06 00:00:00 1970 PST | {"c3": "00036"} | {"c2": "6", "c6": "6", "c7": "6 ", "c8": "foo", "C 1": "36"} | Fri Feb 06 00:00:00 1970 PST | {"c3": "00036"} | {"c2": "6", "c6": "6", "c7": "6 ", "c8": "foo", "C 1": "36"} + Mon Feb 16 00:00:00 1970 PST | {"c3": "00046"} | {"c2": "6", "c6": "6", "c7": "6 ", "c8": "foo", "C 1": "46"} | Mon Feb 16 00:00:00 1970 PST | {"c3": "00046"} | {"c2": "6", "c6": "6", "c7": "6 ", "c8": "foo", "C 1": "46"} + Thu Feb 26 00:00:00 1970 PST | {"c3": "00056"} | {"c2": "6", "c6": "6", "c7": "6 ", "c8": "foo", "C 1": "56"} | Thu Feb 26 00:00:00 1970 PST | {"c3": "00056"} | {"c2": "6", "c6": "6", "c7": "6 ", "c8": "foo", "C 1": "56"} + Sun Mar 08 00:00:00 1970 PST | {"c3": "00066"} | {"c2": "6", "c6": "6", "c7": "6 ", "c8": "foo", "C 1": "66"} | Sun Mar 08 00:00:00 1970 PST | {"c3": "00066"} | {"c2": "6", "c6": "6", "c7": "6 ", "c8": "foo", "C 1": "66"} + Wed Mar 18 00:00:00 1970 PST | {"c3": "00076"} | {"c2": "6", "c6": "6", "c7": "6 ", "c8": "foo", "C 1": "76"} | Wed Mar 18 00:00:00 1970 PST | {"c3": "00076"} | {"c2": "6", "c6": "6", "c7": "6 ", "c8": "foo", "C 1": "76"} + Sat Mar 28 00:00:00 1970 PST | {"c3": "00086"} | {"c2": "6", "c6": "6", "c7": "6 ", "c8": "foo", "C 1": "86"} | Sat Mar 28 00:00:00 1970 PST | {"c3": "00086"} | {"c2": "6", "c6": "6", "c7": "6 ", "c8": "foo", "C 1": "86"} + Tue Apr 07 00:00:00 1970 PST | {"c3": "00096"} | {"c2": "6", "c6": "6", "c7": "6 ", "c8": "foo", "C 1": "96"} | Tue Apr 07 00:00:00 1970 PST | {"c3": "00096"} | {"c2": "6", "c6": "6", "c7": "6 ", "c8": "foo", "C 1": "96"} + Wed Jan 07 00:00:00 1970 PST | {"c3": "00106"} | {"c2": "6", "c6": "6", "c7": "6 ", "c8": "foo", "C 1": "106"} | Wed Jan 07 00:00:00 1970 PST | {"c3": "00106"} | {"c2": "6", "c6": "6", "c7": "6 ", "c8": "foo", "C 1": "106"} + Sat Jan 17 00:00:00 1970 PST | {"c3": "00116"} | {"c2": "6", "c6": "6", "c7": "6 ", "c8": "foo", "C 1": "116"} | Sat Jan 17 00:00:00 1970 PST | {"c3": "00116"} | {"c2": "6", "c6": "6", "c7": "6 ", "c8": "foo", "C 1": "116"} + Tue Jan 27 00:00:00 1970 PST | {"c3": "00126"} | {"c2": "6", "c6": "6", "c7": "6 ", "c8": "foo", "C 1": "126"} | Tue Jan 27 00:00:00 1970 PST | {"c3": "00126"} | {"c2": "6", "c6": "6", "c7": "6 ", "c8": "foo", "C 1": "126"} + Fri Feb 06 00:00:00 1970 PST | {"c3": "00136"} | {"c2": "6", "c6": "6", "c7": "6 ", "c8": "foo", "C 1": "136"} | Fri Feb 06 00:00:00 1970 PST | {"c3": "00136"} | {"c2": "6", "c6": "6", "c7": "6 ", "c8": "foo", "C 1": "136"} + Mon Feb 16 00:00:00 1970 PST | {"c3": "00146"} | {"c2": "6", "c6": "6", "c7": "6 ", "c8": "foo", "C 1": "146"} | Mon Feb 16 00:00:00 1970 PST | {"c3": "00146"} | {"c2": "6", "c6": "6", "c7": "6 ", "c8": "foo", "C 1": "146"} + Thu Feb 26 00:00:00 1970 PST | {"c3": "00156"} | {"c2": "6", "c6": "6", "c7": "6 ", "c8": "foo", "C 1": "156"} | Thu Feb 26 00:00:00 1970 PST | {"c3": "00156"} | {"c2": "6", "c6": "6", "c7": "6 ", "c8": "foo", "C 1": "156"} + Sun Mar 08 00:00:00 1970 PST | {"c3": "00166"} | {"c2": "6", "c6": "6", "c7": "6 ", "c8": "foo", "C 1": "166"} | Sun Mar 08 00:00:00 1970 PST | {"c3": "00166"} | {"c2": "6", "c6": "6", "c7": "6 ", "c8": "foo", "C 1": "166"} + Wed Mar 18 00:00:00 1970 PST | {"c3": "00176"} | {"c2": "6", "c6": "6", "c7": "6 ", "c8": "foo", "C 1": "176"} | Wed Mar 18 00:00:00 1970 PST | {"c3": "00176"} | {"c2": "6", "c6": "6", "c7": "6 ", "c8": "foo", "C 1": "176"} + Sat Mar 28 00:00:00 1970 PST | {"c3": "00186"} | {"c2": "6", "c6": "6", "c7": "6 ", "c8": "foo", "C 1": "186"} | Sat Mar 28 00:00:00 1970 PST | {"c3": "00186"} | {"c2": "6", "c6": "6", "c7": "6 ", "c8": "foo", "C 1": "186"} + Tue Apr 07 00:00:00 1970 PST | {"c3": "00196"} | {"c2": "6", "c6": "6", "c7": "6 ", "c8": "foo", "C 1": "196"} | Tue Apr 07 00:00:00 1970 PST | {"c3": "00196"} | {"c2": "6", "c6": "6", "c7": "6 ", "c8": "foo", "C 1": "196"} + Wed Jan 07 00:00:00 1970 PST | {"c3": "00206"} | {"c2": "6", "c6": "6", "c7": "6 ", "c8": "foo", "C 1": "206"} | Wed Jan 07 00:00:00 1970 PST | {"c3": "00206"} | {"c2": "6", "c6": "6", "c7": "6 ", "c8": "foo", "C 1": "206"} + Sat Jan 17 00:00:00 1970 PST | {"c3": "00216"} | {"c2": "6", "c6": "6", "c7": "6 ", "c8": "foo", "C 1": "216"} | Sat Jan 17 00:00:00 1970 PST | {"c3": "00216"} | {"c2": "6", "c6": "6", "c7": "6 ", "c8": "foo", "C 1": "216"} + Tue Jan 27 00:00:00 1970 PST | {"c3": "00226"} | {"c2": "6", "c6": "6", "c7": "6 ", "c8": "foo", "C 1": "226"} | Tue Jan 27 00:00:00 1970 PST | {"c3": "00226"} | {"c2": "6", "c6": "6", "c7": "6 ", "c8": "foo", "C 1": "226"} + Fri Feb 06 00:00:00 1970 PST | {"c3": "00236"} | {"c2": "6", "c6": "6", "c7": "6 ", "c8": "foo", "C 1": "236"} | Fri Feb 06 00:00:00 1970 PST | {"c3": "00236"} | {"c2": "6", "c6": "6", "c7": "6 ", "c8": "foo", "C 1": "236"} + Mon Feb 16 00:00:00 1970 PST | {"c3": "00246"} | {"c2": "6", "c6": "6", "c7": "6 ", "c8": "foo", "C 1": "246"} | Mon Feb 16 00:00:00 1970 PST | {"c3": "00246"} | {"c2": "6", "c6": "6", "c7": "6 ", "c8": "foo", "C 1": "246"} + Thu Feb 26 00:00:00 1970 PST | {"c3": "00256"} | {"c2": "6", "c6": "6", "c7": "6 ", "c8": "foo", "C 1": "256"} | Thu Feb 26 00:00:00 1970 PST | {"c3": "00256"} | {"c2": "6", "c6": "6", "c7": "6 ", "c8": "foo", "C 1": "256"} + Sun Mar 08 00:00:00 1970 PST | {"c3": "00266"} | {"c2": "6", "c6": "6", "c7": "6 ", "c8": "foo", "C 1": "266"} | Sun Mar 08 00:00:00 1970 PST | {"c3": "00266"} | {"c2": "6", "c6": "6", "c7": "6 ", "c8": "foo", "C 1": "266"} + Wed Mar 18 00:00:00 1970 PST | {"c3": "00276"} | {"c2": "6", "c6": "6", "c7": "6 ", "c8": "foo", "C 1": "276"} | Wed Mar 18 00:00:00 1970 PST | {"c3": "00276"} | {"c2": "6", "c6": "6", "c7": "6 ", "c8": "foo", "C 1": "276"} + Sat Mar 28 00:00:00 1970 PST | {"c3": "00286"} | {"c2": "6", "c6": "6", "c7": "6 ", "c8": "foo", "C 1": "286"} | Sat Mar 28 00:00:00 1970 PST | {"c3": "00286"} | {"c2": "6", "c6": "6", "c7": "6 ", "c8": "foo", "C 1": "286"} + Tue Apr 07 00:00:00 1970 PST | {"c3": "00296"} | {"c2": "6", "c6": "6", "c7": "6 ", "c8": "foo", "C 1": "296"} | Tue Apr 07 00:00:00 1970 PST | {"c3": "00296"} | {"c2": "6", "c6": "6", "c7": "6 ", "c8": "foo", "C 1": "296"} + Wed Jan 07 00:00:00 1970 PST | {"c3": "00306"} | {"c2": "6", "c6": "6", "c7": "6 ", "c8": "foo", "C 1": "306"} | Wed Jan 07 00:00:00 1970 PST | {"c3": "00306"} | {"c2": "6", "c6": "6", "c7": "6 ", "c8": "foo", "C 1": "306"} + Sat Jan 17 00:00:00 1970 PST | {"c3": "00316"} | {"c2": "6", "c6": "6", "c7": "6 ", "c8": "foo", "C 1": "316"} | Sat Jan 17 00:00:00 1970 PST | {"c3": "00316"} | {"c2": "6", "c6": "6", "c7": "6 ", "c8": "foo", "C 1": "316"} + Tue Jan 27 00:00:00 1970 PST | {"c3": "00326"} | {"c2": "6", "c6": "6", "c7": "6 ", "c8": "foo", "C 1": "326"} | Tue Jan 27 00:00:00 1970 PST | {"c3": "00326"} | {"c2": "6", "c6": "6", "c7": "6 ", "c8": "foo", "C 1": "326"} + Fri Feb 06 00:00:00 1970 PST | {"c3": "00336"} | {"c2": "6", "c6": "6", "c7": "6 ", "c8": "foo", "C 1": "336"} | Fri Feb 06 00:00:00 1970 PST | {"c3": "00336"} | {"c2": "6", "c6": "6", "c7": "6 ", "c8": "foo", "C 1": "336"} + Mon Feb 16 00:00:00 1970 PST | {"c3": "00346"} | {"c2": "6", "c6": "6", "c7": "6 ", "c8": "foo", "C 1": "346"} | Mon Feb 16 00:00:00 1970 PST | {"c3": "00346"} | {"c2": "6", "c6": "6", "c7": "6 ", "c8": "foo", "C 1": "346"} + Thu Feb 26 00:00:00 1970 PST | {"c3": "00356"} | {"c2": "6", "c6": "6", "c7": "6 ", "c8": "foo", "C 1": "356"} | Thu Feb 26 00:00:00 1970 PST | {"c3": "00356"} | {"c2": "6", "c6": "6", "c7": "6 ", "c8": "foo", "C 1": "356"} + Sun Mar 08 00:00:00 1970 PST | {"c3": "00366"} | {"c2": "6", "c6": "6", "c7": "6 ", "c8": "foo", "C 1": "366"} | Sun Mar 08 00:00:00 1970 PST | {"c3": "00366"} | {"c2": "6", "c6": "6", "c7": "6 ", "c8": "foo", "C 1": "366"} + Wed Mar 18 00:00:00 1970 PST | {"c3": "00376"} | {"c2": "6", "c6": "6", "c7": "6 ", "c8": "foo", "C 1": "376"} | Wed Mar 18 00:00:00 1970 PST | {"c3": "00376"} | {"c2": "6", "c6": "6", "c7": "6 ", "c8": "foo", "C 1": "376"} + Sat Mar 28 00:00:00 1970 PST | {"c3": "00386"} | {"c2": "6", "c6": "6", "c7": "6 ", "c8": "foo", "C 1": "386"} | Sat Mar 28 00:00:00 1970 PST | {"c3": "00386"} | {"c2": "6", "c6": "6", "c7": "6 ", "c8": "foo", "C 1": "386"} + Tue Apr 07 00:00:00 1970 PST | {"c3": "00396"} | {"c2": "6", "c6": "6", "c7": "6 ", "c8": "foo", "C 1": "396"} | Tue Apr 07 00:00:00 1970 PST | {"c3": "00396"} | {"c2": "6", "c6": "6", "c7": "6 ", "c8": "foo", "C 1": "396"} + Wed Jan 07 00:00:00 1970 PST | {"c3": "00406"} | {"c2": "6", "c6": "6", "c7": "6 ", "c8": "foo", "C 1": "406"} | Wed Jan 07 00:00:00 1970 PST | {"c3": "00406"} | {"c2": "6", "c6": "6", "c7": "6 ", "c8": "foo", "C 1": "406"} + Sat Jan 17 00:00:00 1970 PST | {"c3": "00416"} | {"c2": "6", "c6": "6", "c7": "6 ", "c8": "foo", "C 1": "416"} | Sat Jan 17 00:00:00 1970 PST | {"c3": "00416"} | {"c2": "6", "c6": "6", "c7": "6 ", "c8": "foo", "C 1": "416"} + Tue Jan 27 00:00:00 1970 PST | {"c3": "00426"} | {"c2": "6", "c6": "6", "c7": "6 ", "c8": "foo", "C 1": "426"} | Tue Jan 27 00:00:00 1970 PST | {"c3": "00426"} | {"c2": "6", "c6": "6", "c7": "6 ", "c8": "foo", "C 1": "426"} + Fri Feb 06 00:00:00 1970 PST | {"c3": "00436"} | {"c2": "6", "c6": "6", "c7": "6 ", "c8": "foo", "C 1": "436"} | Fri Feb 06 00:00:00 1970 PST | {"c3": "00436"} | {"c2": "6", "c6": "6", "c7": "6 ", "c8": "foo", "C 1": "436"} + Mon Feb 16 00:00:00 1970 PST | {"c3": "00446"} | {"c2": "6", "c6": "6", "c7": "6 ", "c8": "foo", "C 1": "446"} | Mon Feb 16 00:00:00 1970 PST | {"c3": "00446"} | {"c2": "6", "c6": "6", "c7": "6 ", "c8": "foo", "C 1": "446"} + Thu Feb 26 00:00:00 1970 PST | {"c3": "00456"} | {"c2": "6", "c6": "6", "c7": "6 ", "c8": "foo", "C 1": "456"} | Thu Feb 26 00:00:00 1970 PST | {"c3": "00456"} | {"c2": "6", "c6": "6", "c7": "6 ", "c8": "foo", "C 1": "456"} + Sun Mar 08 00:00:00 1970 PST | {"c3": "00466"} | {"c2": "6", "c6": "6", "c7": "6 ", "c8": "foo", "C 1": "466"} | Sun Mar 08 00:00:00 1970 PST | {"c3": "00466"} | {"c2": "6", "c6": "6", "c7": "6 ", "c8": "foo", "C 1": "466"} + Wed Mar 18 00:00:00 1970 PST | {"c3": "00476"} | {"c2": "6", "c6": "6", "c7": "6 ", "c8": "foo", "C 1": "476"} | Wed Mar 18 00:00:00 1970 PST | {"c3": "00476"} | {"c2": "6", "c6": "6", "c7": "6 ", "c8": "foo", "C 1": "476"} + Sat Mar 28 00:00:00 1970 PST | {"c3": "00486"} | {"c2": "6", "c6": "6", "c7": "6 ", "c8": "foo", "C 1": "486"} | Sat Mar 28 00:00:00 1970 PST | {"c3": "00486"} | {"c2": "6", "c6": "6", "c7": "6 ", "c8": "foo", "C 1": "486"} + Tue Apr 07 00:00:00 1970 PST | {"c3": "00496"} | {"c2": "6", "c6": "6", "c7": "6 ", "c8": "foo", "C 1": "496"} | Tue Apr 07 00:00:00 1970 PST | {"c3": "00496"} | {"c2": "6", "c6": "6", "c7": "6 ", "c8": "foo", "C 1": "496"} + Wed Jan 07 00:00:00 1970 PST | {"c3": "00506"} | {"c2": "6", "c6": "6", "c7": "6 ", "c8": "foo", "C 1": "506"} | Wed Jan 07 00:00:00 1970 PST | {"c3": "00506"} | {"c2": "6", "c6": "6", "c7": "6 ", "c8": "foo", "C 1": "506"} + Sat Jan 17 00:00:00 1970 PST | {"c3": "00516"} | {"c2": "6", "c6": "6", "c7": "6 ", "c8": "foo", "C 1": "516"} | Sat Jan 17 00:00:00 1970 PST | {"c3": "00516"} | {"c2": "6", "c6": "6", "c7": "6 ", "c8": "foo", "C 1": "516"} + Tue Jan 27 00:00:00 1970 PST | {"c3": "00526"} | {"c2": "6", "c6": "6", "c7": "6 ", "c8": "foo", "C 1": "526"} | Tue Jan 27 00:00:00 1970 PST | {"c3": "00526"} | {"c2": "6", "c6": "6", "c7": "6 ", "c8": "foo", "C 1": "526"} + Fri Feb 06 00:00:00 1970 PST | {"c3": "00536"} | {"c2": "6", "c6": "6", "c7": "6 ", "c8": "foo", "C 1": "536"} | Fri Feb 06 00:00:00 1970 PST | {"c3": "00536"} | {"c2": "6", "c6": "6", "c7": "6 ", "c8": "foo", "C 1": "536"} + Mon Feb 16 00:00:00 1970 PST | {"c3": "00546"} | {"c2": "6", "c6": "6", "c7": "6 ", "c8": "foo", "C 1": "546"} | Mon Feb 16 00:00:00 1970 PST | {"c3": "00546"} | {"c2": "6", "c6": "6", "c7": "6 ", "c8": "foo", "C 1": "546"} + Thu Feb 26 00:00:00 1970 PST | {"c3": "00556"} | {"c2": "6", "c6": "6", "c7": "6 ", "c8": "foo", "C 1": "556"} | Thu Feb 26 00:00:00 1970 PST | {"c3": "00556"} | {"c2": "6", "c6": "6", "c7": "6 ", "c8": "foo", "C 1": "556"} + Sun Mar 08 00:00:00 1970 PST | {"c3": "00566"} | {"c2": "6", "c6": "6", "c7": "6 ", "c8": "foo", "C 1": "566"} | Sun Mar 08 00:00:00 1970 PST | {"c3": "00566"} | {"c2": "6", "c6": "6", "c7": "6 ", "c8": "foo", "C 1": "566"} + Wed Mar 18 00:00:00 1970 PST | {"c3": "00576"} | {"c2": "6", "c6": "6", "c7": "6 ", "c8": "foo", "C 1": "576"} | Wed Mar 18 00:00:00 1970 PST | {"c3": "00576"} | {"c2": "6", "c6": "6", "c7": "6 ", "c8": "foo", "C 1": "576"} + Sat Mar 28 00:00:00 1970 PST | {"c3": "00586"} | {"c2": "6", "c6": "6", "c7": "6 ", "c8": "foo", "C 1": "586"} | Sat Mar 28 00:00:00 1970 PST | {"c3": "00586"} | {"c2": "6", "c6": "6", "c7": "6 ", "c8": "foo", "C 1": "586"} + Tue Apr 07 00:00:00 1970 PST | {"c3": "00596"} | {"c2": "6", "c6": "6", "c7": "6 ", "c8": "foo", "C 1": "596"} | Tue Apr 07 00:00:00 1970 PST | {"c3": "00596"} | {"c2": "6", "c6": "6", "c7": "6 ", "c8": "foo", "C 1": "596"} + Wed Jan 07 00:00:00 1970 PST | {"c3": "00606"} | {"c2": "6", "c6": "6", "c7": "6 ", "c8": "foo", "C 1": "606"} | Wed Jan 07 00:00:00 1970 PST | {"c3": "00606"} | {"c2": "6", "c6": "6", "c7": "6 ", "c8": "foo", "C 1": "606"} + Sat Jan 17 00:00:00 1970 PST | {"c3": "00616"} | {"c2": "6", "c6": "6", "c7": "6 ", "c8": "foo", "C 1": "616"} | Sat Jan 17 00:00:00 1970 PST | {"c3": "00616"} | {"c2": "6", "c6": "6", "c7": "6 ", "c8": "foo", "C 1": "616"} + Tue Jan 27 00:00:00 1970 PST | {"c3": "00626"} | {"c2": "6", "c6": "6", "c7": "6 ", "c8": "foo", "C 1": "626"} | Tue Jan 27 00:00:00 1970 PST | {"c3": "00626"} | {"c2": "6", "c6": "6", "c7": "6 ", "c8": "foo", "C 1": "626"} + Fri Feb 06 00:00:00 1970 PST | {"c3": "00636"} | {"c2": "6", "c6": "6", "c7": "6 ", "c8": "foo", "C 1": "636"} | Fri Feb 06 00:00:00 1970 PST | {"c3": "00636"} | {"c2": "6", "c6": "6", "c7": "6 ", "c8": "foo", "C 1": "636"} + Mon Feb 16 00:00:00 1970 PST | {"c3": "00646"} | {"c2": "6", "c6": "6", "c7": "6 ", "c8": "foo", "C 1": "646"} | Mon Feb 16 00:00:00 1970 PST | {"c3": "00646"} | {"c2": "6", "c6": "6", "c7": "6 ", "c8": "foo", "C 1": "646"} + Thu Feb 26 00:00:00 1970 PST | {"c3": "00656"} | {"c2": "6", "c6": "6", "c7": "6 ", "c8": "foo", "C 1": "656"} | Thu Feb 26 00:00:00 1970 PST | {"c3": "00656"} | {"c2": "6", "c6": "6", "c7": "6 ", "c8": "foo", "C 1": "656"} + Sun Mar 08 00:00:00 1970 PST | {"c3": "00666"} | {"c2": "6", "c6": "6", "c7": "6 ", "c8": "foo", "C 1": "666"} | Sun Mar 08 00:00:00 1970 PST | {"c3": "00666"} | {"c2": "6", "c6": "6", "c7": "6 ", "c8": "foo", "C 1": "666"} + Wed Mar 18 00:00:00 1970 PST | {"c3": "00676"} | {"c2": "6", "c6": "6", "c7": "6 ", "c8": "foo", "C 1": "676"} | Wed Mar 18 00:00:00 1970 PST | {"c3": "00676"} | {"c2": "6", "c6": "6", "c7": "6 ", "c8": "foo", "C 1": "676"} + Sat Mar 28 00:00:00 1970 PST | {"c3": "00686"} | {"c2": "6", "c6": "6", "c7": "6 ", "c8": "foo", "C 1": "686"} | Sat Mar 28 00:00:00 1970 PST | {"c3": "00686"} | {"c2": "6", "c6": "6", "c7": "6 ", "c8": "foo", "C 1": "686"} + Tue Apr 07 00:00:00 1970 PST | {"c3": "00696"} | {"c2": "6", "c6": "6", "c7": "6 ", "c8": "foo", "C 1": "696"} | Tue Apr 07 00:00:00 1970 PST | {"c3": "00696"} | {"c2": "6", "c6": "6", "c7": "6 ", "c8": "foo", "C 1": "696"} + Wed Jan 07 00:00:00 1970 PST | {"c3": "00706"} | {"c2": "6", "c6": "6", "c7": "6 ", "c8": "foo", "C 1": "706"} | Wed Jan 07 00:00:00 1970 PST | {"c3": "00706"} | {"c2": "6", "c6": "6", "c7": "6 ", "c8": "foo", "C 1": "706"} + Sat Jan 17 00:00:00 1970 PST | {"c3": "00716"} | {"c2": "6", "c6": "6", "c7": "6 ", "c8": "foo", "C 1": "716"} | Sat Jan 17 00:00:00 1970 PST | {"c3": "00716"} | {"c2": "6", "c6": "6", "c7": "6 ", "c8": "foo", "C 1": "716"} + Tue Jan 27 00:00:00 1970 PST | {"c3": "00726"} | {"c2": "6", "c6": "6", "c7": "6 ", "c8": "foo", "C 1": "726"} | Tue Jan 27 00:00:00 1970 PST | {"c3": "00726"} | {"c2": "6", "c6": "6", "c7": "6 ", "c8": "foo", "C 1": "726"} + Fri Feb 06 00:00:00 1970 PST | {"c3": "00736"} | {"c2": "6", "c6": "6", "c7": "6 ", "c8": "foo", "C 1": "736"} | Fri Feb 06 00:00:00 1970 PST | {"c3": "00736"} | {"c2": "6", "c6": "6", "c7": "6 ", "c8": "foo", "C 1": "736"} + Mon Feb 16 00:00:00 1970 PST | {"c3": "00746"} | {"c2": "6", "c6": "6", "c7": "6 ", "c8": "foo", "C 1": "746"} | Mon Feb 16 00:00:00 1970 PST | {"c3": "00746"} | {"c2": "6", "c6": "6", "c7": "6 ", "c8": "foo", "C 1": "746"} + Thu Feb 26 00:00:00 1970 PST | {"c3": "00756"} | {"c2": "6", "c6": "6", "c7": "6 ", "c8": "foo", "C 1": "756"} | Thu Feb 26 00:00:00 1970 PST | {"c3": "00756"} | {"c2": "6", "c6": "6", "c7": "6 ", "c8": "foo", "C 1": "756"} + Sun Mar 08 00:00:00 1970 PST | {"c3": "00766"} | {"c2": "6", "c6": "6", "c7": "6 ", "c8": "foo", "C 1": "766"} | Sun Mar 08 00:00:00 1970 PST | {"c3": "00766"} | {"c2": "6", "c6": "6", "c7": "6 ", "c8": "foo", "C 1": "766"} + Wed Mar 18 00:00:00 1970 PST | {"c3": "00776"} | {"c2": "6", "c6": "6", "c7": "6 ", "c8": "foo", "C 1": "776"} | Wed Mar 18 00:00:00 1970 PST | {"c3": "00776"} | {"c2": "6", "c6": "6", "c7": "6 ", "c8": "foo", "C 1": "776"} + Sat Mar 28 00:00:00 1970 PST | {"c3": "00786"} | {"c2": "6", "c6": "6", "c7": "6 ", "c8": "foo", "C 1": "786"} | Sat Mar 28 00:00:00 1970 PST | {"c3": "00786"} | {"c2": "6", "c6": "6", "c7": "6 ", "c8": "foo", "C 1": "786"} + Tue Apr 07 00:00:00 1970 PST | {"c3": "00796"} | {"c2": "6", "c6": "6", "c7": "6 ", "c8": "foo", "C 1": "796"} | Tue Apr 07 00:00:00 1970 PST | {"c3": "00796"} | {"c2": "6", "c6": "6", "c7": "6 ", "c8": "foo", "C 1": "796"} + Wed Jan 07 00:00:00 1970 PST | {"c3": "00806"} | {"c2": "6", "c6": "6", "c7": "6 ", "c8": "foo", "C 1": "806"} | Wed Jan 07 00:00:00 1970 PST | {"c3": "00806"} | {"c2": "6", "c6": "6", "c7": "6 ", "c8": "foo", "C 1": "806"} + Sat Jan 17 00:00:00 1970 PST | {"c3": "00816"} | {"c2": "6", "c6": "6", "c7": "6 ", "c8": "foo", "C 1": "816"} | Sat Jan 17 00:00:00 1970 PST | {"c3": "00816"} | {"c2": "6", "c6": "6", "c7": "6 ", "c8": "foo", "C 1": "816"} + Tue Jan 27 00:00:00 1970 PST | {"c3": "00826"} | {"c2": "6", "c6": "6", "c7": "6 ", "c8": "foo", "C 1": "826"} | Tue Jan 27 00:00:00 1970 PST | {"c3": "00826"} | {"c2": "6", "c6": "6", "c7": "6 ", "c8": "foo", "C 1": "826"} + Fri Feb 06 00:00:00 1970 PST | {"c3": "00836"} | {"c2": "6", "c6": "6", "c7": "6 ", "c8": "foo", "C 1": "836"} | Fri Feb 06 00:00:00 1970 PST | {"c3": "00836"} | {"c2": "6", "c6": "6", "c7": "6 ", "c8": "foo", "C 1": "836"} + Mon Feb 16 00:00:00 1970 PST | {"c3": "00846"} | {"c2": "6", "c6": "6", "c7": "6 ", "c8": "foo", "C 1": "846"} | Mon Feb 16 00:00:00 1970 PST | {"c3": "00846"} | {"c2": "6", "c6": "6", "c7": "6 ", "c8": "foo", "C 1": "846"} + Thu Feb 26 00:00:00 1970 PST | {"c3": "00856"} | {"c2": "6", "c6": "6", "c7": "6 ", "c8": "foo", "C 1": "856"} | Thu Feb 26 00:00:00 1970 PST | {"c3": "00856"} | {"c2": "6", "c6": "6", "c7": "6 ", "c8": "foo", "C 1": "856"} + Sun Mar 08 00:00:00 1970 PST | {"c3": "00866"} | {"c2": "6", "c6": "6", "c7": "6 ", "c8": "foo", "C 1": "866"} | Sun Mar 08 00:00:00 1970 PST | {"c3": "00866"} | {"c2": "6", "c6": "6", "c7": "6 ", "c8": "foo", "C 1": "866"} + Wed Mar 18 00:00:00 1970 PST | {"c3": "00876"} | {"c2": "6", "c6": "6", "c7": "6 ", "c8": "foo", "C 1": "876"} | Wed Mar 18 00:00:00 1970 PST | {"c3": "00876"} | {"c2": "6", "c6": "6", "c7": "6 ", "c8": "foo", "C 1": "876"} + Sat Mar 28 00:00:00 1970 PST | {"c3": "00886"} | {"c2": "6", "c6": "6", "c7": "6 ", "c8": "foo", "C 1": "886"} | Sat Mar 28 00:00:00 1970 PST | {"c3": "00886"} | {"c2": "6", "c6": "6", "c7": "6 ", "c8": "foo", "C 1": "886"} + Tue Apr 07 00:00:00 1970 PST | {"c3": "00896"} | {"c2": "6", "c6": "6", "c7": "6 ", "c8": "foo", "C 1": "896"} | Tue Apr 07 00:00:00 1970 PST | {"c3": "00896"} | {"c2": "6", "c6": "6", "c7": "6 ", "c8": "foo", "C 1": "896"} + Wed Jan 07 00:00:00 1970 PST | {"c3": "00906"} | {"c2": "6", "c6": "6", "c7": "6 ", "c8": "foo", "C 1": "906"} | Wed Jan 07 00:00:00 1970 PST | {"c3": "00906"} | {"c2": "6", "c6": "6", "c7": "6 ", "c8": "foo", "C 1": "906"} + Sat Jan 17 00:00:00 1970 PST | {"c3": "00916"} | {"c2": "6", "c6": "6", "c7": "6 ", "c8": "foo", "C 1": "916"} | Sat Jan 17 00:00:00 1970 PST | {"c3": "00916"} | {"c2": "6", "c6": "6", "c7": "6 ", "c8": "foo", "C 1": "916"} + Tue Jan 27 00:00:00 1970 PST | {"c3": "00926"} | {"c2": "6", "c6": "6", "c7": "6 ", "c8": "foo", "C 1": "926"} | Tue Jan 27 00:00:00 1970 PST | {"c3": "00926"} | {"c2": "6", "c6": "6", "c7": "6 ", "c8": "foo", "C 1": "926"} + Fri Feb 06 00:00:00 1970 PST | {"c3": "00936"} | {"c2": "6", "c6": "6", "c7": "6 ", "c8": "foo", "C 1": "936"} | Fri Feb 06 00:00:00 1970 PST | {"c3": "00936"} | {"c2": "6", "c6": "6", "c7": "6 ", "c8": "foo", "C 1": "936"} + Mon Feb 16 00:00:00 1970 PST | {"c3": "00946"} | {"c2": "6", "c6": "6", "c7": "6 ", "c8": "foo", "C 1": "946"} | Mon Feb 16 00:00:00 1970 PST | {"c3": "00946"} | {"c2": "6", "c6": "6", "c7": "6 ", "c8": "foo", "C 1": "946"} + Thu Feb 26 00:00:00 1970 PST | {"c3": "00956"} | {"c2": "6", "c6": "6", "c7": "6 ", "c8": "foo", "C 1": "956"} | Thu Feb 26 00:00:00 1970 PST | {"c3": "00956"} | {"c2": "6", "c6": "6", "c7": "6 ", "c8": "foo", "C 1": "956"} + Sun Mar 08 00:00:00 1970 PST | {"c3": "00966"} | {"c2": "6", "c6": "6", "c7": "6 ", "c8": "foo", "C 1": "966"} | Sun Mar 08 00:00:00 1970 PST | {"c3": "00966"} | {"c2": "6", "c6": "6", "c7": "6 ", "c8": "foo", "C 1": "966"} + Wed Mar 18 00:00:00 1970 PST | {"c3": "00976"} | {"c2": "6", "c6": "6", "c7": "6 ", "c8": "foo", "C 1": "976"} | Wed Mar 18 00:00:00 1970 PST | {"c3": "00976"} | {"c2": "6", "c6": "6", "c7": "6 ", "c8": "foo", "C 1": "976"} + Sat Mar 28 00:00:00 1970 PST | {"c3": "00986"} | {"c2": "6", "c6": "6", "c7": "6 ", "c8": "foo", "C 1": "986"} | Sat Mar 28 00:00:00 1970 PST | {"c3": "00986"} | {"c2": "6", "c6": "6", "c7": "6 ", "c8": "foo", "C 1": "986"} + Tue Apr 07 00:00:00 1970 PST | {"c3": "00996"} | {"c2": "6", "c6": "6", "c7": "6 ", "c8": "foo", "C 1": "996"} | Tue Apr 07 00:00:00 1970 PST | {"c3": "00996"} | {"c2": "6", "c6": "6", "c7": "6 ", "c8": "foo", "C 1": "996"} (100 rows) -- bug before 9.3.5 due to sloppy handling of remote-estimate parameters --Testcase 74: SELECT * FROM ft1 WHERE (fields->>'C 1')::int = ANY (ARRAY(SELECT (fields->>'C 1')::int FROM ft2 WHERE (fields->>'C 1')::int < 5)); - time | tags | fields ---------------------------+-----------------+--------------------------------------------------------------------- - Fri Jan 02 00:00:00 1970 | {"c3": "00001"} | {"c2": "1", "c6": "1", "c7": "1 ", "c8": "foo", "C 1": "1"} - Sat Jan 03 00:00:00 1970 | {"c3": "00002"} | {"c2": "2", "c6": "2", "c7": "2 ", "c8": "foo", "C 1": "2"} - Sun Jan 04 00:00:00 1970 | {"c3": "00003"} | {"c2": "3", "c6": "3", "c7": "3 ", "c8": "foo", "C 1": "3"} - Mon Jan 05 00:00:00 1970 | {"c3": "00004"} | {"c2": "4", "c6": "4", "c7": "4 ", "c8": "foo", "C 1": "4"} + time | tags | fields +------------------------------+-----------------+--------------------------------------------------------------------- + Fri Jan 02 00:00:00 1970 PST | {"c3": "00001"} | {"c2": "1", "c6": "1", "c7": "1 ", "c8": "foo", "C 1": "1"} + Sat Jan 03 00:00:00 1970 PST | {"c3": "00002"} | {"c2": "2", "c6": "2", "c7": "2 ", "c8": "foo", "C 1": "2"} + Sun Jan 04 00:00:00 1970 PST | {"c3": "00003"} | {"c2": "3", "c6": "3", "c7": "3 ", "c8": "foo", "C 1": "3"} + Mon Jan 05 00:00:00 1970 PST | {"c3": "00004"} | {"c2": "4", "c6": "4", "c7": "4 ", "c8": "foo", "C 1": "4"} (4 rows) --Testcase 75: SELECT * FROM ft2 WHERE (fields->>'C 1')::int = ANY (ARRAY(SELECT (fields->>'C 1')::int FROM ft1 WHERE (fields->>'C 1')::int < 5)); - time | tags | fields ---------------------------+-----------------+--------------------------------------------------------------------- - Fri Jan 02 00:00:00 1970 | {"c3": "00001"} | {"c2": "1", "c6": "1", "c7": "1 ", "c8": "foo", "C 1": "1"} - Sat Jan 03 00:00:00 1970 | {"c3": "00002"} | {"c2": "2", "c6": "2", "c7": "2 ", "c8": "foo", "C 1": "2"} - Sun Jan 04 00:00:00 1970 | {"c3": "00003"} | {"c2": "3", "c6": "3", "c7": "3 ", "c8": "foo", "C 1": "3"} - Mon Jan 05 00:00:00 1970 | {"c3": "00004"} | {"c2": "4", "c6": "4", "c7": "4 ", "c8": "foo", "C 1": "4"} + time | tags | fields +------------------------------+-----------------+--------------------------------------------------------------------- + Fri Jan 02 00:00:00 1970 PST | {"c3": "00001"} | {"c2": "1", "c6": "1", "c7": "1 ", "c8": "foo", "C 1": "1"} + Sat Jan 03 00:00:00 1970 PST | {"c3": "00002"} | {"c2": "2", "c6": "2", "c7": "2 ", "c8": "foo", "C 1": "2"} + Sun Jan 04 00:00:00 1970 PST | {"c3": "00003"} | {"c2": "3", "c6": "3", "c7": "3 ", "c8": "foo", "C 1": "3"} + Mon Jan 05 00:00:00 1970 PST | {"c3": "00004"} | {"c2": "4", "c6": "4", "c7": "4 ", "c8": "foo", "C 1": "4"} (4 rows) -- we should not push order by clause with volatile expressions or unsafe @@ -1147,9 +1147,9 @@ EXPLAIN (VERBOSE, COSTS OFF) --Testcase 89: SELECT * FROM ft1 t1 WHERE (t1.fields->>'C 1')::int === (t1.fields->>'c2')::int order by (t1.fields->>'c2')::int limit 1; - time | tags | fields ---------------------------+-----------------+--------------------------------------------------------------------- - Fri Jan 02 00:00:00 1970 | {"c3": "00001"} | {"c2": "1", "c6": "1", "c7": "1 ", "c8": "foo", "C 1": "1"} + time | tags | fields +------------------------------+-----------------+--------------------------------------------------------------------- + Fri Jan 02 00:00:00 1970 PST | {"c3": "00001"} | {"c2": "1", "c6": "1", "c7": "1 ", "c8": "foo", "C 1": "1"} (1 row) -- but let's put them in an extension ... @@ -1216,9 +1216,9 @@ EXPLAIN (VERBOSE, COSTS OFF) --Testcase 95: SELECT * FROM ft1 t1 WHERE (t1.fields->>'C 1')::int === (t1.fields->>'c2')::int order by (t1.fields->>'c2')::int limit 1; - time | tags | fields ---------------------------+-----------------+--------------------------------------------------------------------- - Fri Jan 02 00:00:00 1970 | {"c3": "00001"} | {"c2": "1", "c6": "1", "c7": "1 ", "c8": "foo", "C 1": "1"} + time | tags | fields +------------------------------+-----------------+--------------------------------------------------------------------- + Fri Jan 02 00:00:00 1970 PST | {"c3": "00001"} | {"c2": "1", "c6": "1", "c7": "1 ", "c8": "foo", "C 1": "1"} (1 row) -- This test case drop configuration when execute non-schemaless before @@ -3117,18 +3117,18 @@ SELECT * FROM ft1, ft2, ft4, ft5, local_tbl WHERE (ft1.fields->>'C 1')::int = (f --Testcase 181: SELECT * FROM ft1, ft2, ft4, ft5, local_tbl WHERE (ft1.fields->>'C 1')::int = (ft2.fields->>'C 1')::int AND (ft1.fields->>'c2')::int = (ft4.fields->>'c1')::int AND (ft1.fields->>'c2')::int = (ft5.fields->>'c1')::int AND (ft1.fields->>'c2')::int = (local_tbl.fields->>'c1')::int AND (ft1.fields->>'C 1')::int < 100 AND (ft2.fields->>'C 1')::int < 100 ORDER BY (ft1.fields->>'C 1')::int FOR UPDATE; - time | tags | fields | time | tags | fields | tags | fields | tags | fields | fields ---------------------------+-----------------+----------------------------------------------------------------------+--------------------------+-----------------+----------------------------------------------------------------------+------------------+------------------------+------------------+------------------------+-------------------------------------- - Wed Jan 07 00:00:00 1970 | {"c3": "00006"} | {"c2": "6", "c6": "6", "c7": "6 ", "c8": "foo", "C 1": "6"} | Wed Jan 07 00:00:00 1970 | {"c3": "00006"} | {"c2": "6", "c6": "6", "c7": "6 ", "c8": "foo", "C 1": "6"} | {"c3": "AAA006"} | {"c1": "6", "c2": "7"} | {"c3": "AAA006"} | {"c1": "6", "c2": "7"} | {"c1": "6", "c2": "6", "c3": "0006"} - Sat Jan 17 00:00:00 1970 | {"c3": "00016"} | {"c2": "6", "c6": "6", "c7": "6 ", "c8": "foo", "C 1": "16"} | Sat Jan 17 00:00:00 1970 | {"c3": "00016"} | {"c2": "6", "c6": "6", "c7": "6 ", "c8": "foo", "C 1": "16"} | {"c3": "AAA006"} | {"c1": "6", "c2": "7"} | {"c3": "AAA006"} | {"c1": "6", "c2": "7"} | {"c1": "6", "c2": "6", "c3": "0006"} - Tue Jan 27 00:00:00 1970 | {"c3": "00026"} | {"c2": "6", "c6": "6", "c7": "6 ", "c8": "foo", "C 1": "26"} | Tue Jan 27 00:00:00 1970 | {"c3": "00026"} | {"c2": "6", "c6": "6", "c7": "6 ", "c8": "foo", "C 1": "26"} | {"c3": "AAA006"} | {"c1": "6", "c2": "7"} | {"c3": "AAA006"} | {"c1": "6", "c2": "7"} | {"c1": "6", "c2": "6", "c3": "0006"} - Fri Feb 06 00:00:00 1970 | {"c3": "00036"} | {"c2": "6", "c6": "6", "c7": "6 ", "c8": "foo", "C 1": "36"} | Fri Feb 06 00:00:00 1970 | {"c3": "00036"} | {"c2": "6", "c6": "6", "c7": "6 ", "c8": "foo", "C 1": "36"} | {"c3": "AAA006"} | {"c1": "6", "c2": "7"} | {"c3": "AAA006"} | {"c1": "6", "c2": "7"} | {"c1": "6", "c2": "6", "c3": "0006"} - Mon Feb 16 00:00:00 1970 | {"c3": "00046"} | {"c2": "6", "c6": "6", "c7": "6 ", "c8": "foo", "C 1": "46"} | Mon Feb 16 00:00:00 1970 | {"c3": "00046"} | {"c2": "6", "c6": "6", "c7": "6 ", "c8": "foo", "C 1": "46"} | {"c3": "AAA006"} | {"c1": "6", "c2": "7"} | {"c3": "AAA006"} | {"c1": "6", "c2": "7"} | {"c1": "6", "c2": "6", "c3": "0006"} - Thu Feb 26 00:00:00 1970 | {"c3": "00056"} | {"c2": "6", "c6": "6", "c7": "6 ", "c8": "foo", "C 1": "56"} | Thu Feb 26 00:00:00 1970 | {"c3": "00056"} | {"c2": "6", "c6": "6", "c7": "6 ", "c8": "foo", "C 1": "56"} | {"c3": "AAA006"} | {"c1": "6", "c2": "7"} | {"c3": "AAA006"} | {"c1": "6", "c2": "7"} | {"c1": "6", "c2": "6", "c3": "0006"} - Sun Mar 08 00:00:00 1970 | {"c3": "00066"} | {"c2": "6", "c6": "6", "c7": "6 ", "c8": "foo", "C 1": "66"} | Sun Mar 08 00:00:00 1970 | {"c3": "00066"} | {"c2": "6", "c6": "6", "c7": "6 ", "c8": "foo", "C 1": "66"} | {"c3": "AAA006"} | {"c1": "6", "c2": "7"} | {"c3": "AAA006"} | {"c1": "6", "c2": "7"} | {"c1": "6", "c2": "6", "c3": "0006"} - Wed Mar 18 00:00:00 1970 | {"c3": "00076"} | {"c2": "6", "c6": "6", "c7": "6 ", "c8": "foo", "C 1": "76"} | Wed Mar 18 00:00:00 1970 | {"c3": "00076"} | {"c2": "6", "c6": "6", "c7": "6 ", "c8": "foo", "C 1": "76"} | {"c3": "AAA006"} | {"c1": "6", "c2": "7"} | {"c3": "AAA006"} | {"c1": "6", "c2": "7"} | {"c1": "6", "c2": "6", "c3": "0006"} - Sat Mar 28 00:00:00 1970 | {"c3": "00086"} | {"c2": "6", "c6": "6", "c7": "6 ", "c8": "foo", "C 1": "86"} | Sat Mar 28 00:00:00 1970 | {"c3": "00086"} | {"c2": "6", "c6": "6", "c7": "6 ", "c8": "foo", "C 1": "86"} | {"c3": "AAA006"} | {"c1": "6", "c2": "7"} | {"c3": "AAA006"} | {"c1": "6", "c2": "7"} | {"c1": "6", "c2": "6", "c3": "0006"} - Tue Apr 07 00:00:00 1970 | {"c3": "00096"} | {"c2": "6", "c6": "6", "c7": "6 ", "c8": "foo", "C 1": "96"} | Tue Apr 07 00:00:00 1970 | {"c3": "00096"} | {"c2": "6", "c6": "6", "c7": "6 ", "c8": "foo", "C 1": "96"} | {"c3": "AAA006"} | {"c1": "6", "c2": "7"} | {"c3": "AAA006"} | {"c1": "6", "c2": "7"} | {"c1": "6", "c2": "6", "c3": "0006"} + time | tags | fields | time | tags | fields | tags | fields | tags | fields | fields +------------------------------+-----------------+----------------------------------------------------------------------+------------------------------+-----------------+----------------------------------------------------------------------+------------------+------------------------+------------------+------------------------+-------------------------------------- + Wed Jan 07 00:00:00 1970 PST | {"c3": "00006"} | {"c2": "6", "c6": "6", "c7": "6 ", "c8": "foo", "C 1": "6"} | Wed Jan 07 00:00:00 1970 PST | {"c3": "00006"} | {"c2": "6", "c6": "6", "c7": "6 ", "c8": "foo", "C 1": "6"} | {"c3": "AAA006"} | {"c1": "6", "c2": "7"} | {"c3": "AAA006"} | {"c1": "6", "c2": "7"} | {"c1": "6", "c2": "6", "c3": "0006"} + Sat Jan 17 00:00:00 1970 PST | {"c3": "00016"} | {"c2": "6", "c6": "6", "c7": "6 ", "c8": "foo", "C 1": "16"} | Sat Jan 17 00:00:00 1970 PST | {"c3": "00016"} | {"c2": "6", "c6": "6", "c7": "6 ", "c8": "foo", "C 1": "16"} | {"c3": "AAA006"} | {"c1": "6", "c2": "7"} | {"c3": "AAA006"} | {"c1": "6", "c2": "7"} | {"c1": "6", "c2": "6", "c3": "0006"} + Tue Jan 27 00:00:00 1970 PST | {"c3": "00026"} | {"c2": "6", "c6": "6", "c7": "6 ", "c8": "foo", "C 1": "26"} | Tue Jan 27 00:00:00 1970 PST | {"c3": "00026"} | {"c2": "6", "c6": "6", "c7": "6 ", "c8": "foo", "C 1": "26"} | {"c3": "AAA006"} | {"c1": "6", "c2": "7"} | {"c3": "AAA006"} | {"c1": "6", "c2": "7"} | {"c1": "6", "c2": "6", "c3": "0006"} + Fri Feb 06 00:00:00 1970 PST | {"c3": "00036"} | {"c2": "6", "c6": "6", "c7": "6 ", "c8": "foo", "C 1": "36"} | Fri Feb 06 00:00:00 1970 PST | {"c3": "00036"} | {"c2": "6", "c6": "6", "c7": "6 ", "c8": "foo", "C 1": "36"} | {"c3": "AAA006"} | {"c1": "6", "c2": "7"} | {"c3": "AAA006"} | {"c1": "6", "c2": "7"} | {"c1": "6", "c2": "6", "c3": "0006"} + Mon Feb 16 00:00:00 1970 PST | {"c3": "00046"} | {"c2": "6", "c6": "6", "c7": "6 ", "c8": "foo", "C 1": "46"} | Mon Feb 16 00:00:00 1970 PST | {"c3": "00046"} | {"c2": "6", "c6": "6", "c7": "6 ", "c8": "foo", "C 1": "46"} | {"c3": "AAA006"} | {"c1": "6", "c2": "7"} | {"c3": "AAA006"} | {"c1": "6", "c2": "7"} | {"c1": "6", "c2": "6", "c3": "0006"} + Thu Feb 26 00:00:00 1970 PST | {"c3": "00056"} | {"c2": "6", "c6": "6", "c7": "6 ", "c8": "foo", "C 1": "56"} | Thu Feb 26 00:00:00 1970 PST | {"c3": "00056"} | {"c2": "6", "c6": "6", "c7": "6 ", "c8": "foo", "C 1": "56"} | {"c3": "AAA006"} | {"c1": "6", "c2": "7"} | {"c3": "AAA006"} | {"c1": "6", "c2": "7"} | {"c1": "6", "c2": "6", "c3": "0006"} + Sun Mar 08 00:00:00 1970 PST | {"c3": "00066"} | {"c2": "6", "c6": "6", "c7": "6 ", "c8": "foo", "C 1": "66"} | Sun Mar 08 00:00:00 1970 PST | {"c3": "00066"} | {"c2": "6", "c6": "6", "c7": "6 ", "c8": "foo", "C 1": "66"} | {"c3": "AAA006"} | {"c1": "6", "c2": "7"} | {"c3": "AAA006"} | {"c1": "6", "c2": "7"} | {"c1": "6", "c2": "6", "c3": "0006"} + Wed Mar 18 00:00:00 1970 PST | {"c3": "00076"} | {"c2": "6", "c6": "6", "c7": "6 ", "c8": "foo", "C 1": "76"} | Wed Mar 18 00:00:00 1970 PST | {"c3": "00076"} | {"c2": "6", "c6": "6", "c7": "6 ", "c8": "foo", "C 1": "76"} | {"c3": "AAA006"} | {"c1": "6", "c2": "7"} | {"c3": "AAA006"} | {"c1": "6", "c2": "7"} | {"c1": "6", "c2": "6", "c3": "0006"} + Sat Mar 28 00:00:00 1970 PST | {"c3": "00086"} | {"c2": "6", "c6": "6", "c7": "6 ", "c8": "foo", "C 1": "86"} | Sat Mar 28 00:00:00 1970 PST | {"c3": "00086"} | {"c2": "6", "c6": "6", "c7": "6 ", "c8": "foo", "C 1": "86"} | {"c3": "AAA006"} | {"c1": "6", "c2": "7"} | {"c3": "AAA006"} | {"c1": "6", "c2": "7"} | {"c1": "6", "c2": "6", "c3": "0006"} + Tue Apr 07 00:00:00 1970 PST | {"c3": "00096"} | {"c2": "6", "c6": "6", "c7": "6 ", "c8": "foo", "C 1": "96"} | Tue Apr 07 00:00:00 1970 PST | {"c3": "00096"} | {"c2": "6", "c6": "6", "c7": "6 ", "c8": "foo", "C 1": "96"} | {"c3": "AAA006"} | {"c1": "6", "c2": "7"} | {"c3": "AAA006"} | {"c1": "6", "c2": "7"} | {"c1": "6", "c2": "6", "c3": "0006"} (10 rows) RESET enable_nestloop; @@ -3782,9 +3782,9 @@ select array_agg(time order by (fields->>'C 1')::int desc) from ft2 where (field --Testcase 228: select array_agg(time order by (fields->>'C 1')::int desc) from ft2 where (fields->>'c2')::int = 6 and (fields->>'C 1')::int < 50; - array_agg ------------------------------------------------------------------------------------------------------------------------------------------- - {"Mon Feb 16 00:00:00 1970","Fri Feb 06 00:00:00 1970","Tue Jan 27 00:00:00 1970","Sat Jan 17 00:00:00 1970","Wed Jan 07 00:00:00 1970"} + array_agg +-------------------------------------------------------------------------------------------------------------------------------------------------------------- + {"Mon Feb 16 00:00:00 1970 PST","Fri Feb 06 00:00:00 1970 PST","Tue Jan 27 00:00:00 1970 PST","Sat Jan 17 00:00:00 1970 PST","Wed Jan 07 00:00:00 1970 PST"} (1 row) -- DISTINCT within aggregate @@ -4952,16 +4952,16 @@ EXPLAIN (VERBOSE, COSTS OFF) EXECUTE st2(10, 20); --Testcase 310: EXECUTE st2(10, 20); - time | tags | fields ---------------------------+-----------------+---------------------------------------------------------------------- - Sat Jan 17 00:00:00 1970 | {"c3": "00016"} | {"c2": "6", "c6": "6", "c7": "6 ", "c8": "foo", "C 1": "16"} + time | tags | fields +------------------------------+-----------------+---------------------------------------------------------------------- + Sat Jan 17 00:00:00 1970 PST | {"c3": "00016"} | {"c2": "6", "c6": "6", "c7": "6 ", "c8": "foo", "C 1": "16"} (1 row) --Testcase 311: EXECUTE st2(101, 121); - time | tags | fields ---------------------------+-----------------+----------------------------------------------------------------------- - Sat Jan 17 00:00:00 1970 | {"c3": "00116"} | {"c2": "6", "c6": "6", "c7": "6 ", "c8": "foo", "C 1": "116"} + time | tags | fields +------------------------------+-----------------+----------------------------------------------------------------------- + Sat Jan 17 00:00:00 1970 PST | {"c3": "00116"} | {"c2": "6", "c6": "6", "c7": "6 ", "c8": "foo", "C 1": "116"} (1 row) -- subquery using immutable function (can be sent to remote) @@ -4990,9 +4990,9 @@ EXPLAIN (VERBOSE, COSTS OFF) EXECUTE st3(10, 20); --Testcase 314: EXECUTE st3(10, 20); - time | tags | fields ---------------------------+-----------------+---------------------------------------------------------------------- - Sat Jan 17 00:00:00 1970 | {"c3": "00016"} | {"c2": "6", "c6": "6", "c7": "6 ", "c8": "foo", "C 1": "16"} + time | tags | fields +------------------------------+-----------------+---------------------------------------------------------------------- + Sat Jan 17 00:00:00 1970 PST | {"c3": "00016"} | {"c2": "6", "c6": "6", "c7": "6 ", "c8": "foo", "C 1": "16"} (1 row) --Testcase 315: @@ -5118,9 +5118,9 @@ EXPLAIN (VERBOSE, COSTS OFF) EXECUTE st5('foo', 1); --Testcase 330: EXECUTE st5('foo', 1); - time | tags | fields ---------------------------+-----------------+--------------------------------------------------------------------- - Fri Jan 02 00:00:00 1970 | {"c3": "00001"} | {"c2": "1", "c6": "1", "c7": "1 ", "c8": "foo", "C 1": "1"} + time | tags | fields +------------------------------+-----------------+--------------------------------------------------------------------- + Fri Jan 02 00:00:00 1970 PST | {"c3": "00001"} | {"c2": "1", "c6": "1", "c7": "1 ", "c8": "foo", "C 1": "1"} (1 row) -- altering FDW options requires replanning @@ -5139,11 +5139,11 @@ EXPLAIN (VERBOSE, COSTS OFF) EXECUTE st6; PREPARE st7 AS INSERT INTO ft1_nsc (c1,c2,c3) VALUES (1001,101,'foo'); --Testcase 334: EXPLAIN (VERBOSE, COSTS OFF) EXECUTE st7; - QUERY PLAN ------------------------------------------------------------------------------------------------------------------------------------------------------------- + QUERY PLAN +--------------------------------------------------------------------------------------------------------------------------------------------------------- Insert on public.ft1_nsc -> Result - Output: NULL::integer, 1001, 101, 'foo'::text, NULL::timestamp without time zone, NULL::character varying, 'ft1 '::character(10), NULL::text + Output: NULL::integer, 1001, 101, 'foo'::text, NULL::timestamp with time zone, NULL::character varying, 'ft1 '::character(10), NULL::text (3 rows) --Testcase 335: @@ -5160,26 +5160,26 @@ EXPLAIN (VERBOSE, COSTS OFF) EXECUTE st6; --Testcase 337: EXECUTE st6; - time | tags | fields ---------------------------+-----------------+--------------------------------------------------------------------- - Fri Jan 02 00:00:00 1970 | {"c3": "00001"} | {"c2": "1", "c6": "1", "c7": "1 ", "c8": "foo", "C 1": "1"} - Sat Jan 03 00:00:00 1970 | {"c3": "00002"} | {"c2": "2", "c6": "2", "c7": "2 ", "c8": "foo", "C 1": "2"} - Sun Jan 04 00:00:00 1970 | {"c3": "00003"} | {"c2": "3", "c6": "3", "c7": "3 ", "c8": "foo", "C 1": "3"} - Mon Jan 05 00:00:00 1970 | {"c3": "00004"} | {"c2": "4", "c6": "4", "c7": "4 ", "c8": "foo", "C 1": "4"} - Tue Jan 06 00:00:00 1970 | {"c3": "00005"} | {"c2": "5", "c6": "5", "c7": "5 ", "c8": "foo", "C 1": "5"} - Wed Jan 07 00:00:00 1970 | {"c3": "00006"} | {"c2": "6", "c6": "6", "c7": "6 ", "c8": "foo", "C 1": "6"} - Thu Jan 08 00:00:00 1970 | {"c3": "00007"} | {"c2": "7", "c6": "7", "c7": "7 ", "c8": "foo", "C 1": "7"} - Fri Jan 09 00:00:00 1970 | {"c3": "00008"} | {"c2": "8", "c6": "8", "c7": "8 ", "c8": "foo", "C 1": "8"} - Sat Jan 10 00:00:00 1970 | {"c3": "00009"} | {"c2": "9", "c6": "9", "c7": "9 ", "c8": "foo", "C 1": "9"} + time | tags | fields +------------------------------+-----------------+--------------------------------------------------------------------- + Fri Jan 02 00:00:00 1970 PST | {"c3": "00001"} | {"c2": "1", "c6": "1", "c7": "1 ", "c8": "foo", "C 1": "1"} + Sat Jan 03 00:00:00 1970 PST | {"c3": "00002"} | {"c2": "2", "c6": "2", "c7": "2 ", "c8": "foo", "C 1": "2"} + Sun Jan 04 00:00:00 1970 PST | {"c3": "00003"} | {"c2": "3", "c6": "3", "c7": "3 ", "c8": "foo", "C 1": "3"} + Mon Jan 05 00:00:00 1970 PST | {"c3": "00004"} | {"c2": "4", "c6": "4", "c7": "4 ", "c8": "foo", "C 1": "4"} + Tue Jan 06 00:00:00 1970 PST | {"c3": "00005"} | {"c2": "5", "c6": "5", "c7": "5 ", "c8": "foo", "C 1": "5"} + Wed Jan 07 00:00:00 1970 PST | {"c3": "00006"} | {"c2": "6", "c6": "6", "c7": "6 ", "c8": "foo", "C 1": "6"} + Thu Jan 08 00:00:00 1970 PST | {"c3": "00007"} | {"c2": "7", "c6": "7", "c7": "7 ", "c8": "foo", "C 1": "7"} + Fri Jan 09 00:00:00 1970 PST | {"c3": "00008"} | {"c2": "8", "c6": "8", "c7": "8 ", "c8": "foo", "C 1": "8"} + Sat Jan 10 00:00:00 1970 PST | {"c3": "00009"} | {"c2": "9", "c6": "9", "c7": "9 ", "c8": "foo", "C 1": "9"} (9 rows) --Testcase 338: EXPLAIN (VERBOSE, COSTS OFF) EXECUTE st7; - QUERY PLAN ------------------------------------------------------------------------------------------------------------------------------------------------------------- + QUERY PLAN +--------------------------------------------------------------------------------------------------------------------------------------------------------- Insert on public.ft1_nsc -> Result - Output: NULL::integer, 1001, 101, 'foo'::text, NULL::timestamp without time zone, NULL::character varying, 'ft1 '::character(10), NULL::text + Output: NULL::integer, 1001, 101, 'foo'::text, NULL::timestamp with time zone, NULL::character varying, 'ft1 '::character(10), NULL::text (3 rows) --Testcase 339: @@ -5246,9 +5246,9 @@ SELECT * FROM ft1 t1 WHERE t1.tableoid = 'pg_class'::regclass LIMIT 1; --Testcase 345: SELECT * FROM ft1 t1 WHERE t1.tableoid = 'ft1'::regclass ORDER BY (fields->>'C 1')::int LIMIT 1; - time | tags | fields ---------------------------+-----------------+--------------------------------------------------------------------- - Fri Jan 02 00:00:00 1970 | {"c3": "00001"} | {"c2": "1", "c6": "1", "c7": "1 ", "c8": "foo", "C 1": "1"} + time | tags | fields +------------------------------+-----------------+--------------------------------------------------------------------- + Fri Jan 02 00:00:00 1970 PST | {"c3": "00001"} | {"c2": "1", "c6": "1", "c7": "1 ", "c8": "foo", "C 1": "1"} (1 row) --Testcase 346: @@ -5263,9 +5263,9 @@ SELECT tableoid::regclass, * FROM ft1 t1 LIMIT 1; --Testcase 347: SELECT tableoid::regclass, * FROM ft1 t1 ORDER BY (fields->>'C 1')::int LIMIT 1; - tableoid | time | tags | fields -----------+--------------------------+-----------------+--------------------------------------------------------------------- - ft1 | Fri Jan 02 00:00:00 1970 | {"c3": "00001"} | {"c2": "1", "c6": "1", "c7": "1 ", "c8": "foo", "C 1": "1"} + tableoid | time | tags | fields +----------+------------------------------+-----------------+--------------------------------------------------------------------- + ft1 | Fri Jan 02 00:00:00 1970 PST | {"c3": "00001"} | {"c2": "1", "c6": "1", "c7": "1 ", "c8": "foo", "C 1": "1"} (1 row) --Testcase 348: @@ -5297,9 +5297,9 @@ SELECT ctid, * FROM ft1 t1 LIMIT 1; --Testcase 351: SELECT ctid, * FROM ft1 t1 ORDER BY (fields->>'C 1')::int LIMIT 1; - ctid | time | tags | fields -----------------+--------------------------+-----------------+--------------------------------------------------------------------- - (4294967295,0) | Fri Jan 02 00:00:00 1970 | {"c3": "00001"} | {"c2": "1", "c6": "1", "c7": "1 ", "c8": "foo", "C 1": "1"} + ctid | time | tags | fields +----------------+------------------------------+-----------------+--------------------------------------------------------------------- + (4294967295,0) | Fri Jan 02 00:00:00 1970 PST | {"c3": "00001"} | {"c2": "1", "c6": "1", "c7": "1 ", "c8": "foo", "C 1": "1"} (1 row) -- =================================================================== @@ -5484,11 +5484,11 @@ explain (verbose, costs off) select * from ft3 f, loct3 l --Testcase 372: EXPLAIN (verbose, costs off) INSERT INTO ft2_nsc (c1,c2,c3) SELECT c1+1000,c2+100, c3 || c3 FROM ft2_nsc ORDER BY c1 LIMIT 20; - QUERY PLAN -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- + QUERY PLAN +---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- Insert on public.ft2_nsc -> Subquery Scan on "*SELECT*" - Output: "*SELECT*"."?column?", "*SELECT*"."?column?_1", NULL::integer, "*SELECT*"."?column?_2", NULL::timestamp without time zone, NULL::character varying, 'ft2 '::character(10), NULL::text + Output: "*SELECT*"."?column?", "*SELECT*"."?column?_1", NULL::integer, "*SELECT*"."?column?_2", NULL::timestamp with time zone, NULL::character varying, 'ft2 '::character(10), NULL::text -> Limit Output: ((ft2_nsc_1.c1 + 1000)), ((ft2_nsc_1.c2 + 100)), ((ft2_nsc_1.c3 || ft2_nsc_1.c3)), ft2_nsc_1.c1 -> Sort @@ -6502,11 +6502,11 @@ SELECT (fields->>'C 1')::int c1, (fields->>'c2')::int c2, tags->>'c3' c3 FROM ft --Testcase 384: EXPLAIN (verbose, costs off) INSERT INTO ft2_nsc (c1,c2,c3) VALUES (1200,999,'foo'); - QUERY PLAN ------------------------------------------------------------------------------------------------------------------------------------------------------------- + QUERY PLAN +--------------------------------------------------------------------------------------------------------------------------------------------------------- Insert on public.ft2_nsc -> Result - Output: 1200, 999, NULL::integer, 'foo'::text, NULL::timestamp without time zone, NULL::character varying, 'ft2 '::character(10), NULL::text + Output: 1200, 999, NULL::integer, 'foo'::text, NULL::timestamp with time zone, NULL::character varying, 'ft2 '::character(10), NULL::text (3 rows) --Testcase 385: @@ -8876,7 +8876,7 @@ CREATE FOREIGN TABLE ft1_nopw ( c2 int NOT NULL, c3 text, c4 timestamptz, - c5 timestamp, + c5 timestamptz, c6 varchar(10), c7 char(10) default 'ft1', c8 user_enum diff --git a/expected/11.17/schemaless/extra/insert.out b/expected/12.16/schemaless/extra/insert.out similarity index 100% rename from expected/11.17/schemaless/extra/insert.out rename to expected/12.16/schemaless/extra/insert.out diff --git a/expected/12.12/schemaless/extra/join.out b/expected/12.16/schemaless/extra/join.out similarity index 100% rename from expected/12.12/schemaless/extra/join.out rename to expected/12.16/schemaless/extra/join.out diff --git a/expected/11.17/schemaless/extra/limit.out b/expected/12.16/schemaless/extra/limit.out similarity index 100% rename from expected/11.17/schemaless/extra/limit.out rename to expected/12.16/schemaless/extra/limit.out diff --git a/expected/11.17/schemaless/extra/prepare.out b/expected/12.16/schemaless/extra/prepare.out similarity index 100% rename from expected/11.17/schemaless/extra/prepare.out rename to expected/12.16/schemaless/extra/prepare.out diff --git a/expected/11.17/schemaless/extra/select.out b/expected/12.16/schemaless/extra/select.out similarity index 100% rename from expected/11.17/schemaless/extra/select.out rename to expected/12.16/schemaless/extra/select.out diff --git a/expected/11.17/schemaless/extra/select_having.out b/expected/12.16/schemaless/extra/select_having.out similarity index 100% rename from expected/11.17/schemaless/extra/select_having.out rename to expected/12.16/schemaless/extra/select_having.out diff --git a/expected/13.8/schemaless/influxdb_fdw.out b/expected/12.16/schemaless/influxdb_fdw.out similarity index 99% rename from expected/13.8/schemaless/influxdb_fdw.out rename to expected/12.16/schemaless/influxdb_fdw.out index 9776ad4..cb9325d 100644 --- a/expected/13.8/schemaless/influxdb_fdw.out +++ b/expected/12.16/schemaless/influxdb_fdw.out @@ -1130,14 +1130,14 @@ SELECT * FROM t5; SELECT * FROM public.influxdb_fdw_version(); influxdb_fdw_version ---------------------- - 20000 + 20100 (1 row) --Testcase 146: SELECT influxdb_fdw_version(); influxdb_fdw_version ---------------------- - 20000 + 20100 (1 row) --Test pushdown LIMIT...OFFSET diff --git a/expected/12.12/schemaless/schemaless.out b/expected/12.16/schemaless/schemaless.out similarity index 100% rename from expected/12.12/schemaless/schemaless.out rename to expected/12.16/schemaless/schemaless.out diff --git a/expected/12.12/schemaless/selectfunc.out b/expected/12.16/schemaless/selectfunc.out similarity index 100% rename from expected/12.12/schemaless/selectfunc.out rename to expected/12.16/schemaless/selectfunc.out diff --git a/expected/12.12/selectfunc.out b/expected/12.16/selectfunc.out similarity index 100% rename from expected/12.12/selectfunc.out rename to expected/12.16/selectfunc.out diff --git a/expected/12.12/aggregate.out b/expected/13.12/aggregate.out similarity index 100% rename from expected/12.12/aggregate.out rename to expected/13.12/aggregate.out diff --git a/expected/13.8/extra/aggregates.out b/expected/13.12/extra/aggregates.out similarity index 100% rename from expected/13.8/extra/aggregates.out rename to expected/13.12/extra/aggregates.out diff --git a/expected/13.8/extra/influxdb_fdw_post.out b/expected/13.12/extra/influxdb_fdw_post.out similarity index 91% rename from expected/13.8/extra/influxdb_fdw_post.out rename to expected/13.12/extra/influxdb_fdw_post.out index 885769b..c668266 100644 --- a/expected/13.8/extra/influxdb_fdw_post.out +++ b/expected/13.12/extra/influxdb_fdw_post.out @@ -30,7 +30,7 @@ CREATE FOREIGN TABLE "S 1"."T 0" ( "C 1" int NOT NULL, c2 int NOT NULL, c3 text, - time timestamp, + time timestamptz, c6 varchar(10), c7 char(10), c8 text @@ -40,7 +40,7 @@ CREATE FOREIGN TABLE "S 1"."T 1" ( "C 1" int NOT NULL, c2 int NOT NULL, c3 text, - time timestamp, + time timestamptz, c6 varchar(10), c7 char(10), c8 text @@ -72,7 +72,7 @@ INSERT INTO "S 1"."T 1" SELECT id, id % 10, to_char(id, 'FM00000'), - '1970-01-01'::timestamp + ((id % 100) || ' days')::interval, + '1970-01-01'::timestamptz + ((id % 100) || ' days')::interval, id % 10, id % 10, 'foo'::text @@ -111,7 +111,7 @@ CREATE FOREIGN TABLE ft1 ( c1 int NOT NULL, c2 int NOT NULL, c3 text, - time timestamp, + time timestamptz, c6 varchar(10), c7 char(10) default 'ft1', c8 text @@ -123,7 +123,7 @@ CREATE FOREIGN TABLE ft2 ( c2 int NOT NULL, cx int, c3 text, - time timestamp, + time timestamptz, c6 varchar(10), c7 char(10) default 'ft2', c8 text @@ -221,9 +221,9 @@ ALTER FOREIGN TABLE ft2 ALTER COLUMN c1 OPTIONS (column_name 'C 1'); \set VERBOSITY terse --Testcase 27: SELECT c3, time FROM ft1 ORDER BY c3, c1 LIMIT 1; -- should work - c3 | time --------+-------------------------- - 00001 | Fri Jan 02 00:00:00 1970 + c3 | time +-------+------------------------------ + 00001 | Fri Jan 02 00:00:00 1970 PST (1 row) ALTER SERVER influxdb_svr OPTIONS (SET dbname 'no such database'); @@ -238,9 +238,9 @@ DO $d$ $d$; --Testcase 29: SELECT c3, time FROM ft1 ORDER BY c3, c1 LIMIT 1; -- should work again - c3 | time --------+-------------------------- - 00001 | Fri Jan 02 00:00:00 1970 + c3 | time +-------+------------------------------ + 00001 | Fri Jan 02 00:00:00 1970 PST (1 row) \set VERBOSITY default @@ -260,18 +260,18 @@ EXPLAIN (COSTS OFF) SELECT * FROM ft1 ORDER BY c3, c1 OFFSET 100 LIMIT 10; --Testcase 31: SELECT * FROM ft1 ORDER BY c3, c1 OFFSET 100 LIMIT 10; - c1 | c2 | c3 | time | c6 | c7 | c8 ------+----+-------+--------------------------+----+------------+----- - 101 | 1 | 00101 | Fri Jan 02 00:00:00 1970 | 1 | 1 | foo - 102 | 2 | 00102 | Sat Jan 03 00:00:00 1970 | 2 | 2 | foo - 103 | 3 | 00103 | Sun Jan 04 00:00:00 1970 | 3 | 3 | foo - 104 | 4 | 00104 | Mon Jan 05 00:00:00 1970 | 4 | 4 | foo - 105 | 5 | 00105 | Tue Jan 06 00:00:00 1970 | 5 | 5 | foo - 106 | 6 | 00106 | Wed Jan 07 00:00:00 1970 | 6 | 6 | foo - 107 | 7 | 00107 | Thu Jan 08 00:00:00 1970 | 7 | 7 | foo - 108 | 8 | 00108 | Fri Jan 09 00:00:00 1970 | 8 | 8 | foo - 109 | 9 | 00109 | Sat Jan 10 00:00:00 1970 | 9 | 9 | foo - 110 | 0 | 00110 | Sun Jan 11 00:00:00 1970 | 0 | 0 | foo + c1 | c2 | c3 | time | c6 | c7 | c8 +-----+----+-------+------------------------------+----+------------+----- + 101 | 1 | 00101 | Fri Jan 02 00:00:00 1970 PST | 1 | 1 | foo + 102 | 2 | 00102 | Sat Jan 03 00:00:00 1970 PST | 2 | 2 | foo + 103 | 3 | 00103 | Sun Jan 04 00:00:00 1970 PST | 3 | 3 | foo + 104 | 4 | 00104 | Mon Jan 05 00:00:00 1970 PST | 4 | 4 | foo + 105 | 5 | 00105 | Tue Jan 06 00:00:00 1970 PST | 5 | 5 | foo + 106 | 6 | 00106 | Wed Jan 07 00:00:00 1970 PST | 6 | 6 | foo + 107 | 7 | 00107 | Thu Jan 08 00:00:00 1970 PST | 7 | 7 | foo + 108 | 8 | 00108 | Fri Jan 09 00:00:00 1970 PST | 8 | 8 | foo + 109 | 9 | 00109 | Sat Jan 10 00:00:00 1970 PST | 9 | 9 | foo + 110 | 0 | 00110 | Sun Jan 11 00:00:00 1970 PST | 0 | 0 | foo (10 rows) -- single table with alias - also test that tableoid sort is not pushed to remote side @@ -291,18 +291,18 @@ EXPLAIN (VERBOSE, COSTS OFF) SELECT * FROM ft1 t1 ORDER BY t1.c3, t1.c1, t1.tabl --Testcase 33: SELECT * FROM ft1 t1 ORDER BY t1.c3, t1.c1, t1.tableoid OFFSET 100 LIMIT 10; - c1 | c2 | c3 | time | c6 | c7 | c8 ------+----+-------+--------------------------+----+------------+----- - 101 | 1 | 00101 | Fri Jan 02 00:00:00 1970 | 1 | 1 | foo - 102 | 2 | 00102 | Sat Jan 03 00:00:00 1970 | 2 | 2 | foo - 103 | 3 | 00103 | Sun Jan 04 00:00:00 1970 | 3 | 3 | foo - 104 | 4 | 00104 | Mon Jan 05 00:00:00 1970 | 4 | 4 | foo - 105 | 5 | 00105 | Tue Jan 06 00:00:00 1970 | 5 | 5 | foo - 106 | 6 | 00106 | Wed Jan 07 00:00:00 1970 | 6 | 6 | foo - 107 | 7 | 00107 | Thu Jan 08 00:00:00 1970 | 7 | 7 | foo - 108 | 8 | 00108 | Fri Jan 09 00:00:00 1970 | 8 | 8 | foo - 109 | 9 | 00109 | Sat Jan 10 00:00:00 1970 | 9 | 9 | foo - 110 | 0 | 00110 | Sun Jan 11 00:00:00 1970 | 0 | 0 | foo + c1 | c2 | c3 | time | c6 | c7 | c8 +-----+----+-------+------------------------------+----+------------+----- + 101 | 1 | 00101 | Fri Jan 02 00:00:00 1970 PST | 1 | 1 | foo + 102 | 2 | 00102 | Sat Jan 03 00:00:00 1970 PST | 2 | 2 | foo + 103 | 3 | 00103 | Sun Jan 04 00:00:00 1970 PST | 3 | 3 | foo + 104 | 4 | 00104 | Mon Jan 05 00:00:00 1970 PST | 4 | 4 | foo + 105 | 5 | 00105 | Tue Jan 06 00:00:00 1970 PST | 5 | 5 | foo + 106 | 6 | 00106 | Wed Jan 07 00:00:00 1970 PST | 6 | 6 | foo + 107 | 7 | 00107 | Thu Jan 08 00:00:00 1970 PST | 7 | 7 | foo + 108 | 8 | 00108 | Fri Jan 09 00:00:00 1970 PST | 8 | 8 | foo + 109 | 9 | 00109 | Sat Jan 10 00:00:00 1970 PST | 9 | 9 | foo + 110 | 0 | 00110 | Sun Jan 11 00:00:00 1970 PST | 0 | 0 | foo (10 rows) -- whole-row reference @@ -322,18 +322,18 @@ EXPLAIN (VERBOSE, COSTS OFF) SELECT t1 FROM ft1 t1 ORDER BY t1.c3, t1.c1 OFFSET --Testcase 35: SELECT t1 FROM ft1 t1 ORDER BY t1.c3, t1.c1 OFFSET 100 LIMIT 10; - t1 -------------------------------------------------------------- - (101,1,00101,"Fri Jan 02 00:00:00 1970",1,"1 ",foo) - (102,2,00102,"Sat Jan 03 00:00:00 1970",2,"2 ",foo) - (103,3,00103,"Sun Jan 04 00:00:00 1970",3,"3 ",foo) - (104,4,00104,"Mon Jan 05 00:00:00 1970",4,"4 ",foo) - (105,5,00105,"Tue Jan 06 00:00:00 1970",5,"5 ",foo) - (106,6,00106,"Wed Jan 07 00:00:00 1970",6,"6 ",foo) - (107,7,00107,"Thu Jan 08 00:00:00 1970",7,"7 ",foo) - (108,8,00108,"Fri Jan 09 00:00:00 1970",8,"8 ",foo) - (109,9,00109,"Sat Jan 10 00:00:00 1970",9,"9 ",foo) - (110,0,00110,"Sun Jan 11 00:00:00 1970",0,"0 ",foo) + t1 +----------------------------------------------------------------- + (101,1,00101,"Fri Jan 02 00:00:00 1970 PST",1,"1 ",foo) + (102,2,00102,"Sat Jan 03 00:00:00 1970 PST",2,"2 ",foo) + (103,3,00103,"Sun Jan 04 00:00:00 1970 PST",3,"3 ",foo) + (104,4,00104,"Mon Jan 05 00:00:00 1970 PST",4,"4 ",foo) + (105,5,00105,"Tue Jan 06 00:00:00 1970 PST",5,"5 ",foo) + (106,6,00106,"Wed Jan 07 00:00:00 1970 PST",6,"6 ",foo) + (107,7,00107,"Thu Jan 08 00:00:00 1970 PST",7,"7 ",foo) + (108,8,00108,"Fri Jan 09 00:00:00 1970 PST",8,"8 ",foo) + (109,9,00109,"Sat Jan 10 00:00:00 1970 PST",9,"9 ",foo) + (110,0,00110,"Sun Jan 11 00:00:00 1970 PST",0,"0 ",foo) (10 rows) -- empty result @@ -356,9 +356,9 @@ EXPLAIN (VERBOSE, COSTS OFF) SELECT * FROM ft1 t1 WHERE t1.c1 = 101 AND t1.c6 = --Testcase 38: SELECT * FROM ft1 t1 WHERE t1.c1 = 101 AND t1.c6 = '1' AND t1.c7 >= '1'; - c1 | c2 | c3 | time | c6 | c7 | c8 ------+----+-------+--------------------------+----+------------+----- - 101 | 1 | 00101 | Fri Jan 02 00:00:00 1970 | 1 | 1 | foo + c1 | c2 | c3 | time | c6 | c7 | c8 +-----+----+-------+------------------------------+----+------------+----- + 101 | 1 | 00101 | Fri Jan 02 00:00:00 1970 PST | 1 | 1 | foo (1 row) -- with FOR UPDATE/SHARE @@ -375,9 +375,9 @@ EXPLAIN (VERBOSE, COSTS OFF) SELECT * FROM ft1 t1 WHERE c1 = 101 FOR UPDATE; --Testcase 40: SELECT * FROM ft1 t1 WHERE c1 = 101 FOR UPDATE; - c1 | c2 | c3 | time | c6 | c7 | c8 ------+----+-------+--------------------------+----+------------+----- - 101 | 1 | 00101 | Fri Jan 02 00:00:00 1970 | 1 | 1 | foo + c1 | c2 | c3 | time | c6 | c7 | c8 +-----+----+-------+------------------------------+----+------------+----- + 101 | 1 | 00101 | Fri Jan 02 00:00:00 1970 PST | 1 | 1 | foo (1 row) --Testcase 41: @@ -393,9 +393,9 @@ EXPLAIN (VERBOSE, COSTS OFF) SELECT * FROM ft1 t1 WHERE c1 = 102 FOR SHARE; --Testcase 42: SELECT * FROM ft1 t1 WHERE c1 = 102 FOR SHARE; - c1 | c2 | c3 | time | c6 | c7 | c8 ------+----+-------+--------------------------+----+------------+----- - 102 | 2 | 00102 | Sat Jan 03 00:00:00 1970 | 2 | 2 | foo + c1 | c2 | c3 | time | c6 | c7 | c8 +-----+----+-------+------------------------------+----+------------+----- + 102 | 2 | 00102 | Sat Jan 03 00:00:00 1970 PST | 2 | 2 | foo (1 row) -- aggregate @@ -409,43 +409,43 @@ SELECT COUNT(*) FROM ft1 t1; -- subquery --Testcase 44: SELECT * FROM ft1 t1 WHERE t1.c3 IN (SELECT c3 FROM ft2 t2 WHERE c1 <= 10) ORDER BY c1; - c1 | c2 | c3 | time | c6 | c7 | c8 -----+----+-------+--------------------------+----+------------+----- - 1 | 1 | 00001 | Fri Jan 02 00:00:00 1970 | 1 | 1 | foo - 2 | 2 | 00002 | Sat Jan 03 00:00:00 1970 | 2 | 2 | foo - 3 | 3 | 00003 | Sun Jan 04 00:00:00 1970 | 3 | 3 | foo - 4 | 4 | 00004 | Mon Jan 05 00:00:00 1970 | 4 | 4 | foo - 5 | 5 | 00005 | Tue Jan 06 00:00:00 1970 | 5 | 5 | foo - 6 | 6 | 00006 | Wed Jan 07 00:00:00 1970 | 6 | 6 | foo - 7 | 7 | 00007 | Thu Jan 08 00:00:00 1970 | 7 | 7 | foo - 8 | 8 | 00008 | Fri Jan 09 00:00:00 1970 | 8 | 8 | foo - 9 | 9 | 00009 | Sat Jan 10 00:00:00 1970 | 9 | 9 | foo - 10 | 0 | 00010 | Sun Jan 11 00:00:00 1970 | 0 | 0 | foo + c1 | c2 | c3 | time | c6 | c7 | c8 +----+----+-------+------------------------------+----+------------+----- + 1 | 1 | 00001 | Fri Jan 02 00:00:00 1970 PST | 1 | 1 | foo + 2 | 2 | 00002 | Sat Jan 03 00:00:00 1970 PST | 2 | 2 | foo + 3 | 3 | 00003 | Sun Jan 04 00:00:00 1970 PST | 3 | 3 | foo + 4 | 4 | 00004 | Mon Jan 05 00:00:00 1970 PST | 4 | 4 | foo + 5 | 5 | 00005 | Tue Jan 06 00:00:00 1970 PST | 5 | 5 | foo + 6 | 6 | 00006 | Wed Jan 07 00:00:00 1970 PST | 6 | 6 | foo + 7 | 7 | 00007 | Thu Jan 08 00:00:00 1970 PST | 7 | 7 | foo + 8 | 8 | 00008 | Fri Jan 09 00:00:00 1970 PST | 8 | 8 | foo + 9 | 9 | 00009 | Sat Jan 10 00:00:00 1970 PST | 9 | 9 | foo + 10 | 0 | 00010 | Sun Jan 11 00:00:00 1970 PST | 0 | 0 | foo (10 rows) -- subquery+MAX --Testcase 45: SELECT * FROM ft1 t1 WHERE t1.c3 = (SELECT MAX(c3) FROM ft2 t2) ORDER BY c1; - c1 | c2 | c3 | time | c6 | c7 | c8 -------+----+-------+--------------------------+----+------------+----- - 1000 | 0 | 01000 | Thu Jan 01 00:00:00 1970 | 0 | 0 | foo + c1 | c2 | c3 | time | c6 | c7 | c8 +------+----+-------+------------------------------+----+------------+----- + 1000 | 0 | 01000 | Thu Jan 01 00:00:00 1970 PST | 0 | 0 | foo (1 row) -- used in CTE --Testcase 46: WITH t1 AS (SELECT * FROM ft1 WHERE c1 <= 10) SELECT t2.c1, t2.c2, t2.c3, t2.time FROM t1, ft2 t2 WHERE t1.c1 = t2.c1 ORDER BY t1.c1; - c1 | c2 | c3 | time -----+----+-------+-------------------------- - 1 | 1 | 00001 | Fri Jan 02 00:00:00 1970 - 2 | 2 | 00002 | Sat Jan 03 00:00:00 1970 - 3 | 3 | 00003 | Sun Jan 04 00:00:00 1970 - 4 | 4 | 00004 | Mon Jan 05 00:00:00 1970 - 5 | 5 | 00005 | Tue Jan 06 00:00:00 1970 - 6 | 6 | 00006 | Wed Jan 07 00:00:00 1970 - 7 | 7 | 00007 | Thu Jan 08 00:00:00 1970 - 8 | 8 | 00008 | Fri Jan 09 00:00:00 1970 - 9 | 9 | 00009 | Sat Jan 10 00:00:00 1970 - 10 | 0 | 00010 | Sun Jan 11 00:00:00 1970 + c1 | c2 | c3 | time +----+----+-------+------------------------------ + 1 | 1 | 00001 | Fri Jan 02 00:00:00 1970 PST + 2 | 2 | 00002 | Sat Jan 03 00:00:00 1970 PST + 3 | 3 | 00003 | Sun Jan 04 00:00:00 1970 PST + 4 | 4 | 00004 | Mon Jan 05 00:00:00 1970 PST + 5 | 5 | 00005 | Tue Jan 06 00:00:00 1970 PST + 6 | 6 | 00006 | Wed Jan 07 00:00:00 1970 PST + 7 | 7 | 00007 | Thu Jan 08 00:00:00 1970 PST + 8 | 8 | 00008 | Fri Jan 09 00:00:00 1970 PST + 9 | 9 | 00009 | Sat Jan 10 00:00:00 1970 PST + 10 | 0 | 00010 | Sun Jan 11 00:00:00 1970 PST (10 rows) -- fixed values @@ -842,9 +842,9 @@ EXPLAIN (VERBOSE, COSTS OFF) --Testcase 71: SELECT * FROM ft2 a, ft2 b WHERE a.c1 = 47 AND b.c1 = a.c2; - c1 | c2 | c3 | time | c6 | c7 | c8 | c1 | c2 | c3 | time | c6 | c7 | c8 -----+----+-------+--------------------------+----+------------+-----+----+----+-------+--------------------------+----+------------+----- - 47 | 7 | 00047 | Tue Feb 17 00:00:00 1970 | 7 | 7 | foo | 7 | 7 | 00007 | Thu Jan 08 00:00:00 1970 | 7 | 7 | foo + c1 | c2 | c3 | time | c6 | c7 | c8 | c1 | c2 | c3 | time | c6 | c7 | c8 +----+----+-------+------------------------------+----+------------+-----+----+----+-------+------------------------------+----+------------+----- + 47 | 7 | 00047 | Tue Feb 17 00:00:00 1970 PST | 7 | 7 | foo | 7 | 7 | 00007 | Thu Jan 08 00:00:00 1970 PST | 7 | 7 | foo (1 row) -- check both safe and unsafe join conditions @@ -870,129 +870,129 @@ EXPLAIN (VERBOSE, COSTS OFF) --Testcase 73: SELECT * FROM ft2 a, ft2 b WHERE a.c2 = 6 AND b.c1 = a.c1 AND a.c8 = 'foo' AND b.c7 = upper(a.c7) ORDER BY a.c1; - c1 | c2 | c3 | time | c6 | c7 | c8 | c1 | c2 | c3 | time | c6 | c7 | c8 ------+----+-------+--------------------------+----+------------+-----+-----+----+-------+--------------------------+----+------------+----- - 6 | 6 | 00006 | Wed Jan 07 00:00:00 1970 | 6 | 6 | foo | 6 | 6 | 00006 | Wed Jan 07 00:00:00 1970 | 6 | 6 | foo - 16 | 6 | 00016 | Sat Jan 17 00:00:00 1970 | 6 | 6 | foo | 16 | 6 | 00016 | Sat Jan 17 00:00:00 1970 | 6 | 6 | foo - 26 | 6 | 00026 | Tue Jan 27 00:00:00 1970 | 6 | 6 | foo | 26 | 6 | 00026 | Tue Jan 27 00:00:00 1970 | 6 | 6 | foo - 36 | 6 | 00036 | Fri Feb 06 00:00:00 1970 | 6 | 6 | foo | 36 | 6 | 00036 | Fri Feb 06 00:00:00 1970 | 6 | 6 | foo - 46 | 6 | 00046 | Mon Feb 16 00:00:00 1970 | 6 | 6 | foo | 46 | 6 | 00046 | Mon Feb 16 00:00:00 1970 | 6 | 6 | foo - 56 | 6 | 00056 | Thu Feb 26 00:00:00 1970 | 6 | 6 | foo | 56 | 6 | 00056 | Thu Feb 26 00:00:00 1970 | 6 | 6 | foo - 66 | 6 | 00066 | Sun Mar 08 00:00:00 1970 | 6 | 6 | foo | 66 | 6 | 00066 | Sun Mar 08 00:00:00 1970 | 6 | 6 | foo - 76 | 6 | 00076 | Wed Mar 18 00:00:00 1970 | 6 | 6 | foo | 76 | 6 | 00076 | Wed Mar 18 00:00:00 1970 | 6 | 6 | foo - 86 | 6 | 00086 | Sat Mar 28 00:00:00 1970 | 6 | 6 | foo | 86 | 6 | 00086 | Sat Mar 28 00:00:00 1970 | 6 | 6 | foo - 96 | 6 | 00096 | Tue Apr 07 00:00:00 1970 | 6 | 6 | foo | 96 | 6 | 00096 | Tue Apr 07 00:00:00 1970 | 6 | 6 | foo - 106 | 6 | 00106 | Wed Jan 07 00:00:00 1970 | 6 | 6 | foo | 106 | 6 | 00106 | Wed Jan 07 00:00:00 1970 | 6 | 6 | foo - 116 | 6 | 00116 | Sat Jan 17 00:00:00 1970 | 6 | 6 | foo | 116 | 6 | 00116 | Sat Jan 17 00:00:00 1970 | 6 | 6 | foo - 126 | 6 | 00126 | Tue Jan 27 00:00:00 1970 | 6 | 6 | foo | 126 | 6 | 00126 | Tue Jan 27 00:00:00 1970 | 6 | 6 | foo - 136 | 6 | 00136 | Fri Feb 06 00:00:00 1970 | 6 | 6 | foo | 136 | 6 | 00136 | Fri Feb 06 00:00:00 1970 | 6 | 6 | foo - 146 | 6 | 00146 | Mon Feb 16 00:00:00 1970 | 6 | 6 | foo | 146 | 6 | 00146 | Mon Feb 16 00:00:00 1970 | 6 | 6 | foo - 156 | 6 | 00156 | Thu Feb 26 00:00:00 1970 | 6 | 6 | foo | 156 | 6 | 00156 | Thu Feb 26 00:00:00 1970 | 6 | 6 | foo - 166 | 6 | 00166 | Sun Mar 08 00:00:00 1970 | 6 | 6 | foo | 166 | 6 | 00166 | Sun Mar 08 00:00:00 1970 | 6 | 6 | foo - 176 | 6 | 00176 | Wed Mar 18 00:00:00 1970 | 6 | 6 | foo | 176 | 6 | 00176 | Wed Mar 18 00:00:00 1970 | 6 | 6 | foo - 186 | 6 | 00186 | Sat Mar 28 00:00:00 1970 | 6 | 6 | foo | 186 | 6 | 00186 | Sat Mar 28 00:00:00 1970 | 6 | 6 | foo - 196 | 6 | 00196 | Tue Apr 07 00:00:00 1970 | 6 | 6 | foo | 196 | 6 | 00196 | Tue Apr 07 00:00:00 1970 | 6 | 6 | foo - 206 | 6 | 00206 | Wed Jan 07 00:00:00 1970 | 6 | 6 | foo | 206 | 6 | 00206 | Wed Jan 07 00:00:00 1970 | 6 | 6 | foo - 216 | 6 | 00216 | Sat Jan 17 00:00:00 1970 | 6 | 6 | foo | 216 | 6 | 00216 | Sat Jan 17 00:00:00 1970 | 6 | 6 | foo - 226 | 6 | 00226 | Tue Jan 27 00:00:00 1970 | 6 | 6 | foo | 226 | 6 | 00226 | Tue Jan 27 00:00:00 1970 | 6 | 6 | foo - 236 | 6 | 00236 | Fri Feb 06 00:00:00 1970 | 6 | 6 | foo | 236 | 6 | 00236 | Fri Feb 06 00:00:00 1970 | 6 | 6 | foo - 246 | 6 | 00246 | Mon Feb 16 00:00:00 1970 | 6 | 6 | foo | 246 | 6 | 00246 | Mon Feb 16 00:00:00 1970 | 6 | 6 | foo - 256 | 6 | 00256 | Thu Feb 26 00:00:00 1970 | 6 | 6 | foo | 256 | 6 | 00256 | Thu Feb 26 00:00:00 1970 | 6 | 6 | foo - 266 | 6 | 00266 | Sun Mar 08 00:00:00 1970 | 6 | 6 | foo | 266 | 6 | 00266 | Sun Mar 08 00:00:00 1970 | 6 | 6 | foo - 276 | 6 | 00276 | Wed Mar 18 00:00:00 1970 | 6 | 6 | foo | 276 | 6 | 00276 | Wed Mar 18 00:00:00 1970 | 6 | 6 | foo - 286 | 6 | 00286 | Sat Mar 28 00:00:00 1970 | 6 | 6 | foo | 286 | 6 | 00286 | Sat Mar 28 00:00:00 1970 | 6 | 6 | foo - 296 | 6 | 00296 | Tue Apr 07 00:00:00 1970 | 6 | 6 | foo | 296 | 6 | 00296 | Tue Apr 07 00:00:00 1970 | 6 | 6 | foo - 306 | 6 | 00306 | Wed Jan 07 00:00:00 1970 | 6 | 6 | foo | 306 | 6 | 00306 | Wed Jan 07 00:00:00 1970 | 6 | 6 | foo - 316 | 6 | 00316 | Sat Jan 17 00:00:00 1970 | 6 | 6 | foo | 316 | 6 | 00316 | Sat Jan 17 00:00:00 1970 | 6 | 6 | foo - 326 | 6 | 00326 | Tue Jan 27 00:00:00 1970 | 6 | 6 | foo | 326 | 6 | 00326 | Tue Jan 27 00:00:00 1970 | 6 | 6 | foo - 336 | 6 | 00336 | Fri Feb 06 00:00:00 1970 | 6 | 6 | foo | 336 | 6 | 00336 | Fri Feb 06 00:00:00 1970 | 6 | 6 | foo - 346 | 6 | 00346 | Mon Feb 16 00:00:00 1970 | 6 | 6 | foo | 346 | 6 | 00346 | Mon Feb 16 00:00:00 1970 | 6 | 6 | foo - 356 | 6 | 00356 | Thu Feb 26 00:00:00 1970 | 6 | 6 | foo | 356 | 6 | 00356 | Thu Feb 26 00:00:00 1970 | 6 | 6 | foo - 366 | 6 | 00366 | Sun Mar 08 00:00:00 1970 | 6 | 6 | foo | 366 | 6 | 00366 | Sun Mar 08 00:00:00 1970 | 6 | 6 | foo - 376 | 6 | 00376 | Wed Mar 18 00:00:00 1970 | 6 | 6 | foo | 376 | 6 | 00376 | Wed Mar 18 00:00:00 1970 | 6 | 6 | foo - 386 | 6 | 00386 | Sat Mar 28 00:00:00 1970 | 6 | 6 | foo | 386 | 6 | 00386 | Sat Mar 28 00:00:00 1970 | 6 | 6 | foo - 396 | 6 | 00396 | Tue Apr 07 00:00:00 1970 | 6 | 6 | foo | 396 | 6 | 00396 | Tue Apr 07 00:00:00 1970 | 6 | 6 | foo - 406 | 6 | 00406 | Wed Jan 07 00:00:00 1970 | 6 | 6 | foo | 406 | 6 | 00406 | Wed Jan 07 00:00:00 1970 | 6 | 6 | foo - 416 | 6 | 00416 | Sat Jan 17 00:00:00 1970 | 6 | 6 | foo | 416 | 6 | 00416 | Sat Jan 17 00:00:00 1970 | 6 | 6 | foo - 426 | 6 | 00426 | Tue Jan 27 00:00:00 1970 | 6 | 6 | foo | 426 | 6 | 00426 | Tue Jan 27 00:00:00 1970 | 6 | 6 | foo - 436 | 6 | 00436 | Fri Feb 06 00:00:00 1970 | 6 | 6 | foo | 436 | 6 | 00436 | Fri Feb 06 00:00:00 1970 | 6 | 6 | foo - 446 | 6 | 00446 | Mon Feb 16 00:00:00 1970 | 6 | 6 | foo | 446 | 6 | 00446 | Mon Feb 16 00:00:00 1970 | 6 | 6 | foo - 456 | 6 | 00456 | Thu Feb 26 00:00:00 1970 | 6 | 6 | foo | 456 | 6 | 00456 | Thu Feb 26 00:00:00 1970 | 6 | 6 | foo - 466 | 6 | 00466 | Sun Mar 08 00:00:00 1970 | 6 | 6 | foo | 466 | 6 | 00466 | Sun Mar 08 00:00:00 1970 | 6 | 6 | foo - 476 | 6 | 00476 | Wed Mar 18 00:00:00 1970 | 6 | 6 | foo | 476 | 6 | 00476 | Wed Mar 18 00:00:00 1970 | 6 | 6 | foo - 486 | 6 | 00486 | Sat Mar 28 00:00:00 1970 | 6 | 6 | foo | 486 | 6 | 00486 | Sat Mar 28 00:00:00 1970 | 6 | 6 | foo - 496 | 6 | 00496 | Tue Apr 07 00:00:00 1970 | 6 | 6 | foo | 496 | 6 | 00496 | Tue Apr 07 00:00:00 1970 | 6 | 6 | foo - 506 | 6 | 00506 | Wed Jan 07 00:00:00 1970 | 6 | 6 | foo | 506 | 6 | 00506 | Wed Jan 07 00:00:00 1970 | 6 | 6 | foo - 516 | 6 | 00516 | Sat Jan 17 00:00:00 1970 | 6 | 6 | foo | 516 | 6 | 00516 | Sat Jan 17 00:00:00 1970 | 6 | 6 | foo - 526 | 6 | 00526 | Tue Jan 27 00:00:00 1970 | 6 | 6 | foo | 526 | 6 | 00526 | Tue Jan 27 00:00:00 1970 | 6 | 6 | foo - 536 | 6 | 00536 | Fri Feb 06 00:00:00 1970 | 6 | 6 | foo | 536 | 6 | 00536 | Fri Feb 06 00:00:00 1970 | 6 | 6 | foo - 546 | 6 | 00546 | Mon Feb 16 00:00:00 1970 | 6 | 6 | foo | 546 | 6 | 00546 | Mon Feb 16 00:00:00 1970 | 6 | 6 | foo - 556 | 6 | 00556 | Thu Feb 26 00:00:00 1970 | 6 | 6 | foo | 556 | 6 | 00556 | Thu Feb 26 00:00:00 1970 | 6 | 6 | foo - 566 | 6 | 00566 | Sun Mar 08 00:00:00 1970 | 6 | 6 | foo | 566 | 6 | 00566 | Sun Mar 08 00:00:00 1970 | 6 | 6 | foo - 576 | 6 | 00576 | Wed Mar 18 00:00:00 1970 | 6 | 6 | foo | 576 | 6 | 00576 | Wed Mar 18 00:00:00 1970 | 6 | 6 | foo - 586 | 6 | 00586 | Sat Mar 28 00:00:00 1970 | 6 | 6 | foo | 586 | 6 | 00586 | Sat Mar 28 00:00:00 1970 | 6 | 6 | foo - 596 | 6 | 00596 | Tue Apr 07 00:00:00 1970 | 6 | 6 | foo | 596 | 6 | 00596 | Tue Apr 07 00:00:00 1970 | 6 | 6 | foo - 606 | 6 | 00606 | Wed Jan 07 00:00:00 1970 | 6 | 6 | foo | 606 | 6 | 00606 | Wed Jan 07 00:00:00 1970 | 6 | 6 | foo - 616 | 6 | 00616 | Sat Jan 17 00:00:00 1970 | 6 | 6 | foo | 616 | 6 | 00616 | Sat Jan 17 00:00:00 1970 | 6 | 6 | foo - 626 | 6 | 00626 | Tue Jan 27 00:00:00 1970 | 6 | 6 | foo | 626 | 6 | 00626 | Tue Jan 27 00:00:00 1970 | 6 | 6 | foo - 636 | 6 | 00636 | Fri Feb 06 00:00:00 1970 | 6 | 6 | foo | 636 | 6 | 00636 | Fri Feb 06 00:00:00 1970 | 6 | 6 | foo - 646 | 6 | 00646 | Mon Feb 16 00:00:00 1970 | 6 | 6 | foo | 646 | 6 | 00646 | Mon Feb 16 00:00:00 1970 | 6 | 6 | foo - 656 | 6 | 00656 | Thu Feb 26 00:00:00 1970 | 6 | 6 | foo | 656 | 6 | 00656 | Thu Feb 26 00:00:00 1970 | 6 | 6 | foo - 666 | 6 | 00666 | Sun Mar 08 00:00:00 1970 | 6 | 6 | foo | 666 | 6 | 00666 | Sun Mar 08 00:00:00 1970 | 6 | 6 | foo - 676 | 6 | 00676 | Wed Mar 18 00:00:00 1970 | 6 | 6 | foo | 676 | 6 | 00676 | Wed Mar 18 00:00:00 1970 | 6 | 6 | foo - 686 | 6 | 00686 | Sat Mar 28 00:00:00 1970 | 6 | 6 | foo | 686 | 6 | 00686 | Sat Mar 28 00:00:00 1970 | 6 | 6 | foo - 696 | 6 | 00696 | Tue Apr 07 00:00:00 1970 | 6 | 6 | foo | 696 | 6 | 00696 | Tue Apr 07 00:00:00 1970 | 6 | 6 | foo - 706 | 6 | 00706 | Wed Jan 07 00:00:00 1970 | 6 | 6 | foo | 706 | 6 | 00706 | Wed Jan 07 00:00:00 1970 | 6 | 6 | foo - 716 | 6 | 00716 | Sat Jan 17 00:00:00 1970 | 6 | 6 | foo | 716 | 6 | 00716 | Sat Jan 17 00:00:00 1970 | 6 | 6 | foo - 726 | 6 | 00726 | Tue Jan 27 00:00:00 1970 | 6 | 6 | foo | 726 | 6 | 00726 | Tue Jan 27 00:00:00 1970 | 6 | 6 | foo - 736 | 6 | 00736 | Fri Feb 06 00:00:00 1970 | 6 | 6 | foo | 736 | 6 | 00736 | Fri Feb 06 00:00:00 1970 | 6 | 6 | foo - 746 | 6 | 00746 | Mon Feb 16 00:00:00 1970 | 6 | 6 | foo | 746 | 6 | 00746 | Mon Feb 16 00:00:00 1970 | 6 | 6 | foo - 756 | 6 | 00756 | Thu Feb 26 00:00:00 1970 | 6 | 6 | foo | 756 | 6 | 00756 | Thu Feb 26 00:00:00 1970 | 6 | 6 | foo - 766 | 6 | 00766 | Sun Mar 08 00:00:00 1970 | 6 | 6 | foo | 766 | 6 | 00766 | Sun Mar 08 00:00:00 1970 | 6 | 6 | foo - 776 | 6 | 00776 | Wed Mar 18 00:00:00 1970 | 6 | 6 | foo | 776 | 6 | 00776 | Wed Mar 18 00:00:00 1970 | 6 | 6 | foo - 786 | 6 | 00786 | Sat Mar 28 00:00:00 1970 | 6 | 6 | foo | 786 | 6 | 00786 | Sat Mar 28 00:00:00 1970 | 6 | 6 | foo - 796 | 6 | 00796 | Tue Apr 07 00:00:00 1970 | 6 | 6 | foo | 796 | 6 | 00796 | Tue Apr 07 00:00:00 1970 | 6 | 6 | foo - 806 | 6 | 00806 | Wed Jan 07 00:00:00 1970 | 6 | 6 | foo | 806 | 6 | 00806 | Wed Jan 07 00:00:00 1970 | 6 | 6 | foo - 816 | 6 | 00816 | Sat Jan 17 00:00:00 1970 | 6 | 6 | foo | 816 | 6 | 00816 | Sat Jan 17 00:00:00 1970 | 6 | 6 | foo - 826 | 6 | 00826 | Tue Jan 27 00:00:00 1970 | 6 | 6 | foo | 826 | 6 | 00826 | Tue Jan 27 00:00:00 1970 | 6 | 6 | foo - 836 | 6 | 00836 | Fri Feb 06 00:00:00 1970 | 6 | 6 | foo | 836 | 6 | 00836 | Fri Feb 06 00:00:00 1970 | 6 | 6 | foo - 846 | 6 | 00846 | Mon Feb 16 00:00:00 1970 | 6 | 6 | foo | 846 | 6 | 00846 | Mon Feb 16 00:00:00 1970 | 6 | 6 | foo - 856 | 6 | 00856 | Thu Feb 26 00:00:00 1970 | 6 | 6 | foo | 856 | 6 | 00856 | Thu Feb 26 00:00:00 1970 | 6 | 6 | foo - 866 | 6 | 00866 | Sun Mar 08 00:00:00 1970 | 6 | 6 | foo | 866 | 6 | 00866 | Sun Mar 08 00:00:00 1970 | 6 | 6 | foo - 876 | 6 | 00876 | Wed Mar 18 00:00:00 1970 | 6 | 6 | foo | 876 | 6 | 00876 | Wed Mar 18 00:00:00 1970 | 6 | 6 | foo - 886 | 6 | 00886 | Sat Mar 28 00:00:00 1970 | 6 | 6 | foo | 886 | 6 | 00886 | Sat Mar 28 00:00:00 1970 | 6 | 6 | foo - 896 | 6 | 00896 | Tue Apr 07 00:00:00 1970 | 6 | 6 | foo | 896 | 6 | 00896 | Tue Apr 07 00:00:00 1970 | 6 | 6 | foo - 906 | 6 | 00906 | Wed Jan 07 00:00:00 1970 | 6 | 6 | foo | 906 | 6 | 00906 | Wed Jan 07 00:00:00 1970 | 6 | 6 | foo - 916 | 6 | 00916 | Sat Jan 17 00:00:00 1970 | 6 | 6 | foo | 916 | 6 | 00916 | Sat Jan 17 00:00:00 1970 | 6 | 6 | foo - 926 | 6 | 00926 | Tue Jan 27 00:00:00 1970 | 6 | 6 | foo | 926 | 6 | 00926 | Tue Jan 27 00:00:00 1970 | 6 | 6 | foo - 936 | 6 | 00936 | Fri Feb 06 00:00:00 1970 | 6 | 6 | foo | 936 | 6 | 00936 | Fri Feb 06 00:00:00 1970 | 6 | 6 | foo - 946 | 6 | 00946 | Mon Feb 16 00:00:00 1970 | 6 | 6 | foo | 946 | 6 | 00946 | Mon Feb 16 00:00:00 1970 | 6 | 6 | foo - 956 | 6 | 00956 | Thu Feb 26 00:00:00 1970 | 6 | 6 | foo | 956 | 6 | 00956 | Thu Feb 26 00:00:00 1970 | 6 | 6 | foo - 966 | 6 | 00966 | Sun Mar 08 00:00:00 1970 | 6 | 6 | foo | 966 | 6 | 00966 | Sun Mar 08 00:00:00 1970 | 6 | 6 | foo - 976 | 6 | 00976 | Wed Mar 18 00:00:00 1970 | 6 | 6 | foo | 976 | 6 | 00976 | Wed Mar 18 00:00:00 1970 | 6 | 6 | foo - 986 | 6 | 00986 | Sat Mar 28 00:00:00 1970 | 6 | 6 | foo | 986 | 6 | 00986 | Sat Mar 28 00:00:00 1970 | 6 | 6 | foo - 996 | 6 | 00996 | Tue Apr 07 00:00:00 1970 | 6 | 6 | foo | 996 | 6 | 00996 | Tue Apr 07 00:00:00 1970 | 6 | 6 | foo + c1 | c2 | c3 | time | c6 | c7 | c8 | c1 | c2 | c3 | time | c6 | c7 | c8 +-----+----+-------+------------------------------+----+------------+-----+-----+----+-------+------------------------------+----+------------+----- + 6 | 6 | 00006 | Wed Jan 07 00:00:00 1970 PST | 6 | 6 | foo | 6 | 6 | 00006 | Wed Jan 07 00:00:00 1970 PST | 6 | 6 | foo + 16 | 6 | 00016 | Sat Jan 17 00:00:00 1970 PST | 6 | 6 | foo | 16 | 6 | 00016 | Sat Jan 17 00:00:00 1970 PST | 6 | 6 | foo + 26 | 6 | 00026 | Tue Jan 27 00:00:00 1970 PST | 6 | 6 | foo | 26 | 6 | 00026 | Tue Jan 27 00:00:00 1970 PST | 6 | 6 | foo + 36 | 6 | 00036 | Fri Feb 06 00:00:00 1970 PST | 6 | 6 | foo | 36 | 6 | 00036 | Fri Feb 06 00:00:00 1970 PST | 6 | 6 | foo + 46 | 6 | 00046 | Mon Feb 16 00:00:00 1970 PST | 6 | 6 | foo | 46 | 6 | 00046 | Mon Feb 16 00:00:00 1970 PST | 6 | 6 | foo + 56 | 6 | 00056 | Thu Feb 26 00:00:00 1970 PST | 6 | 6 | foo | 56 | 6 | 00056 | Thu Feb 26 00:00:00 1970 PST | 6 | 6 | foo + 66 | 6 | 00066 | Sun Mar 08 00:00:00 1970 PST | 6 | 6 | foo | 66 | 6 | 00066 | Sun Mar 08 00:00:00 1970 PST | 6 | 6 | foo + 76 | 6 | 00076 | Wed Mar 18 00:00:00 1970 PST | 6 | 6 | foo | 76 | 6 | 00076 | Wed Mar 18 00:00:00 1970 PST | 6 | 6 | foo + 86 | 6 | 00086 | Sat Mar 28 00:00:00 1970 PST | 6 | 6 | foo | 86 | 6 | 00086 | Sat Mar 28 00:00:00 1970 PST | 6 | 6 | foo + 96 | 6 | 00096 | Tue Apr 07 00:00:00 1970 PST | 6 | 6 | foo | 96 | 6 | 00096 | Tue Apr 07 00:00:00 1970 PST | 6 | 6 | foo + 106 | 6 | 00106 | Wed Jan 07 00:00:00 1970 PST | 6 | 6 | foo | 106 | 6 | 00106 | Wed Jan 07 00:00:00 1970 PST | 6 | 6 | foo + 116 | 6 | 00116 | Sat Jan 17 00:00:00 1970 PST | 6 | 6 | foo | 116 | 6 | 00116 | Sat Jan 17 00:00:00 1970 PST | 6 | 6 | foo + 126 | 6 | 00126 | Tue Jan 27 00:00:00 1970 PST | 6 | 6 | foo | 126 | 6 | 00126 | Tue Jan 27 00:00:00 1970 PST | 6 | 6 | foo + 136 | 6 | 00136 | Fri Feb 06 00:00:00 1970 PST | 6 | 6 | foo | 136 | 6 | 00136 | Fri Feb 06 00:00:00 1970 PST | 6 | 6 | foo + 146 | 6 | 00146 | Mon Feb 16 00:00:00 1970 PST | 6 | 6 | foo | 146 | 6 | 00146 | Mon Feb 16 00:00:00 1970 PST | 6 | 6 | foo + 156 | 6 | 00156 | Thu Feb 26 00:00:00 1970 PST | 6 | 6 | foo | 156 | 6 | 00156 | Thu Feb 26 00:00:00 1970 PST | 6 | 6 | foo + 166 | 6 | 00166 | Sun Mar 08 00:00:00 1970 PST | 6 | 6 | foo | 166 | 6 | 00166 | Sun Mar 08 00:00:00 1970 PST | 6 | 6 | foo + 176 | 6 | 00176 | Wed Mar 18 00:00:00 1970 PST | 6 | 6 | foo | 176 | 6 | 00176 | Wed Mar 18 00:00:00 1970 PST | 6 | 6 | foo + 186 | 6 | 00186 | Sat Mar 28 00:00:00 1970 PST | 6 | 6 | foo | 186 | 6 | 00186 | Sat Mar 28 00:00:00 1970 PST | 6 | 6 | foo + 196 | 6 | 00196 | Tue Apr 07 00:00:00 1970 PST | 6 | 6 | foo | 196 | 6 | 00196 | Tue Apr 07 00:00:00 1970 PST | 6 | 6 | foo + 206 | 6 | 00206 | Wed Jan 07 00:00:00 1970 PST | 6 | 6 | foo | 206 | 6 | 00206 | Wed Jan 07 00:00:00 1970 PST | 6 | 6 | foo + 216 | 6 | 00216 | Sat Jan 17 00:00:00 1970 PST | 6 | 6 | foo | 216 | 6 | 00216 | Sat Jan 17 00:00:00 1970 PST | 6 | 6 | foo + 226 | 6 | 00226 | Tue Jan 27 00:00:00 1970 PST | 6 | 6 | foo | 226 | 6 | 00226 | Tue Jan 27 00:00:00 1970 PST | 6 | 6 | foo + 236 | 6 | 00236 | Fri Feb 06 00:00:00 1970 PST | 6 | 6 | foo | 236 | 6 | 00236 | Fri Feb 06 00:00:00 1970 PST | 6 | 6 | foo + 246 | 6 | 00246 | Mon Feb 16 00:00:00 1970 PST | 6 | 6 | foo | 246 | 6 | 00246 | Mon Feb 16 00:00:00 1970 PST | 6 | 6 | foo + 256 | 6 | 00256 | Thu Feb 26 00:00:00 1970 PST | 6 | 6 | foo | 256 | 6 | 00256 | Thu Feb 26 00:00:00 1970 PST | 6 | 6 | foo + 266 | 6 | 00266 | Sun Mar 08 00:00:00 1970 PST | 6 | 6 | foo | 266 | 6 | 00266 | Sun Mar 08 00:00:00 1970 PST | 6 | 6 | foo + 276 | 6 | 00276 | Wed Mar 18 00:00:00 1970 PST | 6 | 6 | foo | 276 | 6 | 00276 | Wed Mar 18 00:00:00 1970 PST | 6 | 6 | foo + 286 | 6 | 00286 | Sat Mar 28 00:00:00 1970 PST | 6 | 6 | foo | 286 | 6 | 00286 | Sat Mar 28 00:00:00 1970 PST | 6 | 6 | foo + 296 | 6 | 00296 | Tue Apr 07 00:00:00 1970 PST | 6 | 6 | foo | 296 | 6 | 00296 | Tue Apr 07 00:00:00 1970 PST | 6 | 6 | foo + 306 | 6 | 00306 | Wed Jan 07 00:00:00 1970 PST | 6 | 6 | foo | 306 | 6 | 00306 | Wed Jan 07 00:00:00 1970 PST | 6 | 6 | foo + 316 | 6 | 00316 | Sat Jan 17 00:00:00 1970 PST | 6 | 6 | foo | 316 | 6 | 00316 | Sat Jan 17 00:00:00 1970 PST | 6 | 6 | foo + 326 | 6 | 00326 | Tue Jan 27 00:00:00 1970 PST | 6 | 6 | foo | 326 | 6 | 00326 | Tue Jan 27 00:00:00 1970 PST | 6 | 6 | foo + 336 | 6 | 00336 | Fri Feb 06 00:00:00 1970 PST | 6 | 6 | foo | 336 | 6 | 00336 | Fri Feb 06 00:00:00 1970 PST | 6 | 6 | foo + 346 | 6 | 00346 | Mon Feb 16 00:00:00 1970 PST | 6 | 6 | foo | 346 | 6 | 00346 | Mon Feb 16 00:00:00 1970 PST | 6 | 6 | foo + 356 | 6 | 00356 | Thu Feb 26 00:00:00 1970 PST | 6 | 6 | foo | 356 | 6 | 00356 | Thu Feb 26 00:00:00 1970 PST | 6 | 6 | foo + 366 | 6 | 00366 | Sun Mar 08 00:00:00 1970 PST | 6 | 6 | foo | 366 | 6 | 00366 | Sun Mar 08 00:00:00 1970 PST | 6 | 6 | foo + 376 | 6 | 00376 | Wed Mar 18 00:00:00 1970 PST | 6 | 6 | foo | 376 | 6 | 00376 | Wed Mar 18 00:00:00 1970 PST | 6 | 6 | foo + 386 | 6 | 00386 | Sat Mar 28 00:00:00 1970 PST | 6 | 6 | foo | 386 | 6 | 00386 | Sat Mar 28 00:00:00 1970 PST | 6 | 6 | foo + 396 | 6 | 00396 | Tue Apr 07 00:00:00 1970 PST | 6 | 6 | foo | 396 | 6 | 00396 | Tue Apr 07 00:00:00 1970 PST | 6 | 6 | foo + 406 | 6 | 00406 | Wed Jan 07 00:00:00 1970 PST | 6 | 6 | foo | 406 | 6 | 00406 | Wed Jan 07 00:00:00 1970 PST | 6 | 6 | foo + 416 | 6 | 00416 | Sat Jan 17 00:00:00 1970 PST | 6 | 6 | foo | 416 | 6 | 00416 | Sat Jan 17 00:00:00 1970 PST | 6 | 6 | foo + 426 | 6 | 00426 | Tue Jan 27 00:00:00 1970 PST | 6 | 6 | foo | 426 | 6 | 00426 | Tue Jan 27 00:00:00 1970 PST | 6 | 6 | foo + 436 | 6 | 00436 | Fri Feb 06 00:00:00 1970 PST | 6 | 6 | foo | 436 | 6 | 00436 | Fri Feb 06 00:00:00 1970 PST | 6 | 6 | foo + 446 | 6 | 00446 | Mon Feb 16 00:00:00 1970 PST | 6 | 6 | foo | 446 | 6 | 00446 | Mon Feb 16 00:00:00 1970 PST | 6 | 6 | foo + 456 | 6 | 00456 | Thu Feb 26 00:00:00 1970 PST | 6 | 6 | foo | 456 | 6 | 00456 | Thu Feb 26 00:00:00 1970 PST | 6 | 6 | foo + 466 | 6 | 00466 | Sun Mar 08 00:00:00 1970 PST | 6 | 6 | foo | 466 | 6 | 00466 | Sun Mar 08 00:00:00 1970 PST | 6 | 6 | foo + 476 | 6 | 00476 | Wed Mar 18 00:00:00 1970 PST | 6 | 6 | foo | 476 | 6 | 00476 | Wed Mar 18 00:00:00 1970 PST | 6 | 6 | foo + 486 | 6 | 00486 | Sat Mar 28 00:00:00 1970 PST | 6 | 6 | foo | 486 | 6 | 00486 | Sat Mar 28 00:00:00 1970 PST | 6 | 6 | foo + 496 | 6 | 00496 | Tue Apr 07 00:00:00 1970 PST | 6 | 6 | foo | 496 | 6 | 00496 | Tue Apr 07 00:00:00 1970 PST | 6 | 6 | foo + 506 | 6 | 00506 | Wed Jan 07 00:00:00 1970 PST | 6 | 6 | foo | 506 | 6 | 00506 | Wed Jan 07 00:00:00 1970 PST | 6 | 6 | foo + 516 | 6 | 00516 | Sat Jan 17 00:00:00 1970 PST | 6 | 6 | foo | 516 | 6 | 00516 | Sat Jan 17 00:00:00 1970 PST | 6 | 6 | foo + 526 | 6 | 00526 | Tue Jan 27 00:00:00 1970 PST | 6 | 6 | foo | 526 | 6 | 00526 | Tue Jan 27 00:00:00 1970 PST | 6 | 6 | foo + 536 | 6 | 00536 | Fri Feb 06 00:00:00 1970 PST | 6 | 6 | foo | 536 | 6 | 00536 | Fri Feb 06 00:00:00 1970 PST | 6 | 6 | foo + 546 | 6 | 00546 | Mon Feb 16 00:00:00 1970 PST | 6 | 6 | foo | 546 | 6 | 00546 | Mon Feb 16 00:00:00 1970 PST | 6 | 6 | foo + 556 | 6 | 00556 | Thu Feb 26 00:00:00 1970 PST | 6 | 6 | foo | 556 | 6 | 00556 | Thu Feb 26 00:00:00 1970 PST | 6 | 6 | foo + 566 | 6 | 00566 | Sun Mar 08 00:00:00 1970 PST | 6 | 6 | foo | 566 | 6 | 00566 | Sun Mar 08 00:00:00 1970 PST | 6 | 6 | foo + 576 | 6 | 00576 | Wed Mar 18 00:00:00 1970 PST | 6 | 6 | foo | 576 | 6 | 00576 | Wed Mar 18 00:00:00 1970 PST | 6 | 6 | foo + 586 | 6 | 00586 | Sat Mar 28 00:00:00 1970 PST | 6 | 6 | foo | 586 | 6 | 00586 | Sat Mar 28 00:00:00 1970 PST | 6 | 6 | foo + 596 | 6 | 00596 | Tue Apr 07 00:00:00 1970 PST | 6 | 6 | foo | 596 | 6 | 00596 | Tue Apr 07 00:00:00 1970 PST | 6 | 6 | foo + 606 | 6 | 00606 | Wed Jan 07 00:00:00 1970 PST | 6 | 6 | foo | 606 | 6 | 00606 | Wed Jan 07 00:00:00 1970 PST | 6 | 6 | foo + 616 | 6 | 00616 | Sat Jan 17 00:00:00 1970 PST | 6 | 6 | foo | 616 | 6 | 00616 | Sat Jan 17 00:00:00 1970 PST | 6 | 6 | foo + 626 | 6 | 00626 | Tue Jan 27 00:00:00 1970 PST | 6 | 6 | foo | 626 | 6 | 00626 | Tue Jan 27 00:00:00 1970 PST | 6 | 6 | foo + 636 | 6 | 00636 | Fri Feb 06 00:00:00 1970 PST | 6 | 6 | foo | 636 | 6 | 00636 | Fri Feb 06 00:00:00 1970 PST | 6 | 6 | foo + 646 | 6 | 00646 | Mon Feb 16 00:00:00 1970 PST | 6 | 6 | foo | 646 | 6 | 00646 | Mon Feb 16 00:00:00 1970 PST | 6 | 6 | foo + 656 | 6 | 00656 | Thu Feb 26 00:00:00 1970 PST | 6 | 6 | foo | 656 | 6 | 00656 | Thu Feb 26 00:00:00 1970 PST | 6 | 6 | foo + 666 | 6 | 00666 | Sun Mar 08 00:00:00 1970 PST | 6 | 6 | foo | 666 | 6 | 00666 | Sun Mar 08 00:00:00 1970 PST | 6 | 6 | foo + 676 | 6 | 00676 | Wed Mar 18 00:00:00 1970 PST | 6 | 6 | foo | 676 | 6 | 00676 | Wed Mar 18 00:00:00 1970 PST | 6 | 6 | foo + 686 | 6 | 00686 | Sat Mar 28 00:00:00 1970 PST | 6 | 6 | foo | 686 | 6 | 00686 | Sat Mar 28 00:00:00 1970 PST | 6 | 6 | foo + 696 | 6 | 00696 | Tue Apr 07 00:00:00 1970 PST | 6 | 6 | foo | 696 | 6 | 00696 | Tue Apr 07 00:00:00 1970 PST | 6 | 6 | foo + 706 | 6 | 00706 | Wed Jan 07 00:00:00 1970 PST | 6 | 6 | foo | 706 | 6 | 00706 | Wed Jan 07 00:00:00 1970 PST | 6 | 6 | foo + 716 | 6 | 00716 | Sat Jan 17 00:00:00 1970 PST | 6 | 6 | foo | 716 | 6 | 00716 | Sat Jan 17 00:00:00 1970 PST | 6 | 6 | foo + 726 | 6 | 00726 | Tue Jan 27 00:00:00 1970 PST | 6 | 6 | foo | 726 | 6 | 00726 | Tue Jan 27 00:00:00 1970 PST | 6 | 6 | foo + 736 | 6 | 00736 | Fri Feb 06 00:00:00 1970 PST | 6 | 6 | foo | 736 | 6 | 00736 | Fri Feb 06 00:00:00 1970 PST | 6 | 6 | foo + 746 | 6 | 00746 | Mon Feb 16 00:00:00 1970 PST | 6 | 6 | foo | 746 | 6 | 00746 | Mon Feb 16 00:00:00 1970 PST | 6 | 6 | foo + 756 | 6 | 00756 | Thu Feb 26 00:00:00 1970 PST | 6 | 6 | foo | 756 | 6 | 00756 | Thu Feb 26 00:00:00 1970 PST | 6 | 6 | foo + 766 | 6 | 00766 | Sun Mar 08 00:00:00 1970 PST | 6 | 6 | foo | 766 | 6 | 00766 | Sun Mar 08 00:00:00 1970 PST | 6 | 6 | foo + 776 | 6 | 00776 | Wed Mar 18 00:00:00 1970 PST | 6 | 6 | foo | 776 | 6 | 00776 | Wed Mar 18 00:00:00 1970 PST | 6 | 6 | foo + 786 | 6 | 00786 | Sat Mar 28 00:00:00 1970 PST | 6 | 6 | foo | 786 | 6 | 00786 | Sat Mar 28 00:00:00 1970 PST | 6 | 6 | foo + 796 | 6 | 00796 | Tue Apr 07 00:00:00 1970 PST | 6 | 6 | foo | 796 | 6 | 00796 | Tue Apr 07 00:00:00 1970 PST | 6 | 6 | foo + 806 | 6 | 00806 | Wed Jan 07 00:00:00 1970 PST | 6 | 6 | foo | 806 | 6 | 00806 | Wed Jan 07 00:00:00 1970 PST | 6 | 6 | foo + 816 | 6 | 00816 | Sat Jan 17 00:00:00 1970 PST | 6 | 6 | foo | 816 | 6 | 00816 | Sat Jan 17 00:00:00 1970 PST | 6 | 6 | foo + 826 | 6 | 00826 | Tue Jan 27 00:00:00 1970 PST | 6 | 6 | foo | 826 | 6 | 00826 | Tue Jan 27 00:00:00 1970 PST | 6 | 6 | foo + 836 | 6 | 00836 | Fri Feb 06 00:00:00 1970 PST | 6 | 6 | foo | 836 | 6 | 00836 | Fri Feb 06 00:00:00 1970 PST | 6 | 6 | foo + 846 | 6 | 00846 | Mon Feb 16 00:00:00 1970 PST | 6 | 6 | foo | 846 | 6 | 00846 | Mon Feb 16 00:00:00 1970 PST | 6 | 6 | foo + 856 | 6 | 00856 | Thu Feb 26 00:00:00 1970 PST | 6 | 6 | foo | 856 | 6 | 00856 | Thu Feb 26 00:00:00 1970 PST | 6 | 6 | foo + 866 | 6 | 00866 | Sun Mar 08 00:00:00 1970 PST | 6 | 6 | foo | 866 | 6 | 00866 | Sun Mar 08 00:00:00 1970 PST | 6 | 6 | foo + 876 | 6 | 00876 | Wed Mar 18 00:00:00 1970 PST | 6 | 6 | foo | 876 | 6 | 00876 | Wed Mar 18 00:00:00 1970 PST | 6 | 6 | foo + 886 | 6 | 00886 | Sat Mar 28 00:00:00 1970 PST | 6 | 6 | foo | 886 | 6 | 00886 | Sat Mar 28 00:00:00 1970 PST | 6 | 6 | foo + 896 | 6 | 00896 | Tue Apr 07 00:00:00 1970 PST | 6 | 6 | foo | 896 | 6 | 00896 | Tue Apr 07 00:00:00 1970 PST | 6 | 6 | foo + 906 | 6 | 00906 | Wed Jan 07 00:00:00 1970 PST | 6 | 6 | foo | 906 | 6 | 00906 | Wed Jan 07 00:00:00 1970 PST | 6 | 6 | foo + 916 | 6 | 00916 | Sat Jan 17 00:00:00 1970 PST | 6 | 6 | foo | 916 | 6 | 00916 | Sat Jan 17 00:00:00 1970 PST | 6 | 6 | foo + 926 | 6 | 00926 | Tue Jan 27 00:00:00 1970 PST | 6 | 6 | foo | 926 | 6 | 00926 | Tue Jan 27 00:00:00 1970 PST | 6 | 6 | foo + 936 | 6 | 00936 | Fri Feb 06 00:00:00 1970 PST | 6 | 6 | foo | 936 | 6 | 00936 | Fri Feb 06 00:00:00 1970 PST | 6 | 6 | foo + 946 | 6 | 00946 | Mon Feb 16 00:00:00 1970 PST | 6 | 6 | foo | 946 | 6 | 00946 | Mon Feb 16 00:00:00 1970 PST | 6 | 6 | foo + 956 | 6 | 00956 | Thu Feb 26 00:00:00 1970 PST | 6 | 6 | foo | 956 | 6 | 00956 | Thu Feb 26 00:00:00 1970 PST | 6 | 6 | foo + 966 | 6 | 00966 | Sun Mar 08 00:00:00 1970 PST | 6 | 6 | foo | 966 | 6 | 00966 | Sun Mar 08 00:00:00 1970 PST | 6 | 6 | foo + 976 | 6 | 00976 | Wed Mar 18 00:00:00 1970 PST | 6 | 6 | foo | 976 | 6 | 00976 | Wed Mar 18 00:00:00 1970 PST | 6 | 6 | foo + 986 | 6 | 00986 | Sat Mar 28 00:00:00 1970 PST | 6 | 6 | foo | 986 | 6 | 00986 | Sat Mar 28 00:00:00 1970 PST | 6 | 6 | foo + 996 | 6 | 00996 | Tue Apr 07 00:00:00 1970 PST | 6 | 6 | foo | 996 | 6 | 00996 | Tue Apr 07 00:00:00 1970 PST | 6 | 6 | foo (100 rows) -- bug before 9.3.5 due to sloppy handling of remote-estimate parameters --Testcase 74: SELECT * FROM ft1 WHERE c1 = ANY (ARRAY(SELECT c1 FROM ft2 WHERE c1 < 5)); - c1 | c2 | c3 | time | c6 | c7 | c8 -----+----+-------+--------------------------+----+------------+----- - 1 | 1 | 00001 | Fri Jan 02 00:00:00 1970 | 1 | 1 | foo - 2 | 2 | 00002 | Sat Jan 03 00:00:00 1970 | 2 | 2 | foo - 3 | 3 | 00003 | Sun Jan 04 00:00:00 1970 | 3 | 3 | foo - 4 | 4 | 00004 | Mon Jan 05 00:00:00 1970 | 4 | 4 | foo + c1 | c2 | c3 | time | c6 | c7 | c8 +----+----+-------+------------------------------+----+------------+----- + 1 | 1 | 00001 | Fri Jan 02 00:00:00 1970 PST | 1 | 1 | foo + 2 | 2 | 00002 | Sat Jan 03 00:00:00 1970 PST | 2 | 2 | foo + 3 | 3 | 00003 | Sun Jan 04 00:00:00 1970 PST | 3 | 3 | foo + 4 | 4 | 00004 | Mon Jan 05 00:00:00 1970 PST | 4 | 4 | foo (4 rows) --Testcase 75: SELECT * FROM ft2 WHERE c1 = ANY (ARRAY(SELECT c1 FROM ft1 WHERE c1 < 5)); - c1 | c2 | c3 | time | c6 | c7 | c8 -----+----+-------+--------------------------+----+------------+----- - 1 | 1 | 00001 | Fri Jan 02 00:00:00 1970 | 1 | 1 | foo - 2 | 2 | 00002 | Sat Jan 03 00:00:00 1970 | 2 | 2 | foo - 3 | 3 | 00003 | Sun Jan 04 00:00:00 1970 | 3 | 3 | foo - 4 | 4 | 00004 | Mon Jan 05 00:00:00 1970 | 4 | 4 | foo + c1 | c2 | c3 | time | c6 | c7 | c8 +----+----+-------+------------------------------+----+------------+----- + 1 | 1 | 00001 | Fri Jan 02 00:00:00 1970 PST | 1 | 1 | foo + 2 | 2 | 00002 | Sat Jan 03 00:00:00 1970 PST | 2 | 2 | foo + 3 | 3 | 00003 | Sun Jan 04 00:00:00 1970 PST | 3 | 3 | foo + 4 | 4 | 00004 | Mon Jan 05 00:00:00 1970 PST | 4 | 4 | foo (4 rows) -- we should not push order by clause with volatile expressions or unsafe @@ -1136,9 +1136,9 @@ EXPLAIN (VERBOSE, COSTS OFF) --Testcase 89: SELECT * FROM ft1 t1 WHERE t1.c1 === t1.c2 order by t1.c2 limit 1; - c1 | c2 | c3 | time | c6 | c7 | c8 -----+----+-------+--------------------------+----+------------+----- - 1 | 1 | 00001 | Fri Jan 02 00:00:00 1970 | 1 | 1 | foo + c1 | c2 | c3 | time | c6 | c7 | c8 +----+----+-------+------------------------------+----+------------+----- + 1 | 1 | 00001 | Fri Jan 02 00:00:00 1970 PST | 1 | 1 | foo (1 row) -- but let's put them in an extension ... @@ -1205,9 +1205,9 @@ EXPLAIN (VERBOSE, COSTS OFF) --Testcase 95: SELECT * FROM ft1 t1 WHERE t1.c1 === t1.c2 order by t1.c2 limit 1; - c1 | c2 | c3 | time | c6 | c7 | c8 -----+----+-------+--------------------------+----+------------+----- - 1 | 1 | 00001 | Fri Jan 02 00:00:00 1970 | 1 | 1 | foo + c1 | c2 | c3 | time | c6 | c7 | c8 +----+----+-------+------------------------------+----+------------+----- + 1 | 1 | 00001 | Fri Jan 02 00:00:00 1970 PST | 1 | 1 | foo (1 row) -- =================================================================== @@ -3058,18 +3058,18 @@ SELECT * FROM ft1, ft2, ft4, ft5, local_tbl WHERE ft1.c1 = ft2.c1 AND ft1.c2 = f --Testcase 181: SELECT * FROM ft1, ft2, ft4, ft5, local_tbl WHERE ft1.c1 = ft2.c1 AND ft1.c2 = ft4.c1 AND ft1.c2 = ft5.c1 AND ft1.c2 = local_tbl.c1 AND ft1.c1 < 100 AND ft2.c1 < 100 ORDER BY ft1.c1 FOR UPDATE; - c1 | c2 | c3 | time | c6 | c7 | c8 | c1 | c2 | c3 | time | c6 | c7 | c8 | c1 | c2 | c3 | c1 | c2 | c3 | c1 | c2 | c3 -----+----+-------+--------------------------+----+------------+-----+----+----+-------+--------------------------+----+------------+-----+----+----+--------+----+----+--------+----+----+------ - 6 | 6 | 00006 | Wed Jan 07 00:00:00 1970 | 6 | 6 | foo | 6 | 6 | 00006 | Wed Jan 07 00:00:00 1970 | 6 | 6 | foo | 6 | 7 | AAA006 | 6 | 7 | AAA006 | 6 | 6 | 0006 - 16 | 6 | 00016 | Sat Jan 17 00:00:00 1970 | 6 | 6 | foo | 16 | 6 | 00016 | Sat Jan 17 00:00:00 1970 | 6 | 6 | foo | 6 | 7 | AAA006 | 6 | 7 | AAA006 | 6 | 6 | 0006 - 26 | 6 | 00026 | Tue Jan 27 00:00:00 1970 | 6 | 6 | foo | 26 | 6 | 00026 | Tue Jan 27 00:00:00 1970 | 6 | 6 | foo | 6 | 7 | AAA006 | 6 | 7 | AAA006 | 6 | 6 | 0006 - 36 | 6 | 00036 | Fri Feb 06 00:00:00 1970 | 6 | 6 | foo | 36 | 6 | 00036 | Fri Feb 06 00:00:00 1970 | 6 | 6 | foo | 6 | 7 | AAA006 | 6 | 7 | AAA006 | 6 | 6 | 0006 - 46 | 6 | 00046 | Mon Feb 16 00:00:00 1970 | 6 | 6 | foo | 46 | 6 | 00046 | Mon Feb 16 00:00:00 1970 | 6 | 6 | foo | 6 | 7 | AAA006 | 6 | 7 | AAA006 | 6 | 6 | 0006 - 56 | 6 | 00056 | Thu Feb 26 00:00:00 1970 | 6 | 6 | foo | 56 | 6 | 00056 | Thu Feb 26 00:00:00 1970 | 6 | 6 | foo | 6 | 7 | AAA006 | 6 | 7 | AAA006 | 6 | 6 | 0006 - 66 | 6 | 00066 | Sun Mar 08 00:00:00 1970 | 6 | 6 | foo | 66 | 6 | 00066 | Sun Mar 08 00:00:00 1970 | 6 | 6 | foo | 6 | 7 | AAA006 | 6 | 7 | AAA006 | 6 | 6 | 0006 - 76 | 6 | 00076 | Wed Mar 18 00:00:00 1970 | 6 | 6 | foo | 76 | 6 | 00076 | Wed Mar 18 00:00:00 1970 | 6 | 6 | foo | 6 | 7 | AAA006 | 6 | 7 | AAA006 | 6 | 6 | 0006 - 86 | 6 | 00086 | Sat Mar 28 00:00:00 1970 | 6 | 6 | foo | 86 | 6 | 00086 | Sat Mar 28 00:00:00 1970 | 6 | 6 | foo | 6 | 7 | AAA006 | 6 | 7 | AAA006 | 6 | 6 | 0006 - 96 | 6 | 00096 | Tue Apr 07 00:00:00 1970 | 6 | 6 | foo | 96 | 6 | 00096 | Tue Apr 07 00:00:00 1970 | 6 | 6 | foo | 6 | 7 | AAA006 | 6 | 7 | AAA006 | 6 | 6 | 0006 + c1 | c2 | c3 | time | c6 | c7 | c8 | c1 | c2 | c3 | time | c6 | c7 | c8 | c1 | c2 | c3 | c1 | c2 | c3 | c1 | c2 | c3 +----+----+-------+------------------------------+----+------------+-----+----+----+-------+------------------------------+----+------------+-----+----+----+--------+----+----+--------+----+----+------ + 6 | 6 | 00006 | Wed Jan 07 00:00:00 1970 PST | 6 | 6 | foo | 6 | 6 | 00006 | Wed Jan 07 00:00:00 1970 PST | 6 | 6 | foo | 6 | 7 | AAA006 | 6 | 7 | AAA006 | 6 | 6 | 0006 + 16 | 6 | 00016 | Sat Jan 17 00:00:00 1970 PST | 6 | 6 | foo | 16 | 6 | 00016 | Sat Jan 17 00:00:00 1970 PST | 6 | 6 | foo | 6 | 7 | AAA006 | 6 | 7 | AAA006 | 6 | 6 | 0006 + 26 | 6 | 00026 | Tue Jan 27 00:00:00 1970 PST | 6 | 6 | foo | 26 | 6 | 00026 | Tue Jan 27 00:00:00 1970 PST | 6 | 6 | foo | 6 | 7 | AAA006 | 6 | 7 | AAA006 | 6 | 6 | 0006 + 36 | 6 | 00036 | Fri Feb 06 00:00:00 1970 PST | 6 | 6 | foo | 36 | 6 | 00036 | Fri Feb 06 00:00:00 1970 PST | 6 | 6 | foo | 6 | 7 | AAA006 | 6 | 7 | AAA006 | 6 | 6 | 0006 + 46 | 6 | 00046 | Mon Feb 16 00:00:00 1970 PST | 6 | 6 | foo | 46 | 6 | 00046 | Mon Feb 16 00:00:00 1970 PST | 6 | 6 | foo | 6 | 7 | AAA006 | 6 | 7 | AAA006 | 6 | 6 | 0006 + 56 | 6 | 00056 | Thu Feb 26 00:00:00 1970 PST | 6 | 6 | foo | 56 | 6 | 00056 | Thu Feb 26 00:00:00 1970 PST | 6 | 6 | foo | 6 | 7 | AAA006 | 6 | 7 | AAA006 | 6 | 6 | 0006 + 66 | 6 | 00066 | Sun Mar 08 00:00:00 1970 PST | 6 | 6 | foo | 66 | 6 | 00066 | Sun Mar 08 00:00:00 1970 PST | 6 | 6 | foo | 6 | 7 | AAA006 | 6 | 7 | AAA006 | 6 | 6 | 0006 + 76 | 6 | 00076 | Wed Mar 18 00:00:00 1970 PST | 6 | 6 | foo | 76 | 6 | 00076 | Wed Mar 18 00:00:00 1970 PST | 6 | 6 | foo | 6 | 7 | AAA006 | 6 | 7 | AAA006 | 6 | 6 | 0006 + 86 | 6 | 00086 | Sat Mar 28 00:00:00 1970 PST | 6 | 6 | foo | 86 | 6 | 00086 | Sat Mar 28 00:00:00 1970 PST | 6 | 6 | foo | 6 | 7 | AAA006 | 6 | 7 | AAA006 | 6 | 6 | 0006 + 96 | 6 | 00096 | Tue Apr 07 00:00:00 1970 PST | 6 | 6 | foo | 96 | 6 | 00096 | Tue Apr 07 00:00:00 1970 PST | 6 | 6 | foo | 6 | 7 | AAA006 | 6 | 7 | AAA006 | 6 | 6 | 0006 (10 rows) RESET enable_nestloop; @@ -3726,9 +3726,9 @@ select array_agg(time order by c1 desc) from ft2 where c2 = 6 and c1 < 50; --Testcase 228: select array_agg(time order by c1 desc) from ft2 where c2 = 6 and c1 < 50; - array_agg ------------------------------------------------------------------------------------------------------------------------------------------- - {"Mon Feb 16 00:00:00 1970","Fri Feb 06 00:00:00 1970","Tue Jan 27 00:00:00 1970","Sat Jan 17 00:00:00 1970","Wed Jan 07 00:00:00 1970"} + array_agg +-------------------------------------------------------------------------------------------------------------------------------------------------------------- + {"Mon Feb 16 00:00:00 1970 PST","Fri Feb 06 00:00:00 1970 PST","Tue Jan 27 00:00:00 1970 PST","Sat Jan 17 00:00:00 1970 PST","Wed Jan 07 00:00:00 1970 PST"} (1 row) -- DISTINCT within aggregate @@ -4869,16 +4869,16 @@ EXPLAIN (VERBOSE, COSTS OFF) EXECUTE st2(10, 20); --Testcase 310: EXECUTE st2(10, 20); - c1 | c2 | c3 | time | c6 | c7 | c8 -----+----+-------+--------------------------+----+------------+----- - 16 | 6 | 00016 | Sat Jan 17 00:00:00 1970 | 6 | 6 | foo + c1 | c2 | c3 | time | c6 | c7 | c8 +----+----+-------+------------------------------+----+------------+----- + 16 | 6 | 00016 | Sat Jan 17 00:00:00 1970 PST | 6 | 6 | foo (1 row) --Testcase 311: EXECUTE st2(101, 121); - c1 | c2 | c3 | time | c6 | c7 | c8 ------+----+-------+--------------------------+----+------------+----- - 116 | 6 | 00116 | Sat Jan 17 00:00:00 1970 | 6 | 6 | foo + c1 | c2 | c3 | time | c6 | c7 | c8 +-----+----+-------+------------------------------+----+------------+----- + 116 | 6 | 00116 | Sat Jan 17 00:00:00 1970 PST | 6 | 6 | foo (1 row) -- subquery using immutable function (can be sent to remote) @@ -4907,9 +4907,9 @@ EXPLAIN (VERBOSE, COSTS OFF) EXECUTE st3(10, 20); --Testcase 314: EXECUTE st3(10, 20); - c1 | c2 | c3 | time | c6 | c7 | c8 -----+----+-------+--------------------------+----+------------+----- - 16 | 6 | 00016 | Sat Jan 17 00:00:00 1970 | 6 | 6 | foo + c1 | c2 | c3 | time | c6 | c7 | c8 +----+----+-------+------------------------------+----+------------+----- + 16 | 6 | 00016 | Sat Jan 17 00:00:00 1970 PST | 6 | 6 | foo (1 row) --Testcase 315: @@ -5035,9 +5035,9 @@ EXPLAIN (VERBOSE, COSTS OFF) EXECUTE st5('foo', 1); --Testcase 330: EXECUTE st5('foo', 1); - c1 | c2 | c3 | time | c6 | c7 | c8 -----+----+-------+--------------------------+----+------------+----- - 1 | 1 | 00001 | Fri Jan 02 00:00:00 1970 | 1 | 1 | foo + c1 | c2 | c3 | time | c6 | c7 | c8 +----+----+-------+------------------------------+----+------------+----- + 1 | 1 | 00001 | Fri Jan 02 00:00:00 1970 PST | 1 | 1 | foo (1 row) -- altering FDW options requires replanning @@ -5056,11 +5056,11 @@ EXPLAIN (VERBOSE, COSTS OFF) EXECUTE st6; PREPARE st7 AS INSERT INTO ft1 (c1,c2,c3) VALUES (1001,101,'foo'); --Testcase 334: EXPLAIN (VERBOSE, COSTS OFF) EXECUTE st7; - QUERY PLAN ------------------------------------------------------------------------------------------------------------------------------------------------------------- + QUERY PLAN +--------------------------------------------------------------------------------------------------------------------------------------------------------- Insert on public.ft1 -> Result - Output: NULL::integer, 1001, 101, 'foo'::text, NULL::timestamp without time zone, NULL::character varying, 'ft1 '::character(10), NULL::text + Output: NULL::integer, 1001, 101, 'foo'::text, NULL::timestamp with time zone, NULL::character varying, 'ft1 '::character(10), NULL::text (3 rows) --Testcase 335: @@ -5077,26 +5077,26 @@ EXPLAIN (VERBOSE, COSTS OFF) EXECUTE st6; --Testcase 337: EXECUTE st6; - c1 | c2 | c3 | time | c6 | c7 | c8 -----+----+-------+--------------------------+----+------------+----- - 1 | 1 | 00001 | Fri Jan 02 00:00:00 1970 | 1 | 1 | foo - 2 | 2 | 00002 | Sat Jan 03 00:00:00 1970 | 2 | 2 | foo - 3 | 3 | 00003 | Sun Jan 04 00:00:00 1970 | 3 | 3 | foo - 4 | 4 | 00004 | Mon Jan 05 00:00:00 1970 | 4 | 4 | foo - 5 | 5 | 00005 | Tue Jan 06 00:00:00 1970 | 5 | 5 | foo - 6 | 6 | 00006 | Wed Jan 07 00:00:00 1970 | 6 | 6 | foo - 7 | 7 | 00007 | Thu Jan 08 00:00:00 1970 | 7 | 7 | foo - 8 | 8 | 00008 | Fri Jan 09 00:00:00 1970 | 8 | 8 | foo - 9 | 9 | 00009 | Sat Jan 10 00:00:00 1970 | 9 | 9 | foo + c1 | c2 | c3 | time | c6 | c7 | c8 +----+----+-------+------------------------------+----+------------+----- + 1 | 1 | 00001 | Fri Jan 02 00:00:00 1970 PST | 1 | 1 | foo + 2 | 2 | 00002 | Sat Jan 03 00:00:00 1970 PST | 2 | 2 | foo + 3 | 3 | 00003 | Sun Jan 04 00:00:00 1970 PST | 3 | 3 | foo + 4 | 4 | 00004 | Mon Jan 05 00:00:00 1970 PST | 4 | 4 | foo + 5 | 5 | 00005 | Tue Jan 06 00:00:00 1970 PST | 5 | 5 | foo + 6 | 6 | 00006 | Wed Jan 07 00:00:00 1970 PST | 6 | 6 | foo + 7 | 7 | 00007 | Thu Jan 08 00:00:00 1970 PST | 7 | 7 | foo + 8 | 8 | 00008 | Fri Jan 09 00:00:00 1970 PST | 8 | 8 | foo + 9 | 9 | 00009 | Sat Jan 10 00:00:00 1970 PST | 9 | 9 | foo (9 rows) --Testcase 338: EXPLAIN (VERBOSE, COSTS OFF) EXECUTE st7; - QUERY PLAN ------------------------------------------------------------------------------------------------------------------------------------------------------------- + QUERY PLAN +--------------------------------------------------------------------------------------------------------------------------------------------------------- Insert on public.ft1 -> Result - Output: NULL::integer, 1001, 101, 'foo'::text, NULL::timestamp without time zone, NULL::character varying, 'ft1 '::character(10), NULL::text + Output: NULL::integer, 1001, 101, 'foo'::text, NULL::timestamp with time zone, NULL::character varying, 'ft1 '::character(10), NULL::text (3 rows) --Testcase 339: @@ -5163,9 +5163,9 @@ SELECT * FROM ft1 t1 WHERE t1.tableoid = 'pg_class'::regclass LIMIT 1; --Testcase 345: SELECT * FROM ft1 t1 WHERE t1.tableoid = 'ft1'::regclass ORDER BY c1 LIMIT 1; - c1 | c2 | c3 | time | c6 | c7 | c8 -----+----+-------+--------------------------+----+------------+----- - 1 | 1 | 00001 | Fri Jan 02 00:00:00 1970 | 1 | 1 | foo + c1 | c2 | c3 | time | c6 | c7 | c8 +----+----+-------+------------------------------+----+------------+----- + 1 | 1 | 00001 | Fri Jan 02 00:00:00 1970 PST | 1 | 1 | foo (1 row) --Testcase 346: @@ -5180,9 +5180,9 @@ SELECT tableoid::regclass, * FROM ft1 t1 LIMIT 1; --Testcase 347: SELECT tableoid::regclass, * FROM ft1 t1 ORDER BY c1 LIMIT 1; - tableoid | c1 | c2 | c3 | time | c6 | c7 | c8 -----------+----+----+-------+--------------------------+----+------------+----- - ft1 | 1 | 1 | 00001 | Fri Jan 02 00:00:00 1970 | 1 | 1 | foo + tableoid | c1 | c2 | c3 | time | c6 | c7 | c8 +----------+----+----+-------+------------------------------+----+------------+----- + ft1 | 1 | 1 | 00001 | Fri Jan 02 00:00:00 1970 PST | 1 | 1 | foo (1 row) --Testcase 348: @@ -5214,9 +5214,9 @@ SELECT ctid, * FROM ft1 t1 LIMIT 1; --Testcase 351: SELECT ctid, * FROM ft1 t1 ORDER BY c1 LIMIT 1; - ctid | c1 | c2 | c3 | time | c6 | c7 | c8 -----------------+----+----+-------+--------------------------+----+------------+----- - (4294967295,0) | 1 | 1 | 00001 | Fri Jan 02 00:00:00 1970 | 1 | 1 | foo + ctid | c1 | c2 | c3 | time | c6 | c7 | c8 +----------------+----+----+-------+------------------------------+----+------------+----- + (4294967295,0) | 1 | 1 | 00001 | Fri Jan 02 00:00:00 1970 PST | 1 | 1 | foo (1 row) -- =================================================================== @@ -5408,11 +5408,11 @@ explain (verbose, costs off) select * from ft3 f, loct3 l --Testcase 372: EXPLAIN (verbose, costs off) INSERT INTO ft2 (c1,c2,c3) SELECT c1+1000,c2+100, c3 || c3 FROM ft2 ORDER BY c1 LIMIT 20; - QUERY PLAN -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- + QUERY PLAN +---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- Insert on public.ft2 -> Subquery Scan on "*SELECT*" - Output: "*SELECT*"."?column?", "*SELECT*"."?column?_1", NULL::integer, "*SELECT*"."?column?_2", NULL::timestamp without time zone, NULL::character varying, 'ft2 '::character(10), NULL::text + Output: "*SELECT*"."?column?", "*SELECT*"."?column?_1", NULL::integer, "*SELECT*"."?column?_2", NULL::timestamp with time zone, NULL::character varying, 'ft2 '::character(10), NULL::text -> Limit Output: ((ft2_1.c1 + 1000)), ((ft2_1.c2 + 100)), ((ft2_1.c3 || ft2_1.c3)), ft2_1.c1 -> Sort @@ -6426,11 +6426,11 @@ SELECT c1,c2,c3 FROM ft2 ORDER BY c1; --Testcase 384: EXPLAIN (verbose, costs off) INSERT INTO ft2 (c1,c2,c3) VALUES (1200,999,'foo'); - QUERY PLAN ------------------------------------------------------------------------------------------------------------------------------------------------------------- + QUERY PLAN +--------------------------------------------------------------------------------------------------------------------------------------------------------- Insert on public.ft2 -> Result - Output: 1200, 999, NULL::integer, 'foo'::text, NULL::timestamp without time zone, NULL::character varying, 'ft2 '::character(10), NULL::text + Output: 1200, 999, NULL::integer, 'foo'::text, NULL::timestamp with time zone, NULL::character varying, 'ft2 '::character(10), NULL::text (3 rows) --Testcase 385: @@ -8786,7 +8786,7 @@ CREATE FOREIGN TABLE ft1_nopw ( c2 int NOT NULL, c3 text, c4 timestamptz, - c5 timestamp, + c5 timestamptz, c6 varchar(10), c7 char(10) default 'ft1', c8 user_enum diff --git a/expected/12.12/extra/insert.out b/expected/13.12/extra/insert.out similarity index 100% rename from expected/12.12/extra/insert.out rename to expected/13.12/extra/insert.out diff --git a/expected/13.8/extra/join.out b/expected/13.12/extra/join.out similarity index 100% rename from expected/13.8/extra/join.out rename to expected/13.12/extra/join.out diff --git a/expected/13.8/extra/limit.out b/expected/13.12/extra/limit.out similarity index 100% rename from expected/13.8/extra/limit.out rename to expected/13.12/extra/limit.out diff --git a/expected/13.8/extra/prepare.out b/expected/13.12/extra/prepare.out similarity index 100% rename from expected/13.8/extra/prepare.out rename to expected/13.12/extra/prepare.out diff --git a/expected/13.8/extra/select.out b/expected/13.12/extra/select.out similarity index 100% rename from expected/13.8/extra/select.out rename to expected/13.12/extra/select.out diff --git a/expected/12.12/extra/select_having.out b/expected/13.12/extra/select_having.out similarity index 100% rename from expected/12.12/extra/select_having.out rename to expected/13.12/extra/select_having.out diff --git a/expected/13.8/influxdb_fdw.out b/expected/13.12/influxdb_fdw.out similarity index 92% rename from expected/13.8/influxdb_fdw.out rename to expected/13.12/influxdb_fdw.out index de81a38..eba36bd 100644 --- a/expected/13.8/influxdb_fdw.out +++ b/expected/13.12/influxdb_fdw.out @@ -1128,14 +1128,14 @@ SELECT * FROM t5; SELECT * FROM public.influxdb_fdw_version(); influxdb_fdw_version ---------------------- - 20000 + 20100 (1 row) --Testcase 146: SELECT influxdb_fdw_version(); influxdb_fdw_version ---------------------- - 20000 + 20100 (1 row) --Test pushdown LIMIT...OFFSET @@ -1618,6 +1618,122 @@ SELECT * FROM tmp_time; 2100-01-01 01:01:01 | 04:05:06 | | (6 rows) +-- Type mis-match +--Testcase 212: +CREATE FOREIGN TABLE datatype_test ( + time timestamp with time zone, + tag1 text, + tag2 text, + value1 int, + value2 text +) SERVER server1 OPTIONS (table 'datatype_test', tags 'tag1,tag2'); +--Testcase 213: +INSERT INTO datatype_test (tag1, tag2, value1, value2) VALUES ('time', '2021-02-02T00:00:01Z', '1', '2021-02-05T00:00:00Z'); +--Testcase 214: +INSERT INTO datatype_test (tag1, tag2, value1, value2) VALUES ('time', '2022-02-02T00:00:01Z', '2', '2022-02-05T00:00:00Z'); +--Testcase 215: +SELECT tag1, tag2, value1, value2 FROM datatype_test; + tag1 | tag2 | value1 | value2 +------+----------------------+--------+---------------------- + time | 2021-02-02T00:00:01Z | 1 | 2021-02-05T00:00:00Z + time | 2022-02-02T00:00:01Z | 2 | 2022-02-05T00:00:00Z +(2 rows) + +-- Using text as timestamp +--Testcase 216: +ALTER FOREIGN TABLE datatype_test ALTER COLUMN tag2 TYPE timestamptz; +--Testcase 217: +ALTER FOREIGN TABLE datatype_test ALTER COLUMN value2 TYPE timestamptz; +-- SELECT OK without filter +--Testcase 218: +SELECT tag1, tag2, value1, value2 FROM datatype_test; + tag1 | tag2 | value1 | value2 +------+------------------------+--------+------------------------ + time | 2021-02-02 09:00:01+09 | 1 | 2021-02-05 09:00:00+09 + time | 2022-02-02 09:00:01+09 | 2 | 2022-02-05 09:00:00+09 +(2 rows) + +-- SELECT with timestamp filter, WHERE clause is pushed down +-- InfluxDB cannot compare correctly, 0 row returned +--Testcase 219: +EXPLAIN (VERBOSE, COSTS OFF) +SELECT tag1, tag2, value1, value2 FROM datatype_test WHERE tag2 > '2021-02-02 00:00:01+00'; + QUERY PLAN +--------------------------------------------------------------------------------------------------------------------------- + Foreign Scan on public.datatype_test + Output: tag1, tag2, value1, value2 + InfluxDB query: SELECT "tag1", "tag2", "value1", "value2" FROM "datatype_test" WHERE (("tag2" > '2021-02-02 00:00:01')) +(3 rows) + +--Testcase 220: +SELECT tag1, tag2, value1, value2 FROM datatype_test WHERE tag2 > '2021-02-02 00:00:01+00'; + tag1 | tag2 | value1 | value2 +------+------+--------+-------- +(0 rows) + +--Testcase 221: +EXPLAIN (VERBOSE, COSTS OFF) +SELECT tag1, tag2, value1, value2 FROM datatype_test WHERE value2 > '2021-02-05 00:00:00+00'; + QUERY PLAN +----------------------------------------------------------------------------------------------------------------------------- + Foreign Scan on public.datatype_test + Output: tag1, tag2, value1, value2 + InfluxDB query: SELECT "tag1", "tag2", "value1", "value2" FROM "datatype_test" WHERE (("value2" > '2021-02-05 00:00:00')) +(3 rows) + +--Testcase 222: +SELECT tag1, tag2, value1, value2 FROM datatype_test WHERE value2 > '2021-02-05 00:00:00+00'; + tag1 | tag2 | value1 | value2 +------+------+--------+-------- +(0 rows) + +--Testcase 223: +ALTER FOREIGN TABLE datatype_test ALTER COLUMN tag2 TYPE text; +--Testcase 224: +ALTER FOREIGN TABLE datatype_test ALTER COLUMN value2 TYPE text; +-- uses explicit cast, WHERE clause is not pushed down +-- compared correctly by postgres, 1 row returned +--Testcase 225: +EXPLAIN (VERBOSE, COSTS OFF) +SELECT tag1, tag2, value1, value2 FROM datatype_test WHERE tag2::timestamptz > '2021-02-02 00:00:01+00'; + QUERY PLAN +----------------------------------------------------------------------------------------------------------------- + Foreign Scan on public.datatype_test + Output: tag1, tag2, value1, value2 + Filter: ((datatype_test.tag2)::timestamp with time zone > '2021-02-02 09:00:01+09'::timestamp with time zone) + InfluxDB query: SELECT "tag1", "tag2", "value1", "value2" FROM "datatype_test" +(4 rows) + +--Testcase 226: +SELECT tag1, tag2, value1, value2 FROM datatype_test WHERE tag2::timestamptz > '2021-02-02 00:00:01+00'; + tag1 | tag2 | value1 | value2 +------+----------------------+--------+---------------------- + time | 2022-02-02T00:00:01Z | 2 | 2022-02-05T00:00:00Z +(1 row) + +--Testcase 227: +EXPLAIN (VERBOSE, COSTS OFF) +SELECT tag1, tag2, value1, value2 FROM datatype_test WHERE value2::timestamptz > '2021-02-05 00:00:00+00'; + QUERY PLAN +------------------------------------------------------------------------------------------------------------------- + Foreign Scan on public.datatype_test + Output: tag1, tag2, value1, value2 + Filter: ((datatype_test.value2)::timestamp with time zone > '2021-02-05 09:00:00+09'::timestamp with time zone) + InfluxDB query: SELECT "tag1", "tag2", "value1", "value2" FROM "datatype_test" +(4 rows) + +--Testcase 228: +SELECT tag1, tag2, value1, value2 FROM datatype_test WHERE value2::timestamptz > '2021-02-05 00:00:00+00'; + tag1 | tag2 | value1 | value2 +------+----------------------+--------+---------------------- + time | 2022-02-02T00:00:01Z | 2 | 2022-02-05T00:00:00Z +(1 row) + +-- clean-up +--Testcase 229: +DELETE FROM datatype_test; +--Testcase 230: +DROP FOREIGN TABLE datatype_test; -- Recover data :RECOVER_INIT_TXT_DROP_BUCKET; :RECOVER_INIT_TXT_CREATE_BUCKET; diff --git a/expected/12.12/option.out b/expected/13.12/option.out similarity index 100% rename from expected/12.12/option.out rename to expected/13.12/option.out diff --git a/expected/13.8/schemaless/add_fields.out b/expected/13.12/schemaless/add_fields.out similarity index 100% rename from expected/13.8/schemaless/add_fields.out rename to expected/13.12/schemaless/add_fields.out diff --git a/expected/13.8/schemaless/add_multi_key.out b/expected/13.12/schemaless/add_multi_key.out similarity index 100% rename from expected/13.8/schemaless/add_multi_key.out rename to expected/13.12/schemaless/add_multi_key.out diff --git a/expected/13.8/schemaless/add_tags.out b/expected/13.12/schemaless/add_tags.out similarity index 100% rename from expected/13.8/schemaless/add_tags.out rename to expected/13.12/schemaless/add_tags.out diff --git a/expected/12.12/schemaless/aggregate.out b/expected/13.12/schemaless/aggregate.out similarity index 100% rename from expected/12.12/schemaless/aggregate.out rename to expected/13.12/schemaless/aggregate.out diff --git a/expected/13.8/schemaless/extra/aggregates.out b/expected/13.12/schemaless/extra/aggregates.out similarity index 100% rename from expected/13.8/schemaless/extra/aggregates.out rename to expected/13.12/schemaless/extra/aggregates.out diff --git a/expected/13.8/schemaless/extra/influxdb_fdw_post.out b/expected/13.12/schemaless/extra/influxdb_fdw_post.out similarity index 90% rename from expected/13.8/schemaless/extra/influxdb_fdw_post.out rename to expected/13.12/schemaless/extra/influxdb_fdw_post.out index b042d63..a2e8e86 100644 --- a/expected/13.8/schemaless/extra/influxdb_fdw_post.out +++ b/expected/13.12/schemaless/extra/influxdb_fdw_post.out @@ -26,23 +26,23 @@ CREATE TYPE user_enum AS ENUM ('foo', 'bar', 'buz'); --Testcase 9: CREATE SCHEMA "S 1"; --Testcase 10: -CREATE FOREIGN TABLE "S 1"."T 0" (time timestamp, tags jsonb OPTIONS(tags 'true'), fields jsonb OPTIONS(fields 'true')) SERVER influxdb_svr OPTIONS (table 'T0', tags 'c3', schemaless 'true'); +CREATE FOREIGN TABLE "S 1"."T 0" (time timestamptz, tags jsonb OPTIONS(tags 'true'), fields jsonb OPTIONS(fields 'true')) SERVER influxdb_svr OPTIONS (table 'T0', tags 'c3', schemaless 'true'); CREATE FOREIGN TABLE "S 1".s1t0 ( "C 1" int NOT NULL, c2 int NOT NULL, c3 text, - time timestamp, + time timestamptz, c6 varchar(10), c7 char(10), c8 text ) SERVER influxdb_svr OPTIONS (table 'T0', tags 'c3'); --Testcase 11: -CREATE FOREIGN TABLE "S 1"."T 1" (time timestamp, tags jsonb OPTIONS(tags 'true'), fields jsonb OPTIONS(fields 'true')) SERVER influxdb_svr OPTIONS (table 'T1', tags 'c3', schemaless 'true'); +CREATE FOREIGN TABLE "S 1"."T 1" (time timestamptz, tags jsonb OPTIONS(tags 'true'), fields jsonb OPTIONS(fields 'true')) SERVER influxdb_svr OPTIONS (table 'T1', tags 'c3', schemaless 'true'); CREATE FOREIGN TABLE "S 1".s1t1 ( "C 1" int NOT NULL, c2 int NOT NULL, c3 text, - time timestamp, + time timestamptz, c6 varchar(10), c7 char(10), c8 text @@ -77,7 +77,7 @@ INSERT INTO "S 1".s1t1 SELECT id, id % 10, to_char(id, 'FM00000'), - '1970-01-01'::timestamp + ((id % 100) || ' days')::interval, + '1970-01-01'::timestamptz + ((id % 100) || ' days')::interval, id % 10, id % 10, 'foo'::text @@ -111,26 +111,26 @@ DELETE FROM "S 1".s1t4 WHERE c1 % 3 != 0; -- delete for outer join tests -- create foreign tables -- =================================================================== --Testcase 21: -CREATE FOREIGN TABLE ft1 (time timestamp, tags jsonb OPTIONS(tags 'true'), fields jsonb OPTIONS(fields 'true')) SERVER influxdb_svr OPTIONS (schemaless 'true'); +CREATE FOREIGN TABLE ft1 (time timestamptz, tags jsonb OPTIONS(tags 'true'), fields jsonb OPTIONS(fields 'true')) SERVER influxdb_svr OPTIONS (schemaless 'true'); CREATE FOREIGN TABLE ft1_nsc ( c0 int, c1 int NOT NULL, c2 int NOT NULL, c3 text, - time timestamp, + time timestamptz, c6 varchar(10), c7 char(10) default 'ft1', c8 text ) SERVER influxdb_svr; ALTER FOREIGN TABLE ft1_nsc DROP COLUMN c0; --Testcase 22: -CREATE FOREIGN TABLE ft2 (time timestamp, tags jsonb OPTIONS(tags 'true'), fields jsonb OPTIONS(fields 'true')) SERVER influxdb_svr OPTIONS (schemaless 'true'); +CREATE FOREIGN TABLE ft2 (time timestamptz, tags jsonb OPTIONS(tags 'true'), fields jsonb OPTIONS(fields 'true')) SERVER influxdb_svr OPTIONS (schemaless 'true'); CREATE FOREIGN TABLE ft2_nsc ( c1 int NOT NULL, c2 int NOT NULL, cx int, c3 text, - time timestamp, + time timestamptz, c6 varchar(10), c7 char(10) default 'ft2', c8 text @@ -232,9 +232,9 @@ ALTER FOREIGN TABLE ft2_nsc ALTER COLUMN c1 OPTIONS (column_name 'C 1'); \set VERBOSITY terse --Testcase 27: SELECT tags->>'c3' c3, time FROM ft1 ORDER BY tags->>'c3', (fields->>'C 1')::int LIMIT 1; -- should work - c3 | time --------+-------------------------- - 00001 | Fri Jan 02 00:00:00 1970 + c3 | time +-------+------------------------------ + 00001 | Fri Jan 02 00:00:00 1970 PST (1 row) ALTER SERVER influxdb_svr OPTIONS (SET dbname 'no such database'); @@ -249,9 +249,9 @@ DO $d$ $d$; --Testcase 29: SELECT tags->>'c3' c3, time FROM ft1 ORDER BY tags->>'c3', (fields->>'C 1')::int LIMIT 1; -- should work again - c3 | time --------+-------------------------- - 00001 | Fri Jan 02 00:00:00 1970 + c3 | time +-------+------------------------------ + 00001 | Fri Jan 02 00:00:00 1970 PST (1 row) \set VERBOSITY default @@ -271,18 +271,18 @@ EXPLAIN (COSTS OFF) SELECT * FROM ft1 ORDER BY tags->>'c3', (fields->>'C 1')::in --Testcase 31: SELECT * FROM ft1 ORDER BY tags->>'c3', (fields->>'C 1')::int OFFSET 100 LIMIT 10; - time | tags | fields ---------------------------+-----------------+----------------------------------------------------------------------- - Fri Jan 02 00:00:00 1970 | {"c3": "00101"} | {"c2": "1", "c6": "1", "c7": "1 ", "c8": "foo", "C 1": "101"} - Sat Jan 03 00:00:00 1970 | {"c3": "00102"} | {"c2": "2", "c6": "2", "c7": "2 ", "c8": "foo", "C 1": "102"} - Sun Jan 04 00:00:00 1970 | {"c3": "00103"} | {"c2": "3", "c6": "3", "c7": "3 ", "c8": "foo", "C 1": "103"} - Mon Jan 05 00:00:00 1970 | {"c3": "00104"} | {"c2": "4", "c6": "4", "c7": "4 ", "c8": "foo", "C 1": "104"} - Tue Jan 06 00:00:00 1970 | {"c3": "00105"} | {"c2": "5", "c6": "5", "c7": "5 ", "c8": "foo", "C 1": "105"} - Wed Jan 07 00:00:00 1970 | {"c3": "00106"} | {"c2": "6", "c6": "6", "c7": "6 ", "c8": "foo", "C 1": "106"} - Thu Jan 08 00:00:00 1970 | {"c3": "00107"} | {"c2": "7", "c6": "7", "c7": "7 ", "c8": "foo", "C 1": "107"} - Fri Jan 09 00:00:00 1970 | {"c3": "00108"} | {"c2": "8", "c6": "8", "c7": "8 ", "c8": "foo", "C 1": "108"} - Sat Jan 10 00:00:00 1970 | {"c3": "00109"} | {"c2": "9", "c6": "9", "c7": "9 ", "c8": "foo", "C 1": "109"} - Sun Jan 11 00:00:00 1970 | {"c3": "00110"} | {"c2": "0", "c6": "0", "c7": "0 ", "c8": "foo", "C 1": "110"} + time | tags | fields +------------------------------+-----------------+----------------------------------------------------------------------- + Fri Jan 02 00:00:00 1970 PST | {"c3": "00101"} | {"c2": "1", "c6": "1", "c7": "1 ", "c8": "foo", "C 1": "101"} + Sat Jan 03 00:00:00 1970 PST | {"c3": "00102"} | {"c2": "2", "c6": "2", "c7": "2 ", "c8": "foo", "C 1": "102"} + Sun Jan 04 00:00:00 1970 PST | {"c3": "00103"} | {"c2": "3", "c6": "3", "c7": "3 ", "c8": "foo", "C 1": "103"} + Mon Jan 05 00:00:00 1970 PST | {"c3": "00104"} | {"c2": "4", "c6": "4", "c7": "4 ", "c8": "foo", "C 1": "104"} + Tue Jan 06 00:00:00 1970 PST | {"c3": "00105"} | {"c2": "5", "c6": "5", "c7": "5 ", "c8": "foo", "C 1": "105"} + Wed Jan 07 00:00:00 1970 PST | {"c3": "00106"} | {"c2": "6", "c6": "6", "c7": "6 ", "c8": "foo", "C 1": "106"} + Thu Jan 08 00:00:00 1970 PST | {"c3": "00107"} | {"c2": "7", "c6": "7", "c7": "7 ", "c8": "foo", "C 1": "107"} + Fri Jan 09 00:00:00 1970 PST | {"c3": "00108"} | {"c2": "8", "c6": "8", "c7": "8 ", "c8": "foo", "C 1": "108"} + Sat Jan 10 00:00:00 1970 PST | {"c3": "00109"} | {"c2": "9", "c6": "9", "c7": "9 ", "c8": "foo", "C 1": "109"} + Sun Jan 11 00:00:00 1970 PST | {"c3": "00110"} | {"c2": "0", "c6": "0", "c7": "0 ", "c8": "foo", "C 1": "110"} (10 rows) -- single table with alias - also test that tableoid sort is not pushed to remote side @@ -302,18 +302,18 @@ EXPLAIN (VERBOSE, COSTS OFF) SELECT * FROM ft1 t1 ORDER BY t1.tags->>'c3', (t1.f --Testcase 33: SELECT * FROM ft1 t1 ORDER BY t1.tags->>'c3', (t1.fields->>'C 1')::int, t1.tableoid OFFSET 100 LIMIT 10; - time | tags | fields ---------------------------+-----------------+----------------------------------------------------------------------- - Fri Jan 02 00:00:00 1970 | {"c3": "00101"} | {"c2": "1", "c6": "1", "c7": "1 ", "c8": "foo", "C 1": "101"} - Sat Jan 03 00:00:00 1970 | {"c3": "00102"} | {"c2": "2", "c6": "2", "c7": "2 ", "c8": "foo", "C 1": "102"} - Sun Jan 04 00:00:00 1970 | {"c3": "00103"} | {"c2": "3", "c6": "3", "c7": "3 ", "c8": "foo", "C 1": "103"} - Mon Jan 05 00:00:00 1970 | {"c3": "00104"} | {"c2": "4", "c6": "4", "c7": "4 ", "c8": "foo", "C 1": "104"} - Tue Jan 06 00:00:00 1970 | {"c3": "00105"} | {"c2": "5", "c6": "5", "c7": "5 ", "c8": "foo", "C 1": "105"} - Wed Jan 07 00:00:00 1970 | {"c3": "00106"} | {"c2": "6", "c6": "6", "c7": "6 ", "c8": "foo", "C 1": "106"} - Thu Jan 08 00:00:00 1970 | {"c3": "00107"} | {"c2": "7", "c6": "7", "c7": "7 ", "c8": "foo", "C 1": "107"} - Fri Jan 09 00:00:00 1970 | {"c3": "00108"} | {"c2": "8", "c6": "8", "c7": "8 ", "c8": "foo", "C 1": "108"} - Sat Jan 10 00:00:00 1970 | {"c3": "00109"} | {"c2": "9", "c6": "9", "c7": "9 ", "c8": "foo", "C 1": "109"} - Sun Jan 11 00:00:00 1970 | {"c3": "00110"} | {"c2": "0", "c6": "0", "c7": "0 ", "c8": "foo", "C 1": "110"} + time | tags | fields +------------------------------+-----------------+----------------------------------------------------------------------- + Fri Jan 02 00:00:00 1970 PST | {"c3": "00101"} | {"c2": "1", "c6": "1", "c7": "1 ", "c8": "foo", "C 1": "101"} + Sat Jan 03 00:00:00 1970 PST | {"c3": "00102"} | {"c2": "2", "c6": "2", "c7": "2 ", "c8": "foo", "C 1": "102"} + Sun Jan 04 00:00:00 1970 PST | {"c3": "00103"} | {"c2": "3", "c6": "3", "c7": "3 ", "c8": "foo", "C 1": "103"} + Mon Jan 05 00:00:00 1970 PST | {"c3": "00104"} | {"c2": "4", "c6": "4", "c7": "4 ", "c8": "foo", "C 1": "104"} + Tue Jan 06 00:00:00 1970 PST | {"c3": "00105"} | {"c2": "5", "c6": "5", "c7": "5 ", "c8": "foo", "C 1": "105"} + Wed Jan 07 00:00:00 1970 PST | {"c3": "00106"} | {"c2": "6", "c6": "6", "c7": "6 ", "c8": "foo", "C 1": "106"} + Thu Jan 08 00:00:00 1970 PST | {"c3": "00107"} | {"c2": "7", "c6": "7", "c7": "7 ", "c8": "foo", "C 1": "107"} + Fri Jan 09 00:00:00 1970 PST | {"c3": "00108"} | {"c2": "8", "c6": "8", "c7": "8 ", "c8": "foo", "C 1": "108"} + Sat Jan 10 00:00:00 1970 PST | {"c3": "00109"} | {"c2": "9", "c6": "9", "c7": "9 ", "c8": "foo", "C 1": "109"} + Sun Jan 11 00:00:00 1970 PST | {"c3": "00110"} | {"c2": "0", "c6": "0", "c7": "0 ", "c8": "foo", "C 1": "110"} (10 rows) -- whole-row reference @@ -333,18 +333,18 @@ EXPLAIN (VERBOSE, COSTS OFF) SELECT t1 FROM ft1 t1 ORDER BY t1.tags->>'c3', (t1. --Testcase 35: SELECT t1 FROM ft1 t1 ORDER BY t1.tags->>'c3', (t1.fields->>'C 1')::int OFFSET 100 LIMIT 10; - t1 ------------------------------------------------------------------------------------------------------------------------------------------------- - ("Fri Jan 02 00:00:00 1970","{""c3"": ""00101""}","{""c2"": ""1"", ""c6"": ""1"", ""c7"": ""1 "", ""c8"": ""foo"", ""C 1"": ""101""}") - ("Sat Jan 03 00:00:00 1970","{""c3"": ""00102""}","{""c2"": ""2"", ""c6"": ""2"", ""c7"": ""2 "", ""c8"": ""foo"", ""C 1"": ""102""}") - ("Sun Jan 04 00:00:00 1970","{""c3"": ""00103""}","{""c2"": ""3"", ""c6"": ""3"", ""c7"": ""3 "", ""c8"": ""foo"", ""C 1"": ""103""}") - ("Mon Jan 05 00:00:00 1970","{""c3"": ""00104""}","{""c2"": ""4"", ""c6"": ""4"", ""c7"": ""4 "", ""c8"": ""foo"", ""C 1"": ""104""}") - ("Tue Jan 06 00:00:00 1970","{""c3"": ""00105""}","{""c2"": ""5"", ""c6"": ""5"", ""c7"": ""5 "", ""c8"": ""foo"", ""C 1"": ""105""}") - ("Wed Jan 07 00:00:00 1970","{""c3"": ""00106""}","{""c2"": ""6"", ""c6"": ""6"", ""c7"": ""6 "", ""c8"": ""foo"", ""C 1"": ""106""}") - ("Thu Jan 08 00:00:00 1970","{""c3"": ""00107""}","{""c2"": ""7"", ""c6"": ""7"", ""c7"": ""7 "", ""c8"": ""foo"", ""C 1"": ""107""}") - ("Fri Jan 09 00:00:00 1970","{""c3"": ""00108""}","{""c2"": ""8"", ""c6"": ""8"", ""c7"": ""8 "", ""c8"": ""foo"", ""C 1"": ""108""}") - ("Sat Jan 10 00:00:00 1970","{""c3"": ""00109""}","{""c2"": ""9"", ""c6"": ""9"", ""c7"": ""9 "", ""c8"": ""foo"", ""C 1"": ""109""}") - ("Sun Jan 11 00:00:00 1970","{""c3"": ""00110""}","{""c2"": ""0"", ""c6"": ""0"", ""c7"": ""0 "", ""c8"": ""foo"", ""C 1"": ""110""}") + t1 +---------------------------------------------------------------------------------------------------------------------------------------------------- + ("Fri Jan 02 00:00:00 1970 PST","{""c3"": ""00101""}","{""c2"": ""1"", ""c6"": ""1"", ""c7"": ""1 "", ""c8"": ""foo"", ""C 1"": ""101""}") + ("Sat Jan 03 00:00:00 1970 PST","{""c3"": ""00102""}","{""c2"": ""2"", ""c6"": ""2"", ""c7"": ""2 "", ""c8"": ""foo"", ""C 1"": ""102""}") + ("Sun Jan 04 00:00:00 1970 PST","{""c3"": ""00103""}","{""c2"": ""3"", ""c6"": ""3"", ""c7"": ""3 "", ""c8"": ""foo"", ""C 1"": ""103""}") + ("Mon Jan 05 00:00:00 1970 PST","{""c3"": ""00104""}","{""c2"": ""4"", ""c6"": ""4"", ""c7"": ""4 "", ""c8"": ""foo"", ""C 1"": ""104""}") + ("Tue Jan 06 00:00:00 1970 PST","{""c3"": ""00105""}","{""c2"": ""5"", ""c6"": ""5"", ""c7"": ""5 "", ""c8"": ""foo"", ""C 1"": ""105""}") + ("Wed Jan 07 00:00:00 1970 PST","{""c3"": ""00106""}","{""c2"": ""6"", ""c6"": ""6"", ""c7"": ""6 "", ""c8"": ""foo"", ""C 1"": ""106""}") + ("Thu Jan 08 00:00:00 1970 PST","{""c3"": ""00107""}","{""c2"": ""7"", ""c6"": ""7"", ""c7"": ""7 "", ""c8"": ""foo"", ""C 1"": ""107""}") + ("Fri Jan 09 00:00:00 1970 PST","{""c3"": ""00108""}","{""c2"": ""8"", ""c6"": ""8"", ""c7"": ""8 "", ""c8"": ""foo"", ""C 1"": ""108""}") + ("Sat Jan 10 00:00:00 1970 PST","{""c3"": ""00109""}","{""c2"": ""9"", ""c6"": ""9"", ""c7"": ""9 "", ""c8"": ""foo"", ""C 1"": ""109""}") + ("Sun Jan 11 00:00:00 1970 PST","{""c3"": ""00110""}","{""c2"": ""0"", ""c6"": ""0"", ""c7"": ""0 "", ""c8"": ""foo"", ""C 1"": ""110""}") (10 rows) -- empty result @@ -367,9 +367,9 @@ EXPLAIN (VERBOSE, COSTS OFF) SELECT * FROM ft1 t1 WHERE (t1.fields->>'C 1')::int --Testcase 38: SELECT * FROM ft1 t1 WHERE (t1.fields->>'C 1')::int = 101 AND t1.fields->>'c6' = '1' AND t1.fields->>'c7' >= '1'; - time | tags | fields ---------------------------+-----------------+----------------------------------------------------------------------- - Fri Jan 02 00:00:00 1970 | {"c3": "00101"} | {"c2": "1", "c6": "1", "c7": "1 ", "c8": "foo", "C 1": "101"} + time | tags | fields +------------------------------+-----------------+----------------------------------------------------------------------- + Fri Jan 02 00:00:00 1970 PST | {"c3": "00101"} | {"c2": "1", "c6": "1", "c7": "1 ", "c8": "foo", "C 1": "101"} (1 row) -- with FOR UPDATE/SHARE @@ -386,9 +386,9 @@ EXPLAIN (VERBOSE, COSTS OFF) SELECT * FROM ft1 t1 WHERE (fields->>'C 1')::int = --Testcase 40: SELECT * FROM ft1 t1 WHERE (fields->>'C 1')::int = 101 FOR UPDATE; - time | tags | fields ---------------------------+-----------------+----------------------------------------------------------------------- - Fri Jan 02 00:00:00 1970 | {"c3": "00101"} | {"c2": "1", "c6": "1", "c7": "1 ", "c8": "foo", "C 1": "101"} + time | tags | fields +------------------------------+-----------------+----------------------------------------------------------------------- + Fri Jan 02 00:00:00 1970 PST | {"c3": "00101"} | {"c2": "1", "c6": "1", "c7": "1 ", "c8": "foo", "C 1": "101"} (1 row) --Testcase 41: @@ -404,9 +404,9 @@ EXPLAIN (VERBOSE, COSTS OFF) SELECT * FROM ft1 t1 WHERE (fields->>'C 1')::int = --Testcase 42: SELECT * FROM ft1 t1 WHERE (fields->>'C 1')::int = 102 FOR SHARE; - time | tags | fields ---------------------------+-----------------+----------------------------------------------------------------------- - Sat Jan 03 00:00:00 1970 | {"c3": "00102"} | {"c2": "2", "c6": "2", "c7": "2 ", "c8": "foo", "C 1": "102"} + time | tags | fields +------------------------------+-----------------+----------------------------------------------------------------------- + Sat Jan 03 00:00:00 1970 PST | {"c3": "00102"} | {"c2": "2", "c6": "2", "c7": "2 ", "c8": "foo", "C 1": "102"} (1 row) -- aggregate @@ -420,43 +420,43 @@ SELECT COUNT(*) FROM ft1 t1; -- subquery --Testcase 44: SELECT * FROM ft1 t1 WHERE t1.tags->>'c3' IN (SELECT tags->>'c3' FROM ft2 t2 WHERE (fields->>'C 1')::int <= 10) ORDER BY (fields->>'C 1')::int; - time | tags | fields ---------------------------+-----------------+---------------------------------------------------------------------- - Fri Jan 02 00:00:00 1970 | {"c3": "00001"} | {"c2": "1", "c6": "1", "c7": "1 ", "c8": "foo", "C 1": "1"} - Sat Jan 03 00:00:00 1970 | {"c3": "00002"} | {"c2": "2", "c6": "2", "c7": "2 ", "c8": "foo", "C 1": "2"} - Sun Jan 04 00:00:00 1970 | {"c3": "00003"} | {"c2": "3", "c6": "3", "c7": "3 ", "c8": "foo", "C 1": "3"} - Mon Jan 05 00:00:00 1970 | {"c3": "00004"} | {"c2": "4", "c6": "4", "c7": "4 ", "c8": "foo", "C 1": "4"} - Tue Jan 06 00:00:00 1970 | {"c3": "00005"} | {"c2": "5", "c6": "5", "c7": "5 ", "c8": "foo", "C 1": "5"} - Wed Jan 07 00:00:00 1970 | {"c3": "00006"} | {"c2": "6", "c6": "6", "c7": "6 ", "c8": "foo", "C 1": "6"} - Thu Jan 08 00:00:00 1970 | {"c3": "00007"} | {"c2": "7", "c6": "7", "c7": "7 ", "c8": "foo", "C 1": "7"} - Fri Jan 09 00:00:00 1970 | {"c3": "00008"} | {"c2": "8", "c6": "8", "c7": "8 ", "c8": "foo", "C 1": "8"} - Sat Jan 10 00:00:00 1970 | {"c3": "00009"} | {"c2": "9", "c6": "9", "c7": "9 ", "c8": "foo", "C 1": "9"} - Sun Jan 11 00:00:00 1970 | {"c3": "00010"} | {"c2": "0", "c6": "0", "c7": "0 ", "c8": "foo", "C 1": "10"} + time | tags | fields +------------------------------+-----------------+---------------------------------------------------------------------- + Fri Jan 02 00:00:00 1970 PST | {"c3": "00001"} | {"c2": "1", "c6": "1", "c7": "1 ", "c8": "foo", "C 1": "1"} + Sat Jan 03 00:00:00 1970 PST | {"c3": "00002"} | {"c2": "2", "c6": "2", "c7": "2 ", "c8": "foo", "C 1": "2"} + Sun Jan 04 00:00:00 1970 PST | {"c3": "00003"} | {"c2": "3", "c6": "3", "c7": "3 ", "c8": "foo", "C 1": "3"} + Mon Jan 05 00:00:00 1970 PST | {"c3": "00004"} | {"c2": "4", "c6": "4", "c7": "4 ", "c8": "foo", "C 1": "4"} + Tue Jan 06 00:00:00 1970 PST | {"c3": "00005"} | {"c2": "5", "c6": "5", "c7": "5 ", "c8": "foo", "C 1": "5"} + Wed Jan 07 00:00:00 1970 PST | {"c3": "00006"} | {"c2": "6", "c6": "6", "c7": "6 ", "c8": "foo", "C 1": "6"} + Thu Jan 08 00:00:00 1970 PST | {"c3": "00007"} | {"c2": "7", "c6": "7", "c7": "7 ", "c8": "foo", "C 1": "7"} + Fri Jan 09 00:00:00 1970 PST | {"c3": "00008"} | {"c2": "8", "c6": "8", "c7": "8 ", "c8": "foo", "C 1": "8"} + Sat Jan 10 00:00:00 1970 PST | {"c3": "00009"} | {"c2": "9", "c6": "9", "c7": "9 ", "c8": "foo", "C 1": "9"} + Sun Jan 11 00:00:00 1970 PST | {"c3": "00010"} | {"c2": "0", "c6": "0", "c7": "0 ", "c8": "foo", "C 1": "10"} (10 rows) -- subquery+MAX --Testcase 45: SELECT * FROM ft1 t1 WHERE t1.tags->>'c3' = (SELECT MAX(tags->>'c3') FROM ft2 t2) ORDER BY (fields->>'C 1')::int; - time | tags | fields ---------------------------+-----------------+------------------------------------------------------------------------ - Thu Jan 01 00:00:00 1970 | {"c3": "01000"} | {"c2": "0", "c6": "0", "c7": "0 ", "c8": "foo", "C 1": "1000"} + time | tags | fields +------------------------------+-----------------+------------------------------------------------------------------------ + Thu Jan 01 00:00:00 1970 PST | {"c3": "01000"} | {"c2": "0", "c6": "0", "c7": "0 ", "c8": "foo", "C 1": "1000"} (1 row) -- used in CTE --Testcase 46: WITH t1 AS (SELECT * FROM ft1 WHERE (fields->>'C 1')::int <= 10) SELECT (t2.fields->>'C 1')::int c1, (t2.fields->>'c2')::int c2, t2.tags->>'c3' c3, t2.time FROM t1, ft2 t2 WHERE (t1.fields->>'C 1')::int = (t2.fields->>'C 1')::int ORDER BY (t1.fields->>'C 1')::int; - c1 | c2 | c3 | time -----+----+-------+-------------------------- - 1 | 1 | 00001 | Fri Jan 02 00:00:00 1970 - 2 | 2 | 00002 | Sat Jan 03 00:00:00 1970 - 3 | 3 | 00003 | Sun Jan 04 00:00:00 1970 - 4 | 4 | 00004 | Mon Jan 05 00:00:00 1970 - 5 | 5 | 00005 | Tue Jan 06 00:00:00 1970 - 6 | 6 | 00006 | Wed Jan 07 00:00:00 1970 - 7 | 7 | 00007 | Thu Jan 08 00:00:00 1970 - 8 | 8 | 00008 | Fri Jan 09 00:00:00 1970 - 9 | 9 | 00009 | Sat Jan 10 00:00:00 1970 - 10 | 0 | 00010 | Sun Jan 11 00:00:00 1970 + c1 | c2 | c3 | time +----+----+-------+------------------------------ + 1 | 1 | 00001 | Fri Jan 02 00:00:00 1970 PST + 2 | 2 | 00002 | Sat Jan 03 00:00:00 1970 PST + 3 | 3 | 00003 | Sun Jan 04 00:00:00 1970 PST + 4 | 4 | 00004 | Mon Jan 05 00:00:00 1970 PST + 5 | 5 | 00005 | Tue Jan 06 00:00:00 1970 PST + 6 | 6 | 00006 | Wed Jan 07 00:00:00 1970 PST + 7 | 7 | 00007 | Thu Jan 08 00:00:00 1970 PST + 8 | 8 | 00008 | Fri Jan 09 00:00:00 1970 PST + 9 | 9 | 00009 | Sat Jan 10 00:00:00 1970 PST + 10 | 0 | 00010 | Sun Jan 11 00:00:00 1970 PST (10 rows) -- fixed values @@ -853,9 +853,9 @@ EXPLAIN (VERBOSE, COSTS OFF) --Testcase 71: SELECT * FROM ft2 a, ft2 b WHERE (a.fields->>'C 1')::int = 47 AND (b.fields->>'C 1')::int = (a.fields->>'c2')::int; - time | tags | fields | time | tags | fields ---------------------------+-----------------+----------------------------------------------------------------------+--------------------------+-----------------+--------------------------------------------------------------------- - Tue Feb 17 00:00:00 1970 | {"c3": "00047"} | {"c2": "7", "c6": "7", "c7": "7 ", "c8": "foo", "C 1": "47"} | Thu Jan 08 00:00:00 1970 | {"c3": "00007"} | {"c2": "7", "c6": "7", "c7": "7 ", "c8": "foo", "C 1": "7"} + time | tags | fields | time | tags | fields +------------------------------+-----------------+----------------------------------------------------------------------+------------------------------+-----------------+--------------------------------------------------------------------- + Tue Feb 17 00:00:00 1970 PST | {"c3": "00047"} | {"c2": "7", "c6": "7", "c7": "7 ", "c8": "foo", "C 1": "47"} | Thu Jan 08 00:00:00 1970 PST | {"c3": "00007"} | {"c2": "7", "c6": "7", "c7": "7 ", "c8": "foo", "C 1": "7"} (1 row) -- check both safe and unsafe join conditions @@ -881,129 +881,129 @@ EXPLAIN (VERBOSE, COSTS OFF) --Testcase 73: SELECT * FROM ft2 a, ft2 b WHERE (a.fields->>'c2')::int = 6 AND (b.fields->>'C 1')::int = (a.fields->>'C 1')::int AND a.fields->>'c8' = 'foo' AND b.fields->>'c7' = upper(a.fields->>'c7') ORDER BY (a.fields->>'C 1')::int; - time | tags | fields | time | tags | fields ---------------------------+-----------------+-----------------------------------------------------------------------+--------------------------+-----------------+----------------------------------------------------------------------- - Wed Jan 07 00:00:00 1970 | {"c3": "00006"} | {"c2": "6", "c6": "6", "c7": "6 ", "c8": "foo", "C 1": "6"} | Wed Jan 07 00:00:00 1970 | {"c3": "00006"} | {"c2": "6", "c6": "6", "c7": "6 ", "c8": "foo", "C 1": "6"} - Sat Jan 17 00:00:00 1970 | {"c3": "00016"} | {"c2": "6", "c6": "6", "c7": "6 ", "c8": "foo", "C 1": "16"} | Sat Jan 17 00:00:00 1970 | {"c3": "00016"} | {"c2": "6", "c6": "6", "c7": "6 ", "c8": "foo", "C 1": "16"} - Tue Jan 27 00:00:00 1970 | {"c3": "00026"} | {"c2": "6", "c6": "6", "c7": "6 ", "c8": "foo", "C 1": "26"} | Tue Jan 27 00:00:00 1970 | {"c3": "00026"} | {"c2": "6", "c6": "6", "c7": "6 ", "c8": "foo", "C 1": "26"} - Fri Feb 06 00:00:00 1970 | {"c3": "00036"} | {"c2": "6", "c6": "6", "c7": "6 ", "c8": "foo", "C 1": "36"} | Fri Feb 06 00:00:00 1970 | {"c3": "00036"} | {"c2": "6", "c6": "6", "c7": "6 ", "c8": "foo", "C 1": "36"} - Mon Feb 16 00:00:00 1970 | {"c3": "00046"} | {"c2": "6", "c6": "6", "c7": "6 ", "c8": "foo", "C 1": "46"} | Mon Feb 16 00:00:00 1970 | {"c3": "00046"} | {"c2": "6", "c6": "6", "c7": "6 ", "c8": "foo", "C 1": "46"} - Thu Feb 26 00:00:00 1970 | {"c3": "00056"} | {"c2": "6", "c6": "6", "c7": "6 ", "c8": "foo", "C 1": "56"} | Thu Feb 26 00:00:00 1970 | {"c3": "00056"} | {"c2": "6", "c6": "6", "c7": "6 ", "c8": "foo", "C 1": "56"} - Sun Mar 08 00:00:00 1970 | {"c3": "00066"} | {"c2": "6", "c6": "6", "c7": "6 ", "c8": "foo", "C 1": "66"} | Sun Mar 08 00:00:00 1970 | {"c3": "00066"} | {"c2": "6", "c6": "6", "c7": "6 ", "c8": "foo", "C 1": "66"} - Wed Mar 18 00:00:00 1970 | {"c3": "00076"} | {"c2": "6", "c6": "6", "c7": "6 ", "c8": "foo", "C 1": "76"} | Wed Mar 18 00:00:00 1970 | {"c3": "00076"} | {"c2": "6", "c6": "6", "c7": "6 ", "c8": "foo", "C 1": "76"} - Sat Mar 28 00:00:00 1970 | {"c3": "00086"} | {"c2": "6", "c6": "6", "c7": "6 ", "c8": "foo", "C 1": "86"} | Sat Mar 28 00:00:00 1970 | {"c3": "00086"} | {"c2": "6", "c6": "6", "c7": "6 ", "c8": "foo", "C 1": "86"} - Tue Apr 07 00:00:00 1970 | {"c3": "00096"} | {"c2": "6", "c6": "6", "c7": "6 ", "c8": "foo", "C 1": "96"} | Tue Apr 07 00:00:00 1970 | {"c3": "00096"} | {"c2": "6", "c6": "6", "c7": "6 ", "c8": "foo", "C 1": "96"} - Wed Jan 07 00:00:00 1970 | {"c3": "00106"} | {"c2": "6", "c6": "6", "c7": "6 ", "c8": "foo", "C 1": "106"} | Wed Jan 07 00:00:00 1970 | {"c3": "00106"} | {"c2": "6", "c6": "6", "c7": "6 ", "c8": "foo", "C 1": "106"} - Sat Jan 17 00:00:00 1970 | {"c3": "00116"} | {"c2": "6", "c6": "6", "c7": "6 ", "c8": "foo", "C 1": "116"} | Sat Jan 17 00:00:00 1970 | {"c3": "00116"} | {"c2": "6", "c6": "6", "c7": "6 ", "c8": "foo", "C 1": "116"} - Tue Jan 27 00:00:00 1970 | {"c3": "00126"} | {"c2": "6", "c6": "6", "c7": "6 ", "c8": "foo", "C 1": "126"} | Tue Jan 27 00:00:00 1970 | {"c3": "00126"} | {"c2": "6", "c6": "6", "c7": "6 ", "c8": "foo", "C 1": "126"} - Fri Feb 06 00:00:00 1970 | {"c3": "00136"} | {"c2": "6", "c6": "6", "c7": "6 ", "c8": "foo", "C 1": "136"} | Fri Feb 06 00:00:00 1970 | {"c3": "00136"} | {"c2": "6", "c6": "6", "c7": "6 ", "c8": "foo", "C 1": "136"} - Mon Feb 16 00:00:00 1970 | {"c3": "00146"} | {"c2": "6", "c6": "6", "c7": "6 ", "c8": "foo", "C 1": "146"} | Mon Feb 16 00:00:00 1970 | {"c3": "00146"} | {"c2": "6", "c6": "6", "c7": "6 ", "c8": "foo", "C 1": "146"} - Thu Feb 26 00:00:00 1970 | {"c3": "00156"} | {"c2": "6", "c6": "6", "c7": "6 ", "c8": "foo", "C 1": "156"} | Thu Feb 26 00:00:00 1970 | {"c3": "00156"} | {"c2": "6", "c6": "6", "c7": "6 ", "c8": "foo", "C 1": "156"} - Sun Mar 08 00:00:00 1970 | {"c3": "00166"} | {"c2": "6", "c6": "6", "c7": "6 ", "c8": "foo", "C 1": "166"} | Sun Mar 08 00:00:00 1970 | {"c3": "00166"} | {"c2": "6", "c6": "6", "c7": "6 ", "c8": "foo", "C 1": "166"} - Wed Mar 18 00:00:00 1970 | {"c3": "00176"} | {"c2": "6", "c6": "6", "c7": "6 ", "c8": "foo", "C 1": "176"} | Wed Mar 18 00:00:00 1970 | {"c3": "00176"} | {"c2": "6", "c6": "6", "c7": "6 ", "c8": "foo", "C 1": "176"} - Sat Mar 28 00:00:00 1970 | {"c3": "00186"} | {"c2": "6", "c6": "6", "c7": "6 ", "c8": "foo", "C 1": "186"} | Sat Mar 28 00:00:00 1970 | {"c3": "00186"} | {"c2": "6", "c6": "6", "c7": "6 ", "c8": "foo", "C 1": "186"} - Tue Apr 07 00:00:00 1970 | {"c3": "00196"} | {"c2": "6", "c6": "6", "c7": "6 ", "c8": "foo", "C 1": "196"} | Tue Apr 07 00:00:00 1970 | {"c3": "00196"} | {"c2": "6", "c6": "6", "c7": "6 ", "c8": "foo", "C 1": "196"} - Wed Jan 07 00:00:00 1970 | {"c3": "00206"} | {"c2": "6", "c6": "6", "c7": "6 ", "c8": "foo", "C 1": "206"} | Wed Jan 07 00:00:00 1970 | {"c3": "00206"} | {"c2": "6", "c6": "6", "c7": "6 ", "c8": "foo", "C 1": "206"} - Sat Jan 17 00:00:00 1970 | {"c3": "00216"} | {"c2": "6", "c6": "6", "c7": "6 ", "c8": "foo", "C 1": "216"} | Sat Jan 17 00:00:00 1970 | {"c3": "00216"} | {"c2": "6", "c6": "6", "c7": "6 ", "c8": "foo", "C 1": "216"} - Tue Jan 27 00:00:00 1970 | {"c3": "00226"} | {"c2": "6", "c6": "6", "c7": "6 ", "c8": "foo", "C 1": "226"} | Tue Jan 27 00:00:00 1970 | {"c3": "00226"} | {"c2": "6", "c6": "6", "c7": "6 ", "c8": "foo", "C 1": "226"} - Fri Feb 06 00:00:00 1970 | {"c3": "00236"} | {"c2": "6", "c6": "6", "c7": "6 ", "c8": "foo", "C 1": "236"} | Fri Feb 06 00:00:00 1970 | {"c3": "00236"} | {"c2": "6", "c6": "6", "c7": "6 ", "c8": "foo", "C 1": "236"} - Mon Feb 16 00:00:00 1970 | {"c3": "00246"} | {"c2": "6", "c6": "6", "c7": "6 ", "c8": "foo", "C 1": "246"} | Mon Feb 16 00:00:00 1970 | {"c3": "00246"} | {"c2": "6", "c6": "6", "c7": "6 ", "c8": "foo", "C 1": "246"} - Thu Feb 26 00:00:00 1970 | {"c3": "00256"} | {"c2": "6", "c6": "6", "c7": "6 ", "c8": "foo", "C 1": "256"} | Thu Feb 26 00:00:00 1970 | {"c3": "00256"} | {"c2": "6", "c6": "6", "c7": "6 ", "c8": "foo", "C 1": "256"} - Sun Mar 08 00:00:00 1970 | {"c3": "00266"} | {"c2": "6", "c6": "6", "c7": "6 ", "c8": "foo", "C 1": "266"} | Sun Mar 08 00:00:00 1970 | {"c3": "00266"} | {"c2": "6", "c6": "6", "c7": "6 ", "c8": "foo", "C 1": "266"} - Wed Mar 18 00:00:00 1970 | {"c3": "00276"} | {"c2": "6", "c6": "6", "c7": "6 ", "c8": "foo", "C 1": "276"} | Wed Mar 18 00:00:00 1970 | {"c3": "00276"} | {"c2": "6", "c6": "6", "c7": "6 ", "c8": "foo", "C 1": "276"} - Sat Mar 28 00:00:00 1970 | {"c3": "00286"} | {"c2": "6", "c6": "6", "c7": "6 ", "c8": "foo", "C 1": "286"} | Sat Mar 28 00:00:00 1970 | {"c3": "00286"} | {"c2": "6", "c6": "6", "c7": "6 ", "c8": "foo", "C 1": "286"} - Tue Apr 07 00:00:00 1970 | {"c3": "00296"} | {"c2": "6", "c6": "6", "c7": "6 ", "c8": "foo", "C 1": "296"} | Tue Apr 07 00:00:00 1970 | {"c3": "00296"} | {"c2": "6", "c6": "6", "c7": "6 ", "c8": "foo", "C 1": "296"} - Wed Jan 07 00:00:00 1970 | {"c3": "00306"} | {"c2": "6", "c6": "6", "c7": "6 ", "c8": "foo", "C 1": "306"} | Wed Jan 07 00:00:00 1970 | {"c3": "00306"} | {"c2": "6", "c6": "6", "c7": "6 ", "c8": "foo", "C 1": "306"} - Sat Jan 17 00:00:00 1970 | {"c3": "00316"} | {"c2": "6", "c6": "6", "c7": "6 ", "c8": "foo", "C 1": "316"} | Sat Jan 17 00:00:00 1970 | {"c3": "00316"} | {"c2": "6", "c6": "6", "c7": "6 ", "c8": "foo", "C 1": "316"} - Tue Jan 27 00:00:00 1970 | {"c3": "00326"} | {"c2": "6", "c6": "6", "c7": "6 ", "c8": "foo", "C 1": "326"} | Tue Jan 27 00:00:00 1970 | {"c3": "00326"} | {"c2": "6", "c6": "6", "c7": "6 ", "c8": "foo", "C 1": "326"} - Fri Feb 06 00:00:00 1970 | {"c3": "00336"} | {"c2": "6", "c6": "6", "c7": "6 ", "c8": "foo", "C 1": "336"} | Fri Feb 06 00:00:00 1970 | {"c3": "00336"} | {"c2": "6", "c6": "6", "c7": "6 ", "c8": "foo", "C 1": "336"} - Mon Feb 16 00:00:00 1970 | {"c3": "00346"} | {"c2": "6", "c6": "6", "c7": "6 ", "c8": "foo", "C 1": "346"} | Mon Feb 16 00:00:00 1970 | {"c3": "00346"} | {"c2": "6", "c6": "6", "c7": "6 ", "c8": "foo", "C 1": "346"} - Thu Feb 26 00:00:00 1970 | {"c3": "00356"} | {"c2": "6", "c6": "6", "c7": "6 ", "c8": "foo", "C 1": "356"} | Thu Feb 26 00:00:00 1970 | {"c3": "00356"} | {"c2": "6", "c6": "6", "c7": "6 ", "c8": "foo", "C 1": "356"} - Sun Mar 08 00:00:00 1970 | {"c3": "00366"} | {"c2": "6", "c6": "6", "c7": "6 ", "c8": "foo", "C 1": "366"} | Sun Mar 08 00:00:00 1970 | {"c3": "00366"} | {"c2": "6", "c6": "6", "c7": "6 ", "c8": "foo", "C 1": "366"} - Wed Mar 18 00:00:00 1970 | {"c3": "00376"} | {"c2": "6", "c6": "6", "c7": "6 ", "c8": "foo", "C 1": "376"} | Wed Mar 18 00:00:00 1970 | {"c3": "00376"} | {"c2": "6", "c6": "6", "c7": "6 ", "c8": "foo", "C 1": "376"} - Sat Mar 28 00:00:00 1970 | {"c3": "00386"} | {"c2": "6", "c6": "6", "c7": "6 ", "c8": "foo", "C 1": "386"} | Sat Mar 28 00:00:00 1970 | {"c3": "00386"} | {"c2": "6", "c6": "6", "c7": "6 ", "c8": "foo", "C 1": "386"} - Tue Apr 07 00:00:00 1970 | {"c3": "00396"} | {"c2": "6", "c6": "6", "c7": "6 ", "c8": "foo", "C 1": "396"} | Tue Apr 07 00:00:00 1970 | {"c3": "00396"} | {"c2": "6", "c6": "6", "c7": "6 ", "c8": "foo", "C 1": "396"} - Wed Jan 07 00:00:00 1970 | {"c3": "00406"} | {"c2": "6", "c6": "6", "c7": "6 ", "c8": "foo", "C 1": "406"} | Wed Jan 07 00:00:00 1970 | {"c3": "00406"} | {"c2": "6", "c6": "6", "c7": "6 ", "c8": "foo", "C 1": "406"} - Sat Jan 17 00:00:00 1970 | {"c3": "00416"} | {"c2": "6", "c6": "6", "c7": "6 ", "c8": "foo", "C 1": "416"} | Sat Jan 17 00:00:00 1970 | {"c3": "00416"} | {"c2": "6", "c6": "6", "c7": "6 ", "c8": "foo", "C 1": "416"} - Tue Jan 27 00:00:00 1970 | {"c3": "00426"} | {"c2": "6", "c6": "6", "c7": "6 ", "c8": "foo", "C 1": "426"} | Tue Jan 27 00:00:00 1970 | {"c3": "00426"} | {"c2": "6", "c6": "6", "c7": "6 ", "c8": "foo", "C 1": "426"} - Fri Feb 06 00:00:00 1970 | {"c3": "00436"} | {"c2": "6", "c6": "6", "c7": "6 ", "c8": "foo", "C 1": "436"} | Fri Feb 06 00:00:00 1970 | {"c3": "00436"} | {"c2": "6", "c6": "6", "c7": "6 ", "c8": "foo", "C 1": "436"} - Mon Feb 16 00:00:00 1970 | {"c3": "00446"} | {"c2": "6", "c6": "6", "c7": "6 ", "c8": "foo", "C 1": "446"} | Mon Feb 16 00:00:00 1970 | {"c3": "00446"} | {"c2": "6", "c6": "6", "c7": "6 ", "c8": "foo", "C 1": "446"} - Thu Feb 26 00:00:00 1970 | {"c3": "00456"} | {"c2": "6", "c6": "6", "c7": "6 ", "c8": "foo", "C 1": "456"} | Thu Feb 26 00:00:00 1970 | {"c3": "00456"} | {"c2": "6", "c6": "6", "c7": "6 ", "c8": "foo", "C 1": "456"} - Sun Mar 08 00:00:00 1970 | {"c3": "00466"} | {"c2": "6", "c6": "6", "c7": "6 ", "c8": "foo", "C 1": "466"} | Sun Mar 08 00:00:00 1970 | {"c3": "00466"} | {"c2": "6", "c6": "6", "c7": "6 ", "c8": "foo", "C 1": "466"} - Wed Mar 18 00:00:00 1970 | {"c3": "00476"} | {"c2": "6", "c6": "6", "c7": "6 ", "c8": "foo", "C 1": "476"} | Wed Mar 18 00:00:00 1970 | {"c3": "00476"} | {"c2": "6", "c6": "6", "c7": "6 ", "c8": "foo", "C 1": "476"} - Sat Mar 28 00:00:00 1970 | {"c3": "00486"} | {"c2": "6", "c6": "6", "c7": "6 ", "c8": "foo", "C 1": "486"} | Sat Mar 28 00:00:00 1970 | {"c3": "00486"} | {"c2": "6", "c6": "6", "c7": "6 ", "c8": "foo", "C 1": "486"} - Tue Apr 07 00:00:00 1970 | {"c3": "00496"} | {"c2": "6", "c6": "6", "c7": "6 ", "c8": "foo", "C 1": "496"} | Tue Apr 07 00:00:00 1970 | {"c3": "00496"} | {"c2": "6", "c6": "6", "c7": "6 ", "c8": "foo", "C 1": "496"} - Wed Jan 07 00:00:00 1970 | {"c3": "00506"} | {"c2": "6", "c6": "6", "c7": "6 ", "c8": "foo", "C 1": "506"} | Wed Jan 07 00:00:00 1970 | {"c3": "00506"} | {"c2": "6", "c6": "6", "c7": "6 ", "c8": "foo", "C 1": "506"} - Sat Jan 17 00:00:00 1970 | {"c3": "00516"} | {"c2": "6", "c6": "6", "c7": "6 ", "c8": "foo", "C 1": "516"} | Sat Jan 17 00:00:00 1970 | {"c3": "00516"} | {"c2": "6", "c6": "6", "c7": "6 ", "c8": "foo", "C 1": "516"} - Tue Jan 27 00:00:00 1970 | {"c3": "00526"} | {"c2": "6", "c6": "6", "c7": "6 ", "c8": "foo", "C 1": "526"} | Tue Jan 27 00:00:00 1970 | {"c3": "00526"} | {"c2": "6", "c6": "6", "c7": "6 ", "c8": "foo", "C 1": "526"} - Fri Feb 06 00:00:00 1970 | {"c3": "00536"} | {"c2": "6", "c6": "6", "c7": "6 ", "c8": "foo", "C 1": "536"} | Fri Feb 06 00:00:00 1970 | {"c3": "00536"} | {"c2": "6", "c6": "6", "c7": "6 ", "c8": "foo", "C 1": "536"} - Mon Feb 16 00:00:00 1970 | {"c3": "00546"} | {"c2": "6", "c6": "6", "c7": "6 ", "c8": "foo", "C 1": "546"} | Mon Feb 16 00:00:00 1970 | {"c3": "00546"} | {"c2": "6", "c6": "6", "c7": "6 ", "c8": "foo", "C 1": "546"} - Thu Feb 26 00:00:00 1970 | {"c3": "00556"} | {"c2": "6", "c6": "6", "c7": "6 ", "c8": "foo", "C 1": "556"} | Thu Feb 26 00:00:00 1970 | {"c3": "00556"} | {"c2": "6", "c6": "6", "c7": "6 ", "c8": "foo", "C 1": "556"} - Sun Mar 08 00:00:00 1970 | {"c3": "00566"} | {"c2": "6", "c6": "6", "c7": "6 ", "c8": "foo", "C 1": "566"} | Sun Mar 08 00:00:00 1970 | {"c3": "00566"} | {"c2": "6", "c6": "6", "c7": "6 ", "c8": "foo", "C 1": "566"} - Wed Mar 18 00:00:00 1970 | {"c3": "00576"} | {"c2": "6", "c6": "6", "c7": "6 ", "c8": "foo", "C 1": "576"} | Wed Mar 18 00:00:00 1970 | {"c3": "00576"} | {"c2": "6", "c6": "6", "c7": "6 ", "c8": "foo", "C 1": "576"} - Sat Mar 28 00:00:00 1970 | {"c3": "00586"} | {"c2": "6", "c6": "6", "c7": "6 ", "c8": "foo", "C 1": "586"} | Sat Mar 28 00:00:00 1970 | {"c3": "00586"} | {"c2": "6", "c6": "6", "c7": "6 ", "c8": "foo", "C 1": "586"} - Tue Apr 07 00:00:00 1970 | {"c3": "00596"} | {"c2": "6", "c6": "6", "c7": "6 ", "c8": "foo", "C 1": "596"} | Tue Apr 07 00:00:00 1970 | {"c3": "00596"} | {"c2": "6", "c6": "6", "c7": "6 ", "c8": "foo", "C 1": "596"} - Wed Jan 07 00:00:00 1970 | {"c3": "00606"} | {"c2": "6", "c6": "6", "c7": "6 ", "c8": "foo", "C 1": "606"} | Wed Jan 07 00:00:00 1970 | {"c3": "00606"} | {"c2": "6", "c6": "6", "c7": "6 ", "c8": "foo", "C 1": "606"} - Sat Jan 17 00:00:00 1970 | {"c3": "00616"} | {"c2": "6", "c6": "6", "c7": "6 ", "c8": "foo", "C 1": "616"} | Sat Jan 17 00:00:00 1970 | {"c3": "00616"} | {"c2": "6", "c6": "6", "c7": "6 ", "c8": "foo", "C 1": "616"} - Tue Jan 27 00:00:00 1970 | {"c3": "00626"} | {"c2": "6", "c6": "6", "c7": "6 ", "c8": "foo", "C 1": "626"} | Tue Jan 27 00:00:00 1970 | {"c3": "00626"} | {"c2": "6", "c6": "6", "c7": "6 ", "c8": "foo", "C 1": "626"} - Fri Feb 06 00:00:00 1970 | {"c3": "00636"} | {"c2": "6", "c6": "6", "c7": "6 ", "c8": "foo", "C 1": "636"} | Fri Feb 06 00:00:00 1970 | {"c3": "00636"} | {"c2": "6", "c6": "6", "c7": "6 ", "c8": "foo", "C 1": "636"} - Mon Feb 16 00:00:00 1970 | {"c3": "00646"} | {"c2": "6", "c6": "6", "c7": "6 ", "c8": "foo", "C 1": "646"} | Mon Feb 16 00:00:00 1970 | {"c3": "00646"} | {"c2": "6", "c6": "6", "c7": "6 ", "c8": "foo", "C 1": "646"} - Thu Feb 26 00:00:00 1970 | {"c3": "00656"} | {"c2": "6", "c6": "6", "c7": "6 ", "c8": "foo", "C 1": "656"} | Thu Feb 26 00:00:00 1970 | {"c3": "00656"} | {"c2": "6", "c6": "6", "c7": "6 ", "c8": "foo", "C 1": "656"} - Sun Mar 08 00:00:00 1970 | {"c3": "00666"} | {"c2": "6", "c6": "6", "c7": "6 ", "c8": "foo", "C 1": "666"} | Sun Mar 08 00:00:00 1970 | {"c3": "00666"} | {"c2": "6", "c6": "6", "c7": "6 ", "c8": "foo", "C 1": "666"} - Wed Mar 18 00:00:00 1970 | {"c3": "00676"} | {"c2": "6", "c6": "6", "c7": "6 ", "c8": "foo", "C 1": "676"} | Wed Mar 18 00:00:00 1970 | {"c3": "00676"} | {"c2": "6", "c6": "6", "c7": "6 ", "c8": "foo", "C 1": "676"} - Sat Mar 28 00:00:00 1970 | {"c3": "00686"} | {"c2": "6", "c6": "6", "c7": "6 ", "c8": "foo", "C 1": "686"} | Sat Mar 28 00:00:00 1970 | {"c3": "00686"} | {"c2": "6", "c6": "6", "c7": "6 ", "c8": "foo", "C 1": "686"} - Tue Apr 07 00:00:00 1970 | {"c3": "00696"} | {"c2": "6", "c6": "6", "c7": "6 ", "c8": "foo", "C 1": "696"} | Tue Apr 07 00:00:00 1970 | {"c3": "00696"} | {"c2": "6", "c6": "6", "c7": "6 ", "c8": "foo", "C 1": "696"} - Wed Jan 07 00:00:00 1970 | {"c3": "00706"} | {"c2": "6", "c6": "6", "c7": "6 ", "c8": "foo", "C 1": "706"} | Wed Jan 07 00:00:00 1970 | {"c3": "00706"} | {"c2": "6", "c6": "6", "c7": "6 ", "c8": "foo", "C 1": "706"} - Sat Jan 17 00:00:00 1970 | {"c3": "00716"} | {"c2": "6", "c6": "6", "c7": "6 ", "c8": "foo", "C 1": "716"} | Sat Jan 17 00:00:00 1970 | {"c3": "00716"} | {"c2": "6", "c6": "6", "c7": "6 ", "c8": "foo", "C 1": "716"} - Tue Jan 27 00:00:00 1970 | {"c3": "00726"} | {"c2": "6", "c6": "6", "c7": "6 ", "c8": "foo", "C 1": "726"} | Tue Jan 27 00:00:00 1970 | {"c3": "00726"} | {"c2": "6", "c6": "6", "c7": "6 ", "c8": "foo", "C 1": "726"} - Fri Feb 06 00:00:00 1970 | {"c3": "00736"} | {"c2": "6", "c6": "6", "c7": "6 ", "c8": "foo", "C 1": "736"} | Fri Feb 06 00:00:00 1970 | {"c3": "00736"} | {"c2": "6", "c6": "6", "c7": "6 ", "c8": "foo", "C 1": "736"} - Mon Feb 16 00:00:00 1970 | {"c3": "00746"} | {"c2": "6", "c6": "6", "c7": "6 ", "c8": "foo", "C 1": "746"} | Mon Feb 16 00:00:00 1970 | {"c3": "00746"} | {"c2": "6", "c6": "6", "c7": "6 ", "c8": "foo", "C 1": "746"} - Thu Feb 26 00:00:00 1970 | {"c3": "00756"} | {"c2": "6", "c6": "6", "c7": "6 ", "c8": "foo", "C 1": "756"} | Thu Feb 26 00:00:00 1970 | {"c3": "00756"} | {"c2": "6", "c6": "6", "c7": "6 ", "c8": "foo", "C 1": "756"} - Sun Mar 08 00:00:00 1970 | {"c3": "00766"} | {"c2": "6", "c6": "6", "c7": "6 ", "c8": "foo", "C 1": "766"} | Sun Mar 08 00:00:00 1970 | {"c3": "00766"} | {"c2": "6", "c6": "6", "c7": "6 ", "c8": "foo", "C 1": "766"} - Wed Mar 18 00:00:00 1970 | {"c3": "00776"} | {"c2": "6", "c6": "6", "c7": "6 ", "c8": "foo", "C 1": "776"} | Wed Mar 18 00:00:00 1970 | {"c3": "00776"} | {"c2": "6", "c6": "6", "c7": "6 ", "c8": "foo", "C 1": "776"} - Sat Mar 28 00:00:00 1970 | {"c3": "00786"} | {"c2": "6", "c6": "6", "c7": "6 ", "c8": "foo", "C 1": "786"} | Sat Mar 28 00:00:00 1970 | {"c3": "00786"} | {"c2": "6", "c6": "6", "c7": "6 ", "c8": "foo", "C 1": "786"} - Tue Apr 07 00:00:00 1970 | {"c3": "00796"} | {"c2": "6", "c6": "6", "c7": "6 ", "c8": "foo", "C 1": "796"} | Tue Apr 07 00:00:00 1970 | {"c3": "00796"} | {"c2": "6", "c6": "6", "c7": "6 ", "c8": "foo", "C 1": "796"} - Wed Jan 07 00:00:00 1970 | {"c3": "00806"} | {"c2": "6", "c6": "6", "c7": "6 ", "c8": "foo", "C 1": "806"} | Wed Jan 07 00:00:00 1970 | {"c3": "00806"} | {"c2": "6", "c6": "6", "c7": "6 ", "c8": "foo", "C 1": "806"} - Sat Jan 17 00:00:00 1970 | {"c3": "00816"} | {"c2": "6", "c6": "6", "c7": "6 ", "c8": "foo", "C 1": "816"} | Sat Jan 17 00:00:00 1970 | {"c3": "00816"} | {"c2": "6", "c6": "6", "c7": "6 ", "c8": "foo", "C 1": "816"} - Tue Jan 27 00:00:00 1970 | {"c3": "00826"} | {"c2": "6", "c6": "6", "c7": "6 ", "c8": "foo", "C 1": "826"} | Tue Jan 27 00:00:00 1970 | {"c3": "00826"} | {"c2": "6", "c6": "6", "c7": "6 ", "c8": "foo", "C 1": "826"} - Fri Feb 06 00:00:00 1970 | {"c3": "00836"} | {"c2": "6", "c6": "6", "c7": "6 ", "c8": "foo", "C 1": "836"} | Fri Feb 06 00:00:00 1970 | {"c3": "00836"} | {"c2": "6", "c6": "6", "c7": "6 ", "c8": "foo", "C 1": "836"} - Mon Feb 16 00:00:00 1970 | {"c3": "00846"} | {"c2": "6", "c6": "6", "c7": "6 ", "c8": "foo", "C 1": "846"} | Mon Feb 16 00:00:00 1970 | {"c3": "00846"} | {"c2": "6", "c6": "6", "c7": "6 ", "c8": "foo", "C 1": "846"} - Thu Feb 26 00:00:00 1970 | {"c3": "00856"} | {"c2": "6", "c6": "6", "c7": "6 ", "c8": "foo", "C 1": "856"} | Thu Feb 26 00:00:00 1970 | {"c3": "00856"} | {"c2": "6", "c6": "6", "c7": "6 ", "c8": "foo", "C 1": "856"} - Sun Mar 08 00:00:00 1970 | {"c3": "00866"} | {"c2": "6", "c6": "6", "c7": "6 ", "c8": "foo", "C 1": "866"} | Sun Mar 08 00:00:00 1970 | {"c3": "00866"} | {"c2": "6", "c6": "6", "c7": "6 ", "c8": "foo", "C 1": "866"} - Wed Mar 18 00:00:00 1970 | {"c3": "00876"} | {"c2": "6", "c6": "6", "c7": "6 ", "c8": "foo", "C 1": "876"} | Wed Mar 18 00:00:00 1970 | {"c3": "00876"} | {"c2": "6", "c6": "6", "c7": "6 ", "c8": "foo", "C 1": "876"} - Sat Mar 28 00:00:00 1970 | {"c3": "00886"} | {"c2": "6", "c6": "6", "c7": "6 ", "c8": "foo", "C 1": "886"} | Sat Mar 28 00:00:00 1970 | {"c3": "00886"} | {"c2": "6", "c6": "6", "c7": "6 ", "c8": "foo", "C 1": "886"} - Tue Apr 07 00:00:00 1970 | {"c3": "00896"} | {"c2": "6", "c6": "6", "c7": "6 ", "c8": "foo", "C 1": "896"} | Tue Apr 07 00:00:00 1970 | {"c3": "00896"} | {"c2": "6", "c6": "6", "c7": "6 ", "c8": "foo", "C 1": "896"} - Wed Jan 07 00:00:00 1970 | {"c3": "00906"} | {"c2": "6", "c6": "6", "c7": "6 ", "c8": "foo", "C 1": "906"} | Wed Jan 07 00:00:00 1970 | {"c3": "00906"} | {"c2": "6", "c6": "6", "c7": "6 ", "c8": "foo", "C 1": "906"} - Sat Jan 17 00:00:00 1970 | {"c3": "00916"} | {"c2": "6", "c6": "6", "c7": "6 ", "c8": "foo", "C 1": "916"} | Sat Jan 17 00:00:00 1970 | {"c3": "00916"} | {"c2": "6", "c6": "6", "c7": "6 ", "c8": "foo", "C 1": "916"} - Tue Jan 27 00:00:00 1970 | {"c3": "00926"} | {"c2": "6", "c6": "6", "c7": "6 ", "c8": "foo", "C 1": "926"} | Tue Jan 27 00:00:00 1970 | {"c3": "00926"} | {"c2": "6", "c6": "6", "c7": "6 ", "c8": "foo", "C 1": "926"} - Fri Feb 06 00:00:00 1970 | {"c3": "00936"} | {"c2": "6", "c6": "6", "c7": "6 ", "c8": "foo", "C 1": "936"} | Fri Feb 06 00:00:00 1970 | {"c3": "00936"} | {"c2": "6", "c6": "6", "c7": "6 ", "c8": "foo", "C 1": "936"} - Mon Feb 16 00:00:00 1970 | {"c3": "00946"} | {"c2": "6", "c6": "6", "c7": "6 ", "c8": "foo", "C 1": "946"} | Mon Feb 16 00:00:00 1970 | {"c3": "00946"} | {"c2": "6", "c6": "6", "c7": "6 ", "c8": "foo", "C 1": "946"} - Thu Feb 26 00:00:00 1970 | {"c3": "00956"} | {"c2": "6", "c6": "6", "c7": "6 ", "c8": "foo", "C 1": "956"} | Thu Feb 26 00:00:00 1970 | {"c3": "00956"} | {"c2": "6", "c6": "6", "c7": "6 ", "c8": "foo", "C 1": "956"} - Sun Mar 08 00:00:00 1970 | {"c3": "00966"} | {"c2": "6", "c6": "6", "c7": "6 ", "c8": "foo", "C 1": "966"} | Sun Mar 08 00:00:00 1970 | {"c3": "00966"} | {"c2": "6", "c6": "6", "c7": "6 ", "c8": "foo", "C 1": "966"} - Wed Mar 18 00:00:00 1970 | {"c3": "00976"} | {"c2": "6", "c6": "6", "c7": "6 ", "c8": "foo", "C 1": "976"} | Wed Mar 18 00:00:00 1970 | {"c3": "00976"} | {"c2": "6", "c6": "6", "c7": "6 ", "c8": "foo", "C 1": "976"} - Sat Mar 28 00:00:00 1970 | {"c3": "00986"} | {"c2": "6", "c6": "6", "c7": "6 ", "c8": "foo", "C 1": "986"} | Sat Mar 28 00:00:00 1970 | {"c3": "00986"} | {"c2": "6", "c6": "6", "c7": "6 ", "c8": "foo", "C 1": "986"} - Tue Apr 07 00:00:00 1970 | {"c3": "00996"} | {"c2": "6", "c6": "6", "c7": "6 ", "c8": "foo", "C 1": "996"} | Tue Apr 07 00:00:00 1970 | {"c3": "00996"} | {"c2": "6", "c6": "6", "c7": "6 ", "c8": "foo", "C 1": "996"} + time | tags | fields | time | tags | fields +------------------------------+-----------------+-----------------------------------------------------------------------+------------------------------+-----------------+----------------------------------------------------------------------- + Wed Jan 07 00:00:00 1970 PST | {"c3": "00006"} | {"c2": "6", "c6": "6", "c7": "6 ", "c8": "foo", "C 1": "6"} | Wed Jan 07 00:00:00 1970 PST | {"c3": "00006"} | {"c2": "6", "c6": "6", "c7": "6 ", "c8": "foo", "C 1": "6"} + Sat Jan 17 00:00:00 1970 PST | {"c3": "00016"} | {"c2": "6", "c6": "6", "c7": "6 ", "c8": "foo", "C 1": "16"} | Sat Jan 17 00:00:00 1970 PST | {"c3": "00016"} | {"c2": "6", "c6": "6", "c7": "6 ", "c8": "foo", "C 1": "16"} + Tue Jan 27 00:00:00 1970 PST | {"c3": "00026"} | {"c2": "6", "c6": "6", "c7": "6 ", "c8": "foo", "C 1": "26"} | Tue Jan 27 00:00:00 1970 PST | {"c3": "00026"} | {"c2": "6", "c6": "6", "c7": "6 ", "c8": "foo", "C 1": "26"} + Fri Feb 06 00:00:00 1970 PST | {"c3": "00036"} | {"c2": "6", "c6": "6", "c7": "6 ", "c8": "foo", "C 1": "36"} | Fri Feb 06 00:00:00 1970 PST | {"c3": "00036"} | {"c2": "6", "c6": "6", "c7": "6 ", "c8": "foo", "C 1": "36"} + Mon Feb 16 00:00:00 1970 PST | {"c3": "00046"} | {"c2": "6", "c6": "6", "c7": "6 ", "c8": "foo", "C 1": "46"} | Mon Feb 16 00:00:00 1970 PST | {"c3": "00046"} | {"c2": "6", "c6": "6", "c7": "6 ", "c8": "foo", "C 1": "46"} + Thu Feb 26 00:00:00 1970 PST | {"c3": "00056"} | {"c2": "6", "c6": "6", "c7": "6 ", "c8": "foo", "C 1": "56"} | Thu Feb 26 00:00:00 1970 PST | {"c3": "00056"} | {"c2": "6", "c6": "6", "c7": "6 ", "c8": "foo", "C 1": "56"} + Sun Mar 08 00:00:00 1970 PST | {"c3": "00066"} | {"c2": "6", "c6": "6", "c7": "6 ", "c8": "foo", "C 1": "66"} | Sun Mar 08 00:00:00 1970 PST | {"c3": "00066"} | {"c2": "6", "c6": "6", "c7": "6 ", "c8": "foo", "C 1": "66"} + Wed Mar 18 00:00:00 1970 PST | {"c3": "00076"} | {"c2": "6", "c6": "6", "c7": "6 ", "c8": "foo", "C 1": "76"} | Wed Mar 18 00:00:00 1970 PST | {"c3": "00076"} | {"c2": "6", "c6": "6", "c7": "6 ", "c8": "foo", "C 1": "76"} + Sat Mar 28 00:00:00 1970 PST | {"c3": "00086"} | {"c2": "6", "c6": "6", "c7": "6 ", "c8": "foo", "C 1": "86"} | Sat Mar 28 00:00:00 1970 PST | {"c3": "00086"} | {"c2": "6", "c6": "6", "c7": "6 ", "c8": "foo", "C 1": "86"} + Tue Apr 07 00:00:00 1970 PST | {"c3": "00096"} | {"c2": "6", "c6": "6", "c7": "6 ", "c8": "foo", "C 1": "96"} | Tue Apr 07 00:00:00 1970 PST | {"c3": "00096"} | {"c2": "6", "c6": "6", "c7": "6 ", "c8": "foo", "C 1": "96"} + Wed Jan 07 00:00:00 1970 PST | {"c3": "00106"} | {"c2": "6", "c6": "6", "c7": "6 ", "c8": "foo", "C 1": "106"} | Wed Jan 07 00:00:00 1970 PST | {"c3": "00106"} | {"c2": "6", "c6": "6", "c7": "6 ", "c8": "foo", "C 1": "106"} + Sat Jan 17 00:00:00 1970 PST | {"c3": "00116"} | {"c2": "6", "c6": "6", "c7": "6 ", "c8": "foo", "C 1": "116"} | Sat Jan 17 00:00:00 1970 PST | {"c3": "00116"} | {"c2": "6", "c6": "6", "c7": "6 ", "c8": "foo", "C 1": "116"} + Tue Jan 27 00:00:00 1970 PST | {"c3": "00126"} | {"c2": "6", "c6": "6", "c7": "6 ", "c8": "foo", "C 1": "126"} | Tue Jan 27 00:00:00 1970 PST | {"c3": "00126"} | {"c2": "6", "c6": "6", "c7": "6 ", "c8": "foo", "C 1": "126"} + Fri Feb 06 00:00:00 1970 PST | {"c3": "00136"} | {"c2": "6", "c6": "6", "c7": "6 ", "c8": "foo", "C 1": "136"} | Fri Feb 06 00:00:00 1970 PST | {"c3": "00136"} | {"c2": "6", "c6": "6", "c7": "6 ", "c8": "foo", "C 1": "136"} + Mon Feb 16 00:00:00 1970 PST | {"c3": "00146"} | {"c2": "6", "c6": "6", "c7": "6 ", "c8": "foo", "C 1": "146"} | Mon Feb 16 00:00:00 1970 PST | {"c3": "00146"} | {"c2": "6", "c6": "6", "c7": "6 ", "c8": "foo", "C 1": "146"} + Thu Feb 26 00:00:00 1970 PST | {"c3": "00156"} | {"c2": "6", "c6": "6", "c7": "6 ", "c8": "foo", "C 1": "156"} | Thu Feb 26 00:00:00 1970 PST | {"c3": "00156"} | {"c2": "6", "c6": "6", "c7": "6 ", "c8": "foo", "C 1": "156"} + Sun Mar 08 00:00:00 1970 PST | {"c3": "00166"} | {"c2": "6", "c6": "6", "c7": "6 ", "c8": "foo", "C 1": "166"} | Sun Mar 08 00:00:00 1970 PST | {"c3": "00166"} | {"c2": "6", "c6": "6", "c7": "6 ", "c8": "foo", "C 1": "166"} + Wed Mar 18 00:00:00 1970 PST | {"c3": "00176"} | {"c2": "6", "c6": "6", "c7": "6 ", "c8": "foo", "C 1": "176"} | Wed Mar 18 00:00:00 1970 PST | {"c3": "00176"} | {"c2": "6", "c6": "6", "c7": "6 ", "c8": "foo", "C 1": "176"} + Sat Mar 28 00:00:00 1970 PST | {"c3": "00186"} | {"c2": "6", "c6": "6", "c7": "6 ", "c8": "foo", "C 1": "186"} | Sat Mar 28 00:00:00 1970 PST | {"c3": "00186"} | {"c2": "6", "c6": "6", "c7": "6 ", "c8": "foo", "C 1": "186"} + Tue Apr 07 00:00:00 1970 PST | {"c3": "00196"} | {"c2": "6", "c6": "6", "c7": "6 ", "c8": "foo", "C 1": "196"} | Tue Apr 07 00:00:00 1970 PST | {"c3": "00196"} | {"c2": "6", "c6": "6", "c7": "6 ", "c8": "foo", "C 1": "196"} + Wed Jan 07 00:00:00 1970 PST | {"c3": "00206"} | {"c2": "6", "c6": "6", "c7": "6 ", "c8": "foo", "C 1": "206"} | Wed Jan 07 00:00:00 1970 PST | {"c3": "00206"} | {"c2": "6", "c6": "6", "c7": "6 ", "c8": "foo", "C 1": "206"} + Sat Jan 17 00:00:00 1970 PST | {"c3": "00216"} | {"c2": "6", "c6": "6", "c7": "6 ", "c8": "foo", "C 1": "216"} | Sat Jan 17 00:00:00 1970 PST | {"c3": "00216"} | {"c2": "6", "c6": "6", "c7": "6 ", "c8": "foo", "C 1": "216"} + Tue Jan 27 00:00:00 1970 PST | {"c3": "00226"} | {"c2": "6", "c6": "6", "c7": "6 ", "c8": "foo", "C 1": "226"} | Tue Jan 27 00:00:00 1970 PST | {"c3": "00226"} | {"c2": "6", "c6": "6", "c7": "6 ", "c8": "foo", "C 1": "226"} + Fri Feb 06 00:00:00 1970 PST | {"c3": "00236"} | {"c2": "6", "c6": "6", "c7": "6 ", "c8": "foo", "C 1": "236"} | Fri Feb 06 00:00:00 1970 PST | {"c3": "00236"} | {"c2": "6", "c6": "6", "c7": "6 ", "c8": "foo", "C 1": "236"} + Mon Feb 16 00:00:00 1970 PST | {"c3": "00246"} | {"c2": "6", "c6": "6", "c7": "6 ", "c8": "foo", "C 1": "246"} | Mon Feb 16 00:00:00 1970 PST | {"c3": "00246"} | {"c2": "6", "c6": "6", "c7": "6 ", "c8": "foo", "C 1": "246"} + Thu Feb 26 00:00:00 1970 PST | {"c3": "00256"} | {"c2": "6", "c6": "6", "c7": "6 ", "c8": "foo", "C 1": "256"} | Thu Feb 26 00:00:00 1970 PST | {"c3": "00256"} | {"c2": "6", "c6": "6", "c7": "6 ", "c8": "foo", "C 1": "256"} + Sun Mar 08 00:00:00 1970 PST | {"c3": "00266"} | {"c2": "6", "c6": "6", "c7": "6 ", "c8": "foo", "C 1": "266"} | Sun Mar 08 00:00:00 1970 PST | {"c3": "00266"} | {"c2": "6", "c6": "6", "c7": "6 ", "c8": "foo", "C 1": "266"} + Wed Mar 18 00:00:00 1970 PST | {"c3": "00276"} | {"c2": "6", "c6": "6", "c7": "6 ", "c8": "foo", "C 1": "276"} | Wed Mar 18 00:00:00 1970 PST | {"c3": "00276"} | {"c2": "6", "c6": "6", "c7": "6 ", "c8": "foo", "C 1": "276"} + Sat Mar 28 00:00:00 1970 PST | {"c3": "00286"} | {"c2": "6", "c6": "6", "c7": "6 ", "c8": "foo", "C 1": "286"} | Sat Mar 28 00:00:00 1970 PST | {"c3": "00286"} | {"c2": "6", "c6": "6", "c7": "6 ", "c8": "foo", "C 1": "286"} + Tue Apr 07 00:00:00 1970 PST | {"c3": "00296"} | {"c2": "6", "c6": "6", "c7": "6 ", "c8": "foo", "C 1": "296"} | Tue Apr 07 00:00:00 1970 PST | {"c3": "00296"} | {"c2": "6", "c6": "6", "c7": "6 ", "c8": "foo", "C 1": "296"} + Wed Jan 07 00:00:00 1970 PST | {"c3": "00306"} | {"c2": "6", "c6": "6", "c7": "6 ", "c8": "foo", "C 1": "306"} | Wed Jan 07 00:00:00 1970 PST | {"c3": "00306"} | {"c2": "6", "c6": "6", "c7": "6 ", "c8": "foo", "C 1": "306"} + Sat Jan 17 00:00:00 1970 PST | {"c3": "00316"} | {"c2": "6", "c6": "6", "c7": "6 ", "c8": "foo", "C 1": "316"} | Sat Jan 17 00:00:00 1970 PST | {"c3": "00316"} | {"c2": "6", "c6": "6", "c7": "6 ", "c8": "foo", "C 1": "316"} + Tue Jan 27 00:00:00 1970 PST | {"c3": "00326"} | {"c2": "6", "c6": "6", "c7": "6 ", "c8": "foo", "C 1": "326"} | Tue Jan 27 00:00:00 1970 PST | {"c3": "00326"} | {"c2": "6", "c6": "6", "c7": "6 ", "c8": "foo", "C 1": "326"} + Fri Feb 06 00:00:00 1970 PST | {"c3": "00336"} | {"c2": "6", "c6": "6", "c7": "6 ", "c8": "foo", "C 1": "336"} | Fri Feb 06 00:00:00 1970 PST | {"c3": "00336"} | {"c2": "6", "c6": "6", "c7": "6 ", "c8": "foo", "C 1": "336"} + Mon Feb 16 00:00:00 1970 PST | {"c3": "00346"} | {"c2": "6", "c6": "6", "c7": "6 ", "c8": "foo", "C 1": "346"} | Mon Feb 16 00:00:00 1970 PST | {"c3": "00346"} | {"c2": "6", "c6": "6", "c7": "6 ", "c8": "foo", "C 1": "346"} + Thu Feb 26 00:00:00 1970 PST | {"c3": "00356"} | {"c2": "6", "c6": "6", "c7": "6 ", "c8": "foo", "C 1": "356"} | Thu Feb 26 00:00:00 1970 PST | {"c3": "00356"} | {"c2": "6", "c6": "6", "c7": "6 ", "c8": "foo", "C 1": "356"} + Sun Mar 08 00:00:00 1970 PST | {"c3": "00366"} | {"c2": "6", "c6": "6", "c7": "6 ", "c8": "foo", "C 1": "366"} | Sun Mar 08 00:00:00 1970 PST | {"c3": "00366"} | {"c2": "6", "c6": "6", "c7": "6 ", "c8": "foo", "C 1": "366"} + Wed Mar 18 00:00:00 1970 PST | {"c3": "00376"} | {"c2": "6", "c6": "6", "c7": "6 ", "c8": "foo", "C 1": "376"} | Wed Mar 18 00:00:00 1970 PST | {"c3": "00376"} | {"c2": "6", "c6": "6", "c7": "6 ", "c8": "foo", "C 1": "376"} + Sat Mar 28 00:00:00 1970 PST | {"c3": "00386"} | {"c2": "6", "c6": "6", "c7": "6 ", "c8": "foo", "C 1": "386"} | Sat Mar 28 00:00:00 1970 PST | {"c3": "00386"} | {"c2": "6", "c6": "6", "c7": "6 ", "c8": "foo", "C 1": "386"} + Tue Apr 07 00:00:00 1970 PST | {"c3": "00396"} | {"c2": "6", "c6": "6", "c7": "6 ", "c8": "foo", "C 1": "396"} | Tue Apr 07 00:00:00 1970 PST | {"c3": "00396"} | {"c2": "6", "c6": "6", "c7": "6 ", "c8": "foo", "C 1": "396"} + Wed Jan 07 00:00:00 1970 PST | {"c3": "00406"} | {"c2": "6", "c6": "6", "c7": "6 ", "c8": "foo", "C 1": "406"} | Wed Jan 07 00:00:00 1970 PST | {"c3": "00406"} | {"c2": "6", "c6": "6", "c7": "6 ", "c8": "foo", "C 1": "406"} + Sat Jan 17 00:00:00 1970 PST | {"c3": "00416"} | {"c2": "6", "c6": "6", "c7": "6 ", "c8": "foo", "C 1": "416"} | Sat Jan 17 00:00:00 1970 PST | {"c3": "00416"} | {"c2": "6", "c6": "6", "c7": "6 ", "c8": "foo", "C 1": "416"} + Tue Jan 27 00:00:00 1970 PST | {"c3": "00426"} | {"c2": "6", "c6": "6", "c7": "6 ", "c8": "foo", "C 1": "426"} | Tue Jan 27 00:00:00 1970 PST | {"c3": "00426"} | {"c2": "6", "c6": "6", "c7": "6 ", "c8": "foo", "C 1": "426"} + Fri Feb 06 00:00:00 1970 PST | {"c3": "00436"} | {"c2": "6", "c6": "6", "c7": "6 ", "c8": "foo", "C 1": "436"} | Fri Feb 06 00:00:00 1970 PST | {"c3": "00436"} | {"c2": "6", "c6": "6", "c7": "6 ", "c8": "foo", "C 1": "436"} + Mon Feb 16 00:00:00 1970 PST | {"c3": "00446"} | {"c2": "6", "c6": "6", "c7": "6 ", "c8": "foo", "C 1": "446"} | Mon Feb 16 00:00:00 1970 PST | {"c3": "00446"} | {"c2": "6", "c6": "6", "c7": "6 ", "c8": "foo", "C 1": "446"} + Thu Feb 26 00:00:00 1970 PST | {"c3": "00456"} | {"c2": "6", "c6": "6", "c7": "6 ", "c8": "foo", "C 1": "456"} | Thu Feb 26 00:00:00 1970 PST | {"c3": "00456"} | {"c2": "6", "c6": "6", "c7": "6 ", "c8": "foo", "C 1": "456"} + Sun Mar 08 00:00:00 1970 PST | {"c3": "00466"} | {"c2": "6", "c6": "6", "c7": "6 ", "c8": "foo", "C 1": "466"} | Sun Mar 08 00:00:00 1970 PST | {"c3": "00466"} | {"c2": "6", "c6": "6", "c7": "6 ", "c8": "foo", "C 1": "466"} + Wed Mar 18 00:00:00 1970 PST | {"c3": "00476"} | {"c2": "6", "c6": "6", "c7": "6 ", "c8": "foo", "C 1": "476"} | Wed Mar 18 00:00:00 1970 PST | {"c3": "00476"} | {"c2": "6", "c6": "6", "c7": "6 ", "c8": "foo", "C 1": "476"} + Sat Mar 28 00:00:00 1970 PST | {"c3": "00486"} | {"c2": "6", "c6": "6", "c7": "6 ", "c8": "foo", "C 1": "486"} | Sat Mar 28 00:00:00 1970 PST | {"c3": "00486"} | {"c2": "6", "c6": "6", "c7": "6 ", "c8": "foo", "C 1": "486"} + Tue Apr 07 00:00:00 1970 PST | {"c3": "00496"} | {"c2": "6", "c6": "6", "c7": "6 ", "c8": "foo", "C 1": "496"} | Tue Apr 07 00:00:00 1970 PST | {"c3": "00496"} | {"c2": "6", "c6": "6", "c7": "6 ", "c8": "foo", "C 1": "496"} + Wed Jan 07 00:00:00 1970 PST | {"c3": "00506"} | {"c2": "6", "c6": "6", "c7": "6 ", "c8": "foo", "C 1": "506"} | Wed Jan 07 00:00:00 1970 PST | {"c3": "00506"} | {"c2": "6", "c6": "6", "c7": "6 ", "c8": "foo", "C 1": "506"} + Sat Jan 17 00:00:00 1970 PST | {"c3": "00516"} | {"c2": "6", "c6": "6", "c7": "6 ", "c8": "foo", "C 1": "516"} | Sat Jan 17 00:00:00 1970 PST | {"c3": "00516"} | {"c2": "6", "c6": "6", "c7": "6 ", "c8": "foo", "C 1": "516"} + Tue Jan 27 00:00:00 1970 PST | {"c3": "00526"} | {"c2": "6", "c6": "6", "c7": "6 ", "c8": "foo", "C 1": "526"} | Tue Jan 27 00:00:00 1970 PST | {"c3": "00526"} | {"c2": "6", "c6": "6", "c7": "6 ", "c8": "foo", "C 1": "526"} + Fri Feb 06 00:00:00 1970 PST | {"c3": "00536"} | {"c2": "6", "c6": "6", "c7": "6 ", "c8": "foo", "C 1": "536"} | Fri Feb 06 00:00:00 1970 PST | {"c3": "00536"} | {"c2": "6", "c6": "6", "c7": "6 ", "c8": "foo", "C 1": "536"} + Mon Feb 16 00:00:00 1970 PST | {"c3": "00546"} | {"c2": "6", "c6": "6", "c7": "6 ", "c8": "foo", "C 1": "546"} | Mon Feb 16 00:00:00 1970 PST | {"c3": "00546"} | {"c2": "6", "c6": "6", "c7": "6 ", "c8": "foo", "C 1": "546"} + Thu Feb 26 00:00:00 1970 PST | {"c3": "00556"} | {"c2": "6", "c6": "6", "c7": "6 ", "c8": "foo", "C 1": "556"} | Thu Feb 26 00:00:00 1970 PST | {"c3": "00556"} | {"c2": "6", "c6": "6", "c7": "6 ", "c8": "foo", "C 1": "556"} + Sun Mar 08 00:00:00 1970 PST | {"c3": "00566"} | {"c2": "6", "c6": "6", "c7": "6 ", "c8": "foo", "C 1": "566"} | Sun Mar 08 00:00:00 1970 PST | {"c3": "00566"} | {"c2": "6", "c6": "6", "c7": "6 ", "c8": "foo", "C 1": "566"} + Wed Mar 18 00:00:00 1970 PST | {"c3": "00576"} | {"c2": "6", "c6": "6", "c7": "6 ", "c8": "foo", "C 1": "576"} | Wed Mar 18 00:00:00 1970 PST | {"c3": "00576"} | {"c2": "6", "c6": "6", "c7": "6 ", "c8": "foo", "C 1": "576"} + Sat Mar 28 00:00:00 1970 PST | {"c3": "00586"} | {"c2": "6", "c6": "6", "c7": "6 ", "c8": "foo", "C 1": "586"} | Sat Mar 28 00:00:00 1970 PST | {"c3": "00586"} | {"c2": "6", "c6": "6", "c7": "6 ", "c8": "foo", "C 1": "586"} + Tue Apr 07 00:00:00 1970 PST | {"c3": "00596"} | {"c2": "6", "c6": "6", "c7": "6 ", "c8": "foo", "C 1": "596"} | Tue Apr 07 00:00:00 1970 PST | {"c3": "00596"} | {"c2": "6", "c6": "6", "c7": "6 ", "c8": "foo", "C 1": "596"} + Wed Jan 07 00:00:00 1970 PST | {"c3": "00606"} | {"c2": "6", "c6": "6", "c7": "6 ", "c8": "foo", "C 1": "606"} | Wed Jan 07 00:00:00 1970 PST | {"c3": "00606"} | {"c2": "6", "c6": "6", "c7": "6 ", "c8": "foo", "C 1": "606"} + Sat Jan 17 00:00:00 1970 PST | {"c3": "00616"} | {"c2": "6", "c6": "6", "c7": "6 ", "c8": "foo", "C 1": "616"} | Sat Jan 17 00:00:00 1970 PST | {"c3": "00616"} | {"c2": "6", "c6": "6", "c7": "6 ", "c8": "foo", "C 1": "616"} + Tue Jan 27 00:00:00 1970 PST | {"c3": "00626"} | {"c2": "6", "c6": "6", "c7": "6 ", "c8": "foo", "C 1": "626"} | Tue Jan 27 00:00:00 1970 PST | {"c3": "00626"} | {"c2": "6", "c6": "6", "c7": "6 ", "c8": "foo", "C 1": "626"} + Fri Feb 06 00:00:00 1970 PST | {"c3": "00636"} | {"c2": "6", "c6": "6", "c7": "6 ", "c8": "foo", "C 1": "636"} | Fri Feb 06 00:00:00 1970 PST | {"c3": "00636"} | {"c2": "6", "c6": "6", "c7": "6 ", "c8": "foo", "C 1": "636"} + Mon Feb 16 00:00:00 1970 PST | {"c3": "00646"} | {"c2": "6", "c6": "6", "c7": "6 ", "c8": "foo", "C 1": "646"} | Mon Feb 16 00:00:00 1970 PST | {"c3": "00646"} | {"c2": "6", "c6": "6", "c7": "6 ", "c8": "foo", "C 1": "646"} + Thu Feb 26 00:00:00 1970 PST | {"c3": "00656"} | {"c2": "6", "c6": "6", "c7": "6 ", "c8": "foo", "C 1": "656"} | Thu Feb 26 00:00:00 1970 PST | {"c3": "00656"} | {"c2": "6", "c6": "6", "c7": "6 ", "c8": "foo", "C 1": "656"} + Sun Mar 08 00:00:00 1970 PST | {"c3": "00666"} | {"c2": "6", "c6": "6", "c7": "6 ", "c8": "foo", "C 1": "666"} | Sun Mar 08 00:00:00 1970 PST | {"c3": "00666"} | {"c2": "6", "c6": "6", "c7": "6 ", "c8": "foo", "C 1": "666"} + Wed Mar 18 00:00:00 1970 PST | {"c3": "00676"} | {"c2": "6", "c6": "6", "c7": "6 ", "c8": "foo", "C 1": "676"} | Wed Mar 18 00:00:00 1970 PST | {"c3": "00676"} | {"c2": "6", "c6": "6", "c7": "6 ", "c8": "foo", "C 1": "676"} + Sat Mar 28 00:00:00 1970 PST | {"c3": "00686"} | {"c2": "6", "c6": "6", "c7": "6 ", "c8": "foo", "C 1": "686"} | Sat Mar 28 00:00:00 1970 PST | {"c3": "00686"} | {"c2": "6", "c6": "6", "c7": "6 ", "c8": "foo", "C 1": "686"} + Tue Apr 07 00:00:00 1970 PST | {"c3": "00696"} | {"c2": "6", "c6": "6", "c7": "6 ", "c8": "foo", "C 1": "696"} | Tue Apr 07 00:00:00 1970 PST | {"c3": "00696"} | {"c2": "6", "c6": "6", "c7": "6 ", "c8": "foo", "C 1": "696"} + Wed Jan 07 00:00:00 1970 PST | {"c3": "00706"} | {"c2": "6", "c6": "6", "c7": "6 ", "c8": "foo", "C 1": "706"} | Wed Jan 07 00:00:00 1970 PST | {"c3": "00706"} | {"c2": "6", "c6": "6", "c7": "6 ", "c8": "foo", "C 1": "706"} + Sat Jan 17 00:00:00 1970 PST | {"c3": "00716"} | {"c2": "6", "c6": "6", "c7": "6 ", "c8": "foo", "C 1": "716"} | Sat Jan 17 00:00:00 1970 PST | {"c3": "00716"} | {"c2": "6", "c6": "6", "c7": "6 ", "c8": "foo", "C 1": "716"} + Tue Jan 27 00:00:00 1970 PST | {"c3": "00726"} | {"c2": "6", "c6": "6", "c7": "6 ", "c8": "foo", "C 1": "726"} | Tue Jan 27 00:00:00 1970 PST | {"c3": "00726"} | {"c2": "6", "c6": "6", "c7": "6 ", "c8": "foo", "C 1": "726"} + Fri Feb 06 00:00:00 1970 PST | {"c3": "00736"} | {"c2": "6", "c6": "6", "c7": "6 ", "c8": "foo", "C 1": "736"} | Fri Feb 06 00:00:00 1970 PST | {"c3": "00736"} | {"c2": "6", "c6": "6", "c7": "6 ", "c8": "foo", "C 1": "736"} + Mon Feb 16 00:00:00 1970 PST | {"c3": "00746"} | {"c2": "6", "c6": "6", "c7": "6 ", "c8": "foo", "C 1": "746"} | Mon Feb 16 00:00:00 1970 PST | {"c3": "00746"} | {"c2": "6", "c6": "6", "c7": "6 ", "c8": "foo", "C 1": "746"} + Thu Feb 26 00:00:00 1970 PST | {"c3": "00756"} | {"c2": "6", "c6": "6", "c7": "6 ", "c8": "foo", "C 1": "756"} | Thu Feb 26 00:00:00 1970 PST | {"c3": "00756"} | {"c2": "6", "c6": "6", "c7": "6 ", "c8": "foo", "C 1": "756"} + Sun Mar 08 00:00:00 1970 PST | {"c3": "00766"} | {"c2": "6", "c6": "6", "c7": "6 ", "c8": "foo", "C 1": "766"} | Sun Mar 08 00:00:00 1970 PST | {"c3": "00766"} | {"c2": "6", "c6": "6", "c7": "6 ", "c8": "foo", "C 1": "766"} + Wed Mar 18 00:00:00 1970 PST | {"c3": "00776"} | {"c2": "6", "c6": "6", "c7": "6 ", "c8": "foo", "C 1": "776"} | Wed Mar 18 00:00:00 1970 PST | {"c3": "00776"} | {"c2": "6", "c6": "6", "c7": "6 ", "c8": "foo", "C 1": "776"} + Sat Mar 28 00:00:00 1970 PST | {"c3": "00786"} | {"c2": "6", "c6": "6", "c7": "6 ", "c8": "foo", "C 1": "786"} | Sat Mar 28 00:00:00 1970 PST | {"c3": "00786"} | {"c2": "6", "c6": "6", "c7": "6 ", "c8": "foo", "C 1": "786"} + Tue Apr 07 00:00:00 1970 PST | {"c3": "00796"} | {"c2": "6", "c6": "6", "c7": "6 ", "c8": "foo", "C 1": "796"} | Tue Apr 07 00:00:00 1970 PST | {"c3": "00796"} | {"c2": "6", "c6": "6", "c7": "6 ", "c8": "foo", "C 1": "796"} + Wed Jan 07 00:00:00 1970 PST | {"c3": "00806"} | {"c2": "6", "c6": "6", "c7": "6 ", "c8": "foo", "C 1": "806"} | Wed Jan 07 00:00:00 1970 PST | {"c3": "00806"} | {"c2": "6", "c6": "6", "c7": "6 ", "c8": "foo", "C 1": "806"} + Sat Jan 17 00:00:00 1970 PST | {"c3": "00816"} | {"c2": "6", "c6": "6", "c7": "6 ", "c8": "foo", "C 1": "816"} | Sat Jan 17 00:00:00 1970 PST | {"c3": "00816"} | {"c2": "6", "c6": "6", "c7": "6 ", "c8": "foo", "C 1": "816"} + Tue Jan 27 00:00:00 1970 PST | {"c3": "00826"} | {"c2": "6", "c6": "6", "c7": "6 ", "c8": "foo", "C 1": "826"} | Tue Jan 27 00:00:00 1970 PST | {"c3": "00826"} | {"c2": "6", "c6": "6", "c7": "6 ", "c8": "foo", "C 1": "826"} + Fri Feb 06 00:00:00 1970 PST | {"c3": "00836"} | {"c2": "6", "c6": "6", "c7": "6 ", "c8": "foo", "C 1": "836"} | Fri Feb 06 00:00:00 1970 PST | {"c3": "00836"} | {"c2": "6", "c6": "6", "c7": "6 ", "c8": "foo", "C 1": "836"} + Mon Feb 16 00:00:00 1970 PST | {"c3": "00846"} | {"c2": "6", "c6": "6", "c7": "6 ", "c8": "foo", "C 1": "846"} | Mon Feb 16 00:00:00 1970 PST | {"c3": "00846"} | {"c2": "6", "c6": "6", "c7": "6 ", "c8": "foo", "C 1": "846"} + Thu Feb 26 00:00:00 1970 PST | {"c3": "00856"} | {"c2": "6", "c6": "6", "c7": "6 ", "c8": "foo", "C 1": "856"} | Thu Feb 26 00:00:00 1970 PST | {"c3": "00856"} | {"c2": "6", "c6": "6", "c7": "6 ", "c8": "foo", "C 1": "856"} + Sun Mar 08 00:00:00 1970 PST | {"c3": "00866"} | {"c2": "6", "c6": "6", "c7": "6 ", "c8": "foo", "C 1": "866"} | Sun Mar 08 00:00:00 1970 PST | {"c3": "00866"} | {"c2": "6", "c6": "6", "c7": "6 ", "c8": "foo", "C 1": "866"} + Wed Mar 18 00:00:00 1970 PST | {"c3": "00876"} | {"c2": "6", "c6": "6", "c7": "6 ", "c8": "foo", "C 1": "876"} | Wed Mar 18 00:00:00 1970 PST | {"c3": "00876"} | {"c2": "6", "c6": "6", "c7": "6 ", "c8": "foo", "C 1": "876"} + Sat Mar 28 00:00:00 1970 PST | {"c3": "00886"} | {"c2": "6", "c6": "6", "c7": "6 ", "c8": "foo", "C 1": "886"} | Sat Mar 28 00:00:00 1970 PST | {"c3": "00886"} | {"c2": "6", "c6": "6", "c7": "6 ", "c8": "foo", "C 1": "886"} + Tue Apr 07 00:00:00 1970 PST | {"c3": "00896"} | {"c2": "6", "c6": "6", "c7": "6 ", "c8": "foo", "C 1": "896"} | Tue Apr 07 00:00:00 1970 PST | {"c3": "00896"} | {"c2": "6", "c6": "6", "c7": "6 ", "c8": "foo", "C 1": "896"} + Wed Jan 07 00:00:00 1970 PST | {"c3": "00906"} | {"c2": "6", "c6": "6", "c7": "6 ", "c8": "foo", "C 1": "906"} | Wed Jan 07 00:00:00 1970 PST | {"c3": "00906"} | {"c2": "6", "c6": "6", "c7": "6 ", "c8": "foo", "C 1": "906"} + Sat Jan 17 00:00:00 1970 PST | {"c3": "00916"} | {"c2": "6", "c6": "6", "c7": "6 ", "c8": "foo", "C 1": "916"} | Sat Jan 17 00:00:00 1970 PST | {"c3": "00916"} | {"c2": "6", "c6": "6", "c7": "6 ", "c8": "foo", "C 1": "916"} + Tue Jan 27 00:00:00 1970 PST | {"c3": "00926"} | {"c2": "6", "c6": "6", "c7": "6 ", "c8": "foo", "C 1": "926"} | Tue Jan 27 00:00:00 1970 PST | {"c3": "00926"} | {"c2": "6", "c6": "6", "c7": "6 ", "c8": "foo", "C 1": "926"} + Fri Feb 06 00:00:00 1970 PST | {"c3": "00936"} | {"c2": "6", "c6": "6", "c7": "6 ", "c8": "foo", "C 1": "936"} | Fri Feb 06 00:00:00 1970 PST | {"c3": "00936"} | {"c2": "6", "c6": "6", "c7": "6 ", "c8": "foo", "C 1": "936"} + Mon Feb 16 00:00:00 1970 PST | {"c3": "00946"} | {"c2": "6", "c6": "6", "c7": "6 ", "c8": "foo", "C 1": "946"} | Mon Feb 16 00:00:00 1970 PST | {"c3": "00946"} | {"c2": "6", "c6": "6", "c7": "6 ", "c8": "foo", "C 1": "946"} + Thu Feb 26 00:00:00 1970 PST | {"c3": "00956"} | {"c2": "6", "c6": "6", "c7": "6 ", "c8": "foo", "C 1": "956"} | Thu Feb 26 00:00:00 1970 PST | {"c3": "00956"} | {"c2": "6", "c6": "6", "c7": "6 ", "c8": "foo", "C 1": "956"} + Sun Mar 08 00:00:00 1970 PST | {"c3": "00966"} | {"c2": "6", "c6": "6", "c7": "6 ", "c8": "foo", "C 1": "966"} | Sun Mar 08 00:00:00 1970 PST | {"c3": "00966"} | {"c2": "6", "c6": "6", "c7": "6 ", "c8": "foo", "C 1": "966"} + Wed Mar 18 00:00:00 1970 PST | {"c3": "00976"} | {"c2": "6", "c6": "6", "c7": "6 ", "c8": "foo", "C 1": "976"} | Wed Mar 18 00:00:00 1970 PST | {"c3": "00976"} | {"c2": "6", "c6": "6", "c7": "6 ", "c8": "foo", "C 1": "976"} + Sat Mar 28 00:00:00 1970 PST | {"c3": "00986"} | {"c2": "6", "c6": "6", "c7": "6 ", "c8": "foo", "C 1": "986"} | Sat Mar 28 00:00:00 1970 PST | {"c3": "00986"} | {"c2": "6", "c6": "6", "c7": "6 ", "c8": "foo", "C 1": "986"} + Tue Apr 07 00:00:00 1970 PST | {"c3": "00996"} | {"c2": "6", "c6": "6", "c7": "6 ", "c8": "foo", "C 1": "996"} | Tue Apr 07 00:00:00 1970 PST | {"c3": "00996"} | {"c2": "6", "c6": "6", "c7": "6 ", "c8": "foo", "C 1": "996"} (100 rows) -- bug before 9.3.5 due to sloppy handling of remote-estimate parameters --Testcase 74: SELECT * FROM ft1 WHERE (fields->>'C 1')::int = ANY (ARRAY(SELECT (fields->>'C 1')::int FROM ft2 WHERE (fields->>'C 1')::int < 5)); - time | tags | fields ---------------------------+-----------------+--------------------------------------------------------------------- - Fri Jan 02 00:00:00 1970 | {"c3": "00001"} | {"c2": "1", "c6": "1", "c7": "1 ", "c8": "foo", "C 1": "1"} - Sat Jan 03 00:00:00 1970 | {"c3": "00002"} | {"c2": "2", "c6": "2", "c7": "2 ", "c8": "foo", "C 1": "2"} - Sun Jan 04 00:00:00 1970 | {"c3": "00003"} | {"c2": "3", "c6": "3", "c7": "3 ", "c8": "foo", "C 1": "3"} - Mon Jan 05 00:00:00 1970 | {"c3": "00004"} | {"c2": "4", "c6": "4", "c7": "4 ", "c8": "foo", "C 1": "4"} + time | tags | fields +------------------------------+-----------------+--------------------------------------------------------------------- + Fri Jan 02 00:00:00 1970 PST | {"c3": "00001"} | {"c2": "1", "c6": "1", "c7": "1 ", "c8": "foo", "C 1": "1"} + Sat Jan 03 00:00:00 1970 PST | {"c3": "00002"} | {"c2": "2", "c6": "2", "c7": "2 ", "c8": "foo", "C 1": "2"} + Sun Jan 04 00:00:00 1970 PST | {"c3": "00003"} | {"c2": "3", "c6": "3", "c7": "3 ", "c8": "foo", "C 1": "3"} + Mon Jan 05 00:00:00 1970 PST | {"c3": "00004"} | {"c2": "4", "c6": "4", "c7": "4 ", "c8": "foo", "C 1": "4"} (4 rows) --Testcase 75: SELECT * FROM ft2 WHERE (fields->>'C 1')::int = ANY (ARRAY(SELECT (fields->>'C 1')::int FROM ft1 WHERE (fields->>'C 1')::int < 5)); - time | tags | fields ---------------------------+-----------------+--------------------------------------------------------------------- - Fri Jan 02 00:00:00 1970 | {"c3": "00001"} | {"c2": "1", "c6": "1", "c7": "1 ", "c8": "foo", "C 1": "1"} - Sat Jan 03 00:00:00 1970 | {"c3": "00002"} | {"c2": "2", "c6": "2", "c7": "2 ", "c8": "foo", "C 1": "2"} - Sun Jan 04 00:00:00 1970 | {"c3": "00003"} | {"c2": "3", "c6": "3", "c7": "3 ", "c8": "foo", "C 1": "3"} - Mon Jan 05 00:00:00 1970 | {"c3": "00004"} | {"c2": "4", "c6": "4", "c7": "4 ", "c8": "foo", "C 1": "4"} + time | tags | fields +------------------------------+-----------------+--------------------------------------------------------------------- + Fri Jan 02 00:00:00 1970 PST | {"c3": "00001"} | {"c2": "1", "c6": "1", "c7": "1 ", "c8": "foo", "C 1": "1"} + Sat Jan 03 00:00:00 1970 PST | {"c3": "00002"} | {"c2": "2", "c6": "2", "c7": "2 ", "c8": "foo", "C 1": "2"} + Sun Jan 04 00:00:00 1970 PST | {"c3": "00003"} | {"c2": "3", "c6": "3", "c7": "3 ", "c8": "foo", "C 1": "3"} + Mon Jan 05 00:00:00 1970 PST | {"c3": "00004"} | {"c2": "4", "c6": "4", "c7": "4 ", "c8": "foo", "C 1": "4"} (4 rows) -- we should not push order by clause with volatile expressions or unsafe @@ -1147,9 +1147,9 @@ EXPLAIN (VERBOSE, COSTS OFF) --Testcase 89: SELECT * FROM ft1 t1 WHERE (t1.fields->>'C 1')::int === (t1.fields->>'c2')::int order by (t1.fields->>'c2')::int limit 1; - time | tags | fields ---------------------------+-----------------+--------------------------------------------------------------------- - Fri Jan 02 00:00:00 1970 | {"c3": "00001"} | {"c2": "1", "c6": "1", "c7": "1 ", "c8": "foo", "C 1": "1"} + time | tags | fields +------------------------------+-----------------+--------------------------------------------------------------------- + Fri Jan 02 00:00:00 1970 PST | {"c3": "00001"} | {"c2": "1", "c6": "1", "c7": "1 ", "c8": "foo", "C 1": "1"} (1 row) -- but let's put them in an extension ... @@ -1216,9 +1216,9 @@ EXPLAIN (VERBOSE, COSTS OFF) --Testcase 95: SELECT * FROM ft1 t1 WHERE (t1.fields->>'C 1')::int === (t1.fields->>'c2')::int order by (t1.fields->>'c2')::int limit 1; - time | tags | fields ---------------------------+-----------------+--------------------------------------------------------------------- - Fri Jan 02 00:00:00 1970 | {"c3": "00001"} | {"c2": "1", "c6": "1", "c7": "1 ", "c8": "foo", "C 1": "1"} + time | tags | fields +------------------------------+-----------------+--------------------------------------------------------------------- + Fri Jan 02 00:00:00 1970 PST | {"c3": "00001"} | {"c2": "1", "c6": "1", "c7": "1 ", "c8": "foo", "C 1": "1"} (1 row) -- This test case drop configuration when execute non-schemaless before @@ -3119,18 +3119,18 @@ SELECT * FROM ft1, ft2, ft4, ft5, local_tbl WHERE (ft1.fields->>'C 1')::int = (f --Testcase 181: SELECT * FROM ft1, ft2, ft4, ft5, local_tbl WHERE (ft1.fields->>'C 1')::int = (ft2.fields->>'C 1')::int AND (ft1.fields->>'c2')::int = (ft4.fields->>'c1')::int AND (ft1.fields->>'c2')::int = (ft5.fields->>'c1')::int AND (ft1.fields->>'c2')::int = (local_tbl.fields->>'c1')::int AND (ft1.fields->>'C 1')::int < 100 AND (ft2.fields->>'C 1')::int < 100 ORDER BY (ft1.fields->>'C 1')::int FOR UPDATE; - time | tags | fields | time | tags | fields | tags | fields | tags | fields | fields ---------------------------+-----------------+----------------------------------------------------------------------+--------------------------+-----------------+----------------------------------------------------------------------+------------------+------------------------+------------------+------------------------+-------------------------------------- - Wed Jan 07 00:00:00 1970 | {"c3": "00006"} | {"c2": "6", "c6": "6", "c7": "6 ", "c8": "foo", "C 1": "6"} | Wed Jan 07 00:00:00 1970 | {"c3": "00006"} | {"c2": "6", "c6": "6", "c7": "6 ", "c8": "foo", "C 1": "6"} | {"c3": "AAA006"} | {"c1": "6", "c2": "7"} | {"c3": "AAA006"} | {"c1": "6", "c2": "7"} | {"c1": "6", "c2": "6", "c3": "0006"} - Sat Jan 17 00:00:00 1970 | {"c3": "00016"} | {"c2": "6", "c6": "6", "c7": "6 ", "c8": "foo", "C 1": "16"} | Sat Jan 17 00:00:00 1970 | {"c3": "00016"} | {"c2": "6", "c6": "6", "c7": "6 ", "c8": "foo", "C 1": "16"} | {"c3": "AAA006"} | {"c1": "6", "c2": "7"} | {"c3": "AAA006"} | {"c1": "6", "c2": "7"} | {"c1": "6", "c2": "6", "c3": "0006"} - Tue Jan 27 00:00:00 1970 | {"c3": "00026"} | {"c2": "6", "c6": "6", "c7": "6 ", "c8": "foo", "C 1": "26"} | Tue Jan 27 00:00:00 1970 | {"c3": "00026"} | {"c2": "6", "c6": "6", "c7": "6 ", "c8": "foo", "C 1": "26"} | {"c3": "AAA006"} | {"c1": "6", "c2": "7"} | {"c3": "AAA006"} | {"c1": "6", "c2": "7"} | {"c1": "6", "c2": "6", "c3": "0006"} - Fri Feb 06 00:00:00 1970 | {"c3": "00036"} | {"c2": "6", "c6": "6", "c7": "6 ", "c8": "foo", "C 1": "36"} | Fri Feb 06 00:00:00 1970 | {"c3": "00036"} | {"c2": "6", "c6": "6", "c7": "6 ", "c8": "foo", "C 1": "36"} | {"c3": "AAA006"} | {"c1": "6", "c2": "7"} | {"c3": "AAA006"} | {"c1": "6", "c2": "7"} | {"c1": "6", "c2": "6", "c3": "0006"} - Mon Feb 16 00:00:00 1970 | {"c3": "00046"} | {"c2": "6", "c6": "6", "c7": "6 ", "c8": "foo", "C 1": "46"} | Mon Feb 16 00:00:00 1970 | {"c3": "00046"} | {"c2": "6", "c6": "6", "c7": "6 ", "c8": "foo", "C 1": "46"} | {"c3": "AAA006"} | {"c1": "6", "c2": "7"} | {"c3": "AAA006"} | {"c1": "6", "c2": "7"} | {"c1": "6", "c2": "6", "c3": "0006"} - Thu Feb 26 00:00:00 1970 | {"c3": "00056"} | {"c2": "6", "c6": "6", "c7": "6 ", "c8": "foo", "C 1": "56"} | Thu Feb 26 00:00:00 1970 | {"c3": "00056"} | {"c2": "6", "c6": "6", "c7": "6 ", "c8": "foo", "C 1": "56"} | {"c3": "AAA006"} | {"c1": "6", "c2": "7"} | {"c3": "AAA006"} | {"c1": "6", "c2": "7"} | {"c1": "6", "c2": "6", "c3": "0006"} - Sun Mar 08 00:00:00 1970 | {"c3": "00066"} | {"c2": "6", "c6": "6", "c7": "6 ", "c8": "foo", "C 1": "66"} | Sun Mar 08 00:00:00 1970 | {"c3": "00066"} | {"c2": "6", "c6": "6", "c7": "6 ", "c8": "foo", "C 1": "66"} | {"c3": "AAA006"} | {"c1": "6", "c2": "7"} | {"c3": "AAA006"} | {"c1": "6", "c2": "7"} | {"c1": "6", "c2": "6", "c3": "0006"} - Wed Mar 18 00:00:00 1970 | {"c3": "00076"} | {"c2": "6", "c6": "6", "c7": "6 ", "c8": "foo", "C 1": "76"} | Wed Mar 18 00:00:00 1970 | {"c3": "00076"} | {"c2": "6", "c6": "6", "c7": "6 ", "c8": "foo", "C 1": "76"} | {"c3": "AAA006"} | {"c1": "6", "c2": "7"} | {"c3": "AAA006"} | {"c1": "6", "c2": "7"} | {"c1": "6", "c2": "6", "c3": "0006"} - Sat Mar 28 00:00:00 1970 | {"c3": "00086"} | {"c2": "6", "c6": "6", "c7": "6 ", "c8": "foo", "C 1": "86"} | Sat Mar 28 00:00:00 1970 | {"c3": "00086"} | {"c2": "6", "c6": "6", "c7": "6 ", "c8": "foo", "C 1": "86"} | {"c3": "AAA006"} | {"c1": "6", "c2": "7"} | {"c3": "AAA006"} | {"c1": "6", "c2": "7"} | {"c1": "6", "c2": "6", "c3": "0006"} - Tue Apr 07 00:00:00 1970 | {"c3": "00096"} | {"c2": "6", "c6": "6", "c7": "6 ", "c8": "foo", "C 1": "96"} | Tue Apr 07 00:00:00 1970 | {"c3": "00096"} | {"c2": "6", "c6": "6", "c7": "6 ", "c8": "foo", "C 1": "96"} | {"c3": "AAA006"} | {"c1": "6", "c2": "7"} | {"c3": "AAA006"} | {"c1": "6", "c2": "7"} | {"c1": "6", "c2": "6", "c3": "0006"} + time | tags | fields | time | tags | fields | tags | fields | tags | fields | fields +------------------------------+-----------------+----------------------------------------------------------------------+------------------------------+-----------------+----------------------------------------------------------------------+------------------+------------------------+------------------+------------------------+-------------------------------------- + Wed Jan 07 00:00:00 1970 PST | {"c3": "00006"} | {"c2": "6", "c6": "6", "c7": "6 ", "c8": "foo", "C 1": "6"} | Wed Jan 07 00:00:00 1970 PST | {"c3": "00006"} | {"c2": "6", "c6": "6", "c7": "6 ", "c8": "foo", "C 1": "6"} | {"c3": "AAA006"} | {"c1": "6", "c2": "7"} | {"c3": "AAA006"} | {"c1": "6", "c2": "7"} | {"c1": "6", "c2": "6", "c3": "0006"} + Sat Jan 17 00:00:00 1970 PST | {"c3": "00016"} | {"c2": "6", "c6": "6", "c7": "6 ", "c8": "foo", "C 1": "16"} | Sat Jan 17 00:00:00 1970 PST | {"c3": "00016"} | {"c2": "6", "c6": "6", "c7": "6 ", "c8": "foo", "C 1": "16"} | {"c3": "AAA006"} | {"c1": "6", "c2": "7"} | {"c3": "AAA006"} | {"c1": "6", "c2": "7"} | {"c1": "6", "c2": "6", "c3": "0006"} + Tue Jan 27 00:00:00 1970 PST | {"c3": "00026"} | {"c2": "6", "c6": "6", "c7": "6 ", "c8": "foo", "C 1": "26"} | Tue Jan 27 00:00:00 1970 PST | {"c3": "00026"} | {"c2": "6", "c6": "6", "c7": "6 ", "c8": "foo", "C 1": "26"} | {"c3": "AAA006"} | {"c1": "6", "c2": "7"} | {"c3": "AAA006"} | {"c1": "6", "c2": "7"} | {"c1": "6", "c2": "6", "c3": "0006"} + Fri Feb 06 00:00:00 1970 PST | {"c3": "00036"} | {"c2": "6", "c6": "6", "c7": "6 ", "c8": "foo", "C 1": "36"} | Fri Feb 06 00:00:00 1970 PST | {"c3": "00036"} | {"c2": "6", "c6": "6", "c7": "6 ", "c8": "foo", "C 1": "36"} | {"c3": "AAA006"} | {"c1": "6", "c2": "7"} | {"c3": "AAA006"} | {"c1": "6", "c2": "7"} | {"c1": "6", "c2": "6", "c3": "0006"} + Mon Feb 16 00:00:00 1970 PST | {"c3": "00046"} | {"c2": "6", "c6": "6", "c7": "6 ", "c8": "foo", "C 1": "46"} | Mon Feb 16 00:00:00 1970 PST | {"c3": "00046"} | {"c2": "6", "c6": "6", "c7": "6 ", "c8": "foo", "C 1": "46"} | {"c3": "AAA006"} | {"c1": "6", "c2": "7"} | {"c3": "AAA006"} | {"c1": "6", "c2": "7"} | {"c1": "6", "c2": "6", "c3": "0006"} + Thu Feb 26 00:00:00 1970 PST | {"c3": "00056"} | {"c2": "6", "c6": "6", "c7": "6 ", "c8": "foo", "C 1": "56"} | Thu Feb 26 00:00:00 1970 PST | {"c3": "00056"} | {"c2": "6", "c6": "6", "c7": "6 ", "c8": "foo", "C 1": "56"} | {"c3": "AAA006"} | {"c1": "6", "c2": "7"} | {"c3": "AAA006"} | {"c1": "6", "c2": "7"} | {"c1": "6", "c2": "6", "c3": "0006"} + Sun Mar 08 00:00:00 1970 PST | {"c3": "00066"} | {"c2": "6", "c6": "6", "c7": "6 ", "c8": "foo", "C 1": "66"} | Sun Mar 08 00:00:00 1970 PST | {"c3": "00066"} | {"c2": "6", "c6": "6", "c7": "6 ", "c8": "foo", "C 1": "66"} | {"c3": "AAA006"} | {"c1": "6", "c2": "7"} | {"c3": "AAA006"} | {"c1": "6", "c2": "7"} | {"c1": "6", "c2": "6", "c3": "0006"} + Wed Mar 18 00:00:00 1970 PST | {"c3": "00076"} | {"c2": "6", "c6": "6", "c7": "6 ", "c8": "foo", "C 1": "76"} | Wed Mar 18 00:00:00 1970 PST | {"c3": "00076"} | {"c2": "6", "c6": "6", "c7": "6 ", "c8": "foo", "C 1": "76"} | {"c3": "AAA006"} | {"c1": "6", "c2": "7"} | {"c3": "AAA006"} | {"c1": "6", "c2": "7"} | {"c1": "6", "c2": "6", "c3": "0006"} + Sat Mar 28 00:00:00 1970 PST | {"c3": "00086"} | {"c2": "6", "c6": "6", "c7": "6 ", "c8": "foo", "C 1": "86"} | Sat Mar 28 00:00:00 1970 PST | {"c3": "00086"} | {"c2": "6", "c6": "6", "c7": "6 ", "c8": "foo", "C 1": "86"} | {"c3": "AAA006"} | {"c1": "6", "c2": "7"} | {"c3": "AAA006"} | {"c1": "6", "c2": "7"} | {"c1": "6", "c2": "6", "c3": "0006"} + Tue Apr 07 00:00:00 1970 PST | {"c3": "00096"} | {"c2": "6", "c6": "6", "c7": "6 ", "c8": "foo", "C 1": "96"} | Tue Apr 07 00:00:00 1970 PST | {"c3": "00096"} | {"c2": "6", "c6": "6", "c7": "6 ", "c8": "foo", "C 1": "96"} | {"c3": "AAA006"} | {"c1": "6", "c2": "7"} | {"c3": "AAA006"} | {"c1": "6", "c2": "7"} | {"c1": "6", "c2": "6", "c3": "0006"} (10 rows) RESET enable_nestloop; @@ -3788,9 +3788,9 @@ select array_agg(time order by (fields->>'C 1')::int desc) from ft2 where (field --Testcase 228: select array_agg(time order by (fields->>'C 1')::int desc) from ft2 where (fields->>'c2')::int = 6 and (fields->>'C 1')::int < 50; - array_agg ------------------------------------------------------------------------------------------------------------------------------------------- - {"Mon Feb 16 00:00:00 1970","Fri Feb 06 00:00:00 1970","Tue Jan 27 00:00:00 1970","Sat Jan 17 00:00:00 1970","Wed Jan 07 00:00:00 1970"} + array_agg +-------------------------------------------------------------------------------------------------------------------------------------------------------------- + {"Mon Feb 16 00:00:00 1970 PST","Fri Feb 06 00:00:00 1970 PST","Tue Jan 27 00:00:00 1970 PST","Sat Jan 17 00:00:00 1970 PST","Wed Jan 07 00:00:00 1970 PST"} (1 row) -- DISTINCT within aggregate @@ -4958,16 +4958,16 @@ EXPLAIN (VERBOSE, COSTS OFF) EXECUTE st2(10, 20); --Testcase 310: EXECUTE st2(10, 20); - time | tags | fields ---------------------------+-----------------+---------------------------------------------------------------------- - Sat Jan 17 00:00:00 1970 | {"c3": "00016"} | {"c2": "6", "c6": "6", "c7": "6 ", "c8": "foo", "C 1": "16"} + time | tags | fields +------------------------------+-----------------+---------------------------------------------------------------------- + Sat Jan 17 00:00:00 1970 PST | {"c3": "00016"} | {"c2": "6", "c6": "6", "c7": "6 ", "c8": "foo", "C 1": "16"} (1 row) --Testcase 311: EXECUTE st2(101, 121); - time | tags | fields ---------------------------+-----------------+----------------------------------------------------------------------- - Sat Jan 17 00:00:00 1970 | {"c3": "00116"} | {"c2": "6", "c6": "6", "c7": "6 ", "c8": "foo", "C 1": "116"} + time | tags | fields +------------------------------+-----------------+----------------------------------------------------------------------- + Sat Jan 17 00:00:00 1970 PST | {"c3": "00116"} | {"c2": "6", "c6": "6", "c7": "6 ", "c8": "foo", "C 1": "116"} (1 row) -- subquery using immutable function (can be sent to remote) @@ -4996,9 +4996,9 @@ EXPLAIN (VERBOSE, COSTS OFF) EXECUTE st3(10, 20); --Testcase 314: EXECUTE st3(10, 20); - time | tags | fields ---------------------------+-----------------+---------------------------------------------------------------------- - Sat Jan 17 00:00:00 1970 | {"c3": "00016"} | {"c2": "6", "c6": "6", "c7": "6 ", "c8": "foo", "C 1": "16"} + time | tags | fields +------------------------------+-----------------+---------------------------------------------------------------------- + Sat Jan 17 00:00:00 1970 PST | {"c3": "00016"} | {"c2": "6", "c6": "6", "c7": "6 ", "c8": "foo", "C 1": "16"} (1 row) --Testcase 315: @@ -5124,9 +5124,9 @@ EXPLAIN (VERBOSE, COSTS OFF) EXECUTE st5('foo', 1); --Testcase 330: EXECUTE st5('foo', 1); - time | tags | fields ---------------------------+-----------------+--------------------------------------------------------------------- - Fri Jan 02 00:00:00 1970 | {"c3": "00001"} | {"c2": "1", "c6": "1", "c7": "1 ", "c8": "foo", "C 1": "1"} + time | tags | fields +------------------------------+-----------------+--------------------------------------------------------------------- + Fri Jan 02 00:00:00 1970 PST | {"c3": "00001"} | {"c2": "1", "c6": "1", "c7": "1 ", "c8": "foo", "C 1": "1"} (1 row) -- altering FDW options requires replanning @@ -5145,11 +5145,11 @@ EXPLAIN (VERBOSE, COSTS OFF) EXECUTE st6; PREPARE st7 AS INSERT INTO ft1_nsc (c1,c2,c3) VALUES (1001,101,'foo'); --Testcase 334: EXPLAIN (VERBOSE, COSTS OFF) EXECUTE st7; - QUERY PLAN ------------------------------------------------------------------------------------------------------------------------------------------------------------- + QUERY PLAN +--------------------------------------------------------------------------------------------------------------------------------------------------------- Insert on public.ft1_nsc -> Result - Output: NULL::integer, 1001, 101, 'foo'::text, NULL::timestamp without time zone, NULL::character varying, 'ft1 '::character(10), NULL::text + Output: NULL::integer, 1001, 101, 'foo'::text, NULL::timestamp with time zone, NULL::character varying, 'ft1 '::character(10), NULL::text (3 rows) --Testcase 335: @@ -5166,26 +5166,26 @@ EXPLAIN (VERBOSE, COSTS OFF) EXECUTE st6; --Testcase 337: EXECUTE st6; - time | tags | fields ---------------------------+-----------------+--------------------------------------------------------------------- - Fri Jan 02 00:00:00 1970 | {"c3": "00001"} | {"c2": "1", "c6": "1", "c7": "1 ", "c8": "foo", "C 1": "1"} - Sat Jan 03 00:00:00 1970 | {"c3": "00002"} | {"c2": "2", "c6": "2", "c7": "2 ", "c8": "foo", "C 1": "2"} - Sun Jan 04 00:00:00 1970 | {"c3": "00003"} | {"c2": "3", "c6": "3", "c7": "3 ", "c8": "foo", "C 1": "3"} - Mon Jan 05 00:00:00 1970 | {"c3": "00004"} | {"c2": "4", "c6": "4", "c7": "4 ", "c8": "foo", "C 1": "4"} - Tue Jan 06 00:00:00 1970 | {"c3": "00005"} | {"c2": "5", "c6": "5", "c7": "5 ", "c8": "foo", "C 1": "5"} - Wed Jan 07 00:00:00 1970 | {"c3": "00006"} | {"c2": "6", "c6": "6", "c7": "6 ", "c8": "foo", "C 1": "6"} - Thu Jan 08 00:00:00 1970 | {"c3": "00007"} | {"c2": "7", "c6": "7", "c7": "7 ", "c8": "foo", "C 1": "7"} - Fri Jan 09 00:00:00 1970 | {"c3": "00008"} | {"c2": "8", "c6": "8", "c7": "8 ", "c8": "foo", "C 1": "8"} - Sat Jan 10 00:00:00 1970 | {"c3": "00009"} | {"c2": "9", "c6": "9", "c7": "9 ", "c8": "foo", "C 1": "9"} + time | tags | fields +------------------------------+-----------------+--------------------------------------------------------------------- + Fri Jan 02 00:00:00 1970 PST | {"c3": "00001"} | {"c2": "1", "c6": "1", "c7": "1 ", "c8": "foo", "C 1": "1"} + Sat Jan 03 00:00:00 1970 PST | {"c3": "00002"} | {"c2": "2", "c6": "2", "c7": "2 ", "c8": "foo", "C 1": "2"} + Sun Jan 04 00:00:00 1970 PST | {"c3": "00003"} | {"c2": "3", "c6": "3", "c7": "3 ", "c8": "foo", "C 1": "3"} + Mon Jan 05 00:00:00 1970 PST | {"c3": "00004"} | {"c2": "4", "c6": "4", "c7": "4 ", "c8": "foo", "C 1": "4"} + Tue Jan 06 00:00:00 1970 PST | {"c3": "00005"} | {"c2": "5", "c6": "5", "c7": "5 ", "c8": "foo", "C 1": "5"} + Wed Jan 07 00:00:00 1970 PST | {"c3": "00006"} | {"c2": "6", "c6": "6", "c7": "6 ", "c8": "foo", "C 1": "6"} + Thu Jan 08 00:00:00 1970 PST | {"c3": "00007"} | {"c2": "7", "c6": "7", "c7": "7 ", "c8": "foo", "C 1": "7"} + Fri Jan 09 00:00:00 1970 PST | {"c3": "00008"} | {"c2": "8", "c6": "8", "c7": "8 ", "c8": "foo", "C 1": "8"} + Sat Jan 10 00:00:00 1970 PST | {"c3": "00009"} | {"c2": "9", "c6": "9", "c7": "9 ", "c8": "foo", "C 1": "9"} (9 rows) --Testcase 338: EXPLAIN (VERBOSE, COSTS OFF) EXECUTE st7; - QUERY PLAN ------------------------------------------------------------------------------------------------------------------------------------------------------------- + QUERY PLAN +--------------------------------------------------------------------------------------------------------------------------------------------------------- Insert on public.ft1_nsc -> Result - Output: NULL::integer, 1001, 101, 'foo'::text, NULL::timestamp without time zone, NULL::character varying, 'ft1 '::character(10), NULL::text + Output: NULL::integer, 1001, 101, 'foo'::text, NULL::timestamp with time zone, NULL::character varying, 'ft1 '::character(10), NULL::text (3 rows) --Testcase 339: @@ -5252,9 +5252,9 @@ SELECT * FROM ft1 t1 WHERE t1.tableoid = 'pg_class'::regclass LIMIT 1; --Testcase 345: SELECT * FROM ft1 t1 WHERE t1.tableoid = 'ft1'::regclass ORDER BY (fields->>'C 1')::int LIMIT 1; - time | tags | fields ---------------------------+-----------------+--------------------------------------------------------------------- - Fri Jan 02 00:00:00 1970 | {"c3": "00001"} | {"c2": "1", "c6": "1", "c7": "1 ", "c8": "foo", "C 1": "1"} + time | tags | fields +------------------------------+-----------------+--------------------------------------------------------------------- + Fri Jan 02 00:00:00 1970 PST | {"c3": "00001"} | {"c2": "1", "c6": "1", "c7": "1 ", "c8": "foo", "C 1": "1"} (1 row) --Testcase 346: @@ -5269,9 +5269,9 @@ SELECT tableoid::regclass, * FROM ft1 t1 LIMIT 1; --Testcase 347: SELECT tableoid::regclass, * FROM ft1 t1 ORDER BY (fields->>'C 1')::int LIMIT 1; - tableoid | time | tags | fields -----------+--------------------------+-----------------+--------------------------------------------------------------------- - ft1 | Fri Jan 02 00:00:00 1970 | {"c3": "00001"} | {"c2": "1", "c6": "1", "c7": "1 ", "c8": "foo", "C 1": "1"} + tableoid | time | tags | fields +----------+------------------------------+-----------------+--------------------------------------------------------------------- + ft1 | Fri Jan 02 00:00:00 1970 PST | {"c3": "00001"} | {"c2": "1", "c6": "1", "c7": "1 ", "c8": "foo", "C 1": "1"} (1 row) --Testcase 348: @@ -5303,9 +5303,9 @@ SELECT ctid, * FROM ft1 t1 LIMIT 1; --Testcase 351: SELECT ctid, * FROM ft1 t1 ORDER BY (fields->>'C 1')::int LIMIT 1; - ctid | time | tags | fields -----------------+--------------------------+-----------------+--------------------------------------------------------------------- - (4294967295,0) | Fri Jan 02 00:00:00 1970 | {"c3": "00001"} | {"c2": "1", "c6": "1", "c7": "1 ", "c8": "foo", "C 1": "1"} + ctid | time | tags | fields +----------------+------------------------------+-----------------+--------------------------------------------------------------------- + (4294967295,0) | Fri Jan 02 00:00:00 1970 PST | {"c3": "00001"} | {"c2": "1", "c6": "1", "c7": "1 ", "c8": "foo", "C 1": "1"} (1 row) -- =================================================================== @@ -5490,11 +5490,11 @@ explain (verbose, costs off) select * from ft3 f, loct3 l --Testcase 372: EXPLAIN (verbose, costs off) INSERT INTO ft2_nsc (c1,c2,c3) SELECT c1+1000,c2+100, c3 || c3 FROM ft2_nsc ORDER BY c1 LIMIT 20; - QUERY PLAN -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- + QUERY PLAN +---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- Insert on public.ft2_nsc -> Subquery Scan on "*SELECT*" - Output: "*SELECT*"."?column?", "*SELECT*"."?column?_1", NULL::integer, "*SELECT*"."?column?_2", NULL::timestamp without time zone, NULL::character varying, 'ft2 '::character(10), NULL::text + Output: "*SELECT*"."?column?", "*SELECT*"."?column?_1", NULL::integer, "*SELECT*"."?column?_2", NULL::timestamp with time zone, NULL::character varying, 'ft2 '::character(10), NULL::text -> Limit Output: ((ft2_nsc_1.c1 + 1000)), ((ft2_nsc_1.c2 + 100)), ((ft2_nsc_1.c3 || ft2_nsc_1.c3)), ft2_nsc_1.c1 -> Sort @@ -6508,11 +6508,11 @@ SELECT (fields->>'C 1')::int c1, (fields->>'c2')::int c2, tags->>'c3' c3 FROM ft --Testcase 384: EXPLAIN (verbose, costs off) INSERT INTO ft2_nsc (c1,c2,c3) VALUES (1200,999,'foo'); - QUERY PLAN ------------------------------------------------------------------------------------------------------------------------------------------------------------- + QUERY PLAN +--------------------------------------------------------------------------------------------------------------------------------------------------------- Insert on public.ft2_nsc -> Result - Output: 1200, 999, NULL::integer, 'foo'::text, NULL::timestamp without time zone, NULL::character varying, 'ft2 '::character(10), NULL::text + Output: 1200, 999, NULL::integer, 'foo'::text, NULL::timestamp with time zone, NULL::character varying, 'ft2 '::character(10), NULL::text (3 rows) --Testcase 385: @@ -8882,7 +8882,7 @@ CREATE FOREIGN TABLE ft1_nopw ( c2 int NOT NULL, c3 text, c4 timestamptz, - c5 timestamp, + c5 timestamptz, c6 varchar(10), c7 char(10) default 'ft1', c8 user_enum diff --git a/expected/12.12/schemaless/extra/insert.out b/expected/13.12/schemaless/extra/insert.out similarity index 100% rename from expected/12.12/schemaless/extra/insert.out rename to expected/13.12/schemaless/extra/insert.out diff --git a/expected/13.8/schemaless/extra/join.out b/expected/13.12/schemaless/extra/join.out similarity index 100% rename from expected/13.8/schemaless/extra/join.out rename to expected/13.12/schemaless/extra/join.out diff --git a/expected/13.8/schemaless/extra/limit.out b/expected/13.12/schemaless/extra/limit.out similarity index 100% rename from expected/13.8/schemaless/extra/limit.out rename to expected/13.12/schemaless/extra/limit.out diff --git a/expected/13.8/schemaless/extra/prepare.out b/expected/13.12/schemaless/extra/prepare.out similarity index 100% rename from expected/13.8/schemaless/extra/prepare.out rename to expected/13.12/schemaless/extra/prepare.out diff --git a/expected/12.12/schemaless/extra/select.out b/expected/13.12/schemaless/extra/select.out similarity index 100% rename from expected/12.12/schemaless/extra/select.out rename to expected/13.12/schemaless/extra/select.out diff --git a/expected/12.12/schemaless/extra/select_having.out b/expected/13.12/schemaless/extra/select_having.out similarity index 100% rename from expected/12.12/schemaless/extra/select_having.out rename to expected/13.12/schemaless/extra/select_having.out diff --git a/expected/12.12/schemaless/influxdb_fdw.out b/expected/13.12/schemaless/influxdb_fdw.out similarity index 99% rename from expected/12.12/schemaless/influxdb_fdw.out rename to expected/13.12/schemaless/influxdb_fdw.out index 9776ad4..cb9325d 100644 --- a/expected/12.12/schemaless/influxdb_fdw.out +++ b/expected/13.12/schemaless/influxdb_fdw.out @@ -1130,14 +1130,14 @@ SELECT * FROM t5; SELECT * FROM public.influxdb_fdw_version(); influxdb_fdw_version ---------------------- - 20000 + 20100 (1 row) --Testcase 146: SELECT influxdb_fdw_version(); influxdb_fdw_version ---------------------- - 20000 + 20100 (1 row) --Test pushdown LIMIT...OFFSET diff --git a/expected/13.8/schemaless/schemaless.out b/expected/13.12/schemaless/schemaless.out similarity index 100% rename from expected/13.8/schemaless/schemaless.out rename to expected/13.12/schemaless/schemaless.out diff --git a/expected/13.8/schemaless/selectfunc.out b/expected/13.12/schemaless/selectfunc.out similarity index 100% rename from expected/13.8/schemaless/selectfunc.out rename to expected/13.12/schemaless/selectfunc.out diff --git a/expected/13.8/selectfunc.out b/expected/13.12/selectfunc.out similarity index 100% rename from expected/13.8/selectfunc.out rename to expected/13.12/selectfunc.out diff --git a/expected/13.8/aggregate.out b/expected/14.9/aggregate.out similarity index 100% rename from expected/13.8/aggregate.out rename to expected/14.9/aggregate.out diff --git a/expected/14.5/extra/aggregates.out b/expected/14.9/extra/aggregates.out similarity index 100% rename from expected/14.5/extra/aggregates.out rename to expected/14.9/extra/aggregates.out diff --git a/expected/14.5/extra/influxdb_fdw_post.out b/expected/14.9/extra/influxdb_fdw_post.out similarity index 92% rename from expected/14.5/extra/influxdb_fdw_post.out rename to expected/14.9/extra/influxdb_fdw_post.out index 2c5cc8d..d9024d5 100644 --- a/expected/14.5/extra/influxdb_fdw_post.out +++ b/expected/14.9/extra/influxdb_fdw_post.out @@ -30,7 +30,7 @@ CREATE FOREIGN TABLE "S 1"."T 0" ( "C 1" int NOT NULL, c2 int NOT NULL, c3 text, - time timestamp, + time timestamptz, c6 varchar(10), c7 char(10), c8 text @@ -40,7 +40,7 @@ CREATE FOREIGN TABLE "S 1"."T 1" ( "C 1" int NOT NULL, c2 int NOT NULL, c3 text, - time timestamp, + time timestamptz, c6 varchar(10), c7 char(10), c8 text @@ -72,7 +72,7 @@ INSERT INTO "S 1"."T 1" SELECT id, id % 10, to_char(id, 'FM00000'), - '1970-01-01'::timestamp + ((id % 100) || ' days')::interval, + '1970-01-01'::timestamptz + ((id % 100) || ' days')::interval, id % 10, id % 10, 'foo'::text @@ -111,7 +111,7 @@ CREATE FOREIGN TABLE ft1 ( c1 int NOT NULL, c2 int NOT NULL, c3 text, - time timestamp, + time timestamptz, c6 varchar(10), c7 char(10) default 'ft1', c8 text @@ -124,7 +124,7 @@ CREATE FOREIGN TABLE ft2 ( c2 int NOT NULL, cx int, c3 text, - time timestamp, + time timestamptz, c6 varchar(10), c7 char(10) default 'ft2', c8 text @@ -229,9 +229,9 @@ ALTER FOREIGN TABLE ft2 ALTER COLUMN c1 OPTIONS (column_name 'C 1'); \set VERBOSITY terse --Testcase 35: SELECT c3, time FROM ft1 ORDER BY c3, c1 LIMIT 1; -- should work - c3 | time --------+-------------------------- - 00001 | Fri Jan 02 00:00:00 1970 + c3 | time +-------+------------------------------ + 00001 | Fri Jan 02 00:00:00 1970 PST (1 row) --Testcase 36: @@ -247,9 +247,9 @@ DO $d$ $d$; --Testcase 38: SELECT c3, time FROM ft1 ORDER BY c3, c1 LIMIT 1; -- should work again - c3 | time --------+-------------------------- - 00001 | Fri Jan 02 00:00:00 1970 + c3 | time +-------+------------------------------ + 00001 | Fri Jan 02 00:00:00 1970 PST (1 row) \set VERBOSITY default @@ -269,18 +269,18 @@ EXPLAIN (COSTS OFF) SELECT * FROM ft1 ORDER BY c3, c1 OFFSET 100 LIMIT 10; --Testcase 40: SELECT * FROM ft1 ORDER BY c3, c1 OFFSET 100 LIMIT 10; - c1 | c2 | c3 | time | c6 | c7 | c8 ------+----+-------+--------------------------+----+------------+----- - 101 | 1 | 00101 | Fri Jan 02 00:00:00 1970 | 1 | 1 | foo - 102 | 2 | 00102 | Sat Jan 03 00:00:00 1970 | 2 | 2 | foo - 103 | 3 | 00103 | Sun Jan 04 00:00:00 1970 | 3 | 3 | foo - 104 | 4 | 00104 | Mon Jan 05 00:00:00 1970 | 4 | 4 | foo - 105 | 5 | 00105 | Tue Jan 06 00:00:00 1970 | 5 | 5 | foo - 106 | 6 | 00106 | Wed Jan 07 00:00:00 1970 | 6 | 6 | foo - 107 | 7 | 00107 | Thu Jan 08 00:00:00 1970 | 7 | 7 | foo - 108 | 8 | 00108 | Fri Jan 09 00:00:00 1970 | 8 | 8 | foo - 109 | 9 | 00109 | Sat Jan 10 00:00:00 1970 | 9 | 9 | foo - 110 | 0 | 00110 | Sun Jan 11 00:00:00 1970 | 0 | 0 | foo + c1 | c2 | c3 | time | c6 | c7 | c8 +-----+----+-------+------------------------------+----+------------+----- + 101 | 1 | 00101 | Fri Jan 02 00:00:00 1970 PST | 1 | 1 | foo + 102 | 2 | 00102 | Sat Jan 03 00:00:00 1970 PST | 2 | 2 | foo + 103 | 3 | 00103 | Sun Jan 04 00:00:00 1970 PST | 3 | 3 | foo + 104 | 4 | 00104 | Mon Jan 05 00:00:00 1970 PST | 4 | 4 | foo + 105 | 5 | 00105 | Tue Jan 06 00:00:00 1970 PST | 5 | 5 | foo + 106 | 6 | 00106 | Wed Jan 07 00:00:00 1970 PST | 6 | 6 | foo + 107 | 7 | 00107 | Thu Jan 08 00:00:00 1970 PST | 7 | 7 | foo + 108 | 8 | 00108 | Fri Jan 09 00:00:00 1970 PST | 8 | 8 | foo + 109 | 9 | 00109 | Sat Jan 10 00:00:00 1970 PST | 9 | 9 | foo + 110 | 0 | 00110 | Sun Jan 11 00:00:00 1970 PST | 0 | 0 | foo (10 rows) -- single table with alias - also test that tableoid sort is not pushed to remote side @@ -300,18 +300,18 @@ EXPLAIN (VERBOSE, COSTS OFF) SELECT * FROM ft1 t1 ORDER BY t1.c3, t1.c1, t1.tabl --Testcase 42: SELECT * FROM ft1 t1 ORDER BY t1.c3, t1.c1, t1.tableoid OFFSET 100 LIMIT 10; - c1 | c2 | c3 | time | c6 | c7 | c8 ------+----+-------+--------------------------+----+------------+----- - 101 | 1 | 00101 | Fri Jan 02 00:00:00 1970 | 1 | 1 | foo - 102 | 2 | 00102 | Sat Jan 03 00:00:00 1970 | 2 | 2 | foo - 103 | 3 | 00103 | Sun Jan 04 00:00:00 1970 | 3 | 3 | foo - 104 | 4 | 00104 | Mon Jan 05 00:00:00 1970 | 4 | 4 | foo - 105 | 5 | 00105 | Tue Jan 06 00:00:00 1970 | 5 | 5 | foo - 106 | 6 | 00106 | Wed Jan 07 00:00:00 1970 | 6 | 6 | foo - 107 | 7 | 00107 | Thu Jan 08 00:00:00 1970 | 7 | 7 | foo - 108 | 8 | 00108 | Fri Jan 09 00:00:00 1970 | 8 | 8 | foo - 109 | 9 | 00109 | Sat Jan 10 00:00:00 1970 | 9 | 9 | foo - 110 | 0 | 00110 | Sun Jan 11 00:00:00 1970 | 0 | 0 | foo + c1 | c2 | c3 | time | c6 | c7 | c8 +-----+----+-------+------------------------------+----+------------+----- + 101 | 1 | 00101 | Fri Jan 02 00:00:00 1970 PST | 1 | 1 | foo + 102 | 2 | 00102 | Sat Jan 03 00:00:00 1970 PST | 2 | 2 | foo + 103 | 3 | 00103 | Sun Jan 04 00:00:00 1970 PST | 3 | 3 | foo + 104 | 4 | 00104 | Mon Jan 05 00:00:00 1970 PST | 4 | 4 | foo + 105 | 5 | 00105 | Tue Jan 06 00:00:00 1970 PST | 5 | 5 | foo + 106 | 6 | 00106 | Wed Jan 07 00:00:00 1970 PST | 6 | 6 | foo + 107 | 7 | 00107 | Thu Jan 08 00:00:00 1970 PST | 7 | 7 | foo + 108 | 8 | 00108 | Fri Jan 09 00:00:00 1970 PST | 8 | 8 | foo + 109 | 9 | 00109 | Sat Jan 10 00:00:00 1970 PST | 9 | 9 | foo + 110 | 0 | 00110 | Sun Jan 11 00:00:00 1970 PST | 0 | 0 | foo (10 rows) -- whole-row reference @@ -331,18 +331,18 @@ EXPLAIN (VERBOSE, COSTS OFF) SELECT t1 FROM ft1 t1 ORDER BY t1.c3, t1.c1 OFFSET --Testcase 44: SELECT t1 FROM ft1 t1 ORDER BY t1.c3, t1.c1 OFFSET 100 LIMIT 10; - t1 -------------------------------------------------------------- - (101,1,00101,"Fri Jan 02 00:00:00 1970",1,"1 ",foo) - (102,2,00102,"Sat Jan 03 00:00:00 1970",2,"2 ",foo) - (103,3,00103,"Sun Jan 04 00:00:00 1970",3,"3 ",foo) - (104,4,00104,"Mon Jan 05 00:00:00 1970",4,"4 ",foo) - (105,5,00105,"Tue Jan 06 00:00:00 1970",5,"5 ",foo) - (106,6,00106,"Wed Jan 07 00:00:00 1970",6,"6 ",foo) - (107,7,00107,"Thu Jan 08 00:00:00 1970",7,"7 ",foo) - (108,8,00108,"Fri Jan 09 00:00:00 1970",8,"8 ",foo) - (109,9,00109,"Sat Jan 10 00:00:00 1970",9,"9 ",foo) - (110,0,00110,"Sun Jan 11 00:00:00 1970",0,"0 ",foo) + t1 +----------------------------------------------------------------- + (101,1,00101,"Fri Jan 02 00:00:00 1970 PST",1,"1 ",foo) + (102,2,00102,"Sat Jan 03 00:00:00 1970 PST",2,"2 ",foo) + (103,3,00103,"Sun Jan 04 00:00:00 1970 PST",3,"3 ",foo) + (104,4,00104,"Mon Jan 05 00:00:00 1970 PST",4,"4 ",foo) + (105,5,00105,"Tue Jan 06 00:00:00 1970 PST",5,"5 ",foo) + (106,6,00106,"Wed Jan 07 00:00:00 1970 PST",6,"6 ",foo) + (107,7,00107,"Thu Jan 08 00:00:00 1970 PST",7,"7 ",foo) + (108,8,00108,"Fri Jan 09 00:00:00 1970 PST",8,"8 ",foo) + (109,9,00109,"Sat Jan 10 00:00:00 1970 PST",9,"9 ",foo) + (110,0,00110,"Sun Jan 11 00:00:00 1970 PST",0,"0 ",foo) (10 rows) -- empty result @@ -365,9 +365,9 @@ EXPLAIN (VERBOSE, COSTS OFF) SELECT * FROM ft1 t1 WHERE t1.c1 = 101 AND t1.c6 = --Testcase 47: SELECT * FROM ft1 t1 WHERE t1.c1 = 101 AND t1.c6 = '1' AND t1.c7 >= '1'; - c1 | c2 | c3 | time | c6 | c7 | c8 ------+----+-------+--------------------------+----+------------+----- - 101 | 1 | 00101 | Fri Jan 02 00:00:00 1970 | 1 | 1 | foo + c1 | c2 | c3 | time | c6 | c7 | c8 +-----+----+-------+------------------------------+----+------------+----- + 101 | 1 | 00101 | Fri Jan 02 00:00:00 1970 PST | 1 | 1 | foo (1 row) -- with FOR UPDATE/SHARE @@ -384,9 +384,9 @@ EXPLAIN (VERBOSE, COSTS OFF) SELECT * FROM ft1 t1 WHERE c1 = 101 FOR UPDATE; --Testcase 49: SELECT * FROM ft1 t1 WHERE c1 = 101 FOR UPDATE; - c1 | c2 | c3 | time | c6 | c7 | c8 ------+----+-------+--------------------------+----+------------+----- - 101 | 1 | 00101 | Fri Jan 02 00:00:00 1970 | 1 | 1 | foo + c1 | c2 | c3 | time | c6 | c7 | c8 +-----+----+-------+------------------------------+----+------------+----- + 101 | 1 | 00101 | Fri Jan 02 00:00:00 1970 PST | 1 | 1 | foo (1 row) --Testcase 50: @@ -402,9 +402,9 @@ EXPLAIN (VERBOSE, COSTS OFF) SELECT * FROM ft1 t1 WHERE c1 = 102 FOR SHARE; --Testcase 51: SELECT * FROM ft1 t1 WHERE c1 = 102 FOR SHARE; - c1 | c2 | c3 | time | c6 | c7 | c8 ------+----+-------+--------------------------+----+------------+----- - 102 | 2 | 00102 | Sat Jan 03 00:00:00 1970 | 2 | 2 | foo + c1 | c2 | c3 | time | c6 | c7 | c8 +-----+----+-------+------------------------------+----+------------+----- + 102 | 2 | 00102 | Sat Jan 03 00:00:00 1970 PST | 2 | 2 | foo (1 row) -- aggregate @@ -418,43 +418,43 @@ SELECT COUNT(*) FROM ft1 t1; -- subquery --Testcase 53: SELECT * FROM ft1 t1 WHERE t1.c3 IN (SELECT c3 FROM ft2 t2 WHERE c1 <= 10) ORDER BY c1; - c1 | c2 | c3 | time | c6 | c7 | c8 -----+----+-------+--------------------------+----+------------+----- - 1 | 1 | 00001 | Fri Jan 02 00:00:00 1970 | 1 | 1 | foo - 2 | 2 | 00002 | Sat Jan 03 00:00:00 1970 | 2 | 2 | foo - 3 | 3 | 00003 | Sun Jan 04 00:00:00 1970 | 3 | 3 | foo - 4 | 4 | 00004 | Mon Jan 05 00:00:00 1970 | 4 | 4 | foo - 5 | 5 | 00005 | Tue Jan 06 00:00:00 1970 | 5 | 5 | foo - 6 | 6 | 00006 | Wed Jan 07 00:00:00 1970 | 6 | 6 | foo - 7 | 7 | 00007 | Thu Jan 08 00:00:00 1970 | 7 | 7 | foo - 8 | 8 | 00008 | Fri Jan 09 00:00:00 1970 | 8 | 8 | foo - 9 | 9 | 00009 | Sat Jan 10 00:00:00 1970 | 9 | 9 | foo - 10 | 0 | 00010 | Sun Jan 11 00:00:00 1970 | 0 | 0 | foo + c1 | c2 | c3 | time | c6 | c7 | c8 +----+----+-------+------------------------------+----+------------+----- + 1 | 1 | 00001 | Fri Jan 02 00:00:00 1970 PST | 1 | 1 | foo + 2 | 2 | 00002 | Sat Jan 03 00:00:00 1970 PST | 2 | 2 | foo + 3 | 3 | 00003 | Sun Jan 04 00:00:00 1970 PST | 3 | 3 | foo + 4 | 4 | 00004 | Mon Jan 05 00:00:00 1970 PST | 4 | 4 | foo + 5 | 5 | 00005 | Tue Jan 06 00:00:00 1970 PST | 5 | 5 | foo + 6 | 6 | 00006 | Wed Jan 07 00:00:00 1970 PST | 6 | 6 | foo + 7 | 7 | 00007 | Thu Jan 08 00:00:00 1970 PST | 7 | 7 | foo + 8 | 8 | 00008 | Fri Jan 09 00:00:00 1970 PST | 8 | 8 | foo + 9 | 9 | 00009 | Sat Jan 10 00:00:00 1970 PST | 9 | 9 | foo + 10 | 0 | 00010 | Sun Jan 11 00:00:00 1970 PST | 0 | 0 | foo (10 rows) -- subquery+MAX --Testcase 54: SELECT * FROM ft1 t1 WHERE t1.c3 = (SELECT MAX(c3) FROM ft2 t2) ORDER BY c1; - c1 | c2 | c3 | time | c6 | c7 | c8 -------+----+-------+--------------------------+----+------------+----- - 1000 | 0 | 01000 | Thu Jan 01 00:00:00 1970 | 0 | 0 | foo + c1 | c2 | c3 | time | c6 | c7 | c8 +------+----+-------+------------------------------+----+------------+----- + 1000 | 0 | 01000 | Thu Jan 01 00:00:00 1970 PST | 0 | 0 | foo (1 row) -- used in CTE --Testcase 55: WITH t1 AS (SELECT * FROM ft1 WHERE c1 <= 10) SELECT t2.c1, t2.c2, t2.c3, t2.time FROM t1, ft2 t2 WHERE t1.c1 = t2.c1 ORDER BY t1.c1; - c1 | c2 | c3 | time -----+----+-------+-------------------------- - 1 | 1 | 00001 | Fri Jan 02 00:00:00 1970 - 2 | 2 | 00002 | Sat Jan 03 00:00:00 1970 - 3 | 3 | 00003 | Sun Jan 04 00:00:00 1970 - 4 | 4 | 00004 | Mon Jan 05 00:00:00 1970 - 5 | 5 | 00005 | Tue Jan 06 00:00:00 1970 - 6 | 6 | 00006 | Wed Jan 07 00:00:00 1970 - 7 | 7 | 00007 | Thu Jan 08 00:00:00 1970 - 8 | 8 | 00008 | Fri Jan 09 00:00:00 1970 - 9 | 9 | 00009 | Sat Jan 10 00:00:00 1970 - 10 | 0 | 00010 | Sun Jan 11 00:00:00 1970 + c1 | c2 | c3 | time +----+----+-------+------------------------------ + 1 | 1 | 00001 | Fri Jan 02 00:00:00 1970 PST + 2 | 2 | 00002 | Sat Jan 03 00:00:00 1970 PST + 3 | 3 | 00003 | Sun Jan 04 00:00:00 1970 PST + 4 | 4 | 00004 | Mon Jan 05 00:00:00 1970 PST + 5 | 5 | 00005 | Tue Jan 06 00:00:00 1970 PST + 6 | 6 | 00006 | Wed Jan 07 00:00:00 1970 PST + 7 | 7 | 00007 | Thu Jan 08 00:00:00 1970 PST + 8 | 8 | 00008 | Fri Jan 09 00:00:00 1970 PST + 9 | 9 | 00009 | Sat Jan 10 00:00:00 1970 PST + 10 | 0 | 00010 | Sun Jan 11 00:00:00 1970 PST (10 rows) -- fixed values @@ -871,9 +871,9 @@ EXPLAIN (VERBOSE, COSTS OFF) --Testcase 88: SELECT * FROM ft2 a, ft2 b WHERE a.c1 = 47 AND b.c1 = a.c2; - c1 | c2 | c3 | time | c6 | c7 | c8 | c1 | c2 | c3 | time | c6 | c7 | c8 -----+----+-------+--------------------------+----+------------+-----+----+----+-------+--------------------------+----+------------+----- - 47 | 7 | 00047 | Tue Feb 17 00:00:00 1970 | 7 | 7 | foo | 7 | 7 | 00007 | Thu Jan 08 00:00:00 1970 | 7 | 7 | foo + c1 | c2 | c3 | time | c6 | c7 | c8 | c1 | c2 | c3 | time | c6 | c7 | c8 +----+----+-------+------------------------------+----+------------+-----+----+----+-------+------------------------------+----+------------+----- + 47 | 7 | 00047 | Tue Feb 17 00:00:00 1970 PST | 7 | 7 | foo | 7 | 7 | 00007 | Thu Jan 08 00:00:00 1970 PST | 7 | 7 | foo (1 row) -- check both safe and unsafe join conditions @@ -899,129 +899,129 @@ EXPLAIN (VERBOSE, COSTS OFF) --Testcase 90: SELECT * FROM ft2 a, ft2 b WHERE a.c2 = 6 AND b.c1 = a.c1 AND a.c8 = 'foo' AND b.c7 = upper(a.c7) ORDER BY a.c1; - c1 | c2 | c3 | time | c6 | c7 | c8 | c1 | c2 | c3 | time | c6 | c7 | c8 ------+----+-------+--------------------------+----+------------+-----+-----+----+-------+--------------------------+----+------------+----- - 6 | 6 | 00006 | Wed Jan 07 00:00:00 1970 | 6 | 6 | foo | 6 | 6 | 00006 | Wed Jan 07 00:00:00 1970 | 6 | 6 | foo - 16 | 6 | 00016 | Sat Jan 17 00:00:00 1970 | 6 | 6 | foo | 16 | 6 | 00016 | Sat Jan 17 00:00:00 1970 | 6 | 6 | foo - 26 | 6 | 00026 | Tue Jan 27 00:00:00 1970 | 6 | 6 | foo | 26 | 6 | 00026 | Tue Jan 27 00:00:00 1970 | 6 | 6 | foo - 36 | 6 | 00036 | Fri Feb 06 00:00:00 1970 | 6 | 6 | foo | 36 | 6 | 00036 | Fri Feb 06 00:00:00 1970 | 6 | 6 | foo - 46 | 6 | 00046 | Mon Feb 16 00:00:00 1970 | 6 | 6 | foo | 46 | 6 | 00046 | Mon Feb 16 00:00:00 1970 | 6 | 6 | foo - 56 | 6 | 00056 | Thu Feb 26 00:00:00 1970 | 6 | 6 | foo | 56 | 6 | 00056 | Thu Feb 26 00:00:00 1970 | 6 | 6 | foo - 66 | 6 | 00066 | Sun Mar 08 00:00:00 1970 | 6 | 6 | foo | 66 | 6 | 00066 | Sun Mar 08 00:00:00 1970 | 6 | 6 | foo - 76 | 6 | 00076 | Wed Mar 18 00:00:00 1970 | 6 | 6 | foo | 76 | 6 | 00076 | Wed Mar 18 00:00:00 1970 | 6 | 6 | foo - 86 | 6 | 00086 | Sat Mar 28 00:00:00 1970 | 6 | 6 | foo | 86 | 6 | 00086 | Sat Mar 28 00:00:00 1970 | 6 | 6 | foo - 96 | 6 | 00096 | Tue Apr 07 00:00:00 1970 | 6 | 6 | foo | 96 | 6 | 00096 | Tue Apr 07 00:00:00 1970 | 6 | 6 | foo - 106 | 6 | 00106 | Wed Jan 07 00:00:00 1970 | 6 | 6 | foo | 106 | 6 | 00106 | Wed Jan 07 00:00:00 1970 | 6 | 6 | foo - 116 | 6 | 00116 | Sat Jan 17 00:00:00 1970 | 6 | 6 | foo | 116 | 6 | 00116 | Sat Jan 17 00:00:00 1970 | 6 | 6 | foo - 126 | 6 | 00126 | Tue Jan 27 00:00:00 1970 | 6 | 6 | foo | 126 | 6 | 00126 | Tue Jan 27 00:00:00 1970 | 6 | 6 | foo - 136 | 6 | 00136 | Fri Feb 06 00:00:00 1970 | 6 | 6 | foo | 136 | 6 | 00136 | Fri Feb 06 00:00:00 1970 | 6 | 6 | foo - 146 | 6 | 00146 | Mon Feb 16 00:00:00 1970 | 6 | 6 | foo | 146 | 6 | 00146 | Mon Feb 16 00:00:00 1970 | 6 | 6 | foo - 156 | 6 | 00156 | Thu Feb 26 00:00:00 1970 | 6 | 6 | foo | 156 | 6 | 00156 | Thu Feb 26 00:00:00 1970 | 6 | 6 | foo - 166 | 6 | 00166 | Sun Mar 08 00:00:00 1970 | 6 | 6 | foo | 166 | 6 | 00166 | Sun Mar 08 00:00:00 1970 | 6 | 6 | foo - 176 | 6 | 00176 | Wed Mar 18 00:00:00 1970 | 6 | 6 | foo | 176 | 6 | 00176 | Wed Mar 18 00:00:00 1970 | 6 | 6 | foo - 186 | 6 | 00186 | Sat Mar 28 00:00:00 1970 | 6 | 6 | foo | 186 | 6 | 00186 | Sat Mar 28 00:00:00 1970 | 6 | 6 | foo - 196 | 6 | 00196 | Tue Apr 07 00:00:00 1970 | 6 | 6 | foo | 196 | 6 | 00196 | Tue Apr 07 00:00:00 1970 | 6 | 6 | foo - 206 | 6 | 00206 | Wed Jan 07 00:00:00 1970 | 6 | 6 | foo | 206 | 6 | 00206 | Wed Jan 07 00:00:00 1970 | 6 | 6 | foo - 216 | 6 | 00216 | Sat Jan 17 00:00:00 1970 | 6 | 6 | foo | 216 | 6 | 00216 | Sat Jan 17 00:00:00 1970 | 6 | 6 | foo - 226 | 6 | 00226 | Tue Jan 27 00:00:00 1970 | 6 | 6 | foo | 226 | 6 | 00226 | Tue Jan 27 00:00:00 1970 | 6 | 6 | foo - 236 | 6 | 00236 | Fri Feb 06 00:00:00 1970 | 6 | 6 | foo | 236 | 6 | 00236 | Fri Feb 06 00:00:00 1970 | 6 | 6 | foo - 246 | 6 | 00246 | Mon Feb 16 00:00:00 1970 | 6 | 6 | foo | 246 | 6 | 00246 | Mon Feb 16 00:00:00 1970 | 6 | 6 | foo - 256 | 6 | 00256 | Thu Feb 26 00:00:00 1970 | 6 | 6 | foo | 256 | 6 | 00256 | Thu Feb 26 00:00:00 1970 | 6 | 6 | foo - 266 | 6 | 00266 | Sun Mar 08 00:00:00 1970 | 6 | 6 | foo | 266 | 6 | 00266 | Sun Mar 08 00:00:00 1970 | 6 | 6 | foo - 276 | 6 | 00276 | Wed Mar 18 00:00:00 1970 | 6 | 6 | foo | 276 | 6 | 00276 | Wed Mar 18 00:00:00 1970 | 6 | 6 | foo - 286 | 6 | 00286 | Sat Mar 28 00:00:00 1970 | 6 | 6 | foo | 286 | 6 | 00286 | Sat Mar 28 00:00:00 1970 | 6 | 6 | foo - 296 | 6 | 00296 | Tue Apr 07 00:00:00 1970 | 6 | 6 | foo | 296 | 6 | 00296 | Tue Apr 07 00:00:00 1970 | 6 | 6 | foo - 306 | 6 | 00306 | Wed Jan 07 00:00:00 1970 | 6 | 6 | foo | 306 | 6 | 00306 | Wed Jan 07 00:00:00 1970 | 6 | 6 | foo - 316 | 6 | 00316 | Sat Jan 17 00:00:00 1970 | 6 | 6 | foo | 316 | 6 | 00316 | Sat Jan 17 00:00:00 1970 | 6 | 6 | foo - 326 | 6 | 00326 | Tue Jan 27 00:00:00 1970 | 6 | 6 | foo | 326 | 6 | 00326 | Tue Jan 27 00:00:00 1970 | 6 | 6 | foo - 336 | 6 | 00336 | Fri Feb 06 00:00:00 1970 | 6 | 6 | foo | 336 | 6 | 00336 | Fri Feb 06 00:00:00 1970 | 6 | 6 | foo - 346 | 6 | 00346 | Mon Feb 16 00:00:00 1970 | 6 | 6 | foo | 346 | 6 | 00346 | Mon Feb 16 00:00:00 1970 | 6 | 6 | foo - 356 | 6 | 00356 | Thu Feb 26 00:00:00 1970 | 6 | 6 | foo | 356 | 6 | 00356 | Thu Feb 26 00:00:00 1970 | 6 | 6 | foo - 366 | 6 | 00366 | Sun Mar 08 00:00:00 1970 | 6 | 6 | foo | 366 | 6 | 00366 | Sun Mar 08 00:00:00 1970 | 6 | 6 | foo - 376 | 6 | 00376 | Wed Mar 18 00:00:00 1970 | 6 | 6 | foo | 376 | 6 | 00376 | Wed Mar 18 00:00:00 1970 | 6 | 6 | foo - 386 | 6 | 00386 | Sat Mar 28 00:00:00 1970 | 6 | 6 | foo | 386 | 6 | 00386 | Sat Mar 28 00:00:00 1970 | 6 | 6 | foo - 396 | 6 | 00396 | Tue Apr 07 00:00:00 1970 | 6 | 6 | foo | 396 | 6 | 00396 | Tue Apr 07 00:00:00 1970 | 6 | 6 | foo - 406 | 6 | 00406 | Wed Jan 07 00:00:00 1970 | 6 | 6 | foo | 406 | 6 | 00406 | Wed Jan 07 00:00:00 1970 | 6 | 6 | foo - 416 | 6 | 00416 | Sat Jan 17 00:00:00 1970 | 6 | 6 | foo | 416 | 6 | 00416 | Sat Jan 17 00:00:00 1970 | 6 | 6 | foo - 426 | 6 | 00426 | Tue Jan 27 00:00:00 1970 | 6 | 6 | foo | 426 | 6 | 00426 | Tue Jan 27 00:00:00 1970 | 6 | 6 | foo - 436 | 6 | 00436 | Fri Feb 06 00:00:00 1970 | 6 | 6 | foo | 436 | 6 | 00436 | Fri Feb 06 00:00:00 1970 | 6 | 6 | foo - 446 | 6 | 00446 | Mon Feb 16 00:00:00 1970 | 6 | 6 | foo | 446 | 6 | 00446 | Mon Feb 16 00:00:00 1970 | 6 | 6 | foo - 456 | 6 | 00456 | Thu Feb 26 00:00:00 1970 | 6 | 6 | foo | 456 | 6 | 00456 | Thu Feb 26 00:00:00 1970 | 6 | 6 | foo - 466 | 6 | 00466 | Sun Mar 08 00:00:00 1970 | 6 | 6 | foo | 466 | 6 | 00466 | Sun Mar 08 00:00:00 1970 | 6 | 6 | foo - 476 | 6 | 00476 | Wed Mar 18 00:00:00 1970 | 6 | 6 | foo | 476 | 6 | 00476 | Wed Mar 18 00:00:00 1970 | 6 | 6 | foo - 486 | 6 | 00486 | Sat Mar 28 00:00:00 1970 | 6 | 6 | foo | 486 | 6 | 00486 | Sat Mar 28 00:00:00 1970 | 6 | 6 | foo - 496 | 6 | 00496 | Tue Apr 07 00:00:00 1970 | 6 | 6 | foo | 496 | 6 | 00496 | Tue Apr 07 00:00:00 1970 | 6 | 6 | foo - 506 | 6 | 00506 | Wed Jan 07 00:00:00 1970 | 6 | 6 | foo | 506 | 6 | 00506 | Wed Jan 07 00:00:00 1970 | 6 | 6 | foo - 516 | 6 | 00516 | Sat Jan 17 00:00:00 1970 | 6 | 6 | foo | 516 | 6 | 00516 | Sat Jan 17 00:00:00 1970 | 6 | 6 | foo - 526 | 6 | 00526 | Tue Jan 27 00:00:00 1970 | 6 | 6 | foo | 526 | 6 | 00526 | Tue Jan 27 00:00:00 1970 | 6 | 6 | foo - 536 | 6 | 00536 | Fri Feb 06 00:00:00 1970 | 6 | 6 | foo | 536 | 6 | 00536 | Fri Feb 06 00:00:00 1970 | 6 | 6 | foo - 546 | 6 | 00546 | Mon Feb 16 00:00:00 1970 | 6 | 6 | foo | 546 | 6 | 00546 | Mon Feb 16 00:00:00 1970 | 6 | 6 | foo - 556 | 6 | 00556 | Thu Feb 26 00:00:00 1970 | 6 | 6 | foo | 556 | 6 | 00556 | Thu Feb 26 00:00:00 1970 | 6 | 6 | foo - 566 | 6 | 00566 | Sun Mar 08 00:00:00 1970 | 6 | 6 | foo | 566 | 6 | 00566 | Sun Mar 08 00:00:00 1970 | 6 | 6 | foo - 576 | 6 | 00576 | Wed Mar 18 00:00:00 1970 | 6 | 6 | foo | 576 | 6 | 00576 | Wed Mar 18 00:00:00 1970 | 6 | 6 | foo - 586 | 6 | 00586 | Sat Mar 28 00:00:00 1970 | 6 | 6 | foo | 586 | 6 | 00586 | Sat Mar 28 00:00:00 1970 | 6 | 6 | foo - 596 | 6 | 00596 | Tue Apr 07 00:00:00 1970 | 6 | 6 | foo | 596 | 6 | 00596 | Tue Apr 07 00:00:00 1970 | 6 | 6 | foo - 606 | 6 | 00606 | Wed Jan 07 00:00:00 1970 | 6 | 6 | foo | 606 | 6 | 00606 | Wed Jan 07 00:00:00 1970 | 6 | 6 | foo - 616 | 6 | 00616 | Sat Jan 17 00:00:00 1970 | 6 | 6 | foo | 616 | 6 | 00616 | Sat Jan 17 00:00:00 1970 | 6 | 6 | foo - 626 | 6 | 00626 | Tue Jan 27 00:00:00 1970 | 6 | 6 | foo | 626 | 6 | 00626 | Tue Jan 27 00:00:00 1970 | 6 | 6 | foo - 636 | 6 | 00636 | Fri Feb 06 00:00:00 1970 | 6 | 6 | foo | 636 | 6 | 00636 | Fri Feb 06 00:00:00 1970 | 6 | 6 | foo - 646 | 6 | 00646 | Mon Feb 16 00:00:00 1970 | 6 | 6 | foo | 646 | 6 | 00646 | Mon Feb 16 00:00:00 1970 | 6 | 6 | foo - 656 | 6 | 00656 | Thu Feb 26 00:00:00 1970 | 6 | 6 | foo | 656 | 6 | 00656 | Thu Feb 26 00:00:00 1970 | 6 | 6 | foo - 666 | 6 | 00666 | Sun Mar 08 00:00:00 1970 | 6 | 6 | foo | 666 | 6 | 00666 | Sun Mar 08 00:00:00 1970 | 6 | 6 | foo - 676 | 6 | 00676 | Wed Mar 18 00:00:00 1970 | 6 | 6 | foo | 676 | 6 | 00676 | Wed Mar 18 00:00:00 1970 | 6 | 6 | foo - 686 | 6 | 00686 | Sat Mar 28 00:00:00 1970 | 6 | 6 | foo | 686 | 6 | 00686 | Sat Mar 28 00:00:00 1970 | 6 | 6 | foo - 696 | 6 | 00696 | Tue Apr 07 00:00:00 1970 | 6 | 6 | foo | 696 | 6 | 00696 | Tue Apr 07 00:00:00 1970 | 6 | 6 | foo - 706 | 6 | 00706 | Wed Jan 07 00:00:00 1970 | 6 | 6 | foo | 706 | 6 | 00706 | Wed Jan 07 00:00:00 1970 | 6 | 6 | foo - 716 | 6 | 00716 | Sat Jan 17 00:00:00 1970 | 6 | 6 | foo | 716 | 6 | 00716 | Sat Jan 17 00:00:00 1970 | 6 | 6 | foo - 726 | 6 | 00726 | Tue Jan 27 00:00:00 1970 | 6 | 6 | foo | 726 | 6 | 00726 | Tue Jan 27 00:00:00 1970 | 6 | 6 | foo - 736 | 6 | 00736 | Fri Feb 06 00:00:00 1970 | 6 | 6 | foo | 736 | 6 | 00736 | Fri Feb 06 00:00:00 1970 | 6 | 6 | foo - 746 | 6 | 00746 | Mon Feb 16 00:00:00 1970 | 6 | 6 | foo | 746 | 6 | 00746 | Mon Feb 16 00:00:00 1970 | 6 | 6 | foo - 756 | 6 | 00756 | Thu Feb 26 00:00:00 1970 | 6 | 6 | foo | 756 | 6 | 00756 | Thu Feb 26 00:00:00 1970 | 6 | 6 | foo - 766 | 6 | 00766 | Sun Mar 08 00:00:00 1970 | 6 | 6 | foo | 766 | 6 | 00766 | Sun Mar 08 00:00:00 1970 | 6 | 6 | foo - 776 | 6 | 00776 | Wed Mar 18 00:00:00 1970 | 6 | 6 | foo | 776 | 6 | 00776 | Wed Mar 18 00:00:00 1970 | 6 | 6 | foo - 786 | 6 | 00786 | Sat Mar 28 00:00:00 1970 | 6 | 6 | foo | 786 | 6 | 00786 | Sat Mar 28 00:00:00 1970 | 6 | 6 | foo - 796 | 6 | 00796 | Tue Apr 07 00:00:00 1970 | 6 | 6 | foo | 796 | 6 | 00796 | Tue Apr 07 00:00:00 1970 | 6 | 6 | foo - 806 | 6 | 00806 | Wed Jan 07 00:00:00 1970 | 6 | 6 | foo | 806 | 6 | 00806 | Wed Jan 07 00:00:00 1970 | 6 | 6 | foo - 816 | 6 | 00816 | Sat Jan 17 00:00:00 1970 | 6 | 6 | foo | 816 | 6 | 00816 | Sat Jan 17 00:00:00 1970 | 6 | 6 | foo - 826 | 6 | 00826 | Tue Jan 27 00:00:00 1970 | 6 | 6 | foo | 826 | 6 | 00826 | Tue Jan 27 00:00:00 1970 | 6 | 6 | foo - 836 | 6 | 00836 | Fri Feb 06 00:00:00 1970 | 6 | 6 | foo | 836 | 6 | 00836 | Fri Feb 06 00:00:00 1970 | 6 | 6 | foo - 846 | 6 | 00846 | Mon Feb 16 00:00:00 1970 | 6 | 6 | foo | 846 | 6 | 00846 | Mon Feb 16 00:00:00 1970 | 6 | 6 | foo - 856 | 6 | 00856 | Thu Feb 26 00:00:00 1970 | 6 | 6 | foo | 856 | 6 | 00856 | Thu Feb 26 00:00:00 1970 | 6 | 6 | foo - 866 | 6 | 00866 | Sun Mar 08 00:00:00 1970 | 6 | 6 | foo | 866 | 6 | 00866 | Sun Mar 08 00:00:00 1970 | 6 | 6 | foo - 876 | 6 | 00876 | Wed Mar 18 00:00:00 1970 | 6 | 6 | foo | 876 | 6 | 00876 | Wed Mar 18 00:00:00 1970 | 6 | 6 | foo - 886 | 6 | 00886 | Sat Mar 28 00:00:00 1970 | 6 | 6 | foo | 886 | 6 | 00886 | Sat Mar 28 00:00:00 1970 | 6 | 6 | foo - 896 | 6 | 00896 | Tue Apr 07 00:00:00 1970 | 6 | 6 | foo | 896 | 6 | 00896 | Tue Apr 07 00:00:00 1970 | 6 | 6 | foo - 906 | 6 | 00906 | Wed Jan 07 00:00:00 1970 | 6 | 6 | foo | 906 | 6 | 00906 | Wed Jan 07 00:00:00 1970 | 6 | 6 | foo - 916 | 6 | 00916 | Sat Jan 17 00:00:00 1970 | 6 | 6 | foo | 916 | 6 | 00916 | Sat Jan 17 00:00:00 1970 | 6 | 6 | foo - 926 | 6 | 00926 | Tue Jan 27 00:00:00 1970 | 6 | 6 | foo | 926 | 6 | 00926 | Tue Jan 27 00:00:00 1970 | 6 | 6 | foo - 936 | 6 | 00936 | Fri Feb 06 00:00:00 1970 | 6 | 6 | foo | 936 | 6 | 00936 | Fri Feb 06 00:00:00 1970 | 6 | 6 | foo - 946 | 6 | 00946 | Mon Feb 16 00:00:00 1970 | 6 | 6 | foo | 946 | 6 | 00946 | Mon Feb 16 00:00:00 1970 | 6 | 6 | foo - 956 | 6 | 00956 | Thu Feb 26 00:00:00 1970 | 6 | 6 | foo | 956 | 6 | 00956 | Thu Feb 26 00:00:00 1970 | 6 | 6 | foo - 966 | 6 | 00966 | Sun Mar 08 00:00:00 1970 | 6 | 6 | foo | 966 | 6 | 00966 | Sun Mar 08 00:00:00 1970 | 6 | 6 | foo - 976 | 6 | 00976 | Wed Mar 18 00:00:00 1970 | 6 | 6 | foo | 976 | 6 | 00976 | Wed Mar 18 00:00:00 1970 | 6 | 6 | foo - 986 | 6 | 00986 | Sat Mar 28 00:00:00 1970 | 6 | 6 | foo | 986 | 6 | 00986 | Sat Mar 28 00:00:00 1970 | 6 | 6 | foo - 996 | 6 | 00996 | Tue Apr 07 00:00:00 1970 | 6 | 6 | foo | 996 | 6 | 00996 | Tue Apr 07 00:00:00 1970 | 6 | 6 | foo + c1 | c2 | c3 | time | c6 | c7 | c8 | c1 | c2 | c3 | time | c6 | c7 | c8 +-----+----+-------+------------------------------+----+------------+-----+-----+----+-------+------------------------------+----+------------+----- + 6 | 6 | 00006 | Wed Jan 07 00:00:00 1970 PST | 6 | 6 | foo | 6 | 6 | 00006 | Wed Jan 07 00:00:00 1970 PST | 6 | 6 | foo + 16 | 6 | 00016 | Sat Jan 17 00:00:00 1970 PST | 6 | 6 | foo | 16 | 6 | 00016 | Sat Jan 17 00:00:00 1970 PST | 6 | 6 | foo + 26 | 6 | 00026 | Tue Jan 27 00:00:00 1970 PST | 6 | 6 | foo | 26 | 6 | 00026 | Tue Jan 27 00:00:00 1970 PST | 6 | 6 | foo + 36 | 6 | 00036 | Fri Feb 06 00:00:00 1970 PST | 6 | 6 | foo | 36 | 6 | 00036 | Fri Feb 06 00:00:00 1970 PST | 6 | 6 | foo + 46 | 6 | 00046 | Mon Feb 16 00:00:00 1970 PST | 6 | 6 | foo | 46 | 6 | 00046 | Mon Feb 16 00:00:00 1970 PST | 6 | 6 | foo + 56 | 6 | 00056 | Thu Feb 26 00:00:00 1970 PST | 6 | 6 | foo | 56 | 6 | 00056 | Thu Feb 26 00:00:00 1970 PST | 6 | 6 | foo + 66 | 6 | 00066 | Sun Mar 08 00:00:00 1970 PST | 6 | 6 | foo | 66 | 6 | 00066 | Sun Mar 08 00:00:00 1970 PST | 6 | 6 | foo + 76 | 6 | 00076 | Wed Mar 18 00:00:00 1970 PST | 6 | 6 | foo | 76 | 6 | 00076 | Wed Mar 18 00:00:00 1970 PST | 6 | 6 | foo + 86 | 6 | 00086 | Sat Mar 28 00:00:00 1970 PST | 6 | 6 | foo | 86 | 6 | 00086 | Sat Mar 28 00:00:00 1970 PST | 6 | 6 | foo + 96 | 6 | 00096 | Tue Apr 07 00:00:00 1970 PST | 6 | 6 | foo | 96 | 6 | 00096 | Tue Apr 07 00:00:00 1970 PST | 6 | 6 | foo + 106 | 6 | 00106 | Wed Jan 07 00:00:00 1970 PST | 6 | 6 | foo | 106 | 6 | 00106 | Wed Jan 07 00:00:00 1970 PST | 6 | 6 | foo + 116 | 6 | 00116 | Sat Jan 17 00:00:00 1970 PST | 6 | 6 | foo | 116 | 6 | 00116 | Sat Jan 17 00:00:00 1970 PST | 6 | 6 | foo + 126 | 6 | 00126 | Tue Jan 27 00:00:00 1970 PST | 6 | 6 | foo | 126 | 6 | 00126 | Tue Jan 27 00:00:00 1970 PST | 6 | 6 | foo + 136 | 6 | 00136 | Fri Feb 06 00:00:00 1970 PST | 6 | 6 | foo | 136 | 6 | 00136 | Fri Feb 06 00:00:00 1970 PST | 6 | 6 | foo + 146 | 6 | 00146 | Mon Feb 16 00:00:00 1970 PST | 6 | 6 | foo | 146 | 6 | 00146 | Mon Feb 16 00:00:00 1970 PST | 6 | 6 | foo + 156 | 6 | 00156 | Thu Feb 26 00:00:00 1970 PST | 6 | 6 | foo | 156 | 6 | 00156 | Thu Feb 26 00:00:00 1970 PST | 6 | 6 | foo + 166 | 6 | 00166 | Sun Mar 08 00:00:00 1970 PST | 6 | 6 | foo | 166 | 6 | 00166 | Sun Mar 08 00:00:00 1970 PST | 6 | 6 | foo + 176 | 6 | 00176 | Wed Mar 18 00:00:00 1970 PST | 6 | 6 | foo | 176 | 6 | 00176 | Wed Mar 18 00:00:00 1970 PST | 6 | 6 | foo + 186 | 6 | 00186 | Sat Mar 28 00:00:00 1970 PST | 6 | 6 | foo | 186 | 6 | 00186 | Sat Mar 28 00:00:00 1970 PST | 6 | 6 | foo + 196 | 6 | 00196 | Tue Apr 07 00:00:00 1970 PST | 6 | 6 | foo | 196 | 6 | 00196 | Tue Apr 07 00:00:00 1970 PST | 6 | 6 | foo + 206 | 6 | 00206 | Wed Jan 07 00:00:00 1970 PST | 6 | 6 | foo | 206 | 6 | 00206 | Wed Jan 07 00:00:00 1970 PST | 6 | 6 | foo + 216 | 6 | 00216 | Sat Jan 17 00:00:00 1970 PST | 6 | 6 | foo | 216 | 6 | 00216 | Sat Jan 17 00:00:00 1970 PST | 6 | 6 | foo + 226 | 6 | 00226 | Tue Jan 27 00:00:00 1970 PST | 6 | 6 | foo | 226 | 6 | 00226 | Tue Jan 27 00:00:00 1970 PST | 6 | 6 | foo + 236 | 6 | 00236 | Fri Feb 06 00:00:00 1970 PST | 6 | 6 | foo | 236 | 6 | 00236 | Fri Feb 06 00:00:00 1970 PST | 6 | 6 | foo + 246 | 6 | 00246 | Mon Feb 16 00:00:00 1970 PST | 6 | 6 | foo | 246 | 6 | 00246 | Mon Feb 16 00:00:00 1970 PST | 6 | 6 | foo + 256 | 6 | 00256 | Thu Feb 26 00:00:00 1970 PST | 6 | 6 | foo | 256 | 6 | 00256 | Thu Feb 26 00:00:00 1970 PST | 6 | 6 | foo + 266 | 6 | 00266 | Sun Mar 08 00:00:00 1970 PST | 6 | 6 | foo | 266 | 6 | 00266 | Sun Mar 08 00:00:00 1970 PST | 6 | 6 | foo + 276 | 6 | 00276 | Wed Mar 18 00:00:00 1970 PST | 6 | 6 | foo | 276 | 6 | 00276 | Wed Mar 18 00:00:00 1970 PST | 6 | 6 | foo + 286 | 6 | 00286 | Sat Mar 28 00:00:00 1970 PST | 6 | 6 | foo | 286 | 6 | 00286 | Sat Mar 28 00:00:00 1970 PST | 6 | 6 | foo + 296 | 6 | 00296 | Tue Apr 07 00:00:00 1970 PST | 6 | 6 | foo | 296 | 6 | 00296 | Tue Apr 07 00:00:00 1970 PST | 6 | 6 | foo + 306 | 6 | 00306 | Wed Jan 07 00:00:00 1970 PST | 6 | 6 | foo | 306 | 6 | 00306 | Wed Jan 07 00:00:00 1970 PST | 6 | 6 | foo + 316 | 6 | 00316 | Sat Jan 17 00:00:00 1970 PST | 6 | 6 | foo | 316 | 6 | 00316 | Sat Jan 17 00:00:00 1970 PST | 6 | 6 | foo + 326 | 6 | 00326 | Tue Jan 27 00:00:00 1970 PST | 6 | 6 | foo | 326 | 6 | 00326 | Tue Jan 27 00:00:00 1970 PST | 6 | 6 | foo + 336 | 6 | 00336 | Fri Feb 06 00:00:00 1970 PST | 6 | 6 | foo | 336 | 6 | 00336 | Fri Feb 06 00:00:00 1970 PST | 6 | 6 | foo + 346 | 6 | 00346 | Mon Feb 16 00:00:00 1970 PST | 6 | 6 | foo | 346 | 6 | 00346 | Mon Feb 16 00:00:00 1970 PST | 6 | 6 | foo + 356 | 6 | 00356 | Thu Feb 26 00:00:00 1970 PST | 6 | 6 | foo | 356 | 6 | 00356 | Thu Feb 26 00:00:00 1970 PST | 6 | 6 | foo + 366 | 6 | 00366 | Sun Mar 08 00:00:00 1970 PST | 6 | 6 | foo | 366 | 6 | 00366 | Sun Mar 08 00:00:00 1970 PST | 6 | 6 | foo + 376 | 6 | 00376 | Wed Mar 18 00:00:00 1970 PST | 6 | 6 | foo | 376 | 6 | 00376 | Wed Mar 18 00:00:00 1970 PST | 6 | 6 | foo + 386 | 6 | 00386 | Sat Mar 28 00:00:00 1970 PST | 6 | 6 | foo | 386 | 6 | 00386 | Sat Mar 28 00:00:00 1970 PST | 6 | 6 | foo + 396 | 6 | 00396 | Tue Apr 07 00:00:00 1970 PST | 6 | 6 | foo | 396 | 6 | 00396 | Tue Apr 07 00:00:00 1970 PST | 6 | 6 | foo + 406 | 6 | 00406 | Wed Jan 07 00:00:00 1970 PST | 6 | 6 | foo | 406 | 6 | 00406 | Wed Jan 07 00:00:00 1970 PST | 6 | 6 | foo + 416 | 6 | 00416 | Sat Jan 17 00:00:00 1970 PST | 6 | 6 | foo | 416 | 6 | 00416 | Sat Jan 17 00:00:00 1970 PST | 6 | 6 | foo + 426 | 6 | 00426 | Tue Jan 27 00:00:00 1970 PST | 6 | 6 | foo | 426 | 6 | 00426 | Tue Jan 27 00:00:00 1970 PST | 6 | 6 | foo + 436 | 6 | 00436 | Fri Feb 06 00:00:00 1970 PST | 6 | 6 | foo | 436 | 6 | 00436 | Fri Feb 06 00:00:00 1970 PST | 6 | 6 | foo + 446 | 6 | 00446 | Mon Feb 16 00:00:00 1970 PST | 6 | 6 | foo | 446 | 6 | 00446 | Mon Feb 16 00:00:00 1970 PST | 6 | 6 | foo + 456 | 6 | 00456 | Thu Feb 26 00:00:00 1970 PST | 6 | 6 | foo | 456 | 6 | 00456 | Thu Feb 26 00:00:00 1970 PST | 6 | 6 | foo + 466 | 6 | 00466 | Sun Mar 08 00:00:00 1970 PST | 6 | 6 | foo | 466 | 6 | 00466 | Sun Mar 08 00:00:00 1970 PST | 6 | 6 | foo + 476 | 6 | 00476 | Wed Mar 18 00:00:00 1970 PST | 6 | 6 | foo | 476 | 6 | 00476 | Wed Mar 18 00:00:00 1970 PST | 6 | 6 | foo + 486 | 6 | 00486 | Sat Mar 28 00:00:00 1970 PST | 6 | 6 | foo | 486 | 6 | 00486 | Sat Mar 28 00:00:00 1970 PST | 6 | 6 | foo + 496 | 6 | 00496 | Tue Apr 07 00:00:00 1970 PST | 6 | 6 | foo | 496 | 6 | 00496 | Tue Apr 07 00:00:00 1970 PST | 6 | 6 | foo + 506 | 6 | 00506 | Wed Jan 07 00:00:00 1970 PST | 6 | 6 | foo | 506 | 6 | 00506 | Wed Jan 07 00:00:00 1970 PST | 6 | 6 | foo + 516 | 6 | 00516 | Sat Jan 17 00:00:00 1970 PST | 6 | 6 | foo | 516 | 6 | 00516 | Sat Jan 17 00:00:00 1970 PST | 6 | 6 | foo + 526 | 6 | 00526 | Tue Jan 27 00:00:00 1970 PST | 6 | 6 | foo | 526 | 6 | 00526 | Tue Jan 27 00:00:00 1970 PST | 6 | 6 | foo + 536 | 6 | 00536 | Fri Feb 06 00:00:00 1970 PST | 6 | 6 | foo | 536 | 6 | 00536 | Fri Feb 06 00:00:00 1970 PST | 6 | 6 | foo + 546 | 6 | 00546 | Mon Feb 16 00:00:00 1970 PST | 6 | 6 | foo | 546 | 6 | 00546 | Mon Feb 16 00:00:00 1970 PST | 6 | 6 | foo + 556 | 6 | 00556 | Thu Feb 26 00:00:00 1970 PST | 6 | 6 | foo | 556 | 6 | 00556 | Thu Feb 26 00:00:00 1970 PST | 6 | 6 | foo + 566 | 6 | 00566 | Sun Mar 08 00:00:00 1970 PST | 6 | 6 | foo | 566 | 6 | 00566 | Sun Mar 08 00:00:00 1970 PST | 6 | 6 | foo + 576 | 6 | 00576 | Wed Mar 18 00:00:00 1970 PST | 6 | 6 | foo | 576 | 6 | 00576 | Wed Mar 18 00:00:00 1970 PST | 6 | 6 | foo + 586 | 6 | 00586 | Sat Mar 28 00:00:00 1970 PST | 6 | 6 | foo | 586 | 6 | 00586 | Sat Mar 28 00:00:00 1970 PST | 6 | 6 | foo + 596 | 6 | 00596 | Tue Apr 07 00:00:00 1970 PST | 6 | 6 | foo | 596 | 6 | 00596 | Tue Apr 07 00:00:00 1970 PST | 6 | 6 | foo + 606 | 6 | 00606 | Wed Jan 07 00:00:00 1970 PST | 6 | 6 | foo | 606 | 6 | 00606 | Wed Jan 07 00:00:00 1970 PST | 6 | 6 | foo + 616 | 6 | 00616 | Sat Jan 17 00:00:00 1970 PST | 6 | 6 | foo | 616 | 6 | 00616 | Sat Jan 17 00:00:00 1970 PST | 6 | 6 | foo + 626 | 6 | 00626 | Tue Jan 27 00:00:00 1970 PST | 6 | 6 | foo | 626 | 6 | 00626 | Tue Jan 27 00:00:00 1970 PST | 6 | 6 | foo + 636 | 6 | 00636 | Fri Feb 06 00:00:00 1970 PST | 6 | 6 | foo | 636 | 6 | 00636 | Fri Feb 06 00:00:00 1970 PST | 6 | 6 | foo + 646 | 6 | 00646 | Mon Feb 16 00:00:00 1970 PST | 6 | 6 | foo | 646 | 6 | 00646 | Mon Feb 16 00:00:00 1970 PST | 6 | 6 | foo + 656 | 6 | 00656 | Thu Feb 26 00:00:00 1970 PST | 6 | 6 | foo | 656 | 6 | 00656 | Thu Feb 26 00:00:00 1970 PST | 6 | 6 | foo + 666 | 6 | 00666 | Sun Mar 08 00:00:00 1970 PST | 6 | 6 | foo | 666 | 6 | 00666 | Sun Mar 08 00:00:00 1970 PST | 6 | 6 | foo + 676 | 6 | 00676 | Wed Mar 18 00:00:00 1970 PST | 6 | 6 | foo | 676 | 6 | 00676 | Wed Mar 18 00:00:00 1970 PST | 6 | 6 | foo + 686 | 6 | 00686 | Sat Mar 28 00:00:00 1970 PST | 6 | 6 | foo | 686 | 6 | 00686 | Sat Mar 28 00:00:00 1970 PST | 6 | 6 | foo + 696 | 6 | 00696 | Tue Apr 07 00:00:00 1970 PST | 6 | 6 | foo | 696 | 6 | 00696 | Tue Apr 07 00:00:00 1970 PST | 6 | 6 | foo + 706 | 6 | 00706 | Wed Jan 07 00:00:00 1970 PST | 6 | 6 | foo | 706 | 6 | 00706 | Wed Jan 07 00:00:00 1970 PST | 6 | 6 | foo + 716 | 6 | 00716 | Sat Jan 17 00:00:00 1970 PST | 6 | 6 | foo | 716 | 6 | 00716 | Sat Jan 17 00:00:00 1970 PST | 6 | 6 | foo + 726 | 6 | 00726 | Tue Jan 27 00:00:00 1970 PST | 6 | 6 | foo | 726 | 6 | 00726 | Tue Jan 27 00:00:00 1970 PST | 6 | 6 | foo + 736 | 6 | 00736 | Fri Feb 06 00:00:00 1970 PST | 6 | 6 | foo | 736 | 6 | 00736 | Fri Feb 06 00:00:00 1970 PST | 6 | 6 | foo + 746 | 6 | 00746 | Mon Feb 16 00:00:00 1970 PST | 6 | 6 | foo | 746 | 6 | 00746 | Mon Feb 16 00:00:00 1970 PST | 6 | 6 | foo + 756 | 6 | 00756 | Thu Feb 26 00:00:00 1970 PST | 6 | 6 | foo | 756 | 6 | 00756 | Thu Feb 26 00:00:00 1970 PST | 6 | 6 | foo + 766 | 6 | 00766 | Sun Mar 08 00:00:00 1970 PST | 6 | 6 | foo | 766 | 6 | 00766 | Sun Mar 08 00:00:00 1970 PST | 6 | 6 | foo + 776 | 6 | 00776 | Wed Mar 18 00:00:00 1970 PST | 6 | 6 | foo | 776 | 6 | 00776 | Wed Mar 18 00:00:00 1970 PST | 6 | 6 | foo + 786 | 6 | 00786 | Sat Mar 28 00:00:00 1970 PST | 6 | 6 | foo | 786 | 6 | 00786 | Sat Mar 28 00:00:00 1970 PST | 6 | 6 | foo + 796 | 6 | 00796 | Tue Apr 07 00:00:00 1970 PST | 6 | 6 | foo | 796 | 6 | 00796 | Tue Apr 07 00:00:00 1970 PST | 6 | 6 | foo + 806 | 6 | 00806 | Wed Jan 07 00:00:00 1970 PST | 6 | 6 | foo | 806 | 6 | 00806 | Wed Jan 07 00:00:00 1970 PST | 6 | 6 | foo + 816 | 6 | 00816 | Sat Jan 17 00:00:00 1970 PST | 6 | 6 | foo | 816 | 6 | 00816 | Sat Jan 17 00:00:00 1970 PST | 6 | 6 | foo + 826 | 6 | 00826 | Tue Jan 27 00:00:00 1970 PST | 6 | 6 | foo | 826 | 6 | 00826 | Tue Jan 27 00:00:00 1970 PST | 6 | 6 | foo + 836 | 6 | 00836 | Fri Feb 06 00:00:00 1970 PST | 6 | 6 | foo | 836 | 6 | 00836 | Fri Feb 06 00:00:00 1970 PST | 6 | 6 | foo + 846 | 6 | 00846 | Mon Feb 16 00:00:00 1970 PST | 6 | 6 | foo | 846 | 6 | 00846 | Mon Feb 16 00:00:00 1970 PST | 6 | 6 | foo + 856 | 6 | 00856 | Thu Feb 26 00:00:00 1970 PST | 6 | 6 | foo | 856 | 6 | 00856 | Thu Feb 26 00:00:00 1970 PST | 6 | 6 | foo + 866 | 6 | 00866 | Sun Mar 08 00:00:00 1970 PST | 6 | 6 | foo | 866 | 6 | 00866 | Sun Mar 08 00:00:00 1970 PST | 6 | 6 | foo + 876 | 6 | 00876 | Wed Mar 18 00:00:00 1970 PST | 6 | 6 | foo | 876 | 6 | 00876 | Wed Mar 18 00:00:00 1970 PST | 6 | 6 | foo + 886 | 6 | 00886 | Sat Mar 28 00:00:00 1970 PST | 6 | 6 | foo | 886 | 6 | 00886 | Sat Mar 28 00:00:00 1970 PST | 6 | 6 | foo + 896 | 6 | 00896 | Tue Apr 07 00:00:00 1970 PST | 6 | 6 | foo | 896 | 6 | 00896 | Tue Apr 07 00:00:00 1970 PST | 6 | 6 | foo + 906 | 6 | 00906 | Wed Jan 07 00:00:00 1970 PST | 6 | 6 | foo | 906 | 6 | 00906 | Wed Jan 07 00:00:00 1970 PST | 6 | 6 | foo + 916 | 6 | 00916 | Sat Jan 17 00:00:00 1970 PST | 6 | 6 | foo | 916 | 6 | 00916 | Sat Jan 17 00:00:00 1970 PST | 6 | 6 | foo + 926 | 6 | 00926 | Tue Jan 27 00:00:00 1970 PST | 6 | 6 | foo | 926 | 6 | 00926 | Tue Jan 27 00:00:00 1970 PST | 6 | 6 | foo + 936 | 6 | 00936 | Fri Feb 06 00:00:00 1970 PST | 6 | 6 | foo | 936 | 6 | 00936 | Fri Feb 06 00:00:00 1970 PST | 6 | 6 | foo + 946 | 6 | 00946 | Mon Feb 16 00:00:00 1970 PST | 6 | 6 | foo | 946 | 6 | 00946 | Mon Feb 16 00:00:00 1970 PST | 6 | 6 | foo + 956 | 6 | 00956 | Thu Feb 26 00:00:00 1970 PST | 6 | 6 | foo | 956 | 6 | 00956 | Thu Feb 26 00:00:00 1970 PST | 6 | 6 | foo + 966 | 6 | 00966 | Sun Mar 08 00:00:00 1970 PST | 6 | 6 | foo | 966 | 6 | 00966 | Sun Mar 08 00:00:00 1970 PST | 6 | 6 | foo + 976 | 6 | 00976 | Wed Mar 18 00:00:00 1970 PST | 6 | 6 | foo | 976 | 6 | 00976 | Wed Mar 18 00:00:00 1970 PST | 6 | 6 | foo + 986 | 6 | 00986 | Sat Mar 28 00:00:00 1970 PST | 6 | 6 | foo | 986 | 6 | 00986 | Sat Mar 28 00:00:00 1970 PST | 6 | 6 | foo + 996 | 6 | 00996 | Tue Apr 07 00:00:00 1970 PST | 6 | 6 | foo | 996 | 6 | 00996 | Tue Apr 07 00:00:00 1970 PST | 6 | 6 | foo (100 rows) -- bug before 9.3.5 due to sloppy handling of remote-estimate parameters --Testcase 91: SELECT * FROM ft1 WHERE c1 = ANY (ARRAY(SELECT c1 FROM ft2 WHERE c1 < 5)); - c1 | c2 | c3 | time | c6 | c7 | c8 -----+----+-------+--------------------------+----+------------+----- - 1 | 1 | 00001 | Fri Jan 02 00:00:00 1970 | 1 | 1 | foo - 2 | 2 | 00002 | Sat Jan 03 00:00:00 1970 | 2 | 2 | foo - 3 | 3 | 00003 | Sun Jan 04 00:00:00 1970 | 3 | 3 | foo - 4 | 4 | 00004 | Mon Jan 05 00:00:00 1970 | 4 | 4 | foo + c1 | c2 | c3 | time | c6 | c7 | c8 +----+----+-------+------------------------------+----+------------+----- + 1 | 1 | 00001 | Fri Jan 02 00:00:00 1970 PST | 1 | 1 | foo + 2 | 2 | 00002 | Sat Jan 03 00:00:00 1970 PST | 2 | 2 | foo + 3 | 3 | 00003 | Sun Jan 04 00:00:00 1970 PST | 3 | 3 | foo + 4 | 4 | 00004 | Mon Jan 05 00:00:00 1970 PST | 4 | 4 | foo (4 rows) --Testcase 92: SELECT * FROM ft2 WHERE c1 = ANY (ARRAY(SELECT c1 FROM ft1 WHERE c1 < 5)); - c1 | c2 | c3 | time | c6 | c7 | c8 -----+----+-------+--------------------------+----+------------+----- - 1 | 1 | 00001 | Fri Jan 02 00:00:00 1970 | 1 | 1 | foo - 2 | 2 | 00002 | Sat Jan 03 00:00:00 1970 | 2 | 2 | foo - 3 | 3 | 00003 | Sun Jan 04 00:00:00 1970 | 3 | 3 | foo - 4 | 4 | 00004 | Mon Jan 05 00:00:00 1970 | 4 | 4 | foo + c1 | c2 | c3 | time | c6 | c7 | c8 +----+----+-------+------------------------------+----+------------+----- + 1 | 1 | 00001 | Fri Jan 02 00:00:00 1970 PST | 1 | 1 | foo + 2 | 2 | 00002 | Sat Jan 03 00:00:00 1970 PST | 2 | 2 | foo + 3 | 3 | 00003 | Sun Jan 04 00:00:00 1970 PST | 3 | 3 | foo + 4 | 4 | 00004 | Mon Jan 05 00:00:00 1970 PST | 4 | 4 | foo (4 rows) -- we should not push order by clause with volatile expressions or unsafe @@ -1165,9 +1165,9 @@ EXPLAIN (VERBOSE, COSTS OFF) --Testcase 106: SELECT * FROM ft1 t1 WHERE t1.c1 === t1.c2 order by t1.c2 limit 1; - c1 | c2 | c3 | time | c6 | c7 | c8 -----+----+-------+--------------------------+----+------------+----- - 1 | 1 | 00001 | Fri Jan 02 00:00:00 1970 | 1 | 1 | foo + c1 | c2 | c3 | time | c6 | c7 | c8 +----+----+-------+------------------------------+----+------------+----- + 1 | 1 | 00001 | Fri Jan 02 00:00:00 1970 PST | 1 | 1 | foo (1 row) -- but let's put them in an extension ... @@ -1236,9 +1236,9 @@ EXPLAIN (VERBOSE, COSTS OFF) --Testcase 114: SELECT * FROM ft1 t1 WHERE t1.c1 === t1.c2 order by t1.c2 limit 1; - c1 | c2 | c3 | time | c6 | c7 | c8 -----+----+-------+--------------------------+----+------------+----- - 1 | 1 | 00001 | Fri Jan 02 00:00:00 1970 | 1 | 1 | foo + c1 | c2 | c3 | time | c6 | c7 | c8 +----+----+-------+------------------------------+----+------------+----- + 1 | 1 | 00001 | Fri Jan 02 00:00:00 1970 PST | 1 | 1 | foo (1 row) -- =================================================================== @@ -3095,18 +3095,18 @@ SELECT * FROM ft1, ft2, ft4, ft5, local_tbl WHERE ft1.c1 = ft2.c1 AND ft1.c2 = f --Testcase 204: SELECT * FROM ft1, ft2, ft4, ft5, local_tbl WHERE ft1.c1 = ft2.c1 AND ft1.c2 = ft4.c1 AND ft1.c2 = ft5.c1 AND ft1.c2 = local_tbl.c1 AND ft1.c1 < 100 AND ft2.c1 < 100 ORDER BY ft1.c1 FOR UPDATE; - c1 | c2 | c3 | time | c6 | c7 | c8 | c1 | c2 | c3 | time | c6 | c7 | c8 | c1 | c2 | c3 | c1 | c2 | c3 | c1 | c2 | c3 -----+----+-------+--------------------------+----+------------+-----+----+----+-------+--------------------------+----+------------+-----+----+----+--------+----+----+--------+----+----+------ - 6 | 6 | 00006 | Wed Jan 07 00:00:00 1970 | 6 | 6 | foo | 6 | 6 | 00006 | Wed Jan 07 00:00:00 1970 | 6 | 6 | foo | 6 | 7 | AAA006 | 6 | 7 | AAA006 | 6 | 6 | 0006 - 16 | 6 | 00016 | Sat Jan 17 00:00:00 1970 | 6 | 6 | foo | 16 | 6 | 00016 | Sat Jan 17 00:00:00 1970 | 6 | 6 | foo | 6 | 7 | AAA006 | 6 | 7 | AAA006 | 6 | 6 | 0006 - 26 | 6 | 00026 | Tue Jan 27 00:00:00 1970 | 6 | 6 | foo | 26 | 6 | 00026 | Tue Jan 27 00:00:00 1970 | 6 | 6 | foo | 6 | 7 | AAA006 | 6 | 7 | AAA006 | 6 | 6 | 0006 - 36 | 6 | 00036 | Fri Feb 06 00:00:00 1970 | 6 | 6 | foo | 36 | 6 | 00036 | Fri Feb 06 00:00:00 1970 | 6 | 6 | foo | 6 | 7 | AAA006 | 6 | 7 | AAA006 | 6 | 6 | 0006 - 46 | 6 | 00046 | Mon Feb 16 00:00:00 1970 | 6 | 6 | foo | 46 | 6 | 00046 | Mon Feb 16 00:00:00 1970 | 6 | 6 | foo | 6 | 7 | AAA006 | 6 | 7 | AAA006 | 6 | 6 | 0006 - 56 | 6 | 00056 | Thu Feb 26 00:00:00 1970 | 6 | 6 | foo | 56 | 6 | 00056 | Thu Feb 26 00:00:00 1970 | 6 | 6 | foo | 6 | 7 | AAA006 | 6 | 7 | AAA006 | 6 | 6 | 0006 - 66 | 6 | 00066 | Sun Mar 08 00:00:00 1970 | 6 | 6 | foo | 66 | 6 | 00066 | Sun Mar 08 00:00:00 1970 | 6 | 6 | foo | 6 | 7 | AAA006 | 6 | 7 | AAA006 | 6 | 6 | 0006 - 76 | 6 | 00076 | Wed Mar 18 00:00:00 1970 | 6 | 6 | foo | 76 | 6 | 00076 | Wed Mar 18 00:00:00 1970 | 6 | 6 | foo | 6 | 7 | AAA006 | 6 | 7 | AAA006 | 6 | 6 | 0006 - 86 | 6 | 00086 | Sat Mar 28 00:00:00 1970 | 6 | 6 | foo | 86 | 6 | 00086 | Sat Mar 28 00:00:00 1970 | 6 | 6 | foo | 6 | 7 | AAA006 | 6 | 7 | AAA006 | 6 | 6 | 0006 - 96 | 6 | 00096 | Tue Apr 07 00:00:00 1970 | 6 | 6 | foo | 96 | 6 | 00096 | Tue Apr 07 00:00:00 1970 | 6 | 6 | foo | 6 | 7 | AAA006 | 6 | 7 | AAA006 | 6 | 6 | 0006 + c1 | c2 | c3 | time | c6 | c7 | c8 | c1 | c2 | c3 | time | c6 | c7 | c8 | c1 | c2 | c3 | c1 | c2 | c3 | c1 | c2 | c3 +----+----+-------+------------------------------+----+------------+-----+----+----+-------+------------------------------+----+------------+-----+----+----+--------+----+----+--------+----+----+------ + 6 | 6 | 00006 | Wed Jan 07 00:00:00 1970 PST | 6 | 6 | foo | 6 | 6 | 00006 | Wed Jan 07 00:00:00 1970 PST | 6 | 6 | foo | 6 | 7 | AAA006 | 6 | 7 | AAA006 | 6 | 6 | 0006 + 16 | 6 | 00016 | Sat Jan 17 00:00:00 1970 PST | 6 | 6 | foo | 16 | 6 | 00016 | Sat Jan 17 00:00:00 1970 PST | 6 | 6 | foo | 6 | 7 | AAA006 | 6 | 7 | AAA006 | 6 | 6 | 0006 + 26 | 6 | 00026 | Tue Jan 27 00:00:00 1970 PST | 6 | 6 | foo | 26 | 6 | 00026 | Tue Jan 27 00:00:00 1970 PST | 6 | 6 | foo | 6 | 7 | AAA006 | 6 | 7 | AAA006 | 6 | 6 | 0006 + 36 | 6 | 00036 | Fri Feb 06 00:00:00 1970 PST | 6 | 6 | foo | 36 | 6 | 00036 | Fri Feb 06 00:00:00 1970 PST | 6 | 6 | foo | 6 | 7 | AAA006 | 6 | 7 | AAA006 | 6 | 6 | 0006 + 46 | 6 | 00046 | Mon Feb 16 00:00:00 1970 PST | 6 | 6 | foo | 46 | 6 | 00046 | Mon Feb 16 00:00:00 1970 PST | 6 | 6 | foo | 6 | 7 | AAA006 | 6 | 7 | AAA006 | 6 | 6 | 0006 + 56 | 6 | 00056 | Thu Feb 26 00:00:00 1970 PST | 6 | 6 | foo | 56 | 6 | 00056 | Thu Feb 26 00:00:00 1970 PST | 6 | 6 | foo | 6 | 7 | AAA006 | 6 | 7 | AAA006 | 6 | 6 | 0006 + 66 | 6 | 00066 | Sun Mar 08 00:00:00 1970 PST | 6 | 6 | foo | 66 | 6 | 00066 | Sun Mar 08 00:00:00 1970 PST | 6 | 6 | foo | 6 | 7 | AAA006 | 6 | 7 | AAA006 | 6 | 6 | 0006 + 76 | 6 | 00076 | Wed Mar 18 00:00:00 1970 PST | 6 | 6 | foo | 76 | 6 | 00076 | Wed Mar 18 00:00:00 1970 PST | 6 | 6 | foo | 6 | 7 | AAA006 | 6 | 7 | AAA006 | 6 | 6 | 0006 + 86 | 6 | 00086 | Sat Mar 28 00:00:00 1970 PST | 6 | 6 | foo | 86 | 6 | 00086 | Sat Mar 28 00:00:00 1970 PST | 6 | 6 | foo | 6 | 7 | AAA006 | 6 | 7 | AAA006 | 6 | 6 | 0006 + 96 | 6 | 00096 | Tue Apr 07 00:00:00 1970 PST | 6 | 6 | foo | 96 | 6 | 00096 | Tue Apr 07 00:00:00 1970 PST | 6 | 6 | foo | 6 | 7 | AAA006 | 6 | 7 | AAA006 | 6 | 6 | 0006 (10 rows) --Testcase 205: @@ -3769,9 +3769,9 @@ select array_agg(time order by c1 desc) from ft2 where c2 = 6 and c1 < 50; --Testcase 257: select array_agg(time order by c1 desc) from ft2 where c2 = 6 and c1 < 50; - array_agg ------------------------------------------------------------------------------------------------------------------------------------------- - {"Mon Feb 16 00:00:00 1970","Fri Feb 06 00:00:00 1970","Tue Jan 27 00:00:00 1970","Sat Jan 17 00:00:00 1970","Wed Jan 07 00:00:00 1970"} + array_agg +-------------------------------------------------------------------------------------------------------------------------------------------------------------- + {"Mon Feb 16 00:00:00 1970 PST","Fri Feb 06 00:00:00 1970 PST","Tue Jan 27 00:00:00 1970 PST","Sat Jan 17 00:00:00 1970 PST","Wed Jan 07 00:00:00 1970 PST"} (1 row) -- DISTINCT within aggregate @@ -4932,16 +4932,16 @@ EXPLAIN (VERBOSE, COSTS OFF) EXECUTE st2(10, 20); --Testcase 359: EXECUTE st2(10, 20); - c1 | c2 | c3 | time | c6 | c7 | c8 -----+----+-------+--------------------------+----+------------+----- - 16 | 6 | 00016 | Sat Jan 17 00:00:00 1970 | 6 | 6 | foo + c1 | c2 | c3 | time | c6 | c7 | c8 +----+----+-------+------------------------------+----+------------+----- + 16 | 6 | 00016 | Sat Jan 17 00:00:00 1970 PST | 6 | 6 | foo (1 row) --Testcase 360: EXECUTE st2(101, 121); - c1 | c2 | c3 | time | c6 | c7 | c8 ------+----+-------+--------------------------+----+------------+----- - 116 | 6 | 00116 | Sat Jan 17 00:00:00 1970 | 6 | 6 | foo + c1 | c2 | c3 | time | c6 | c7 | c8 +-----+----+-------+------------------------------+----+------------+----- + 116 | 6 | 00116 | Sat Jan 17 00:00:00 1970 PST | 6 | 6 | foo (1 row) -- subquery using immutable function (can be sent to remote) @@ -4970,9 +4970,9 @@ EXPLAIN (VERBOSE, COSTS OFF) EXECUTE st3(10, 20); --Testcase 363: EXECUTE st3(10, 20); - c1 | c2 | c3 | time | c6 | c7 | c8 -----+----+-------+--------------------------+----+------------+----- - 16 | 6 | 00016 | Sat Jan 17 00:00:00 1970 | 6 | 6 | foo + c1 | c2 | c3 | time | c6 | c7 | c8 +----+----+-------+------------------------------+----+------------+----- + 16 | 6 | 00016 | Sat Jan 17 00:00:00 1970 PST | 6 | 6 | foo (1 row) --Testcase 364: @@ -5098,9 +5098,9 @@ EXPLAIN (VERBOSE, COSTS OFF) EXECUTE st5('foo', 1); --Testcase 379: EXECUTE st5('foo', 1); - c1 | c2 | c3 | time | c6 | c7 | c8 -----+----+-------+--------------------------+----+------------+----- - 1 | 1 | 00001 | Fri Jan 02 00:00:00 1970 | 1 | 1 | foo + c1 | c2 | c3 | time | c6 | c7 | c8 +----+----+-------+------------------------------+----+------------+----- + 1 | 1 | 00001 | Fri Jan 02 00:00:00 1970 PST | 1 | 1 | foo (1 row) -- altering FDW options requires replanning @@ -5119,12 +5119,12 @@ EXPLAIN (VERBOSE, COSTS OFF) EXECUTE st6; PREPARE st7 AS INSERT INTO ft1 (c1,c2,c3) VALUES (1001,101,'foo'); --Testcase 383: EXPLAIN (VERBOSE, COSTS OFF) EXECUTE st7; - QUERY PLAN ------------------------------------------------------------------------------------------------------------------------------------------------------------- + QUERY PLAN +--------------------------------------------------------------------------------------------------------------------------------------------------------- Insert on public.ft1 Batch Size: 1 -> Result - Output: NULL::integer, 1001, 101, 'foo'::text, NULL::timestamp without time zone, NULL::character varying, 'ft1 '::character(10), NULL::text + Output: NULL::integer, 1001, 101, 'foo'::text, NULL::timestamp with time zone, NULL::character varying, 'ft1 '::character(10), NULL::text (4 rows) --Testcase 384: @@ -5142,27 +5142,27 @@ EXPLAIN (VERBOSE, COSTS OFF) EXECUTE st6; --Testcase 387: EXECUTE st6; - c1 | c2 | c3 | time | c6 | c7 | c8 -----+----+-------+--------------------------+----+------------+----- - 1 | 1 | 00001 | Fri Jan 02 00:00:00 1970 | 1 | 1 | foo - 2 | 2 | 00002 | Sat Jan 03 00:00:00 1970 | 2 | 2 | foo - 3 | 3 | 00003 | Sun Jan 04 00:00:00 1970 | 3 | 3 | foo - 4 | 4 | 00004 | Mon Jan 05 00:00:00 1970 | 4 | 4 | foo - 5 | 5 | 00005 | Tue Jan 06 00:00:00 1970 | 5 | 5 | foo - 6 | 6 | 00006 | Wed Jan 07 00:00:00 1970 | 6 | 6 | foo - 7 | 7 | 00007 | Thu Jan 08 00:00:00 1970 | 7 | 7 | foo - 8 | 8 | 00008 | Fri Jan 09 00:00:00 1970 | 8 | 8 | foo - 9 | 9 | 00009 | Sat Jan 10 00:00:00 1970 | 9 | 9 | foo + c1 | c2 | c3 | time | c6 | c7 | c8 +----+----+-------+------------------------------+----+------------+----- + 1 | 1 | 00001 | Fri Jan 02 00:00:00 1970 PST | 1 | 1 | foo + 2 | 2 | 00002 | Sat Jan 03 00:00:00 1970 PST | 2 | 2 | foo + 3 | 3 | 00003 | Sun Jan 04 00:00:00 1970 PST | 3 | 3 | foo + 4 | 4 | 00004 | Mon Jan 05 00:00:00 1970 PST | 4 | 4 | foo + 5 | 5 | 00005 | Tue Jan 06 00:00:00 1970 PST | 5 | 5 | foo + 6 | 6 | 00006 | Wed Jan 07 00:00:00 1970 PST | 6 | 6 | foo + 7 | 7 | 00007 | Thu Jan 08 00:00:00 1970 PST | 7 | 7 | foo + 8 | 8 | 00008 | Fri Jan 09 00:00:00 1970 PST | 8 | 8 | foo + 9 | 9 | 00009 | Sat Jan 10 00:00:00 1970 PST | 9 | 9 | foo (9 rows) --Testcase 388: EXPLAIN (VERBOSE, COSTS OFF) EXECUTE st7; - QUERY PLAN ------------------------------------------------------------------------------------------------------------------------------------------------------------- + QUERY PLAN +--------------------------------------------------------------------------------------------------------------------------------------------------------- Insert on public.ft1 Batch Size: 1 -> Result - Output: NULL::integer, 1001, 101, 'foo'::text, NULL::timestamp without time zone, NULL::character varying, 'ft1 '::character(10), NULL::text + Output: NULL::integer, 1001, 101, 'foo'::text, NULL::timestamp with time zone, NULL::character varying, 'ft1 '::character(10), NULL::text (4 rows) --Testcase 389: @@ -5230,9 +5230,9 @@ SELECT * FROM ft1 t1 WHERE t1.tableoid = 'pg_class'::regclass LIMIT 1; --Testcase 396: SELECT * FROM ft1 t1 WHERE t1.tableoid = 'ft1'::regclass ORDER BY c1 LIMIT 1; - c1 | c2 | c3 | time | c6 | c7 | c8 -----+----+-------+--------------------------+----+------------+----- - 1 | 1 | 00001 | Fri Jan 02 00:00:00 1970 | 1 | 1 | foo + c1 | c2 | c3 | time | c6 | c7 | c8 +----+----+-------+------------------------------+----+------------+----- + 1 | 1 | 00001 | Fri Jan 02 00:00:00 1970 PST | 1 | 1 | foo (1 row) --Testcase 397: @@ -5247,9 +5247,9 @@ SELECT tableoid::regclass, * FROM ft1 t1 LIMIT 1; --Testcase 398: SELECT tableoid::regclass, * FROM ft1 t1 ORDER BY c1 LIMIT 1; - tableoid | c1 | c2 | c3 | time | c6 | c7 | c8 -----------+----+----+-------+--------------------------+----+------------+----- - ft1 | 1 | 1 | 00001 | Fri Jan 02 00:00:00 1970 | 1 | 1 | foo + tableoid | c1 | c2 | c3 | time | c6 | c7 | c8 +----------+----+----+-------+------------------------------+----+------------+----- + ft1 | 1 | 1 | 00001 | Fri Jan 02 00:00:00 1970 PST | 1 | 1 | foo (1 row) --Testcase 399: @@ -5281,9 +5281,9 @@ SELECT ctid, * FROM ft1 t1 LIMIT 1; --Testcase 402: SELECT ctid, * FROM ft1 t1 ORDER BY c1 LIMIT 1; - ctid | c1 | c2 | c3 | time | c6 | c7 | c8 -----------------+----+----+-------+--------------------------+----+------------+----- - (4294967295,0) | 1 | 1 | 00001 | Fri Jan 02 00:00:00 1970 | 1 | 1 | foo + ctid | c1 | c2 | c3 | time | c6 | c7 | c8 +----------------+----+----+-------+------------------------------+----+------------+----- + (4294967295,0) | 1 | 1 | 00001 | Fri Jan 02 00:00:00 1970 PST | 1 | 1 | foo (1 row) -- =================================================================== @@ -5506,12 +5506,12 @@ explain (verbose, costs off) select * from ft3 f, loct3 l --Testcase 431: EXPLAIN (verbose, costs off) INSERT INTO ft2 (c1,c2,c3) SELECT c1+1000,c2+100, c3 || c3 FROM ft2 ORDER BY c1 LIMIT 20; - QUERY PLAN -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- + QUERY PLAN +---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- Insert on public.ft2 Batch Size: 1 -> Subquery Scan on "*SELECT*" - Output: "*SELECT*"."?column?", "*SELECT*"."?column?_1", NULL::integer, "*SELECT*"."?column?_2", NULL::timestamp without time zone, NULL::character varying, 'ft2 '::character(10), NULL::text + Output: "*SELECT*"."?column?", "*SELECT*"."?column?_1", NULL::integer, "*SELECT*"."?column?_2", NULL::timestamp with time zone, NULL::character varying, 'ft2 '::character(10), NULL::text -> Limit Output: ((ft2_1.c1 + 1000)), ((ft2_1.c2 + 100)), ((ft2_1.c3 || ft2_1.c3)), ft2_1.c1 -> Sort @@ -6525,12 +6525,12 @@ SELECT c1,c2,c3 FROM ft2 ORDER BY c1; --Testcase 443: EXPLAIN (verbose, costs off) INSERT INTO ft2 (c1,c2,c3) VALUES (1200,999,'foo'); - QUERY PLAN ------------------------------------------------------------------------------------------------------------------------------------------------------------- + QUERY PLAN +--------------------------------------------------------------------------------------------------------------------------------------------------------- Insert on public.ft2 Batch Size: 1 -> Result - Output: 1200, 999, NULL::integer, 'foo'::text, NULL::timestamp without time zone, NULL::character varying, 'ft2 '::character(10), NULL::text + Output: 1200, 999, NULL::integer, 'foo'::text, NULL::timestamp with time zone, NULL::character varying, 'ft2 '::character(10), NULL::text (4 rows) --Testcase 444: @@ -9238,7 +9238,7 @@ CREATE FOREIGN TABLE ft1_nopw ( c2 int NOT NULL, c3 text, c4 timestamptz, - c5 timestamp, + c5 timestamptz, c6 varchar(10), c7 char(10) default 'ft1', c8 user_enum diff --git a/expected/13.8/extra/insert.out b/expected/14.9/extra/insert.out similarity index 100% rename from expected/13.8/extra/insert.out rename to expected/14.9/extra/insert.out diff --git a/expected/14.5/extra/join.out b/expected/14.9/extra/join.out similarity index 100% rename from expected/14.5/extra/join.out rename to expected/14.9/extra/join.out diff --git a/expected/14.5/extra/limit.out b/expected/14.9/extra/limit.out similarity index 100% rename from expected/14.5/extra/limit.out rename to expected/14.9/extra/limit.out diff --git a/expected/14.5/extra/prepare.out b/expected/14.9/extra/prepare.out similarity index 100% rename from expected/14.5/extra/prepare.out rename to expected/14.9/extra/prepare.out diff --git a/expected/14.5/extra/select.out b/expected/14.9/extra/select.out similarity index 100% rename from expected/14.5/extra/select.out rename to expected/14.9/extra/select.out diff --git a/expected/13.8/extra/select_having.out b/expected/14.9/extra/select_having.out similarity index 100% rename from expected/13.8/extra/select_having.out rename to expected/14.9/extra/select_having.out diff --git a/expected/15.0/influxdb_fdw.out b/expected/14.9/influxdb_fdw.out similarity index 92% rename from expected/15.0/influxdb_fdw.out rename to expected/14.9/influxdb_fdw.out index 506d3da..7e6a546 100644 --- a/expected/15.0/influxdb_fdw.out +++ b/expected/14.9/influxdb_fdw.out @@ -1128,14 +1128,14 @@ SELECT * FROM t5; SELECT * FROM public.influxdb_fdw_version(); influxdb_fdw_version ---------------------- - 20000 + 20100 (1 row) --Testcase 146: SELECT influxdb_fdw_version(); influxdb_fdw_version ---------------------- - 20000 + 20100 (1 row) --Test pushdown LIMIT...OFFSET @@ -1620,6 +1620,122 @@ SELECT * FROM tmp_time; 2100-01-01 01:01:01 | 04:05:06 | | (6 rows) +-- Type mis-match +--Testcase 212: +CREATE FOREIGN TABLE datatype_test ( + time timestamp with time zone, + tag1 text, + tag2 text, + value1 int, + value2 text +) SERVER server1 OPTIONS (table 'datatype_test', tags 'tag1,tag2'); +--Testcase 213: +INSERT INTO datatype_test (tag1, tag2, value1, value2) VALUES ('time', '2021-02-02T00:00:01Z', '1', '2021-02-05T00:00:00Z'); +--Testcase 214: +INSERT INTO datatype_test (tag1, tag2, value1, value2) VALUES ('time', '2022-02-02T00:00:01Z', '2', '2022-02-05T00:00:00Z'); +--Testcase 215: +SELECT tag1, tag2, value1, value2 FROM datatype_test; + tag1 | tag2 | value1 | value2 +------+----------------------+--------+---------------------- + time | 2021-02-02T00:00:01Z | 1 | 2021-02-05T00:00:00Z + time | 2022-02-02T00:00:01Z | 2 | 2022-02-05T00:00:00Z +(2 rows) + +-- Using text as timestamp +--Testcase 216: +ALTER FOREIGN TABLE datatype_test ALTER COLUMN tag2 TYPE timestamptz; +--Testcase 217: +ALTER FOREIGN TABLE datatype_test ALTER COLUMN value2 TYPE timestamptz; +-- SELECT OK without filter +--Testcase 218: +SELECT tag1, tag2, value1, value2 FROM datatype_test; + tag1 | tag2 | value1 | value2 +------+------------------------+--------+------------------------ + time | 2021-02-02 09:00:01+09 | 1 | 2021-02-05 09:00:00+09 + time | 2022-02-02 09:00:01+09 | 2 | 2022-02-05 09:00:00+09 +(2 rows) + +-- SELECT with timestamp filter, WHERE clause is pushed down +-- InfluxDB cannot compare correctly, 0 row returned +--Testcase 219: +EXPLAIN (VERBOSE, COSTS OFF) +SELECT tag1, tag2, value1, value2 FROM datatype_test WHERE tag2 > '2021-02-02 00:00:01+00'; + QUERY PLAN +--------------------------------------------------------------------------------------------------------------------------- + Foreign Scan on public.datatype_test + Output: tag1, tag2, value1, value2 + InfluxDB query: SELECT "tag1", "tag2", "value1", "value2" FROM "datatype_test" WHERE (("tag2" > '2021-02-02 00:00:01')) +(3 rows) + +--Testcase 220: +SELECT tag1, tag2, value1, value2 FROM datatype_test WHERE tag2 > '2021-02-02 00:00:01+00'; + tag1 | tag2 | value1 | value2 +------+------+--------+-------- +(0 rows) + +--Testcase 221: +EXPLAIN (VERBOSE, COSTS OFF) +SELECT tag1, tag2, value1, value2 FROM datatype_test WHERE value2 > '2021-02-05 00:00:00+00'; + QUERY PLAN +----------------------------------------------------------------------------------------------------------------------------- + Foreign Scan on public.datatype_test + Output: tag1, tag2, value1, value2 + InfluxDB query: SELECT "tag1", "tag2", "value1", "value2" FROM "datatype_test" WHERE (("value2" > '2021-02-05 00:00:00')) +(3 rows) + +--Testcase 222: +SELECT tag1, tag2, value1, value2 FROM datatype_test WHERE value2 > '2021-02-05 00:00:00+00'; + tag1 | tag2 | value1 | value2 +------+------+--------+-------- +(0 rows) + +--Testcase 223: +ALTER FOREIGN TABLE datatype_test ALTER COLUMN tag2 TYPE text; +--Testcase 224: +ALTER FOREIGN TABLE datatype_test ALTER COLUMN value2 TYPE text; +-- uses explicit cast, WHERE clause is not pushed down +-- compared correctly by postgres, 1 row returned +--Testcase 225: +EXPLAIN (VERBOSE, COSTS OFF) +SELECT tag1, tag2, value1, value2 FROM datatype_test WHERE tag2::timestamptz > '2021-02-02 00:00:01+00'; + QUERY PLAN +----------------------------------------------------------------------------------------------------------------- + Foreign Scan on public.datatype_test + Output: tag1, tag2, value1, value2 + Filter: ((datatype_test.tag2)::timestamp with time zone > '2021-02-02 09:00:01+09'::timestamp with time zone) + InfluxDB query: SELECT "tag1", "tag2", "value1", "value2" FROM "datatype_test" +(4 rows) + +--Testcase 226: +SELECT tag1, tag2, value1, value2 FROM datatype_test WHERE tag2::timestamptz > '2021-02-02 00:00:01+00'; + tag1 | tag2 | value1 | value2 +------+----------------------+--------+---------------------- + time | 2022-02-02T00:00:01Z | 2 | 2022-02-05T00:00:00Z +(1 row) + +--Testcase 227: +EXPLAIN (VERBOSE, COSTS OFF) +SELECT tag1, tag2, value1, value2 FROM datatype_test WHERE value2::timestamptz > '2021-02-05 00:00:00+00'; + QUERY PLAN +------------------------------------------------------------------------------------------------------------------- + Foreign Scan on public.datatype_test + Output: tag1, tag2, value1, value2 + Filter: ((datatype_test.value2)::timestamp with time zone > '2021-02-05 09:00:00+09'::timestamp with time zone) + InfluxDB query: SELECT "tag1", "tag2", "value1", "value2" FROM "datatype_test" +(4 rows) + +--Testcase 228: +SELECT tag1, tag2, value1, value2 FROM datatype_test WHERE value2::timestamptz > '2021-02-05 00:00:00+00'; + tag1 | tag2 | value1 | value2 +------+----------------------+--------+---------------------- + time | 2022-02-02T00:00:01Z | 2 | 2022-02-05T00:00:00Z +(1 row) + +-- clean-up +--Testcase 229: +DELETE FROM datatype_test; +--Testcase 230: +DROP FOREIGN TABLE datatype_test; -- Recover data :RECOVER_INIT_TXT_DROP_BUCKET; :RECOVER_INIT_TXT_CREATE_BUCKET; diff --git a/expected/13.8/option.out b/expected/14.9/option.out similarity index 100% rename from expected/13.8/option.out rename to expected/14.9/option.out diff --git a/expected/14.5/schemaless/add_fields.out b/expected/14.9/schemaless/add_fields.out similarity index 100% rename from expected/14.5/schemaless/add_fields.out rename to expected/14.9/schemaless/add_fields.out diff --git a/expected/14.5/schemaless/add_multi_key.out b/expected/14.9/schemaless/add_multi_key.out similarity index 100% rename from expected/14.5/schemaless/add_multi_key.out rename to expected/14.9/schemaless/add_multi_key.out diff --git a/expected/14.5/schemaless/add_tags.out b/expected/14.9/schemaless/add_tags.out similarity index 100% rename from expected/14.5/schemaless/add_tags.out rename to expected/14.9/schemaless/add_tags.out diff --git a/expected/13.8/schemaless/aggregate.out b/expected/14.9/schemaless/aggregate.out similarity index 100% rename from expected/13.8/schemaless/aggregate.out rename to expected/14.9/schemaless/aggregate.out diff --git a/expected/14.5/schemaless/extra/aggregates.out b/expected/14.9/schemaless/extra/aggregates.out similarity index 100% rename from expected/14.5/schemaless/extra/aggregates.out rename to expected/14.9/schemaless/extra/aggregates.out diff --git a/expected/14.5/schemaless/extra/influxdb_fdw_post.out b/expected/14.9/schemaless/extra/influxdb_fdw_post.out similarity index 91% rename from expected/14.5/schemaless/extra/influxdb_fdw_post.out rename to expected/14.9/schemaless/extra/influxdb_fdw_post.out index 6d2abb9..d9d20d2 100644 --- a/expected/14.5/schemaless/extra/influxdb_fdw_post.out +++ b/expected/14.9/schemaless/extra/influxdb_fdw_post.out @@ -26,23 +26,23 @@ CREATE TYPE user_enum AS ENUM ('foo', 'bar', 'buz'); --Testcase 9: CREATE SCHEMA "S 1"; --Testcase 10: -CREATE FOREIGN TABLE "S 1"."T 0" (time timestamp, tags jsonb OPTIONS(tags 'true'), fields jsonb OPTIONS(fields 'true')) SERVER influxdb_svr OPTIONS (table 'T0', tags 'c3', schemaless 'true'); +CREATE FOREIGN TABLE "S 1"."T 0" (time timestamptz, tags jsonb OPTIONS(tags 'true'), fields jsonb OPTIONS(fields 'true')) SERVER influxdb_svr OPTIONS (table 'T0', tags 'c3', schemaless 'true'); CREATE FOREIGN TABLE "S 1".s1t0 ( "C 1" int NOT NULL, c2 int NOT NULL, c3 text, - time timestamp, + time timestamptz, c6 varchar(10), c7 char(10), c8 text ) SERVER influxdb_svr OPTIONS (table 'T0', tags 'c3'); --Testcase 11: -CREATE FOREIGN TABLE "S 1"."T 1" (time timestamp, tags jsonb OPTIONS(tags 'true'), fields jsonb OPTIONS(fields 'true')) SERVER influxdb_svr OPTIONS (table 'T1', tags 'c3', schemaless 'true'); +CREATE FOREIGN TABLE "S 1"."T 1" (time timestamptz, tags jsonb OPTIONS(tags 'true'), fields jsonb OPTIONS(fields 'true')) SERVER influxdb_svr OPTIONS (table 'T1', tags 'c3', schemaless 'true'); CREATE FOREIGN TABLE "S 1".s1t1 ( "C 1" int NOT NULL, c2 int NOT NULL, c3 text, - time timestamp, + time timestamptz, c6 varchar(10), c7 char(10), c8 text @@ -77,7 +77,7 @@ INSERT INTO "S 1".s1t1 SELECT id, id % 10, to_char(id, 'FM00000'), - '1970-01-01'::timestamp + ((id % 100) || ' days')::interval, + '1970-01-01'::timestamptz + ((id % 100) || ' days')::interval, id % 10, id % 10, 'foo'::text @@ -111,13 +111,13 @@ DELETE FROM "S 1".s1t4 WHERE c1 % 3 != 0; -- delete for outer join tests -- create foreign tables -- =================================================================== --Testcase 21: -CREATE FOREIGN TABLE ft1 (time timestamp, tags jsonb OPTIONS(tags 'true'), fields jsonb OPTIONS(fields 'true')) SERVER influxdb_svr OPTIONS (schemaless 'true'); +CREATE FOREIGN TABLE ft1 (time timestamptz, tags jsonb OPTIONS(tags 'true'), fields jsonb OPTIONS(fields 'true')) SERVER influxdb_svr OPTIONS (schemaless 'true'); CREATE FOREIGN TABLE ft1_nsc ( c0 int, c1 int NOT NULL, c2 int NOT NULL, c3 text, - time timestamp, + time timestamptz, c6 varchar(10), c7 char(10) default 'ft1', c8 text @@ -125,13 +125,13 @@ CREATE FOREIGN TABLE ft1_nsc ( --Testcase 22: ALTER FOREIGN TABLE ft1_nsc DROP COLUMN c0; --Testcase 23: -CREATE FOREIGN TABLE ft2 (time timestamp, tags jsonb OPTIONS(tags 'true'), fields jsonb OPTIONS(fields 'true')) SERVER influxdb_svr OPTIONS (schemaless 'true'); +CREATE FOREIGN TABLE ft2 (time timestamptz, tags jsonb OPTIONS(tags 'true'), fields jsonb OPTIONS(fields 'true')) SERVER influxdb_svr OPTIONS (schemaless 'true'); CREATE FOREIGN TABLE ft2_nsc ( c1 int NOT NULL, c2 int NOT NULL, cx int, c3 text, - time timestamp, + time timestamptz, c6 varchar(10), c7 char(10) default 'ft2', c8 text @@ -240,9 +240,9 @@ ALTER FOREIGN TABLE ft2_nsc ALTER COLUMN c1 OPTIONS (column_name 'C 1'); \set VERBOSITY terse --Testcase 35: SELECT tags->>'c3' c3, time FROM ft1 ORDER BY tags->>'c3', (fields->>'C 1')::int LIMIT 1; -- should work - c3 | time --------+-------------------------- - 00001 | Fri Jan 02 00:00:00 1970 + c3 | time +-------+------------------------------ + 00001 | Fri Jan 02 00:00:00 1970 PST (1 row) --Testcase 36: @@ -258,9 +258,9 @@ DO $d$ $d$; --Testcase 38: SELECT tags->>'c3' c3, time FROM ft1 ORDER BY tags->>'c3', (fields->>'C 1')::int LIMIT 1; -- should work again - c3 | time --------+-------------------------- - 00001 | Fri Jan 02 00:00:00 1970 + c3 | time +-------+------------------------------ + 00001 | Fri Jan 02 00:00:00 1970 PST (1 row) \set VERBOSITY default @@ -280,18 +280,18 @@ EXPLAIN (COSTS OFF) SELECT * FROM ft1 ORDER BY tags->>'c3', (fields->>'C 1')::in --Testcase 40: SELECT * FROM ft1 ORDER BY tags->>'c3', (fields->>'C 1')::int OFFSET 100 LIMIT 10; - time | tags | fields ---------------------------+-----------------+----------------------------------------------------------------------- - Fri Jan 02 00:00:00 1970 | {"c3": "00101"} | {"c2": "1", "c6": "1", "c7": "1 ", "c8": "foo", "C 1": "101"} - Sat Jan 03 00:00:00 1970 | {"c3": "00102"} | {"c2": "2", "c6": "2", "c7": "2 ", "c8": "foo", "C 1": "102"} - Sun Jan 04 00:00:00 1970 | {"c3": "00103"} | {"c2": "3", "c6": "3", "c7": "3 ", "c8": "foo", "C 1": "103"} - Mon Jan 05 00:00:00 1970 | {"c3": "00104"} | {"c2": "4", "c6": "4", "c7": "4 ", "c8": "foo", "C 1": "104"} - Tue Jan 06 00:00:00 1970 | {"c3": "00105"} | {"c2": "5", "c6": "5", "c7": "5 ", "c8": "foo", "C 1": "105"} - Wed Jan 07 00:00:00 1970 | {"c3": "00106"} | {"c2": "6", "c6": "6", "c7": "6 ", "c8": "foo", "C 1": "106"} - Thu Jan 08 00:00:00 1970 | {"c3": "00107"} | {"c2": "7", "c6": "7", "c7": "7 ", "c8": "foo", "C 1": "107"} - Fri Jan 09 00:00:00 1970 | {"c3": "00108"} | {"c2": "8", "c6": "8", "c7": "8 ", "c8": "foo", "C 1": "108"} - Sat Jan 10 00:00:00 1970 | {"c3": "00109"} | {"c2": "9", "c6": "9", "c7": "9 ", "c8": "foo", "C 1": "109"} - Sun Jan 11 00:00:00 1970 | {"c3": "00110"} | {"c2": "0", "c6": "0", "c7": "0 ", "c8": "foo", "C 1": "110"} + time | tags | fields +------------------------------+-----------------+----------------------------------------------------------------------- + Fri Jan 02 00:00:00 1970 PST | {"c3": "00101"} | {"c2": "1", "c6": "1", "c7": "1 ", "c8": "foo", "C 1": "101"} + Sat Jan 03 00:00:00 1970 PST | {"c3": "00102"} | {"c2": "2", "c6": "2", "c7": "2 ", "c8": "foo", "C 1": "102"} + Sun Jan 04 00:00:00 1970 PST | {"c3": "00103"} | {"c2": "3", "c6": "3", "c7": "3 ", "c8": "foo", "C 1": "103"} + Mon Jan 05 00:00:00 1970 PST | {"c3": "00104"} | {"c2": "4", "c6": "4", "c7": "4 ", "c8": "foo", "C 1": "104"} + Tue Jan 06 00:00:00 1970 PST | {"c3": "00105"} | {"c2": "5", "c6": "5", "c7": "5 ", "c8": "foo", "C 1": "105"} + Wed Jan 07 00:00:00 1970 PST | {"c3": "00106"} | {"c2": "6", "c6": "6", "c7": "6 ", "c8": "foo", "C 1": "106"} + Thu Jan 08 00:00:00 1970 PST | {"c3": "00107"} | {"c2": "7", "c6": "7", "c7": "7 ", "c8": "foo", "C 1": "107"} + Fri Jan 09 00:00:00 1970 PST | {"c3": "00108"} | {"c2": "8", "c6": "8", "c7": "8 ", "c8": "foo", "C 1": "108"} + Sat Jan 10 00:00:00 1970 PST | {"c3": "00109"} | {"c2": "9", "c6": "9", "c7": "9 ", "c8": "foo", "C 1": "109"} + Sun Jan 11 00:00:00 1970 PST | {"c3": "00110"} | {"c2": "0", "c6": "0", "c7": "0 ", "c8": "foo", "C 1": "110"} (10 rows) -- single table with alias - also test that tableoid sort is not pushed to remote side @@ -311,18 +311,18 @@ EXPLAIN (VERBOSE, COSTS OFF) SELECT * FROM ft1 t1 ORDER BY t1.tags->>'c3', (t1.f --Testcase 42: SELECT * FROM ft1 t1 ORDER BY t1.tags->>'c3', (t1.fields->>'C 1')::int, t1.tableoid OFFSET 100 LIMIT 10; - time | tags | fields ---------------------------+-----------------+----------------------------------------------------------------------- - Fri Jan 02 00:00:00 1970 | {"c3": "00101"} | {"c2": "1", "c6": "1", "c7": "1 ", "c8": "foo", "C 1": "101"} - Sat Jan 03 00:00:00 1970 | {"c3": "00102"} | {"c2": "2", "c6": "2", "c7": "2 ", "c8": "foo", "C 1": "102"} - Sun Jan 04 00:00:00 1970 | {"c3": "00103"} | {"c2": "3", "c6": "3", "c7": "3 ", "c8": "foo", "C 1": "103"} - Mon Jan 05 00:00:00 1970 | {"c3": "00104"} | {"c2": "4", "c6": "4", "c7": "4 ", "c8": "foo", "C 1": "104"} - Tue Jan 06 00:00:00 1970 | {"c3": "00105"} | {"c2": "5", "c6": "5", "c7": "5 ", "c8": "foo", "C 1": "105"} - Wed Jan 07 00:00:00 1970 | {"c3": "00106"} | {"c2": "6", "c6": "6", "c7": "6 ", "c8": "foo", "C 1": "106"} - Thu Jan 08 00:00:00 1970 | {"c3": "00107"} | {"c2": "7", "c6": "7", "c7": "7 ", "c8": "foo", "C 1": "107"} - Fri Jan 09 00:00:00 1970 | {"c3": "00108"} | {"c2": "8", "c6": "8", "c7": "8 ", "c8": "foo", "C 1": "108"} - Sat Jan 10 00:00:00 1970 | {"c3": "00109"} | {"c2": "9", "c6": "9", "c7": "9 ", "c8": "foo", "C 1": "109"} - Sun Jan 11 00:00:00 1970 | {"c3": "00110"} | {"c2": "0", "c6": "0", "c7": "0 ", "c8": "foo", "C 1": "110"} + time | tags | fields +------------------------------+-----------------+----------------------------------------------------------------------- + Fri Jan 02 00:00:00 1970 PST | {"c3": "00101"} | {"c2": "1", "c6": "1", "c7": "1 ", "c8": "foo", "C 1": "101"} + Sat Jan 03 00:00:00 1970 PST | {"c3": "00102"} | {"c2": "2", "c6": "2", "c7": "2 ", "c8": "foo", "C 1": "102"} + Sun Jan 04 00:00:00 1970 PST | {"c3": "00103"} | {"c2": "3", "c6": "3", "c7": "3 ", "c8": "foo", "C 1": "103"} + Mon Jan 05 00:00:00 1970 PST | {"c3": "00104"} | {"c2": "4", "c6": "4", "c7": "4 ", "c8": "foo", "C 1": "104"} + Tue Jan 06 00:00:00 1970 PST | {"c3": "00105"} | {"c2": "5", "c6": "5", "c7": "5 ", "c8": "foo", "C 1": "105"} + Wed Jan 07 00:00:00 1970 PST | {"c3": "00106"} | {"c2": "6", "c6": "6", "c7": "6 ", "c8": "foo", "C 1": "106"} + Thu Jan 08 00:00:00 1970 PST | {"c3": "00107"} | {"c2": "7", "c6": "7", "c7": "7 ", "c8": "foo", "C 1": "107"} + Fri Jan 09 00:00:00 1970 PST | {"c3": "00108"} | {"c2": "8", "c6": "8", "c7": "8 ", "c8": "foo", "C 1": "108"} + Sat Jan 10 00:00:00 1970 PST | {"c3": "00109"} | {"c2": "9", "c6": "9", "c7": "9 ", "c8": "foo", "C 1": "109"} + Sun Jan 11 00:00:00 1970 PST | {"c3": "00110"} | {"c2": "0", "c6": "0", "c7": "0 ", "c8": "foo", "C 1": "110"} (10 rows) -- whole-row reference @@ -342,18 +342,18 @@ EXPLAIN (VERBOSE, COSTS OFF) SELECT t1 FROM ft1 t1 ORDER BY t1.tags->>'c3', (t1. --Testcase 44: SELECT t1 FROM ft1 t1 ORDER BY t1.tags->>'c3', (t1.fields->>'C 1')::int OFFSET 100 LIMIT 10; - t1 ------------------------------------------------------------------------------------------------------------------------------------------------- - ("Fri Jan 02 00:00:00 1970","{""c3"": ""00101""}","{""c2"": ""1"", ""c6"": ""1"", ""c7"": ""1 "", ""c8"": ""foo"", ""C 1"": ""101""}") - ("Sat Jan 03 00:00:00 1970","{""c3"": ""00102""}","{""c2"": ""2"", ""c6"": ""2"", ""c7"": ""2 "", ""c8"": ""foo"", ""C 1"": ""102""}") - ("Sun Jan 04 00:00:00 1970","{""c3"": ""00103""}","{""c2"": ""3"", ""c6"": ""3"", ""c7"": ""3 "", ""c8"": ""foo"", ""C 1"": ""103""}") - ("Mon Jan 05 00:00:00 1970","{""c3"": ""00104""}","{""c2"": ""4"", ""c6"": ""4"", ""c7"": ""4 "", ""c8"": ""foo"", ""C 1"": ""104""}") - ("Tue Jan 06 00:00:00 1970","{""c3"": ""00105""}","{""c2"": ""5"", ""c6"": ""5"", ""c7"": ""5 "", ""c8"": ""foo"", ""C 1"": ""105""}") - ("Wed Jan 07 00:00:00 1970","{""c3"": ""00106""}","{""c2"": ""6"", ""c6"": ""6"", ""c7"": ""6 "", ""c8"": ""foo"", ""C 1"": ""106""}") - ("Thu Jan 08 00:00:00 1970","{""c3"": ""00107""}","{""c2"": ""7"", ""c6"": ""7"", ""c7"": ""7 "", ""c8"": ""foo"", ""C 1"": ""107""}") - ("Fri Jan 09 00:00:00 1970","{""c3"": ""00108""}","{""c2"": ""8"", ""c6"": ""8"", ""c7"": ""8 "", ""c8"": ""foo"", ""C 1"": ""108""}") - ("Sat Jan 10 00:00:00 1970","{""c3"": ""00109""}","{""c2"": ""9"", ""c6"": ""9"", ""c7"": ""9 "", ""c8"": ""foo"", ""C 1"": ""109""}") - ("Sun Jan 11 00:00:00 1970","{""c3"": ""00110""}","{""c2"": ""0"", ""c6"": ""0"", ""c7"": ""0 "", ""c8"": ""foo"", ""C 1"": ""110""}") + t1 +---------------------------------------------------------------------------------------------------------------------------------------------------- + ("Fri Jan 02 00:00:00 1970 PST","{""c3"": ""00101""}","{""c2"": ""1"", ""c6"": ""1"", ""c7"": ""1 "", ""c8"": ""foo"", ""C 1"": ""101""}") + ("Sat Jan 03 00:00:00 1970 PST","{""c3"": ""00102""}","{""c2"": ""2"", ""c6"": ""2"", ""c7"": ""2 "", ""c8"": ""foo"", ""C 1"": ""102""}") + ("Sun Jan 04 00:00:00 1970 PST","{""c3"": ""00103""}","{""c2"": ""3"", ""c6"": ""3"", ""c7"": ""3 "", ""c8"": ""foo"", ""C 1"": ""103""}") + ("Mon Jan 05 00:00:00 1970 PST","{""c3"": ""00104""}","{""c2"": ""4"", ""c6"": ""4"", ""c7"": ""4 "", ""c8"": ""foo"", ""C 1"": ""104""}") + ("Tue Jan 06 00:00:00 1970 PST","{""c3"": ""00105""}","{""c2"": ""5"", ""c6"": ""5"", ""c7"": ""5 "", ""c8"": ""foo"", ""C 1"": ""105""}") + ("Wed Jan 07 00:00:00 1970 PST","{""c3"": ""00106""}","{""c2"": ""6"", ""c6"": ""6"", ""c7"": ""6 "", ""c8"": ""foo"", ""C 1"": ""106""}") + ("Thu Jan 08 00:00:00 1970 PST","{""c3"": ""00107""}","{""c2"": ""7"", ""c6"": ""7"", ""c7"": ""7 "", ""c8"": ""foo"", ""C 1"": ""107""}") + ("Fri Jan 09 00:00:00 1970 PST","{""c3"": ""00108""}","{""c2"": ""8"", ""c6"": ""8"", ""c7"": ""8 "", ""c8"": ""foo"", ""C 1"": ""108""}") + ("Sat Jan 10 00:00:00 1970 PST","{""c3"": ""00109""}","{""c2"": ""9"", ""c6"": ""9"", ""c7"": ""9 "", ""c8"": ""foo"", ""C 1"": ""109""}") + ("Sun Jan 11 00:00:00 1970 PST","{""c3"": ""00110""}","{""c2"": ""0"", ""c6"": ""0"", ""c7"": ""0 "", ""c8"": ""foo"", ""C 1"": ""110""}") (10 rows) -- empty result @@ -376,9 +376,9 @@ EXPLAIN (VERBOSE, COSTS OFF) SELECT * FROM ft1 t1 WHERE (t1.fields->>'C 1')::int --Testcase 47: SELECT * FROM ft1 t1 WHERE (t1.fields->>'C 1')::int = 101 AND t1.fields->>'c6' = '1' AND t1.fields->>'c7' >= '1'; - time | tags | fields ---------------------------+-----------------+----------------------------------------------------------------------- - Fri Jan 02 00:00:00 1970 | {"c3": "00101"} | {"c2": "1", "c6": "1", "c7": "1 ", "c8": "foo", "C 1": "101"} + time | tags | fields +------------------------------+-----------------+----------------------------------------------------------------------- + Fri Jan 02 00:00:00 1970 PST | {"c3": "00101"} | {"c2": "1", "c6": "1", "c7": "1 ", "c8": "foo", "C 1": "101"} (1 row) -- with FOR UPDATE/SHARE @@ -395,9 +395,9 @@ EXPLAIN (VERBOSE, COSTS OFF) SELECT * FROM ft1 t1 WHERE (fields->>'C 1')::int = --Testcase 49: SELECT * FROM ft1 t1 WHERE (fields->>'C 1')::int = 101 FOR UPDATE; - time | tags | fields ---------------------------+-----------------+----------------------------------------------------------------------- - Fri Jan 02 00:00:00 1970 | {"c3": "00101"} | {"c2": "1", "c6": "1", "c7": "1 ", "c8": "foo", "C 1": "101"} + time | tags | fields +------------------------------+-----------------+----------------------------------------------------------------------- + Fri Jan 02 00:00:00 1970 PST | {"c3": "00101"} | {"c2": "1", "c6": "1", "c7": "1 ", "c8": "foo", "C 1": "101"} (1 row) --Testcase 50: @@ -413,9 +413,9 @@ EXPLAIN (VERBOSE, COSTS OFF) SELECT * FROM ft1 t1 WHERE (fields->>'C 1')::int = --Testcase 51: SELECT * FROM ft1 t1 WHERE (fields->>'C 1')::int = 102 FOR SHARE; - time | tags | fields ---------------------------+-----------------+----------------------------------------------------------------------- - Sat Jan 03 00:00:00 1970 | {"c3": "00102"} | {"c2": "2", "c6": "2", "c7": "2 ", "c8": "foo", "C 1": "102"} + time | tags | fields +------------------------------+-----------------+----------------------------------------------------------------------- + Sat Jan 03 00:00:00 1970 PST | {"c3": "00102"} | {"c2": "2", "c6": "2", "c7": "2 ", "c8": "foo", "C 1": "102"} (1 row) -- aggregate @@ -429,43 +429,43 @@ SELECT COUNT(*) FROM ft1 t1; -- subquery --Testcase 53: SELECT * FROM ft1 t1 WHERE t1.tags->>'c3' IN (SELECT tags->>'c3' FROM ft2 t2 WHERE (fields->>'C 1')::int <= 10) ORDER BY (fields->>'C 1')::int; - time | tags | fields ---------------------------+-----------------+---------------------------------------------------------------------- - Fri Jan 02 00:00:00 1970 | {"c3": "00001"} | {"c2": "1", "c6": "1", "c7": "1 ", "c8": "foo", "C 1": "1"} - Sat Jan 03 00:00:00 1970 | {"c3": "00002"} | {"c2": "2", "c6": "2", "c7": "2 ", "c8": "foo", "C 1": "2"} - Sun Jan 04 00:00:00 1970 | {"c3": "00003"} | {"c2": "3", "c6": "3", "c7": "3 ", "c8": "foo", "C 1": "3"} - Mon Jan 05 00:00:00 1970 | {"c3": "00004"} | {"c2": "4", "c6": "4", "c7": "4 ", "c8": "foo", "C 1": "4"} - Tue Jan 06 00:00:00 1970 | {"c3": "00005"} | {"c2": "5", "c6": "5", "c7": "5 ", "c8": "foo", "C 1": "5"} - Wed Jan 07 00:00:00 1970 | {"c3": "00006"} | {"c2": "6", "c6": "6", "c7": "6 ", "c8": "foo", "C 1": "6"} - Thu Jan 08 00:00:00 1970 | {"c3": "00007"} | {"c2": "7", "c6": "7", "c7": "7 ", "c8": "foo", "C 1": "7"} - Fri Jan 09 00:00:00 1970 | {"c3": "00008"} | {"c2": "8", "c6": "8", "c7": "8 ", "c8": "foo", "C 1": "8"} - Sat Jan 10 00:00:00 1970 | {"c3": "00009"} | {"c2": "9", "c6": "9", "c7": "9 ", "c8": "foo", "C 1": "9"} - Sun Jan 11 00:00:00 1970 | {"c3": "00010"} | {"c2": "0", "c6": "0", "c7": "0 ", "c8": "foo", "C 1": "10"} + time | tags | fields +------------------------------+-----------------+---------------------------------------------------------------------- + Fri Jan 02 00:00:00 1970 PST | {"c3": "00001"} | {"c2": "1", "c6": "1", "c7": "1 ", "c8": "foo", "C 1": "1"} + Sat Jan 03 00:00:00 1970 PST | {"c3": "00002"} | {"c2": "2", "c6": "2", "c7": "2 ", "c8": "foo", "C 1": "2"} + Sun Jan 04 00:00:00 1970 PST | {"c3": "00003"} | {"c2": "3", "c6": "3", "c7": "3 ", "c8": "foo", "C 1": "3"} + Mon Jan 05 00:00:00 1970 PST | {"c3": "00004"} | {"c2": "4", "c6": "4", "c7": "4 ", "c8": "foo", "C 1": "4"} + Tue Jan 06 00:00:00 1970 PST | {"c3": "00005"} | {"c2": "5", "c6": "5", "c7": "5 ", "c8": "foo", "C 1": "5"} + Wed Jan 07 00:00:00 1970 PST | {"c3": "00006"} | {"c2": "6", "c6": "6", "c7": "6 ", "c8": "foo", "C 1": "6"} + Thu Jan 08 00:00:00 1970 PST | {"c3": "00007"} | {"c2": "7", "c6": "7", "c7": "7 ", "c8": "foo", "C 1": "7"} + Fri Jan 09 00:00:00 1970 PST | {"c3": "00008"} | {"c2": "8", "c6": "8", "c7": "8 ", "c8": "foo", "C 1": "8"} + Sat Jan 10 00:00:00 1970 PST | {"c3": "00009"} | {"c2": "9", "c6": "9", "c7": "9 ", "c8": "foo", "C 1": "9"} + Sun Jan 11 00:00:00 1970 PST | {"c3": "00010"} | {"c2": "0", "c6": "0", "c7": "0 ", "c8": "foo", "C 1": "10"} (10 rows) -- subquery+MAX --Testcase 54: SELECT * FROM ft1 t1 WHERE t1.tags->>'c3' = (SELECT MAX(tags->>'c3') FROM ft2 t2) ORDER BY (fields->>'C 1')::int; - time | tags | fields ---------------------------+-----------------+------------------------------------------------------------------------ - Thu Jan 01 00:00:00 1970 | {"c3": "01000"} | {"c2": "0", "c6": "0", "c7": "0 ", "c8": "foo", "C 1": "1000"} + time | tags | fields +------------------------------+-----------------+------------------------------------------------------------------------ + Thu Jan 01 00:00:00 1970 PST | {"c3": "01000"} | {"c2": "0", "c6": "0", "c7": "0 ", "c8": "foo", "C 1": "1000"} (1 row) -- used in CTE --Testcase 55: WITH t1 AS (SELECT * FROM ft1 WHERE (fields->>'C 1')::int <= 10) SELECT (t2.fields->>'C 1')::int c1, (t2.fields->>'c2')::int c2, t2.tags->>'c3' c3, t2.time FROM t1, ft2 t2 WHERE (t1.fields->>'C 1')::int = (t2.fields->>'C 1')::int ORDER BY (t1.fields->>'C 1')::int; - c1 | c2 | c3 | time -----+----+-------+-------------------------- - 1 | 1 | 00001 | Fri Jan 02 00:00:00 1970 - 2 | 2 | 00002 | Sat Jan 03 00:00:00 1970 - 3 | 3 | 00003 | Sun Jan 04 00:00:00 1970 - 4 | 4 | 00004 | Mon Jan 05 00:00:00 1970 - 5 | 5 | 00005 | Tue Jan 06 00:00:00 1970 - 6 | 6 | 00006 | Wed Jan 07 00:00:00 1970 - 7 | 7 | 00007 | Thu Jan 08 00:00:00 1970 - 8 | 8 | 00008 | Fri Jan 09 00:00:00 1970 - 9 | 9 | 00009 | Sat Jan 10 00:00:00 1970 - 10 | 0 | 00010 | Sun Jan 11 00:00:00 1970 + c1 | c2 | c3 | time +----+----+-------+------------------------------ + 1 | 1 | 00001 | Fri Jan 02 00:00:00 1970 PST + 2 | 2 | 00002 | Sat Jan 03 00:00:00 1970 PST + 3 | 3 | 00003 | Sun Jan 04 00:00:00 1970 PST + 4 | 4 | 00004 | Mon Jan 05 00:00:00 1970 PST + 5 | 5 | 00005 | Tue Jan 06 00:00:00 1970 PST + 6 | 6 | 00006 | Wed Jan 07 00:00:00 1970 PST + 7 | 7 | 00007 | Thu Jan 08 00:00:00 1970 PST + 8 | 8 | 00008 | Fri Jan 09 00:00:00 1970 PST + 9 | 9 | 00009 | Sat Jan 10 00:00:00 1970 PST + 10 | 0 | 00010 | Sun Jan 11 00:00:00 1970 PST (10 rows) -- fixed values @@ -883,9 +883,9 @@ EXPLAIN (VERBOSE, COSTS OFF) --Testcase 88: SELECT * FROM ft2 a, ft2 b WHERE (a.fields->>'C 1')::int = 47 AND (b.fields->>'C 1')::int = (a.fields->>'c2')::int; - time | tags | fields | time | tags | fields ---------------------------+-----------------+----------------------------------------------------------------------+--------------------------+-----------------+--------------------------------------------------------------------- - Tue Feb 17 00:00:00 1970 | {"c3": "00047"} | {"c2": "7", "c6": "7", "c7": "7 ", "c8": "foo", "C 1": "47"} | Thu Jan 08 00:00:00 1970 | {"c3": "00007"} | {"c2": "7", "c6": "7", "c7": "7 ", "c8": "foo", "C 1": "7"} + time | tags | fields | time | tags | fields +------------------------------+-----------------+----------------------------------------------------------------------+------------------------------+-----------------+--------------------------------------------------------------------- + Tue Feb 17 00:00:00 1970 PST | {"c3": "00047"} | {"c2": "7", "c6": "7", "c7": "7 ", "c8": "foo", "C 1": "47"} | Thu Jan 08 00:00:00 1970 PST | {"c3": "00007"} | {"c2": "7", "c6": "7", "c7": "7 ", "c8": "foo", "C 1": "7"} (1 row) -- check both safe and unsafe join conditions @@ -911,129 +911,129 @@ EXPLAIN (VERBOSE, COSTS OFF) --Testcase 90: SELECT * FROM ft2 a, ft2 b WHERE (a.fields->>'c2')::int = 6 AND (b.fields->>'C 1')::int = (a.fields->>'C 1')::int AND a.fields->>'c8' = 'foo' AND b.fields->>'c7' = upper(a.fields->>'c7') ORDER BY (a.fields->>'C 1')::int; - time | tags | fields | time | tags | fields ---------------------------+-----------------+-----------------------------------------------------------------------+--------------------------+-----------------+----------------------------------------------------------------------- - Wed Jan 07 00:00:00 1970 | {"c3": "00006"} | {"c2": "6", "c6": "6", "c7": "6 ", "c8": "foo", "C 1": "6"} | Wed Jan 07 00:00:00 1970 | {"c3": "00006"} | {"c2": "6", "c6": "6", "c7": "6 ", "c8": "foo", "C 1": "6"} - Sat Jan 17 00:00:00 1970 | {"c3": "00016"} | {"c2": "6", "c6": "6", "c7": "6 ", "c8": "foo", "C 1": "16"} | Sat Jan 17 00:00:00 1970 | {"c3": "00016"} | {"c2": "6", "c6": "6", "c7": "6 ", "c8": "foo", "C 1": "16"} - Tue Jan 27 00:00:00 1970 | {"c3": "00026"} | {"c2": "6", "c6": "6", "c7": "6 ", "c8": "foo", "C 1": "26"} | Tue Jan 27 00:00:00 1970 | {"c3": "00026"} | {"c2": "6", "c6": "6", "c7": "6 ", "c8": "foo", "C 1": "26"} - Fri Feb 06 00:00:00 1970 | {"c3": "00036"} | {"c2": "6", "c6": "6", "c7": "6 ", "c8": "foo", "C 1": "36"} | Fri Feb 06 00:00:00 1970 | {"c3": "00036"} | {"c2": "6", "c6": "6", "c7": "6 ", "c8": "foo", "C 1": "36"} - Mon Feb 16 00:00:00 1970 | {"c3": "00046"} | {"c2": "6", "c6": "6", "c7": "6 ", "c8": "foo", "C 1": "46"} | Mon Feb 16 00:00:00 1970 | {"c3": "00046"} | {"c2": "6", "c6": "6", "c7": "6 ", "c8": "foo", "C 1": "46"} - Thu Feb 26 00:00:00 1970 | {"c3": "00056"} | {"c2": "6", "c6": "6", "c7": "6 ", "c8": "foo", "C 1": "56"} | Thu Feb 26 00:00:00 1970 | {"c3": "00056"} | {"c2": "6", "c6": "6", "c7": "6 ", "c8": "foo", "C 1": "56"} - Sun Mar 08 00:00:00 1970 | {"c3": "00066"} | {"c2": "6", "c6": "6", "c7": "6 ", "c8": "foo", "C 1": "66"} | Sun Mar 08 00:00:00 1970 | {"c3": "00066"} | {"c2": "6", "c6": "6", "c7": "6 ", "c8": "foo", "C 1": "66"} - Wed Mar 18 00:00:00 1970 | {"c3": "00076"} | {"c2": "6", "c6": "6", "c7": "6 ", "c8": "foo", "C 1": "76"} | Wed Mar 18 00:00:00 1970 | {"c3": "00076"} | {"c2": "6", "c6": "6", "c7": "6 ", "c8": "foo", "C 1": "76"} - Sat Mar 28 00:00:00 1970 | {"c3": "00086"} | {"c2": "6", "c6": "6", "c7": "6 ", "c8": "foo", "C 1": "86"} | Sat Mar 28 00:00:00 1970 | {"c3": "00086"} | {"c2": "6", "c6": "6", "c7": "6 ", "c8": "foo", "C 1": "86"} - Tue Apr 07 00:00:00 1970 | {"c3": "00096"} | {"c2": "6", "c6": "6", "c7": "6 ", "c8": "foo", "C 1": "96"} | Tue Apr 07 00:00:00 1970 | {"c3": "00096"} | {"c2": "6", "c6": "6", "c7": "6 ", "c8": "foo", "C 1": "96"} - Wed Jan 07 00:00:00 1970 | {"c3": "00106"} | {"c2": "6", "c6": "6", "c7": "6 ", "c8": "foo", "C 1": "106"} | Wed Jan 07 00:00:00 1970 | {"c3": "00106"} | {"c2": "6", "c6": "6", "c7": "6 ", "c8": "foo", "C 1": "106"} - Sat Jan 17 00:00:00 1970 | {"c3": "00116"} | {"c2": "6", "c6": "6", "c7": "6 ", "c8": "foo", "C 1": "116"} | Sat Jan 17 00:00:00 1970 | {"c3": "00116"} | {"c2": "6", "c6": "6", "c7": "6 ", "c8": "foo", "C 1": "116"} - Tue Jan 27 00:00:00 1970 | {"c3": "00126"} | {"c2": "6", "c6": "6", "c7": "6 ", "c8": "foo", "C 1": "126"} | Tue Jan 27 00:00:00 1970 | {"c3": "00126"} | {"c2": "6", "c6": "6", "c7": "6 ", "c8": "foo", "C 1": "126"} - Fri Feb 06 00:00:00 1970 | {"c3": "00136"} | {"c2": "6", "c6": "6", "c7": "6 ", "c8": "foo", "C 1": "136"} | Fri Feb 06 00:00:00 1970 | {"c3": "00136"} | {"c2": "6", "c6": "6", "c7": "6 ", "c8": "foo", "C 1": "136"} - Mon Feb 16 00:00:00 1970 | {"c3": "00146"} | {"c2": "6", "c6": "6", "c7": "6 ", "c8": "foo", "C 1": "146"} | Mon Feb 16 00:00:00 1970 | {"c3": "00146"} | {"c2": "6", "c6": "6", "c7": "6 ", "c8": "foo", "C 1": "146"} - Thu Feb 26 00:00:00 1970 | {"c3": "00156"} | {"c2": "6", "c6": "6", "c7": "6 ", "c8": "foo", "C 1": "156"} | Thu Feb 26 00:00:00 1970 | {"c3": "00156"} | {"c2": "6", "c6": "6", "c7": "6 ", "c8": "foo", "C 1": "156"} - Sun Mar 08 00:00:00 1970 | {"c3": "00166"} | {"c2": "6", "c6": "6", "c7": "6 ", "c8": "foo", "C 1": "166"} | Sun Mar 08 00:00:00 1970 | {"c3": "00166"} | {"c2": "6", "c6": "6", "c7": "6 ", "c8": "foo", "C 1": "166"} - Wed Mar 18 00:00:00 1970 | {"c3": "00176"} | {"c2": "6", "c6": "6", "c7": "6 ", "c8": "foo", "C 1": "176"} | Wed Mar 18 00:00:00 1970 | {"c3": "00176"} | {"c2": "6", "c6": "6", "c7": "6 ", "c8": "foo", "C 1": "176"} - Sat Mar 28 00:00:00 1970 | {"c3": "00186"} | {"c2": "6", "c6": "6", "c7": "6 ", "c8": "foo", "C 1": "186"} | Sat Mar 28 00:00:00 1970 | {"c3": "00186"} | {"c2": "6", "c6": "6", "c7": "6 ", "c8": "foo", "C 1": "186"} - Tue Apr 07 00:00:00 1970 | {"c3": "00196"} | {"c2": "6", "c6": "6", "c7": "6 ", "c8": "foo", "C 1": "196"} | Tue Apr 07 00:00:00 1970 | {"c3": "00196"} | {"c2": "6", "c6": "6", "c7": "6 ", "c8": "foo", "C 1": "196"} - Wed Jan 07 00:00:00 1970 | {"c3": "00206"} | {"c2": "6", "c6": "6", "c7": "6 ", "c8": "foo", "C 1": "206"} | Wed Jan 07 00:00:00 1970 | {"c3": "00206"} | {"c2": "6", "c6": "6", "c7": "6 ", "c8": "foo", "C 1": "206"} - Sat Jan 17 00:00:00 1970 | {"c3": "00216"} | {"c2": "6", "c6": "6", "c7": "6 ", "c8": "foo", "C 1": "216"} | Sat Jan 17 00:00:00 1970 | {"c3": "00216"} | {"c2": "6", "c6": "6", "c7": "6 ", "c8": "foo", "C 1": "216"} - Tue Jan 27 00:00:00 1970 | {"c3": "00226"} | {"c2": "6", "c6": "6", "c7": "6 ", "c8": "foo", "C 1": "226"} | Tue Jan 27 00:00:00 1970 | {"c3": "00226"} | {"c2": "6", "c6": "6", "c7": "6 ", "c8": "foo", "C 1": "226"} - Fri Feb 06 00:00:00 1970 | {"c3": "00236"} | {"c2": "6", "c6": "6", "c7": "6 ", "c8": "foo", "C 1": "236"} | Fri Feb 06 00:00:00 1970 | {"c3": "00236"} | {"c2": "6", "c6": "6", "c7": "6 ", "c8": "foo", "C 1": "236"} - Mon Feb 16 00:00:00 1970 | {"c3": "00246"} | {"c2": "6", "c6": "6", "c7": "6 ", "c8": "foo", "C 1": "246"} | Mon Feb 16 00:00:00 1970 | {"c3": "00246"} | {"c2": "6", "c6": "6", "c7": "6 ", "c8": "foo", "C 1": "246"} - Thu Feb 26 00:00:00 1970 | {"c3": "00256"} | {"c2": "6", "c6": "6", "c7": "6 ", "c8": "foo", "C 1": "256"} | Thu Feb 26 00:00:00 1970 | {"c3": "00256"} | {"c2": "6", "c6": "6", "c7": "6 ", "c8": "foo", "C 1": "256"} - Sun Mar 08 00:00:00 1970 | {"c3": "00266"} | {"c2": "6", "c6": "6", "c7": "6 ", "c8": "foo", "C 1": "266"} | Sun Mar 08 00:00:00 1970 | {"c3": "00266"} | {"c2": "6", "c6": "6", "c7": "6 ", "c8": "foo", "C 1": "266"} - Wed Mar 18 00:00:00 1970 | {"c3": "00276"} | {"c2": "6", "c6": "6", "c7": "6 ", "c8": "foo", "C 1": "276"} | Wed Mar 18 00:00:00 1970 | {"c3": "00276"} | {"c2": "6", "c6": "6", "c7": "6 ", "c8": "foo", "C 1": "276"} - Sat Mar 28 00:00:00 1970 | {"c3": "00286"} | {"c2": "6", "c6": "6", "c7": "6 ", "c8": "foo", "C 1": "286"} | Sat Mar 28 00:00:00 1970 | {"c3": "00286"} | {"c2": "6", "c6": "6", "c7": "6 ", "c8": "foo", "C 1": "286"} - Tue Apr 07 00:00:00 1970 | {"c3": "00296"} | {"c2": "6", "c6": "6", "c7": "6 ", "c8": "foo", "C 1": "296"} | Tue Apr 07 00:00:00 1970 | {"c3": "00296"} | {"c2": "6", "c6": "6", "c7": "6 ", "c8": "foo", "C 1": "296"} - Wed Jan 07 00:00:00 1970 | {"c3": "00306"} | {"c2": "6", "c6": "6", "c7": "6 ", "c8": "foo", "C 1": "306"} | Wed Jan 07 00:00:00 1970 | {"c3": "00306"} | {"c2": "6", "c6": "6", "c7": "6 ", "c8": "foo", "C 1": "306"} - Sat Jan 17 00:00:00 1970 | {"c3": "00316"} | {"c2": "6", "c6": "6", "c7": "6 ", "c8": "foo", "C 1": "316"} | Sat Jan 17 00:00:00 1970 | {"c3": "00316"} | {"c2": "6", "c6": "6", "c7": "6 ", "c8": "foo", "C 1": "316"} - Tue Jan 27 00:00:00 1970 | {"c3": "00326"} | {"c2": "6", "c6": "6", "c7": "6 ", "c8": "foo", "C 1": "326"} | Tue Jan 27 00:00:00 1970 | {"c3": "00326"} | {"c2": "6", "c6": "6", "c7": "6 ", "c8": "foo", "C 1": "326"} - Fri Feb 06 00:00:00 1970 | {"c3": "00336"} | {"c2": "6", "c6": "6", "c7": "6 ", "c8": "foo", "C 1": "336"} | Fri Feb 06 00:00:00 1970 | {"c3": "00336"} | {"c2": "6", "c6": "6", "c7": "6 ", "c8": "foo", "C 1": "336"} - Mon Feb 16 00:00:00 1970 | {"c3": "00346"} | {"c2": "6", "c6": "6", "c7": "6 ", "c8": "foo", "C 1": "346"} | Mon Feb 16 00:00:00 1970 | {"c3": "00346"} | {"c2": "6", "c6": "6", "c7": "6 ", "c8": "foo", "C 1": "346"} - Thu Feb 26 00:00:00 1970 | {"c3": "00356"} | {"c2": "6", "c6": "6", "c7": "6 ", "c8": "foo", "C 1": "356"} | Thu Feb 26 00:00:00 1970 | {"c3": "00356"} | {"c2": "6", "c6": "6", "c7": "6 ", "c8": "foo", "C 1": "356"} - Sun Mar 08 00:00:00 1970 | {"c3": "00366"} | {"c2": "6", "c6": "6", "c7": "6 ", "c8": "foo", "C 1": "366"} | Sun Mar 08 00:00:00 1970 | {"c3": "00366"} | {"c2": "6", "c6": "6", "c7": "6 ", "c8": "foo", "C 1": "366"} - Wed Mar 18 00:00:00 1970 | {"c3": "00376"} | {"c2": "6", "c6": "6", "c7": "6 ", "c8": "foo", "C 1": "376"} | Wed Mar 18 00:00:00 1970 | {"c3": "00376"} | {"c2": "6", "c6": "6", "c7": "6 ", "c8": "foo", "C 1": "376"} - Sat Mar 28 00:00:00 1970 | {"c3": "00386"} | {"c2": "6", "c6": "6", "c7": "6 ", "c8": "foo", "C 1": "386"} | Sat Mar 28 00:00:00 1970 | {"c3": "00386"} | {"c2": "6", "c6": "6", "c7": "6 ", "c8": "foo", "C 1": "386"} - Tue Apr 07 00:00:00 1970 | {"c3": "00396"} | {"c2": "6", "c6": "6", "c7": "6 ", "c8": "foo", "C 1": "396"} | Tue Apr 07 00:00:00 1970 | {"c3": "00396"} | {"c2": "6", "c6": "6", "c7": "6 ", "c8": "foo", "C 1": "396"} - Wed Jan 07 00:00:00 1970 | {"c3": "00406"} | {"c2": "6", "c6": "6", "c7": "6 ", "c8": "foo", "C 1": "406"} | Wed Jan 07 00:00:00 1970 | {"c3": "00406"} | {"c2": "6", "c6": "6", "c7": "6 ", "c8": "foo", "C 1": "406"} - Sat Jan 17 00:00:00 1970 | {"c3": "00416"} | {"c2": "6", "c6": "6", "c7": "6 ", "c8": "foo", "C 1": "416"} | Sat Jan 17 00:00:00 1970 | {"c3": "00416"} | {"c2": "6", "c6": "6", "c7": "6 ", "c8": "foo", "C 1": "416"} - Tue Jan 27 00:00:00 1970 | {"c3": "00426"} | {"c2": "6", "c6": "6", "c7": "6 ", "c8": "foo", "C 1": "426"} | Tue Jan 27 00:00:00 1970 | {"c3": "00426"} | {"c2": "6", "c6": "6", "c7": "6 ", "c8": "foo", "C 1": "426"} - Fri Feb 06 00:00:00 1970 | {"c3": "00436"} | {"c2": "6", "c6": "6", "c7": "6 ", "c8": "foo", "C 1": "436"} | Fri Feb 06 00:00:00 1970 | {"c3": "00436"} | {"c2": "6", "c6": "6", "c7": "6 ", "c8": "foo", "C 1": "436"} - Mon Feb 16 00:00:00 1970 | {"c3": "00446"} | {"c2": "6", "c6": "6", "c7": "6 ", "c8": "foo", "C 1": "446"} | Mon Feb 16 00:00:00 1970 | {"c3": "00446"} | {"c2": "6", "c6": "6", "c7": "6 ", "c8": "foo", "C 1": "446"} - Thu Feb 26 00:00:00 1970 | {"c3": "00456"} | {"c2": "6", "c6": "6", "c7": "6 ", "c8": "foo", "C 1": "456"} | Thu Feb 26 00:00:00 1970 | {"c3": "00456"} | {"c2": "6", "c6": "6", "c7": "6 ", "c8": "foo", "C 1": "456"} - Sun Mar 08 00:00:00 1970 | {"c3": "00466"} | {"c2": "6", "c6": "6", "c7": "6 ", "c8": "foo", "C 1": "466"} | Sun Mar 08 00:00:00 1970 | {"c3": "00466"} | {"c2": "6", "c6": "6", "c7": "6 ", "c8": "foo", "C 1": "466"} - Wed Mar 18 00:00:00 1970 | {"c3": "00476"} | {"c2": "6", "c6": "6", "c7": "6 ", "c8": "foo", "C 1": "476"} | Wed Mar 18 00:00:00 1970 | {"c3": "00476"} | {"c2": "6", "c6": "6", "c7": "6 ", "c8": "foo", "C 1": "476"} - Sat Mar 28 00:00:00 1970 | {"c3": "00486"} | {"c2": "6", "c6": "6", "c7": "6 ", "c8": "foo", "C 1": "486"} | Sat Mar 28 00:00:00 1970 | {"c3": "00486"} | {"c2": "6", "c6": "6", "c7": "6 ", "c8": "foo", "C 1": "486"} - Tue Apr 07 00:00:00 1970 | {"c3": "00496"} | {"c2": "6", "c6": "6", "c7": "6 ", "c8": "foo", "C 1": "496"} | Tue Apr 07 00:00:00 1970 | {"c3": "00496"} | {"c2": "6", "c6": "6", "c7": "6 ", "c8": "foo", "C 1": "496"} - Wed Jan 07 00:00:00 1970 | {"c3": "00506"} | {"c2": "6", "c6": "6", "c7": "6 ", "c8": "foo", "C 1": "506"} | Wed Jan 07 00:00:00 1970 | {"c3": "00506"} | {"c2": "6", "c6": "6", "c7": "6 ", "c8": "foo", "C 1": "506"} - Sat Jan 17 00:00:00 1970 | {"c3": "00516"} | {"c2": "6", "c6": "6", "c7": "6 ", "c8": "foo", "C 1": "516"} | Sat Jan 17 00:00:00 1970 | {"c3": "00516"} | {"c2": "6", "c6": "6", "c7": "6 ", "c8": "foo", "C 1": "516"} - Tue Jan 27 00:00:00 1970 | {"c3": "00526"} | {"c2": "6", "c6": "6", "c7": "6 ", "c8": "foo", "C 1": "526"} | Tue Jan 27 00:00:00 1970 | {"c3": "00526"} | {"c2": "6", "c6": "6", "c7": "6 ", "c8": "foo", "C 1": "526"} - Fri Feb 06 00:00:00 1970 | {"c3": "00536"} | {"c2": "6", "c6": "6", "c7": "6 ", "c8": "foo", "C 1": "536"} | Fri Feb 06 00:00:00 1970 | {"c3": "00536"} | {"c2": "6", "c6": "6", "c7": "6 ", "c8": "foo", "C 1": "536"} - Mon Feb 16 00:00:00 1970 | {"c3": "00546"} | {"c2": "6", "c6": "6", "c7": "6 ", "c8": "foo", "C 1": "546"} | Mon Feb 16 00:00:00 1970 | {"c3": "00546"} | {"c2": "6", "c6": "6", "c7": "6 ", "c8": "foo", "C 1": "546"} - Thu Feb 26 00:00:00 1970 | {"c3": "00556"} | {"c2": "6", "c6": "6", "c7": "6 ", "c8": "foo", "C 1": "556"} | Thu Feb 26 00:00:00 1970 | {"c3": "00556"} | {"c2": "6", "c6": "6", "c7": "6 ", "c8": "foo", "C 1": "556"} - Sun Mar 08 00:00:00 1970 | {"c3": "00566"} | {"c2": "6", "c6": "6", "c7": "6 ", "c8": "foo", "C 1": "566"} | Sun Mar 08 00:00:00 1970 | {"c3": "00566"} | {"c2": "6", "c6": "6", "c7": "6 ", "c8": "foo", "C 1": "566"} - Wed Mar 18 00:00:00 1970 | {"c3": "00576"} | {"c2": "6", "c6": "6", "c7": "6 ", "c8": "foo", "C 1": "576"} | Wed Mar 18 00:00:00 1970 | {"c3": "00576"} | {"c2": "6", "c6": "6", "c7": "6 ", "c8": "foo", "C 1": "576"} - Sat Mar 28 00:00:00 1970 | {"c3": "00586"} | {"c2": "6", "c6": "6", "c7": "6 ", "c8": "foo", "C 1": "586"} | Sat Mar 28 00:00:00 1970 | {"c3": "00586"} | {"c2": "6", "c6": "6", "c7": "6 ", "c8": "foo", "C 1": "586"} - Tue Apr 07 00:00:00 1970 | {"c3": "00596"} | {"c2": "6", "c6": "6", "c7": "6 ", "c8": "foo", "C 1": "596"} | Tue Apr 07 00:00:00 1970 | {"c3": "00596"} | {"c2": "6", "c6": "6", "c7": "6 ", "c8": "foo", "C 1": "596"} - Wed Jan 07 00:00:00 1970 | {"c3": "00606"} | {"c2": "6", "c6": "6", "c7": "6 ", "c8": "foo", "C 1": "606"} | Wed Jan 07 00:00:00 1970 | {"c3": "00606"} | {"c2": "6", "c6": "6", "c7": "6 ", "c8": "foo", "C 1": "606"} - Sat Jan 17 00:00:00 1970 | {"c3": "00616"} | {"c2": "6", "c6": "6", "c7": "6 ", "c8": "foo", "C 1": "616"} | Sat Jan 17 00:00:00 1970 | {"c3": "00616"} | {"c2": "6", "c6": "6", "c7": "6 ", "c8": "foo", "C 1": "616"} - Tue Jan 27 00:00:00 1970 | {"c3": "00626"} | {"c2": "6", "c6": "6", "c7": "6 ", "c8": "foo", "C 1": "626"} | Tue Jan 27 00:00:00 1970 | {"c3": "00626"} | {"c2": "6", "c6": "6", "c7": "6 ", "c8": "foo", "C 1": "626"} - Fri Feb 06 00:00:00 1970 | {"c3": "00636"} | {"c2": "6", "c6": "6", "c7": "6 ", "c8": "foo", "C 1": "636"} | Fri Feb 06 00:00:00 1970 | {"c3": "00636"} | {"c2": "6", "c6": "6", "c7": "6 ", "c8": "foo", "C 1": "636"} - Mon Feb 16 00:00:00 1970 | {"c3": "00646"} | {"c2": "6", "c6": "6", "c7": "6 ", "c8": "foo", "C 1": "646"} | Mon Feb 16 00:00:00 1970 | {"c3": "00646"} | {"c2": "6", "c6": "6", "c7": "6 ", "c8": "foo", "C 1": "646"} - Thu Feb 26 00:00:00 1970 | {"c3": "00656"} | {"c2": "6", "c6": "6", "c7": "6 ", "c8": "foo", "C 1": "656"} | Thu Feb 26 00:00:00 1970 | {"c3": "00656"} | {"c2": "6", "c6": "6", "c7": "6 ", "c8": "foo", "C 1": "656"} - Sun Mar 08 00:00:00 1970 | {"c3": "00666"} | {"c2": "6", "c6": "6", "c7": "6 ", "c8": "foo", "C 1": "666"} | Sun Mar 08 00:00:00 1970 | {"c3": "00666"} | {"c2": "6", "c6": "6", "c7": "6 ", "c8": "foo", "C 1": "666"} - Wed Mar 18 00:00:00 1970 | {"c3": "00676"} | {"c2": "6", "c6": "6", "c7": "6 ", "c8": "foo", "C 1": "676"} | Wed Mar 18 00:00:00 1970 | {"c3": "00676"} | {"c2": "6", "c6": "6", "c7": "6 ", "c8": "foo", "C 1": "676"} - Sat Mar 28 00:00:00 1970 | {"c3": "00686"} | {"c2": "6", "c6": "6", "c7": "6 ", "c8": "foo", "C 1": "686"} | Sat Mar 28 00:00:00 1970 | {"c3": "00686"} | {"c2": "6", "c6": "6", "c7": "6 ", "c8": "foo", "C 1": "686"} - Tue Apr 07 00:00:00 1970 | {"c3": "00696"} | {"c2": "6", "c6": "6", "c7": "6 ", "c8": "foo", "C 1": "696"} | Tue Apr 07 00:00:00 1970 | {"c3": "00696"} | {"c2": "6", "c6": "6", "c7": "6 ", "c8": "foo", "C 1": "696"} - Wed Jan 07 00:00:00 1970 | {"c3": "00706"} | {"c2": "6", "c6": "6", "c7": "6 ", "c8": "foo", "C 1": "706"} | Wed Jan 07 00:00:00 1970 | {"c3": "00706"} | {"c2": "6", "c6": "6", "c7": "6 ", "c8": "foo", "C 1": "706"} - Sat Jan 17 00:00:00 1970 | {"c3": "00716"} | {"c2": "6", "c6": "6", "c7": "6 ", "c8": "foo", "C 1": "716"} | Sat Jan 17 00:00:00 1970 | {"c3": "00716"} | {"c2": "6", "c6": "6", "c7": "6 ", "c8": "foo", "C 1": "716"} - Tue Jan 27 00:00:00 1970 | {"c3": "00726"} | {"c2": "6", "c6": "6", "c7": "6 ", "c8": "foo", "C 1": "726"} | Tue Jan 27 00:00:00 1970 | {"c3": "00726"} | {"c2": "6", "c6": "6", "c7": "6 ", "c8": "foo", "C 1": "726"} - Fri Feb 06 00:00:00 1970 | {"c3": "00736"} | {"c2": "6", "c6": "6", "c7": "6 ", "c8": "foo", "C 1": "736"} | Fri Feb 06 00:00:00 1970 | {"c3": "00736"} | {"c2": "6", "c6": "6", "c7": "6 ", "c8": "foo", "C 1": "736"} - Mon Feb 16 00:00:00 1970 | {"c3": "00746"} | {"c2": "6", "c6": "6", "c7": "6 ", "c8": "foo", "C 1": "746"} | Mon Feb 16 00:00:00 1970 | {"c3": "00746"} | {"c2": "6", "c6": "6", "c7": "6 ", "c8": "foo", "C 1": "746"} - Thu Feb 26 00:00:00 1970 | {"c3": "00756"} | {"c2": "6", "c6": "6", "c7": "6 ", "c8": "foo", "C 1": "756"} | Thu Feb 26 00:00:00 1970 | {"c3": "00756"} | {"c2": "6", "c6": "6", "c7": "6 ", "c8": "foo", "C 1": "756"} - Sun Mar 08 00:00:00 1970 | {"c3": "00766"} | {"c2": "6", "c6": "6", "c7": "6 ", "c8": "foo", "C 1": "766"} | Sun Mar 08 00:00:00 1970 | {"c3": "00766"} | {"c2": "6", "c6": "6", "c7": "6 ", "c8": "foo", "C 1": "766"} - Wed Mar 18 00:00:00 1970 | {"c3": "00776"} | {"c2": "6", "c6": "6", "c7": "6 ", "c8": "foo", "C 1": "776"} | Wed Mar 18 00:00:00 1970 | {"c3": "00776"} | {"c2": "6", "c6": "6", "c7": "6 ", "c8": "foo", "C 1": "776"} - Sat Mar 28 00:00:00 1970 | {"c3": "00786"} | {"c2": "6", "c6": "6", "c7": "6 ", "c8": "foo", "C 1": "786"} | Sat Mar 28 00:00:00 1970 | {"c3": "00786"} | {"c2": "6", "c6": "6", "c7": "6 ", "c8": "foo", "C 1": "786"} - Tue Apr 07 00:00:00 1970 | {"c3": "00796"} | {"c2": "6", "c6": "6", "c7": "6 ", "c8": "foo", "C 1": "796"} | Tue Apr 07 00:00:00 1970 | {"c3": "00796"} | {"c2": "6", "c6": "6", "c7": "6 ", "c8": "foo", "C 1": "796"} - Wed Jan 07 00:00:00 1970 | {"c3": "00806"} | {"c2": "6", "c6": "6", "c7": "6 ", "c8": "foo", "C 1": "806"} | Wed Jan 07 00:00:00 1970 | {"c3": "00806"} | {"c2": "6", "c6": "6", "c7": "6 ", "c8": "foo", "C 1": "806"} - Sat Jan 17 00:00:00 1970 | {"c3": "00816"} | {"c2": "6", "c6": "6", "c7": "6 ", "c8": "foo", "C 1": "816"} | Sat Jan 17 00:00:00 1970 | {"c3": "00816"} | {"c2": "6", "c6": "6", "c7": "6 ", "c8": "foo", "C 1": "816"} - Tue Jan 27 00:00:00 1970 | {"c3": "00826"} | {"c2": "6", "c6": "6", "c7": "6 ", "c8": "foo", "C 1": "826"} | Tue Jan 27 00:00:00 1970 | {"c3": "00826"} | {"c2": "6", "c6": "6", "c7": "6 ", "c8": "foo", "C 1": "826"} - Fri Feb 06 00:00:00 1970 | {"c3": "00836"} | {"c2": "6", "c6": "6", "c7": "6 ", "c8": "foo", "C 1": "836"} | Fri Feb 06 00:00:00 1970 | {"c3": "00836"} | {"c2": "6", "c6": "6", "c7": "6 ", "c8": "foo", "C 1": "836"} - Mon Feb 16 00:00:00 1970 | {"c3": "00846"} | {"c2": "6", "c6": "6", "c7": "6 ", "c8": "foo", "C 1": "846"} | Mon Feb 16 00:00:00 1970 | {"c3": "00846"} | {"c2": "6", "c6": "6", "c7": "6 ", "c8": "foo", "C 1": "846"} - Thu Feb 26 00:00:00 1970 | {"c3": "00856"} | {"c2": "6", "c6": "6", "c7": "6 ", "c8": "foo", "C 1": "856"} | Thu Feb 26 00:00:00 1970 | {"c3": "00856"} | {"c2": "6", "c6": "6", "c7": "6 ", "c8": "foo", "C 1": "856"} - Sun Mar 08 00:00:00 1970 | {"c3": "00866"} | {"c2": "6", "c6": "6", "c7": "6 ", "c8": "foo", "C 1": "866"} | Sun Mar 08 00:00:00 1970 | {"c3": "00866"} | {"c2": "6", "c6": "6", "c7": "6 ", "c8": "foo", "C 1": "866"} - Wed Mar 18 00:00:00 1970 | {"c3": "00876"} | {"c2": "6", "c6": "6", "c7": "6 ", "c8": "foo", "C 1": "876"} | Wed Mar 18 00:00:00 1970 | {"c3": "00876"} | {"c2": "6", "c6": "6", "c7": "6 ", "c8": "foo", "C 1": "876"} - Sat Mar 28 00:00:00 1970 | {"c3": "00886"} | {"c2": "6", "c6": "6", "c7": "6 ", "c8": "foo", "C 1": "886"} | Sat Mar 28 00:00:00 1970 | {"c3": "00886"} | {"c2": "6", "c6": "6", "c7": "6 ", "c8": "foo", "C 1": "886"} - Tue Apr 07 00:00:00 1970 | {"c3": "00896"} | {"c2": "6", "c6": "6", "c7": "6 ", "c8": "foo", "C 1": "896"} | Tue Apr 07 00:00:00 1970 | {"c3": "00896"} | {"c2": "6", "c6": "6", "c7": "6 ", "c8": "foo", "C 1": "896"} - Wed Jan 07 00:00:00 1970 | {"c3": "00906"} | {"c2": "6", "c6": "6", "c7": "6 ", "c8": "foo", "C 1": "906"} | Wed Jan 07 00:00:00 1970 | {"c3": "00906"} | {"c2": "6", "c6": "6", "c7": "6 ", "c8": "foo", "C 1": "906"} - Sat Jan 17 00:00:00 1970 | {"c3": "00916"} | {"c2": "6", "c6": "6", "c7": "6 ", "c8": "foo", "C 1": "916"} | Sat Jan 17 00:00:00 1970 | {"c3": "00916"} | {"c2": "6", "c6": "6", "c7": "6 ", "c8": "foo", "C 1": "916"} - Tue Jan 27 00:00:00 1970 | {"c3": "00926"} | {"c2": "6", "c6": "6", "c7": "6 ", "c8": "foo", "C 1": "926"} | Tue Jan 27 00:00:00 1970 | {"c3": "00926"} | {"c2": "6", "c6": "6", "c7": "6 ", "c8": "foo", "C 1": "926"} - Fri Feb 06 00:00:00 1970 | {"c3": "00936"} | {"c2": "6", "c6": "6", "c7": "6 ", "c8": "foo", "C 1": "936"} | Fri Feb 06 00:00:00 1970 | {"c3": "00936"} | {"c2": "6", "c6": "6", "c7": "6 ", "c8": "foo", "C 1": "936"} - Mon Feb 16 00:00:00 1970 | {"c3": "00946"} | {"c2": "6", "c6": "6", "c7": "6 ", "c8": "foo", "C 1": "946"} | Mon Feb 16 00:00:00 1970 | {"c3": "00946"} | {"c2": "6", "c6": "6", "c7": "6 ", "c8": "foo", "C 1": "946"} - Thu Feb 26 00:00:00 1970 | {"c3": "00956"} | {"c2": "6", "c6": "6", "c7": "6 ", "c8": "foo", "C 1": "956"} | Thu Feb 26 00:00:00 1970 | {"c3": "00956"} | {"c2": "6", "c6": "6", "c7": "6 ", "c8": "foo", "C 1": "956"} - Sun Mar 08 00:00:00 1970 | {"c3": "00966"} | {"c2": "6", "c6": "6", "c7": "6 ", "c8": "foo", "C 1": "966"} | Sun Mar 08 00:00:00 1970 | {"c3": "00966"} | {"c2": "6", "c6": "6", "c7": "6 ", "c8": "foo", "C 1": "966"} - Wed Mar 18 00:00:00 1970 | {"c3": "00976"} | {"c2": "6", "c6": "6", "c7": "6 ", "c8": "foo", "C 1": "976"} | Wed Mar 18 00:00:00 1970 | {"c3": "00976"} | {"c2": "6", "c6": "6", "c7": "6 ", "c8": "foo", "C 1": "976"} - Sat Mar 28 00:00:00 1970 | {"c3": "00986"} | {"c2": "6", "c6": "6", "c7": "6 ", "c8": "foo", "C 1": "986"} | Sat Mar 28 00:00:00 1970 | {"c3": "00986"} | {"c2": "6", "c6": "6", "c7": "6 ", "c8": "foo", "C 1": "986"} - Tue Apr 07 00:00:00 1970 | {"c3": "00996"} | {"c2": "6", "c6": "6", "c7": "6 ", "c8": "foo", "C 1": "996"} | Tue Apr 07 00:00:00 1970 | {"c3": "00996"} | {"c2": "6", "c6": "6", "c7": "6 ", "c8": "foo", "C 1": "996"} + time | tags | fields | time | tags | fields +------------------------------+-----------------+-----------------------------------------------------------------------+------------------------------+-----------------+----------------------------------------------------------------------- + Wed Jan 07 00:00:00 1970 PST | {"c3": "00006"} | {"c2": "6", "c6": "6", "c7": "6 ", "c8": "foo", "C 1": "6"} | Wed Jan 07 00:00:00 1970 PST | {"c3": "00006"} | {"c2": "6", "c6": "6", "c7": "6 ", "c8": "foo", "C 1": "6"} + Sat Jan 17 00:00:00 1970 PST | {"c3": "00016"} | {"c2": "6", "c6": "6", "c7": "6 ", "c8": "foo", "C 1": "16"} | Sat Jan 17 00:00:00 1970 PST | {"c3": "00016"} | {"c2": "6", "c6": "6", "c7": "6 ", "c8": "foo", "C 1": "16"} + Tue Jan 27 00:00:00 1970 PST | {"c3": "00026"} | {"c2": "6", "c6": "6", "c7": "6 ", "c8": "foo", "C 1": "26"} | Tue Jan 27 00:00:00 1970 PST | {"c3": "00026"} | {"c2": "6", "c6": "6", "c7": "6 ", "c8": "foo", "C 1": "26"} + Fri Feb 06 00:00:00 1970 PST | {"c3": "00036"} | {"c2": "6", "c6": "6", "c7": "6 ", "c8": "foo", "C 1": "36"} | Fri Feb 06 00:00:00 1970 PST | {"c3": "00036"} | {"c2": "6", "c6": "6", "c7": "6 ", "c8": "foo", "C 1": "36"} + Mon Feb 16 00:00:00 1970 PST | {"c3": "00046"} | {"c2": "6", "c6": "6", "c7": "6 ", "c8": "foo", "C 1": "46"} | Mon Feb 16 00:00:00 1970 PST | {"c3": "00046"} | {"c2": "6", "c6": "6", "c7": "6 ", "c8": "foo", "C 1": "46"} + Thu Feb 26 00:00:00 1970 PST | {"c3": "00056"} | {"c2": "6", "c6": "6", "c7": "6 ", "c8": "foo", "C 1": "56"} | Thu Feb 26 00:00:00 1970 PST | {"c3": "00056"} | {"c2": "6", "c6": "6", "c7": "6 ", "c8": "foo", "C 1": "56"} + Sun Mar 08 00:00:00 1970 PST | {"c3": "00066"} | {"c2": "6", "c6": "6", "c7": "6 ", "c8": "foo", "C 1": "66"} | Sun Mar 08 00:00:00 1970 PST | {"c3": "00066"} | {"c2": "6", "c6": "6", "c7": "6 ", "c8": "foo", "C 1": "66"} + Wed Mar 18 00:00:00 1970 PST | {"c3": "00076"} | {"c2": "6", "c6": "6", "c7": "6 ", "c8": "foo", "C 1": "76"} | Wed Mar 18 00:00:00 1970 PST | {"c3": "00076"} | {"c2": "6", "c6": "6", "c7": "6 ", "c8": "foo", "C 1": "76"} + Sat Mar 28 00:00:00 1970 PST | {"c3": "00086"} | {"c2": "6", "c6": "6", "c7": "6 ", "c8": "foo", "C 1": "86"} | Sat Mar 28 00:00:00 1970 PST | {"c3": "00086"} | {"c2": "6", "c6": "6", "c7": "6 ", "c8": "foo", "C 1": "86"} + Tue Apr 07 00:00:00 1970 PST | {"c3": "00096"} | {"c2": "6", "c6": "6", "c7": "6 ", "c8": "foo", "C 1": "96"} | Tue Apr 07 00:00:00 1970 PST | {"c3": "00096"} | {"c2": "6", "c6": "6", "c7": "6 ", "c8": "foo", "C 1": "96"} + Wed Jan 07 00:00:00 1970 PST | {"c3": "00106"} | {"c2": "6", "c6": "6", "c7": "6 ", "c8": "foo", "C 1": "106"} | Wed Jan 07 00:00:00 1970 PST | {"c3": "00106"} | {"c2": "6", "c6": "6", "c7": "6 ", "c8": "foo", "C 1": "106"} + Sat Jan 17 00:00:00 1970 PST | {"c3": "00116"} | {"c2": "6", "c6": "6", "c7": "6 ", "c8": "foo", "C 1": "116"} | Sat Jan 17 00:00:00 1970 PST | {"c3": "00116"} | {"c2": "6", "c6": "6", "c7": "6 ", "c8": "foo", "C 1": "116"} + Tue Jan 27 00:00:00 1970 PST | {"c3": "00126"} | {"c2": "6", "c6": "6", "c7": "6 ", "c8": "foo", "C 1": "126"} | Tue Jan 27 00:00:00 1970 PST | {"c3": "00126"} | {"c2": "6", "c6": "6", "c7": "6 ", "c8": "foo", "C 1": "126"} + Fri Feb 06 00:00:00 1970 PST | {"c3": "00136"} | {"c2": "6", "c6": "6", "c7": "6 ", "c8": "foo", "C 1": "136"} | Fri Feb 06 00:00:00 1970 PST | {"c3": "00136"} | {"c2": "6", "c6": "6", "c7": "6 ", "c8": "foo", "C 1": "136"} + Mon Feb 16 00:00:00 1970 PST | {"c3": "00146"} | {"c2": "6", "c6": "6", "c7": "6 ", "c8": "foo", "C 1": "146"} | Mon Feb 16 00:00:00 1970 PST | {"c3": "00146"} | {"c2": "6", "c6": "6", "c7": "6 ", "c8": "foo", "C 1": "146"} + Thu Feb 26 00:00:00 1970 PST | {"c3": "00156"} | {"c2": "6", "c6": "6", "c7": "6 ", "c8": "foo", "C 1": "156"} | Thu Feb 26 00:00:00 1970 PST | {"c3": "00156"} | {"c2": "6", "c6": "6", "c7": "6 ", "c8": "foo", "C 1": "156"} + Sun Mar 08 00:00:00 1970 PST | {"c3": "00166"} | {"c2": "6", "c6": "6", "c7": "6 ", "c8": "foo", "C 1": "166"} | Sun Mar 08 00:00:00 1970 PST | {"c3": "00166"} | {"c2": "6", "c6": "6", "c7": "6 ", "c8": "foo", "C 1": "166"} + Wed Mar 18 00:00:00 1970 PST | {"c3": "00176"} | {"c2": "6", "c6": "6", "c7": "6 ", "c8": "foo", "C 1": "176"} | Wed Mar 18 00:00:00 1970 PST | {"c3": "00176"} | {"c2": "6", "c6": "6", "c7": "6 ", "c8": "foo", "C 1": "176"} + Sat Mar 28 00:00:00 1970 PST | {"c3": "00186"} | {"c2": "6", "c6": "6", "c7": "6 ", "c8": "foo", "C 1": "186"} | Sat Mar 28 00:00:00 1970 PST | {"c3": "00186"} | {"c2": "6", "c6": "6", "c7": "6 ", "c8": "foo", "C 1": "186"} + Tue Apr 07 00:00:00 1970 PST | {"c3": "00196"} | {"c2": "6", "c6": "6", "c7": "6 ", "c8": "foo", "C 1": "196"} | Tue Apr 07 00:00:00 1970 PST | {"c3": "00196"} | {"c2": "6", "c6": "6", "c7": "6 ", "c8": "foo", "C 1": "196"} + Wed Jan 07 00:00:00 1970 PST | {"c3": "00206"} | {"c2": "6", "c6": "6", "c7": "6 ", "c8": "foo", "C 1": "206"} | Wed Jan 07 00:00:00 1970 PST | {"c3": "00206"} | {"c2": "6", "c6": "6", "c7": "6 ", "c8": "foo", "C 1": "206"} + Sat Jan 17 00:00:00 1970 PST | {"c3": "00216"} | {"c2": "6", "c6": "6", "c7": "6 ", "c8": "foo", "C 1": "216"} | Sat Jan 17 00:00:00 1970 PST | {"c3": "00216"} | {"c2": "6", "c6": "6", "c7": "6 ", "c8": "foo", "C 1": "216"} + Tue Jan 27 00:00:00 1970 PST | {"c3": "00226"} | {"c2": "6", "c6": "6", "c7": "6 ", "c8": "foo", "C 1": "226"} | Tue Jan 27 00:00:00 1970 PST | {"c3": "00226"} | {"c2": "6", "c6": "6", "c7": "6 ", "c8": "foo", "C 1": "226"} + Fri Feb 06 00:00:00 1970 PST | {"c3": "00236"} | {"c2": "6", "c6": "6", "c7": "6 ", "c8": "foo", "C 1": "236"} | Fri Feb 06 00:00:00 1970 PST | {"c3": "00236"} | {"c2": "6", "c6": "6", "c7": "6 ", "c8": "foo", "C 1": "236"} + Mon Feb 16 00:00:00 1970 PST | {"c3": "00246"} | {"c2": "6", "c6": "6", "c7": "6 ", "c8": "foo", "C 1": "246"} | Mon Feb 16 00:00:00 1970 PST | {"c3": "00246"} | {"c2": "6", "c6": "6", "c7": "6 ", "c8": "foo", "C 1": "246"} + Thu Feb 26 00:00:00 1970 PST | {"c3": "00256"} | {"c2": "6", "c6": "6", "c7": "6 ", "c8": "foo", "C 1": "256"} | Thu Feb 26 00:00:00 1970 PST | {"c3": "00256"} | {"c2": "6", "c6": "6", "c7": "6 ", "c8": "foo", "C 1": "256"} + Sun Mar 08 00:00:00 1970 PST | {"c3": "00266"} | {"c2": "6", "c6": "6", "c7": "6 ", "c8": "foo", "C 1": "266"} | Sun Mar 08 00:00:00 1970 PST | {"c3": "00266"} | {"c2": "6", "c6": "6", "c7": "6 ", "c8": "foo", "C 1": "266"} + Wed Mar 18 00:00:00 1970 PST | {"c3": "00276"} | {"c2": "6", "c6": "6", "c7": "6 ", "c8": "foo", "C 1": "276"} | Wed Mar 18 00:00:00 1970 PST | {"c3": "00276"} | {"c2": "6", "c6": "6", "c7": "6 ", "c8": "foo", "C 1": "276"} + Sat Mar 28 00:00:00 1970 PST | {"c3": "00286"} | {"c2": "6", "c6": "6", "c7": "6 ", "c8": "foo", "C 1": "286"} | Sat Mar 28 00:00:00 1970 PST | {"c3": "00286"} | {"c2": "6", "c6": "6", "c7": "6 ", "c8": "foo", "C 1": "286"} + Tue Apr 07 00:00:00 1970 PST | {"c3": "00296"} | {"c2": "6", "c6": "6", "c7": "6 ", "c8": "foo", "C 1": "296"} | Tue Apr 07 00:00:00 1970 PST | {"c3": "00296"} | {"c2": "6", "c6": "6", "c7": "6 ", "c8": "foo", "C 1": "296"} + Wed Jan 07 00:00:00 1970 PST | {"c3": "00306"} | {"c2": "6", "c6": "6", "c7": "6 ", "c8": "foo", "C 1": "306"} | Wed Jan 07 00:00:00 1970 PST | {"c3": "00306"} | {"c2": "6", "c6": "6", "c7": "6 ", "c8": "foo", "C 1": "306"} + Sat Jan 17 00:00:00 1970 PST | {"c3": "00316"} | {"c2": "6", "c6": "6", "c7": "6 ", "c8": "foo", "C 1": "316"} | Sat Jan 17 00:00:00 1970 PST | {"c3": "00316"} | {"c2": "6", "c6": "6", "c7": "6 ", "c8": "foo", "C 1": "316"} + Tue Jan 27 00:00:00 1970 PST | {"c3": "00326"} | {"c2": "6", "c6": "6", "c7": "6 ", "c8": "foo", "C 1": "326"} | Tue Jan 27 00:00:00 1970 PST | {"c3": "00326"} | {"c2": "6", "c6": "6", "c7": "6 ", "c8": "foo", "C 1": "326"} + Fri Feb 06 00:00:00 1970 PST | {"c3": "00336"} | {"c2": "6", "c6": "6", "c7": "6 ", "c8": "foo", "C 1": "336"} | Fri Feb 06 00:00:00 1970 PST | {"c3": "00336"} | {"c2": "6", "c6": "6", "c7": "6 ", "c8": "foo", "C 1": "336"} + Mon Feb 16 00:00:00 1970 PST | {"c3": "00346"} | {"c2": "6", "c6": "6", "c7": "6 ", "c8": "foo", "C 1": "346"} | Mon Feb 16 00:00:00 1970 PST | {"c3": "00346"} | {"c2": "6", "c6": "6", "c7": "6 ", "c8": "foo", "C 1": "346"} + Thu Feb 26 00:00:00 1970 PST | {"c3": "00356"} | {"c2": "6", "c6": "6", "c7": "6 ", "c8": "foo", "C 1": "356"} | Thu Feb 26 00:00:00 1970 PST | {"c3": "00356"} | {"c2": "6", "c6": "6", "c7": "6 ", "c8": "foo", "C 1": "356"} + Sun Mar 08 00:00:00 1970 PST | {"c3": "00366"} | {"c2": "6", "c6": "6", "c7": "6 ", "c8": "foo", "C 1": "366"} | Sun Mar 08 00:00:00 1970 PST | {"c3": "00366"} | {"c2": "6", "c6": "6", "c7": "6 ", "c8": "foo", "C 1": "366"} + Wed Mar 18 00:00:00 1970 PST | {"c3": "00376"} | {"c2": "6", "c6": "6", "c7": "6 ", "c8": "foo", "C 1": "376"} | Wed Mar 18 00:00:00 1970 PST | {"c3": "00376"} | {"c2": "6", "c6": "6", "c7": "6 ", "c8": "foo", "C 1": "376"} + Sat Mar 28 00:00:00 1970 PST | {"c3": "00386"} | {"c2": "6", "c6": "6", "c7": "6 ", "c8": "foo", "C 1": "386"} | Sat Mar 28 00:00:00 1970 PST | {"c3": "00386"} | {"c2": "6", "c6": "6", "c7": "6 ", "c8": "foo", "C 1": "386"} + Tue Apr 07 00:00:00 1970 PST | {"c3": "00396"} | {"c2": "6", "c6": "6", "c7": "6 ", "c8": "foo", "C 1": "396"} | Tue Apr 07 00:00:00 1970 PST | {"c3": "00396"} | {"c2": "6", "c6": "6", "c7": "6 ", "c8": "foo", "C 1": "396"} + Wed Jan 07 00:00:00 1970 PST | {"c3": "00406"} | {"c2": "6", "c6": "6", "c7": "6 ", "c8": "foo", "C 1": "406"} | Wed Jan 07 00:00:00 1970 PST | {"c3": "00406"} | {"c2": "6", "c6": "6", "c7": "6 ", "c8": "foo", "C 1": "406"} + Sat Jan 17 00:00:00 1970 PST | {"c3": "00416"} | {"c2": "6", "c6": "6", "c7": "6 ", "c8": "foo", "C 1": "416"} | Sat Jan 17 00:00:00 1970 PST | {"c3": "00416"} | {"c2": "6", "c6": "6", "c7": "6 ", "c8": "foo", "C 1": "416"} + Tue Jan 27 00:00:00 1970 PST | {"c3": "00426"} | {"c2": "6", "c6": "6", "c7": "6 ", "c8": "foo", "C 1": "426"} | Tue Jan 27 00:00:00 1970 PST | {"c3": "00426"} | {"c2": "6", "c6": "6", "c7": "6 ", "c8": "foo", "C 1": "426"} + Fri Feb 06 00:00:00 1970 PST | {"c3": "00436"} | {"c2": "6", "c6": "6", "c7": "6 ", "c8": "foo", "C 1": "436"} | Fri Feb 06 00:00:00 1970 PST | {"c3": "00436"} | {"c2": "6", "c6": "6", "c7": "6 ", "c8": "foo", "C 1": "436"} + Mon Feb 16 00:00:00 1970 PST | {"c3": "00446"} | {"c2": "6", "c6": "6", "c7": "6 ", "c8": "foo", "C 1": "446"} | Mon Feb 16 00:00:00 1970 PST | {"c3": "00446"} | {"c2": "6", "c6": "6", "c7": "6 ", "c8": "foo", "C 1": "446"} + Thu Feb 26 00:00:00 1970 PST | {"c3": "00456"} | {"c2": "6", "c6": "6", "c7": "6 ", "c8": "foo", "C 1": "456"} | Thu Feb 26 00:00:00 1970 PST | {"c3": "00456"} | {"c2": "6", "c6": "6", "c7": "6 ", "c8": "foo", "C 1": "456"} + Sun Mar 08 00:00:00 1970 PST | {"c3": "00466"} | {"c2": "6", "c6": "6", "c7": "6 ", "c8": "foo", "C 1": "466"} | Sun Mar 08 00:00:00 1970 PST | {"c3": "00466"} | {"c2": "6", "c6": "6", "c7": "6 ", "c8": "foo", "C 1": "466"} + Wed Mar 18 00:00:00 1970 PST | {"c3": "00476"} | {"c2": "6", "c6": "6", "c7": "6 ", "c8": "foo", "C 1": "476"} | Wed Mar 18 00:00:00 1970 PST | {"c3": "00476"} | {"c2": "6", "c6": "6", "c7": "6 ", "c8": "foo", "C 1": "476"} + Sat Mar 28 00:00:00 1970 PST | {"c3": "00486"} | {"c2": "6", "c6": "6", "c7": "6 ", "c8": "foo", "C 1": "486"} | Sat Mar 28 00:00:00 1970 PST | {"c3": "00486"} | {"c2": "6", "c6": "6", "c7": "6 ", "c8": "foo", "C 1": "486"} + Tue Apr 07 00:00:00 1970 PST | {"c3": "00496"} | {"c2": "6", "c6": "6", "c7": "6 ", "c8": "foo", "C 1": "496"} | Tue Apr 07 00:00:00 1970 PST | {"c3": "00496"} | {"c2": "6", "c6": "6", "c7": "6 ", "c8": "foo", "C 1": "496"} + Wed Jan 07 00:00:00 1970 PST | {"c3": "00506"} | {"c2": "6", "c6": "6", "c7": "6 ", "c8": "foo", "C 1": "506"} | Wed Jan 07 00:00:00 1970 PST | {"c3": "00506"} | {"c2": "6", "c6": "6", "c7": "6 ", "c8": "foo", "C 1": "506"} + Sat Jan 17 00:00:00 1970 PST | {"c3": "00516"} | {"c2": "6", "c6": "6", "c7": "6 ", "c8": "foo", "C 1": "516"} | Sat Jan 17 00:00:00 1970 PST | {"c3": "00516"} | {"c2": "6", "c6": "6", "c7": "6 ", "c8": "foo", "C 1": "516"} + Tue Jan 27 00:00:00 1970 PST | {"c3": "00526"} | {"c2": "6", "c6": "6", "c7": "6 ", "c8": "foo", "C 1": "526"} | Tue Jan 27 00:00:00 1970 PST | {"c3": "00526"} | {"c2": "6", "c6": "6", "c7": "6 ", "c8": "foo", "C 1": "526"} + Fri Feb 06 00:00:00 1970 PST | {"c3": "00536"} | {"c2": "6", "c6": "6", "c7": "6 ", "c8": "foo", "C 1": "536"} | Fri Feb 06 00:00:00 1970 PST | {"c3": "00536"} | {"c2": "6", "c6": "6", "c7": "6 ", "c8": "foo", "C 1": "536"} + Mon Feb 16 00:00:00 1970 PST | {"c3": "00546"} | {"c2": "6", "c6": "6", "c7": "6 ", "c8": "foo", "C 1": "546"} | Mon Feb 16 00:00:00 1970 PST | {"c3": "00546"} | {"c2": "6", "c6": "6", "c7": "6 ", "c8": "foo", "C 1": "546"} + Thu Feb 26 00:00:00 1970 PST | {"c3": "00556"} | {"c2": "6", "c6": "6", "c7": "6 ", "c8": "foo", "C 1": "556"} | Thu Feb 26 00:00:00 1970 PST | {"c3": "00556"} | {"c2": "6", "c6": "6", "c7": "6 ", "c8": "foo", "C 1": "556"} + Sun Mar 08 00:00:00 1970 PST | {"c3": "00566"} | {"c2": "6", "c6": "6", "c7": "6 ", "c8": "foo", "C 1": "566"} | Sun Mar 08 00:00:00 1970 PST | {"c3": "00566"} | {"c2": "6", "c6": "6", "c7": "6 ", "c8": "foo", "C 1": "566"} + Wed Mar 18 00:00:00 1970 PST | {"c3": "00576"} | {"c2": "6", "c6": "6", "c7": "6 ", "c8": "foo", "C 1": "576"} | Wed Mar 18 00:00:00 1970 PST | {"c3": "00576"} | {"c2": "6", "c6": "6", "c7": "6 ", "c8": "foo", "C 1": "576"} + Sat Mar 28 00:00:00 1970 PST | {"c3": "00586"} | {"c2": "6", "c6": "6", "c7": "6 ", "c8": "foo", "C 1": "586"} | Sat Mar 28 00:00:00 1970 PST | {"c3": "00586"} | {"c2": "6", "c6": "6", "c7": "6 ", "c8": "foo", "C 1": "586"} + Tue Apr 07 00:00:00 1970 PST | {"c3": "00596"} | {"c2": "6", "c6": "6", "c7": "6 ", "c8": "foo", "C 1": "596"} | Tue Apr 07 00:00:00 1970 PST | {"c3": "00596"} | {"c2": "6", "c6": "6", "c7": "6 ", "c8": "foo", "C 1": "596"} + Wed Jan 07 00:00:00 1970 PST | {"c3": "00606"} | {"c2": "6", "c6": "6", "c7": "6 ", "c8": "foo", "C 1": "606"} | Wed Jan 07 00:00:00 1970 PST | {"c3": "00606"} | {"c2": "6", "c6": "6", "c7": "6 ", "c8": "foo", "C 1": "606"} + Sat Jan 17 00:00:00 1970 PST | {"c3": "00616"} | {"c2": "6", "c6": "6", "c7": "6 ", "c8": "foo", "C 1": "616"} | Sat Jan 17 00:00:00 1970 PST | {"c3": "00616"} | {"c2": "6", "c6": "6", "c7": "6 ", "c8": "foo", "C 1": "616"} + Tue Jan 27 00:00:00 1970 PST | {"c3": "00626"} | {"c2": "6", "c6": "6", "c7": "6 ", "c8": "foo", "C 1": "626"} | Tue Jan 27 00:00:00 1970 PST | {"c3": "00626"} | {"c2": "6", "c6": "6", "c7": "6 ", "c8": "foo", "C 1": "626"} + Fri Feb 06 00:00:00 1970 PST | {"c3": "00636"} | {"c2": "6", "c6": "6", "c7": "6 ", "c8": "foo", "C 1": "636"} | Fri Feb 06 00:00:00 1970 PST | {"c3": "00636"} | {"c2": "6", "c6": "6", "c7": "6 ", "c8": "foo", "C 1": "636"} + Mon Feb 16 00:00:00 1970 PST | {"c3": "00646"} | {"c2": "6", "c6": "6", "c7": "6 ", "c8": "foo", "C 1": "646"} | Mon Feb 16 00:00:00 1970 PST | {"c3": "00646"} | {"c2": "6", "c6": "6", "c7": "6 ", "c8": "foo", "C 1": "646"} + Thu Feb 26 00:00:00 1970 PST | {"c3": "00656"} | {"c2": "6", "c6": "6", "c7": "6 ", "c8": "foo", "C 1": "656"} | Thu Feb 26 00:00:00 1970 PST | {"c3": "00656"} | {"c2": "6", "c6": "6", "c7": "6 ", "c8": "foo", "C 1": "656"} + Sun Mar 08 00:00:00 1970 PST | {"c3": "00666"} | {"c2": "6", "c6": "6", "c7": "6 ", "c8": "foo", "C 1": "666"} | Sun Mar 08 00:00:00 1970 PST | {"c3": "00666"} | {"c2": "6", "c6": "6", "c7": "6 ", "c8": "foo", "C 1": "666"} + Wed Mar 18 00:00:00 1970 PST | {"c3": "00676"} | {"c2": "6", "c6": "6", "c7": "6 ", "c8": "foo", "C 1": "676"} | Wed Mar 18 00:00:00 1970 PST | {"c3": "00676"} | {"c2": "6", "c6": "6", "c7": "6 ", "c8": "foo", "C 1": "676"} + Sat Mar 28 00:00:00 1970 PST | {"c3": "00686"} | {"c2": "6", "c6": "6", "c7": "6 ", "c8": "foo", "C 1": "686"} | Sat Mar 28 00:00:00 1970 PST | {"c3": "00686"} | {"c2": "6", "c6": "6", "c7": "6 ", "c8": "foo", "C 1": "686"} + Tue Apr 07 00:00:00 1970 PST | {"c3": "00696"} | {"c2": "6", "c6": "6", "c7": "6 ", "c8": "foo", "C 1": "696"} | Tue Apr 07 00:00:00 1970 PST | {"c3": "00696"} | {"c2": "6", "c6": "6", "c7": "6 ", "c8": "foo", "C 1": "696"} + Wed Jan 07 00:00:00 1970 PST | {"c3": "00706"} | {"c2": "6", "c6": "6", "c7": "6 ", "c8": "foo", "C 1": "706"} | Wed Jan 07 00:00:00 1970 PST | {"c3": "00706"} | {"c2": "6", "c6": "6", "c7": "6 ", "c8": "foo", "C 1": "706"} + Sat Jan 17 00:00:00 1970 PST | {"c3": "00716"} | {"c2": "6", "c6": "6", "c7": "6 ", "c8": "foo", "C 1": "716"} | Sat Jan 17 00:00:00 1970 PST | {"c3": "00716"} | {"c2": "6", "c6": "6", "c7": "6 ", "c8": "foo", "C 1": "716"} + Tue Jan 27 00:00:00 1970 PST | {"c3": "00726"} | {"c2": "6", "c6": "6", "c7": "6 ", "c8": "foo", "C 1": "726"} | Tue Jan 27 00:00:00 1970 PST | {"c3": "00726"} | {"c2": "6", "c6": "6", "c7": "6 ", "c8": "foo", "C 1": "726"} + Fri Feb 06 00:00:00 1970 PST | {"c3": "00736"} | {"c2": "6", "c6": "6", "c7": "6 ", "c8": "foo", "C 1": "736"} | Fri Feb 06 00:00:00 1970 PST | {"c3": "00736"} | {"c2": "6", "c6": "6", "c7": "6 ", "c8": "foo", "C 1": "736"} + Mon Feb 16 00:00:00 1970 PST | {"c3": "00746"} | {"c2": "6", "c6": "6", "c7": "6 ", "c8": "foo", "C 1": "746"} | Mon Feb 16 00:00:00 1970 PST | {"c3": "00746"} | {"c2": "6", "c6": "6", "c7": "6 ", "c8": "foo", "C 1": "746"} + Thu Feb 26 00:00:00 1970 PST | {"c3": "00756"} | {"c2": "6", "c6": "6", "c7": "6 ", "c8": "foo", "C 1": "756"} | Thu Feb 26 00:00:00 1970 PST | {"c3": "00756"} | {"c2": "6", "c6": "6", "c7": "6 ", "c8": "foo", "C 1": "756"} + Sun Mar 08 00:00:00 1970 PST | {"c3": "00766"} | {"c2": "6", "c6": "6", "c7": "6 ", "c8": "foo", "C 1": "766"} | Sun Mar 08 00:00:00 1970 PST | {"c3": "00766"} | {"c2": "6", "c6": "6", "c7": "6 ", "c8": "foo", "C 1": "766"} + Wed Mar 18 00:00:00 1970 PST | {"c3": "00776"} | {"c2": "6", "c6": "6", "c7": "6 ", "c8": "foo", "C 1": "776"} | Wed Mar 18 00:00:00 1970 PST | {"c3": "00776"} | {"c2": "6", "c6": "6", "c7": "6 ", "c8": "foo", "C 1": "776"} + Sat Mar 28 00:00:00 1970 PST | {"c3": "00786"} | {"c2": "6", "c6": "6", "c7": "6 ", "c8": "foo", "C 1": "786"} | Sat Mar 28 00:00:00 1970 PST | {"c3": "00786"} | {"c2": "6", "c6": "6", "c7": "6 ", "c8": "foo", "C 1": "786"} + Tue Apr 07 00:00:00 1970 PST | {"c3": "00796"} | {"c2": "6", "c6": "6", "c7": "6 ", "c8": "foo", "C 1": "796"} | Tue Apr 07 00:00:00 1970 PST | {"c3": "00796"} | {"c2": "6", "c6": "6", "c7": "6 ", "c8": "foo", "C 1": "796"} + Wed Jan 07 00:00:00 1970 PST | {"c3": "00806"} | {"c2": "6", "c6": "6", "c7": "6 ", "c8": "foo", "C 1": "806"} | Wed Jan 07 00:00:00 1970 PST | {"c3": "00806"} | {"c2": "6", "c6": "6", "c7": "6 ", "c8": "foo", "C 1": "806"} + Sat Jan 17 00:00:00 1970 PST | {"c3": "00816"} | {"c2": "6", "c6": "6", "c7": "6 ", "c8": "foo", "C 1": "816"} | Sat Jan 17 00:00:00 1970 PST | {"c3": "00816"} | {"c2": "6", "c6": "6", "c7": "6 ", "c8": "foo", "C 1": "816"} + Tue Jan 27 00:00:00 1970 PST | {"c3": "00826"} | {"c2": "6", "c6": "6", "c7": "6 ", "c8": "foo", "C 1": "826"} | Tue Jan 27 00:00:00 1970 PST | {"c3": "00826"} | {"c2": "6", "c6": "6", "c7": "6 ", "c8": "foo", "C 1": "826"} + Fri Feb 06 00:00:00 1970 PST | {"c3": "00836"} | {"c2": "6", "c6": "6", "c7": "6 ", "c8": "foo", "C 1": "836"} | Fri Feb 06 00:00:00 1970 PST | {"c3": "00836"} | {"c2": "6", "c6": "6", "c7": "6 ", "c8": "foo", "C 1": "836"} + Mon Feb 16 00:00:00 1970 PST | {"c3": "00846"} | {"c2": "6", "c6": "6", "c7": "6 ", "c8": "foo", "C 1": "846"} | Mon Feb 16 00:00:00 1970 PST | {"c3": "00846"} | {"c2": "6", "c6": "6", "c7": "6 ", "c8": "foo", "C 1": "846"} + Thu Feb 26 00:00:00 1970 PST | {"c3": "00856"} | {"c2": "6", "c6": "6", "c7": "6 ", "c8": "foo", "C 1": "856"} | Thu Feb 26 00:00:00 1970 PST | {"c3": "00856"} | {"c2": "6", "c6": "6", "c7": "6 ", "c8": "foo", "C 1": "856"} + Sun Mar 08 00:00:00 1970 PST | {"c3": "00866"} | {"c2": "6", "c6": "6", "c7": "6 ", "c8": "foo", "C 1": "866"} | Sun Mar 08 00:00:00 1970 PST | {"c3": "00866"} | {"c2": "6", "c6": "6", "c7": "6 ", "c8": "foo", "C 1": "866"} + Wed Mar 18 00:00:00 1970 PST | {"c3": "00876"} | {"c2": "6", "c6": "6", "c7": "6 ", "c8": "foo", "C 1": "876"} | Wed Mar 18 00:00:00 1970 PST | {"c3": "00876"} | {"c2": "6", "c6": "6", "c7": "6 ", "c8": "foo", "C 1": "876"} + Sat Mar 28 00:00:00 1970 PST | {"c3": "00886"} | {"c2": "6", "c6": "6", "c7": "6 ", "c8": "foo", "C 1": "886"} | Sat Mar 28 00:00:00 1970 PST | {"c3": "00886"} | {"c2": "6", "c6": "6", "c7": "6 ", "c8": "foo", "C 1": "886"} + Tue Apr 07 00:00:00 1970 PST | {"c3": "00896"} | {"c2": "6", "c6": "6", "c7": "6 ", "c8": "foo", "C 1": "896"} | Tue Apr 07 00:00:00 1970 PST | {"c3": "00896"} | {"c2": "6", "c6": "6", "c7": "6 ", "c8": "foo", "C 1": "896"} + Wed Jan 07 00:00:00 1970 PST | {"c3": "00906"} | {"c2": "6", "c6": "6", "c7": "6 ", "c8": "foo", "C 1": "906"} | Wed Jan 07 00:00:00 1970 PST | {"c3": "00906"} | {"c2": "6", "c6": "6", "c7": "6 ", "c8": "foo", "C 1": "906"} + Sat Jan 17 00:00:00 1970 PST | {"c3": "00916"} | {"c2": "6", "c6": "6", "c7": "6 ", "c8": "foo", "C 1": "916"} | Sat Jan 17 00:00:00 1970 PST | {"c3": "00916"} | {"c2": "6", "c6": "6", "c7": "6 ", "c8": "foo", "C 1": "916"} + Tue Jan 27 00:00:00 1970 PST | {"c3": "00926"} | {"c2": "6", "c6": "6", "c7": "6 ", "c8": "foo", "C 1": "926"} | Tue Jan 27 00:00:00 1970 PST | {"c3": "00926"} | {"c2": "6", "c6": "6", "c7": "6 ", "c8": "foo", "C 1": "926"} + Fri Feb 06 00:00:00 1970 PST | {"c3": "00936"} | {"c2": "6", "c6": "6", "c7": "6 ", "c8": "foo", "C 1": "936"} | Fri Feb 06 00:00:00 1970 PST | {"c3": "00936"} | {"c2": "6", "c6": "6", "c7": "6 ", "c8": "foo", "C 1": "936"} + Mon Feb 16 00:00:00 1970 PST | {"c3": "00946"} | {"c2": "6", "c6": "6", "c7": "6 ", "c8": "foo", "C 1": "946"} | Mon Feb 16 00:00:00 1970 PST | {"c3": "00946"} | {"c2": "6", "c6": "6", "c7": "6 ", "c8": "foo", "C 1": "946"} + Thu Feb 26 00:00:00 1970 PST | {"c3": "00956"} | {"c2": "6", "c6": "6", "c7": "6 ", "c8": "foo", "C 1": "956"} | Thu Feb 26 00:00:00 1970 PST | {"c3": "00956"} | {"c2": "6", "c6": "6", "c7": "6 ", "c8": "foo", "C 1": "956"} + Sun Mar 08 00:00:00 1970 PST | {"c3": "00966"} | {"c2": "6", "c6": "6", "c7": "6 ", "c8": "foo", "C 1": "966"} | Sun Mar 08 00:00:00 1970 PST | {"c3": "00966"} | {"c2": "6", "c6": "6", "c7": "6 ", "c8": "foo", "C 1": "966"} + Wed Mar 18 00:00:00 1970 PST | {"c3": "00976"} | {"c2": "6", "c6": "6", "c7": "6 ", "c8": "foo", "C 1": "976"} | Wed Mar 18 00:00:00 1970 PST | {"c3": "00976"} | {"c2": "6", "c6": "6", "c7": "6 ", "c8": "foo", "C 1": "976"} + Sat Mar 28 00:00:00 1970 PST | {"c3": "00986"} | {"c2": "6", "c6": "6", "c7": "6 ", "c8": "foo", "C 1": "986"} | Sat Mar 28 00:00:00 1970 PST | {"c3": "00986"} | {"c2": "6", "c6": "6", "c7": "6 ", "c8": "foo", "C 1": "986"} + Tue Apr 07 00:00:00 1970 PST | {"c3": "00996"} | {"c2": "6", "c6": "6", "c7": "6 ", "c8": "foo", "C 1": "996"} | Tue Apr 07 00:00:00 1970 PST | {"c3": "00996"} | {"c2": "6", "c6": "6", "c7": "6 ", "c8": "foo", "C 1": "996"} (100 rows) -- bug before 9.3.5 due to sloppy handling of remote-estimate parameters --Testcase 91: SELECT * FROM ft1 WHERE (fields->>'C 1')::int = ANY (ARRAY(SELECT (fields->>'C 1')::int FROM ft2 WHERE (fields->>'C 1')::int < 5)); - time | tags | fields ---------------------------+-----------------+--------------------------------------------------------------------- - Fri Jan 02 00:00:00 1970 | {"c3": "00001"} | {"c2": "1", "c6": "1", "c7": "1 ", "c8": "foo", "C 1": "1"} - Sat Jan 03 00:00:00 1970 | {"c3": "00002"} | {"c2": "2", "c6": "2", "c7": "2 ", "c8": "foo", "C 1": "2"} - Sun Jan 04 00:00:00 1970 | {"c3": "00003"} | {"c2": "3", "c6": "3", "c7": "3 ", "c8": "foo", "C 1": "3"} - Mon Jan 05 00:00:00 1970 | {"c3": "00004"} | {"c2": "4", "c6": "4", "c7": "4 ", "c8": "foo", "C 1": "4"} + time | tags | fields +------------------------------+-----------------+--------------------------------------------------------------------- + Fri Jan 02 00:00:00 1970 PST | {"c3": "00001"} | {"c2": "1", "c6": "1", "c7": "1 ", "c8": "foo", "C 1": "1"} + Sat Jan 03 00:00:00 1970 PST | {"c3": "00002"} | {"c2": "2", "c6": "2", "c7": "2 ", "c8": "foo", "C 1": "2"} + Sun Jan 04 00:00:00 1970 PST | {"c3": "00003"} | {"c2": "3", "c6": "3", "c7": "3 ", "c8": "foo", "C 1": "3"} + Mon Jan 05 00:00:00 1970 PST | {"c3": "00004"} | {"c2": "4", "c6": "4", "c7": "4 ", "c8": "foo", "C 1": "4"} (4 rows) --Testcase 92: SELECT * FROM ft2 WHERE (fields->>'C 1')::int = ANY (ARRAY(SELECT (fields->>'C 1')::int FROM ft1 WHERE (fields->>'C 1')::int < 5)); - time | tags | fields ---------------------------+-----------------+--------------------------------------------------------------------- - Fri Jan 02 00:00:00 1970 | {"c3": "00001"} | {"c2": "1", "c6": "1", "c7": "1 ", "c8": "foo", "C 1": "1"} - Sat Jan 03 00:00:00 1970 | {"c3": "00002"} | {"c2": "2", "c6": "2", "c7": "2 ", "c8": "foo", "C 1": "2"} - Sun Jan 04 00:00:00 1970 | {"c3": "00003"} | {"c2": "3", "c6": "3", "c7": "3 ", "c8": "foo", "C 1": "3"} - Mon Jan 05 00:00:00 1970 | {"c3": "00004"} | {"c2": "4", "c6": "4", "c7": "4 ", "c8": "foo", "C 1": "4"} + time | tags | fields +------------------------------+-----------------+--------------------------------------------------------------------- + Fri Jan 02 00:00:00 1970 PST | {"c3": "00001"} | {"c2": "1", "c6": "1", "c7": "1 ", "c8": "foo", "C 1": "1"} + Sat Jan 03 00:00:00 1970 PST | {"c3": "00002"} | {"c2": "2", "c6": "2", "c7": "2 ", "c8": "foo", "C 1": "2"} + Sun Jan 04 00:00:00 1970 PST | {"c3": "00003"} | {"c2": "3", "c6": "3", "c7": "3 ", "c8": "foo", "C 1": "3"} + Mon Jan 05 00:00:00 1970 PST | {"c3": "00004"} | {"c2": "4", "c6": "4", "c7": "4 ", "c8": "foo", "C 1": "4"} (4 rows) -- we should not push order by clause with volatile expressions or unsafe @@ -1177,9 +1177,9 @@ EXPLAIN (VERBOSE, COSTS OFF) --Testcase 106: SELECT * FROM ft1 t1 WHERE (t1.fields->>'C 1')::int === (t1.fields->>'c2')::int order by (t1.fields->>'c2')::int limit 1; - time | tags | fields ---------------------------+-----------------+--------------------------------------------------------------------- - Fri Jan 02 00:00:00 1970 | {"c3": "00001"} | {"c2": "1", "c6": "1", "c7": "1 ", "c8": "foo", "C 1": "1"} + time | tags | fields +------------------------------+-----------------+--------------------------------------------------------------------- + Fri Jan 02 00:00:00 1970 PST | {"c3": "00001"} | {"c2": "1", "c6": "1", "c7": "1 ", "c8": "foo", "C 1": "1"} (1 row) -- but let's put them in an extension ... @@ -1248,9 +1248,9 @@ EXPLAIN (VERBOSE, COSTS OFF) --Testcase 114: SELECT * FROM ft1 t1 WHERE (t1.fields->>'C 1')::int === (t1.fields->>'c2')::int order by (t1.fields->>'c2')::int limit 1; - time | tags | fields ---------------------------+-----------------+--------------------------------------------------------------------- - Fri Jan 02 00:00:00 1970 | {"c3": "00001"} | {"c2": "1", "c6": "1", "c7": "1 ", "c8": "foo", "C 1": "1"} + time | tags | fields +------------------------------+-----------------+--------------------------------------------------------------------- + Fri Jan 02 00:00:00 1970 PST | {"c3": "00001"} | {"c2": "1", "c6": "1", "c7": "1 ", "c8": "foo", "C 1": "1"} (1 row) -- This test case drop configuration when execute non-schemaless before @@ -3157,18 +3157,18 @@ SELECT * FROM ft1, ft2, ft4, ft5, local_tbl WHERE (ft1.fields->>'C 1')::int = (f --Testcase 204: SELECT * FROM ft1, ft2, ft4, ft5, local_tbl WHERE (ft1.fields->>'C 1')::int = (ft2.fields->>'C 1')::int AND (ft1.fields->>'c2')::int = (ft4.fields->>'c1')::int AND (ft1.fields->>'c2')::int = (ft5.fields->>'c1')::int AND (ft1.fields->>'c2')::int = (local_tbl.fields->>'c1')::int AND (ft1.fields->>'C 1')::int < 100 AND (ft2.fields->>'C 1')::int < 100 ORDER BY (ft1.fields->>'C 1')::int FOR UPDATE; - time | tags | fields | time | tags | fields | tags | fields | tags | fields | fields ---------------------------+-----------------+----------------------------------------------------------------------+--------------------------+-----------------+----------------------------------------------------------------------+------------------+------------------------+------------------+------------------------+-------------------------------------- - Wed Jan 07 00:00:00 1970 | {"c3": "00006"} | {"c2": "6", "c6": "6", "c7": "6 ", "c8": "foo", "C 1": "6"} | Wed Jan 07 00:00:00 1970 | {"c3": "00006"} | {"c2": "6", "c6": "6", "c7": "6 ", "c8": "foo", "C 1": "6"} | {"c3": "AAA006"} | {"c1": "6", "c2": "7"} | {"c3": "AAA006"} | {"c1": "6", "c2": "7"} | {"c1": "6", "c2": "6", "c3": "0006"} - Sat Jan 17 00:00:00 1970 | {"c3": "00016"} | {"c2": "6", "c6": "6", "c7": "6 ", "c8": "foo", "C 1": "16"} | Sat Jan 17 00:00:00 1970 | {"c3": "00016"} | {"c2": "6", "c6": "6", "c7": "6 ", "c8": "foo", "C 1": "16"} | {"c3": "AAA006"} | {"c1": "6", "c2": "7"} | {"c3": "AAA006"} | {"c1": "6", "c2": "7"} | {"c1": "6", "c2": "6", "c3": "0006"} - Tue Jan 27 00:00:00 1970 | {"c3": "00026"} | {"c2": "6", "c6": "6", "c7": "6 ", "c8": "foo", "C 1": "26"} | Tue Jan 27 00:00:00 1970 | {"c3": "00026"} | {"c2": "6", "c6": "6", "c7": "6 ", "c8": "foo", "C 1": "26"} | {"c3": "AAA006"} | {"c1": "6", "c2": "7"} | {"c3": "AAA006"} | {"c1": "6", "c2": "7"} | {"c1": "6", "c2": "6", "c3": "0006"} - Fri Feb 06 00:00:00 1970 | {"c3": "00036"} | {"c2": "6", "c6": "6", "c7": "6 ", "c8": "foo", "C 1": "36"} | Fri Feb 06 00:00:00 1970 | {"c3": "00036"} | {"c2": "6", "c6": "6", "c7": "6 ", "c8": "foo", "C 1": "36"} | {"c3": "AAA006"} | {"c1": "6", "c2": "7"} | {"c3": "AAA006"} | {"c1": "6", "c2": "7"} | {"c1": "6", "c2": "6", "c3": "0006"} - Mon Feb 16 00:00:00 1970 | {"c3": "00046"} | {"c2": "6", "c6": "6", "c7": "6 ", "c8": "foo", "C 1": "46"} | Mon Feb 16 00:00:00 1970 | {"c3": "00046"} | {"c2": "6", "c6": "6", "c7": "6 ", "c8": "foo", "C 1": "46"} | {"c3": "AAA006"} | {"c1": "6", "c2": "7"} | {"c3": "AAA006"} | {"c1": "6", "c2": "7"} | {"c1": "6", "c2": "6", "c3": "0006"} - Thu Feb 26 00:00:00 1970 | {"c3": "00056"} | {"c2": "6", "c6": "6", "c7": "6 ", "c8": "foo", "C 1": "56"} | Thu Feb 26 00:00:00 1970 | {"c3": "00056"} | {"c2": "6", "c6": "6", "c7": "6 ", "c8": "foo", "C 1": "56"} | {"c3": "AAA006"} | {"c1": "6", "c2": "7"} | {"c3": "AAA006"} | {"c1": "6", "c2": "7"} | {"c1": "6", "c2": "6", "c3": "0006"} - Sun Mar 08 00:00:00 1970 | {"c3": "00066"} | {"c2": "6", "c6": "6", "c7": "6 ", "c8": "foo", "C 1": "66"} | Sun Mar 08 00:00:00 1970 | {"c3": "00066"} | {"c2": "6", "c6": "6", "c7": "6 ", "c8": "foo", "C 1": "66"} | {"c3": "AAA006"} | {"c1": "6", "c2": "7"} | {"c3": "AAA006"} | {"c1": "6", "c2": "7"} | {"c1": "6", "c2": "6", "c3": "0006"} - Wed Mar 18 00:00:00 1970 | {"c3": "00076"} | {"c2": "6", "c6": "6", "c7": "6 ", "c8": "foo", "C 1": "76"} | Wed Mar 18 00:00:00 1970 | {"c3": "00076"} | {"c2": "6", "c6": "6", "c7": "6 ", "c8": "foo", "C 1": "76"} | {"c3": "AAA006"} | {"c1": "6", "c2": "7"} | {"c3": "AAA006"} | {"c1": "6", "c2": "7"} | {"c1": "6", "c2": "6", "c3": "0006"} - Sat Mar 28 00:00:00 1970 | {"c3": "00086"} | {"c2": "6", "c6": "6", "c7": "6 ", "c8": "foo", "C 1": "86"} | Sat Mar 28 00:00:00 1970 | {"c3": "00086"} | {"c2": "6", "c6": "6", "c7": "6 ", "c8": "foo", "C 1": "86"} | {"c3": "AAA006"} | {"c1": "6", "c2": "7"} | {"c3": "AAA006"} | {"c1": "6", "c2": "7"} | {"c1": "6", "c2": "6", "c3": "0006"} - Tue Apr 07 00:00:00 1970 | {"c3": "00096"} | {"c2": "6", "c6": "6", "c7": "6 ", "c8": "foo", "C 1": "96"} | Tue Apr 07 00:00:00 1970 | {"c3": "00096"} | {"c2": "6", "c6": "6", "c7": "6 ", "c8": "foo", "C 1": "96"} | {"c3": "AAA006"} | {"c1": "6", "c2": "7"} | {"c3": "AAA006"} | {"c1": "6", "c2": "7"} | {"c1": "6", "c2": "6", "c3": "0006"} + time | tags | fields | time | tags | fields | tags | fields | tags | fields | fields +------------------------------+-----------------+----------------------------------------------------------------------+------------------------------+-----------------+----------------------------------------------------------------------+------------------+------------------------+------------------+------------------------+-------------------------------------- + Wed Jan 07 00:00:00 1970 PST | {"c3": "00006"} | {"c2": "6", "c6": "6", "c7": "6 ", "c8": "foo", "C 1": "6"} | Wed Jan 07 00:00:00 1970 PST | {"c3": "00006"} | {"c2": "6", "c6": "6", "c7": "6 ", "c8": "foo", "C 1": "6"} | {"c3": "AAA006"} | {"c1": "6", "c2": "7"} | {"c3": "AAA006"} | {"c1": "6", "c2": "7"} | {"c1": "6", "c2": "6", "c3": "0006"} + Sat Jan 17 00:00:00 1970 PST | {"c3": "00016"} | {"c2": "6", "c6": "6", "c7": "6 ", "c8": "foo", "C 1": "16"} | Sat Jan 17 00:00:00 1970 PST | {"c3": "00016"} | {"c2": "6", "c6": "6", "c7": "6 ", "c8": "foo", "C 1": "16"} | {"c3": "AAA006"} | {"c1": "6", "c2": "7"} | {"c3": "AAA006"} | {"c1": "6", "c2": "7"} | {"c1": "6", "c2": "6", "c3": "0006"} + Tue Jan 27 00:00:00 1970 PST | {"c3": "00026"} | {"c2": "6", "c6": "6", "c7": "6 ", "c8": "foo", "C 1": "26"} | Tue Jan 27 00:00:00 1970 PST | {"c3": "00026"} | {"c2": "6", "c6": "6", "c7": "6 ", "c8": "foo", "C 1": "26"} | {"c3": "AAA006"} | {"c1": "6", "c2": "7"} | {"c3": "AAA006"} | {"c1": "6", "c2": "7"} | {"c1": "6", "c2": "6", "c3": "0006"} + Fri Feb 06 00:00:00 1970 PST | {"c3": "00036"} | {"c2": "6", "c6": "6", "c7": "6 ", "c8": "foo", "C 1": "36"} | Fri Feb 06 00:00:00 1970 PST | {"c3": "00036"} | {"c2": "6", "c6": "6", "c7": "6 ", "c8": "foo", "C 1": "36"} | {"c3": "AAA006"} | {"c1": "6", "c2": "7"} | {"c3": "AAA006"} | {"c1": "6", "c2": "7"} | {"c1": "6", "c2": "6", "c3": "0006"} + Mon Feb 16 00:00:00 1970 PST | {"c3": "00046"} | {"c2": "6", "c6": "6", "c7": "6 ", "c8": "foo", "C 1": "46"} | Mon Feb 16 00:00:00 1970 PST | {"c3": "00046"} | {"c2": "6", "c6": "6", "c7": "6 ", "c8": "foo", "C 1": "46"} | {"c3": "AAA006"} | {"c1": "6", "c2": "7"} | {"c3": "AAA006"} | {"c1": "6", "c2": "7"} | {"c1": "6", "c2": "6", "c3": "0006"} + Thu Feb 26 00:00:00 1970 PST | {"c3": "00056"} | {"c2": "6", "c6": "6", "c7": "6 ", "c8": "foo", "C 1": "56"} | Thu Feb 26 00:00:00 1970 PST | {"c3": "00056"} | {"c2": "6", "c6": "6", "c7": "6 ", "c8": "foo", "C 1": "56"} | {"c3": "AAA006"} | {"c1": "6", "c2": "7"} | {"c3": "AAA006"} | {"c1": "6", "c2": "7"} | {"c1": "6", "c2": "6", "c3": "0006"} + Sun Mar 08 00:00:00 1970 PST | {"c3": "00066"} | {"c2": "6", "c6": "6", "c7": "6 ", "c8": "foo", "C 1": "66"} | Sun Mar 08 00:00:00 1970 PST | {"c3": "00066"} | {"c2": "6", "c6": "6", "c7": "6 ", "c8": "foo", "C 1": "66"} | {"c3": "AAA006"} | {"c1": "6", "c2": "7"} | {"c3": "AAA006"} | {"c1": "6", "c2": "7"} | {"c1": "6", "c2": "6", "c3": "0006"} + Wed Mar 18 00:00:00 1970 PST | {"c3": "00076"} | {"c2": "6", "c6": "6", "c7": "6 ", "c8": "foo", "C 1": "76"} | Wed Mar 18 00:00:00 1970 PST | {"c3": "00076"} | {"c2": "6", "c6": "6", "c7": "6 ", "c8": "foo", "C 1": "76"} | {"c3": "AAA006"} | {"c1": "6", "c2": "7"} | {"c3": "AAA006"} | {"c1": "6", "c2": "7"} | {"c1": "6", "c2": "6", "c3": "0006"} + Sat Mar 28 00:00:00 1970 PST | {"c3": "00086"} | {"c2": "6", "c6": "6", "c7": "6 ", "c8": "foo", "C 1": "86"} | Sat Mar 28 00:00:00 1970 PST | {"c3": "00086"} | {"c2": "6", "c6": "6", "c7": "6 ", "c8": "foo", "C 1": "86"} | {"c3": "AAA006"} | {"c1": "6", "c2": "7"} | {"c3": "AAA006"} | {"c1": "6", "c2": "7"} | {"c1": "6", "c2": "6", "c3": "0006"} + Tue Apr 07 00:00:00 1970 PST | {"c3": "00096"} | {"c2": "6", "c6": "6", "c7": "6 ", "c8": "foo", "C 1": "96"} | Tue Apr 07 00:00:00 1970 PST | {"c3": "00096"} | {"c2": "6", "c6": "6", "c7": "6 ", "c8": "foo", "C 1": "96"} | {"c3": "AAA006"} | {"c1": "6", "c2": "7"} | {"c3": "AAA006"} | {"c1": "6", "c2": "7"} | {"c1": "6", "c2": "6", "c3": "0006"} (10 rows) --Testcase 205: @@ -3832,9 +3832,9 @@ select array_agg(time order by (fields->>'C 1')::int desc) from ft2 where (field --Testcase 257: select array_agg(time order by (fields->>'C 1')::int desc) from ft2 where (fields->>'c2')::int = 6 and (fields->>'C 1')::int < 50; - array_agg ------------------------------------------------------------------------------------------------------------------------------------------- - {"Mon Feb 16 00:00:00 1970","Fri Feb 06 00:00:00 1970","Tue Jan 27 00:00:00 1970","Sat Jan 17 00:00:00 1970","Wed Jan 07 00:00:00 1970"} + array_agg +-------------------------------------------------------------------------------------------------------------------------------------------------------------- + {"Mon Feb 16 00:00:00 1970 PST","Fri Feb 06 00:00:00 1970 PST","Tue Jan 27 00:00:00 1970 PST","Sat Jan 17 00:00:00 1970 PST","Wed Jan 07 00:00:00 1970 PST"} (1 row) -- DISTINCT within aggregate @@ -5022,16 +5022,16 @@ EXPLAIN (VERBOSE, COSTS OFF) EXECUTE st2(10, 20); --Testcase 359: EXECUTE st2(10, 20); - time | tags | fields ---------------------------+-----------------+---------------------------------------------------------------------- - Sat Jan 17 00:00:00 1970 | {"c3": "00016"} | {"c2": "6", "c6": "6", "c7": "6 ", "c8": "foo", "C 1": "16"} + time | tags | fields +------------------------------+-----------------+---------------------------------------------------------------------- + Sat Jan 17 00:00:00 1970 PST | {"c3": "00016"} | {"c2": "6", "c6": "6", "c7": "6 ", "c8": "foo", "C 1": "16"} (1 row) --Testcase 360: EXECUTE st2(101, 121); - time | tags | fields ---------------------------+-----------------+----------------------------------------------------------------------- - Sat Jan 17 00:00:00 1970 | {"c3": "00116"} | {"c2": "6", "c6": "6", "c7": "6 ", "c8": "foo", "C 1": "116"} + time | tags | fields +------------------------------+-----------------+----------------------------------------------------------------------- + Sat Jan 17 00:00:00 1970 PST | {"c3": "00116"} | {"c2": "6", "c6": "6", "c7": "6 ", "c8": "foo", "C 1": "116"} (1 row) -- subquery using immutable function (can be sent to remote) @@ -5060,9 +5060,9 @@ EXPLAIN (VERBOSE, COSTS OFF) EXECUTE st3(10, 20); --Testcase 363: EXECUTE st3(10, 20); - time | tags | fields ---------------------------+-----------------+---------------------------------------------------------------------- - Sat Jan 17 00:00:00 1970 | {"c3": "00016"} | {"c2": "6", "c6": "6", "c7": "6 ", "c8": "foo", "C 1": "16"} + time | tags | fields +------------------------------+-----------------+---------------------------------------------------------------------- + Sat Jan 17 00:00:00 1970 PST | {"c3": "00016"} | {"c2": "6", "c6": "6", "c7": "6 ", "c8": "foo", "C 1": "16"} (1 row) --Testcase 364: @@ -5188,9 +5188,9 @@ EXPLAIN (VERBOSE, COSTS OFF) EXECUTE st5('foo', 1); --Testcase 379: EXECUTE st5('foo', 1); - time | tags | fields ---------------------------+-----------------+--------------------------------------------------------------------- - Fri Jan 02 00:00:00 1970 | {"c3": "00001"} | {"c2": "1", "c6": "1", "c7": "1 ", "c8": "foo", "C 1": "1"} + time | tags | fields +------------------------------+-----------------+--------------------------------------------------------------------- + Fri Jan 02 00:00:00 1970 PST | {"c3": "00001"} | {"c2": "1", "c6": "1", "c7": "1 ", "c8": "foo", "C 1": "1"} (1 row) -- altering FDW options requires replanning @@ -5209,12 +5209,12 @@ EXPLAIN (VERBOSE, COSTS OFF) EXECUTE st6; PREPARE st7 AS INSERT INTO ft1_nsc (c1,c2,c3) VALUES (1001,101,'foo'); --Testcase 383: EXPLAIN (VERBOSE, COSTS OFF) EXECUTE st7; - QUERY PLAN ------------------------------------------------------------------------------------------------------------------------------------------------------------- + QUERY PLAN +--------------------------------------------------------------------------------------------------------------------------------------------------------- Insert on public.ft1_nsc Batch Size: 1 -> Result - Output: NULL::integer, 1001, 101, 'foo'::text, NULL::timestamp without time zone, NULL::character varying, 'ft1 '::character(10), NULL::text + Output: NULL::integer, 1001, 101, 'foo'::text, NULL::timestamp with time zone, NULL::character varying, 'ft1 '::character(10), NULL::text (4 rows) --Testcase 384: @@ -5232,27 +5232,27 @@ EXPLAIN (VERBOSE, COSTS OFF) EXECUTE st6; --Testcase 387: EXECUTE st6; - time | tags | fields ---------------------------+-----------------+--------------------------------------------------------------------- - Fri Jan 02 00:00:00 1970 | {"c3": "00001"} | {"c2": "1", "c6": "1", "c7": "1 ", "c8": "foo", "C 1": "1"} - Sat Jan 03 00:00:00 1970 | {"c3": "00002"} | {"c2": "2", "c6": "2", "c7": "2 ", "c8": "foo", "C 1": "2"} - Sun Jan 04 00:00:00 1970 | {"c3": "00003"} | {"c2": "3", "c6": "3", "c7": "3 ", "c8": "foo", "C 1": "3"} - Mon Jan 05 00:00:00 1970 | {"c3": "00004"} | {"c2": "4", "c6": "4", "c7": "4 ", "c8": "foo", "C 1": "4"} - Tue Jan 06 00:00:00 1970 | {"c3": "00005"} | {"c2": "5", "c6": "5", "c7": "5 ", "c8": "foo", "C 1": "5"} - Wed Jan 07 00:00:00 1970 | {"c3": "00006"} | {"c2": "6", "c6": "6", "c7": "6 ", "c8": "foo", "C 1": "6"} - Thu Jan 08 00:00:00 1970 | {"c3": "00007"} | {"c2": "7", "c6": "7", "c7": "7 ", "c8": "foo", "C 1": "7"} - Fri Jan 09 00:00:00 1970 | {"c3": "00008"} | {"c2": "8", "c6": "8", "c7": "8 ", "c8": "foo", "C 1": "8"} - Sat Jan 10 00:00:00 1970 | {"c3": "00009"} | {"c2": "9", "c6": "9", "c7": "9 ", "c8": "foo", "C 1": "9"} + time | tags | fields +------------------------------+-----------------+--------------------------------------------------------------------- + Fri Jan 02 00:00:00 1970 PST | {"c3": "00001"} | {"c2": "1", "c6": "1", "c7": "1 ", "c8": "foo", "C 1": "1"} + Sat Jan 03 00:00:00 1970 PST | {"c3": "00002"} | {"c2": "2", "c6": "2", "c7": "2 ", "c8": "foo", "C 1": "2"} + Sun Jan 04 00:00:00 1970 PST | {"c3": "00003"} | {"c2": "3", "c6": "3", "c7": "3 ", "c8": "foo", "C 1": "3"} + Mon Jan 05 00:00:00 1970 PST | {"c3": "00004"} | {"c2": "4", "c6": "4", "c7": "4 ", "c8": "foo", "C 1": "4"} + Tue Jan 06 00:00:00 1970 PST | {"c3": "00005"} | {"c2": "5", "c6": "5", "c7": "5 ", "c8": "foo", "C 1": "5"} + Wed Jan 07 00:00:00 1970 PST | {"c3": "00006"} | {"c2": "6", "c6": "6", "c7": "6 ", "c8": "foo", "C 1": "6"} + Thu Jan 08 00:00:00 1970 PST | {"c3": "00007"} | {"c2": "7", "c6": "7", "c7": "7 ", "c8": "foo", "C 1": "7"} + Fri Jan 09 00:00:00 1970 PST | {"c3": "00008"} | {"c2": "8", "c6": "8", "c7": "8 ", "c8": "foo", "C 1": "8"} + Sat Jan 10 00:00:00 1970 PST | {"c3": "00009"} | {"c2": "9", "c6": "9", "c7": "9 ", "c8": "foo", "C 1": "9"} (9 rows) --Testcase 388: EXPLAIN (VERBOSE, COSTS OFF) EXECUTE st7; - QUERY PLAN ------------------------------------------------------------------------------------------------------------------------------------------------------------- + QUERY PLAN +--------------------------------------------------------------------------------------------------------------------------------------------------------- Insert on public.ft1_nsc Batch Size: 1 -> Result - Output: NULL::integer, 1001, 101, 'foo'::text, NULL::timestamp without time zone, NULL::character varying, 'ft1 '::character(10), NULL::text + Output: NULL::integer, 1001, 101, 'foo'::text, NULL::timestamp with time zone, NULL::character varying, 'ft1 '::character(10), NULL::text (4 rows) --Testcase 389: @@ -5320,9 +5320,9 @@ SELECT * FROM ft1 t1 WHERE t1.tableoid = 'pg_class'::regclass LIMIT 1; --Testcase 396: SELECT * FROM ft1 t1 WHERE t1.tableoid = 'ft1'::regclass ORDER BY (fields->>'C 1')::int LIMIT 1; - time | tags | fields ---------------------------+-----------------+--------------------------------------------------------------------- - Fri Jan 02 00:00:00 1970 | {"c3": "00001"} | {"c2": "1", "c6": "1", "c7": "1 ", "c8": "foo", "C 1": "1"} + time | tags | fields +------------------------------+-----------------+--------------------------------------------------------------------- + Fri Jan 02 00:00:00 1970 PST | {"c3": "00001"} | {"c2": "1", "c6": "1", "c7": "1 ", "c8": "foo", "C 1": "1"} (1 row) --Testcase 397: @@ -5337,9 +5337,9 @@ SELECT tableoid::regclass, * FROM ft1 t1 LIMIT 1; --Testcase 398: SELECT tableoid::regclass, * FROM ft1 t1 ORDER BY (fields->>'C 1')::int LIMIT 1; - tableoid | time | tags | fields -----------+--------------------------+-----------------+--------------------------------------------------------------------- - ft1 | Fri Jan 02 00:00:00 1970 | {"c3": "00001"} | {"c2": "1", "c6": "1", "c7": "1 ", "c8": "foo", "C 1": "1"} + tableoid | time | tags | fields +----------+------------------------------+-----------------+--------------------------------------------------------------------- + ft1 | Fri Jan 02 00:00:00 1970 PST | {"c3": "00001"} | {"c2": "1", "c6": "1", "c7": "1 ", "c8": "foo", "C 1": "1"} (1 row) --Testcase 399: @@ -5371,9 +5371,9 @@ SELECT ctid, * FROM ft1 t1 LIMIT 1; --Testcase 402: SELECT ctid, * FROM ft1 t1 ORDER BY (fields->>'C 1')::int LIMIT 1; - ctid | time | tags | fields -----------------+--------------------------+-----------------+--------------------------------------------------------------------- - (4294967295,0) | Fri Jan 02 00:00:00 1970 | {"c3": "00001"} | {"c2": "1", "c6": "1", "c7": "1 ", "c8": "foo", "C 1": "1"} + ctid | time | tags | fields +----------------+------------------------------+-----------------+--------------------------------------------------------------------- + (4294967295,0) | Fri Jan 02 00:00:00 1970 PST | {"c3": "00001"} | {"c2": "1", "c6": "1", "c7": "1 ", "c8": "foo", "C 1": "1"} (1 row) -- =================================================================== @@ -5588,12 +5588,12 @@ explain (verbose, costs off) select * from ft3 f, loct3 l --Testcase 431: EXPLAIN (verbose, costs off) INSERT INTO ft2_nsc (c1,c2,c3) SELECT c1+1000,c2+100, c3 || c3 FROM ft2_nsc ORDER BY c1 LIMIT 20; - QUERY PLAN -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- + QUERY PLAN +---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- Insert on public.ft2_nsc Batch Size: 1 -> Subquery Scan on "*SELECT*" - Output: "*SELECT*"."?column?", "*SELECT*"."?column?_1", NULL::integer, "*SELECT*"."?column?_2", NULL::timestamp without time zone, NULL::character varying, 'ft2 '::character(10), NULL::text + Output: "*SELECT*"."?column?", "*SELECT*"."?column?_1", NULL::integer, "*SELECT*"."?column?_2", NULL::timestamp with time zone, NULL::character varying, 'ft2 '::character(10), NULL::text -> Limit Output: ((ft2_nsc_1.c1 + 1000)), ((ft2_nsc_1.c2 + 100)), ((ft2_nsc_1.c3 || ft2_nsc_1.c3)), ft2_nsc_1.c1 -> Sort @@ -6607,12 +6607,12 @@ SELECT (fields->>'C 1')::int c1, (fields->>'c2')::int c2, tags->>'c3' c3 FROM ft --Testcase 443: EXPLAIN (verbose, costs off) INSERT INTO ft2_nsc (c1,c2,c3) VALUES (1200,999,'foo'); - QUERY PLAN ------------------------------------------------------------------------------------------------------------------------------------------------------------- + QUERY PLAN +--------------------------------------------------------------------------------------------------------------------------------------------------------- Insert on public.ft2_nsc Batch Size: 1 -> Result - Output: 1200, 999, NULL::integer, 'foo'::text, NULL::timestamp without time zone, NULL::character varying, 'ft2 '::character(10), NULL::text + Output: 1200, 999, NULL::integer, 'foo'::text, NULL::timestamp with time zone, NULL::character varying, 'ft2 '::character(10), NULL::text (4 rows) --Testcase 444: @@ -9330,7 +9330,7 @@ CREATE FOREIGN TABLE ft1_nopw ( c2 int NOT NULL, c3 text, c4 timestamptz, - c5 timestamp, + c5 timestamptz, c6 varchar(10), c7 char(10) default 'ft1', c8 user_enum diff --git a/expected/13.8/schemaless/extra/insert.out b/expected/14.9/schemaless/extra/insert.out similarity index 100% rename from expected/13.8/schemaless/extra/insert.out rename to expected/14.9/schemaless/extra/insert.out diff --git a/expected/14.5/schemaless/extra/join.out b/expected/14.9/schemaless/extra/join.out similarity index 100% rename from expected/14.5/schemaless/extra/join.out rename to expected/14.9/schemaless/extra/join.out diff --git a/expected/14.5/schemaless/extra/limit.out b/expected/14.9/schemaless/extra/limit.out similarity index 100% rename from expected/14.5/schemaless/extra/limit.out rename to expected/14.9/schemaless/extra/limit.out diff --git a/expected/14.5/schemaless/extra/prepare.out b/expected/14.9/schemaless/extra/prepare.out similarity index 100% rename from expected/14.5/schemaless/extra/prepare.out rename to expected/14.9/schemaless/extra/prepare.out diff --git a/expected/14.5/schemaless/extra/select.out b/expected/14.9/schemaless/extra/select.out similarity index 100% rename from expected/14.5/schemaless/extra/select.out rename to expected/14.9/schemaless/extra/select.out diff --git a/expected/13.8/schemaless/extra/select_having.out b/expected/14.9/schemaless/extra/select_having.out similarity index 100% rename from expected/13.8/schemaless/extra/select_having.out rename to expected/14.9/schemaless/extra/select_having.out diff --git a/expected/14.5/schemaless/influxdb_fdw.out b/expected/14.9/schemaless/influxdb_fdw.out similarity index 99% rename from expected/14.5/schemaless/influxdb_fdw.out rename to expected/14.9/schemaless/influxdb_fdw.out index 959f1e1..4f0c243 100644 --- a/expected/14.5/schemaless/influxdb_fdw.out +++ b/expected/14.9/schemaless/influxdb_fdw.out @@ -1130,14 +1130,14 @@ SELECT * FROM t5; SELECT * FROM public.influxdb_fdw_version(); influxdb_fdw_version ---------------------- - 20000 + 20100 (1 row) --Testcase 146: SELECT influxdb_fdw_version(); influxdb_fdw_version ---------------------- - 20000 + 20100 (1 row) --Test pushdown LIMIT...OFFSET diff --git a/expected/14.5/schemaless/schemaless.out b/expected/14.9/schemaless/schemaless.out similarity index 100% rename from expected/14.5/schemaless/schemaless.out rename to expected/14.9/schemaless/schemaless.out diff --git a/expected/14.5/schemaless/selectfunc.out b/expected/14.9/schemaless/selectfunc.out similarity index 100% rename from expected/14.5/schemaless/selectfunc.out rename to expected/14.9/schemaless/selectfunc.out diff --git a/expected/14.5/selectfunc.out b/expected/14.9/selectfunc.out similarity index 100% rename from expected/14.5/selectfunc.out rename to expected/14.9/selectfunc.out diff --git a/expected/14.5/aggregate.out b/expected/15.4/aggregate.out similarity index 100% rename from expected/14.5/aggregate.out rename to expected/15.4/aggregate.out diff --git a/expected/15.0/extra/aggregates.out b/expected/15.4/extra/aggregates.out similarity index 100% rename from expected/15.0/extra/aggregates.out rename to expected/15.4/extra/aggregates.out diff --git a/expected/15.0/extra/influxdb_fdw_post.out b/expected/15.4/extra/influxdb_fdw_post.out similarity index 92% rename from expected/15.0/extra/influxdb_fdw_post.out rename to expected/15.4/extra/influxdb_fdw_post.out index 0c0047a..ee0b144 100644 --- a/expected/15.0/extra/influxdb_fdw_post.out +++ b/expected/15.4/extra/influxdb_fdw_post.out @@ -30,7 +30,7 @@ CREATE FOREIGN TABLE "S 1"."T 0" ( "C 1" int NOT NULL, c2 int NOT NULL, c3 text, - time timestamp, + time timestamptz, c6 varchar(10), c7 char(10), c8 text @@ -40,7 +40,7 @@ CREATE FOREIGN TABLE "S 1"."T 1" ( "C 1" int NOT NULL, c2 int NOT NULL, c3 text, - time timestamp, + time timestamptz, c6 varchar(10), c7 char(10), c8 text @@ -72,7 +72,7 @@ INSERT INTO "S 1"."T 1" SELECT id, id % 10, to_char(id, 'FM00000'), - '1970-01-01'::timestamp + ((id % 100) || ' days')::interval, + '1970-01-01'::timestamptz + ((id % 100) || ' days')::interval, id % 10, id % 10, 'foo'::text @@ -111,7 +111,7 @@ CREATE FOREIGN TABLE ft1 ( c1 int NOT NULL, c2 int NOT NULL, c3 text, - time timestamp, + time timestamptz, c6 varchar(10), c7 char(10) default 'ft1', c8 text @@ -124,7 +124,7 @@ CREATE FOREIGN TABLE ft2 ( c2 int NOT NULL, cx int, c3 text, - time timestamp, + time timestamptz, c6 varchar(10), c7 char(10) default 'ft2', c8 text @@ -229,9 +229,9 @@ ALTER FOREIGN TABLE ft2 ALTER COLUMN c1 OPTIONS (column_name 'C 1'); \set VERBOSITY terse --Testcase 35: SELECT c3, time FROM ft1 ORDER BY c3, c1 LIMIT 1; -- should work - c3 | time --------+-------------------------- - 00001 | Fri Jan 02 00:00:00 1970 + c3 | time +-------+------------------------------ + 00001 | Fri Jan 02 00:00:00 1970 PST (1 row) --Testcase 36: @@ -247,9 +247,9 @@ DO $d$ $d$; --Testcase 38: SELECT c3, time FROM ft1 ORDER BY c3, c1 LIMIT 1; -- should work again - c3 | time --------+-------------------------- - 00001 | Fri Jan 02 00:00:00 1970 + c3 | time +-------+------------------------------ + 00001 | Fri Jan 02 00:00:00 1970 PST (1 row) \set VERBOSITY default @@ -276,18 +276,18 @@ EXPLAIN (COSTS OFF) SELECT * FROM ft1 ORDER BY c3, c1 OFFSET 100 LIMIT 10; --Testcase 40: SELECT * FROM ft1 ORDER BY c3, c1 OFFSET 100 LIMIT 10; - c1 | c2 | c3 | time | c6 | c7 | c8 ------+----+-------+--------------------------+----+------------+----- - 101 | 1 | 00101 | Fri Jan 02 00:00:00 1970 | 1 | 1 | foo - 102 | 2 | 00102 | Sat Jan 03 00:00:00 1970 | 2 | 2 | foo - 103 | 3 | 00103 | Sun Jan 04 00:00:00 1970 | 3 | 3 | foo - 104 | 4 | 00104 | Mon Jan 05 00:00:00 1970 | 4 | 4 | foo - 105 | 5 | 00105 | Tue Jan 06 00:00:00 1970 | 5 | 5 | foo - 106 | 6 | 00106 | Wed Jan 07 00:00:00 1970 | 6 | 6 | foo - 107 | 7 | 00107 | Thu Jan 08 00:00:00 1970 | 7 | 7 | foo - 108 | 8 | 00108 | Fri Jan 09 00:00:00 1970 | 8 | 8 | foo - 109 | 9 | 00109 | Sat Jan 10 00:00:00 1970 | 9 | 9 | foo - 110 | 0 | 00110 | Sun Jan 11 00:00:00 1970 | 0 | 0 | foo + c1 | c2 | c3 | time | c6 | c7 | c8 +-----+----+-------+------------------------------+----+------------+----- + 101 | 1 | 00101 | Fri Jan 02 00:00:00 1970 PST | 1 | 1 | foo + 102 | 2 | 00102 | Sat Jan 03 00:00:00 1970 PST | 2 | 2 | foo + 103 | 3 | 00103 | Sun Jan 04 00:00:00 1970 PST | 3 | 3 | foo + 104 | 4 | 00104 | Mon Jan 05 00:00:00 1970 PST | 4 | 4 | foo + 105 | 5 | 00105 | Tue Jan 06 00:00:00 1970 PST | 5 | 5 | foo + 106 | 6 | 00106 | Wed Jan 07 00:00:00 1970 PST | 6 | 6 | foo + 107 | 7 | 00107 | Thu Jan 08 00:00:00 1970 PST | 7 | 7 | foo + 108 | 8 | 00108 | Fri Jan 09 00:00:00 1970 PST | 8 | 8 | foo + 109 | 9 | 00109 | Sat Jan 10 00:00:00 1970 PST | 9 | 9 | foo + 110 | 0 | 00110 | Sun Jan 11 00:00:00 1970 PST | 0 | 0 | foo (10 rows) -- single table with alias - also test that tableoid sort is not pushed to remote side @@ -307,18 +307,18 @@ EXPLAIN (VERBOSE, COSTS OFF) SELECT * FROM ft1 t1 ORDER BY t1.c3, t1.c1, t1.tabl --Testcase 42: SELECT * FROM ft1 t1 ORDER BY t1.c3, t1.c1, t1.tableoid OFFSET 100 LIMIT 10; - c1 | c2 | c3 | time | c6 | c7 | c8 ------+----+-------+--------------------------+----+------------+----- - 101 | 1 | 00101 | Fri Jan 02 00:00:00 1970 | 1 | 1 | foo - 102 | 2 | 00102 | Sat Jan 03 00:00:00 1970 | 2 | 2 | foo - 103 | 3 | 00103 | Sun Jan 04 00:00:00 1970 | 3 | 3 | foo - 104 | 4 | 00104 | Mon Jan 05 00:00:00 1970 | 4 | 4 | foo - 105 | 5 | 00105 | Tue Jan 06 00:00:00 1970 | 5 | 5 | foo - 106 | 6 | 00106 | Wed Jan 07 00:00:00 1970 | 6 | 6 | foo - 107 | 7 | 00107 | Thu Jan 08 00:00:00 1970 | 7 | 7 | foo - 108 | 8 | 00108 | Fri Jan 09 00:00:00 1970 | 8 | 8 | foo - 109 | 9 | 00109 | Sat Jan 10 00:00:00 1970 | 9 | 9 | foo - 110 | 0 | 00110 | Sun Jan 11 00:00:00 1970 | 0 | 0 | foo + c1 | c2 | c3 | time | c6 | c7 | c8 +-----+----+-------+------------------------------+----+------------+----- + 101 | 1 | 00101 | Fri Jan 02 00:00:00 1970 PST | 1 | 1 | foo + 102 | 2 | 00102 | Sat Jan 03 00:00:00 1970 PST | 2 | 2 | foo + 103 | 3 | 00103 | Sun Jan 04 00:00:00 1970 PST | 3 | 3 | foo + 104 | 4 | 00104 | Mon Jan 05 00:00:00 1970 PST | 4 | 4 | foo + 105 | 5 | 00105 | Tue Jan 06 00:00:00 1970 PST | 5 | 5 | foo + 106 | 6 | 00106 | Wed Jan 07 00:00:00 1970 PST | 6 | 6 | foo + 107 | 7 | 00107 | Thu Jan 08 00:00:00 1970 PST | 7 | 7 | foo + 108 | 8 | 00108 | Fri Jan 09 00:00:00 1970 PST | 8 | 8 | foo + 109 | 9 | 00109 | Sat Jan 10 00:00:00 1970 PST | 9 | 9 | foo + 110 | 0 | 00110 | Sun Jan 11 00:00:00 1970 PST | 0 | 0 | foo (10 rows) -- whole-row reference @@ -338,18 +338,18 @@ EXPLAIN (VERBOSE, COSTS OFF) SELECT t1 FROM ft1 t1 ORDER BY t1.c3, t1.c1 OFFSET --Testcase 44: SELECT t1 FROM ft1 t1 ORDER BY t1.c3, t1.c1 OFFSET 100 LIMIT 10; - t1 -------------------------------------------------------------- - (101,1,00101,"Fri Jan 02 00:00:00 1970",1,"1 ",foo) - (102,2,00102,"Sat Jan 03 00:00:00 1970",2,"2 ",foo) - (103,3,00103,"Sun Jan 04 00:00:00 1970",3,"3 ",foo) - (104,4,00104,"Mon Jan 05 00:00:00 1970",4,"4 ",foo) - (105,5,00105,"Tue Jan 06 00:00:00 1970",5,"5 ",foo) - (106,6,00106,"Wed Jan 07 00:00:00 1970",6,"6 ",foo) - (107,7,00107,"Thu Jan 08 00:00:00 1970",7,"7 ",foo) - (108,8,00108,"Fri Jan 09 00:00:00 1970",8,"8 ",foo) - (109,9,00109,"Sat Jan 10 00:00:00 1970",9,"9 ",foo) - (110,0,00110,"Sun Jan 11 00:00:00 1970",0,"0 ",foo) + t1 +----------------------------------------------------------------- + (101,1,00101,"Fri Jan 02 00:00:00 1970 PST",1,"1 ",foo) + (102,2,00102,"Sat Jan 03 00:00:00 1970 PST",2,"2 ",foo) + (103,3,00103,"Sun Jan 04 00:00:00 1970 PST",3,"3 ",foo) + (104,4,00104,"Mon Jan 05 00:00:00 1970 PST",4,"4 ",foo) + (105,5,00105,"Tue Jan 06 00:00:00 1970 PST",5,"5 ",foo) + (106,6,00106,"Wed Jan 07 00:00:00 1970 PST",6,"6 ",foo) + (107,7,00107,"Thu Jan 08 00:00:00 1970 PST",7,"7 ",foo) + (108,8,00108,"Fri Jan 09 00:00:00 1970 PST",8,"8 ",foo) + (109,9,00109,"Sat Jan 10 00:00:00 1970 PST",9,"9 ",foo) + (110,0,00110,"Sun Jan 11 00:00:00 1970 PST",0,"0 ",foo) (10 rows) -- empty result @@ -372,9 +372,9 @@ EXPLAIN (VERBOSE, COSTS OFF) SELECT * FROM ft1 t1 WHERE t1.c1 = 101 AND t1.c6 = --Testcase 47: SELECT * FROM ft1 t1 WHERE t1.c1 = 101 AND t1.c6 = '1' AND t1.c7 >= '1'; - c1 | c2 | c3 | time | c6 | c7 | c8 ------+----+-------+--------------------------+----+------------+----- - 101 | 1 | 00101 | Fri Jan 02 00:00:00 1970 | 1 | 1 | foo + c1 | c2 | c3 | time | c6 | c7 | c8 +-----+----+-------+------------------------------+----+------------+----- + 101 | 1 | 00101 | Fri Jan 02 00:00:00 1970 PST | 1 | 1 | foo (1 row) -- with FOR UPDATE/SHARE @@ -391,9 +391,9 @@ EXPLAIN (VERBOSE, COSTS OFF) SELECT * FROM ft1 t1 WHERE c1 = 101 FOR UPDATE; --Testcase 49: SELECT * FROM ft1 t1 WHERE c1 = 101 FOR UPDATE; - c1 | c2 | c3 | time | c6 | c7 | c8 ------+----+-------+--------------------------+----+------------+----- - 101 | 1 | 00101 | Fri Jan 02 00:00:00 1970 | 1 | 1 | foo + c1 | c2 | c3 | time | c6 | c7 | c8 +-----+----+-------+------------------------------+----+------------+----- + 101 | 1 | 00101 | Fri Jan 02 00:00:00 1970 PST | 1 | 1 | foo (1 row) --Testcase 50: @@ -409,9 +409,9 @@ EXPLAIN (VERBOSE, COSTS OFF) SELECT * FROM ft1 t1 WHERE c1 = 102 FOR SHARE; --Testcase 51: SELECT * FROM ft1 t1 WHERE c1 = 102 FOR SHARE; - c1 | c2 | c3 | time | c6 | c7 | c8 ------+----+-------+--------------------------+----+------------+----- - 102 | 2 | 00102 | Sat Jan 03 00:00:00 1970 | 2 | 2 | foo + c1 | c2 | c3 | time | c6 | c7 | c8 +-----+----+-------+------------------------------+----+------------+----- + 102 | 2 | 00102 | Sat Jan 03 00:00:00 1970 PST | 2 | 2 | foo (1 row) -- aggregate @@ -425,43 +425,43 @@ SELECT COUNT(*) FROM ft1 t1; -- subquery --Testcase 53: SELECT * FROM ft1 t1 WHERE t1.c3 IN (SELECT c3 FROM ft2 t2 WHERE c1 <= 10) ORDER BY c1; - c1 | c2 | c3 | time | c6 | c7 | c8 -----+----+-------+--------------------------+----+------------+----- - 1 | 1 | 00001 | Fri Jan 02 00:00:00 1970 | 1 | 1 | foo - 2 | 2 | 00002 | Sat Jan 03 00:00:00 1970 | 2 | 2 | foo - 3 | 3 | 00003 | Sun Jan 04 00:00:00 1970 | 3 | 3 | foo - 4 | 4 | 00004 | Mon Jan 05 00:00:00 1970 | 4 | 4 | foo - 5 | 5 | 00005 | Tue Jan 06 00:00:00 1970 | 5 | 5 | foo - 6 | 6 | 00006 | Wed Jan 07 00:00:00 1970 | 6 | 6 | foo - 7 | 7 | 00007 | Thu Jan 08 00:00:00 1970 | 7 | 7 | foo - 8 | 8 | 00008 | Fri Jan 09 00:00:00 1970 | 8 | 8 | foo - 9 | 9 | 00009 | Sat Jan 10 00:00:00 1970 | 9 | 9 | foo - 10 | 0 | 00010 | Sun Jan 11 00:00:00 1970 | 0 | 0 | foo + c1 | c2 | c3 | time | c6 | c7 | c8 +----+----+-------+------------------------------+----+------------+----- + 1 | 1 | 00001 | Fri Jan 02 00:00:00 1970 PST | 1 | 1 | foo + 2 | 2 | 00002 | Sat Jan 03 00:00:00 1970 PST | 2 | 2 | foo + 3 | 3 | 00003 | Sun Jan 04 00:00:00 1970 PST | 3 | 3 | foo + 4 | 4 | 00004 | Mon Jan 05 00:00:00 1970 PST | 4 | 4 | foo + 5 | 5 | 00005 | Tue Jan 06 00:00:00 1970 PST | 5 | 5 | foo + 6 | 6 | 00006 | Wed Jan 07 00:00:00 1970 PST | 6 | 6 | foo + 7 | 7 | 00007 | Thu Jan 08 00:00:00 1970 PST | 7 | 7 | foo + 8 | 8 | 00008 | Fri Jan 09 00:00:00 1970 PST | 8 | 8 | foo + 9 | 9 | 00009 | Sat Jan 10 00:00:00 1970 PST | 9 | 9 | foo + 10 | 0 | 00010 | Sun Jan 11 00:00:00 1970 PST | 0 | 0 | foo (10 rows) -- subquery+MAX --Testcase 54: SELECT * FROM ft1 t1 WHERE t1.c3 = (SELECT MAX(c3) FROM ft2 t2) ORDER BY c1; - c1 | c2 | c3 | time | c6 | c7 | c8 -------+----+-------+--------------------------+----+------------+----- - 1000 | 0 | 01000 | Thu Jan 01 00:00:00 1970 | 0 | 0 | foo + c1 | c2 | c3 | time | c6 | c7 | c8 +------+----+-------+------------------------------+----+------------+----- + 1000 | 0 | 01000 | Thu Jan 01 00:00:00 1970 PST | 0 | 0 | foo (1 row) -- used in CTE --Testcase 55: WITH t1 AS (SELECT * FROM ft1 WHERE c1 <= 10) SELECT t2.c1, t2.c2, t2.c3, t2.time FROM t1, ft2 t2 WHERE t1.c1 = t2.c1 ORDER BY t1.c1; - c1 | c2 | c3 | time -----+----+-------+-------------------------- - 1 | 1 | 00001 | Fri Jan 02 00:00:00 1970 - 2 | 2 | 00002 | Sat Jan 03 00:00:00 1970 - 3 | 3 | 00003 | Sun Jan 04 00:00:00 1970 - 4 | 4 | 00004 | Mon Jan 05 00:00:00 1970 - 5 | 5 | 00005 | Tue Jan 06 00:00:00 1970 - 6 | 6 | 00006 | Wed Jan 07 00:00:00 1970 - 7 | 7 | 00007 | Thu Jan 08 00:00:00 1970 - 8 | 8 | 00008 | Fri Jan 09 00:00:00 1970 - 9 | 9 | 00009 | Sat Jan 10 00:00:00 1970 - 10 | 0 | 00010 | Sun Jan 11 00:00:00 1970 + c1 | c2 | c3 | time +----+----+-------+------------------------------ + 1 | 1 | 00001 | Fri Jan 02 00:00:00 1970 PST + 2 | 2 | 00002 | Sat Jan 03 00:00:00 1970 PST + 3 | 3 | 00003 | Sun Jan 04 00:00:00 1970 PST + 4 | 4 | 00004 | Mon Jan 05 00:00:00 1970 PST + 5 | 5 | 00005 | Tue Jan 06 00:00:00 1970 PST + 6 | 6 | 00006 | Wed Jan 07 00:00:00 1970 PST + 7 | 7 | 00007 | Thu Jan 08 00:00:00 1970 PST + 8 | 8 | 00008 | Fri Jan 09 00:00:00 1970 PST + 9 | 9 | 00009 | Sat Jan 10 00:00:00 1970 PST + 10 | 0 | 00010 | Sun Jan 11 00:00:00 1970 PST (10 rows) -- fixed values @@ -878,9 +878,9 @@ EXPLAIN (VERBOSE, COSTS OFF) --Testcase 88: SELECT * FROM ft2 a, ft2 b WHERE a.c1 = 47 AND b.c1 = a.c2; - c1 | c2 | c3 | time | c6 | c7 | c8 | c1 | c2 | c3 | time | c6 | c7 | c8 -----+----+-------+--------------------------+----+------------+-----+----+----+-------+--------------------------+----+------------+----- - 47 | 7 | 00047 | Tue Feb 17 00:00:00 1970 | 7 | 7 | foo | 7 | 7 | 00007 | Thu Jan 08 00:00:00 1970 | 7 | 7 | foo + c1 | c2 | c3 | time | c6 | c7 | c8 | c1 | c2 | c3 | time | c6 | c7 | c8 +----+----+-------+------------------------------+----+------------+-----+----+----+-------+------------------------------+----+------------+----- + 47 | 7 | 00047 | Tue Feb 17 00:00:00 1970 PST | 7 | 7 | foo | 7 | 7 | 00007 | Thu Jan 08 00:00:00 1970 PST | 7 | 7 | foo (1 row) -- check both safe and unsafe join conditions @@ -906,129 +906,129 @@ EXPLAIN (VERBOSE, COSTS OFF) --Testcase 90: SELECT * FROM ft2 a, ft2 b WHERE a.c2 = 6 AND b.c1 = a.c1 AND a.c8 = 'foo' AND b.c7 = upper(a.c7) ORDER BY a.c1; - c1 | c2 | c3 | time | c6 | c7 | c8 | c1 | c2 | c3 | time | c6 | c7 | c8 ------+----+-------+--------------------------+----+------------+-----+-----+----+-------+--------------------------+----+------------+----- - 6 | 6 | 00006 | Wed Jan 07 00:00:00 1970 | 6 | 6 | foo | 6 | 6 | 00006 | Wed Jan 07 00:00:00 1970 | 6 | 6 | foo - 16 | 6 | 00016 | Sat Jan 17 00:00:00 1970 | 6 | 6 | foo | 16 | 6 | 00016 | Sat Jan 17 00:00:00 1970 | 6 | 6 | foo - 26 | 6 | 00026 | Tue Jan 27 00:00:00 1970 | 6 | 6 | foo | 26 | 6 | 00026 | Tue Jan 27 00:00:00 1970 | 6 | 6 | foo - 36 | 6 | 00036 | Fri Feb 06 00:00:00 1970 | 6 | 6 | foo | 36 | 6 | 00036 | Fri Feb 06 00:00:00 1970 | 6 | 6 | foo - 46 | 6 | 00046 | Mon Feb 16 00:00:00 1970 | 6 | 6 | foo | 46 | 6 | 00046 | Mon Feb 16 00:00:00 1970 | 6 | 6 | foo - 56 | 6 | 00056 | Thu Feb 26 00:00:00 1970 | 6 | 6 | foo | 56 | 6 | 00056 | Thu Feb 26 00:00:00 1970 | 6 | 6 | foo - 66 | 6 | 00066 | Sun Mar 08 00:00:00 1970 | 6 | 6 | foo | 66 | 6 | 00066 | Sun Mar 08 00:00:00 1970 | 6 | 6 | foo - 76 | 6 | 00076 | Wed Mar 18 00:00:00 1970 | 6 | 6 | foo | 76 | 6 | 00076 | Wed Mar 18 00:00:00 1970 | 6 | 6 | foo - 86 | 6 | 00086 | Sat Mar 28 00:00:00 1970 | 6 | 6 | foo | 86 | 6 | 00086 | Sat Mar 28 00:00:00 1970 | 6 | 6 | foo - 96 | 6 | 00096 | Tue Apr 07 00:00:00 1970 | 6 | 6 | foo | 96 | 6 | 00096 | Tue Apr 07 00:00:00 1970 | 6 | 6 | foo - 106 | 6 | 00106 | Wed Jan 07 00:00:00 1970 | 6 | 6 | foo | 106 | 6 | 00106 | Wed Jan 07 00:00:00 1970 | 6 | 6 | foo - 116 | 6 | 00116 | Sat Jan 17 00:00:00 1970 | 6 | 6 | foo | 116 | 6 | 00116 | Sat Jan 17 00:00:00 1970 | 6 | 6 | foo - 126 | 6 | 00126 | Tue Jan 27 00:00:00 1970 | 6 | 6 | foo | 126 | 6 | 00126 | Tue Jan 27 00:00:00 1970 | 6 | 6 | foo - 136 | 6 | 00136 | Fri Feb 06 00:00:00 1970 | 6 | 6 | foo | 136 | 6 | 00136 | Fri Feb 06 00:00:00 1970 | 6 | 6 | foo - 146 | 6 | 00146 | Mon Feb 16 00:00:00 1970 | 6 | 6 | foo | 146 | 6 | 00146 | Mon Feb 16 00:00:00 1970 | 6 | 6 | foo - 156 | 6 | 00156 | Thu Feb 26 00:00:00 1970 | 6 | 6 | foo | 156 | 6 | 00156 | Thu Feb 26 00:00:00 1970 | 6 | 6 | foo - 166 | 6 | 00166 | Sun Mar 08 00:00:00 1970 | 6 | 6 | foo | 166 | 6 | 00166 | Sun Mar 08 00:00:00 1970 | 6 | 6 | foo - 176 | 6 | 00176 | Wed Mar 18 00:00:00 1970 | 6 | 6 | foo | 176 | 6 | 00176 | Wed Mar 18 00:00:00 1970 | 6 | 6 | foo - 186 | 6 | 00186 | Sat Mar 28 00:00:00 1970 | 6 | 6 | foo | 186 | 6 | 00186 | Sat Mar 28 00:00:00 1970 | 6 | 6 | foo - 196 | 6 | 00196 | Tue Apr 07 00:00:00 1970 | 6 | 6 | foo | 196 | 6 | 00196 | Tue Apr 07 00:00:00 1970 | 6 | 6 | foo - 206 | 6 | 00206 | Wed Jan 07 00:00:00 1970 | 6 | 6 | foo | 206 | 6 | 00206 | Wed Jan 07 00:00:00 1970 | 6 | 6 | foo - 216 | 6 | 00216 | Sat Jan 17 00:00:00 1970 | 6 | 6 | foo | 216 | 6 | 00216 | Sat Jan 17 00:00:00 1970 | 6 | 6 | foo - 226 | 6 | 00226 | Tue Jan 27 00:00:00 1970 | 6 | 6 | foo | 226 | 6 | 00226 | Tue Jan 27 00:00:00 1970 | 6 | 6 | foo - 236 | 6 | 00236 | Fri Feb 06 00:00:00 1970 | 6 | 6 | foo | 236 | 6 | 00236 | Fri Feb 06 00:00:00 1970 | 6 | 6 | foo - 246 | 6 | 00246 | Mon Feb 16 00:00:00 1970 | 6 | 6 | foo | 246 | 6 | 00246 | Mon Feb 16 00:00:00 1970 | 6 | 6 | foo - 256 | 6 | 00256 | Thu Feb 26 00:00:00 1970 | 6 | 6 | foo | 256 | 6 | 00256 | Thu Feb 26 00:00:00 1970 | 6 | 6 | foo - 266 | 6 | 00266 | Sun Mar 08 00:00:00 1970 | 6 | 6 | foo | 266 | 6 | 00266 | Sun Mar 08 00:00:00 1970 | 6 | 6 | foo - 276 | 6 | 00276 | Wed Mar 18 00:00:00 1970 | 6 | 6 | foo | 276 | 6 | 00276 | Wed Mar 18 00:00:00 1970 | 6 | 6 | foo - 286 | 6 | 00286 | Sat Mar 28 00:00:00 1970 | 6 | 6 | foo | 286 | 6 | 00286 | Sat Mar 28 00:00:00 1970 | 6 | 6 | foo - 296 | 6 | 00296 | Tue Apr 07 00:00:00 1970 | 6 | 6 | foo | 296 | 6 | 00296 | Tue Apr 07 00:00:00 1970 | 6 | 6 | foo - 306 | 6 | 00306 | Wed Jan 07 00:00:00 1970 | 6 | 6 | foo | 306 | 6 | 00306 | Wed Jan 07 00:00:00 1970 | 6 | 6 | foo - 316 | 6 | 00316 | Sat Jan 17 00:00:00 1970 | 6 | 6 | foo | 316 | 6 | 00316 | Sat Jan 17 00:00:00 1970 | 6 | 6 | foo - 326 | 6 | 00326 | Tue Jan 27 00:00:00 1970 | 6 | 6 | foo | 326 | 6 | 00326 | Tue Jan 27 00:00:00 1970 | 6 | 6 | foo - 336 | 6 | 00336 | Fri Feb 06 00:00:00 1970 | 6 | 6 | foo | 336 | 6 | 00336 | Fri Feb 06 00:00:00 1970 | 6 | 6 | foo - 346 | 6 | 00346 | Mon Feb 16 00:00:00 1970 | 6 | 6 | foo | 346 | 6 | 00346 | Mon Feb 16 00:00:00 1970 | 6 | 6 | foo - 356 | 6 | 00356 | Thu Feb 26 00:00:00 1970 | 6 | 6 | foo | 356 | 6 | 00356 | Thu Feb 26 00:00:00 1970 | 6 | 6 | foo - 366 | 6 | 00366 | Sun Mar 08 00:00:00 1970 | 6 | 6 | foo | 366 | 6 | 00366 | Sun Mar 08 00:00:00 1970 | 6 | 6 | foo - 376 | 6 | 00376 | Wed Mar 18 00:00:00 1970 | 6 | 6 | foo | 376 | 6 | 00376 | Wed Mar 18 00:00:00 1970 | 6 | 6 | foo - 386 | 6 | 00386 | Sat Mar 28 00:00:00 1970 | 6 | 6 | foo | 386 | 6 | 00386 | Sat Mar 28 00:00:00 1970 | 6 | 6 | foo - 396 | 6 | 00396 | Tue Apr 07 00:00:00 1970 | 6 | 6 | foo | 396 | 6 | 00396 | Tue Apr 07 00:00:00 1970 | 6 | 6 | foo - 406 | 6 | 00406 | Wed Jan 07 00:00:00 1970 | 6 | 6 | foo | 406 | 6 | 00406 | Wed Jan 07 00:00:00 1970 | 6 | 6 | foo - 416 | 6 | 00416 | Sat Jan 17 00:00:00 1970 | 6 | 6 | foo | 416 | 6 | 00416 | Sat Jan 17 00:00:00 1970 | 6 | 6 | foo - 426 | 6 | 00426 | Tue Jan 27 00:00:00 1970 | 6 | 6 | foo | 426 | 6 | 00426 | Tue Jan 27 00:00:00 1970 | 6 | 6 | foo - 436 | 6 | 00436 | Fri Feb 06 00:00:00 1970 | 6 | 6 | foo | 436 | 6 | 00436 | Fri Feb 06 00:00:00 1970 | 6 | 6 | foo - 446 | 6 | 00446 | Mon Feb 16 00:00:00 1970 | 6 | 6 | foo | 446 | 6 | 00446 | Mon Feb 16 00:00:00 1970 | 6 | 6 | foo - 456 | 6 | 00456 | Thu Feb 26 00:00:00 1970 | 6 | 6 | foo | 456 | 6 | 00456 | Thu Feb 26 00:00:00 1970 | 6 | 6 | foo - 466 | 6 | 00466 | Sun Mar 08 00:00:00 1970 | 6 | 6 | foo | 466 | 6 | 00466 | Sun Mar 08 00:00:00 1970 | 6 | 6 | foo - 476 | 6 | 00476 | Wed Mar 18 00:00:00 1970 | 6 | 6 | foo | 476 | 6 | 00476 | Wed Mar 18 00:00:00 1970 | 6 | 6 | foo - 486 | 6 | 00486 | Sat Mar 28 00:00:00 1970 | 6 | 6 | foo | 486 | 6 | 00486 | Sat Mar 28 00:00:00 1970 | 6 | 6 | foo - 496 | 6 | 00496 | Tue Apr 07 00:00:00 1970 | 6 | 6 | foo | 496 | 6 | 00496 | Tue Apr 07 00:00:00 1970 | 6 | 6 | foo - 506 | 6 | 00506 | Wed Jan 07 00:00:00 1970 | 6 | 6 | foo | 506 | 6 | 00506 | Wed Jan 07 00:00:00 1970 | 6 | 6 | foo - 516 | 6 | 00516 | Sat Jan 17 00:00:00 1970 | 6 | 6 | foo | 516 | 6 | 00516 | Sat Jan 17 00:00:00 1970 | 6 | 6 | foo - 526 | 6 | 00526 | Tue Jan 27 00:00:00 1970 | 6 | 6 | foo | 526 | 6 | 00526 | Tue Jan 27 00:00:00 1970 | 6 | 6 | foo - 536 | 6 | 00536 | Fri Feb 06 00:00:00 1970 | 6 | 6 | foo | 536 | 6 | 00536 | Fri Feb 06 00:00:00 1970 | 6 | 6 | foo - 546 | 6 | 00546 | Mon Feb 16 00:00:00 1970 | 6 | 6 | foo | 546 | 6 | 00546 | Mon Feb 16 00:00:00 1970 | 6 | 6 | foo - 556 | 6 | 00556 | Thu Feb 26 00:00:00 1970 | 6 | 6 | foo | 556 | 6 | 00556 | Thu Feb 26 00:00:00 1970 | 6 | 6 | foo - 566 | 6 | 00566 | Sun Mar 08 00:00:00 1970 | 6 | 6 | foo | 566 | 6 | 00566 | Sun Mar 08 00:00:00 1970 | 6 | 6 | foo - 576 | 6 | 00576 | Wed Mar 18 00:00:00 1970 | 6 | 6 | foo | 576 | 6 | 00576 | Wed Mar 18 00:00:00 1970 | 6 | 6 | foo - 586 | 6 | 00586 | Sat Mar 28 00:00:00 1970 | 6 | 6 | foo | 586 | 6 | 00586 | Sat Mar 28 00:00:00 1970 | 6 | 6 | foo - 596 | 6 | 00596 | Tue Apr 07 00:00:00 1970 | 6 | 6 | foo | 596 | 6 | 00596 | Tue Apr 07 00:00:00 1970 | 6 | 6 | foo - 606 | 6 | 00606 | Wed Jan 07 00:00:00 1970 | 6 | 6 | foo | 606 | 6 | 00606 | Wed Jan 07 00:00:00 1970 | 6 | 6 | foo - 616 | 6 | 00616 | Sat Jan 17 00:00:00 1970 | 6 | 6 | foo | 616 | 6 | 00616 | Sat Jan 17 00:00:00 1970 | 6 | 6 | foo - 626 | 6 | 00626 | Tue Jan 27 00:00:00 1970 | 6 | 6 | foo | 626 | 6 | 00626 | Tue Jan 27 00:00:00 1970 | 6 | 6 | foo - 636 | 6 | 00636 | Fri Feb 06 00:00:00 1970 | 6 | 6 | foo | 636 | 6 | 00636 | Fri Feb 06 00:00:00 1970 | 6 | 6 | foo - 646 | 6 | 00646 | Mon Feb 16 00:00:00 1970 | 6 | 6 | foo | 646 | 6 | 00646 | Mon Feb 16 00:00:00 1970 | 6 | 6 | foo - 656 | 6 | 00656 | Thu Feb 26 00:00:00 1970 | 6 | 6 | foo | 656 | 6 | 00656 | Thu Feb 26 00:00:00 1970 | 6 | 6 | foo - 666 | 6 | 00666 | Sun Mar 08 00:00:00 1970 | 6 | 6 | foo | 666 | 6 | 00666 | Sun Mar 08 00:00:00 1970 | 6 | 6 | foo - 676 | 6 | 00676 | Wed Mar 18 00:00:00 1970 | 6 | 6 | foo | 676 | 6 | 00676 | Wed Mar 18 00:00:00 1970 | 6 | 6 | foo - 686 | 6 | 00686 | Sat Mar 28 00:00:00 1970 | 6 | 6 | foo | 686 | 6 | 00686 | Sat Mar 28 00:00:00 1970 | 6 | 6 | foo - 696 | 6 | 00696 | Tue Apr 07 00:00:00 1970 | 6 | 6 | foo | 696 | 6 | 00696 | Tue Apr 07 00:00:00 1970 | 6 | 6 | foo - 706 | 6 | 00706 | Wed Jan 07 00:00:00 1970 | 6 | 6 | foo | 706 | 6 | 00706 | Wed Jan 07 00:00:00 1970 | 6 | 6 | foo - 716 | 6 | 00716 | Sat Jan 17 00:00:00 1970 | 6 | 6 | foo | 716 | 6 | 00716 | Sat Jan 17 00:00:00 1970 | 6 | 6 | foo - 726 | 6 | 00726 | Tue Jan 27 00:00:00 1970 | 6 | 6 | foo | 726 | 6 | 00726 | Tue Jan 27 00:00:00 1970 | 6 | 6 | foo - 736 | 6 | 00736 | Fri Feb 06 00:00:00 1970 | 6 | 6 | foo | 736 | 6 | 00736 | Fri Feb 06 00:00:00 1970 | 6 | 6 | foo - 746 | 6 | 00746 | Mon Feb 16 00:00:00 1970 | 6 | 6 | foo | 746 | 6 | 00746 | Mon Feb 16 00:00:00 1970 | 6 | 6 | foo - 756 | 6 | 00756 | Thu Feb 26 00:00:00 1970 | 6 | 6 | foo | 756 | 6 | 00756 | Thu Feb 26 00:00:00 1970 | 6 | 6 | foo - 766 | 6 | 00766 | Sun Mar 08 00:00:00 1970 | 6 | 6 | foo | 766 | 6 | 00766 | Sun Mar 08 00:00:00 1970 | 6 | 6 | foo - 776 | 6 | 00776 | Wed Mar 18 00:00:00 1970 | 6 | 6 | foo | 776 | 6 | 00776 | Wed Mar 18 00:00:00 1970 | 6 | 6 | foo - 786 | 6 | 00786 | Sat Mar 28 00:00:00 1970 | 6 | 6 | foo | 786 | 6 | 00786 | Sat Mar 28 00:00:00 1970 | 6 | 6 | foo - 796 | 6 | 00796 | Tue Apr 07 00:00:00 1970 | 6 | 6 | foo | 796 | 6 | 00796 | Tue Apr 07 00:00:00 1970 | 6 | 6 | foo - 806 | 6 | 00806 | Wed Jan 07 00:00:00 1970 | 6 | 6 | foo | 806 | 6 | 00806 | Wed Jan 07 00:00:00 1970 | 6 | 6 | foo - 816 | 6 | 00816 | Sat Jan 17 00:00:00 1970 | 6 | 6 | foo | 816 | 6 | 00816 | Sat Jan 17 00:00:00 1970 | 6 | 6 | foo - 826 | 6 | 00826 | Tue Jan 27 00:00:00 1970 | 6 | 6 | foo | 826 | 6 | 00826 | Tue Jan 27 00:00:00 1970 | 6 | 6 | foo - 836 | 6 | 00836 | Fri Feb 06 00:00:00 1970 | 6 | 6 | foo | 836 | 6 | 00836 | Fri Feb 06 00:00:00 1970 | 6 | 6 | foo - 846 | 6 | 00846 | Mon Feb 16 00:00:00 1970 | 6 | 6 | foo | 846 | 6 | 00846 | Mon Feb 16 00:00:00 1970 | 6 | 6 | foo - 856 | 6 | 00856 | Thu Feb 26 00:00:00 1970 | 6 | 6 | foo | 856 | 6 | 00856 | Thu Feb 26 00:00:00 1970 | 6 | 6 | foo - 866 | 6 | 00866 | Sun Mar 08 00:00:00 1970 | 6 | 6 | foo | 866 | 6 | 00866 | Sun Mar 08 00:00:00 1970 | 6 | 6 | foo - 876 | 6 | 00876 | Wed Mar 18 00:00:00 1970 | 6 | 6 | foo | 876 | 6 | 00876 | Wed Mar 18 00:00:00 1970 | 6 | 6 | foo - 886 | 6 | 00886 | Sat Mar 28 00:00:00 1970 | 6 | 6 | foo | 886 | 6 | 00886 | Sat Mar 28 00:00:00 1970 | 6 | 6 | foo - 896 | 6 | 00896 | Tue Apr 07 00:00:00 1970 | 6 | 6 | foo | 896 | 6 | 00896 | Tue Apr 07 00:00:00 1970 | 6 | 6 | foo - 906 | 6 | 00906 | Wed Jan 07 00:00:00 1970 | 6 | 6 | foo | 906 | 6 | 00906 | Wed Jan 07 00:00:00 1970 | 6 | 6 | foo - 916 | 6 | 00916 | Sat Jan 17 00:00:00 1970 | 6 | 6 | foo | 916 | 6 | 00916 | Sat Jan 17 00:00:00 1970 | 6 | 6 | foo - 926 | 6 | 00926 | Tue Jan 27 00:00:00 1970 | 6 | 6 | foo | 926 | 6 | 00926 | Tue Jan 27 00:00:00 1970 | 6 | 6 | foo - 936 | 6 | 00936 | Fri Feb 06 00:00:00 1970 | 6 | 6 | foo | 936 | 6 | 00936 | Fri Feb 06 00:00:00 1970 | 6 | 6 | foo - 946 | 6 | 00946 | Mon Feb 16 00:00:00 1970 | 6 | 6 | foo | 946 | 6 | 00946 | Mon Feb 16 00:00:00 1970 | 6 | 6 | foo - 956 | 6 | 00956 | Thu Feb 26 00:00:00 1970 | 6 | 6 | foo | 956 | 6 | 00956 | Thu Feb 26 00:00:00 1970 | 6 | 6 | foo - 966 | 6 | 00966 | Sun Mar 08 00:00:00 1970 | 6 | 6 | foo | 966 | 6 | 00966 | Sun Mar 08 00:00:00 1970 | 6 | 6 | foo - 976 | 6 | 00976 | Wed Mar 18 00:00:00 1970 | 6 | 6 | foo | 976 | 6 | 00976 | Wed Mar 18 00:00:00 1970 | 6 | 6 | foo - 986 | 6 | 00986 | Sat Mar 28 00:00:00 1970 | 6 | 6 | foo | 986 | 6 | 00986 | Sat Mar 28 00:00:00 1970 | 6 | 6 | foo - 996 | 6 | 00996 | Tue Apr 07 00:00:00 1970 | 6 | 6 | foo | 996 | 6 | 00996 | Tue Apr 07 00:00:00 1970 | 6 | 6 | foo + c1 | c2 | c3 | time | c6 | c7 | c8 | c1 | c2 | c3 | time | c6 | c7 | c8 +-----+----+-------+------------------------------+----+------------+-----+-----+----+-------+------------------------------+----+------------+----- + 6 | 6 | 00006 | Wed Jan 07 00:00:00 1970 PST | 6 | 6 | foo | 6 | 6 | 00006 | Wed Jan 07 00:00:00 1970 PST | 6 | 6 | foo + 16 | 6 | 00016 | Sat Jan 17 00:00:00 1970 PST | 6 | 6 | foo | 16 | 6 | 00016 | Sat Jan 17 00:00:00 1970 PST | 6 | 6 | foo + 26 | 6 | 00026 | Tue Jan 27 00:00:00 1970 PST | 6 | 6 | foo | 26 | 6 | 00026 | Tue Jan 27 00:00:00 1970 PST | 6 | 6 | foo + 36 | 6 | 00036 | Fri Feb 06 00:00:00 1970 PST | 6 | 6 | foo | 36 | 6 | 00036 | Fri Feb 06 00:00:00 1970 PST | 6 | 6 | foo + 46 | 6 | 00046 | Mon Feb 16 00:00:00 1970 PST | 6 | 6 | foo | 46 | 6 | 00046 | Mon Feb 16 00:00:00 1970 PST | 6 | 6 | foo + 56 | 6 | 00056 | Thu Feb 26 00:00:00 1970 PST | 6 | 6 | foo | 56 | 6 | 00056 | Thu Feb 26 00:00:00 1970 PST | 6 | 6 | foo + 66 | 6 | 00066 | Sun Mar 08 00:00:00 1970 PST | 6 | 6 | foo | 66 | 6 | 00066 | Sun Mar 08 00:00:00 1970 PST | 6 | 6 | foo + 76 | 6 | 00076 | Wed Mar 18 00:00:00 1970 PST | 6 | 6 | foo | 76 | 6 | 00076 | Wed Mar 18 00:00:00 1970 PST | 6 | 6 | foo + 86 | 6 | 00086 | Sat Mar 28 00:00:00 1970 PST | 6 | 6 | foo | 86 | 6 | 00086 | Sat Mar 28 00:00:00 1970 PST | 6 | 6 | foo + 96 | 6 | 00096 | Tue Apr 07 00:00:00 1970 PST | 6 | 6 | foo | 96 | 6 | 00096 | Tue Apr 07 00:00:00 1970 PST | 6 | 6 | foo + 106 | 6 | 00106 | Wed Jan 07 00:00:00 1970 PST | 6 | 6 | foo | 106 | 6 | 00106 | Wed Jan 07 00:00:00 1970 PST | 6 | 6 | foo + 116 | 6 | 00116 | Sat Jan 17 00:00:00 1970 PST | 6 | 6 | foo | 116 | 6 | 00116 | Sat Jan 17 00:00:00 1970 PST | 6 | 6 | foo + 126 | 6 | 00126 | Tue Jan 27 00:00:00 1970 PST | 6 | 6 | foo | 126 | 6 | 00126 | Tue Jan 27 00:00:00 1970 PST | 6 | 6 | foo + 136 | 6 | 00136 | Fri Feb 06 00:00:00 1970 PST | 6 | 6 | foo | 136 | 6 | 00136 | Fri Feb 06 00:00:00 1970 PST | 6 | 6 | foo + 146 | 6 | 00146 | Mon Feb 16 00:00:00 1970 PST | 6 | 6 | foo | 146 | 6 | 00146 | Mon Feb 16 00:00:00 1970 PST | 6 | 6 | foo + 156 | 6 | 00156 | Thu Feb 26 00:00:00 1970 PST | 6 | 6 | foo | 156 | 6 | 00156 | Thu Feb 26 00:00:00 1970 PST | 6 | 6 | foo + 166 | 6 | 00166 | Sun Mar 08 00:00:00 1970 PST | 6 | 6 | foo | 166 | 6 | 00166 | Sun Mar 08 00:00:00 1970 PST | 6 | 6 | foo + 176 | 6 | 00176 | Wed Mar 18 00:00:00 1970 PST | 6 | 6 | foo | 176 | 6 | 00176 | Wed Mar 18 00:00:00 1970 PST | 6 | 6 | foo + 186 | 6 | 00186 | Sat Mar 28 00:00:00 1970 PST | 6 | 6 | foo | 186 | 6 | 00186 | Sat Mar 28 00:00:00 1970 PST | 6 | 6 | foo + 196 | 6 | 00196 | Tue Apr 07 00:00:00 1970 PST | 6 | 6 | foo | 196 | 6 | 00196 | Tue Apr 07 00:00:00 1970 PST | 6 | 6 | foo + 206 | 6 | 00206 | Wed Jan 07 00:00:00 1970 PST | 6 | 6 | foo | 206 | 6 | 00206 | Wed Jan 07 00:00:00 1970 PST | 6 | 6 | foo + 216 | 6 | 00216 | Sat Jan 17 00:00:00 1970 PST | 6 | 6 | foo | 216 | 6 | 00216 | Sat Jan 17 00:00:00 1970 PST | 6 | 6 | foo + 226 | 6 | 00226 | Tue Jan 27 00:00:00 1970 PST | 6 | 6 | foo | 226 | 6 | 00226 | Tue Jan 27 00:00:00 1970 PST | 6 | 6 | foo + 236 | 6 | 00236 | Fri Feb 06 00:00:00 1970 PST | 6 | 6 | foo | 236 | 6 | 00236 | Fri Feb 06 00:00:00 1970 PST | 6 | 6 | foo + 246 | 6 | 00246 | Mon Feb 16 00:00:00 1970 PST | 6 | 6 | foo | 246 | 6 | 00246 | Mon Feb 16 00:00:00 1970 PST | 6 | 6 | foo + 256 | 6 | 00256 | Thu Feb 26 00:00:00 1970 PST | 6 | 6 | foo | 256 | 6 | 00256 | Thu Feb 26 00:00:00 1970 PST | 6 | 6 | foo + 266 | 6 | 00266 | Sun Mar 08 00:00:00 1970 PST | 6 | 6 | foo | 266 | 6 | 00266 | Sun Mar 08 00:00:00 1970 PST | 6 | 6 | foo + 276 | 6 | 00276 | Wed Mar 18 00:00:00 1970 PST | 6 | 6 | foo | 276 | 6 | 00276 | Wed Mar 18 00:00:00 1970 PST | 6 | 6 | foo + 286 | 6 | 00286 | Sat Mar 28 00:00:00 1970 PST | 6 | 6 | foo | 286 | 6 | 00286 | Sat Mar 28 00:00:00 1970 PST | 6 | 6 | foo + 296 | 6 | 00296 | Tue Apr 07 00:00:00 1970 PST | 6 | 6 | foo | 296 | 6 | 00296 | Tue Apr 07 00:00:00 1970 PST | 6 | 6 | foo + 306 | 6 | 00306 | Wed Jan 07 00:00:00 1970 PST | 6 | 6 | foo | 306 | 6 | 00306 | Wed Jan 07 00:00:00 1970 PST | 6 | 6 | foo + 316 | 6 | 00316 | Sat Jan 17 00:00:00 1970 PST | 6 | 6 | foo | 316 | 6 | 00316 | Sat Jan 17 00:00:00 1970 PST | 6 | 6 | foo + 326 | 6 | 00326 | Tue Jan 27 00:00:00 1970 PST | 6 | 6 | foo | 326 | 6 | 00326 | Tue Jan 27 00:00:00 1970 PST | 6 | 6 | foo + 336 | 6 | 00336 | Fri Feb 06 00:00:00 1970 PST | 6 | 6 | foo | 336 | 6 | 00336 | Fri Feb 06 00:00:00 1970 PST | 6 | 6 | foo + 346 | 6 | 00346 | Mon Feb 16 00:00:00 1970 PST | 6 | 6 | foo | 346 | 6 | 00346 | Mon Feb 16 00:00:00 1970 PST | 6 | 6 | foo + 356 | 6 | 00356 | Thu Feb 26 00:00:00 1970 PST | 6 | 6 | foo | 356 | 6 | 00356 | Thu Feb 26 00:00:00 1970 PST | 6 | 6 | foo + 366 | 6 | 00366 | Sun Mar 08 00:00:00 1970 PST | 6 | 6 | foo | 366 | 6 | 00366 | Sun Mar 08 00:00:00 1970 PST | 6 | 6 | foo + 376 | 6 | 00376 | Wed Mar 18 00:00:00 1970 PST | 6 | 6 | foo | 376 | 6 | 00376 | Wed Mar 18 00:00:00 1970 PST | 6 | 6 | foo + 386 | 6 | 00386 | Sat Mar 28 00:00:00 1970 PST | 6 | 6 | foo | 386 | 6 | 00386 | Sat Mar 28 00:00:00 1970 PST | 6 | 6 | foo + 396 | 6 | 00396 | Tue Apr 07 00:00:00 1970 PST | 6 | 6 | foo | 396 | 6 | 00396 | Tue Apr 07 00:00:00 1970 PST | 6 | 6 | foo + 406 | 6 | 00406 | Wed Jan 07 00:00:00 1970 PST | 6 | 6 | foo | 406 | 6 | 00406 | Wed Jan 07 00:00:00 1970 PST | 6 | 6 | foo + 416 | 6 | 00416 | Sat Jan 17 00:00:00 1970 PST | 6 | 6 | foo | 416 | 6 | 00416 | Sat Jan 17 00:00:00 1970 PST | 6 | 6 | foo + 426 | 6 | 00426 | Tue Jan 27 00:00:00 1970 PST | 6 | 6 | foo | 426 | 6 | 00426 | Tue Jan 27 00:00:00 1970 PST | 6 | 6 | foo + 436 | 6 | 00436 | Fri Feb 06 00:00:00 1970 PST | 6 | 6 | foo | 436 | 6 | 00436 | Fri Feb 06 00:00:00 1970 PST | 6 | 6 | foo + 446 | 6 | 00446 | Mon Feb 16 00:00:00 1970 PST | 6 | 6 | foo | 446 | 6 | 00446 | Mon Feb 16 00:00:00 1970 PST | 6 | 6 | foo + 456 | 6 | 00456 | Thu Feb 26 00:00:00 1970 PST | 6 | 6 | foo | 456 | 6 | 00456 | Thu Feb 26 00:00:00 1970 PST | 6 | 6 | foo + 466 | 6 | 00466 | Sun Mar 08 00:00:00 1970 PST | 6 | 6 | foo | 466 | 6 | 00466 | Sun Mar 08 00:00:00 1970 PST | 6 | 6 | foo + 476 | 6 | 00476 | Wed Mar 18 00:00:00 1970 PST | 6 | 6 | foo | 476 | 6 | 00476 | Wed Mar 18 00:00:00 1970 PST | 6 | 6 | foo + 486 | 6 | 00486 | Sat Mar 28 00:00:00 1970 PST | 6 | 6 | foo | 486 | 6 | 00486 | Sat Mar 28 00:00:00 1970 PST | 6 | 6 | foo + 496 | 6 | 00496 | Tue Apr 07 00:00:00 1970 PST | 6 | 6 | foo | 496 | 6 | 00496 | Tue Apr 07 00:00:00 1970 PST | 6 | 6 | foo + 506 | 6 | 00506 | Wed Jan 07 00:00:00 1970 PST | 6 | 6 | foo | 506 | 6 | 00506 | Wed Jan 07 00:00:00 1970 PST | 6 | 6 | foo + 516 | 6 | 00516 | Sat Jan 17 00:00:00 1970 PST | 6 | 6 | foo | 516 | 6 | 00516 | Sat Jan 17 00:00:00 1970 PST | 6 | 6 | foo + 526 | 6 | 00526 | Tue Jan 27 00:00:00 1970 PST | 6 | 6 | foo | 526 | 6 | 00526 | Tue Jan 27 00:00:00 1970 PST | 6 | 6 | foo + 536 | 6 | 00536 | Fri Feb 06 00:00:00 1970 PST | 6 | 6 | foo | 536 | 6 | 00536 | Fri Feb 06 00:00:00 1970 PST | 6 | 6 | foo + 546 | 6 | 00546 | Mon Feb 16 00:00:00 1970 PST | 6 | 6 | foo | 546 | 6 | 00546 | Mon Feb 16 00:00:00 1970 PST | 6 | 6 | foo + 556 | 6 | 00556 | Thu Feb 26 00:00:00 1970 PST | 6 | 6 | foo | 556 | 6 | 00556 | Thu Feb 26 00:00:00 1970 PST | 6 | 6 | foo + 566 | 6 | 00566 | Sun Mar 08 00:00:00 1970 PST | 6 | 6 | foo | 566 | 6 | 00566 | Sun Mar 08 00:00:00 1970 PST | 6 | 6 | foo + 576 | 6 | 00576 | Wed Mar 18 00:00:00 1970 PST | 6 | 6 | foo | 576 | 6 | 00576 | Wed Mar 18 00:00:00 1970 PST | 6 | 6 | foo + 586 | 6 | 00586 | Sat Mar 28 00:00:00 1970 PST | 6 | 6 | foo | 586 | 6 | 00586 | Sat Mar 28 00:00:00 1970 PST | 6 | 6 | foo + 596 | 6 | 00596 | Tue Apr 07 00:00:00 1970 PST | 6 | 6 | foo | 596 | 6 | 00596 | Tue Apr 07 00:00:00 1970 PST | 6 | 6 | foo + 606 | 6 | 00606 | Wed Jan 07 00:00:00 1970 PST | 6 | 6 | foo | 606 | 6 | 00606 | Wed Jan 07 00:00:00 1970 PST | 6 | 6 | foo + 616 | 6 | 00616 | Sat Jan 17 00:00:00 1970 PST | 6 | 6 | foo | 616 | 6 | 00616 | Sat Jan 17 00:00:00 1970 PST | 6 | 6 | foo + 626 | 6 | 00626 | Tue Jan 27 00:00:00 1970 PST | 6 | 6 | foo | 626 | 6 | 00626 | Tue Jan 27 00:00:00 1970 PST | 6 | 6 | foo + 636 | 6 | 00636 | Fri Feb 06 00:00:00 1970 PST | 6 | 6 | foo | 636 | 6 | 00636 | Fri Feb 06 00:00:00 1970 PST | 6 | 6 | foo + 646 | 6 | 00646 | Mon Feb 16 00:00:00 1970 PST | 6 | 6 | foo | 646 | 6 | 00646 | Mon Feb 16 00:00:00 1970 PST | 6 | 6 | foo + 656 | 6 | 00656 | Thu Feb 26 00:00:00 1970 PST | 6 | 6 | foo | 656 | 6 | 00656 | Thu Feb 26 00:00:00 1970 PST | 6 | 6 | foo + 666 | 6 | 00666 | Sun Mar 08 00:00:00 1970 PST | 6 | 6 | foo | 666 | 6 | 00666 | Sun Mar 08 00:00:00 1970 PST | 6 | 6 | foo + 676 | 6 | 00676 | Wed Mar 18 00:00:00 1970 PST | 6 | 6 | foo | 676 | 6 | 00676 | Wed Mar 18 00:00:00 1970 PST | 6 | 6 | foo + 686 | 6 | 00686 | Sat Mar 28 00:00:00 1970 PST | 6 | 6 | foo | 686 | 6 | 00686 | Sat Mar 28 00:00:00 1970 PST | 6 | 6 | foo + 696 | 6 | 00696 | Tue Apr 07 00:00:00 1970 PST | 6 | 6 | foo | 696 | 6 | 00696 | Tue Apr 07 00:00:00 1970 PST | 6 | 6 | foo + 706 | 6 | 00706 | Wed Jan 07 00:00:00 1970 PST | 6 | 6 | foo | 706 | 6 | 00706 | Wed Jan 07 00:00:00 1970 PST | 6 | 6 | foo + 716 | 6 | 00716 | Sat Jan 17 00:00:00 1970 PST | 6 | 6 | foo | 716 | 6 | 00716 | Sat Jan 17 00:00:00 1970 PST | 6 | 6 | foo + 726 | 6 | 00726 | Tue Jan 27 00:00:00 1970 PST | 6 | 6 | foo | 726 | 6 | 00726 | Tue Jan 27 00:00:00 1970 PST | 6 | 6 | foo + 736 | 6 | 00736 | Fri Feb 06 00:00:00 1970 PST | 6 | 6 | foo | 736 | 6 | 00736 | Fri Feb 06 00:00:00 1970 PST | 6 | 6 | foo + 746 | 6 | 00746 | Mon Feb 16 00:00:00 1970 PST | 6 | 6 | foo | 746 | 6 | 00746 | Mon Feb 16 00:00:00 1970 PST | 6 | 6 | foo + 756 | 6 | 00756 | Thu Feb 26 00:00:00 1970 PST | 6 | 6 | foo | 756 | 6 | 00756 | Thu Feb 26 00:00:00 1970 PST | 6 | 6 | foo + 766 | 6 | 00766 | Sun Mar 08 00:00:00 1970 PST | 6 | 6 | foo | 766 | 6 | 00766 | Sun Mar 08 00:00:00 1970 PST | 6 | 6 | foo + 776 | 6 | 00776 | Wed Mar 18 00:00:00 1970 PST | 6 | 6 | foo | 776 | 6 | 00776 | Wed Mar 18 00:00:00 1970 PST | 6 | 6 | foo + 786 | 6 | 00786 | Sat Mar 28 00:00:00 1970 PST | 6 | 6 | foo | 786 | 6 | 00786 | Sat Mar 28 00:00:00 1970 PST | 6 | 6 | foo + 796 | 6 | 00796 | Tue Apr 07 00:00:00 1970 PST | 6 | 6 | foo | 796 | 6 | 00796 | Tue Apr 07 00:00:00 1970 PST | 6 | 6 | foo + 806 | 6 | 00806 | Wed Jan 07 00:00:00 1970 PST | 6 | 6 | foo | 806 | 6 | 00806 | Wed Jan 07 00:00:00 1970 PST | 6 | 6 | foo + 816 | 6 | 00816 | Sat Jan 17 00:00:00 1970 PST | 6 | 6 | foo | 816 | 6 | 00816 | Sat Jan 17 00:00:00 1970 PST | 6 | 6 | foo + 826 | 6 | 00826 | Tue Jan 27 00:00:00 1970 PST | 6 | 6 | foo | 826 | 6 | 00826 | Tue Jan 27 00:00:00 1970 PST | 6 | 6 | foo + 836 | 6 | 00836 | Fri Feb 06 00:00:00 1970 PST | 6 | 6 | foo | 836 | 6 | 00836 | Fri Feb 06 00:00:00 1970 PST | 6 | 6 | foo + 846 | 6 | 00846 | Mon Feb 16 00:00:00 1970 PST | 6 | 6 | foo | 846 | 6 | 00846 | Mon Feb 16 00:00:00 1970 PST | 6 | 6 | foo + 856 | 6 | 00856 | Thu Feb 26 00:00:00 1970 PST | 6 | 6 | foo | 856 | 6 | 00856 | Thu Feb 26 00:00:00 1970 PST | 6 | 6 | foo + 866 | 6 | 00866 | Sun Mar 08 00:00:00 1970 PST | 6 | 6 | foo | 866 | 6 | 00866 | Sun Mar 08 00:00:00 1970 PST | 6 | 6 | foo + 876 | 6 | 00876 | Wed Mar 18 00:00:00 1970 PST | 6 | 6 | foo | 876 | 6 | 00876 | Wed Mar 18 00:00:00 1970 PST | 6 | 6 | foo + 886 | 6 | 00886 | Sat Mar 28 00:00:00 1970 PST | 6 | 6 | foo | 886 | 6 | 00886 | Sat Mar 28 00:00:00 1970 PST | 6 | 6 | foo + 896 | 6 | 00896 | Tue Apr 07 00:00:00 1970 PST | 6 | 6 | foo | 896 | 6 | 00896 | Tue Apr 07 00:00:00 1970 PST | 6 | 6 | foo + 906 | 6 | 00906 | Wed Jan 07 00:00:00 1970 PST | 6 | 6 | foo | 906 | 6 | 00906 | Wed Jan 07 00:00:00 1970 PST | 6 | 6 | foo + 916 | 6 | 00916 | Sat Jan 17 00:00:00 1970 PST | 6 | 6 | foo | 916 | 6 | 00916 | Sat Jan 17 00:00:00 1970 PST | 6 | 6 | foo + 926 | 6 | 00926 | Tue Jan 27 00:00:00 1970 PST | 6 | 6 | foo | 926 | 6 | 00926 | Tue Jan 27 00:00:00 1970 PST | 6 | 6 | foo + 936 | 6 | 00936 | Fri Feb 06 00:00:00 1970 PST | 6 | 6 | foo | 936 | 6 | 00936 | Fri Feb 06 00:00:00 1970 PST | 6 | 6 | foo + 946 | 6 | 00946 | Mon Feb 16 00:00:00 1970 PST | 6 | 6 | foo | 946 | 6 | 00946 | Mon Feb 16 00:00:00 1970 PST | 6 | 6 | foo + 956 | 6 | 00956 | Thu Feb 26 00:00:00 1970 PST | 6 | 6 | foo | 956 | 6 | 00956 | Thu Feb 26 00:00:00 1970 PST | 6 | 6 | foo + 966 | 6 | 00966 | Sun Mar 08 00:00:00 1970 PST | 6 | 6 | foo | 966 | 6 | 00966 | Sun Mar 08 00:00:00 1970 PST | 6 | 6 | foo + 976 | 6 | 00976 | Wed Mar 18 00:00:00 1970 PST | 6 | 6 | foo | 976 | 6 | 00976 | Wed Mar 18 00:00:00 1970 PST | 6 | 6 | foo + 986 | 6 | 00986 | Sat Mar 28 00:00:00 1970 PST | 6 | 6 | foo | 986 | 6 | 00986 | Sat Mar 28 00:00:00 1970 PST | 6 | 6 | foo + 996 | 6 | 00996 | Tue Apr 07 00:00:00 1970 PST | 6 | 6 | foo | 996 | 6 | 00996 | Tue Apr 07 00:00:00 1970 PST | 6 | 6 | foo (100 rows) -- bug before 9.3.5 due to sloppy handling of remote-estimate parameters --Testcase 91: SELECT * FROM ft1 WHERE c1 = ANY (ARRAY(SELECT c1 FROM ft2 WHERE c1 < 5)); - c1 | c2 | c3 | time | c6 | c7 | c8 -----+----+-------+--------------------------+----+------------+----- - 1 | 1 | 00001 | Fri Jan 02 00:00:00 1970 | 1 | 1 | foo - 2 | 2 | 00002 | Sat Jan 03 00:00:00 1970 | 2 | 2 | foo - 3 | 3 | 00003 | Sun Jan 04 00:00:00 1970 | 3 | 3 | foo - 4 | 4 | 00004 | Mon Jan 05 00:00:00 1970 | 4 | 4 | foo + c1 | c2 | c3 | time | c6 | c7 | c8 +----+----+-------+------------------------------+----+------------+----- + 1 | 1 | 00001 | Fri Jan 02 00:00:00 1970 PST | 1 | 1 | foo + 2 | 2 | 00002 | Sat Jan 03 00:00:00 1970 PST | 2 | 2 | foo + 3 | 3 | 00003 | Sun Jan 04 00:00:00 1970 PST | 3 | 3 | foo + 4 | 4 | 00004 | Mon Jan 05 00:00:00 1970 PST | 4 | 4 | foo (4 rows) --Testcase 92: SELECT * FROM ft2 WHERE c1 = ANY (ARRAY(SELECT c1 FROM ft1 WHERE c1 < 5)); - c1 | c2 | c3 | time | c6 | c7 | c8 -----+----+-------+--------------------------+----+------------+----- - 1 | 1 | 00001 | Fri Jan 02 00:00:00 1970 | 1 | 1 | foo - 2 | 2 | 00002 | Sat Jan 03 00:00:00 1970 | 2 | 2 | foo - 3 | 3 | 00003 | Sun Jan 04 00:00:00 1970 | 3 | 3 | foo - 4 | 4 | 00004 | Mon Jan 05 00:00:00 1970 | 4 | 4 | foo + c1 | c2 | c3 | time | c6 | c7 | c8 +----+----+-------+------------------------------+----+------------+----- + 1 | 1 | 00001 | Fri Jan 02 00:00:00 1970 PST | 1 | 1 | foo + 2 | 2 | 00002 | Sat Jan 03 00:00:00 1970 PST | 2 | 2 | foo + 3 | 3 | 00003 | Sun Jan 04 00:00:00 1970 PST | 3 | 3 | foo + 4 | 4 | 00004 | Mon Jan 05 00:00:00 1970 PST | 4 | 4 | foo (4 rows) -- we should not push order by clause with volatile expressions or unsafe @@ -1172,9 +1172,9 @@ EXPLAIN (VERBOSE, COSTS OFF) --Testcase 106: SELECT * FROM ft1 t1 WHERE t1.c1 === t1.c2 order by t1.c2 limit 1; - c1 | c2 | c3 | time | c6 | c7 | c8 -----+----+-------+--------------------------+----+------------+----- - 1 | 1 | 00001 | Fri Jan 02 00:00:00 1970 | 1 | 1 | foo + c1 | c2 | c3 | time | c6 | c7 | c8 +----+----+-------+------------------------------+----+------------+----- + 1 | 1 | 00001 | Fri Jan 02 00:00:00 1970 PST | 1 | 1 | foo (1 row) -- but let's put them in an extension ... @@ -1243,9 +1243,9 @@ EXPLAIN (VERBOSE, COSTS OFF) --Testcase 114: SELECT * FROM ft1 t1 WHERE t1.c1 === t1.c2 order by t1.c2 limit 1; - c1 | c2 | c3 | time | c6 | c7 | c8 -----+----+-------+--------------------------+----+------------+----- - 1 | 1 | 00001 | Fri Jan 02 00:00:00 1970 | 1 | 1 | foo + c1 | c2 | c3 | time | c6 | c7 | c8 +----+----+-------+------------------------------+----+------------+----- + 1 | 1 | 00001 | Fri Jan 02 00:00:00 1970 PST | 1 | 1 | foo (1 row) -- Test CASE pushdown @@ -3237,18 +3237,18 @@ SELECT * FROM ft1, ft2, ft4, ft5, local_tbl WHERE ft1.c1 = ft2.c1 AND ft1.c2 = f --Testcase 204: SELECT * FROM ft1, ft2, ft4, ft5, local_tbl WHERE ft1.c1 = ft2.c1 AND ft1.c2 = ft4.c1 AND ft1.c2 = ft5.c1 AND ft1.c2 = local_tbl.c1 AND ft1.c1 < 100 AND ft2.c1 < 100 ORDER BY ft1.c1 FOR UPDATE; - c1 | c2 | c3 | time | c6 | c7 | c8 | c1 | c2 | c3 | time | c6 | c7 | c8 | c1 | c2 | c3 | c1 | c2 | c3 | c1 | c2 | c3 -----+----+-------+--------------------------+----+------------+-----+----+----+-------+--------------------------+----+------------+-----+----+----+--------+----+----+--------+----+----+------ - 6 | 6 | 00006 | Wed Jan 07 00:00:00 1970 | 6 | 6 | foo | 6 | 6 | 00006 | Wed Jan 07 00:00:00 1970 | 6 | 6 | foo | 6 | 7 | AAA006 | 6 | 7 | AAA006 | 6 | 6 | 0006 - 16 | 6 | 00016 | Sat Jan 17 00:00:00 1970 | 6 | 6 | foo | 16 | 6 | 00016 | Sat Jan 17 00:00:00 1970 | 6 | 6 | foo | 6 | 7 | AAA006 | 6 | 7 | AAA006 | 6 | 6 | 0006 - 26 | 6 | 00026 | Tue Jan 27 00:00:00 1970 | 6 | 6 | foo | 26 | 6 | 00026 | Tue Jan 27 00:00:00 1970 | 6 | 6 | foo | 6 | 7 | AAA006 | 6 | 7 | AAA006 | 6 | 6 | 0006 - 36 | 6 | 00036 | Fri Feb 06 00:00:00 1970 | 6 | 6 | foo | 36 | 6 | 00036 | Fri Feb 06 00:00:00 1970 | 6 | 6 | foo | 6 | 7 | AAA006 | 6 | 7 | AAA006 | 6 | 6 | 0006 - 46 | 6 | 00046 | Mon Feb 16 00:00:00 1970 | 6 | 6 | foo | 46 | 6 | 00046 | Mon Feb 16 00:00:00 1970 | 6 | 6 | foo | 6 | 7 | AAA006 | 6 | 7 | AAA006 | 6 | 6 | 0006 - 56 | 6 | 00056 | Thu Feb 26 00:00:00 1970 | 6 | 6 | foo | 56 | 6 | 00056 | Thu Feb 26 00:00:00 1970 | 6 | 6 | foo | 6 | 7 | AAA006 | 6 | 7 | AAA006 | 6 | 6 | 0006 - 66 | 6 | 00066 | Sun Mar 08 00:00:00 1970 | 6 | 6 | foo | 66 | 6 | 00066 | Sun Mar 08 00:00:00 1970 | 6 | 6 | foo | 6 | 7 | AAA006 | 6 | 7 | AAA006 | 6 | 6 | 0006 - 76 | 6 | 00076 | Wed Mar 18 00:00:00 1970 | 6 | 6 | foo | 76 | 6 | 00076 | Wed Mar 18 00:00:00 1970 | 6 | 6 | foo | 6 | 7 | AAA006 | 6 | 7 | AAA006 | 6 | 6 | 0006 - 86 | 6 | 00086 | Sat Mar 28 00:00:00 1970 | 6 | 6 | foo | 86 | 6 | 00086 | Sat Mar 28 00:00:00 1970 | 6 | 6 | foo | 6 | 7 | AAA006 | 6 | 7 | AAA006 | 6 | 6 | 0006 - 96 | 6 | 00096 | Tue Apr 07 00:00:00 1970 | 6 | 6 | foo | 96 | 6 | 00096 | Tue Apr 07 00:00:00 1970 | 6 | 6 | foo | 6 | 7 | AAA006 | 6 | 7 | AAA006 | 6 | 6 | 0006 + c1 | c2 | c3 | time | c6 | c7 | c8 | c1 | c2 | c3 | time | c6 | c7 | c8 | c1 | c2 | c3 | c1 | c2 | c3 | c1 | c2 | c3 +----+----+-------+------------------------------+----+------------+-----+----+----+-------+------------------------------+----+------------+-----+----+----+--------+----+----+--------+----+----+------ + 6 | 6 | 00006 | Wed Jan 07 00:00:00 1970 PST | 6 | 6 | foo | 6 | 6 | 00006 | Wed Jan 07 00:00:00 1970 PST | 6 | 6 | foo | 6 | 7 | AAA006 | 6 | 7 | AAA006 | 6 | 6 | 0006 + 16 | 6 | 00016 | Sat Jan 17 00:00:00 1970 PST | 6 | 6 | foo | 16 | 6 | 00016 | Sat Jan 17 00:00:00 1970 PST | 6 | 6 | foo | 6 | 7 | AAA006 | 6 | 7 | AAA006 | 6 | 6 | 0006 + 26 | 6 | 00026 | Tue Jan 27 00:00:00 1970 PST | 6 | 6 | foo | 26 | 6 | 00026 | Tue Jan 27 00:00:00 1970 PST | 6 | 6 | foo | 6 | 7 | AAA006 | 6 | 7 | AAA006 | 6 | 6 | 0006 + 36 | 6 | 00036 | Fri Feb 06 00:00:00 1970 PST | 6 | 6 | foo | 36 | 6 | 00036 | Fri Feb 06 00:00:00 1970 PST | 6 | 6 | foo | 6 | 7 | AAA006 | 6 | 7 | AAA006 | 6 | 6 | 0006 + 46 | 6 | 00046 | Mon Feb 16 00:00:00 1970 PST | 6 | 6 | foo | 46 | 6 | 00046 | Mon Feb 16 00:00:00 1970 PST | 6 | 6 | foo | 6 | 7 | AAA006 | 6 | 7 | AAA006 | 6 | 6 | 0006 + 56 | 6 | 00056 | Thu Feb 26 00:00:00 1970 PST | 6 | 6 | foo | 56 | 6 | 00056 | Thu Feb 26 00:00:00 1970 PST | 6 | 6 | foo | 6 | 7 | AAA006 | 6 | 7 | AAA006 | 6 | 6 | 0006 + 66 | 6 | 00066 | Sun Mar 08 00:00:00 1970 PST | 6 | 6 | foo | 66 | 6 | 00066 | Sun Mar 08 00:00:00 1970 PST | 6 | 6 | foo | 6 | 7 | AAA006 | 6 | 7 | AAA006 | 6 | 6 | 0006 + 76 | 6 | 00076 | Wed Mar 18 00:00:00 1970 PST | 6 | 6 | foo | 76 | 6 | 00076 | Wed Mar 18 00:00:00 1970 PST | 6 | 6 | foo | 6 | 7 | AAA006 | 6 | 7 | AAA006 | 6 | 6 | 0006 + 86 | 6 | 00086 | Sat Mar 28 00:00:00 1970 PST | 6 | 6 | foo | 86 | 6 | 00086 | Sat Mar 28 00:00:00 1970 PST | 6 | 6 | foo | 6 | 7 | AAA006 | 6 | 7 | AAA006 | 6 | 6 | 0006 + 96 | 6 | 00096 | Tue Apr 07 00:00:00 1970 PST | 6 | 6 | foo | 96 | 6 | 00096 | Tue Apr 07 00:00:00 1970 PST | 6 | 6 | foo | 6 | 7 | AAA006 | 6 | 7 | AAA006 | 6 | 6 | 0006 (10 rows) --Testcase 205: @@ -3985,9 +3985,9 @@ select array_agg(time order by c1 desc) from ft2 where c2 = 6 and c1 < 50; --Testcase 257: select array_agg(time order by c1 desc) from ft2 where c2 = 6 and c1 < 50; - array_agg ------------------------------------------------------------------------------------------------------------------------------------------- - {"Mon Feb 16 00:00:00 1970","Fri Feb 06 00:00:00 1970","Tue Jan 27 00:00:00 1970","Sat Jan 17 00:00:00 1970","Wed Jan 07 00:00:00 1970"} + array_agg +-------------------------------------------------------------------------------------------------------------------------------------------------------------- + {"Mon Feb 16 00:00:00 1970 PST","Fri Feb 06 00:00:00 1970 PST","Tue Jan 27 00:00:00 1970 PST","Sat Jan 17 00:00:00 1970 PST","Wed Jan 07 00:00:00 1970 PST"} (1 row) -- DISTINCT within aggregate @@ -5177,16 +5177,16 @@ EXPLAIN (VERBOSE, COSTS OFF) EXECUTE st2(10, 20); --Testcase 359: EXECUTE st2(10, 20); - c1 | c2 | c3 | time | c6 | c7 | c8 -----+----+-------+--------------------------+----+------------+----- - 16 | 6 | 00016 | Sat Jan 17 00:00:00 1970 | 6 | 6 | foo + c1 | c2 | c3 | time | c6 | c7 | c8 +----+----+-------+------------------------------+----+------------+----- + 16 | 6 | 00016 | Sat Jan 17 00:00:00 1970 PST | 6 | 6 | foo (1 row) --Testcase 360: EXECUTE st2(101, 121); - c1 | c2 | c3 | time | c6 | c7 | c8 ------+----+-------+--------------------------+----+------------+----- - 116 | 6 | 00116 | Sat Jan 17 00:00:00 1970 | 6 | 6 | foo + c1 | c2 | c3 | time | c6 | c7 | c8 +-----+----+-------+------------------------------+----+------------+----- + 116 | 6 | 00116 | Sat Jan 17 00:00:00 1970 PST | 6 | 6 | foo (1 row) -- subquery using immutable function (can be sent to remote) @@ -5215,9 +5215,9 @@ EXPLAIN (VERBOSE, COSTS OFF) EXECUTE st3(10, 20); --Testcase 363: EXECUTE st3(10, 20); - c1 | c2 | c3 | time | c6 | c7 | c8 -----+----+-------+--------------------------+----+------------+----- - 16 | 6 | 00016 | Sat Jan 17 00:00:00 1970 | 6 | 6 | foo + c1 | c2 | c3 | time | c6 | c7 | c8 +----+----+-------+------------------------------+----+------------+----- + 16 | 6 | 00016 | Sat Jan 17 00:00:00 1970 PST | 6 | 6 | foo (1 row) --Testcase 364: @@ -5343,9 +5343,9 @@ EXPLAIN (VERBOSE, COSTS OFF) EXECUTE st5('foo', 1); --Testcase 379: EXECUTE st5('foo', 1); - c1 | c2 | c3 | time | c6 | c7 | c8 -----+----+-------+--------------------------+----+------------+----- - 1 | 1 | 00001 | Fri Jan 02 00:00:00 1970 | 1 | 1 | foo + c1 | c2 | c3 | time | c6 | c7 | c8 +----+----+-------+------------------------------+----+------------+----- + 1 | 1 | 00001 | Fri Jan 02 00:00:00 1970 PST | 1 | 1 | foo (1 row) -- altering FDW options requires replanning @@ -5364,12 +5364,12 @@ EXPLAIN (VERBOSE, COSTS OFF) EXECUTE st6; PREPARE st7 AS INSERT INTO ft1 (c1,c2,c3) VALUES (1001,101,'foo'); --Testcase 383: EXPLAIN (VERBOSE, COSTS OFF) EXECUTE st7; - QUERY PLAN ------------------------------------------------------------------------------------------------------------------------------------------------------------- + QUERY PLAN +--------------------------------------------------------------------------------------------------------------------------------------------------------- Insert on public.ft1 Batch Size: 1 -> Result - Output: NULL::integer, 1001, 101, 'foo'::text, NULL::timestamp without time zone, NULL::character varying, 'ft1 '::character(10), NULL::text + Output: NULL::integer, 1001, 101, 'foo'::text, NULL::timestamp with time zone, NULL::character varying, 'ft1 '::character(10), NULL::text (4 rows) --Testcase 384: @@ -5387,27 +5387,27 @@ EXPLAIN (VERBOSE, COSTS OFF) EXECUTE st6; --Testcase 387: EXECUTE st6; - c1 | c2 | c3 | time | c6 | c7 | c8 -----+----+-------+--------------------------+----+------------+----- - 1 | 1 | 00001 | Fri Jan 02 00:00:00 1970 | 1 | 1 | foo - 2 | 2 | 00002 | Sat Jan 03 00:00:00 1970 | 2 | 2 | foo - 3 | 3 | 00003 | Sun Jan 04 00:00:00 1970 | 3 | 3 | foo - 4 | 4 | 00004 | Mon Jan 05 00:00:00 1970 | 4 | 4 | foo - 5 | 5 | 00005 | Tue Jan 06 00:00:00 1970 | 5 | 5 | foo - 6 | 6 | 00006 | Wed Jan 07 00:00:00 1970 | 6 | 6 | foo - 7 | 7 | 00007 | Thu Jan 08 00:00:00 1970 | 7 | 7 | foo - 8 | 8 | 00008 | Fri Jan 09 00:00:00 1970 | 8 | 8 | foo - 9 | 9 | 00009 | Sat Jan 10 00:00:00 1970 | 9 | 9 | foo + c1 | c2 | c3 | time | c6 | c7 | c8 +----+----+-------+------------------------------+----+------------+----- + 1 | 1 | 00001 | Fri Jan 02 00:00:00 1970 PST | 1 | 1 | foo + 2 | 2 | 00002 | Sat Jan 03 00:00:00 1970 PST | 2 | 2 | foo + 3 | 3 | 00003 | Sun Jan 04 00:00:00 1970 PST | 3 | 3 | foo + 4 | 4 | 00004 | Mon Jan 05 00:00:00 1970 PST | 4 | 4 | foo + 5 | 5 | 00005 | Tue Jan 06 00:00:00 1970 PST | 5 | 5 | foo + 6 | 6 | 00006 | Wed Jan 07 00:00:00 1970 PST | 6 | 6 | foo + 7 | 7 | 00007 | Thu Jan 08 00:00:00 1970 PST | 7 | 7 | foo + 8 | 8 | 00008 | Fri Jan 09 00:00:00 1970 PST | 8 | 8 | foo + 9 | 9 | 00009 | Sat Jan 10 00:00:00 1970 PST | 9 | 9 | foo (9 rows) --Testcase 388: EXPLAIN (VERBOSE, COSTS OFF) EXECUTE st7; - QUERY PLAN ------------------------------------------------------------------------------------------------------------------------------------------------------------- + QUERY PLAN +--------------------------------------------------------------------------------------------------------------------------------------------------------- Insert on public.ft1 Batch Size: 1 -> Result - Output: NULL::integer, 1001, 101, 'foo'::text, NULL::timestamp without time zone, NULL::character varying, 'ft1 '::character(10), NULL::text + Output: NULL::integer, 1001, 101, 'foo'::text, NULL::timestamp with time zone, NULL::character varying, 'ft1 '::character(10), NULL::text (4 rows) --Testcase 389: @@ -5475,9 +5475,9 @@ SELECT * FROM ft1 t1 WHERE t1.tableoid = 'pg_class'::regclass LIMIT 1; --Testcase 396: SELECT * FROM ft1 t1 WHERE t1.tableoid = 'ft1'::regclass ORDER BY c1 LIMIT 1; - c1 | c2 | c3 | time | c6 | c7 | c8 -----+----+-------+--------------------------+----+------------+----- - 1 | 1 | 00001 | Fri Jan 02 00:00:00 1970 | 1 | 1 | foo + c1 | c2 | c3 | time | c6 | c7 | c8 +----+----+-------+------------------------------+----+------------+----- + 1 | 1 | 00001 | Fri Jan 02 00:00:00 1970 PST | 1 | 1 | foo (1 row) --Testcase 397: @@ -5492,9 +5492,9 @@ SELECT tableoid::regclass, * FROM ft1 t1 LIMIT 1; --Testcase 398: SELECT tableoid::regclass, * FROM ft1 t1 ORDER BY c1 LIMIT 1; - tableoid | c1 | c2 | c3 | time | c6 | c7 | c8 -----------+----+----+-------+--------------------------+----+------------+----- - ft1 | 1 | 1 | 00001 | Fri Jan 02 00:00:00 1970 | 1 | 1 | foo + tableoid | c1 | c2 | c3 | time | c6 | c7 | c8 +----------+----+----+-------+------------------------------+----+------------+----- + ft1 | 1 | 1 | 00001 | Fri Jan 02 00:00:00 1970 PST | 1 | 1 | foo (1 row) --Testcase 399: @@ -5526,9 +5526,9 @@ SELECT ctid, * FROM ft1 t1 LIMIT 1; --Testcase 402: SELECT ctid, * FROM ft1 t1 ORDER BY c1 LIMIT 1; - ctid | c1 | c2 | c3 | time | c6 | c7 | c8 -----------------+----+----+-------+--------------------------+----+------------+----- - (4294967295,0) | 1 | 1 | 00001 | Fri Jan 02 00:00:00 1970 | 1 | 1 | foo + ctid | c1 | c2 | c3 | time | c6 | c7 | c8 +----------------+----+----+-------+------------------------------+----+------------+----- + (4294967295,0) | 1 | 1 | 00001 | Fri Jan 02 00:00:00 1970 PST | 1 | 1 | foo (1 row) -- =================================================================== @@ -5620,9 +5620,9 @@ SELECT * FROM ft1 WHERE c8 = 'foo' LIMIT 1; -- Testcase 769: SELECT * FROM ft1 WHERE c8 = 'foo' LIMIT 1; - c1 | c2 | c3 | time | c6 | c7 | c8 ------+----+-------+--------------------------+----+------------+----- - 100 | 0 | 00100 | Thu Jan 01 00:00:00 1970 | 0 | 0 | foo + c1 | c2 | c3 | time | c6 | c7 | c8 +-----+----+-------+------------------------------+----+------------+----- + 100 | 0 | 00100 | Thu Jan 01 00:00:00 1970 PST | 0 | 0 | foo (1 row) -- Testcase 770: @@ -5637,9 +5637,9 @@ SELECT * FROM ft1 WHERE 'foo' = c8 LIMIT 1; -- Testcase 771: SELECT * FROM ft1 WHERE 'foo' = c8 LIMIT 1; - c1 | c2 | c3 | time | c6 | c7 | c8 ------+----+-------+--------------------------+----+------------+----- - 100 | 0 | 00100 | Thu Jan 01 00:00:00 1970 | 0 | 0 | foo + c1 | c2 | c3 | time | c6 | c7 | c8 +-----+----+-------+------------------------------+----+------------+----- + 100 | 0 | 00100 | Thu Jan 01 00:00:00 1970 PST | 0 | 0 | foo (1 row) -- we declared c8 to be text locally, but it's still the same type on @@ -5650,16 +5650,16 @@ SELECT * FROM ft1 WHERE 'foo' = c8 LIMIT 1; -- match. These case below not error with influxdb_fdw. -- Testcase 772: SELECT * FROM ft1 WHERE c8 LIKE 'foo' LIMIT 1; -- ERROR - c1 | c2 | c3 | time | c6 | c7 | c8 ------+----+-------+--------------------------+----+------------+----- - 100 | 0 | 00100 | Thu Jan 01 00:00:00 1970 | 0 | 0 | foo + c1 | c2 | c3 | time | c6 | c7 | c8 +-----+----+-------+------------------------------+----+------------+----- + 100 | 0 | 00100 | Thu Jan 01 00:00:00 1970 PST | 0 | 0 | foo (1 row) -- Testcase 773: SELECT * FROM ft1 WHERE c8::text LIKE 'foo' LIMIT 1; -- ERROR; cast not pushed down - c1 | c2 | c3 | time | c6 | c7 | c8 ------+----+-------+--------------------------+----+------------+----- - 100 | 0 | 00100 | Thu Jan 01 00:00:00 1970 | 0 | 0 | foo + c1 | c2 | c3 | time | c6 | c7 | c8 +-----+----+-------+------------------------------+----+------------+----- + 100 | 0 | 00100 | Thu Jan 01 00:00:00 1970 PST | 0 | 0 | foo (1 row) /* @@ -5811,12 +5811,12 @@ explain (verbose, costs off) select * from ft3 f, loct3 l --Testcase 431: EXPLAIN (verbose, costs off) INSERT INTO ft2 (c1,c2,c3) SELECT c1+1000,c2+100, c3 || c3 FROM ft2 ORDER BY c1 LIMIT 20; - QUERY PLAN -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- + QUERY PLAN +---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- Insert on public.ft2 Batch Size: 1 -> Subquery Scan on "*SELECT*" - Output: "*SELECT*"."?column?", "*SELECT*"."?column?_1", NULL::integer, "*SELECT*"."?column?_2", NULL::timestamp without time zone, NULL::character varying, 'ft2 '::character(10), NULL::text + Output: "*SELECT*"."?column?", "*SELECT*"."?column?_1", NULL::integer, "*SELECT*"."?column?_2", NULL::timestamp with time zone, NULL::character varying, 'ft2 '::character(10), NULL::text -> Limit Output: ((ft2_1.c1 + 1000)), ((ft2_1.c2 + 100)), ((ft2_1.c3 || ft2_1.c3)), ft2_1.c1 -> Sort @@ -6830,12 +6830,12 @@ SELECT c1,c2,c3 FROM ft2 ORDER BY c1; --Testcase 443: EXPLAIN (verbose, costs off) INSERT INTO ft2 (c1,c2,c3) VALUES (1200,999,'foo'); - QUERY PLAN ------------------------------------------------------------------------------------------------------------------------------------------------------------- + QUERY PLAN +--------------------------------------------------------------------------------------------------------------------------------------------------------- Insert on public.ft2 Batch Size: 1 -> Result - Output: 1200, 999, NULL::integer, 'foo'::text, NULL::timestamp without time zone, NULL::character varying, 'ft2 '::character(10), NULL::text + Output: 1200, 999, NULL::integer, 'foo'::text, NULL::timestamp with time zone, NULL::character varying, 'ft2 '::character(10), NULL::text (4 rows) --Testcase 444: @@ -9555,7 +9555,7 @@ CREATE FOREIGN TABLE pg_temp.ft1_nopw ( c2 int NOT NULL, c3 text, c4 timestamptz, - c5 timestamp, + c5 timestamptz, c6 varchar(10), c7 char(10) default 'ft1', c8 user_enum diff --git a/expected/15.0/extra/insert.out b/expected/15.4/extra/insert.out similarity index 100% rename from expected/15.0/extra/insert.out rename to expected/15.4/extra/insert.out diff --git a/expected/15.0/extra/join.out b/expected/15.4/extra/join.out similarity index 100% rename from expected/15.0/extra/join.out rename to expected/15.4/extra/join.out diff --git a/expected/15.0/extra/limit.out b/expected/15.4/extra/limit.out similarity index 100% rename from expected/15.0/extra/limit.out rename to expected/15.4/extra/limit.out diff --git a/expected/15.0/extra/prepare.out b/expected/15.4/extra/prepare.out similarity index 100% rename from expected/15.0/extra/prepare.out rename to expected/15.4/extra/prepare.out diff --git a/expected/15.0/extra/select.out b/expected/15.4/extra/select.out similarity index 100% rename from expected/15.0/extra/select.out rename to expected/15.4/extra/select.out diff --git a/expected/15.0/extra/select_having.out b/expected/15.4/extra/select_having.out similarity index 100% rename from expected/15.0/extra/select_having.out rename to expected/15.4/extra/select_having.out diff --git a/expected/14.5/influxdb_fdw.out b/expected/15.4/influxdb_fdw.out similarity index 92% rename from expected/14.5/influxdb_fdw.out rename to expected/15.4/influxdb_fdw.out index 506d3da..7e6a546 100644 --- a/expected/14.5/influxdb_fdw.out +++ b/expected/15.4/influxdb_fdw.out @@ -1128,14 +1128,14 @@ SELECT * FROM t5; SELECT * FROM public.influxdb_fdw_version(); influxdb_fdw_version ---------------------- - 20000 + 20100 (1 row) --Testcase 146: SELECT influxdb_fdw_version(); influxdb_fdw_version ---------------------- - 20000 + 20100 (1 row) --Test pushdown LIMIT...OFFSET @@ -1620,6 +1620,122 @@ SELECT * FROM tmp_time; 2100-01-01 01:01:01 | 04:05:06 | | (6 rows) +-- Type mis-match +--Testcase 212: +CREATE FOREIGN TABLE datatype_test ( + time timestamp with time zone, + tag1 text, + tag2 text, + value1 int, + value2 text +) SERVER server1 OPTIONS (table 'datatype_test', tags 'tag1,tag2'); +--Testcase 213: +INSERT INTO datatype_test (tag1, tag2, value1, value2) VALUES ('time', '2021-02-02T00:00:01Z', '1', '2021-02-05T00:00:00Z'); +--Testcase 214: +INSERT INTO datatype_test (tag1, tag2, value1, value2) VALUES ('time', '2022-02-02T00:00:01Z', '2', '2022-02-05T00:00:00Z'); +--Testcase 215: +SELECT tag1, tag2, value1, value2 FROM datatype_test; + tag1 | tag2 | value1 | value2 +------+----------------------+--------+---------------------- + time | 2021-02-02T00:00:01Z | 1 | 2021-02-05T00:00:00Z + time | 2022-02-02T00:00:01Z | 2 | 2022-02-05T00:00:00Z +(2 rows) + +-- Using text as timestamp +--Testcase 216: +ALTER FOREIGN TABLE datatype_test ALTER COLUMN tag2 TYPE timestamptz; +--Testcase 217: +ALTER FOREIGN TABLE datatype_test ALTER COLUMN value2 TYPE timestamptz; +-- SELECT OK without filter +--Testcase 218: +SELECT tag1, tag2, value1, value2 FROM datatype_test; + tag1 | tag2 | value1 | value2 +------+------------------------+--------+------------------------ + time | 2021-02-02 09:00:01+09 | 1 | 2021-02-05 09:00:00+09 + time | 2022-02-02 09:00:01+09 | 2 | 2022-02-05 09:00:00+09 +(2 rows) + +-- SELECT with timestamp filter, WHERE clause is pushed down +-- InfluxDB cannot compare correctly, 0 row returned +--Testcase 219: +EXPLAIN (VERBOSE, COSTS OFF) +SELECT tag1, tag2, value1, value2 FROM datatype_test WHERE tag2 > '2021-02-02 00:00:01+00'; + QUERY PLAN +--------------------------------------------------------------------------------------------------------------------------- + Foreign Scan on public.datatype_test + Output: tag1, tag2, value1, value2 + InfluxDB query: SELECT "tag1", "tag2", "value1", "value2" FROM "datatype_test" WHERE (("tag2" > '2021-02-02 00:00:01')) +(3 rows) + +--Testcase 220: +SELECT tag1, tag2, value1, value2 FROM datatype_test WHERE tag2 > '2021-02-02 00:00:01+00'; + tag1 | tag2 | value1 | value2 +------+------+--------+-------- +(0 rows) + +--Testcase 221: +EXPLAIN (VERBOSE, COSTS OFF) +SELECT tag1, tag2, value1, value2 FROM datatype_test WHERE value2 > '2021-02-05 00:00:00+00'; + QUERY PLAN +----------------------------------------------------------------------------------------------------------------------------- + Foreign Scan on public.datatype_test + Output: tag1, tag2, value1, value2 + InfluxDB query: SELECT "tag1", "tag2", "value1", "value2" FROM "datatype_test" WHERE (("value2" > '2021-02-05 00:00:00')) +(3 rows) + +--Testcase 222: +SELECT tag1, tag2, value1, value2 FROM datatype_test WHERE value2 > '2021-02-05 00:00:00+00'; + tag1 | tag2 | value1 | value2 +------+------+--------+-------- +(0 rows) + +--Testcase 223: +ALTER FOREIGN TABLE datatype_test ALTER COLUMN tag2 TYPE text; +--Testcase 224: +ALTER FOREIGN TABLE datatype_test ALTER COLUMN value2 TYPE text; +-- uses explicit cast, WHERE clause is not pushed down +-- compared correctly by postgres, 1 row returned +--Testcase 225: +EXPLAIN (VERBOSE, COSTS OFF) +SELECT tag1, tag2, value1, value2 FROM datatype_test WHERE tag2::timestamptz > '2021-02-02 00:00:01+00'; + QUERY PLAN +----------------------------------------------------------------------------------------------------------------- + Foreign Scan on public.datatype_test + Output: tag1, tag2, value1, value2 + Filter: ((datatype_test.tag2)::timestamp with time zone > '2021-02-02 09:00:01+09'::timestamp with time zone) + InfluxDB query: SELECT "tag1", "tag2", "value1", "value2" FROM "datatype_test" +(4 rows) + +--Testcase 226: +SELECT tag1, tag2, value1, value2 FROM datatype_test WHERE tag2::timestamptz > '2021-02-02 00:00:01+00'; + tag1 | tag2 | value1 | value2 +------+----------------------+--------+---------------------- + time | 2022-02-02T00:00:01Z | 2 | 2022-02-05T00:00:00Z +(1 row) + +--Testcase 227: +EXPLAIN (VERBOSE, COSTS OFF) +SELECT tag1, tag2, value1, value2 FROM datatype_test WHERE value2::timestamptz > '2021-02-05 00:00:00+00'; + QUERY PLAN +------------------------------------------------------------------------------------------------------------------- + Foreign Scan on public.datatype_test + Output: tag1, tag2, value1, value2 + Filter: ((datatype_test.value2)::timestamp with time zone > '2021-02-05 09:00:00+09'::timestamp with time zone) + InfluxDB query: SELECT "tag1", "tag2", "value1", "value2" FROM "datatype_test" +(4 rows) + +--Testcase 228: +SELECT tag1, tag2, value1, value2 FROM datatype_test WHERE value2::timestamptz > '2021-02-05 00:00:00+00'; + tag1 | tag2 | value1 | value2 +------+----------------------+--------+---------------------- + time | 2022-02-02T00:00:01Z | 2 | 2022-02-05T00:00:00Z +(1 row) + +-- clean-up +--Testcase 229: +DELETE FROM datatype_test; +--Testcase 230: +DROP FOREIGN TABLE datatype_test; -- Recover data :RECOVER_INIT_TXT_DROP_BUCKET; :RECOVER_INIT_TXT_CREATE_BUCKET; diff --git a/expected/14.5/option.out b/expected/15.4/option.out similarity index 100% rename from expected/14.5/option.out rename to expected/15.4/option.out diff --git a/expected/15.0/schemaless/add_fields.out b/expected/15.4/schemaless/add_fields.out similarity index 100% rename from expected/15.0/schemaless/add_fields.out rename to expected/15.4/schemaless/add_fields.out diff --git a/expected/15.0/schemaless/add_multi_key.out b/expected/15.4/schemaless/add_multi_key.out similarity index 100% rename from expected/15.0/schemaless/add_multi_key.out rename to expected/15.4/schemaless/add_multi_key.out diff --git a/expected/15.0/schemaless/add_tags.out b/expected/15.4/schemaless/add_tags.out similarity index 100% rename from expected/15.0/schemaless/add_tags.out rename to expected/15.4/schemaless/add_tags.out diff --git a/expected/14.5/schemaless/aggregate.out b/expected/15.4/schemaless/aggregate.out similarity index 100% rename from expected/14.5/schemaless/aggregate.out rename to expected/15.4/schemaless/aggregate.out diff --git a/expected/15.0/schemaless/extra/aggregates.out b/expected/15.4/schemaless/extra/aggregates.out similarity index 100% rename from expected/15.0/schemaless/extra/aggregates.out rename to expected/15.4/schemaless/extra/aggregates.out diff --git a/expected/15.0/schemaless/extra/influxdb_fdw_post.out b/expected/15.4/schemaless/extra/influxdb_fdw_post.out similarity index 91% rename from expected/15.0/schemaless/extra/influxdb_fdw_post.out rename to expected/15.4/schemaless/extra/influxdb_fdw_post.out index 40087bd..c1c97db 100644 --- a/expected/15.0/schemaless/extra/influxdb_fdw_post.out +++ b/expected/15.4/schemaless/extra/influxdb_fdw_post.out @@ -26,25 +26,25 @@ CREATE TYPE user_enum AS ENUM ('foo', 'bar', 'buz'); --Testcase 9: CREATE SCHEMA "S 1"; --Testcase 10: -CREATE FOREIGN TABLE "S 1"."T 0" (time timestamp, tags jsonb OPTIONS(tags 'true'), fields jsonb OPTIONS(fields 'true')) SERVER influxdb_svr OPTIONS (table 'T0', tags 'c3', schemaless 'true'); +CREATE FOREIGN TABLE "S 1"."T 0" (time timestamptz, tags jsonb OPTIONS(tags 'true'), fields jsonb OPTIONS(fields 'true')) SERVER influxdb_svr OPTIONS (table 'T0', tags 'c3', schemaless 'true'); --Testcase 783: CREATE FOREIGN TABLE "S 1".s1t0 ( "C 1" int NOT NULL, c2 int NOT NULL, c3 text, - time timestamp, + time timestamptz, c6 varchar(10), c7 char(10), c8 text ) SERVER influxdb_svr OPTIONS (table 'T0', tags 'c3'); --Testcase 11: -CREATE FOREIGN TABLE "S 1"."T 1" (time timestamp, tags jsonb OPTIONS(tags 'true'), fields jsonb OPTIONS(fields 'true')) SERVER influxdb_svr OPTIONS (table 'T1', tags 'c3', schemaless 'true'); +CREATE FOREIGN TABLE "S 1"."T 1" (time timestamptz, tags jsonb OPTIONS(tags 'true'), fields jsonb OPTIONS(fields 'true')) SERVER influxdb_svr OPTIONS (table 'T1', tags 'c3', schemaless 'true'); --Testcase 784: CREATE FOREIGN TABLE "S 1".s1t1 ( "C 1" int NOT NULL, c2 int NOT NULL, c3 text, - time timestamp, + time timestamptz, c6 varchar(10), c7 char(10), c8 text @@ -82,7 +82,7 @@ INSERT INTO "S 1".s1t1 SELECT id, id % 10, to_char(id, 'FM00000'), - '1970-01-01'::timestamp + ((id % 100) || ' days')::interval, + '1970-01-01'::timestamptz + ((id % 100) || ' days')::interval, id % 10, id % 10, 'foo'::text @@ -116,14 +116,14 @@ DELETE FROM "S 1".s1t4 WHERE c1 % 3 != 0; -- delete for outer join tests -- create foreign tables -- =================================================================== --Testcase 21: -CREATE FOREIGN TABLE ft1 (time timestamp, tags jsonb OPTIONS(tags 'true'), fields jsonb OPTIONS(fields 'true')) SERVER influxdb_svr OPTIONS (schemaless 'true'); +CREATE FOREIGN TABLE ft1 (time timestamptz, tags jsonb OPTIONS(tags 'true'), fields jsonb OPTIONS(fields 'true')) SERVER influxdb_svr OPTIONS (schemaless 'true'); --Testcase 788: CREATE FOREIGN TABLE ft1_nsc ( c0 int, c1 int NOT NULL, c2 int NOT NULL, c3 text, - time timestamp, + time timestamptz, c6 varchar(10), c7 char(10) default 'ft1', c8 text @@ -131,14 +131,14 @@ CREATE FOREIGN TABLE ft1_nsc ( --Testcase 22: ALTER FOREIGN TABLE ft1_nsc DROP COLUMN c0; --Testcase 23: -CREATE FOREIGN TABLE ft2 (time timestamp, tags jsonb OPTIONS(tags 'true'), fields jsonb OPTIONS(fields 'true')) SERVER influxdb_svr OPTIONS (schemaless 'true'); +CREATE FOREIGN TABLE ft2 (time timestamptz, tags jsonb OPTIONS(tags 'true'), fields jsonb OPTIONS(fields 'true')) SERVER influxdb_svr OPTIONS (schemaless 'true'); --Testcase 789: CREATE FOREIGN TABLE ft2_nsc ( c1 int NOT NULL, c2 int NOT NULL, cx int, c3 text, - time timestamp, + time timestamptz, c6 varchar(10), c7 char(10) default 'ft2', c8 text @@ -249,9 +249,9 @@ ALTER FOREIGN TABLE ft2_nsc ALTER COLUMN c1 OPTIONS (column_name 'C 1'); \set VERBOSITY terse --Testcase 35: SELECT tags->>'c3' c3, time FROM ft1 ORDER BY tags->>'c3', (fields->>'C 1')::int LIMIT 1; -- should work - c3 | time --------+-------------------------- - 00001 | Fri Jan 02 00:00:00 1970 + c3 | time +-------+------------------------------ + 00001 | Fri Jan 02 00:00:00 1970 PST (1 row) --Testcase 36: @@ -267,9 +267,9 @@ DO $d$ $d$; --Testcase 38: SELECT tags->>'c3' c3, time FROM ft1 ORDER BY tags->>'c3', (fields->>'C 1')::int LIMIT 1; -- should work again - c3 | time --------+-------------------------- - 00001 | Fri Jan 02 00:00:00 1970 + c3 | time +-------+------------------------------ + 00001 | Fri Jan 02 00:00:00 1970 PST (1 row) \set VERBOSITY default @@ -296,18 +296,18 @@ EXPLAIN (COSTS OFF) SELECT * FROM ft1 ORDER BY tags->>'c3', (fields->>'C 1')::in --Testcase 40: SELECT * FROM ft1 ORDER BY tags->>'c3', (fields->>'C 1')::int OFFSET 100 LIMIT 10; - time | tags | fields ---------------------------+-----------------+----------------------------------------------------------------------- - Fri Jan 02 00:00:00 1970 | {"c3": "00101"} | {"c2": "1", "c6": "1", "c7": "1 ", "c8": "foo", "C 1": "101"} - Sat Jan 03 00:00:00 1970 | {"c3": "00102"} | {"c2": "2", "c6": "2", "c7": "2 ", "c8": "foo", "C 1": "102"} - Sun Jan 04 00:00:00 1970 | {"c3": "00103"} | {"c2": "3", "c6": "3", "c7": "3 ", "c8": "foo", "C 1": "103"} - Mon Jan 05 00:00:00 1970 | {"c3": "00104"} | {"c2": "4", "c6": "4", "c7": "4 ", "c8": "foo", "C 1": "104"} - Tue Jan 06 00:00:00 1970 | {"c3": "00105"} | {"c2": "5", "c6": "5", "c7": "5 ", "c8": "foo", "C 1": "105"} - Wed Jan 07 00:00:00 1970 | {"c3": "00106"} | {"c2": "6", "c6": "6", "c7": "6 ", "c8": "foo", "C 1": "106"} - Thu Jan 08 00:00:00 1970 | {"c3": "00107"} | {"c2": "7", "c6": "7", "c7": "7 ", "c8": "foo", "C 1": "107"} - Fri Jan 09 00:00:00 1970 | {"c3": "00108"} | {"c2": "8", "c6": "8", "c7": "8 ", "c8": "foo", "C 1": "108"} - Sat Jan 10 00:00:00 1970 | {"c3": "00109"} | {"c2": "9", "c6": "9", "c7": "9 ", "c8": "foo", "C 1": "109"} - Sun Jan 11 00:00:00 1970 | {"c3": "00110"} | {"c2": "0", "c6": "0", "c7": "0 ", "c8": "foo", "C 1": "110"} + time | tags | fields +------------------------------+-----------------+----------------------------------------------------------------------- + Fri Jan 02 00:00:00 1970 PST | {"c3": "00101"} | {"c2": "1", "c6": "1", "c7": "1 ", "c8": "foo", "C 1": "101"} + Sat Jan 03 00:00:00 1970 PST | {"c3": "00102"} | {"c2": "2", "c6": "2", "c7": "2 ", "c8": "foo", "C 1": "102"} + Sun Jan 04 00:00:00 1970 PST | {"c3": "00103"} | {"c2": "3", "c6": "3", "c7": "3 ", "c8": "foo", "C 1": "103"} + Mon Jan 05 00:00:00 1970 PST | {"c3": "00104"} | {"c2": "4", "c6": "4", "c7": "4 ", "c8": "foo", "C 1": "104"} + Tue Jan 06 00:00:00 1970 PST | {"c3": "00105"} | {"c2": "5", "c6": "5", "c7": "5 ", "c8": "foo", "C 1": "105"} + Wed Jan 07 00:00:00 1970 PST | {"c3": "00106"} | {"c2": "6", "c6": "6", "c7": "6 ", "c8": "foo", "C 1": "106"} + Thu Jan 08 00:00:00 1970 PST | {"c3": "00107"} | {"c2": "7", "c6": "7", "c7": "7 ", "c8": "foo", "C 1": "107"} + Fri Jan 09 00:00:00 1970 PST | {"c3": "00108"} | {"c2": "8", "c6": "8", "c7": "8 ", "c8": "foo", "C 1": "108"} + Sat Jan 10 00:00:00 1970 PST | {"c3": "00109"} | {"c2": "9", "c6": "9", "c7": "9 ", "c8": "foo", "C 1": "109"} + Sun Jan 11 00:00:00 1970 PST | {"c3": "00110"} | {"c2": "0", "c6": "0", "c7": "0 ", "c8": "foo", "C 1": "110"} (10 rows) -- single table with alias - also test that tableoid sort is not pushed to remote side @@ -327,18 +327,18 @@ EXPLAIN (VERBOSE, COSTS OFF) SELECT * FROM ft1 t1 ORDER BY t1.tags->>'c3', (t1.f --Testcase 42: SELECT * FROM ft1 t1 ORDER BY t1.tags->>'c3', (t1.fields->>'C 1')::int, t1.tableoid OFFSET 100 LIMIT 10; - time | tags | fields ---------------------------+-----------------+----------------------------------------------------------------------- - Fri Jan 02 00:00:00 1970 | {"c3": "00101"} | {"c2": "1", "c6": "1", "c7": "1 ", "c8": "foo", "C 1": "101"} - Sat Jan 03 00:00:00 1970 | {"c3": "00102"} | {"c2": "2", "c6": "2", "c7": "2 ", "c8": "foo", "C 1": "102"} - Sun Jan 04 00:00:00 1970 | {"c3": "00103"} | {"c2": "3", "c6": "3", "c7": "3 ", "c8": "foo", "C 1": "103"} - Mon Jan 05 00:00:00 1970 | {"c3": "00104"} | {"c2": "4", "c6": "4", "c7": "4 ", "c8": "foo", "C 1": "104"} - Tue Jan 06 00:00:00 1970 | {"c3": "00105"} | {"c2": "5", "c6": "5", "c7": "5 ", "c8": "foo", "C 1": "105"} - Wed Jan 07 00:00:00 1970 | {"c3": "00106"} | {"c2": "6", "c6": "6", "c7": "6 ", "c8": "foo", "C 1": "106"} - Thu Jan 08 00:00:00 1970 | {"c3": "00107"} | {"c2": "7", "c6": "7", "c7": "7 ", "c8": "foo", "C 1": "107"} - Fri Jan 09 00:00:00 1970 | {"c3": "00108"} | {"c2": "8", "c6": "8", "c7": "8 ", "c8": "foo", "C 1": "108"} - Sat Jan 10 00:00:00 1970 | {"c3": "00109"} | {"c2": "9", "c6": "9", "c7": "9 ", "c8": "foo", "C 1": "109"} - Sun Jan 11 00:00:00 1970 | {"c3": "00110"} | {"c2": "0", "c6": "0", "c7": "0 ", "c8": "foo", "C 1": "110"} + time | tags | fields +------------------------------+-----------------+----------------------------------------------------------------------- + Fri Jan 02 00:00:00 1970 PST | {"c3": "00101"} | {"c2": "1", "c6": "1", "c7": "1 ", "c8": "foo", "C 1": "101"} + Sat Jan 03 00:00:00 1970 PST | {"c3": "00102"} | {"c2": "2", "c6": "2", "c7": "2 ", "c8": "foo", "C 1": "102"} + Sun Jan 04 00:00:00 1970 PST | {"c3": "00103"} | {"c2": "3", "c6": "3", "c7": "3 ", "c8": "foo", "C 1": "103"} + Mon Jan 05 00:00:00 1970 PST | {"c3": "00104"} | {"c2": "4", "c6": "4", "c7": "4 ", "c8": "foo", "C 1": "104"} + Tue Jan 06 00:00:00 1970 PST | {"c3": "00105"} | {"c2": "5", "c6": "5", "c7": "5 ", "c8": "foo", "C 1": "105"} + Wed Jan 07 00:00:00 1970 PST | {"c3": "00106"} | {"c2": "6", "c6": "6", "c7": "6 ", "c8": "foo", "C 1": "106"} + Thu Jan 08 00:00:00 1970 PST | {"c3": "00107"} | {"c2": "7", "c6": "7", "c7": "7 ", "c8": "foo", "C 1": "107"} + Fri Jan 09 00:00:00 1970 PST | {"c3": "00108"} | {"c2": "8", "c6": "8", "c7": "8 ", "c8": "foo", "C 1": "108"} + Sat Jan 10 00:00:00 1970 PST | {"c3": "00109"} | {"c2": "9", "c6": "9", "c7": "9 ", "c8": "foo", "C 1": "109"} + Sun Jan 11 00:00:00 1970 PST | {"c3": "00110"} | {"c2": "0", "c6": "0", "c7": "0 ", "c8": "foo", "C 1": "110"} (10 rows) -- whole-row reference @@ -358,18 +358,18 @@ EXPLAIN (VERBOSE, COSTS OFF) SELECT t1 FROM ft1 t1 ORDER BY t1.tags->>'c3', (t1. --Testcase 44: SELECT t1 FROM ft1 t1 ORDER BY t1.tags->>'c3', (t1.fields->>'C 1')::int OFFSET 100 LIMIT 10; - t1 ------------------------------------------------------------------------------------------------------------------------------------------------- - ("Fri Jan 02 00:00:00 1970","{""c3"": ""00101""}","{""c2"": ""1"", ""c6"": ""1"", ""c7"": ""1 "", ""c8"": ""foo"", ""C 1"": ""101""}") - ("Sat Jan 03 00:00:00 1970","{""c3"": ""00102""}","{""c2"": ""2"", ""c6"": ""2"", ""c7"": ""2 "", ""c8"": ""foo"", ""C 1"": ""102""}") - ("Sun Jan 04 00:00:00 1970","{""c3"": ""00103""}","{""c2"": ""3"", ""c6"": ""3"", ""c7"": ""3 "", ""c8"": ""foo"", ""C 1"": ""103""}") - ("Mon Jan 05 00:00:00 1970","{""c3"": ""00104""}","{""c2"": ""4"", ""c6"": ""4"", ""c7"": ""4 "", ""c8"": ""foo"", ""C 1"": ""104""}") - ("Tue Jan 06 00:00:00 1970","{""c3"": ""00105""}","{""c2"": ""5"", ""c6"": ""5"", ""c7"": ""5 "", ""c8"": ""foo"", ""C 1"": ""105""}") - ("Wed Jan 07 00:00:00 1970","{""c3"": ""00106""}","{""c2"": ""6"", ""c6"": ""6"", ""c7"": ""6 "", ""c8"": ""foo"", ""C 1"": ""106""}") - ("Thu Jan 08 00:00:00 1970","{""c3"": ""00107""}","{""c2"": ""7"", ""c6"": ""7"", ""c7"": ""7 "", ""c8"": ""foo"", ""C 1"": ""107""}") - ("Fri Jan 09 00:00:00 1970","{""c3"": ""00108""}","{""c2"": ""8"", ""c6"": ""8"", ""c7"": ""8 "", ""c8"": ""foo"", ""C 1"": ""108""}") - ("Sat Jan 10 00:00:00 1970","{""c3"": ""00109""}","{""c2"": ""9"", ""c6"": ""9"", ""c7"": ""9 "", ""c8"": ""foo"", ""C 1"": ""109""}") - ("Sun Jan 11 00:00:00 1970","{""c3"": ""00110""}","{""c2"": ""0"", ""c6"": ""0"", ""c7"": ""0 "", ""c8"": ""foo"", ""C 1"": ""110""}") + t1 +---------------------------------------------------------------------------------------------------------------------------------------------------- + ("Fri Jan 02 00:00:00 1970 PST","{""c3"": ""00101""}","{""c2"": ""1"", ""c6"": ""1"", ""c7"": ""1 "", ""c8"": ""foo"", ""C 1"": ""101""}") + ("Sat Jan 03 00:00:00 1970 PST","{""c3"": ""00102""}","{""c2"": ""2"", ""c6"": ""2"", ""c7"": ""2 "", ""c8"": ""foo"", ""C 1"": ""102""}") + ("Sun Jan 04 00:00:00 1970 PST","{""c3"": ""00103""}","{""c2"": ""3"", ""c6"": ""3"", ""c7"": ""3 "", ""c8"": ""foo"", ""C 1"": ""103""}") + ("Mon Jan 05 00:00:00 1970 PST","{""c3"": ""00104""}","{""c2"": ""4"", ""c6"": ""4"", ""c7"": ""4 "", ""c8"": ""foo"", ""C 1"": ""104""}") + ("Tue Jan 06 00:00:00 1970 PST","{""c3"": ""00105""}","{""c2"": ""5"", ""c6"": ""5"", ""c7"": ""5 "", ""c8"": ""foo"", ""C 1"": ""105""}") + ("Wed Jan 07 00:00:00 1970 PST","{""c3"": ""00106""}","{""c2"": ""6"", ""c6"": ""6"", ""c7"": ""6 "", ""c8"": ""foo"", ""C 1"": ""106""}") + ("Thu Jan 08 00:00:00 1970 PST","{""c3"": ""00107""}","{""c2"": ""7"", ""c6"": ""7"", ""c7"": ""7 "", ""c8"": ""foo"", ""C 1"": ""107""}") + ("Fri Jan 09 00:00:00 1970 PST","{""c3"": ""00108""}","{""c2"": ""8"", ""c6"": ""8"", ""c7"": ""8 "", ""c8"": ""foo"", ""C 1"": ""108""}") + ("Sat Jan 10 00:00:00 1970 PST","{""c3"": ""00109""}","{""c2"": ""9"", ""c6"": ""9"", ""c7"": ""9 "", ""c8"": ""foo"", ""C 1"": ""109""}") + ("Sun Jan 11 00:00:00 1970 PST","{""c3"": ""00110""}","{""c2"": ""0"", ""c6"": ""0"", ""c7"": ""0 "", ""c8"": ""foo"", ""C 1"": ""110""}") (10 rows) -- empty result @@ -392,9 +392,9 @@ EXPLAIN (VERBOSE, COSTS OFF) SELECT * FROM ft1 t1 WHERE (t1.fields->>'C 1')::int --Testcase 47: SELECT * FROM ft1 t1 WHERE (t1.fields->>'C 1')::int = 101 AND t1.fields->>'c6' = '1' AND t1.fields->>'c7' >= '1'; - time | tags | fields ---------------------------+-----------------+----------------------------------------------------------------------- - Fri Jan 02 00:00:00 1970 | {"c3": "00101"} | {"c2": "1", "c6": "1", "c7": "1 ", "c8": "foo", "C 1": "101"} + time | tags | fields +------------------------------+-----------------+----------------------------------------------------------------------- + Fri Jan 02 00:00:00 1970 PST | {"c3": "00101"} | {"c2": "1", "c6": "1", "c7": "1 ", "c8": "foo", "C 1": "101"} (1 row) -- with FOR UPDATE/SHARE @@ -411,9 +411,9 @@ EXPLAIN (VERBOSE, COSTS OFF) SELECT * FROM ft1 t1 WHERE (fields->>'C 1')::int = --Testcase 49: SELECT * FROM ft1 t1 WHERE (fields->>'C 1')::int = 101 FOR UPDATE; - time | tags | fields ---------------------------+-----------------+----------------------------------------------------------------------- - Fri Jan 02 00:00:00 1970 | {"c3": "00101"} | {"c2": "1", "c6": "1", "c7": "1 ", "c8": "foo", "C 1": "101"} + time | tags | fields +------------------------------+-----------------+----------------------------------------------------------------------- + Fri Jan 02 00:00:00 1970 PST | {"c3": "00101"} | {"c2": "1", "c6": "1", "c7": "1 ", "c8": "foo", "C 1": "101"} (1 row) --Testcase 50: @@ -429,9 +429,9 @@ EXPLAIN (VERBOSE, COSTS OFF) SELECT * FROM ft1 t1 WHERE (fields->>'C 1')::int = --Testcase 51: SELECT * FROM ft1 t1 WHERE (fields->>'C 1')::int = 102 FOR SHARE; - time | tags | fields ---------------------------+-----------------+----------------------------------------------------------------------- - Sat Jan 03 00:00:00 1970 | {"c3": "00102"} | {"c2": "2", "c6": "2", "c7": "2 ", "c8": "foo", "C 1": "102"} + time | tags | fields +------------------------------+-----------------+----------------------------------------------------------------------- + Sat Jan 03 00:00:00 1970 PST | {"c3": "00102"} | {"c2": "2", "c6": "2", "c7": "2 ", "c8": "foo", "C 1": "102"} (1 row) -- aggregate @@ -445,43 +445,43 @@ SELECT COUNT(*) FROM ft1 t1; -- subquery --Testcase 53: SELECT * FROM ft1 t1 WHERE t1.tags->>'c3' IN (SELECT tags->>'c3' FROM ft2 t2 WHERE (fields->>'C 1')::int <= 10) ORDER BY (fields->>'C 1')::int; - time | tags | fields ---------------------------+-----------------+---------------------------------------------------------------------- - Fri Jan 02 00:00:00 1970 | {"c3": "00001"} | {"c2": "1", "c6": "1", "c7": "1 ", "c8": "foo", "C 1": "1"} - Sat Jan 03 00:00:00 1970 | {"c3": "00002"} | {"c2": "2", "c6": "2", "c7": "2 ", "c8": "foo", "C 1": "2"} - Sun Jan 04 00:00:00 1970 | {"c3": "00003"} | {"c2": "3", "c6": "3", "c7": "3 ", "c8": "foo", "C 1": "3"} - Mon Jan 05 00:00:00 1970 | {"c3": "00004"} | {"c2": "4", "c6": "4", "c7": "4 ", "c8": "foo", "C 1": "4"} - Tue Jan 06 00:00:00 1970 | {"c3": "00005"} | {"c2": "5", "c6": "5", "c7": "5 ", "c8": "foo", "C 1": "5"} - Wed Jan 07 00:00:00 1970 | {"c3": "00006"} | {"c2": "6", "c6": "6", "c7": "6 ", "c8": "foo", "C 1": "6"} - Thu Jan 08 00:00:00 1970 | {"c3": "00007"} | {"c2": "7", "c6": "7", "c7": "7 ", "c8": "foo", "C 1": "7"} - Fri Jan 09 00:00:00 1970 | {"c3": "00008"} | {"c2": "8", "c6": "8", "c7": "8 ", "c8": "foo", "C 1": "8"} - Sat Jan 10 00:00:00 1970 | {"c3": "00009"} | {"c2": "9", "c6": "9", "c7": "9 ", "c8": "foo", "C 1": "9"} - Sun Jan 11 00:00:00 1970 | {"c3": "00010"} | {"c2": "0", "c6": "0", "c7": "0 ", "c8": "foo", "C 1": "10"} + time | tags | fields +------------------------------+-----------------+---------------------------------------------------------------------- + Fri Jan 02 00:00:00 1970 PST | {"c3": "00001"} | {"c2": "1", "c6": "1", "c7": "1 ", "c8": "foo", "C 1": "1"} + Sat Jan 03 00:00:00 1970 PST | {"c3": "00002"} | {"c2": "2", "c6": "2", "c7": "2 ", "c8": "foo", "C 1": "2"} + Sun Jan 04 00:00:00 1970 PST | {"c3": "00003"} | {"c2": "3", "c6": "3", "c7": "3 ", "c8": "foo", "C 1": "3"} + Mon Jan 05 00:00:00 1970 PST | {"c3": "00004"} | {"c2": "4", "c6": "4", "c7": "4 ", "c8": "foo", "C 1": "4"} + Tue Jan 06 00:00:00 1970 PST | {"c3": "00005"} | {"c2": "5", "c6": "5", "c7": "5 ", "c8": "foo", "C 1": "5"} + Wed Jan 07 00:00:00 1970 PST | {"c3": "00006"} | {"c2": "6", "c6": "6", "c7": "6 ", "c8": "foo", "C 1": "6"} + Thu Jan 08 00:00:00 1970 PST | {"c3": "00007"} | {"c2": "7", "c6": "7", "c7": "7 ", "c8": "foo", "C 1": "7"} + Fri Jan 09 00:00:00 1970 PST | {"c3": "00008"} | {"c2": "8", "c6": "8", "c7": "8 ", "c8": "foo", "C 1": "8"} + Sat Jan 10 00:00:00 1970 PST | {"c3": "00009"} | {"c2": "9", "c6": "9", "c7": "9 ", "c8": "foo", "C 1": "9"} + Sun Jan 11 00:00:00 1970 PST | {"c3": "00010"} | {"c2": "0", "c6": "0", "c7": "0 ", "c8": "foo", "C 1": "10"} (10 rows) -- subquery+MAX --Testcase 54: SELECT * FROM ft1 t1 WHERE t1.tags->>'c3' = (SELECT MAX(tags->>'c3') FROM ft2 t2) ORDER BY (fields->>'C 1')::int; - time | tags | fields ---------------------------+-----------------+------------------------------------------------------------------------ - Thu Jan 01 00:00:00 1970 | {"c3": "01000"} | {"c2": "0", "c6": "0", "c7": "0 ", "c8": "foo", "C 1": "1000"} + time | tags | fields +------------------------------+-----------------+------------------------------------------------------------------------ + Thu Jan 01 00:00:00 1970 PST | {"c3": "01000"} | {"c2": "0", "c6": "0", "c7": "0 ", "c8": "foo", "C 1": "1000"} (1 row) -- used in CTE --Testcase 55: WITH t1 AS (SELECT * FROM ft1 WHERE (fields->>'C 1')::int <= 10) SELECT (t2.fields->>'C 1')::int c1, (t2.fields->>'c2')::int c2, t2.tags->>'c3' c3, t2.time FROM t1, ft2 t2 WHERE (t1.fields->>'C 1')::int = (t2.fields->>'C 1')::int ORDER BY (t1.fields->>'C 1')::int; - c1 | c2 | c3 | time -----+----+-------+-------------------------- - 1 | 1 | 00001 | Fri Jan 02 00:00:00 1970 - 2 | 2 | 00002 | Sat Jan 03 00:00:00 1970 - 3 | 3 | 00003 | Sun Jan 04 00:00:00 1970 - 4 | 4 | 00004 | Mon Jan 05 00:00:00 1970 - 5 | 5 | 00005 | Tue Jan 06 00:00:00 1970 - 6 | 6 | 00006 | Wed Jan 07 00:00:00 1970 - 7 | 7 | 00007 | Thu Jan 08 00:00:00 1970 - 8 | 8 | 00008 | Fri Jan 09 00:00:00 1970 - 9 | 9 | 00009 | Sat Jan 10 00:00:00 1970 - 10 | 0 | 00010 | Sun Jan 11 00:00:00 1970 + c1 | c2 | c3 | time +----+----+-------+------------------------------ + 1 | 1 | 00001 | Fri Jan 02 00:00:00 1970 PST + 2 | 2 | 00002 | Sat Jan 03 00:00:00 1970 PST + 3 | 3 | 00003 | Sun Jan 04 00:00:00 1970 PST + 4 | 4 | 00004 | Mon Jan 05 00:00:00 1970 PST + 5 | 5 | 00005 | Tue Jan 06 00:00:00 1970 PST + 6 | 6 | 00006 | Wed Jan 07 00:00:00 1970 PST + 7 | 7 | 00007 | Thu Jan 08 00:00:00 1970 PST + 8 | 8 | 00008 | Fri Jan 09 00:00:00 1970 PST + 9 | 9 | 00009 | Sat Jan 10 00:00:00 1970 PST + 10 | 0 | 00010 | Sun Jan 11 00:00:00 1970 PST (10 rows) -- fixed values @@ -901,9 +901,9 @@ EXPLAIN (VERBOSE, COSTS OFF) --Testcase 88: SELECT * FROM ft2 a, ft2 b WHERE (a.fields->>'C 1')::int = 47 AND (b.fields->>'C 1')::int = (a.fields->>'c2')::int; - time | tags | fields | time | tags | fields ---------------------------+-----------------+----------------------------------------------------------------------+--------------------------+-----------------+--------------------------------------------------------------------- - Tue Feb 17 00:00:00 1970 | {"c3": "00047"} | {"c2": "7", "c6": "7", "c7": "7 ", "c8": "foo", "C 1": "47"} | Thu Jan 08 00:00:00 1970 | {"c3": "00007"} | {"c2": "7", "c6": "7", "c7": "7 ", "c8": "foo", "C 1": "7"} + time | tags | fields | time | tags | fields +------------------------------+-----------------+----------------------------------------------------------------------+------------------------------+-----------------+--------------------------------------------------------------------- + Tue Feb 17 00:00:00 1970 PST | {"c3": "00047"} | {"c2": "7", "c6": "7", "c7": "7 ", "c8": "foo", "C 1": "47"} | Thu Jan 08 00:00:00 1970 PST | {"c3": "00007"} | {"c2": "7", "c6": "7", "c7": "7 ", "c8": "foo", "C 1": "7"} (1 row) -- check both safe and unsafe join conditions @@ -929,129 +929,129 @@ EXPLAIN (VERBOSE, COSTS OFF) --Testcase 90: SELECT * FROM ft2 a, ft2 b WHERE (a.fields->>'c2')::int = 6 AND (b.fields->>'C 1')::int = (a.fields->>'C 1')::int AND a.fields->>'c8' = 'foo' AND b.fields->>'c7' = upper(a.fields->>'c7') ORDER BY (a.fields->>'C 1')::int; - time | tags | fields | time | tags | fields ---------------------------+-----------------+-----------------------------------------------------------------------+--------------------------+-----------------+----------------------------------------------------------------------- - Wed Jan 07 00:00:00 1970 | {"c3": "00006"} | {"c2": "6", "c6": "6", "c7": "6 ", "c8": "foo", "C 1": "6"} | Wed Jan 07 00:00:00 1970 | {"c3": "00006"} | {"c2": "6", "c6": "6", "c7": "6 ", "c8": "foo", "C 1": "6"} - Sat Jan 17 00:00:00 1970 | {"c3": "00016"} | {"c2": "6", "c6": "6", "c7": "6 ", "c8": "foo", "C 1": "16"} | Sat Jan 17 00:00:00 1970 | {"c3": "00016"} | {"c2": "6", "c6": "6", "c7": "6 ", "c8": "foo", "C 1": "16"} - Tue Jan 27 00:00:00 1970 | {"c3": "00026"} | {"c2": "6", "c6": "6", "c7": "6 ", "c8": "foo", "C 1": "26"} | Tue Jan 27 00:00:00 1970 | {"c3": "00026"} | {"c2": "6", "c6": "6", "c7": "6 ", "c8": "foo", "C 1": "26"} - Fri Feb 06 00:00:00 1970 | {"c3": "00036"} | {"c2": "6", "c6": "6", "c7": "6 ", "c8": "foo", "C 1": "36"} | Fri Feb 06 00:00:00 1970 | {"c3": "00036"} | {"c2": "6", "c6": "6", "c7": "6 ", "c8": "foo", "C 1": "36"} - Mon Feb 16 00:00:00 1970 | {"c3": "00046"} | {"c2": "6", "c6": "6", "c7": "6 ", "c8": "foo", "C 1": "46"} | Mon Feb 16 00:00:00 1970 | {"c3": "00046"} | {"c2": "6", "c6": "6", "c7": "6 ", "c8": "foo", "C 1": "46"} - Thu Feb 26 00:00:00 1970 | {"c3": "00056"} | {"c2": "6", "c6": "6", "c7": "6 ", "c8": "foo", "C 1": "56"} | Thu Feb 26 00:00:00 1970 | {"c3": "00056"} | {"c2": "6", "c6": "6", "c7": "6 ", "c8": "foo", "C 1": "56"} - Sun Mar 08 00:00:00 1970 | {"c3": "00066"} | {"c2": "6", "c6": "6", "c7": "6 ", "c8": "foo", "C 1": "66"} | Sun Mar 08 00:00:00 1970 | {"c3": "00066"} | {"c2": "6", "c6": "6", "c7": "6 ", "c8": "foo", "C 1": "66"} - Wed Mar 18 00:00:00 1970 | {"c3": "00076"} | {"c2": "6", "c6": "6", "c7": "6 ", "c8": "foo", "C 1": "76"} | Wed Mar 18 00:00:00 1970 | {"c3": "00076"} | {"c2": "6", "c6": "6", "c7": "6 ", "c8": "foo", "C 1": "76"} - Sat Mar 28 00:00:00 1970 | {"c3": "00086"} | {"c2": "6", "c6": "6", "c7": "6 ", "c8": "foo", "C 1": "86"} | Sat Mar 28 00:00:00 1970 | {"c3": "00086"} | {"c2": "6", "c6": "6", "c7": "6 ", "c8": "foo", "C 1": "86"} - Tue Apr 07 00:00:00 1970 | {"c3": "00096"} | {"c2": "6", "c6": "6", "c7": "6 ", "c8": "foo", "C 1": "96"} | Tue Apr 07 00:00:00 1970 | {"c3": "00096"} | {"c2": "6", "c6": "6", "c7": "6 ", "c8": "foo", "C 1": "96"} - Wed Jan 07 00:00:00 1970 | {"c3": "00106"} | {"c2": "6", "c6": "6", "c7": "6 ", "c8": "foo", "C 1": "106"} | Wed Jan 07 00:00:00 1970 | {"c3": "00106"} | {"c2": "6", "c6": "6", "c7": "6 ", "c8": "foo", "C 1": "106"} - Sat Jan 17 00:00:00 1970 | {"c3": "00116"} | {"c2": "6", "c6": "6", "c7": "6 ", "c8": "foo", "C 1": "116"} | Sat Jan 17 00:00:00 1970 | {"c3": "00116"} | {"c2": "6", "c6": "6", "c7": "6 ", "c8": "foo", "C 1": "116"} - Tue Jan 27 00:00:00 1970 | {"c3": "00126"} | {"c2": "6", "c6": "6", "c7": "6 ", "c8": "foo", "C 1": "126"} | Tue Jan 27 00:00:00 1970 | {"c3": "00126"} | {"c2": "6", "c6": "6", "c7": "6 ", "c8": "foo", "C 1": "126"} - Fri Feb 06 00:00:00 1970 | {"c3": "00136"} | {"c2": "6", "c6": "6", "c7": "6 ", "c8": "foo", "C 1": "136"} | Fri Feb 06 00:00:00 1970 | {"c3": "00136"} | {"c2": "6", "c6": "6", "c7": "6 ", "c8": "foo", "C 1": "136"} - Mon Feb 16 00:00:00 1970 | {"c3": "00146"} | {"c2": "6", "c6": "6", "c7": "6 ", "c8": "foo", "C 1": "146"} | Mon Feb 16 00:00:00 1970 | {"c3": "00146"} | {"c2": "6", "c6": "6", "c7": "6 ", "c8": "foo", "C 1": "146"} - Thu Feb 26 00:00:00 1970 | {"c3": "00156"} | {"c2": "6", "c6": "6", "c7": "6 ", "c8": "foo", "C 1": "156"} | Thu Feb 26 00:00:00 1970 | {"c3": "00156"} | {"c2": "6", "c6": "6", "c7": "6 ", "c8": "foo", "C 1": "156"} - Sun Mar 08 00:00:00 1970 | {"c3": "00166"} | {"c2": "6", "c6": "6", "c7": "6 ", "c8": "foo", "C 1": "166"} | Sun Mar 08 00:00:00 1970 | {"c3": "00166"} | {"c2": "6", "c6": "6", "c7": "6 ", "c8": "foo", "C 1": "166"} - Wed Mar 18 00:00:00 1970 | {"c3": "00176"} | {"c2": "6", "c6": "6", "c7": "6 ", "c8": "foo", "C 1": "176"} | Wed Mar 18 00:00:00 1970 | {"c3": "00176"} | {"c2": "6", "c6": "6", "c7": "6 ", "c8": "foo", "C 1": "176"} - Sat Mar 28 00:00:00 1970 | {"c3": "00186"} | {"c2": "6", "c6": "6", "c7": "6 ", "c8": "foo", "C 1": "186"} | Sat Mar 28 00:00:00 1970 | {"c3": "00186"} | {"c2": "6", "c6": "6", "c7": "6 ", "c8": "foo", "C 1": "186"} - Tue Apr 07 00:00:00 1970 | {"c3": "00196"} | {"c2": "6", "c6": "6", "c7": "6 ", "c8": "foo", "C 1": "196"} | Tue Apr 07 00:00:00 1970 | {"c3": "00196"} | {"c2": "6", "c6": "6", "c7": "6 ", "c8": "foo", "C 1": "196"} - Wed Jan 07 00:00:00 1970 | {"c3": "00206"} | {"c2": "6", "c6": "6", "c7": "6 ", "c8": "foo", "C 1": "206"} | Wed Jan 07 00:00:00 1970 | {"c3": "00206"} | {"c2": "6", "c6": "6", "c7": "6 ", "c8": "foo", "C 1": "206"} - Sat Jan 17 00:00:00 1970 | {"c3": "00216"} | {"c2": "6", "c6": "6", "c7": "6 ", "c8": "foo", "C 1": "216"} | Sat Jan 17 00:00:00 1970 | {"c3": "00216"} | {"c2": "6", "c6": "6", "c7": "6 ", "c8": "foo", "C 1": "216"} - Tue Jan 27 00:00:00 1970 | {"c3": "00226"} | {"c2": "6", "c6": "6", "c7": "6 ", "c8": "foo", "C 1": "226"} | Tue Jan 27 00:00:00 1970 | {"c3": "00226"} | {"c2": "6", "c6": "6", "c7": "6 ", "c8": "foo", "C 1": "226"} - Fri Feb 06 00:00:00 1970 | {"c3": "00236"} | {"c2": "6", "c6": "6", "c7": "6 ", "c8": "foo", "C 1": "236"} | Fri Feb 06 00:00:00 1970 | {"c3": "00236"} | {"c2": "6", "c6": "6", "c7": "6 ", "c8": "foo", "C 1": "236"} - Mon Feb 16 00:00:00 1970 | {"c3": "00246"} | {"c2": "6", "c6": "6", "c7": "6 ", "c8": "foo", "C 1": "246"} | Mon Feb 16 00:00:00 1970 | {"c3": "00246"} | {"c2": "6", "c6": "6", "c7": "6 ", "c8": "foo", "C 1": "246"} - Thu Feb 26 00:00:00 1970 | {"c3": "00256"} | {"c2": "6", "c6": "6", "c7": "6 ", "c8": "foo", "C 1": "256"} | Thu Feb 26 00:00:00 1970 | {"c3": "00256"} | {"c2": "6", "c6": "6", "c7": "6 ", "c8": "foo", "C 1": "256"} - Sun Mar 08 00:00:00 1970 | {"c3": "00266"} | {"c2": "6", "c6": "6", "c7": "6 ", "c8": "foo", "C 1": "266"} | Sun Mar 08 00:00:00 1970 | {"c3": "00266"} | {"c2": "6", "c6": "6", "c7": "6 ", "c8": "foo", "C 1": "266"} - Wed Mar 18 00:00:00 1970 | {"c3": "00276"} | {"c2": "6", "c6": "6", "c7": "6 ", "c8": "foo", "C 1": "276"} | Wed Mar 18 00:00:00 1970 | {"c3": "00276"} | {"c2": "6", "c6": "6", "c7": "6 ", "c8": "foo", "C 1": "276"} - Sat Mar 28 00:00:00 1970 | {"c3": "00286"} | {"c2": "6", "c6": "6", "c7": "6 ", "c8": "foo", "C 1": "286"} | Sat Mar 28 00:00:00 1970 | {"c3": "00286"} | {"c2": "6", "c6": "6", "c7": "6 ", "c8": "foo", "C 1": "286"} - Tue Apr 07 00:00:00 1970 | {"c3": "00296"} | {"c2": "6", "c6": "6", "c7": "6 ", "c8": "foo", "C 1": "296"} | Tue Apr 07 00:00:00 1970 | {"c3": "00296"} | {"c2": "6", "c6": "6", "c7": "6 ", "c8": "foo", "C 1": "296"} - Wed Jan 07 00:00:00 1970 | {"c3": "00306"} | {"c2": "6", "c6": "6", "c7": "6 ", "c8": "foo", "C 1": "306"} | Wed Jan 07 00:00:00 1970 | {"c3": "00306"} | {"c2": "6", "c6": "6", "c7": "6 ", "c8": "foo", "C 1": "306"} - Sat Jan 17 00:00:00 1970 | {"c3": "00316"} | {"c2": "6", "c6": "6", "c7": "6 ", "c8": "foo", "C 1": "316"} | Sat Jan 17 00:00:00 1970 | {"c3": "00316"} | {"c2": "6", "c6": "6", "c7": "6 ", "c8": "foo", "C 1": "316"} - Tue Jan 27 00:00:00 1970 | {"c3": "00326"} | {"c2": "6", "c6": "6", "c7": "6 ", "c8": "foo", "C 1": "326"} | Tue Jan 27 00:00:00 1970 | {"c3": "00326"} | {"c2": "6", "c6": "6", "c7": "6 ", "c8": "foo", "C 1": "326"} - Fri Feb 06 00:00:00 1970 | {"c3": "00336"} | {"c2": "6", "c6": "6", "c7": "6 ", "c8": "foo", "C 1": "336"} | Fri Feb 06 00:00:00 1970 | {"c3": "00336"} | {"c2": "6", "c6": "6", "c7": "6 ", "c8": "foo", "C 1": "336"} - Mon Feb 16 00:00:00 1970 | {"c3": "00346"} | {"c2": "6", "c6": "6", "c7": "6 ", "c8": "foo", "C 1": "346"} | Mon Feb 16 00:00:00 1970 | {"c3": "00346"} | {"c2": "6", "c6": "6", "c7": "6 ", "c8": "foo", "C 1": "346"} - Thu Feb 26 00:00:00 1970 | {"c3": "00356"} | {"c2": "6", "c6": "6", "c7": "6 ", "c8": "foo", "C 1": "356"} | Thu Feb 26 00:00:00 1970 | {"c3": "00356"} | {"c2": "6", "c6": "6", "c7": "6 ", "c8": "foo", "C 1": "356"} - Sun Mar 08 00:00:00 1970 | {"c3": "00366"} | {"c2": "6", "c6": "6", "c7": "6 ", "c8": "foo", "C 1": "366"} | Sun Mar 08 00:00:00 1970 | {"c3": "00366"} | {"c2": "6", "c6": "6", "c7": "6 ", "c8": "foo", "C 1": "366"} - Wed Mar 18 00:00:00 1970 | {"c3": "00376"} | {"c2": "6", "c6": "6", "c7": "6 ", "c8": "foo", "C 1": "376"} | Wed Mar 18 00:00:00 1970 | {"c3": "00376"} | {"c2": "6", "c6": "6", "c7": "6 ", "c8": "foo", "C 1": "376"} - Sat Mar 28 00:00:00 1970 | {"c3": "00386"} | {"c2": "6", "c6": "6", "c7": "6 ", "c8": "foo", "C 1": "386"} | Sat Mar 28 00:00:00 1970 | {"c3": "00386"} | {"c2": "6", "c6": "6", "c7": "6 ", "c8": "foo", "C 1": "386"} - Tue Apr 07 00:00:00 1970 | {"c3": "00396"} | {"c2": "6", "c6": "6", "c7": "6 ", "c8": "foo", "C 1": "396"} | Tue Apr 07 00:00:00 1970 | {"c3": "00396"} | {"c2": "6", "c6": "6", "c7": "6 ", "c8": "foo", "C 1": "396"} - Wed Jan 07 00:00:00 1970 | {"c3": "00406"} | {"c2": "6", "c6": "6", "c7": "6 ", "c8": "foo", "C 1": "406"} | Wed Jan 07 00:00:00 1970 | {"c3": "00406"} | {"c2": "6", "c6": "6", "c7": "6 ", "c8": "foo", "C 1": "406"} - Sat Jan 17 00:00:00 1970 | {"c3": "00416"} | {"c2": "6", "c6": "6", "c7": "6 ", "c8": "foo", "C 1": "416"} | Sat Jan 17 00:00:00 1970 | {"c3": "00416"} | {"c2": "6", "c6": "6", "c7": "6 ", "c8": "foo", "C 1": "416"} - Tue Jan 27 00:00:00 1970 | {"c3": "00426"} | {"c2": "6", "c6": "6", "c7": "6 ", "c8": "foo", "C 1": "426"} | Tue Jan 27 00:00:00 1970 | {"c3": "00426"} | {"c2": "6", "c6": "6", "c7": "6 ", "c8": "foo", "C 1": "426"} - Fri Feb 06 00:00:00 1970 | {"c3": "00436"} | {"c2": "6", "c6": "6", "c7": "6 ", "c8": "foo", "C 1": "436"} | Fri Feb 06 00:00:00 1970 | {"c3": "00436"} | {"c2": "6", "c6": "6", "c7": "6 ", "c8": "foo", "C 1": "436"} - Mon Feb 16 00:00:00 1970 | {"c3": "00446"} | {"c2": "6", "c6": "6", "c7": "6 ", "c8": "foo", "C 1": "446"} | Mon Feb 16 00:00:00 1970 | {"c3": "00446"} | {"c2": "6", "c6": "6", "c7": "6 ", "c8": "foo", "C 1": "446"} - Thu Feb 26 00:00:00 1970 | {"c3": "00456"} | {"c2": "6", "c6": "6", "c7": "6 ", "c8": "foo", "C 1": "456"} | Thu Feb 26 00:00:00 1970 | {"c3": "00456"} | {"c2": "6", "c6": "6", "c7": "6 ", "c8": "foo", "C 1": "456"} - Sun Mar 08 00:00:00 1970 | {"c3": "00466"} | {"c2": "6", "c6": "6", "c7": "6 ", "c8": "foo", "C 1": "466"} | Sun Mar 08 00:00:00 1970 | {"c3": "00466"} | {"c2": "6", "c6": "6", "c7": "6 ", "c8": "foo", "C 1": "466"} - Wed Mar 18 00:00:00 1970 | {"c3": "00476"} | {"c2": "6", "c6": "6", "c7": "6 ", "c8": "foo", "C 1": "476"} | Wed Mar 18 00:00:00 1970 | {"c3": "00476"} | {"c2": "6", "c6": "6", "c7": "6 ", "c8": "foo", "C 1": "476"} - Sat Mar 28 00:00:00 1970 | {"c3": "00486"} | {"c2": "6", "c6": "6", "c7": "6 ", "c8": "foo", "C 1": "486"} | Sat Mar 28 00:00:00 1970 | {"c3": "00486"} | {"c2": "6", "c6": "6", "c7": "6 ", "c8": "foo", "C 1": "486"} - Tue Apr 07 00:00:00 1970 | {"c3": "00496"} | {"c2": "6", "c6": "6", "c7": "6 ", "c8": "foo", "C 1": "496"} | Tue Apr 07 00:00:00 1970 | {"c3": "00496"} | {"c2": "6", "c6": "6", "c7": "6 ", "c8": "foo", "C 1": "496"} - Wed Jan 07 00:00:00 1970 | {"c3": "00506"} | {"c2": "6", "c6": "6", "c7": "6 ", "c8": "foo", "C 1": "506"} | Wed Jan 07 00:00:00 1970 | {"c3": "00506"} | {"c2": "6", "c6": "6", "c7": "6 ", "c8": "foo", "C 1": "506"} - Sat Jan 17 00:00:00 1970 | {"c3": "00516"} | {"c2": "6", "c6": "6", "c7": "6 ", "c8": "foo", "C 1": "516"} | Sat Jan 17 00:00:00 1970 | {"c3": "00516"} | {"c2": "6", "c6": "6", "c7": "6 ", "c8": "foo", "C 1": "516"} - Tue Jan 27 00:00:00 1970 | {"c3": "00526"} | {"c2": "6", "c6": "6", "c7": "6 ", "c8": "foo", "C 1": "526"} | Tue Jan 27 00:00:00 1970 | {"c3": "00526"} | {"c2": "6", "c6": "6", "c7": "6 ", "c8": "foo", "C 1": "526"} - Fri Feb 06 00:00:00 1970 | {"c3": "00536"} | {"c2": "6", "c6": "6", "c7": "6 ", "c8": "foo", "C 1": "536"} | Fri Feb 06 00:00:00 1970 | {"c3": "00536"} | {"c2": "6", "c6": "6", "c7": "6 ", "c8": "foo", "C 1": "536"} - Mon Feb 16 00:00:00 1970 | {"c3": "00546"} | {"c2": "6", "c6": "6", "c7": "6 ", "c8": "foo", "C 1": "546"} | Mon Feb 16 00:00:00 1970 | {"c3": "00546"} | {"c2": "6", "c6": "6", "c7": "6 ", "c8": "foo", "C 1": "546"} - Thu Feb 26 00:00:00 1970 | {"c3": "00556"} | {"c2": "6", "c6": "6", "c7": "6 ", "c8": "foo", "C 1": "556"} | Thu Feb 26 00:00:00 1970 | {"c3": "00556"} | {"c2": "6", "c6": "6", "c7": "6 ", "c8": "foo", "C 1": "556"} - Sun Mar 08 00:00:00 1970 | {"c3": "00566"} | {"c2": "6", "c6": "6", "c7": "6 ", "c8": "foo", "C 1": "566"} | Sun Mar 08 00:00:00 1970 | {"c3": "00566"} | {"c2": "6", "c6": "6", "c7": "6 ", "c8": "foo", "C 1": "566"} - Wed Mar 18 00:00:00 1970 | {"c3": "00576"} | {"c2": "6", "c6": "6", "c7": "6 ", "c8": "foo", "C 1": "576"} | Wed Mar 18 00:00:00 1970 | {"c3": "00576"} | {"c2": "6", "c6": "6", "c7": "6 ", "c8": "foo", "C 1": "576"} - Sat Mar 28 00:00:00 1970 | {"c3": "00586"} | {"c2": "6", "c6": "6", "c7": "6 ", "c8": "foo", "C 1": "586"} | Sat Mar 28 00:00:00 1970 | {"c3": "00586"} | {"c2": "6", "c6": "6", "c7": "6 ", "c8": "foo", "C 1": "586"} - Tue Apr 07 00:00:00 1970 | {"c3": "00596"} | {"c2": "6", "c6": "6", "c7": "6 ", "c8": "foo", "C 1": "596"} | Tue Apr 07 00:00:00 1970 | {"c3": "00596"} | {"c2": "6", "c6": "6", "c7": "6 ", "c8": "foo", "C 1": "596"} - Wed Jan 07 00:00:00 1970 | {"c3": "00606"} | {"c2": "6", "c6": "6", "c7": "6 ", "c8": "foo", "C 1": "606"} | Wed Jan 07 00:00:00 1970 | {"c3": "00606"} | {"c2": "6", "c6": "6", "c7": "6 ", "c8": "foo", "C 1": "606"} - Sat Jan 17 00:00:00 1970 | {"c3": "00616"} | {"c2": "6", "c6": "6", "c7": "6 ", "c8": "foo", "C 1": "616"} | Sat Jan 17 00:00:00 1970 | {"c3": "00616"} | {"c2": "6", "c6": "6", "c7": "6 ", "c8": "foo", "C 1": "616"} - Tue Jan 27 00:00:00 1970 | {"c3": "00626"} | {"c2": "6", "c6": "6", "c7": "6 ", "c8": "foo", "C 1": "626"} | Tue Jan 27 00:00:00 1970 | {"c3": "00626"} | {"c2": "6", "c6": "6", "c7": "6 ", "c8": "foo", "C 1": "626"} - Fri Feb 06 00:00:00 1970 | {"c3": "00636"} | {"c2": "6", "c6": "6", "c7": "6 ", "c8": "foo", "C 1": "636"} | Fri Feb 06 00:00:00 1970 | {"c3": "00636"} | {"c2": "6", "c6": "6", "c7": "6 ", "c8": "foo", "C 1": "636"} - Mon Feb 16 00:00:00 1970 | {"c3": "00646"} | {"c2": "6", "c6": "6", "c7": "6 ", "c8": "foo", "C 1": "646"} | Mon Feb 16 00:00:00 1970 | {"c3": "00646"} | {"c2": "6", "c6": "6", "c7": "6 ", "c8": "foo", "C 1": "646"} - Thu Feb 26 00:00:00 1970 | {"c3": "00656"} | {"c2": "6", "c6": "6", "c7": "6 ", "c8": "foo", "C 1": "656"} | Thu Feb 26 00:00:00 1970 | {"c3": "00656"} | {"c2": "6", "c6": "6", "c7": "6 ", "c8": "foo", "C 1": "656"} - Sun Mar 08 00:00:00 1970 | {"c3": "00666"} | {"c2": "6", "c6": "6", "c7": "6 ", "c8": "foo", "C 1": "666"} | Sun Mar 08 00:00:00 1970 | {"c3": "00666"} | {"c2": "6", "c6": "6", "c7": "6 ", "c8": "foo", "C 1": "666"} - Wed Mar 18 00:00:00 1970 | {"c3": "00676"} | {"c2": "6", "c6": "6", "c7": "6 ", "c8": "foo", "C 1": "676"} | Wed Mar 18 00:00:00 1970 | {"c3": "00676"} | {"c2": "6", "c6": "6", "c7": "6 ", "c8": "foo", "C 1": "676"} - Sat Mar 28 00:00:00 1970 | {"c3": "00686"} | {"c2": "6", "c6": "6", "c7": "6 ", "c8": "foo", "C 1": "686"} | Sat Mar 28 00:00:00 1970 | {"c3": "00686"} | {"c2": "6", "c6": "6", "c7": "6 ", "c8": "foo", "C 1": "686"} - Tue Apr 07 00:00:00 1970 | {"c3": "00696"} | {"c2": "6", "c6": "6", "c7": "6 ", "c8": "foo", "C 1": "696"} | Tue Apr 07 00:00:00 1970 | {"c3": "00696"} | {"c2": "6", "c6": "6", "c7": "6 ", "c8": "foo", "C 1": "696"} - Wed Jan 07 00:00:00 1970 | {"c3": "00706"} | {"c2": "6", "c6": "6", "c7": "6 ", "c8": "foo", "C 1": "706"} | Wed Jan 07 00:00:00 1970 | {"c3": "00706"} | {"c2": "6", "c6": "6", "c7": "6 ", "c8": "foo", "C 1": "706"} - Sat Jan 17 00:00:00 1970 | {"c3": "00716"} | {"c2": "6", "c6": "6", "c7": "6 ", "c8": "foo", "C 1": "716"} | Sat Jan 17 00:00:00 1970 | {"c3": "00716"} | {"c2": "6", "c6": "6", "c7": "6 ", "c8": "foo", "C 1": "716"} - Tue Jan 27 00:00:00 1970 | {"c3": "00726"} | {"c2": "6", "c6": "6", "c7": "6 ", "c8": "foo", "C 1": "726"} | Tue Jan 27 00:00:00 1970 | {"c3": "00726"} | {"c2": "6", "c6": "6", "c7": "6 ", "c8": "foo", "C 1": "726"} - Fri Feb 06 00:00:00 1970 | {"c3": "00736"} | {"c2": "6", "c6": "6", "c7": "6 ", "c8": "foo", "C 1": "736"} | Fri Feb 06 00:00:00 1970 | {"c3": "00736"} | {"c2": "6", "c6": "6", "c7": "6 ", "c8": "foo", "C 1": "736"} - Mon Feb 16 00:00:00 1970 | {"c3": "00746"} | {"c2": "6", "c6": "6", "c7": "6 ", "c8": "foo", "C 1": "746"} | Mon Feb 16 00:00:00 1970 | {"c3": "00746"} | {"c2": "6", "c6": "6", "c7": "6 ", "c8": "foo", "C 1": "746"} - Thu Feb 26 00:00:00 1970 | {"c3": "00756"} | {"c2": "6", "c6": "6", "c7": "6 ", "c8": "foo", "C 1": "756"} | Thu Feb 26 00:00:00 1970 | {"c3": "00756"} | {"c2": "6", "c6": "6", "c7": "6 ", "c8": "foo", "C 1": "756"} - Sun Mar 08 00:00:00 1970 | {"c3": "00766"} | {"c2": "6", "c6": "6", "c7": "6 ", "c8": "foo", "C 1": "766"} | Sun Mar 08 00:00:00 1970 | {"c3": "00766"} | {"c2": "6", "c6": "6", "c7": "6 ", "c8": "foo", "C 1": "766"} - Wed Mar 18 00:00:00 1970 | {"c3": "00776"} | {"c2": "6", "c6": "6", "c7": "6 ", "c8": "foo", "C 1": "776"} | Wed Mar 18 00:00:00 1970 | {"c3": "00776"} | {"c2": "6", "c6": "6", "c7": "6 ", "c8": "foo", "C 1": "776"} - Sat Mar 28 00:00:00 1970 | {"c3": "00786"} | {"c2": "6", "c6": "6", "c7": "6 ", "c8": "foo", "C 1": "786"} | Sat Mar 28 00:00:00 1970 | {"c3": "00786"} | {"c2": "6", "c6": "6", "c7": "6 ", "c8": "foo", "C 1": "786"} - Tue Apr 07 00:00:00 1970 | {"c3": "00796"} | {"c2": "6", "c6": "6", "c7": "6 ", "c8": "foo", "C 1": "796"} | Tue Apr 07 00:00:00 1970 | {"c3": "00796"} | {"c2": "6", "c6": "6", "c7": "6 ", "c8": "foo", "C 1": "796"} - Wed Jan 07 00:00:00 1970 | {"c3": "00806"} | {"c2": "6", "c6": "6", "c7": "6 ", "c8": "foo", "C 1": "806"} | Wed Jan 07 00:00:00 1970 | {"c3": "00806"} | {"c2": "6", "c6": "6", "c7": "6 ", "c8": "foo", "C 1": "806"} - Sat Jan 17 00:00:00 1970 | {"c3": "00816"} | {"c2": "6", "c6": "6", "c7": "6 ", "c8": "foo", "C 1": "816"} | Sat Jan 17 00:00:00 1970 | {"c3": "00816"} | {"c2": "6", "c6": "6", "c7": "6 ", "c8": "foo", "C 1": "816"} - Tue Jan 27 00:00:00 1970 | {"c3": "00826"} | {"c2": "6", "c6": "6", "c7": "6 ", "c8": "foo", "C 1": "826"} | Tue Jan 27 00:00:00 1970 | {"c3": "00826"} | {"c2": "6", "c6": "6", "c7": "6 ", "c8": "foo", "C 1": "826"} - Fri Feb 06 00:00:00 1970 | {"c3": "00836"} | {"c2": "6", "c6": "6", "c7": "6 ", "c8": "foo", "C 1": "836"} | Fri Feb 06 00:00:00 1970 | {"c3": "00836"} | {"c2": "6", "c6": "6", "c7": "6 ", "c8": "foo", "C 1": "836"} - Mon Feb 16 00:00:00 1970 | {"c3": "00846"} | {"c2": "6", "c6": "6", "c7": "6 ", "c8": "foo", "C 1": "846"} | Mon Feb 16 00:00:00 1970 | {"c3": "00846"} | {"c2": "6", "c6": "6", "c7": "6 ", "c8": "foo", "C 1": "846"} - Thu Feb 26 00:00:00 1970 | {"c3": "00856"} | {"c2": "6", "c6": "6", "c7": "6 ", "c8": "foo", "C 1": "856"} | Thu Feb 26 00:00:00 1970 | {"c3": "00856"} | {"c2": "6", "c6": "6", "c7": "6 ", "c8": "foo", "C 1": "856"} - Sun Mar 08 00:00:00 1970 | {"c3": "00866"} | {"c2": "6", "c6": "6", "c7": "6 ", "c8": "foo", "C 1": "866"} | Sun Mar 08 00:00:00 1970 | {"c3": "00866"} | {"c2": "6", "c6": "6", "c7": "6 ", "c8": "foo", "C 1": "866"} - Wed Mar 18 00:00:00 1970 | {"c3": "00876"} | {"c2": "6", "c6": "6", "c7": "6 ", "c8": "foo", "C 1": "876"} | Wed Mar 18 00:00:00 1970 | {"c3": "00876"} | {"c2": "6", "c6": "6", "c7": "6 ", "c8": "foo", "C 1": "876"} - Sat Mar 28 00:00:00 1970 | {"c3": "00886"} | {"c2": "6", "c6": "6", "c7": "6 ", "c8": "foo", "C 1": "886"} | Sat Mar 28 00:00:00 1970 | {"c3": "00886"} | {"c2": "6", "c6": "6", "c7": "6 ", "c8": "foo", "C 1": "886"} - Tue Apr 07 00:00:00 1970 | {"c3": "00896"} | {"c2": "6", "c6": "6", "c7": "6 ", "c8": "foo", "C 1": "896"} | Tue Apr 07 00:00:00 1970 | {"c3": "00896"} | {"c2": "6", "c6": "6", "c7": "6 ", "c8": "foo", "C 1": "896"} - Wed Jan 07 00:00:00 1970 | {"c3": "00906"} | {"c2": "6", "c6": "6", "c7": "6 ", "c8": "foo", "C 1": "906"} | Wed Jan 07 00:00:00 1970 | {"c3": "00906"} | {"c2": "6", "c6": "6", "c7": "6 ", "c8": "foo", "C 1": "906"} - Sat Jan 17 00:00:00 1970 | {"c3": "00916"} | {"c2": "6", "c6": "6", "c7": "6 ", "c8": "foo", "C 1": "916"} | Sat Jan 17 00:00:00 1970 | {"c3": "00916"} | {"c2": "6", "c6": "6", "c7": "6 ", "c8": "foo", "C 1": "916"} - Tue Jan 27 00:00:00 1970 | {"c3": "00926"} | {"c2": "6", "c6": "6", "c7": "6 ", "c8": "foo", "C 1": "926"} | Tue Jan 27 00:00:00 1970 | {"c3": "00926"} | {"c2": "6", "c6": "6", "c7": "6 ", "c8": "foo", "C 1": "926"} - Fri Feb 06 00:00:00 1970 | {"c3": "00936"} | {"c2": "6", "c6": "6", "c7": "6 ", "c8": "foo", "C 1": "936"} | Fri Feb 06 00:00:00 1970 | {"c3": "00936"} | {"c2": "6", "c6": "6", "c7": "6 ", "c8": "foo", "C 1": "936"} - Mon Feb 16 00:00:00 1970 | {"c3": "00946"} | {"c2": "6", "c6": "6", "c7": "6 ", "c8": "foo", "C 1": "946"} | Mon Feb 16 00:00:00 1970 | {"c3": "00946"} | {"c2": "6", "c6": "6", "c7": "6 ", "c8": "foo", "C 1": "946"} - Thu Feb 26 00:00:00 1970 | {"c3": "00956"} | {"c2": "6", "c6": "6", "c7": "6 ", "c8": "foo", "C 1": "956"} | Thu Feb 26 00:00:00 1970 | {"c3": "00956"} | {"c2": "6", "c6": "6", "c7": "6 ", "c8": "foo", "C 1": "956"} - Sun Mar 08 00:00:00 1970 | {"c3": "00966"} | {"c2": "6", "c6": "6", "c7": "6 ", "c8": "foo", "C 1": "966"} | Sun Mar 08 00:00:00 1970 | {"c3": "00966"} | {"c2": "6", "c6": "6", "c7": "6 ", "c8": "foo", "C 1": "966"} - Wed Mar 18 00:00:00 1970 | {"c3": "00976"} | {"c2": "6", "c6": "6", "c7": "6 ", "c8": "foo", "C 1": "976"} | Wed Mar 18 00:00:00 1970 | {"c3": "00976"} | {"c2": "6", "c6": "6", "c7": "6 ", "c8": "foo", "C 1": "976"} - Sat Mar 28 00:00:00 1970 | {"c3": "00986"} | {"c2": "6", "c6": "6", "c7": "6 ", "c8": "foo", "C 1": "986"} | Sat Mar 28 00:00:00 1970 | {"c3": "00986"} | {"c2": "6", "c6": "6", "c7": "6 ", "c8": "foo", "C 1": "986"} - Tue Apr 07 00:00:00 1970 | {"c3": "00996"} | {"c2": "6", "c6": "6", "c7": "6 ", "c8": "foo", "C 1": "996"} | Tue Apr 07 00:00:00 1970 | {"c3": "00996"} | {"c2": "6", "c6": "6", "c7": "6 ", "c8": "foo", "C 1": "996"} + time | tags | fields | time | tags | fields +------------------------------+-----------------+-----------------------------------------------------------------------+------------------------------+-----------------+----------------------------------------------------------------------- + Wed Jan 07 00:00:00 1970 PST | {"c3": "00006"} | {"c2": "6", "c6": "6", "c7": "6 ", "c8": "foo", "C 1": "6"} | Wed Jan 07 00:00:00 1970 PST | {"c3": "00006"} | {"c2": "6", "c6": "6", "c7": "6 ", "c8": "foo", "C 1": "6"} + Sat Jan 17 00:00:00 1970 PST | {"c3": "00016"} | {"c2": "6", "c6": "6", "c7": "6 ", "c8": "foo", "C 1": "16"} | Sat Jan 17 00:00:00 1970 PST | {"c3": "00016"} | {"c2": "6", "c6": "6", "c7": "6 ", "c8": "foo", "C 1": "16"} + Tue Jan 27 00:00:00 1970 PST | {"c3": "00026"} | {"c2": "6", "c6": "6", "c7": "6 ", "c8": "foo", "C 1": "26"} | Tue Jan 27 00:00:00 1970 PST | {"c3": "00026"} | {"c2": "6", "c6": "6", "c7": "6 ", "c8": "foo", "C 1": "26"} + Fri Feb 06 00:00:00 1970 PST | {"c3": "00036"} | {"c2": "6", "c6": "6", "c7": "6 ", "c8": "foo", "C 1": "36"} | Fri Feb 06 00:00:00 1970 PST | {"c3": "00036"} | {"c2": "6", "c6": "6", "c7": "6 ", "c8": "foo", "C 1": "36"} + Mon Feb 16 00:00:00 1970 PST | {"c3": "00046"} | {"c2": "6", "c6": "6", "c7": "6 ", "c8": "foo", "C 1": "46"} | Mon Feb 16 00:00:00 1970 PST | {"c3": "00046"} | {"c2": "6", "c6": "6", "c7": "6 ", "c8": "foo", "C 1": "46"} + Thu Feb 26 00:00:00 1970 PST | {"c3": "00056"} | {"c2": "6", "c6": "6", "c7": "6 ", "c8": "foo", "C 1": "56"} | Thu Feb 26 00:00:00 1970 PST | {"c3": "00056"} | {"c2": "6", "c6": "6", "c7": "6 ", "c8": "foo", "C 1": "56"} + Sun Mar 08 00:00:00 1970 PST | {"c3": "00066"} | {"c2": "6", "c6": "6", "c7": "6 ", "c8": "foo", "C 1": "66"} | Sun Mar 08 00:00:00 1970 PST | {"c3": "00066"} | {"c2": "6", "c6": "6", "c7": "6 ", "c8": "foo", "C 1": "66"} + Wed Mar 18 00:00:00 1970 PST | {"c3": "00076"} | {"c2": "6", "c6": "6", "c7": "6 ", "c8": "foo", "C 1": "76"} | Wed Mar 18 00:00:00 1970 PST | {"c3": "00076"} | {"c2": "6", "c6": "6", "c7": "6 ", "c8": "foo", "C 1": "76"} + Sat Mar 28 00:00:00 1970 PST | {"c3": "00086"} | {"c2": "6", "c6": "6", "c7": "6 ", "c8": "foo", "C 1": "86"} | Sat Mar 28 00:00:00 1970 PST | {"c3": "00086"} | {"c2": "6", "c6": "6", "c7": "6 ", "c8": "foo", "C 1": "86"} + Tue Apr 07 00:00:00 1970 PST | {"c3": "00096"} | {"c2": "6", "c6": "6", "c7": "6 ", "c8": "foo", "C 1": "96"} | Tue Apr 07 00:00:00 1970 PST | {"c3": "00096"} | {"c2": "6", "c6": "6", "c7": "6 ", "c8": "foo", "C 1": "96"} + Wed Jan 07 00:00:00 1970 PST | {"c3": "00106"} | {"c2": "6", "c6": "6", "c7": "6 ", "c8": "foo", "C 1": "106"} | Wed Jan 07 00:00:00 1970 PST | {"c3": "00106"} | {"c2": "6", "c6": "6", "c7": "6 ", "c8": "foo", "C 1": "106"} + Sat Jan 17 00:00:00 1970 PST | {"c3": "00116"} | {"c2": "6", "c6": "6", "c7": "6 ", "c8": "foo", "C 1": "116"} | Sat Jan 17 00:00:00 1970 PST | {"c3": "00116"} | {"c2": "6", "c6": "6", "c7": "6 ", "c8": "foo", "C 1": "116"} + Tue Jan 27 00:00:00 1970 PST | {"c3": "00126"} | {"c2": "6", "c6": "6", "c7": "6 ", "c8": "foo", "C 1": "126"} | Tue Jan 27 00:00:00 1970 PST | {"c3": "00126"} | {"c2": "6", "c6": "6", "c7": "6 ", "c8": "foo", "C 1": "126"} + Fri Feb 06 00:00:00 1970 PST | {"c3": "00136"} | {"c2": "6", "c6": "6", "c7": "6 ", "c8": "foo", "C 1": "136"} | Fri Feb 06 00:00:00 1970 PST | {"c3": "00136"} | {"c2": "6", "c6": "6", "c7": "6 ", "c8": "foo", "C 1": "136"} + Mon Feb 16 00:00:00 1970 PST | {"c3": "00146"} | {"c2": "6", "c6": "6", "c7": "6 ", "c8": "foo", "C 1": "146"} | Mon Feb 16 00:00:00 1970 PST | {"c3": "00146"} | {"c2": "6", "c6": "6", "c7": "6 ", "c8": "foo", "C 1": "146"} + Thu Feb 26 00:00:00 1970 PST | {"c3": "00156"} | {"c2": "6", "c6": "6", "c7": "6 ", "c8": "foo", "C 1": "156"} | Thu Feb 26 00:00:00 1970 PST | {"c3": "00156"} | {"c2": "6", "c6": "6", "c7": "6 ", "c8": "foo", "C 1": "156"} + Sun Mar 08 00:00:00 1970 PST | {"c3": "00166"} | {"c2": "6", "c6": "6", "c7": "6 ", "c8": "foo", "C 1": "166"} | Sun Mar 08 00:00:00 1970 PST | {"c3": "00166"} | {"c2": "6", "c6": "6", "c7": "6 ", "c8": "foo", "C 1": "166"} + Wed Mar 18 00:00:00 1970 PST | {"c3": "00176"} | {"c2": "6", "c6": "6", "c7": "6 ", "c8": "foo", "C 1": "176"} | Wed Mar 18 00:00:00 1970 PST | {"c3": "00176"} | {"c2": "6", "c6": "6", "c7": "6 ", "c8": "foo", "C 1": "176"} + Sat Mar 28 00:00:00 1970 PST | {"c3": "00186"} | {"c2": "6", "c6": "6", "c7": "6 ", "c8": "foo", "C 1": "186"} | Sat Mar 28 00:00:00 1970 PST | {"c3": "00186"} | {"c2": "6", "c6": "6", "c7": "6 ", "c8": "foo", "C 1": "186"} + Tue Apr 07 00:00:00 1970 PST | {"c3": "00196"} | {"c2": "6", "c6": "6", "c7": "6 ", "c8": "foo", "C 1": "196"} | Tue Apr 07 00:00:00 1970 PST | {"c3": "00196"} | {"c2": "6", "c6": "6", "c7": "6 ", "c8": "foo", "C 1": "196"} + Wed Jan 07 00:00:00 1970 PST | {"c3": "00206"} | {"c2": "6", "c6": "6", "c7": "6 ", "c8": "foo", "C 1": "206"} | Wed Jan 07 00:00:00 1970 PST | {"c3": "00206"} | {"c2": "6", "c6": "6", "c7": "6 ", "c8": "foo", "C 1": "206"} + Sat Jan 17 00:00:00 1970 PST | {"c3": "00216"} | {"c2": "6", "c6": "6", "c7": "6 ", "c8": "foo", "C 1": "216"} | Sat Jan 17 00:00:00 1970 PST | {"c3": "00216"} | {"c2": "6", "c6": "6", "c7": "6 ", "c8": "foo", "C 1": "216"} + Tue Jan 27 00:00:00 1970 PST | {"c3": "00226"} | {"c2": "6", "c6": "6", "c7": "6 ", "c8": "foo", "C 1": "226"} | Tue Jan 27 00:00:00 1970 PST | {"c3": "00226"} | {"c2": "6", "c6": "6", "c7": "6 ", "c8": "foo", "C 1": "226"} + Fri Feb 06 00:00:00 1970 PST | {"c3": "00236"} | {"c2": "6", "c6": "6", "c7": "6 ", "c8": "foo", "C 1": "236"} | Fri Feb 06 00:00:00 1970 PST | {"c3": "00236"} | {"c2": "6", "c6": "6", "c7": "6 ", "c8": "foo", "C 1": "236"} + Mon Feb 16 00:00:00 1970 PST | {"c3": "00246"} | {"c2": "6", "c6": "6", "c7": "6 ", "c8": "foo", "C 1": "246"} | Mon Feb 16 00:00:00 1970 PST | {"c3": "00246"} | {"c2": "6", "c6": "6", "c7": "6 ", "c8": "foo", "C 1": "246"} + Thu Feb 26 00:00:00 1970 PST | {"c3": "00256"} | {"c2": "6", "c6": "6", "c7": "6 ", "c8": "foo", "C 1": "256"} | Thu Feb 26 00:00:00 1970 PST | {"c3": "00256"} | {"c2": "6", "c6": "6", "c7": "6 ", "c8": "foo", "C 1": "256"} + Sun Mar 08 00:00:00 1970 PST | {"c3": "00266"} | {"c2": "6", "c6": "6", "c7": "6 ", "c8": "foo", "C 1": "266"} | Sun Mar 08 00:00:00 1970 PST | {"c3": "00266"} | {"c2": "6", "c6": "6", "c7": "6 ", "c8": "foo", "C 1": "266"} + Wed Mar 18 00:00:00 1970 PST | {"c3": "00276"} | {"c2": "6", "c6": "6", "c7": "6 ", "c8": "foo", "C 1": "276"} | Wed Mar 18 00:00:00 1970 PST | {"c3": "00276"} | {"c2": "6", "c6": "6", "c7": "6 ", "c8": "foo", "C 1": "276"} + Sat Mar 28 00:00:00 1970 PST | {"c3": "00286"} | {"c2": "6", "c6": "6", "c7": "6 ", "c8": "foo", "C 1": "286"} | Sat Mar 28 00:00:00 1970 PST | {"c3": "00286"} | {"c2": "6", "c6": "6", "c7": "6 ", "c8": "foo", "C 1": "286"} + Tue Apr 07 00:00:00 1970 PST | {"c3": "00296"} | {"c2": "6", "c6": "6", "c7": "6 ", "c8": "foo", "C 1": "296"} | Tue Apr 07 00:00:00 1970 PST | {"c3": "00296"} | {"c2": "6", "c6": "6", "c7": "6 ", "c8": "foo", "C 1": "296"} + Wed Jan 07 00:00:00 1970 PST | {"c3": "00306"} | {"c2": "6", "c6": "6", "c7": "6 ", "c8": "foo", "C 1": "306"} | Wed Jan 07 00:00:00 1970 PST | {"c3": "00306"} | {"c2": "6", "c6": "6", "c7": "6 ", "c8": "foo", "C 1": "306"} + Sat Jan 17 00:00:00 1970 PST | {"c3": "00316"} | {"c2": "6", "c6": "6", "c7": "6 ", "c8": "foo", "C 1": "316"} | Sat Jan 17 00:00:00 1970 PST | {"c3": "00316"} | {"c2": "6", "c6": "6", "c7": "6 ", "c8": "foo", "C 1": "316"} + Tue Jan 27 00:00:00 1970 PST | {"c3": "00326"} | {"c2": "6", "c6": "6", "c7": "6 ", "c8": "foo", "C 1": "326"} | Tue Jan 27 00:00:00 1970 PST | {"c3": "00326"} | {"c2": "6", "c6": "6", "c7": "6 ", "c8": "foo", "C 1": "326"} + Fri Feb 06 00:00:00 1970 PST | {"c3": "00336"} | {"c2": "6", "c6": "6", "c7": "6 ", "c8": "foo", "C 1": "336"} | Fri Feb 06 00:00:00 1970 PST | {"c3": "00336"} | {"c2": "6", "c6": "6", "c7": "6 ", "c8": "foo", "C 1": "336"} + Mon Feb 16 00:00:00 1970 PST | {"c3": "00346"} | {"c2": "6", "c6": "6", "c7": "6 ", "c8": "foo", "C 1": "346"} | Mon Feb 16 00:00:00 1970 PST | {"c3": "00346"} | {"c2": "6", "c6": "6", "c7": "6 ", "c8": "foo", "C 1": "346"} + Thu Feb 26 00:00:00 1970 PST | {"c3": "00356"} | {"c2": "6", "c6": "6", "c7": "6 ", "c8": "foo", "C 1": "356"} | Thu Feb 26 00:00:00 1970 PST | {"c3": "00356"} | {"c2": "6", "c6": "6", "c7": "6 ", "c8": "foo", "C 1": "356"} + Sun Mar 08 00:00:00 1970 PST | {"c3": "00366"} | {"c2": "6", "c6": "6", "c7": "6 ", "c8": "foo", "C 1": "366"} | Sun Mar 08 00:00:00 1970 PST | {"c3": "00366"} | {"c2": "6", "c6": "6", "c7": "6 ", "c8": "foo", "C 1": "366"} + Wed Mar 18 00:00:00 1970 PST | {"c3": "00376"} | {"c2": "6", "c6": "6", "c7": "6 ", "c8": "foo", "C 1": "376"} | Wed Mar 18 00:00:00 1970 PST | {"c3": "00376"} | {"c2": "6", "c6": "6", "c7": "6 ", "c8": "foo", "C 1": "376"} + Sat Mar 28 00:00:00 1970 PST | {"c3": "00386"} | {"c2": "6", "c6": "6", "c7": "6 ", "c8": "foo", "C 1": "386"} | Sat Mar 28 00:00:00 1970 PST | {"c3": "00386"} | {"c2": "6", "c6": "6", "c7": "6 ", "c8": "foo", "C 1": "386"} + Tue Apr 07 00:00:00 1970 PST | {"c3": "00396"} | {"c2": "6", "c6": "6", "c7": "6 ", "c8": "foo", "C 1": "396"} | Tue Apr 07 00:00:00 1970 PST | {"c3": "00396"} | {"c2": "6", "c6": "6", "c7": "6 ", "c8": "foo", "C 1": "396"} + Wed Jan 07 00:00:00 1970 PST | {"c3": "00406"} | {"c2": "6", "c6": "6", "c7": "6 ", "c8": "foo", "C 1": "406"} | Wed Jan 07 00:00:00 1970 PST | {"c3": "00406"} | {"c2": "6", "c6": "6", "c7": "6 ", "c8": "foo", "C 1": "406"} + Sat Jan 17 00:00:00 1970 PST | {"c3": "00416"} | {"c2": "6", "c6": "6", "c7": "6 ", "c8": "foo", "C 1": "416"} | Sat Jan 17 00:00:00 1970 PST | {"c3": "00416"} | {"c2": "6", "c6": "6", "c7": "6 ", "c8": "foo", "C 1": "416"} + Tue Jan 27 00:00:00 1970 PST | {"c3": "00426"} | {"c2": "6", "c6": "6", "c7": "6 ", "c8": "foo", "C 1": "426"} | Tue Jan 27 00:00:00 1970 PST | {"c3": "00426"} | {"c2": "6", "c6": "6", "c7": "6 ", "c8": "foo", "C 1": "426"} + Fri Feb 06 00:00:00 1970 PST | {"c3": "00436"} | {"c2": "6", "c6": "6", "c7": "6 ", "c8": "foo", "C 1": "436"} | Fri Feb 06 00:00:00 1970 PST | {"c3": "00436"} | {"c2": "6", "c6": "6", "c7": "6 ", "c8": "foo", "C 1": "436"} + Mon Feb 16 00:00:00 1970 PST | {"c3": "00446"} | {"c2": "6", "c6": "6", "c7": "6 ", "c8": "foo", "C 1": "446"} | Mon Feb 16 00:00:00 1970 PST | {"c3": "00446"} | {"c2": "6", "c6": "6", "c7": "6 ", "c8": "foo", "C 1": "446"} + Thu Feb 26 00:00:00 1970 PST | {"c3": "00456"} | {"c2": "6", "c6": "6", "c7": "6 ", "c8": "foo", "C 1": "456"} | Thu Feb 26 00:00:00 1970 PST | {"c3": "00456"} | {"c2": "6", "c6": "6", "c7": "6 ", "c8": "foo", "C 1": "456"} + Sun Mar 08 00:00:00 1970 PST | {"c3": "00466"} | {"c2": "6", "c6": "6", "c7": "6 ", "c8": "foo", "C 1": "466"} | Sun Mar 08 00:00:00 1970 PST | {"c3": "00466"} | {"c2": "6", "c6": "6", "c7": "6 ", "c8": "foo", "C 1": "466"} + Wed Mar 18 00:00:00 1970 PST | {"c3": "00476"} | {"c2": "6", "c6": "6", "c7": "6 ", "c8": "foo", "C 1": "476"} | Wed Mar 18 00:00:00 1970 PST | {"c3": "00476"} | {"c2": "6", "c6": "6", "c7": "6 ", "c8": "foo", "C 1": "476"} + Sat Mar 28 00:00:00 1970 PST | {"c3": "00486"} | {"c2": "6", "c6": "6", "c7": "6 ", "c8": "foo", "C 1": "486"} | Sat Mar 28 00:00:00 1970 PST | {"c3": "00486"} | {"c2": "6", "c6": "6", "c7": "6 ", "c8": "foo", "C 1": "486"} + Tue Apr 07 00:00:00 1970 PST | {"c3": "00496"} | {"c2": "6", "c6": "6", "c7": "6 ", "c8": "foo", "C 1": "496"} | Tue Apr 07 00:00:00 1970 PST | {"c3": "00496"} | {"c2": "6", "c6": "6", "c7": "6 ", "c8": "foo", "C 1": "496"} + Wed Jan 07 00:00:00 1970 PST | {"c3": "00506"} | {"c2": "6", "c6": "6", "c7": "6 ", "c8": "foo", "C 1": "506"} | Wed Jan 07 00:00:00 1970 PST | {"c3": "00506"} | {"c2": "6", "c6": "6", "c7": "6 ", "c8": "foo", "C 1": "506"} + Sat Jan 17 00:00:00 1970 PST | {"c3": "00516"} | {"c2": "6", "c6": "6", "c7": "6 ", "c8": "foo", "C 1": "516"} | Sat Jan 17 00:00:00 1970 PST | {"c3": "00516"} | {"c2": "6", "c6": "6", "c7": "6 ", "c8": "foo", "C 1": "516"} + Tue Jan 27 00:00:00 1970 PST | {"c3": "00526"} | {"c2": "6", "c6": "6", "c7": "6 ", "c8": "foo", "C 1": "526"} | Tue Jan 27 00:00:00 1970 PST | {"c3": "00526"} | {"c2": "6", "c6": "6", "c7": "6 ", "c8": "foo", "C 1": "526"} + Fri Feb 06 00:00:00 1970 PST | {"c3": "00536"} | {"c2": "6", "c6": "6", "c7": "6 ", "c8": "foo", "C 1": "536"} | Fri Feb 06 00:00:00 1970 PST | {"c3": "00536"} | {"c2": "6", "c6": "6", "c7": "6 ", "c8": "foo", "C 1": "536"} + Mon Feb 16 00:00:00 1970 PST | {"c3": "00546"} | {"c2": "6", "c6": "6", "c7": "6 ", "c8": "foo", "C 1": "546"} | Mon Feb 16 00:00:00 1970 PST | {"c3": "00546"} | {"c2": "6", "c6": "6", "c7": "6 ", "c8": "foo", "C 1": "546"} + Thu Feb 26 00:00:00 1970 PST | {"c3": "00556"} | {"c2": "6", "c6": "6", "c7": "6 ", "c8": "foo", "C 1": "556"} | Thu Feb 26 00:00:00 1970 PST | {"c3": "00556"} | {"c2": "6", "c6": "6", "c7": "6 ", "c8": "foo", "C 1": "556"} + Sun Mar 08 00:00:00 1970 PST | {"c3": "00566"} | {"c2": "6", "c6": "6", "c7": "6 ", "c8": "foo", "C 1": "566"} | Sun Mar 08 00:00:00 1970 PST | {"c3": "00566"} | {"c2": "6", "c6": "6", "c7": "6 ", "c8": "foo", "C 1": "566"} + Wed Mar 18 00:00:00 1970 PST | {"c3": "00576"} | {"c2": "6", "c6": "6", "c7": "6 ", "c8": "foo", "C 1": "576"} | Wed Mar 18 00:00:00 1970 PST | {"c3": "00576"} | {"c2": "6", "c6": "6", "c7": "6 ", "c8": "foo", "C 1": "576"} + Sat Mar 28 00:00:00 1970 PST | {"c3": "00586"} | {"c2": "6", "c6": "6", "c7": "6 ", "c8": "foo", "C 1": "586"} | Sat Mar 28 00:00:00 1970 PST | {"c3": "00586"} | {"c2": "6", "c6": "6", "c7": "6 ", "c8": "foo", "C 1": "586"} + Tue Apr 07 00:00:00 1970 PST | {"c3": "00596"} | {"c2": "6", "c6": "6", "c7": "6 ", "c8": "foo", "C 1": "596"} | Tue Apr 07 00:00:00 1970 PST | {"c3": "00596"} | {"c2": "6", "c6": "6", "c7": "6 ", "c8": "foo", "C 1": "596"} + Wed Jan 07 00:00:00 1970 PST | {"c3": "00606"} | {"c2": "6", "c6": "6", "c7": "6 ", "c8": "foo", "C 1": "606"} | Wed Jan 07 00:00:00 1970 PST | {"c3": "00606"} | {"c2": "6", "c6": "6", "c7": "6 ", "c8": "foo", "C 1": "606"} + Sat Jan 17 00:00:00 1970 PST | {"c3": "00616"} | {"c2": "6", "c6": "6", "c7": "6 ", "c8": "foo", "C 1": "616"} | Sat Jan 17 00:00:00 1970 PST | {"c3": "00616"} | {"c2": "6", "c6": "6", "c7": "6 ", "c8": "foo", "C 1": "616"} + Tue Jan 27 00:00:00 1970 PST | {"c3": "00626"} | {"c2": "6", "c6": "6", "c7": "6 ", "c8": "foo", "C 1": "626"} | Tue Jan 27 00:00:00 1970 PST | {"c3": "00626"} | {"c2": "6", "c6": "6", "c7": "6 ", "c8": "foo", "C 1": "626"} + Fri Feb 06 00:00:00 1970 PST | {"c3": "00636"} | {"c2": "6", "c6": "6", "c7": "6 ", "c8": "foo", "C 1": "636"} | Fri Feb 06 00:00:00 1970 PST | {"c3": "00636"} | {"c2": "6", "c6": "6", "c7": "6 ", "c8": "foo", "C 1": "636"} + Mon Feb 16 00:00:00 1970 PST | {"c3": "00646"} | {"c2": "6", "c6": "6", "c7": "6 ", "c8": "foo", "C 1": "646"} | Mon Feb 16 00:00:00 1970 PST | {"c3": "00646"} | {"c2": "6", "c6": "6", "c7": "6 ", "c8": "foo", "C 1": "646"} + Thu Feb 26 00:00:00 1970 PST | {"c3": "00656"} | {"c2": "6", "c6": "6", "c7": "6 ", "c8": "foo", "C 1": "656"} | Thu Feb 26 00:00:00 1970 PST | {"c3": "00656"} | {"c2": "6", "c6": "6", "c7": "6 ", "c8": "foo", "C 1": "656"} + Sun Mar 08 00:00:00 1970 PST | {"c3": "00666"} | {"c2": "6", "c6": "6", "c7": "6 ", "c8": "foo", "C 1": "666"} | Sun Mar 08 00:00:00 1970 PST | {"c3": "00666"} | {"c2": "6", "c6": "6", "c7": "6 ", "c8": "foo", "C 1": "666"} + Wed Mar 18 00:00:00 1970 PST | {"c3": "00676"} | {"c2": "6", "c6": "6", "c7": "6 ", "c8": "foo", "C 1": "676"} | Wed Mar 18 00:00:00 1970 PST | {"c3": "00676"} | {"c2": "6", "c6": "6", "c7": "6 ", "c8": "foo", "C 1": "676"} + Sat Mar 28 00:00:00 1970 PST | {"c3": "00686"} | {"c2": "6", "c6": "6", "c7": "6 ", "c8": "foo", "C 1": "686"} | Sat Mar 28 00:00:00 1970 PST | {"c3": "00686"} | {"c2": "6", "c6": "6", "c7": "6 ", "c8": "foo", "C 1": "686"} + Tue Apr 07 00:00:00 1970 PST | {"c3": "00696"} | {"c2": "6", "c6": "6", "c7": "6 ", "c8": "foo", "C 1": "696"} | Tue Apr 07 00:00:00 1970 PST | {"c3": "00696"} | {"c2": "6", "c6": "6", "c7": "6 ", "c8": "foo", "C 1": "696"} + Wed Jan 07 00:00:00 1970 PST | {"c3": "00706"} | {"c2": "6", "c6": "6", "c7": "6 ", "c8": "foo", "C 1": "706"} | Wed Jan 07 00:00:00 1970 PST | {"c3": "00706"} | {"c2": "6", "c6": "6", "c7": "6 ", "c8": "foo", "C 1": "706"} + Sat Jan 17 00:00:00 1970 PST | {"c3": "00716"} | {"c2": "6", "c6": "6", "c7": "6 ", "c8": "foo", "C 1": "716"} | Sat Jan 17 00:00:00 1970 PST | {"c3": "00716"} | {"c2": "6", "c6": "6", "c7": "6 ", "c8": "foo", "C 1": "716"} + Tue Jan 27 00:00:00 1970 PST | {"c3": "00726"} | {"c2": "6", "c6": "6", "c7": "6 ", "c8": "foo", "C 1": "726"} | Tue Jan 27 00:00:00 1970 PST | {"c3": "00726"} | {"c2": "6", "c6": "6", "c7": "6 ", "c8": "foo", "C 1": "726"} + Fri Feb 06 00:00:00 1970 PST | {"c3": "00736"} | {"c2": "6", "c6": "6", "c7": "6 ", "c8": "foo", "C 1": "736"} | Fri Feb 06 00:00:00 1970 PST | {"c3": "00736"} | {"c2": "6", "c6": "6", "c7": "6 ", "c8": "foo", "C 1": "736"} + Mon Feb 16 00:00:00 1970 PST | {"c3": "00746"} | {"c2": "6", "c6": "6", "c7": "6 ", "c8": "foo", "C 1": "746"} | Mon Feb 16 00:00:00 1970 PST | {"c3": "00746"} | {"c2": "6", "c6": "6", "c7": "6 ", "c8": "foo", "C 1": "746"} + Thu Feb 26 00:00:00 1970 PST | {"c3": "00756"} | {"c2": "6", "c6": "6", "c7": "6 ", "c8": "foo", "C 1": "756"} | Thu Feb 26 00:00:00 1970 PST | {"c3": "00756"} | {"c2": "6", "c6": "6", "c7": "6 ", "c8": "foo", "C 1": "756"} + Sun Mar 08 00:00:00 1970 PST | {"c3": "00766"} | {"c2": "6", "c6": "6", "c7": "6 ", "c8": "foo", "C 1": "766"} | Sun Mar 08 00:00:00 1970 PST | {"c3": "00766"} | {"c2": "6", "c6": "6", "c7": "6 ", "c8": "foo", "C 1": "766"} + Wed Mar 18 00:00:00 1970 PST | {"c3": "00776"} | {"c2": "6", "c6": "6", "c7": "6 ", "c8": "foo", "C 1": "776"} | Wed Mar 18 00:00:00 1970 PST | {"c3": "00776"} | {"c2": "6", "c6": "6", "c7": "6 ", "c8": "foo", "C 1": "776"} + Sat Mar 28 00:00:00 1970 PST | {"c3": "00786"} | {"c2": "6", "c6": "6", "c7": "6 ", "c8": "foo", "C 1": "786"} | Sat Mar 28 00:00:00 1970 PST | {"c3": "00786"} | {"c2": "6", "c6": "6", "c7": "6 ", "c8": "foo", "C 1": "786"} + Tue Apr 07 00:00:00 1970 PST | {"c3": "00796"} | {"c2": "6", "c6": "6", "c7": "6 ", "c8": "foo", "C 1": "796"} | Tue Apr 07 00:00:00 1970 PST | {"c3": "00796"} | {"c2": "6", "c6": "6", "c7": "6 ", "c8": "foo", "C 1": "796"} + Wed Jan 07 00:00:00 1970 PST | {"c3": "00806"} | {"c2": "6", "c6": "6", "c7": "6 ", "c8": "foo", "C 1": "806"} | Wed Jan 07 00:00:00 1970 PST | {"c3": "00806"} | {"c2": "6", "c6": "6", "c7": "6 ", "c8": "foo", "C 1": "806"} + Sat Jan 17 00:00:00 1970 PST | {"c3": "00816"} | {"c2": "6", "c6": "6", "c7": "6 ", "c8": "foo", "C 1": "816"} | Sat Jan 17 00:00:00 1970 PST | {"c3": "00816"} | {"c2": "6", "c6": "6", "c7": "6 ", "c8": "foo", "C 1": "816"} + Tue Jan 27 00:00:00 1970 PST | {"c3": "00826"} | {"c2": "6", "c6": "6", "c7": "6 ", "c8": "foo", "C 1": "826"} | Tue Jan 27 00:00:00 1970 PST | {"c3": "00826"} | {"c2": "6", "c6": "6", "c7": "6 ", "c8": "foo", "C 1": "826"} + Fri Feb 06 00:00:00 1970 PST | {"c3": "00836"} | {"c2": "6", "c6": "6", "c7": "6 ", "c8": "foo", "C 1": "836"} | Fri Feb 06 00:00:00 1970 PST | {"c3": "00836"} | {"c2": "6", "c6": "6", "c7": "6 ", "c8": "foo", "C 1": "836"} + Mon Feb 16 00:00:00 1970 PST | {"c3": "00846"} | {"c2": "6", "c6": "6", "c7": "6 ", "c8": "foo", "C 1": "846"} | Mon Feb 16 00:00:00 1970 PST | {"c3": "00846"} | {"c2": "6", "c6": "6", "c7": "6 ", "c8": "foo", "C 1": "846"} + Thu Feb 26 00:00:00 1970 PST | {"c3": "00856"} | {"c2": "6", "c6": "6", "c7": "6 ", "c8": "foo", "C 1": "856"} | Thu Feb 26 00:00:00 1970 PST | {"c3": "00856"} | {"c2": "6", "c6": "6", "c7": "6 ", "c8": "foo", "C 1": "856"} + Sun Mar 08 00:00:00 1970 PST | {"c3": "00866"} | {"c2": "6", "c6": "6", "c7": "6 ", "c8": "foo", "C 1": "866"} | Sun Mar 08 00:00:00 1970 PST | {"c3": "00866"} | {"c2": "6", "c6": "6", "c7": "6 ", "c8": "foo", "C 1": "866"} + Wed Mar 18 00:00:00 1970 PST | {"c3": "00876"} | {"c2": "6", "c6": "6", "c7": "6 ", "c8": "foo", "C 1": "876"} | Wed Mar 18 00:00:00 1970 PST | {"c3": "00876"} | {"c2": "6", "c6": "6", "c7": "6 ", "c8": "foo", "C 1": "876"} + Sat Mar 28 00:00:00 1970 PST | {"c3": "00886"} | {"c2": "6", "c6": "6", "c7": "6 ", "c8": "foo", "C 1": "886"} | Sat Mar 28 00:00:00 1970 PST | {"c3": "00886"} | {"c2": "6", "c6": "6", "c7": "6 ", "c8": "foo", "C 1": "886"} + Tue Apr 07 00:00:00 1970 PST | {"c3": "00896"} | {"c2": "6", "c6": "6", "c7": "6 ", "c8": "foo", "C 1": "896"} | Tue Apr 07 00:00:00 1970 PST | {"c3": "00896"} | {"c2": "6", "c6": "6", "c7": "6 ", "c8": "foo", "C 1": "896"} + Wed Jan 07 00:00:00 1970 PST | {"c3": "00906"} | {"c2": "6", "c6": "6", "c7": "6 ", "c8": "foo", "C 1": "906"} | Wed Jan 07 00:00:00 1970 PST | {"c3": "00906"} | {"c2": "6", "c6": "6", "c7": "6 ", "c8": "foo", "C 1": "906"} + Sat Jan 17 00:00:00 1970 PST | {"c3": "00916"} | {"c2": "6", "c6": "6", "c7": "6 ", "c8": "foo", "C 1": "916"} | Sat Jan 17 00:00:00 1970 PST | {"c3": "00916"} | {"c2": "6", "c6": "6", "c7": "6 ", "c8": "foo", "C 1": "916"} + Tue Jan 27 00:00:00 1970 PST | {"c3": "00926"} | {"c2": "6", "c6": "6", "c7": "6 ", "c8": "foo", "C 1": "926"} | Tue Jan 27 00:00:00 1970 PST | {"c3": "00926"} | {"c2": "6", "c6": "6", "c7": "6 ", "c8": "foo", "C 1": "926"} + Fri Feb 06 00:00:00 1970 PST | {"c3": "00936"} | {"c2": "6", "c6": "6", "c7": "6 ", "c8": "foo", "C 1": "936"} | Fri Feb 06 00:00:00 1970 PST | {"c3": "00936"} | {"c2": "6", "c6": "6", "c7": "6 ", "c8": "foo", "C 1": "936"} + Mon Feb 16 00:00:00 1970 PST | {"c3": "00946"} | {"c2": "6", "c6": "6", "c7": "6 ", "c8": "foo", "C 1": "946"} | Mon Feb 16 00:00:00 1970 PST | {"c3": "00946"} | {"c2": "6", "c6": "6", "c7": "6 ", "c8": "foo", "C 1": "946"} + Thu Feb 26 00:00:00 1970 PST | {"c3": "00956"} | {"c2": "6", "c6": "6", "c7": "6 ", "c8": "foo", "C 1": "956"} | Thu Feb 26 00:00:00 1970 PST | {"c3": "00956"} | {"c2": "6", "c6": "6", "c7": "6 ", "c8": "foo", "C 1": "956"} + Sun Mar 08 00:00:00 1970 PST | {"c3": "00966"} | {"c2": "6", "c6": "6", "c7": "6 ", "c8": "foo", "C 1": "966"} | Sun Mar 08 00:00:00 1970 PST | {"c3": "00966"} | {"c2": "6", "c6": "6", "c7": "6 ", "c8": "foo", "C 1": "966"} + Wed Mar 18 00:00:00 1970 PST | {"c3": "00976"} | {"c2": "6", "c6": "6", "c7": "6 ", "c8": "foo", "C 1": "976"} | Wed Mar 18 00:00:00 1970 PST | {"c3": "00976"} | {"c2": "6", "c6": "6", "c7": "6 ", "c8": "foo", "C 1": "976"} + Sat Mar 28 00:00:00 1970 PST | {"c3": "00986"} | {"c2": "6", "c6": "6", "c7": "6 ", "c8": "foo", "C 1": "986"} | Sat Mar 28 00:00:00 1970 PST | {"c3": "00986"} | {"c2": "6", "c6": "6", "c7": "6 ", "c8": "foo", "C 1": "986"} + Tue Apr 07 00:00:00 1970 PST | {"c3": "00996"} | {"c2": "6", "c6": "6", "c7": "6 ", "c8": "foo", "C 1": "996"} | Tue Apr 07 00:00:00 1970 PST | {"c3": "00996"} | {"c2": "6", "c6": "6", "c7": "6 ", "c8": "foo", "C 1": "996"} (100 rows) -- bug before 9.3.5 due to sloppy handling of remote-estimate parameters --Testcase 91: SELECT * FROM ft1 WHERE (fields->>'C 1')::int = ANY (ARRAY(SELECT (fields->>'C 1')::int FROM ft2 WHERE (fields->>'C 1')::int < 5)); - time | tags | fields ---------------------------+-----------------+--------------------------------------------------------------------- - Fri Jan 02 00:00:00 1970 | {"c3": "00001"} | {"c2": "1", "c6": "1", "c7": "1 ", "c8": "foo", "C 1": "1"} - Sat Jan 03 00:00:00 1970 | {"c3": "00002"} | {"c2": "2", "c6": "2", "c7": "2 ", "c8": "foo", "C 1": "2"} - Sun Jan 04 00:00:00 1970 | {"c3": "00003"} | {"c2": "3", "c6": "3", "c7": "3 ", "c8": "foo", "C 1": "3"} - Mon Jan 05 00:00:00 1970 | {"c3": "00004"} | {"c2": "4", "c6": "4", "c7": "4 ", "c8": "foo", "C 1": "4"} + time | tags | fields +------------------------------+-----------------+--------------------------------------------------------------------- + Fri Jan 02 00:00:00 1970 PST | {"c3": "00001"} | {"c2": "1", "c6": "1", "c7": "1 ", "c8": "foo", "C 1": "1"} + Sat Jan 03 00:00:00 1970 PST | {"c3": "00002"} | {"c2": "2", "c6": "2", "c7": "2 ", "c8": "foo", "C 1": "2"} + Sun Jan 04 00:00:00 1970 PST | {"c3": "00003"} | {"c2": "3", "c6": "3", "c7": "3 ", "c8": "foo", "C 1": "3"} + Mon Jan 05 00:00:00 1970 PST | {"c3": "00004"} | {"c2": "4", "c6": "4", "c7": "4 ", "c8": "foo", "C 1": "4"} (4 rows) --Testcase 92: SELECT * FROM ft2 WHERE (fields->>'C 1')::int = ANY (ARRAY(SELECT (fields->>'C 1')::int FROM ft1 WHERE (fields->>'C 1')::int < 5)); - time | tags | fields ---------------------------+-----------------+--------------------------------------------------------------------- - Fri Jan 02 00:00:00 1970 | {"c3": "00001"} | {"c2": "1", "c6": "1", "c7": "1 ", "c8": "foo", "C 1": "1"} - Sat Jan 03 00:00:00 1970 | {"c3": "00002"} | {"c2": "2", "c6": "2", "c7": "2 ", "c8": "foo", "C 1": "2"} - Sun Jan 04 00:00:00 1970 | {"c3": "00003"} | {"c2": "3", "c6": "3", "c7": "3 ", "c8": "foo", "C 1": "3"} - Mon Jan 05 00:00:00 1970 | {"c3": "00004"} | {"c2": "4", "c6": "4", "c7": "4 ", "c8": "foo", "C 1": "4"} + time | tags | fields +------------------------------+-----------------+--------------------------------------------------------------------- + Fri Jan 02 00:00:00 1970 PST | {"c3": "00001"} | {"c2": "1", "c6": "1", "c7": "1 ", "c8": "foo", "C 1": "1"} + Sat Jan 03 00:00:00 1970 PST | {"c3": "00002"} | {"c2": "2", "c6": "2", "c7": "2 ", "c8": "foo", "C 1": "2"} + Sun Jan 04 00:00:00 1970 PST | {"c3": "00003"} | {"c2": "3", "c6": "3", "c7": "3 ", "c8": "foo", "C 1": "3"} + Mon Jan 05 00:00:00 1970 PST | {"c3": "00004"} | {"c2": "4", "c6": "4", "c7": "4 ", "c8": "foo", "C 1": "4"} (4 rows) -- we should not push order by clause with volatile expressions or unsafe @@ -1195,9 +1195,9 @@ EXPLAIN (VERBOSE, COSTS OFF) --Testcase 106: SELECT * FROM ft1 t1 WHERE (t1.fields->>'C 1')::int === (t1.fields->>'c2')::int order by (t1.fields->>'c2')::int limit 1; - time | tags | fields ---------------------------+-----------------+--------------------------------------------------------------------- - Fri Jan 02 00:00:00 1970 | {"c3": "00001"} | {"c2": "1", "c6": "1", "c7": "1 ", "c8": "foo", "C 1": "1"} + time | tags | fields +------------------------------+-----------------+--------------------------------------------------------------------- + Fri Jan 02 00:00:00 1970 PST | {"c3": "00001"} | {"c2": "1", "c6": "1", "c7": "1 ", "c8": "foo", "C 1": "1"} (1 row) -- but let's put them in an extension ... @@ -1266,9 +1266,9 @@ EXPLAIN (VERBOSE, COSTS OFF) --Testcase 114: SELECT * FROM ft1 t1 WHERE (t1.fields->>'C 1')::int === (t1.fields->>'c2')::int order by (t1.fields->>'c2')::int limit 1; - time | tags | fields ---------------------------+-----------------+--------------------------------------------------------------------- - Fri Jan 02 00:00:00 1970 | {"c3": "00001"} | {"c2": "1", "c6": "1", "c7": "1 ", "c8": "foo", "C 1": "1"} + time | tags | fields +------------------------------+-----------------+--------------------------------------------------------------------- + Fri Jan 02 00:00:00 1970 PST | {"c3": "00001"} | {"c2": "1", "c6": "1", "c7": "1 ", "c8": "foo", "C 1": "1"} (1 row) -- Test CASE pushdown @@ -3289,18 +3289,18 @@ SELECT * FROM ft1, ft2, ft4, ft5, local_tbl WHERE (ft1.fields->>'C 1')::int = (f --Testcase 204: SELECT * FROM ft1, ft2, ft4, ft5, local_tbl WHERE (ft1.fields->>'C 1')::int = (ft2.fields->>'C 1')::int AND (ft1.fields->>'c2')::int = (ft4.fields->>'c1')::int AND (ft1.fields->>'c2')::int = (ft5.fields->>'c1')::int AND (ft1.fields->>'c2')::int = (local_tbl.fields->>'c1')::int AND (ft1.fields->>'C 1')::int < 100 AND (ft2.fields->>'C 1')::int < 100 ORDER BY (ft1.fields->>'C 1')::int FOR UPDATE; - time | tags | fields | time | tags | fields | tags | fields | tags | fields | fields ---------------------------+-----------------+----------------------------------------------------------------------+--------------------------+-----------------+----------------------------------------------------------------------+------------------+------------------------+------------------+------------------------+-------------------------------------- - Wed Jan 07 00:00:00 1970 | {"c3": "00006"} | {"c2": "6", "c6": "6", "c7": "6 ", "c8": "foo", "C 1": "6"} | Wed Jan 07 00:00:00 1970 | {"c3": "00006"} | {"c2": "6", "c6": "6", "c7": "6 ", "c8": "foo", "C 1": "6"} | {"c3": "AAA006"} | {"c1": "6", "c2": "7"} | {"c3": "AAA006"} | {"c1": "6", "c2": "7"} | {"c1": "6", "c2": "6", "c3": "0006"} - Sat Jan 17 00:00:00 1970 | {"c3": "00016"} | {"c2": "6", "c6": "6", "c7": "6 ", "c8": "foo", "C 1": "16"} | Sat Jan 17 00:00:00 1970 | {"c3": "00016"} | {"c2": "6", "c6": "6", "c7": "6 ", "c8": "foo", "C 1": "16"} | {"c3": "AAA006"} | {"c1": "6", "c2": "7"} | {"c3": "AAA006"} | {"c1": "6", "c2": "7"} | {"c1": "6", "c2": "6", "c3": "0006"} - Tue Jan 27 00:00:00 1970 | {"c3": "00026"} | {"c2": "6", "c6": "6", "c7": "6 ", "c8": "foo", "C 1": "26"} | Tue Jan 27 00:00:00 1970 | {"c3": "00026"} | {"c2": "6", "c6": "6", "c7": "6 ", "c8": "foo", "C 1": "26"} | {"c3": "AAA006"} | {"c1": "6", "c2": "7"} | {"c3": "AAA006"} | {"c1": "6", "c2": "7"} | {"c1": "6", "c2": "6", "c3": "0006"} - Fri Feb 06 00:00:00 1970 | {"c3": "00036"} | {"c2": "6", "c6": "6", "c7": "6 ", "c8": "foo", "C 1": "36"} | Fri Feb 06 00:00:00 1970 | {"c3": "00036"} | {"c2": "6", "c6": "6", "c7": "6 ", "c8": "foo", "C 1": "36"} | {"c3": "AAA006"} | {"c1": "6", "c2": "7"} | {"c3": "AAA006"} | {"c1": "6", "c2": "7"} | {"c1": "6", "c2": "6", "c3": "0006"} - Mon Feb 16 00:00:00 1970 | {"c3": "00046"} | {"c2": "6", "c6": "6", "c7": "6 ", "c8": "foo", "C 1": "46"} | Mon Feb 16 00:00:00 1970 | {"c3": "00046"} | {"c2": "6", "c6": "6", "c7": "6 ", "c8": "foo", "C 1": "46"} | {"c3": "AAA006"} | {"c1": "6", "c2": "7"} | {"c3": "AAA006"} | {"c1": "6", "c2": "7"} | {"c1": "6", "c2": "6", "c3": "0006"} - Thu Feb 26 00:00:00 1970 | {"c3": "00056"} | {"c2": "6", "c6": "6", "c7": "6 ", "c8": "foo", "C 1": "56"} | Thu Feb 26 00:00:00 1970 | {"c3": "00056"} | {"c2": "6", "c6": "6", "c7": "6 ", "c8": "foo", "C 1": "56"} | {"c3": "AAA006"} | {"c1": "6", "c2": "7"} | {"c3": "AAA006"} | {"c1": "6", "c2": "7"} | {"c1": "6", "c2": "6", "c3": "0006"} - Sun Mar 08 00:00:00 1970 | {"c3": "00066"} | {"c2": "6", "c6": "6", "c7": "6 ", "c8": "foo", "C 1": "66"} | Sun Mar 08 00:00:00 1970 | {"c3": "00066"} | {"c2": "6", "c6": "6", "c7": "6 ", "c8": "foo", "C 1": "66"} | {"c3": "AAA006"} | {"c1": "6", "c2": "7"} | {"c3": "AAA006"} | {"c1": "6", "c2": "7"} | {"c1": "6", "c2": "6", "c3": "0006"} - Wed Mar 18 00:00:00 1970 | {"c3": "00076"} | {"c2": "6", "c6": "6", "c7": "6 ", "c8": "foo", "C 1": "76"} | Wed Mar 18 00:00:00 1970 | {"c3": "00076"} | {"c2": "6", "c6": "6", "c7": "6 ", "c8": "foo", "C 1": "76"} | {"c3": "AAA006"} | {"c1": "6", "c2": "7"} | {"c3": "AAA006"} | {"c1": "6", "c2": "7"} | {"c1": "6", "c2": "6", "c3": "0006"} - Sat Mar 28 00:00:00 1970 | {"c3": "00086"} | {"c2": "6", "c6": "6", "c7": "6 ", "c8": "foo", "C 1": "86"} | Sat Mar 28 00:00:00 1970 | {"c3": "00086"} | {"c2": "6", "c6": "6", "c7": "6 ", "c8": "foo", "C 1": "86"} | {"c3": "AAA006"} | {"c1": "6", "c2": "7"} | {"c3": "AAA006"} | {"c1": "6", "c2": "7"} | {"c1": "6", "c2": "6", "c3": "0006"} - Tue Apr 07 00:00:00 1970 | {"c3": "00096"} | {"c2": "6", "c6": "6", "c7": "6 ", "c8": "foo", "C 1": "96"} | Tue Apr 07 00:00:00 1970 | {"c3": "00096"} | {"c2": "6", "c6": "6", "c7": "6 ", "c8": "foo", "C 1": "96"} | {"c3": "AAA006"} | {"c1": "6", "c2": "7"} | {"c3": "AAA006"} | {"c1": "6", "c2": "7"} | {"c1": "6", "c2": "6", "c3": "0006"} + time | tags | fields | time | tags | fields | tags | fields | tags | fields | fields +------------------------------+-----------------+----------------------------------------------------------------------+------------------------------+-----------------+----------------------------------------------------------------------+------------------+------------------------+------------------+------------------------+-------------------------------------- + Wed Jan 07 00:00:00 1970 PST | {"c3": "00006"} | {"c2": "6", "c6": "6", "c7": "6 ", "c8": "foo", "C 1": "6"} | Wed Jan 07 00:00:00 1970 PST | {"c3": "00006"} | {"c2": "6", "c6": "6", "c7": "6 ", "c8": "foo", "C 1": "6"} | {"c3": "AAA006"} | {"c1": "6", "c2": "7"} | {"c3": "AAA006"} | {"c1": "6", "c2": "7"} | {"c1": "6", "c2": "6", "c3": "0006"} + Sat Jan 17 00:00:00 1970 PST | {"c3": "00016"} | {"c2": "6", "c6": "6", "c7": "6 ", "c8": "foo", "C 1": "16"} | Sat Jan 17 00:00:00 1970 PST | {"c3": "00016"} | {"c2": "6", "c6": "6", "c7": "6 ", "c8": "foo", "C 1": "16"} | {"c3": "AAA006"} | {"c1": "6", "c2": "7"} | {"c3": "AAA006"} | {"c1": "6", "c2": "7"} | {"c1": "6", "c2": "6", "c3": "0006"} + Tue Jan 27 00:00:00 1970 PST | {"c3": "00026"} | {"c2": "6", "c6": "6", "c7": "6 ", "c8": "foo", "C 1": "26"} | Tue Jan 27 00:00:00 1970 PST | {"c3": "00026"} | {"c2": "6", "c6": "6", "c7": "6 ", "c8": "foo", "C 1": "26"} | {"c3": "AAA006"} | {"c1": "6", "c2": "7"} | {"c3": "AAA006"} | {"c1": "6", "c2": "7"} | {"c1": "6", "c2": "6", "c3": "0006"} + Fri Feb 06 00:00:00 1970 PST | {"c3": "00036"} | {"c2": "6", "c6": "6", "c7": "6 ", "c8": "foo", "C 1": "36"} | Fri Feb 06 00:00:00 1970 PST | {"c3": "00036"} | {"c2": "6", "c6": "6", "c7": "6 ", "c8": "foo", "C 1": "36"} | {"c3": "AAA006"} | {"c1": "6", "c2": "7"} | {"c3": "AAA006"} | {"c1": "6", "c2": "7"} | {"c1": "6", "c2": "6", "c3": "0006"} + Mon Feb 16 00:00:00 1970 PST | {"c3": "00046"} | {"c2": "6", "c6": "6", "c7": "6 ", "c8": "foo", "C 1": "46"} | Mon Feb 16 00:00:00 1970 PST | {"c3": "00046"} | {"c2": "6", "c6": "6", "c7": "6 ", "c8": "foo", "C 1": "46"} | {"c3": "AAA006"} | {"c1": "6", "c2": "7"} | {"c3": "AAA006"} | {"c1": "6", "c2": "7"} | {"c1": "6", "c2": "6", "c3": "0006"} + Thu Feb 26 00:00:00 1970 PST | {"c3": "00056"} | {"c2": "6", "c6": "6", "c7": "6 ", "c8": "foo", "C 1": "56"} | Thu Feb 26 00:00:00 1970 PST | {"c3": "00056"} | {"c2": "6", "c6": "6", "c7": "6 ", "c8": "foo", "C 1": "56"} | {"c3": "AAA006"} | {"c1": "6", "c2": "7"} | {"c3": "AAA006"} | {"c1": "6", "c2": "7"} | {"c1": "6", "c2": "6", "c3": "0006"} + Sun Mar 08 00:00:00 1970 PST | {"c3": "00066"} | {"c2": "6", "c6": "6", "c7": "6 ", "c8": "foo", "C 1": "66"} | Sun Mar 08 00:00:00 1970 PST | {"c3": "00066"} | {"c2": "6", "c6": "6", "c7": "6 ", "c8": "foo", "C 1": "66"} | {"c3": "AAA006"} | {"c1": "6", "c2": "7"} | {"c3": "AAA006"} | {"c1": "6", "c2": "7"} | {"c1": "6", "c2": "6", "c3": "0006"} + Wed Mar 18 00:00:00 1970 PST | {"c3": "00076"} | {"c2": "6", "c6": "6", "c7": "6 ", "c8": "foo", "C 1": "76"} | Wed Mar 18 00:00:00 1970 PST | {"c3": "00076"} | {"c2": "6", "c6": "6", "c7": "6 ", "c8": "foo", "C 1": "76"} | {"c3": "AAA006"} | {"c1": "6", "c2": "7"} | {"c3": "AAA006"} | {"c1": "6", "c2": "7"} | {"c1": "6", "c2": "6", "c3": "0006"} + Sat Mar 28 00:00:00 1970 PST | {"c3": "00086"} | {"c2": "6", "c6": "6", "c7": "6 ", "c8": "foo", "C 1": "86"} | Sat Mar 28 00:00:00 1970 PST | {"c3": "00086"} | {"c2": "6", "c6": "6", "c7": "6 ", "c8": "foo", "C 1": "86"} | {"c3": "AAA006"} | {"c1": "6", "c2": "7"} | {"c3": "AAA006"} | {"c1": "6", "c2": "7"} | {"c1": "6", "c2": "6", "c3": "0006"} + Tue Apr 07 00:00:00 1970 PST | {"c3": "00096"} | {"c2": "6", "c6": "6", "c7": "6 ", "c8": "foo", "C 1": "96"} | Tue Apr 07 00:00:00 1970 PST | {"c3": "00096"} | {"c2": "6", "c6": "6", "c7": "6 ", "c8": "foo", "C 1": "96"} | {"c3": "AAA006"} | {"c1": "6", "c2": "7"} | {"c3": "AAA006"} | {"c1": "6", "c2": "7"} | {"c1": "6", "c2": "6", "c3": "0006"} (10 rows) --Testcase 205: @@ -4039,9 +4039,9 @@ select array_agg(time order by (fields->>'C 1')::int desc) from ft2 where (field --Testcase 257: select array_agg(time order by (fields->>'C 1')::int desc) from ft2 where (fields->>'c2')::int = 6 and (fields->>'C 1')::int < 50; - array_agg ------------------------------------------------------------------------------------------------------------------------------------------- - {"Mon Feb 16 00:00:00 1970","Fri Feb 06 00:00:00 1970","Tue Jan 27 00:00:00 1970","Sat Jan 17 00:00:00 1970","Wed Jan 07 00:00:00 1970"} + array_agg +-------------------------------------------------------------------------------------------------------------------------------------------------------------- + {"Mon Feb 16 00:00:00 1970 PST","Fri Feb 06 00:00:00 1970 PST","Tue Jan 27 00:00:00 1970 PST","Sat Jan 17 00:00:00 1970 PST","Wed Jan 07 00:00:00 1970 PST"} (1 row) -- DISTINCT within aggregate @@ -5258,16 +5258,16 @@ EXPLAIN (VERBOSE, COSTS OFF) EXECUTE st2(10, 20); --Testcase 359: EXECUTE st2(10, 20); - time | tags | fields ---------------------------+-----------------+---------------------------------------------------------------------- - Sat Jan 17 00:00:00 1970 | {"c3": "00016"} | {"c2": "6", "c6": "6", "c7": "6 ", "c8": "foo", "C 1": "16"} + time | tags | fields +------------------------------+-----------------+---------------------------------------------------------------------- + Sat Jan 17 00:00:00 1970 PST | {"c3": "00016"} | {"c2": "6", "c6": "6", "c7": "6 ", "c8": "foo", "C 1": "16"} (1 row) --Testcase 360: EXECUTE st2(101, 121); - time | tags | fields ---------------------------+-----------------+----------------------------------------------------------------------- - Sat Jan 17 00:00:00 1970 | {"c3": "00116"} | {"c2": "6", "c6": "6", "c7": "6 ", "c8": "foo", "C 1": "116"} + time | tags | fields +------------------------------+-----------------+----------------------------------------------------------------------- + Sat Jan 17 00:00:00 1970 PST | {"c3": "00116"} | {"c2": "6", "c6": "6", "c7": "6 ", "c8": "foo", "C 1": "116"} (1 row) -- subquery using immutable function (can be sent to remote) @@ -5296,9 +5296,9 @@ EXPLAIN (VERBOSE, COSTS OFF) EXECUTE st3(10, 20); --Testcase 363: EXECUTE st3(10, 20); - time | tags | fields ---------------------------+-----------------+---------------------------------------------------------------------- - Sat Jan 17 00:00:00 1970 | {"c3": "00016"} | {"c2": "6", "c6": "6", "c7": "6 ", "c8": "foo", "C 1": "16"} + time | tags | fields +------------------------------+-----------------+---------------------------------------------------------------------- + Sat Jan 17 00:00:00 1970 PST | {"c3": "00016"} | {"c2": "6", "c6": "6", "c7": "6 ", "c8": "foo", "C 1": "16"} (1 row) --Testcase 364: @@ -5424,9 +5424,9 @@ EXPLAIN (VERBOSE, COSTS OFF) EXECUTE st5('foo', 1); --Testcase 379: EXECUTE st5('foo', 1); - time | tags | fields ---------------------------+-----------------+--------------------------------------------------------------------- - Fri Jan 02 00:00:00 1970 | {"c3": "00001"} | {"c2": "1", "c6": "1", "c7": "1 ", "c8": "foo", "C 1": "1"} + time | tags | fields +------------------------------+-----------------+--------------------------------------------------------------------- + Fri Jan 02 00:00:00 1970 PST | {"c3": "00001"} | {"c2": "1", "c6": "1", "c7": "1 ", "c8": "foo", "C 1": "1"} (1 row) -- altering FDW options requires replanning @@ -5445,12 +5445,12 @@ EXPLAIN (VERBOSE, COSTS OFF) EXECUTE st6; PREPARE st7 AS INSERT INTO ft1_nsc (c1,c2,c3) VALUES (1001,101,'foo'); --Testcase 383: EXPLAIN (VERBOSE, COSTS OFF) EXECUTE st7; - QUERY PLAN ------------------------------------------------------------------------------------------------------------------------------------------------------------- + QUERY PLAN +--------------------------------------------------------------------------------------------------------------------------------------------------------- Insert on public.ft1_nsc Batch Size: 1 -> Result - Output: NULL::integer, 1001, 101, 'foo'::text, NULL::timestamp without time zone, NULL::character varying, 'ft1 '::character(10), NULL::text + Output: NULL::integer, 1001, 101, 'foo'::text, NULL::timestamp with time zone, NULL::character varying, 'ft1 '::character(10), NULL::text (4 rows) --Testcase 384: @@ -5468,27 +5468,27 @@ EXPLAIN (VERBOSE, COSTS OFF) EXECUTE st6; --Testcase 387: EXECUTE st6; - time | tags | fields ---------------------------+-----------------+--------------------------------------------------------------------- - Fri Jan 02 00:00:00 1970 | {"c3": "00001"} | {"c2": "1", "c6": "1", "c7": "1 ", "c8": "foo", "C 1": "1"} - Sat Jan 03 00:00:00 1970 | {"c3": "00002"} | {"c2": "2", "c6": "2", "c7": "2 ", "c8": "foo", "C 1": "2"} - Sun Jan 04 00:00:00 1970 | {"c3": "00003"} | {"c2": "3", "c6": "3", "c7": "3 ", "c8": "foo", "C 1": "3"} - Mon Jan 05 00:00:00 1970 | {"c3": "00004"} | {"c2": "4", "c6": "4", "c7": "4 ", "c8": "foo", "C 1": "4"} - Tue Jan 06 00:00:00 1970 | {"c3": "00005"} | {"c2": "5", "c6": "5", "c7": "5 ", "c8": "foo", "C 1": "5"} - Wed Jan 07 00:00:00 1970 | {"c3": "00006"} | {"c2": "6", "c6": "6", "c7": "6 ", "c8": "foo", "C 1": "6"} - Thu Jan 08 00:00:00 1970 | {"c3": "00007"} | {"c2": "7", "c6": "7", "c7": "7 ", "c8": "foo", "C 1": "7"} - Fri Jan 09 00:00:00 1970 | {"c3": "00008"} | {"c2": "8", "c6": "8", "c7": "8 ", "c8": "foo", "C 1": "8"} - Sat Jan 10 00:00:00 1970 | {"c3": "00009"} | {"c2": "9", "c6": "9", "c7": "9 ", "c8": "foo", "C 1": "9"} + time | tags | fields +------------------------------+-----------------+--------------------------------------------------------------------- + Fri Jan 02 00:00:00 1970 PST | {"c3": "00001"} | {"c2": "1", "c6": "1", "c7": "1 ", "c8": "foo", "C 1": "1"} + Sat Jan 03 00:00:00 1970 PST | {"c3": "00002"} | {"c2": "2", "c6": "2", "c7": "2 ", "c8": "foo", "C 1": "2"} + Sun Jan 04 00:00:00 1970 PST | {"c3": "00003"} | {"c2": "3", "c6": "3", "c7": "3 ", "c8": "foo", "C 1": "3"} + Mon Jan 05 00:00:00 1970 PST | {"c3": "00004"} | {"c2": "4", "c6": "4", "c7": "4 ", "c8": "foo", "C 1": "4"} + Tue Jan 06 00:00:00 1970 PST | {"c3": "00005"} | {"c2": "5", "c6": "5", "c7": "5 ", "c8": "foo", "C 1": "5"} + Wed Jan 07 00:00:00 1970 PST | {"c3": "00006"} | {"c2": "6", "c6": "6", "c7": "6 ", "c8": "foo", "C 1": "6"} + Thu Jan 08 00:00:00 1970 PST | {"c3": "00007"} | {"c2": "7", "c6": "7", "c7": "7 ", "c8": "foo", "C 1": "7"} + Fri Jan 09 00:00:00 1970 PST | {"c3": "00008"} | {"c2": "8", "c6": "8", "c7": "8 ", "c8": "foo", "C 1": "8"} + Sat Jan 10 00:00:00 1970 PST | {"c3": "00009"} | {"c2": "9", "c6": "9", "c7": "9 ", "c8": "foo", "C 1": "9"} (9 rows) --Testcase 388: EXPLAIN (VERBOSE, COSTS OFF) EXECUTE st7; - QUERY PLAN ------------------------------------------------------------------------------------------------------------------------------------------------------------- + QUERY PLAN +--------------------------------------------------------------------------------------------------------------------------------------------------------- Insert on public.ft1_nsc Batch Size: 1 -> Result - Output: NULL::integer, 1001, 101, 'foo'::text, NULL::timestamp without time zone, NULL::character varying, 'ft1 '::character(10), NULL::text + Output: NULL::integer, 1001, 101, 'foo'::text, NULL::timestamp with time zone, NULL::character varying, 'ft1 '::character(10), NULL::text (4 rows) --Testcase 389: @@ -5556,9 +5556,9 @@ SELECT * FROM ft1 t1 WHERE t1.tableoid = 'pg_class'::regclass LIMIT 1; --Testcase 396: SELECT * FROM ft1 t1 WHERE t1.tableoid = 'ft1'::regclass ORDER BY (fields->>'C 1')::int LIMIT 1; - time | tags | fields ---------------------------+-----------------+--------------------------------------------------------------------- - Fri Jan 02 00:00:00 1970 | {"c3": "00001"} | {"c2": "1", "c6": "1", "c7": "1 ", "c8": "foo", "C 1": "1"} + time | tags | fields +------------------------------+-----------------+--------------------------------------------------------------------- + Fri Jan 02 00:00:00 1970 PST | {"c3": "00001"} | {"c2": "1", "c6": "1", "c7": "1 ", "c8": "foo", "C 1": "1"} (1 row) --Testcase 397: @@ -5573,9 +5573,9 @@ SELECT tableoid::regclass, * FROM ft1 t1 LIMIT 1; --Testcase 398: SELECT tableoid::regclass, * FROM ft1 t1 ORDER BY (fields->>'C 1')::int LIMIT 1; - tableoid | time | tags | fields -----------+--------------------------+-----------------+--------------------------------------------------------------------- - ft1 | Fri Jan 02 00:00:00 1970 | {"c3": "00001"} | {"c2": "1", "c6": "1", "c7": "1 ", "c8": "foo", "C 1": "1"} + tableoid | time | tags | fields +----------+------------------------------+-----------------+--------------------------------------------------------------------- + ft1 | Fri Jan 02 00:00:00 1970 PST | {"c3": "00001"} | {"c2": "1", "c6": "1", "c7": "1 ", "c8": "foo", "C 1": "1"} (1 row) --Testcase 399: @@ -5607,9 +5607,9 @@ SELECT ctid, * FROM ft1 t1 LIMIT 1; --Testcase 402: SELECT ctid, * FROM ft1 t1 ORDER BY (fields->>'C 1')::int LIMIT 1; - ctid | time | tags | fields -----------------+--------------------------+-----------------+--------------------------------------------------------------------- - (4294967295,0) | Fri Jan 02 00:00:00 1970 | {"c3": "00001"} | {"c2": "1", "c6": "1", "c7": "1 ", "c8": "foo", "C 1": "1"} + ctid | time | tags | fields +----------------+------------------------------+-----------------+--------------------------------------------------------------------- + (4294967295,0) | Fri Jan 02 00:00:00 1970 PST | {"c3": "00001"} | {"c2": "1", "c6": "1", "c7": "1 ", "c8": "foo", "C 1": "1"} (1 row) -- =================================================================== @@ -5694,9 +5694,9 @@ SELECT * FROM ft1 WHERE (fields->>'c8')::text = 'foo' LIMIT 1; --Testcase 769: SELECT * FROM ft1 WHERE (fields->>'c8')::text = 'foo' LIMIT 1; - time | tags | fields ---------------------------+-----------------+----------------------------------------------------------------------- - Thu Jan 01 00:00:00 1970 | {"c3": "00100"} | {"c2": "0", "c6": "0", "c7": "0 ", "c8": "foo", "C 1": "100"} + time | tags | fields +------------------------------+-----------------+----------------------------------------------------------------------- + Thu Jan 01 00:00:00 1970 PST | {"c3": "00100"} | {"c2": "0", "c6": "0", "c7": "0 ", "c8": "foo", "C 1": "100"} (1 row) --Testcase 770: @@ -5711,9 +5711,9 @@ SELECT * FROM ft1 WHERE 'foo' = (fields->>'c8')::text LIMIT 1; --Testcase 771: SELECT * FROM ft1 WHERE 'foo' = (fields->>'c8')::text LIMIT 1; - time | tags | fields ---------------------------+-----------------+----------------------------------------------------------------------- - Thu Jan 01 00:00:00 1970 | {"c3": "00100"} | {"c2": "0", "c6": "0", "c7": "0 ", "c8": "foo", "C 1": "100"} + time | tags | fields +------------------------------+-----------------+----------------------------------------------------------------------- + Thu Jan 01 00:00:00 1970 PST | {"c3": "00100"} | {"c2": "0", "c6": "0", "c7": "0 ", "c8": "foo", "C 1": "100"} (1 row) -- we declared c8 to be text locally, but it's still the same type on @@ -5724,16 +5724,16 @@ SELECT * FROM ft1 WHERE 'foo' = (fields->>'c8')::text LIMIT 1; -- match. These case below not error with influxdb_fdw. --Testcase 772: SELECT * FROM ft1 WHERE (fields->>'c8')::text LIKE 'foo' LIMIT 1; -- ERROR - time | tags | fields ---------------------------+-----------------+----------------------------------------------------------------------- - Thu Jan 01 00:00:00 1970 | {"c3": "00100"} | {"c2": "0", "c6": "0", "c7": "0 ", "c8": "foo", "C 1": "100"} + time | tags | fields +------------------------------+-----------------+----------------------------------------------------------------------- + Thu Jan 01 00:00:00 1970 PST | {"c3": "00100"} | {"c2": "0", "c6": "0", "c7": "0 ", "c8": "foo", "C 1": "100"} (1 row) --Testcase 773: SELECT * FROM ft1 WHERE ((fields->>'c8')::text)::text LIKE 'foo' LIMIT 1; -- ERROR; cast not pushed down - time | tags | fields ---------------------------+-----------------+----------------------------------------------------------------------- - Thu Jan 01 00:00:00 1970 | {"c3": "00100"} | {"c2": "0", "c6": "0", "c7": "0 ", "c8": "foo", "C 1": "100"} + time | tags | fields +------------------------------+-----------------+----------------------------------------------------------------------- + Thu Jan 01 00:00:00 1970 PST | {"c3": "00100"} | {"c2": "0", "c6": "0", "c7": "0 ", "c8": "foo", "C 1": "100"} (1 row) /* @@ -5882,12 +5882,12 @@ explain (verbose, costs off) select * from ft3 f, loct3 l --Testcase 431: EXPLAIN (verbose, costs off) INSERT INTO ft2_nsc (c1,c2,c3) SELECT c1+1000,c2+100, c3 || c3 FROM ft2_nsc ORDER BY c1 LIMIT 20; - QUERY PLAN -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- + QUERY PLAN +---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- Insert on public.ft2_nsc Batch Size: 1 -> Subquery Scan on "*SELECT*" - Output: "*SELECT*"."?column?", "*SELECT*"."?column?_1", NULL::integer, "*SELECT*"."?column?_2", NULL::timestamp without time zone, NULL::character varying, 'ft2 '::character(10), NULL::text + Output: "*SELECT*"."?column?", "*SELECT*"."?column?_1", NULL::integer, "*SELECT*"."?column?_2", NULL::timestamp with time zone, NULL::character varying, 'ft2 '::character(10), NULL::text -> Limit Output: ((ft2_nsc_1.c1 + 1000)), ((ft2_nsc_1.c2 + 100)), ((ft2_nsc_1.c3 || ft2_nsc_1.c3)), ft2_nsc_1.c1 -> Sort @@ -6901,12 +6901,12 @@ SELECT (fields->>'C 1')::int c1, (fields->>'c2')::int c2, tags->>'c3' c3 FROM ft --Testcase 443: EXPLAIN (verbose, costs off) INSERT INTO ft2_nsc (c1,c2,c3) VALUES (1200,999,'foo'); - QUERY PLAN ------------------------------------------------------------------------------------------------------------------------------------------------------------- + QUERY PLAN +--------------------------------------------------------------------------------------------------------------------------------------------------------- Insert on public.ft2_nsc Batch Size: 1 -> Result - Output: 1200, 999, NULL::integer, 'foo'::text, NULL::timestamp without time zone, NULL::character varying, 'ft2 '::character(10), NULL::text + Output: 1200, 999, NULL::integer, 'foo'::text, NULL::timestamp with time zone, NULL::character varying, 'ft2 '::character(10), NULL::text (4 rows) --Testcase 444: @@ -9651,7 +9651,7 @@ CREATE FOREIGN TABLE pg_temp.ft1_nopw ( c2 int NOT NULL, c3 text, c4 timestamptz, - c5 timestamp, + c5 timestamptz, c6 varchar(10), c7 char(10) default 'ft1', c8 user_enum diff --git a/expected/15.0/schemaless/extra/insert.out b/expected/15.4/schemaless/extra/insert.out similarity index 100% rename from expected/15.0/schemaless/extra/insert.out rename to expected/15.4/schemaless/extra/insert.out diff --git a/expected/15.0/schemaless/extra/join.out b/expected/15.4/schemaless/extra/join.out similarity index 100% rename from expected/15.0/schemaless/extra/join.out rename to expected/15.4/schemaless/extra/join.out diff --git a/expected/15.0/schemaless/extra/limit.out b/expected/15.4/schemaless/extra/limit.out similarity index 100% rename from expected/15.0/schemaless/extra/limit.out rename to expected/15.4/schemaless/extra/limit.out diff --git a/expected/15.0/schemaless/extra/prepare.out b/expected/15.4/schemaless/extra/prepare.out similarity index 100% rename from expected/15.0/schemaless/extra/prepare.out rename to expected/15.4/schemaless/extra/prepare.out diff --git a/expected/15.0/schemaless/extra/select.out b/expected/15.4/schemaless/extra/select.out similarity index 100% rename from expected/15.0/schemaless/extra/select.out rename to expected/15.4/schemaless/extra/select.out diff --git a/expected/15.0/schemaless/extra/select_having.out b/expected/15.4/schemaless/extra/select_having.out similarity index 100% rename from expected/15.0/schemaless/extra/select_having.out rename to expected/15.4/schemaless/extra/select_having.out diff --git a/expected/15.0/schemaless/influxdb_fdw.out b/expected/15.4/schemaless/influxdb_fdw.out similarity index 99% rename from expected/15.0/schemaless/influxdb_fdw.out rename to expected/15.4/schemaless/influxdb_fdw.out index 8222748..07e19b9 100644 --- a/expected/15.0/schemaless/influxdb_fdw.out +++ b/expected/15.4/schemaless/influxdb_fdw.out @@ -1130,14 +1130,14 @@ SELECT * FROM t5; SELECT * FROM public.influxdb_fdw_version(); influxdb_fdw_version ---------------------- - 20000 + 20100 (1 row) --Testcase 146: SELECT influxdb_fdw_version(); influxdb_fdw_version ---------------------- - 20000 + 20100 (1 row) --Test pushdown LIMIT...OFFSET diff --git a/expected/15.0/schemaless/schemaless.out b/expected/15.4/schemaless/schemaless.out similarity index 100% rename from expected/15.0/schemaless/schemaless.out rename to expected/15.4/schemaless/schemaless.out diff --git a/expected/15.0/schemaless/selectfunc.out b/expected/15.4/schemaless/selectfunc.out similarity index 100% rename from expected/15.0/schemaless/selectfunc.out rename to expected/15.4/schemaless/selectfunc.out diff --git a/expected/15.0/selectfunc.out b/expected/15.4/selectfunc.out similarity index 100% rename from expected/15.0/selectfunc.out rename to expected/15.4/selectfunc.out diff --git a/expected/15.0/aggregate.out b/expected/16.0/aggregate.out similarity index 100% rename from expected/15.0/aggregate.out rename to expected/16.0/aggregate.out diff --git a/expected/11.17/extra/aggregates.out b/expected/16.0/extra/aggregates.out similarity index 81% rename from expected/11.17/extra/aggregates.out rename to expected/16.0/extra/aggregates.out index 1468d84..1b444be 100644 --- a/expected/11.17/extra/aggregates.out +++ b/expected/16.0/extra/aggregates.out @@ -87,9 +87,14 @@ CREATE FOREIGN TABLE FLOAT8_TBL (f1 float8) SERVER influxdb_svr; -- -- AGGREGATES -- +-- directory paths are passed to us in environment variables +--\getenv abs_srcdir PG_ABS_SRCDIR -- avoid bit-exact output here because operations may not be bit-exact. --Testcase 19: SET extra_float_digits = 0; +--\set filename :abs_srcdir '/init/agg.txt' +--COPY aggtest FROM :'filename'; +--ANALYZE aggtest; --Testcase 20: SELECT avg(four) AS avg_1 FROM onek; avg_1 @@ -104,6 +109,61 @@ SELECT avg(a) AS avg_32 FROM aggtest WHERE a < 100; 32.6666666666666667 (1 row) +--Testcase 514: +CREATE FOREIGN TABLE v1 (v int4) SERVER influxdb_svr OPTIONS (table 'v1'); +--Testcase 515: +INSERT INTO v1 (v) VALUES (1), (2), (3); +--Testcase 516: +SELECT any_value(v) FROM v1; + any_value +----------- + 1 +(1 row) + +--Testcase 517: +DELETE FROM v1; +-- NULL datatype is not supported in influxdb. Expectation is error. +--Testcase 518: +INSERT INTO v1 (v) VALUES (NULL); +ERROR: influxdb_fdw : point without fields is unsupported +--Testcase 519: +SELECT any_value(v) FROM v1; + any_value +----------- + +(1 row) + +--Testcase 520: +DELETE FROM v1; +-- NULL datatype is not supported in influxdb. Expectation is error. +--Testcase 521: +INSERT INTO v1 (v) VALUES (NULL), (1), (2); +ERROR: influxdb_fdw : point without fields is unsupported +--Testcase 522: +SELECT any_value(v) FROM v1; + any_value +----------- + +(1 row) + +--Testcase 523: +DELETE FROM v1; +--Testcase 524: +CREATE FOREIGN TABLE v2 (v text[]) SERVER influxdb_svr OPTIONS (table 'v2'); +-- Cannot binding text array. Expectation is error. +--Testcase 525: +INSERT INTO v2 (v) VALUES (array['hello', 'world']); +ERROR: cannot convert constant value to InfluxDB value 1009 +HINT: Constant value data type: 1009 +--Testcase 526: +SELECT any_value(v) FROM v2; + any_value +----------- + +(1 row) + +--Testcase 527: +DELETE FROM v2; -- In 7.1, avg(float4) is computed using float8 arithmetic. -- Round the result to 3 digits to avoid platform-specific results. --Testcase 22: @@ -336,22 +396,30 @@ SELECT stddev_pop(a::numeric), stddev_samp(b::numeric) FROM agg_t5 WHERE id = 2; --Testcase 55: SELECT var_pop(a::numeric), var_samp(b::numeric) FROM agg_t5 WHERE id = 3; -ERROR: invalid input syntax for type numeric: "inf" + var_pop | var_samp +---------+---------- + NaN | +(1 row) + --Testcase 56: SELECT stddev_pop(a::numeric), stddev_samp(b::numeric) FROM agg_t5 WHERE id = 3; -ERROR: invalid input syntax for type numeric: "inf" + stddev_pop | stddev_samp +------------+------------- + NaN | +(1 row) + --Testcase 57: SELECT var_pop(a::numeric), var_samp(b::numeric) FROM agg_t5 WHERE id = 4; var_pop | var_samp ---------+---------- - NaN | NaN + NaN | (1 row) --Testcase 58: SELECT stddev_pop(a::numeric), stddev_samp(b::numeric) FROM agg_t5 WHERE id = 4; stddev_pop | stddev_samp ------------+------------- - NaN | NaN + NaN | (1 row) -- verify correct results for null and NaN inputs @@ -473,23 +541,43 @@ FROM infinite1 WHERE id = 5; --Testcase 76: SELECT sum(x::numeric), avg(x::numeric), var_pop(x::numeric) FROM infinite1 WHERE id = 1; -ERROR: invalid input syntax for type numeric: "infinity" + sum | avg | var_pop +----------+----------+--------- + Infinity | Infinity | NaN +(1 row) + --Testcase 77: SELECT sum(x::numeric), avg(x::numeric), var_pop(x::numeric) FROM infinite1 WHERE id = 2; -ERROR: invalid input syntax for type numeric: "infinity" + sum | avg | var_pop +----------+----------+--------- + Infinity | Infinity | NaN +(1 row) + --Testcase 78: SELECT sum(x::numeric), avg(x::numeric), var_pop(x::numeric) FROM infinite1 WHERE id = 3; -ERROR: invalid input syntax for type numeric: "infinity" + sum | avg | var_pop +----------+----------+--------- + Infinity | Infinity | NaN +(1 row) + --Testcase 79: SELECT sum(x::numeric), avg(x::numeric), var_pop(x::numeric) FROM infinite1 WHERE id = 4; -ERROR: invalid input syntax for type numeric: "-infinity" + sum | avg | var_pop +-----+-----+--------- + NaN | NaN | NaN +(1 row) + --Testcase 80: SELECT sum(x::numeric), avg(x::numeric), var_pop(x::numeric) FROM infinite1 WHERE id = 5; -ERROR: invalid input syntax for type numeric: "-infinity" + sum | avg | var_pop +-----------+-----------+--------- + -Infinity | -Infinity | NaN +(1 row) + -- test accuracy with a large input offset --Testcase 81: create foreign table large_input1(id int, x float8) server influxdb_svr; @@ -498,7 +586,7 @@ SELECT avg(x::float8), var_pop(x::float8) FROM large_input1 WHERE id=1; avg | var_pop -----------+--------- - 100000005 | 4 + 100000005 | 2.5 (1 row) --Testcase 83: @@ -506,7 +594,7 @@ SELECT avg(x::float8), var_pop(x::float8) FROM large_input1 WHERE id=2; avg | var_pop ---------------+--------- - 7000000000006 | 0 + 7000000000006 | 1 (1 row) -- SQL2003 binary aggregates @@ -620,16 +708,16 @@ FROM regr_test; CREATE FOREIGN TABLE float8_arr (id int, x text, y text) server influxdb_svr; --Testcase 101: SELECT float8_accum(x::float8[], 100) FROM float8_arr WHERE id=1; - float8_accum ---------------- - {5,240,12900} + float8_accum +-------------- + {5,240,6280} (1 row) --Testcase 102: SELECT float8_regr_accum(x::float8[], 200, 100) FROM float8_arr WHERE id=2; - float8_regr_accum ---------------------------------- - {5,240,12900,1490,123075,35050} + float8_regr_accum +------------------------------ + {5,240,6280,1490,95080,8680} (1 row) --Testcase 103: @@ -650,22 +738,46 @@ FROM regr_test WHERE x IN (80,100); --Testcase 105: SELECT float8_combine(x::float8[], y::float8[]) FROM float8_arr WHERE id=3; -ERROR: aggregate function called in non-aggregate context + float8_combine +---------------- + {3,60,200} +(1 row) + --Testcase 106: SELECT float8_combine(x::float8[], y::float8[]) FROM float8_arr WHERE id=4; -ERROR: aggregate function called in non-aggregate context + float8_combine +---------------- + {2,180,200} +(1 row) + --Testcase 107: SELECT float8_combine(x::float8[], y::float8[]) FROM float8_arr WHERE id=5; -ERROR: aggregate function called in non-aggregate context + float8_combine +---------------- + {5,240,6280} +(1 row) + --Testcase 108: SELECT float8_regr_combine(x::float8[],y::float8[]) FROM float8_arr WHERE id=6; -ERROR: aggregate function called in non-aggregate context + float8_regr_combine +--------------------------- + {3,60,200,750,20000,2000} +(1 row) + --Testcase 109: SELECT float8_regr_combine(x::float8[],y::float8[]) FROM float8_arr WHERE id=7; -ERROR: aggregate function called in non-aggregate context + float8_regr_combine +----------------------------- + {2,180,200,740,57800,-3400} +(1 row) + --Testcase 110: SELECT float8_regr_combine(x::float8[],y::float8[]) FROM float8_arr WHERE id=8; -ERROR: aggregate function called in non-aggregate context + float8_regr_combine +------------------------------ + {5,240,6280,1490,95080,8680} +(1 row) + --Testcase 111: DROP FOREIGN TABLE regr_test; -- test count, distinct @@ -929,11 +1041,12 @@ CREATE FOREIGN TABLE bitwise_test_empty ( --Testcase 137: SELECT BIT_AND(i2) AS "?", - BIT_OR(i4) AS "?" + BIT_OR(i4) AS "?", + BIT_XOR(i8) AS "?" FROM bitwise_test_empty; - ? | ? ----+--- - | + ? | ? | ? +---+---+--- + | | (1 row) --Testcase 138: @@ -958,11 +1071,17 @@ SELECT BIT_OR(i8) AS "7", BIT_OR(i) AS "?", BIT_OR(x) AS "7", - BIT_OR(y) AS "1101" + 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; - 1 | 1 | 1 | ? | 0 | 0100 | 7 | 7 | 7 | ? | 7 | 1101 ----+---+---+---+---+------+---+---+---+---+---+------ - 1 | 1 | 1 | 1 | 0 | 0100 | 7 | 7 | 7 | 3 | 7 | 1101 + 1 | 1 | 1 | ? | 0 | 0100 | 7 | 7 | 7 | ? | 7 | 1101 | 5 | 5 | 5 | ? | 7 | 1101 +---+---+---+---+---+------+---+---+---+---+---+------+---+---+---+---+---+------ + 1 | 1 | 1 | 1 | 0 | 0100 | 7 | 7 | 7 | 3 | 7 | 1101 | 5 | 5 | 5 | 2 | 7 | 1101 (1 row) -- @@ -1360,14 +1479,14 @@ insert into minmaxtest3 values(17), (18); --Testcase 189: explain (costs off) select min(f1), max(f1) from minmaxtest; - QUERY PLAN ----------------------------------------- + QUERY PLAN +----------------------------------------------------- Aggregate -> Append - -> Foreign Scan on minmaxtest - -> Seq Scan on minmaxtest1 - -> Seq Scan on minmaxtest2 - -> Seq Scan on minmaxtest3 + -> Foreign Scan on minmaxtest minmaxtest_1 + -> Seq Scan on minmaxtest1 minmaxtest_2 + -> Seq Scan on minmaxtest2 minmaxtest_3 + -> Seq Scan on minmaxtest3 minmaxtest_4 (6 rows) --Testcase 190: @@ -1381,17 +1500,17 @@ select min(f1), max(f1) from minmaxtest; --Testcase 191: explain (costs off) select distinct min(f1), max(f1) from minmaxtest; - QUERY PLAN --------------------------------------------------------------- + QUERY PLAN +----------------------------------------------------------------- Unique -> Sort Sort Key: (min(minmaxtest.f1)), (max(minmaxtest.f1)) -> Aggregate -> Append - -> Foreign Scan on minmaxtest - -> Seq Scan on minmaxtest1 - -> Seq Scan on minmaxtest2 - -> Seq Scan on minmaxtest3 + -> Foreign Scan on minmaxtest minmaxtest_1 + -> Seq Scan on minmaxtest1 minmaxtest_2 + -> Seq Scan on minmaxtest2 minmaxtest_3 + -> Seq Scan on minmaxtest3 minmaxtest_4 (9 rows) --Testcase 192: @@ -1418,6 +1537,13 @@ select (select max(min(unique1)) from int8_tbl) from tenk1; ERROR: aggregate function calls cannot be nested LINE 1: select (select max(min(unique1)) from int8_tbl) from tenk1; ^ +--Testcase 528: +select avg((select avg(a1.col1 order by (select avg(a2.col2) from tenk1 a3)) + from tenk1 a1(col1))) +from tenk1 a2(col2); +ERROR: aggregate function calls cannot be nested +LINE 1: select avg((select avg(a1.col1 order by (select avg(a2.col2)... + ^ -- -- Test removal of redundant GROUP BY columns -- @@ -1452,12 +1578,13 @@ explain (costs off) select a,c from agg_t1 group by a,c,d; explain (costs off) select * from agg_t1 inner join agg_t2 on agg_t1.a = agg_t2.x and agg_t1.b = agg_t2.y group by agg_t1.a,agg_t1.b,agg_t1.c,agg_t1.d,agg_t2.x,agg_t2.y,agg_t2.z; - QUERY PLAN ------------------------------------------------------------------------------------ + QUERY PLAN +----------------------------------------------------------------------------- Group - Group Key: agg_t1.a, agg_t1.b, agg_t1.c, agg_t1.d, agg_t2.x, agg_t2.y, agg_t2.z - -> Sort + Group Key: agg_t1.a, agg_t1.b, agg_t1.c, agg_t1.d, agg_t2.z + -> Incremental Sort Sort Key: agg_t1.a, agg_t1.b, agg_t1.c, agg_t1.d, agg_t2.z + Presorted Key: agg_t1.a, agg_t1.b -> Merge Join Merge Cond: ((agg_t1.a = agg_t2.x) AND (agg_t1.b = agg_t2.y)) -> Sort @@ -1466,7 +1593,7 @@ group by agg_t1.a,agg_t1.b,agg_t1.c,agg_t1.d,agg_t2.x,agg_t2.y,agg_t2.z; -> Sort Sort Key: agg_t2.x, agg_t2.y -> Foreign Scan on agg_t2 -(12 rows) +(13 rows) -- Test case where agg_t1 can be optimized but not agg_t2 --Testcase 202: @@ -1476,9 +1603,10 @@ group by agg_t1.a,agg_t1.b,agg_t1.c,agg_t1.d,agg_t2.x,agg_t2.z; QUERY PLAN ----------------------------------------------------------------------------- Group - Group Key: agg_t1.a, agg_t1.b, agg_t1.c, agg_t1.d, agg_t2.x, agg_t2.z - -> Sort + Group Key: agg_t1.a, agg_t1.b, agg_t1.c, agg_t1.d, agg_t2.z + -> Incremental Sort Sort Key: agg_t1.a, agg_t1.b, agg_t1.c, agg_t1.d, agg_t2.z + Presorted Key: agg_t1.a, agg_t1.b -> Merge Join Merge Cond: ((agg_t1.a = agg_t2.x) AND (agg_t1.b = agg_t2.y)) -> Sort @@ -1487,7 +1615,7 @@ group by agg_t1.a,agg_t1.b,agg_t1.c,agg_t1.d,agg_t2.x,agg_t2.z; -> Sort Sort Key: agg_t2.x, agg_t2.y -> Foreign Scan on agg_t2 -(12 rows) +(13 rows) -- Cannot optimize when PK is deferrable --Testcase 203: @@ -1509,8 +1637,8 @@ explain (costs off) select * from agg_t1 group by a,b,c,d; HashAggregate Group Key: agg_t1.a, agg_t1.b, agg_t1.c, agg_t1.d -> Append - -> Foreign Scan on agg_t1 - -> Seq Scan on agg_t1c + -> Foreign Scan on agg_t1 agg_t1_1 + -> Seq Scan on agg_t1c agg_t1_2 (5 rows) -- Okay to remove columns if we're only querying the parent. @@ -1538,10 +1666,10 @@ create temp table p_agg_t1_2 partition of p_agg_t1 for values in(2); -- Ensure we can remove non-PK columns for partitioned tables. --Testcase 210: explain (costs off) select * from p_agg_t1 group by a,b,c,d; - QUERY PLAN ------------------------------------------ + QUERY PLAN +------------------------------------- HashAggregate - Group Key: p_agg_t1_1.a, p_agg_t1_1.b + Group Key: p_agg_t1.a, p_agg_t1.b -> Append -> Seq Scan on p_agg_t1_1 -> Seq Scan on p_agg_t1_2 @@ -1560,9 +1688,9 @@ drop table p_agg_t1; -- Test GROUP BY matching of join columns that are type-coerced due to USING -- --Testcase 215: -create foreign table agg_t1(f1 int, f2 bigint) server influxdb_svr; +create foreign table agg_t1(f1 int, f2 int) server influxdb_svr; --Testcase 216: -create foreign table agg_t2(f1 bigint, f22 bigint) server influxdb_svr; +create foreign table agg_t2(f1 bigint, f2 oid) server influxdb_svr; --Testcase 217: select f1 from agg_t1 left join agg_t2 using (f1) group by f1; f1 @@ -1587,11 +1715,153 @@ select agg_t1.f1 from agg_t1 left join agg_t2 using (f1) group by f1; ERROR: column "agg_t1.f1" must appear in the GROUP BY clause or be used in an aggregate function LINE 1: select agg_t1.f1 from agg_t1 left join agg_t2 using (f1) gro... ^ +-- check case where we have to inject nullingrels into coerced join alias +--Testcase 529: +select f1, count(*) from +agg_t1 x(x0,x1) left join (agg_t1 left join agg_t2 using(f1)) on (x0 = 0) +group by f1; + f1 | count +----+------- +(0 rows) + +-- same, for a RelabelType coercion +--Testcase 530: +select f2, count(*) from +agg_t1 x(x0,x1) left join (agg_t1 left join agg_t2 using(f2)) on (x0 = 0) +group by f2; + f2 | count +----+------- +(0 rows) + --Testcase 221: drop foreign table agg_t1 cascade; --Testcase 222: drop foreign table agg_t2 cascade; -- +-- Test planner's selection of pathkeys for ORDER BY aggregates +-- +-- Ensure we order by four. This suits the most aggregate functions. +--Testcase 531: +explain (costs off) +select sum(two order by two),max(four order by four), min(four order by four) +from tenk1; + QUERY PLAN +----------------------------------- + Aggregate + -> Sort + Sort Key: four + -> Foreign Scan on tenk1 +(4 rows) + +-- Ensure we order by two. It's a tie between ordering by two and four but +-- we tiebreak on the aggregate's position. +--Testcase 532: +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; + QUERY PLAN +----------------------------------- + Aggregate + -> Sort + Sort Key: two + -> Foreign Scan on tenk1 +(4 rows) + +-- Similar to above, but tiebreak on ordering by four +--Testcase 533: +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; + QUERY PLAN +----------------------------------- + Aggregate + -> Sort + Sort Key: four + -> Foreign Scan on tenk1 +(4 rows) + +-- Ensure this one orders by ten since there are 3 aggregates that require ten +-- vs two that suit two and four. +--Testcase 534: +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; + QUERY PLAN +----------------------------------- + Aggregate + -> Sort + Sort Key: ten + -> Foreign Scan on tenk1 +(4 rows) + +-- 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. +--Testcase 535: +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; + QUERY PLAN +----------------------------------- + GroupAggregate + Group Key: ten + -> Sort + Sort Key: ten, two, four + -> Foreign Scan on tenk1 +(5 rows) + +-- 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. +--Testcase 536: +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; + QUERY PLAN +----------------------------------- + GroupAggregate + Group Key: ten + -> Sort + Sort Key: ten, four, two + -> Foreign Scan on tenk1 +(5 rows) + +-- Ensure consecutive NULLs are properly treated as distinct from each other +--Testcase 537: +select array_agg(distinct val) +from (select null as val from generate_series(1, 2)); + array_agg +----------- + {NULL} +(1 row) + +-- Ensure no ordering is requested when enable_presorted_aggregate is off +set enable_presorted_aggregate to off; +--Testcase 538: +explain (costs off) +select sum(two order by two) from tenk1; + QUERY PLAN +----------------------------- + Aggregate + -> Foreign Scan on tenk1 +(2 rows) + +reset enable_presorted_aggregate; +-- -- Test combinations of DISTINCT and/or ORDER BY -- begin; @@ -1785,9 +2055,9 @@ select * from agg_view1; --Testcase 248: select pg_get_viewdef('agg_view1'::regclass); - pg_get_viewdef ------------------------------------------------------------------------------ - SELECT aggfns(multi_arg_agg.a, multi_arg_agg.b, multi_arg_agg.c) AS aggfns+ + pg_get_viewdef +----------------------------------- + SELECT aggfns(a, b, c) AS aggfns+ FROM multi_arg_agg; (1 row) @@ -1846,9 +2116,9 @@ select * from agg_view1; --Testcase 257: select pg_get_viewdef('agg_view1'::regclass); - pg_get_viewdef ------------------------------------------------------------------------------------------------------------- - SELECT aggfns(multi_arg_agg.a, multi_arg_agg.b, multi_arg_agg.c ORDER BY (multi_arg_agg.b + 1)) AS aggfns+ + pg_get_viewdef +---------------------------------------------------- + SELECT aggfns(a, b, c ORDER BY (b + 1)) AS aggfns+ FROM multi_arg_agg; (1 row) @@ -1865,9 +2135,9 @@ select * from agg_view1; --Testcase 260: select pg_get_viewdef('agg_view1'::regclass); - pg_get_viewdef ------------------------------------------------------------------------------------------------------- - SELECT aggfns(multi_arg_agg.a, multi_arg_agg.a, multi_arg_agg.c ORDER BY multi_arg_agg.b) AS aggfns+ + pg_get_viewdef +---------------------------------------------- + SELECT aggfns(a, a, c ORDER BY b) AS aggfns+ FROM multi_arg_agg; (1 row) @@ -1884,9 +2154,9 @@ select * from agg_view1; --Testcase 263: select pg_get_viewdef('agg_view1'::regclass); - pg_get_viewdef ---------------------------------------------------------------------------------------------------------------------------- - SELECT aggfns(multi_arg_agg.a, multi_arg_agg.b, multi_arg_agg.c ORDER BY multi_arg_agg.c USING ~<~ NULLS LAST) AS aggfns+ + pg_get_viewdef +------------------------------------------------------------------- + SELECT aggfns(a, b, c ORDER BY c USING ~<~ NULLS LAST) AS aggfns+ FROM multi_arg_agg; (1 row) @@ -2020,6 +2290,115 @@ select string_agg(v, decode('ee', 'hex')) from bytea_test_table; drop table bytea_test_table; */ +-- Test parallel string_agg and array_agg +--Testcase 539: +create foreign table pagg_test ( + x int, + y int +) server influxdb_svr options (table 'pagg_test'); +--Testcase 540: +insert into pagg_test +select (case x % 4 when 1 then null else x end), x % 10 +from generate_series(1,5000) x; +set parallel_setup_cost TO 0; +set parallel_tuple_cost TO 0; +set parallel_leader_participation TO 0; +set min_parallel_table_scan_size = 0; +set bytea_output = 'escape'; +set max_parallel_workers_per_gather = 2; +-- create a view as we otherwise have to repeat this query a few times. +--Testcase 541: +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; +-- Ensure results are correct. +--Testcase 542: +select * from v_pagg_test order by y; + y | tmin | tmax | tndistinct | bmin | bmax | bndistinct | amin | amax | andistinct | aamin | aamax | aandistinct +---+------+------+------------+------+------+------------+------+------+------------+-------+-------+------------- + 0 | 10 | 5000 | 500 | 10 | 990 | 500 | 10 | 5000 | 500 | 10 | 5000 | 500 + 1 | 11 | 4991 | 250 | 1011 | 991 | 250 | 11 | 4991 | 250 | 11 | 4991 | 250 + 2 | 2 | 4992 | 500 | 1002 | 992 | 500 | 2 | 4992 | 500 | 2 | 4992 | 500 + 3 | 3 | 4983 | 250 | 1003 | 983 | 250 | 3 | 4983 | 250 | 3 | 4983 | 250 + 4 | 4 | 4994 | 500 | 1004 | 994 | 500 | 4 | 4994 | 500 | 4 | 4994 | 500 + 5 | 15 | 4995 | 250 | 1015 | 995 | 250 | 15 | 4995 | 250 | 15 | 4995 | 250 + 6 | 6 | 4996 | 500 | 1006 | 996 | 500 | 6 | 4996 | 500 | 6 | 4996 | 500 + 7 | 7 | 4987 | 250 | 1007 | 987 | 250 | 7 | 4987 | 250 | 7 | 4987 | 250 + 8 | 8 | 4998 | 500 | 1008 | 998 | 500 | 8 | 4998 | 500 | 8 | 4998 | 500 + 9 | 19 | 4999 | 250 | 1019 | 999 | 250 | 19 | 4999 | 250 | 19 | 4999 | 250 +(10 rows) + +-- Ensure parallel aggregation is actually being used. +-- influxdb_fdw: parallel execution is not supported +--Testcase 543: +explain (costs off) select * from v_pagg_test order by y; + QUERY PLAN +-------------------------------------------------------------------------------------------------------------------------------------- + GroupAggregate + Group Key: pagg_test.y + -> Sort + Sort Key: pagg_test.y, (((unnest(regexp_split_to_array((string_agg((pagg_test.x)::text, ','::text)), ','::text))))::integer) + -> Result + -> ProjectSet + -> HashAggregate + Group Key: pagg_test.y + -> Foreign Scan on pagg_test +(9 rows) + +set max_parallel_workers_per_gather = 0; +-- Ensure results are the same without parallel aggregation. +--Testcase 544: +select * from v_pagg_test order by y; + y | tmin | tmax | tndistinct | bmin | bmax | bndistinct | amin | amax | andistinct | aamin | aamax | aandistinct +---+------+------+------------+------+------+------------+------+------+------------+-------+-------+------------- + 0 | 10 | 5000 | 500 | 10 | 990 | 500 | 10 | 5000 | 500 | 10 | 5000 | 500 + 1 | 11 | 4991 | 250 | 1011 | 991 | 250 | 11 | 4991 | 250 | 11 | 4991 | 250 + 2 | 2 | 4992 | 500 | 1002 | 992 | 500 | 2 | 4992 | 500 | 2 | 4992 | 500 + 3 | 3 | 4983 | 250 | 1003 | 983 | 250 | 3 | 4983 | 250 | 3 | 4983 | 250 + 4 | 4 | 4994 | 500 | 1004 | 994 | 500 | 4 | 4994 | 500 | 4 | 4994 | 500 + 5 | 15 | 4995 | 250 | 1015 | 995 | 250 | 15 | 4995 | 250 | 15 | 4995 | 250 + 6 | 6 | 4996 | 500 | 1006 | 996 | 500 | 6 | 4996 | 500 | 6 | 4996 | 500 + 7 | 7 | 4987 | 250 | 1007 | 987 | 250 | 7 | 4987 | 250 | 7 | 4987 | 250 + 8 | 8 | 4998 | 500 | 1008 | 998 | 500 | 8 | 4998 | 500 | 8 | 4998 | 500 + 9 | 19 | 4999 | 250 | 1019 | 999 | 250 | 19 | 4999 | 250 | 19 | 4999 | 250 +(10 rows) + +-- Clean up +reset max_parallel_workers_per_gather; +reset bytea_output; +reset min_parallel_table_scan_size; +reset parallel_leader_participation; +reset parallel_tuple_cost; +reset parallel_setup_cost; +--Testcase 545: +drop view v_pagg_test; +--Testcase 546: +drop table pagg_test; +ERROR: "pagg_test" is not a table +HINT: Use DROP FOREIGN TABLE to remove a foreign table. -- FILTER tests --Testcase 284: select min(unique1) filter (where unique1 > 100) from tenk1; @@ -2073,6 +2452,15 @@ from (values ('a', 'b')) AS v(foo,bar); a (1 row) +--Testcase 553: +INSERT INTO v1 (v) VALUES (1), (2), (3); +--Testcase 547: +select any_value(v) filter (where v > 2) from v1; + any_value +----------- + 3 +(1 row) + -- outer reference in FILTER (PostgreSQL extension) --Testcase 289: select (select count(*) @@ -2134,6 +2522,42 @@ select aggfns(distinct a,b,c order by a,c using ~<~,b) filter (where a > 1) (1 row) rollback; +-- check handling of bare boolean Var in FILTER +--Testcase 454: +select max(0) filter (where b1) from bool_test; + max +----- + 0 +(1 row) + +--Testcase 455: +select (select max(0) filter (where b1)) from bool_test; + max +----- + 0 +(1 row) + +-- check for correct detection of nested-aggregate errors in FILTER +--Testcase 456: +select max(unique1) filter (where sum(ten) > 0) from tenk1; +ERROR: aggregate functions are not allowed in FILTER +LINE 1: select max(unique1) filter (where sum(ten) > 0) from tenk1; + ^ +--Testcase 457: +select (select max(unique1) filter (where sum(ten) > 0) from int8_tbl) from tenk1; +ERROR: aggregate function calls cannot be nested +LINE 1: select (select max(unique1) filter (where sum(ten) > 0) from... + ^ +--Testcase 458: +select max(unique1) filter (where bool_or(ten > 0)) from tenk1; +ERROR: aggregate functions are not allowed in FILTER +LINE 1: select max(unique1) filter (where bool_or(ten > 0)) from ten... + ^ +--Testcase 459: +select (select max(unique1) filter (where bool_or(ten > 0)) from int8_tbl) from tenk1; +ERROR: aggregate function calls cannot be nested +LINE 1: select (select max(unique1) filter (where bool_or(ten > 0)) ... + ^ -- ordered-set aggregates begin; --Testcase 295: @@ -2172,7 +2596,7 @@ from generate_series(1,5) x, FLOAT8_TBL group by f1 order by f1; ERROR: sum is not an ordered-set aggregate, so it cannot have WITHIN GROUP -LINE 1: select f1, sum() within group (order by x::float8) +LINE 1: select f1, sum() within group (order by x::float8) -- error ^ rollback; begin; @@ -2182,7 +2606,7 @@ from generate_series(1,5) x, FLOAT8_TBL group by f1 order by f1; ERROR: WITHIN GROUP is required for ordered-set aggregate percentile_cont -LINE 1: select f1, percentile_cont(f1,f1) +LINE 1: select f1, percentile_cont(f1,f1) -- error ^ rollback; --Testcase 299: @@ -2385,7 +2809,7 @@ LINE 1: select rank(3) within group (order by stringu1,stringu2) fro... HINT: To use the hypothetical-set aggregate rank, the number of hypothetical direct arguments (here 1) must match the number of ordering columns (here 2). --Testcase 328: select rank('fred') within group (order by x) from generate_series3 x; -ERROR: invalid input syntax for integer: "fred" +ERROR: invalid input syntax for type integer: "fred" LINE 1: select rank('fred') within group (order by x) from generate_... ^ --Testcase 329: @@ -2428,15 +2852,15 @@ select ten, group by ten order by ten; --Testcase 334: select pg_get_viewdef('aggordview1'); - pg_get_viewdef -------------------------------------------------------------------------------------------------------------------------------- - SELECT tenk1.ten, + - percentile_disc((0.5)::double precision) WITHIN GROUP (ORDER BY tenk1.thousand) AS p50, + - percentile_disc((0.5)::double precision) WITHIN GROUP (ORDER BY tenk1.thousand) FILTER (WHERE (tenk1.hundred = 1)) AS px,+ - rank(5, 'AZZZZ'::name, 50) WITHIN GROUP (ORDER BY tenk1.hundred, tenk1.string4 DESC, tenk1.hundred) AS rank + - FROM tenk1 + - GROUP BY tenk1.ten + - ORDER BY tenk1.ten; + pg_get_viewdef +------------------------------------------------------------------------------------------------------------------- + SELECT ten, + + percentile_disc((0.5)::double precision) WITHIN GROUP (ORDER BY thousand) AS p50, + + percentile_disc((0.5)::double precision) WITHIN GROUP (ORDER BY thousand) FILTER (WHERE (hundred = 1)) AS px,+ + rank(5, 'AZZZZ'::name, 50) WITHIN GROUP (ORDER BY hundred, string4 DESC, hundred) AS rank + + FROM tenk1 + + GROUP BY ten + + ORDER BY ten; (1 row) --Testcase 335: @@ -2470,12 +2894,10 @@ create aggregate least_agg(variadic items anyarray) ( 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)'; -ERROR: type anycompatible does not exist --Testcase 340: create aggregate cleast_agg(variadic items anycompatiblearray) ( stype = anycompatible, sfunc = cleast_accum ); -ERROR: type anycompatiblearray does not exist -- variadic aggregates --Testcase 341: select least_agg(q1,q2) from int8_tbl; @@ -2493,28 +2915,32 @@ select least_agg(variadic array[q1,q2]) from int8_tbl; --Testcase 343: select cleast_agg(q1,q2) from int8_tbl; -ERROR: function cleast_agg(bigint, bigint) does not exist -LINE 1: select cleast_agg(q1,q2) from int8_tbl; - ^ -HINT: No function matches the given name and argument types. You might need to add explicit type casts. + cleast_agg +------------------- + -4567890123456789 +(1 row) + --Testcase 344: select cleast_agg(4.5,f1) from int4_tbl; -ERROR: function cleast_agg(numeric, integer) does not exist -LINE 1: select cleast_agg(4.5,f1) from int4_tbl; - ^ -HINT: No function matches the given name and argument types. You might need to add explicit type casts. + cleast_agg +------------- + -2147483647 +(1 row) + --Testcase 345: select cleast_agg(variadic array[4.5,f1]) from int4_tbl; -ERROR: function cleast_agg(numeric[]) does not exist -LINE 1: select cleast_agg(variadic array[4.5,f1]) from int4_tbl; - ^ -HINT: No function matches the given name and argument types. You might need to add explicit type casts. + cleast_agg +------------- + -2147483647 +(1 row) + --Testcase 346: select pg_typeof(cleast_agg(variadic array[4.5,f1])) from int4_tbl; -ERROR: function cleast_agg(numeric[]) does not exist -LINE 1: select pg_typeof(cleast_agg(variadic array[4.5,f1])) from in... - ^ -HINT: No function matches the given name and argument types. You might need to add explicit type casts. + pg_typeof +----------- + numeric +(1 row) + --Testcase 347: drop aggregate least_agg(variadic items anyarray); --Testcase 348: @@ -2617,8 +3043,8 @@ NOTICE: avg_transfn called with 3 --Testcase 359: select my_avg(distinct one),my_sum(one) from my_avg1; NOTICE: avg_transfn called with 1 -NOTICE: avg_transfn called with 3 NOTICE: avg_transfn called with 1 +NOTICE: avg_transfn called with 3 NOTICE: avg_transfn called with 3 my_avg | my_sum --------+-------- @@ -2641,10 +3067,10 @@ NOTICE: avg_transfn called with 3 create foreign table my_avg2(one int, two int) server influxdb_svr; --Testcase 362: select my_avg(one),my_sum(two) from my_avg2; -NOTICE: avg_transfn called with 2 NOTICE: avg_transfn called with 1 -NOTICE: avg_transfn called with 4 +NOTICE: avg_transfn called with 2 NOTICE: avg_transfn called with 3 +NOTICE: avg_transfn called with 4 my_avg | my_sum --------+-------- 2 | 6 @@ -2824,6 +3250,48 @@ SELECT balk(hundred) FROM tenk1; (1 row) +ROLLBACK; +-- test multiple usage of an aggregate whose finalfn returns a R/W datum +BEGIN; +--Testcase 548: +CREATE FUNCTION rwagg_sfunc(x anyarray, y anyarray) RETURNS anyarray +LANGUAGE plpgsql IMMUTABLE AS $$ +BEGIN + RETURN array_fill(y[1], ARRAY[4]); +END; +$$; +--Testcase 549: +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; +$$; +--Testcase 550: +CREATE AGGREGATE rwagg(anyarray) ( + STYPE = anyarray, + SFUNC = rwagg_sfunc, + FINALFUNC = rwagg_finalfunc +); +--Testcase 551: +CREATE FUNCTION eatarray(x real[]) RETURNS real[] +LANGUAGE plpgsql STRICT IMMUTABLE AS $$ +BEGIN + x[1] := x[1] + 1; + RETURN x; +END; +$$; +--Testcase 552: +SELECT eatarray(rwagg(ARRAY[1.0::real])), eatarray(rwagg(ARRAY[1.0::real])); + eatarray | eatarray +-----------+----------- + {2,1,1,1} | {2,1,1,1} +(1 row) + ROLLBACK; -- Secondly test the case of a parallel aggregate combiner function -- returning NULL. For that use normal transition function, but a @@ -3005,6 +3473,8 @@ select v||'a', case when v||'a' = 'aa' then 1 else 0 end, count(*) -- does not lead to array overflow due to unexpected duplicate hash keys -- see CAFeeJoKKu0u+A_A9R9316djW-YW3-+Gtgvy3ju655qRHR3jtdA@mail.gmail.com --Testcase 399: +set enable_memoize to off; +--Testcase 400: explain (costs off) select 1 from tenk1 where (hundred, thousand) in (select twothousand, twothousand from onek); @@ -3019,14 +3489,16 @@ explain (costs off) -> Foreign Scan on tenk1 (7 rows) +--Testcase 401: +reset enable_memoize; -- -- Hash Aggregation Spill tests -- ---Testcase 400: +--Testcase 402: set enable_sort=false; ---Testcase 401: +--Testcase 403: set work_mem='64kB'; ---Testcase 402: +--Testcase 404: select unique1, count(*), sum(twothousand) from tenk1 group by unique1 having sum(fivethous) > 4975 @@ -3083,48 +3555,48 @@ order by sum(twothousand); 9999 | 1 | 1999 (48 rows) ---Testcase 403: +--Testcase 405: set work_mem to default; ---Testcase 404: +--Testcase 406: set enable_sort to default; -- -- Compare results between plans using sorting and plans using hash -- aggregation. Force spilling in both cases by setting work_mem low. -- ---Testcase 405: +--Testcase 407: set work_mem='64kB'; ---Testcase 406: +--Testcase 408: create foreign table agg_data_2k(g int) server influxdb_svr; ---Testcase 407: +--Testcase 409: create foreign table agg_data_20k(g int) server influxdb_svr; ---Testcase 408: +--Testcase 410: create foreign table agg_group_1(c1 int, c2 numeric, c3 int) server influxdb_svr; ---Testcase 409: +--Testcase 411: create foreign table agg_group_2(a int, c1 numeric, c2 text, c3 int) server influxdb_svr; ---Testcase 410: +--Testcase 412: create foreign table agg_group_3(c1 numeric, c2 int4, c3 int) server influxdb_svr; ---Testcase 411: +--Testcase 413: create foreign table agg_group_4(c1 numeric, c2 text, c3 int) server influxdb_svr; ---Testcase 412: +--Testcase 414: create foreign table agg_hash_1(c1 int, c2 numeric, c3 int) server influxdb_svr; ---Testcase 413: +--Testcase 415: create foreign table agg_hash_2(a int, c1 numeric, c2 text, c3 int) server influxdb_svr; ---Testcase 414: +--Testcase 416: create foreign table agg_hash_3(c1 numeric, c2 int4, c3 int) server influxdb_svr; ---Testcase 415: +--Testcase 417: create foreign table agg_hash_4(c1 numeric, c2 text, c3 int) server influxdb_svr; ---Testcase 416: +--Testcase 418: insert into agg_data_2k select g from generate_series(0, 1999) g; --analyze agg_data_2k; ---Testcase 417: +--Testcase 419: insert into agg_data_20k select g from generate_series(0, 19999) g; --analyze agg_data_20k; -- Produce results with sorting. ---Testcase 418: +--Testcase 420: set enable_hashagg = false; ---Testcase 419: +--Testcase 421: set jit_above_cost = 0; ---Testcase 420: +--Testcase 422: explain (costs off) select g%10000 as c1, sum(g::numeric) as c2, count(*) as c3 from agg_data_20k group by g%10000; @@ -3137,11 +3609,11 @@ select g%10000 as c1, sum(g::numeric) as c2, count(*) as c3 -> Foreign Scan on agg_data_20k (5 rows) ---Testcase 421: +--Testcase 423: insert into agg_group_1 select g%10000 as c1, sum(g::numeric) as c2, count(*) as c3 from agg_data_20k group by g%10000; ---Testcase 422: +--Testcase 424: insert into agg_group_2 select * from (values (100), (300), (500)) as r(a), @@ -3152,24 +3624,24 @@ select * from from agg_data_2k where g < r.a group by g/2) as s; ---Testcase 423: +--Testcase 425: set jit_above_cost to default; ---Testcase 424: +--Testcase 426: insert into agg_group_3 select (g/2)::numeric as c1, sum(7::int4) as c2, count(*) as c3 from agg_data_2k group by g/2; ---Testcase 425: +--Testcase 427: insert into agg_group_4 select (g/2)::numeric as c1, array_agg(g::numeric) as c2, count(*) as c3 from agg_data_2k group by g/2; -- Produce results with hash aggregation ---Testcase 426: +--Testcase 428: set enable_hashagg = true; ---Testcase 427: +--Testcase 429: set enable_sort = false; ---Testcase 428: +--Testcase 430: set jit_above_cost = 0; ---Testcase 429: +--Testcase 431: explain (costs off) select g%10000 as c1, sum(g::numeric) as c2, count(*) as c3 from agg_data_20k group by g%10000; @@ -3180,11 +3652,11 @@ select g%10000 as c1, sum(g::numeric) as c2, count(*) as c3 -> Foreign Scan on agg_data_20k (3 rows) ---Testcase 430: +--Testcase 432: insert into agg_hash_1 select g%10000 as c1, sum(g::numeric) as c2, count(*) as c3 from agg_data_20k group by g%10000; ---Testcase 431: +--Testcase 433: insert into agg_hash_2 select * from (values (100), (300), (500)) as r(a), @@ -3195,22 +3667,22 @@ select * from from agg_data_2k where g < r.a group by g/2) as s; ---Testcase 432: +--Testcase 434: set jit_above_cost to default; ---Testcase 433: +--Testcase 435: insert into agg_hash_3 select (g/2)::numeric as c1, sum(7::int4) as c2, count(*) as c3 from agg_data_2k group by g/2; ---Testcase 434: +--Testcase 436: insert into agg_hash_4 select (g/2)::numeric as c1, array_agg(g::numeric) as c2, count(*) as c3 from agg_data_2k group by g/2; ---Testcase 435: +--Testcase 437: set enable_sort = true; ---Testcase 436: +--Testcase 438: set work_mem to default; -- Compare group aggregation results to hash aggregation results ---Testcase 437: +--Testcase 439: (select * from agg_hash_1 except select * from agg_group_1) union all (select * from agg_group_1 except select * from agg_hash_1); @@ -3218,7 +3690,7 @@ set work_mem to default; ----+----+---- (0 rows) ---Testcase 438: +--Testcase 440: (select * from agg_hash_2 except select * from agg_group_2) union all (select * from agg_group_2 except select * from agg_hash_2); @@ -3226,7 +3698,7 @@ set work_mem to default; ---+----+----+---- (0 rows) ---Testcase 439: +--Testcase 441: (select * from agg_hash_3 except select * from agg_group_3) union all (select * from agg_group_3 except select * from agg_hash_3); @@ -3234,7 +3706,7 @@ set work_mem to default; ----+----+---- (0 rows) ---Testcase 440: +--Testcase 442: (select * from agg_hash_4 except select * from agg_group_4) union all (select * from agg_group_4 except select * from agg_hash_4); @@ -3242,34 +3714,47 @@ set work_mem to default; ----+----+---- (0 rows) ---Testcase 441: +--Testcase 443: -- Clean up: +--Testcase 485: delete from agg_data_2k; +--Testcase 486: delete from agg_data_20k; +--Testcase 487: delete from agg_group_1; +--Testcase 488: delete from agg_group_2; +--Testcase 489: delete from agg_group_3; +--Testcase 490: delete from agg_group_4; +--Testcase 491: delete from agg_hash_1; +--Testcase 492: delete from agg_hash_2; +--Testcase 493: delete from agg_hash_3; +--Testcase 494: delete from agg_hash_4; +--Testcase 495: drop foreign table agg_data_2k; +--Testcase 496: drop foreign table agg_data_20k; +--Testcase 497: drop foreign table agg_group_1; ---Testcase 442: +--Testcase 444: drop foreign table agg_group_2; ---Testcase 443: +--Testcase 445: drop foreign table agg_group_3; ---Testcase 444: +--Testcase 446: drop foreign table agg_group_4; ---Testcase 445: +--Testcase 447: drop foreign table agg_hash_1; ---Testcase 446: +--Testcase 448: drop foreign table agg_hash_2; ---Testcase 447: +--Testcase 449: drop foreign table agg_hash_3; ---Testcase 448: +--Testcase 450: drop foreign table agg_hash_4; -- Clean up DO $d$ @@ -3283,27 +3768,41 @@ begin end; $d$; -- Clean up: +--Testcase 498: DROP AGGREGATE IF EXISTS newavg (int4); +--Testcase 499: DROP AGGREGATE IF EXISTS newsum (int4); +--Testcase 500: DROP AGGREGATE IF EXISTS newcnt (*); +--Testcase 501: DROP AGGREGATE IF EXISTS oldcnt (*); +--Testcase 502: DROP AGGREGATE IF EXISTS newcnt ("any"); +--Testcase 503: DROP AGGREGATE IF EXISTS sum2(int8,int8); +--Testcase 504: DROP FUNCTION IF EXISTS sum3(int8,int8,int8); +--Testcase 505: DROP AGGREGATE IF EXISTS aggfns(integer,integer,text); +--Testcase 506: DROP AGGREGATE IF EXISTS aggfstr(integer,integer,text); +--Testcase 507: DROP FUNCTION IF EXISTS aggfns_trans(aggtype[],integer,integer,text); +--Testcase 508: DROP FUNCTION IF EXISTS aggf_trans(aggtype[],integer,integer,text); +--Testcase 509: DROP TYPE IF EXISTS aggtype; +--Testcase 510: DROP AGGREGATE IF EXISTS test_percentile_disc(float8 ORDER BY anyelement); +--Testcase 511: DROP AGGREGATE IF EXISTS test_rank(VARIADIC "any" ORDER BY VARIADIC "any"); +--Testcase 512: DROP AGGREGATE IF EXISTS cleast_agg(variadic items anycompatiblearray); -NOTICE: type "anycompatiblearray" does not exist, skipping +--Testcase 513: DROP FUNCTION IF EXISTS cleast_accum(anycompatible, variadic anycompatiblearray); -NOTICE: type "anycompatible" does not exist, skipping ---Testcase 449: +--Testcase 451: DROP USER MAPPING FOR CURRENT_USER SERVER influxdb_svr; ---Testcase 450: +--Testcase 452: DROP SERVER influxdb_svr CASCADE; ---Testcase 451: +--Testcase 453: DROP EXTENSION influxdb_fdw CASCADE; diff --git a/expected/16.0/extra/influxdb_fdw_post.out b/expected/16.0/extra/influxdb_fdw_post.out new file mode 100644 index 0000000..22c753f --- /dev/null +++ b/expected/16.0/extra/influxdb_fdw_post.out @@ -0,0 +1,11086 @@ +-- =================================================================== +-- create FDW objects +-- =================================================================== +\set ECHO none +--Testcase 1: +CREATE EXTENSION influxdb_fdw; +--Testcase 2: +CREATE SERVER testserver1 FOREIGN DATA WRAPPER influxdb_fdw; +--Testcase 3: +CREATE SERVER influxdb_svr FOREIGN DATA WRAPPER influxdb_fdw + OPTIONS (dbname 'postdb', :SERVER); +--Testcase 4: +CREATE SERVER influxdb_svr2 FOREIGN DATA WRAPPER influxdb_fdw + OPTIONS (dbname 'postdb', :SERVER); +--Testcase 5: +CREATE USER MAPPING FOR public SERVER testserver1 OPTIONS (user 'value', password 'value'); +--Testcase 6: +CREATE USER MAPPING FOR CURRENT_USER SERVER influxdb_svr OPTIONS (:AUTHENTICATION); +--Testcase 7: +CREATE USER MAPPING FOR CURRENT_USER SERVER influxdb_svr2 OPTIONS (:AUTHENTICATION); +-- =================================================================== +-- create objects used through FDW influxdb server +-- =================================================================== +--Testcase 8: +CREATE TYPE user_enum AS ENUM ('foo', 'bar', 'buz'); +--Testcase 9: +CREATE SCHEMA "S 1"; +--Testcase 10: +CREATE FOREIGN TABLE "S 1"."T 0" ( + "C 1" int NOT NULL, + c2 int NOT NULL, + c3 text, + time timestamptz, + c6 varchar(10), + c7 char(10), + c8 text +) SERVER influxdb_svr OPTIONS (table 'T0', tags 'c3'); +--Testcase 11: +CREATE FOREIGN TABLE "S 1"."T 1" ( + "C 1" int NOT NULL, + c2 int NOT NULL, + c3 text, + time timestamptz, + c6 varchar(10), + c7 char(10), + c8 text +) SERVER influxdb_svr OPTIONS (table 'T1', tags 'c3'); +--Testcase 12: +CREATE FOREIGN TABLE "S 1"."T 2" ( + c1 int NOT NULL, + c2 text +) SERVER influxdb_svr OPTIONS (table 'T2', tags 'c2'); +--Testcase 13: +CREATE FOREIGN TABLE "S 1"."T 3" ( + c1 int NOT NULL, + c2 int NOT NULL, + c3 text +) SERVER influxdb_svr OPTIONS (table 'T3', tags 'c3'); +--Testcase 14: +CREATE FOREIGN TABLE "S 1"."T 4" ( + c1 int NOT NULL, + c2 int NOT NULL, + c3 text +) SERVER influxdb_svr OPTIONS (table 'T4', tags 'c3'); +-- Disable autovacuum for these tables to avoid unexpected effects of that +--ALTER TABLE "S 1"."T 1" SET (autovacuum_enabled = 'false'); +--ALTER TABLE "S 1"."T 2" SET (autovacuum_enabled = 'false'); +--ALTER TABLE "S 1"."T 3" SET (autovacuum_enabled = 'false'); +--ALTER TABLE "S 1"."T 4" SET (autovacuum_enabled = 'false'); +--Testcase 15: +INSERT INTO "S 1"."T 1" + SELECT id, + id % 10, + to_char(id, 'FM00000'), + '1970-01-01'::timestamptz + ((id % 100) || ' days')::interval, + id % 10, + id % 10, + 'foo'::text + FROM generate_series(1, 1000) id; +--Testcase 16: +INSERT INTO "S 1"."T 2" + SELECT id, + 'AAA' || to_char(id, 'FM000') + FROM generate_series(1, 100) id; +--Testcase 17: +INSERT INTO "S 1"."T 3" + SELECT id, + id + 1, + 'AAA' || to_char(id, 'FM000') + FROM generate_series(1, 100) id; +--Testcase 18: +DELETE FROM "S 1"."T 3" WHERE c1 % 2 != 0; -- delete for outer join tests +--Testcase 19: +INSERT INTO "S 1"."T 4" + SELECT id, + id + 1, + 'AAA' || to_char(id, 'FM000') + FROM generate_series(1, 100) id; +--Testcase 20: +DELETE FROM "S 1"."T 4" WHERE c1 % 3 != 0; -- delete for outer join tests +--ANALYZE "S 1"."T 1"; +--ANALYZE "S 1"."T 2"; +--ANALYZE "S 1"."T 3"; +--ANALYZE "S 1"."T 4"; +-- =================================================================== +-- create foreign tables +-- =================================================================== +--Testcase 21: +CREATE FOREIGN TABLE ft1 ( + c0 int, + c1 int NOT NULL, + c2 int NOT NULL, + c3 text, + time timestamptz, + c6 varchar(10), + c7 char(10) default 'ft1', + c8 text +) SERVER influxdb_svr; +--Testcase 22: +ALTER FOREIGN TABLE ft1 DROP COLUMN c0; +--Testcase 23: +CREATE FOREIGN TABLE ft2 ( + c1 int NOT NULL, + c2 int NOT NULL, + cx int, + c3 text, + time timestamptz, + c6 varchar(10), + c7 char(10) default 'ft2', + c8 text +) SERVER influxdb_svr; +--Testcase 24: +ALTER FOREIGN TABLE ft2 DROP COLUMN cx; +--Testcase 25: +CREATE FOREIGN TABLE ft4 ( + c1 int NOT NULL, + c2 int NOT NULL, + c3 text +) SERVER influxdb_svr OPTIONS (table 'T3', tags 'c3'); +--Testcase 26: +CREATE FOREIGN TABLE ft5 ( + c1 int NOT NULL, + c2 int NOT NULL, + c3 text +) SERVER influxdb_svr OPTIONS (table 'T4', tags 'c3'); +--Testcase 27: +CREATE FOREIGN TABLE ft6 ( + c1 int NOT NULL, + c2 int NOT NULL, + c3 text +) SERVER influxdb_svr2 OPTIONS (table 'T4', tags 'c3'); +-- =================================================================== +-- tests for validator +-- =================================================================== +-- requiressl and some other parameters are omitted because +-- valid values for them depend on configure options +--Testcase 28: +ALTER SERVER testserver1 OPTIONS ( + -- use_remote_estimate 'false', + -- updatable 'true', + -- fdw_startup_cost '123.456', + -- fdw_tuple_cost '0.123', + -- service 'value', + -- connect_timeout 'value', + dbname 'value', + host 'value', + -- hostaddr 'value', + port 'value' + --client_encoding 'value', + -- application_name 'value', + --fallback_application_name 'value', + -- keepalives 'value', + -- keepalives_idle 'value', + -- keepalives_interval 'value', + -- tcp_user_timeout 'value', + -- requiressl 'value', + -- sslcompression 'value', + -- sslmode 'value', + -- sslcert 'value', + -- sslkey 'value', + -- sslrootcert 'value', + -- sslcrl 'value', + --requirepeer 'value', + -- krbsrvname 'value', + -- gsslib 'value', + -- gssdelegation 'value' + --replication 'value' +); +-- influxdb_fdw does not support option extensions +-- Error, invalid list syntax +--ALTER SERVER testserver1 OPTIONS (ADD extensions 'foo; bar'); +-- OK but gets a warning +--ALTER SERVER testserver1 OPTIONS (ADD extensions 'foo, bar'); +--ALTER SERVER testserver1 OPTIONS (DROP extensions); +--Testcase 29: +ALTER USER MAPPING FOR public SERVER testserver1 + OPTIONS (DROP user, DROP password); +-- Attempt to add a valid option that's not allowed in a user mapping +--ALTER USER MAPPING FOR public SERVER testserver1 +-- OPTIONS (ADD sslmode 'require'); +-- But we can add valid ones fine +--ALTER USER MAPPING FOR public SERVER testserver1 +-- OPTIONS (ADD sslpassword 'dummy'); +-- Ensure valid options we haven't used in a user mapping yet are +-- permitted to check validation. +--ALTER USER MAPPING FOR public SERVER testserver1 +-- OPTIONS (ADD sslkey 'value', ADD sslcert 'value'); +--Testcase 30: +ALTER FOREIGN TABLE ft1 OPTIONS (table 'T1', tags 'c3'); +--Testcase 31: +ALTER FOREIGN TABLE ft2 OPTIONS (table 'T1', tags 'c3'); +--Testcase 32: +ALTER FOREIGN TABLE ft1 ALTER COLUMN c1 OPTIONS (column_name 'C 1'); +--Testcase 33: +ALTER FOREIGN TABLE ft2 ALTER COLUMN c1 OPTIONS (column_name 'C 1'); +--Testcase 34: +\det+ + List of foreign tables + Schema | Table | Server | FDW options | Description +--------+-------+---------------+---------------------------+------------- + public | ft1 | influxdb_svr | ("table" 'T1', tags 'c3') | + public | ft2 | influxdb_svr | ("table" 'T1', tags 'c3') | + public | ft4 | influxdb_svr | ("table" 'T3', tags 'c3') | + public | ft5 | influxdb_svr | ("table" 'T4', tags 'c3') | + public | ft6 | influxdb_svr2 | ("table" 'T4', tags 'c3') | +(5 rows) + +-- Test that alteration of server options causes reconnection +-- Remote's errors might be non-English, so hide them to ensure stable results +\set VERBOSITY terse +--Testcase 35: +SELECT c3, time FROM ft1 ORDER BY c3, c1 LIMIT 1; -- should work + c3 | time +-------+------------------------------ + 00001 | Fri Jan 02 00:00:00 1970 PST +(1 row) + +--Testcase 36: +ALTER SERVER influxdb_svr OPTIONS (SET dbname 'no such database'); +--Testcase 37: +SELECT c3, time FROM ft1 ORDER BY c3, c1 LIMIT 1; -- should fail +ERROR: influxdb_fdw : database not found: no such database +DO $d$ + BEGIN + EXECUTE $$ALTER SERVER influxdb_svr + OPTIONS (SET dbname 'postdb')$$; + END; +$d$; +--Testcase 38: +SELECT c3, time FROM ft1 ORDER BY c3, c1 LIMIT 1; -- should work again + c3 | time +-------+------------------------------ + 00001 | Fri Jan 02 00:00:00 1970 PST +(1 row) + +\set VERBOSITY default +-- =================================================================== +-- test error case for create publication on foreign table +-- =================================================================== +--Testcase 765: +CREATE PUBLICATION testpub_ftbl FOR TABLE ft1; -- should fail +ERROR: cannot add relation "ft1" to publication +DETAIL: This operation is not supported for foreign tables. +-- =================================================================== +-- simple queries +-- =================================================================== +-- single table without alias +--Testcase 39: +EXPLAIN (COSTS OFF) SELECT * FROM ft1 ORDER BY c3, c1 OFFSET 100 LIMIT 10; + QUERY PLAN +--------------------------------- + Limit + -> Sort + Sort Key: c3, c1 + -> Foreign Scan on ft1 +(4 rows) + +--Testcase 40: +SELECT * FROM ft1 ORDER BY c3, c1 OFFSET 100 LIMIT 10; + c1 | c2 | c3 | time | c6 | c7 | c8 +-----+----+-------+------------------------------+----+------------+----- + 101 | 1 | 00101 | Fri Jan 02 00:00:00 1970 PST | 1 | 1 | foo + 102 | 2 | 00102 | Sat Jan 03 00:00:00 1970 PST | 2 | 2 | foo + 103 | 3 | 00103 | Sun Jan 04 00:00:00 1970 PST | 3 | 3 | foo + 104 | 4 | 00104 | Mon Jan 05 00:00:00 1970 PST | 4 | 4 | foo + 105 | 5 | 00105 | Tue Jan 06 00:00:00 1970 PST | 5 | 5 | foo + 106 | 6 | 00106 | Wed Jan 07 00:00:00 1970 PST | 6 | 6 | foo + 107 | 7 | 00107 | Thu Jan 08 00:00:00 1970 PST | 7 | 7 | foo + 108 | 8 | 00108 | Fri Jan 09 00:00:00 1970 PST | 8 | 8 | foo + 109 | 9 | 00109 | Sat Jan 10 00:00:00 1970 PST | 9 | 9 | foo + 110 | 0 | 00110 | Sun Jan 11 00:00:00 1970 PST | 0 | 0 | foo +(10 rows) + +-- single table with alias - also test that tableoid sort is not pushed to remote side +--Testcase 41: +EXPLAIN (VERBOSE, COSTS OFF) SELECT * FROM ft1 t1 ORDER BY t1.c3, t1.c1, t1.tableoid OFFSET 100 LIMIT 10; + QUERY PLAN +------------------------------------------------------------------------------------ + Limit + Output: c1, c2, c3, "time", c6, c7, c8, tableoid + -> Sort + Output: c1, c2, c3, "time", c6, c7, c8, tableoid + Sort Key: t1.c3, t1.c1, t1.tableoid + -> Foreign Scan on public.ft1 t1 + Output: c1, c2, c3, "time", c6, c7, c8, tableoid + InfluxDB query: SELECT "C 1", "c2", "c3", "c6", "c7", "c8" FROM "T1" +(8 rows) + +--Testcase 42: +SELECT * FROM ft1 t1 ORDER BY t1.c3, t1.c1, t1.tableoid OFFSET 100 LIMIT 10; + c1 | c2 | c3 | time | c6 | c7 | c8 +-----+----+-------+------------------------------+----+------------+----- + 101 | 1 | 00101 | Fri Jan 02 00:00:00 1970 PST | 1 | 1 | foo + 102 | 2 | 00102 | Sat Jan 03 00:00:00 1970 PST | 2 | 2 | foo + 103 | 3 | 00103 | Sun Jan 04 00:00:00 1970 PST | 3 | 3 | foo + 104 | 4 | 00104 | Mon Jan 05 00:00:00 1970 PST | 4 | 4 | foo + 105 | 5 | 00105 | Tue Jan 06 00:00:00 1970 PST | 5 | 5 | foo + 106 | 6 | 00106 | Wed Jan 07 00:00:00 1970 PST | 6 | 6 | foo + 107 | 7 | 00107 | Thu Jan 08 00:00:00 1970 PST | 7 | 7 | foo + 108 | 8 | 00108 | Fri Jan 09 00:00:00 1970 PST | 8 | 8 | foo + 109 | 9 | 00109 | Sat Jan 10 00:00:00 1970 PST | 9 | 9 | foo + 110 | 0 | 00110 | Sun Jan 11 00:00:00 1970 PST | 0 | 0 | foo +(10 rows) + +-- whole-row reference +--Testcase 43: +EXPLAIN (VERBOSE, COSTS OFF) SELECT t1 FROM ft1 t1 ORDER BY t1.c3, t1.c1 OFFSET 100 LIMIT 10; + QUERY PLAN +------------------------------------------------------------------------------------ + Limit + Output: t1.*, c3, c1 + -> Sort + Output: t1.*, c3, c1 + Sort Key: t1.c3, t1.c1 + -> Foreign Scan on public.ft1 t1 + Output: t1.*, c3, c1 + InfluxDB query: SELECT "C 1", "c2", "c3", "c6", "c7", "c8" FROM "T1" +(8 rows) + +--Testcase 44: +SELECT t1 FROM ft1 t1 ORDER BY t1.c3, t1.c1 OFFSET 100 LIMIT 10; + t1 +----------------------------------------------------------------- + (101,1,00101,"Fri Jan 02 00:00:00 1970 PST",1,"1 ",foo) + (102,2,00102,"Sat Jan 03 00:00:00 1970 PST",2,"2 ",foo) + (103,3,00103,"Sun Jan 04 00:00:00 1970 PST",3,"3 ",foo) + (104,4,00104,"Mon Jan 05 00:00:00 1970 PST",4,"4 ",foo) + (105,5,00105,"Tue Jan 06 00:00:00 1970 PST",5,"5 ",foo) + (106,6,00106,"Wed Jan 07 00:00:00 1970 PST",6,"6 ",foo) + (107,7,00107,"Thu Jan 08 00:00:00 1970 PST",7,"7 ",foo) + (108,8,00108,"Fri Jan 09 00:00:00 1970 PST",8,"8 ",foo) + (109,9,00109,"Sat Jan 10 00:00:00 1970 PST",9,"9 ",foo) + (110,0,00110,"Sun Jan 11 00:00:00 1970 PST",0,"0 ",foo) +(10 rows) + +-- empty result +--Testcase 45: +SELECT * FROM ft1 WHERE false; + c1 | c2 | c3 | time | c6 | c7 | c8 +----+----+----+------+----+----+---- +(0 rows) + +-- with WHERE clause +--Testcase 46: +EXPLAIN (VERBOSE, COSTS OFF) SELECT * FROM ft1 t1 WHERE t1.c1 = 101 AND t1.c6 = '1' AND t1.c7 >= '1'; + QUERY PLAN +----------------------------------------------------------------------------------------------------------------- + Foreign Scan on public.ft1 t1 + Output: c1, c2, c3, "time", c6, c7, c8 + Filter: (t1.c7 >= '1'::bpchar) + InfluxDB query: SELECT "C 1", "c2", "c3", "c6", "c7", "c8" FROM "T1" WHERE (("C 1" = 101)) AND (("c6" = '1')) +(4 rows) + +--Testcase 47: +SELECT * FROM ft1 t1 WHERE t1.c1 = 101 AND t1.c6 = '1' AND t1.c7 >= '1'; + c1 | c2 | c3 | time | c6 | c7 | c8 +-----+----+-------+------------------------------+----+------------+----- + 101 | 1 | 00101 | Fri Jan 02 00:00:00 1970 PST | 1 | 1 | foo +(1 row) + +-- with FOR UPDATE/SHARE +--Testcase 48: +EXPLAIN (VERBOSE, COSTS OFF) SELECT * FROM ft1 t1 WHERE c1 = 101 FOR UPDATE; + QUERY PLAN +---------------------------------------------------------------------------------------------------- + LockRows + Output: c1, c2, c3, "time", c6, c7, c8, t1.* + -> Foreign Scan on public.ft1 t1 + Output: c1, c2, c3, "time", c6, c7, c8, t1.* + InfluxDB query: SELECT "C 1", "c2", "c3", "c6", "c7", "c8" FROM "T1" WHERE (("C 1" = 101)) +(5 rows) + +--Testcase 49: +SELECT * FROM ft1 t1 WHERE c1 = 101 FOR UPDATE; + c1 | c2 | c3 | time | c6 | c7 | c8 +-----+----+-------+------------------------------+----+------------+----- + 101 | 1 | 00101 | Fri Jan 02 00:00:00 1970 PST | 1 | 1 | foo +(1 row) + +--Testcase 50: +EXPLAIN (VERBOSE, COSTS OFF) SELECT * FROM ft1 t1 WHERE c1 = 102 FOR SHARE; + QUERY PLAN +---------------------------------------------------------------------------------------------------- + LockRows + Output: c1, c2, c3, "time", c6, c7, c8, t1.* + -> Foreign Scan on public.ft1 t1 + Output: c1, c2, c3, "time", c6, c7, c8, t1.* + InfluxDB query: SELECT "C 1", "c2", "c3", "c6", "c7", "c8" FROM "T1" WHERE (("C 1" = 102)) +(5 rows) + +--Testcase 51: +SELECT * FROM ft1 t1 WHERE c1 = 102 FOR SHARE; + c1 | c2 | c3 | time | c6 | c7 | c8 +-----+----+-------+------------------------------+----+------------+----- + 102 | 2 | 00102 | Sat Jan 03 00:00:00 1970 PST | 2 | 2 | foo +(1 row) + +-- aggregate +--Testcase 52: +SELECT COUNT(*) FROM ft1 t1; + count +------- + 1000 +(1 row) + +-- subquery +--Testcase 53: +SELECT * FROM ft1 t1 WHERE t1.c3 IN (SELECT c3 FROM ft2 t2 WHERE c1 <= 10) ORDER BY c1; + c1 | c2 | c3 | time | c6 | c7 | c8 +----+----+-------+------------------------------+----+------------+----- + 1 | 1 | 00001 | Fri Jan 02 00:00:00 1970 PST | 1 | 1 | foo + 2 | 2 | 00002 | Sat Jan 03 00:00:00 1970 PST | 2 | 2 | foo + 3 | 3 | 00003 | Sun Jan 04 00:00:00 1970 PST | 3 | 3 | foo + 4 | 4 | 00004 | Mon Jan 05 00:00:00 1970 PST | 4 | 4 | foo + 5 | 5 | 00005 | Tue Jan 06 00:00:00 1970 PST | 5 | 5 | foo + 6 | 6 | 00006 | Wed Jan 07 00:00:00 1970 PST | 6 | 6 | foo + 7 | 7 | 00007 | Thu Jan 08 00:00:00 1970 PST | 7 | 7 | foo + 8 | 8 | 00008 | Fri Jan 09 00:00:00 1970 PST | 8 | 8 | foo + 9 | 9 | 00009 | Sat Jan 10 00:00:00 1970 PST | 9 | 9 | foo + 10 | 0 | 00010 | Sun Jan 11 00:00:00 1970 PST | 0 | 0 | foo +(10 rows) + +-- subquery+MAX +--Testcase 54: +SELECT * FROM ft1 t1 WHERE t1.c3 = (SELECT MAX(c3) FROM ft2 t2) ORDER BY c1; + c1 | c2 | c3 | time | c6 | c7 | c8 +------+----+-------+------------------------------+----+------------+----- + 1000 | 0 | 01000 | Thu Jan 01 00:00:00 1970 PST | 0 | 0 | foo +(1 row) + +-- used in CTE +--Testcase 55: +WITH t1 AS (SELECT * FROM ft1 WHERE c1 <= 10) SELECT t2.c1, t2.c2, t2.c3, t2.time FROM t1, ft2 t2 WHERE t1.c1 = t2.c1 ORDER BY t1.c1; + c1 | c2 | c3 | time +----+----+-------+------------------------------ + 1 | 1 | 00001 | Fri Jan 02 00:00:00 1970 PST + 2 | 2 | 00002 | Sat Jan 03 00:00:00 1970 PST + 3 | 3 | 00003 | Sun Jan 04 00:00:00 1970 PST + 4 | 4 | 00004 | Mon Jan 05 00:00:00 1970 PST + 5 | 5 | 00005 | Tue Jan 06 00:00:00 1970 PST + 6 | 6 | 00006 | Wed Jan 07 00:00:00 1970 PST + 7 | 7 | 00007 | Thu Jan 08 00:00:00 1970 PST + 8 | 8 | 00008 | Fri Jan 09 00:00:00 1970 PST + 9 | 9 | 00009 | Sat Jan 10 00:00:00 1970 PST + 10 | 0 | 00010 | Sun Jan 11 00:00:00 1970 PST +(10 rows) + +-- fixed values +--Testcase 56: +SELECT 'fixed', NULL FROM ft1 t1 WHERE c1 = 1; + ?column? | ?column? +----------+---------- + fixed | +(1 row) + +-- Test forcing the remote server to produce sorted data for a merge join. +--Testcase 57: +SET enable_hashjoin TO false; +--Testcase 58: +SET enable_nestloop TO false; +-- inner join; expressions in the clauses appear in the equivalence class list +--Testcase 59: +EXPLAIN (VERBOSE, COSTS OFF) + SELECT t1.c1, t2."C 1" FROM ft2 t1 JOIN "S 1"."T 1" t2 ON (t1.c1 = t2."C 1") OFFSET 100 LIMIT 10; + QUERY PLAN +------------------------------------------------------------ + Limit + Output: t1.c1, t2."C 1" + -> Merge Join + Output: t1.c1, t2."C 1" + Merge Cond: (t1.c1 = t2."C 1") + -> Sort + Output: t1.c1 + Sort Key: t1.c1 + -> Foreign Scan on public.ft2 t1 + Output: t1.c1 + InfluxDB query: SELECT "C 1" FROM "T1" + -> Sort + Output: t2."C 1" + Sort Key: t2."C 1" + -> Foreign Scan on "S 1"."T 1" t2 + Output: t2."C 1" + InfluxDB query: SELECT "C 1" FROM "T1" +(17 rows) + +--Testcase 60: +SELECT t1.c1, t2."C 1" FROM ft2 t1 JOIN "S 1"."T 1" t2 ON (t1.c1 = t2."C 1") OFFSET 100 LIMIT 10; + c1 | C 1 +-----+----- + 101 | 101 + 102 | 102 + 103 | 103 + 104 | 104 + 105 | 105 + 106 | 106 + 107 | 107 + 108 | 108 + 109 | 109 + 110 | 110 +(10 rows) + +-- outer join; expressions in the clauses do not appear in equivalence class +-- list but no output change as compared to the previous query +--Testcase 61: +EXPLAIN (VERBOSE, COSTS OFF) + SELECT t1.c1, t2."C 1" FROM ft2 t1 LEFT JOIN "S 1"."T 1" t2 ON (t1.c1 = t2."C 1") OFFSET 100 LIMIT 10; + QUERY PLAN +------------------------------------------------------------ + Limit + Output: t1.c1, t2."C 1" + -> Merge Left Join + Output: t1.c1, t2."C 1" + Merge Cond: (t1.c1 = t2."C 1") + -> Sort + Output: t1.c1 + Sort Key: t1.c1 + -> Foreign Scan on public.ft2 t1 + Output: t1.c1 + InfluxDB query: SELECT "C 1" FROM "T1" + -> Sort + Output: t2."C 1" + Sort Key: t2."C 1" + -> Foreign Scan on "S 1"."T 1" t2 + Output: t2."C 1" + InfluxDB query: SELECT "C 1" FROM "T1" +(17 rows) + +--Testcase 62: +SELECT t1.c1, t2."C 1" FROM ft2 t1 LEFT JOIN "S 1"."T 1" t2 ON (t1.c1 = t2."C 1") OFFSET 100 LIMIT 10; + c1 | C 1 +-----+----- + 101 | 101 + 102 | 102 + 103 | 103 + 104 | 104 + 105 | 105 + 106 | 106 + 107 | 107 + 108 | 108 + 109 | 109 + 110 | 110 +(10 rows) + +-- A join between 2 foreign tables. ORDER BY clause is added to the +-- foreign join so that the other table can be joined using merge join strategy. +--Testcase 63: +EXPLAIN (VERBOSE, COSTS OFF) + SELECT t1."C 1" FROM "S 1"."T 1" t1 left join ft1 t2 join ft2 t3 on (t2.c1 = t3.c1) on (t3.c1 = t1."C 1") OFFSET 100 LIMIT 10; + QUERY PLAN +------------------------------------------------------------------------ + Limit + Output: t1."C 1" + -> Merge Left Join + Output: t1."C 1" + Merge Cond: (t1."C 1" = t3.c1) + -> Sort + Output: t1."C 1" + Sort Key: t1."C 1" + -> Foreign Scan on "S 1"."T 1" t1 + Output: t1."C 1" + InfluxDB query: SELECT "C 1" FROM "T1" + -> Materialize + Output: t3.c1 + -> Merge Join + Output: t3.c1 + Merge Cond: (t2.c1 = t3.c1) + -> Sort + Output: t2.c1 + Sort Key: t2.c1 + -> Foreign Scan on public.ft1 t2 + Output: t2.c1 + InfluxDB query: SELECT "C 1" FROM "T1" + -> Sort + Output: t3.c1 + Sort Key: t3.c1 + -> Foreign Scan on public.ft2 t3 + Output: t3.c1 + InfluxDB query: SELECT "C 1" FROM "T1" +(28 rows) + +--Testcase 64: +SELECT t1."C 1" FROM "S 1"."T 1" t1 left join ft1 t2 join ft2 t3 on (t2.c1 = t3.c1) on (t3.c1 = t1."C 1") OFFSET 100 LIMIT 10; + C 1 +----- + 101 + 102 + 103 + 104 + 105 + 106 + 107 + 108 + 109 + 110 +(10 rows) + +-- Test similar to above, except that the full join prevents any equivalence +-- classes from being merged. This produces single relation equivalence classes +-- included in join restrictions. +--Testcase 65: +EXPLAIN (VERBOSE, COSTS OFF) + SELECT t1."C 1", t2.c1, t3.c1 FROM "S 1"."T 1" t1 left join ft1 t2 full join ft2 t3 on (t2.c1 = t3.c1) on (t3.c1 = t1."C 1") OFFSET 100 LIMIT 10; + QUERY PLAN +------------------------------------------------------------------------ + Limit + Output: t1."C 1", t2.c1, t3.c1 + -> Merge Left Join + Output: t1."C 1", t2.c1, t3.c1 + Merge Cond: (t1."C 1" = t3.c1) + -> Sort + Output: t1."C 1" + Sort Key: t1."C 1" + -> Foreign Scan on "S 1"."T 1" t1 + Output: t1."C 1" + InfluxDB query: SELECT "C 1" FROM "T1" + -> Materialize + Output: t3.c1, t2.c1 + -> Merge Left Join + Output: t3.c1, t2.c1 + Merge Cond: (t3.c1 = t2.c1) + -> Sort + Output: t3.c1 + Sort Key: t3.c1 + -> Foreign Scan on public.ft2 t3 + Output: t3.c1 + InfluxDB query: SELECT "C 1" FROM "T1" + -> Sort + Output: t2.c1 + Sort Key: t2.c1 + -> Foreign Scan on public.ft1 t2 + Output: t2.c1 + InfluxDB query: SELECT "C 1" FROM "T1" +(28 rows) + +--Testcase 66: +SELECT t1."C 1", t2.c1, t3.c1 FROM "S 1"."T 1" t1 left join ft1 t2 full join ft2 t3 on (t2.c1 = t3.c1) on (t3.c1 = t1."C 1") OFFSET 100 LIMIT 10; + C 1 | c1 | c1 +-----+-----+----- + 101 | 101 | 101 + 102 | 102 | 102 + 103 | 103 | 103 + 104 | 104 | 104 + 105 | 105 | 105 + 106 | 106 | 106 + 107 | 107 | 107 + 108 | 108 | 108 + 109 | 109 | 109 + 110 | 110 | 110 +(10 rows) + +-- Test similar to above with all full outer joins +--Testcase 67: +EXPLAIN (VERBOSE, COSTS OFF) + SELECT t1."C 1", t2.c1, t3.c1 FROM "S 1"."T 1" t1 full join ft1 t2 full join ft2 t3 on (t2.c1 = t3.c1) on (t3.c1 = t1."C 1") OFFSET 100 LIMIT 10; + QUERY PLAN +------------------------------------------------------------------------ + Limit + Output: t1."C 1", t2.c1, t3.c1 + -> Merge Full Join + Output: t1."C 1", t2.c1, t3.c1 + Merge Cond: (t1."C 1" = t3.c1) + -> Sort + Output: t1."C 1" + Sort Key: t1."C 1" + -> Foreign Scan on "S 1"."T 1" t1 + Output: t1."C 1" + InfluxDB query: SELECT "C 1" FROM "T1" + -> Sort + Output: t2.c1, t3.c1 + Sort Key: t3.c1 + -> Merge Full Join + Output: t2.c1, t3.c1 + Merge Cond: (t2.c1 = t3.c1) + -> Sort + Output: t2.c1 + Sort Key: t2.c1 + -> Foreign Scan on public.ft1 t2 + Output: t2.c1 + InfluxDB query: SELECT "C 1" FROM "T1" + -> Sort + Output: t3.c1 + Sort Key: t3.c1 + -> Foreign Scan on public.ft2 t3 + Output: t3.c1 + InfluxDB query: SELECT "C 1" FROM "T1" +(29 rows) + +--Testcase 68: +SELECT t1."C 1", t2.c1, t3.c1 FROM "S 1"."T 1" t1 full join ft1 t2 full join ft2 t3 on (t2.c1 = t3.c1) on (t3.c1 = t1."C 1") OFFSET 100 LIMIT 10; + C 1 | c1 | c1 +-----+-----+----- + 101 | 101 | 101 + 102 | 102 | 102 + 103 | 103 | 103 + 104 | 104 | 104 + 105 | 105 | 105 + 106 | 106 | 106 + 107 | 107 | 107 + 108 | 108 | 108 + 109 | 109 | 109 + 110 | 110 | 110 +(10 rows) + +--Testcase 69: +RESET enable_hashjoin; +--Testcase 70: +RESET enable_nestloop; +-- Test executing assertion in estimate_path_cost_size() that makes sure that +-- retrieved_rows for foreign rel re-used to cost pre-sorted foreign paths is +-- a sensible value even when the rel has tuples=0 +--Testcase 71: +CREATE FOREIGN TABLE loct_empty (c1 int NOT NULL, c2 text) SERVER influxdb_svr; +--Testcase 72: +CREATE FOREIGN TABLE ft_empty (c1 int NOT NULL, c2 text) + SERVER influxdb_svr OPTIONS (table 'loct_empty'); +--Testcase 73: +INSERT INTO loct_empty + SELECT id, 'AAA' || to_char(id, 'FM000') FROM generate_series(1, 100) id; +--Testcase 74: +DELETE FROM loct_empty; +--ANALYZE ft_empty; +--Testcase 75: +EXPLAIN (VERBOSE, COSTS OFF) SELECT * FROM ft_empty ORDER BY c1; + QUERY PLAN +------------------------------------------------------------- + Sort + Output: c1, c2 + Sort Key: ft_empty.c1 + -> Foreign Scan on public.ft_empty + Output: c1, c2 + InfluxDB query: SELECT "c1", "c2" FROM "loct_empty" +(6 rows) + +-- =================================================================== +-- WHERE with remotely-executable conditions +-- =================================================================== +--Testcase 76: +EXPLAIN (VERBOSE, COSTS OFF) SELECT * FROM ft1 t1 WHERE t1.c1 = 1; -- Var, OpExpr(b), Const + QUERY PLAN +-------------------------------------------------------------------------------------------- + Foreign Scan on public.ft1 t1 + Output: c1, c2, c3, "time", c6, c7, c8 + InfluxDB query: SELECT "C 1", "c2", "c3", "c6", "c7", "c8" FROM "T1" WHERE (("C 1" = 1)) +(3 rows) + +--Testcase 77: +EXPLAIN (VERBOSE, COSTS OFF) SELECT * FROM ft1 t1 WHERE t1.c1 = 100 AND t1.c2 = 0; -- BoolExpr + QUERY PLAN +--------------------------------------------------------------------------------------------------------------- + Foreign Scan on public.ft1 t1 + Output: c1, c2, c3, "time", c6, c7, c8 + InfluxDB query: SELECT "C 1", "c2", "c3", "c6", "c7", "c8" FROM "T1" WHERE (("C 1" = 100)) AND (("c2" = 0)) +(3 rows) + +--Testcase 78: +EXPLAIN (VERBOSE, COSTS OFF) SELECT * FROM ft1 t1 WHERE c1 IS NULL; -- NullTest + QUERY PLAN +------------------------------------------------------------------------ + Foreign Scan on public.ft1 t1 + Output: c1, c2, c3, "time", c6, c7, c8 + Filter: (t1.c1 IS NULL) + InfluxDB query: SELECT "C 1", "c2", "c3", "c6", "c7", "c8" FROM "T1" +(4 rows) + +--Testcase 79: +EXPLAIN (VERBOSE, COSTS OFF) SELECT * FROM ft1 t1 WHERE c1 IS NOT NULL; -- NullTest + QUERY PLAN +------------------------------------------------------------------------ + Foreign Scan on public.ft1 t1 + Output: c1, c2, c3, "time", c6, c7, c8 + Filter: (t1.c1 IS NOT NULL) + InfluxDB query: SELECT "C 1", "c2", "c3", "c6", "c7", "c8" FROM "T1" +(4 rows) + +--Testcase 80: +EXPLAIN (VERBOSE, COSTS OFF) SELECT * FROM ft1 t1 WHERE round(abs(c1), 0) = 1; -- FuncExpr + QUERY PLAN +------------------------------------------------------------------------ + Foreign Scan on public.ft1 t1 + Output: c1, c2, c3, "time", c6, c7, c8 + Filter: (round((abs(t1.c1))::numeric, 0) = '1'::numeric) + InfluxDB query: SELECT "C 1", "c2", "c3", "c6", "c7", "c8" FROM "T1" +(4 rows) + +--Testcase 81: +EXPLAIN (VERBOSE, COSTS OFF) SELECT * FROM ft1 t1 WHERE c1 = -c1; -- OpExpr(l) + QUERY PLAN +---------------------------------------------------------------------------------------------------- + Foreign Scan on public.ft1 t1 + Output: c1, c2, c3, "time", c6, c7, c8 + InfluxDB query: SELECT "C 1", "c2", "c3", "c6", "c7", "c8" FROM "T1" WHERE (("C 1" = (- "C 1"))) +(3 rows) + +--Testcase 82: +EXPLAIN (VERBOSE, COSTS OFF) SELECT * FROM ft1 t1 WHERE (c1 IS NOT NULL) IS DISTINCT FROM (c1 IS NOT NULL); -- DistinctExpr + QUERY PLAN +------------------------------------------------------------------------ + Foreign Scan on public.ft1 t1 + Output: c1, c2, c3, "time", c6, c7, c8 + Filter: ((t1.c1 IS NOT NULL) IS DISTINCT FROM (t1.c1 IS NOT NULL)) + InfluxDB query: SELECT "C 1", "c2", "c3", "c6", "c7", "c8" FROM "T1" +(4 rows) + +--Testcase 83: +EXPLAIN (VERBOSE, COSTS OFF) SELECT * FROM ft1 t1 WHERE c1 = ANY(ARRAY[c2, 1, c1 + 0]); -- ScalarArrayOpExpr + QUERY PLAN +--------------------------------------------------------------------------------------------------------------------------------------- + Foreign Scan on public.ft1 t1 + Output: c1, c2, c3, "time", c6, c7, c8 + InfluxDB query: SELECT "C 1", "c2", "c3", "c6", "c7", "c8" FROM "T1" WHERE (("C 1" = "c2") OR ("C 1" = 1) OR ("C 1" = ("C 1" + 0))) +(3 rows) + +--Testcase 84: +EXPLAIN (VERBOSE, COSTS OFF) SELECT * FROM ft1 t1 WHERE c1 = (ARRAY[c1,c2,3])[1]; -- SubscriptingRef + QUERY PLAN +------------------------------------------------------------------------ + Foreign Scan on public.ft1 t1 + Output: c1, c2, c3, "time", c6, c7, c8 + Filter: (t1.c1 = (ARRAY[t1.c1, t1.c2, 3])[1]) + InfluxDB query: SELECT "C 1", "c2", "c3", "c6", "c7", "c8" FROM "T1" +(4 rows) + +--Testcase 85: +EXPLAIN (VERBOSE, COSTS OFF) SELECT * FROM ft1 t1 WHERE c6 = E'foo''s\\bar'; -- check special chars + QUERY PLAN +------------------------------------------------------------------------------------------------------- + Foreign Scan on public.ft1 t1 + Output: c1, c2, c3, "time", c6, c7, c8 + InfluxDB query: SELECT "C 1", "c2", "c3", "c6", "c7", "c8" FROM "T1" WHERE (("c6" = 'foo''s\\bar')) +(3 rows) + +--Testcase 86: +EXPLAIN (VERBOSE, COSTS OFF) SELECT * FROM ft1 t1 WHERE c8 = 'foo'; -- can't be sent to remote + QUERY PLAN +----------------------------------------------------------------------------------------------- + Foreign Scan on public.ft1 t1 + Output: c1, c2, c3, "time", c6, c7, c8 + InfluxDB query: SELECT "C 1", "c2", "c3", "c6", "c7", "c8" FROM "T1" WHERE (("c8" = 'foo')) +(3 rows) + +-- parameterized remote path for foreign table +--Testcase 87: +EXPLAIN (VERBOSE, COSTS OFF) + SELECT * FROM "S 1"."T 1" a, ft2 b WHERE a."C 1" = 47 AND b.c1 = a.c2; + QUERY PLAN +--------------------------------------------------------------------------------------------------------- + Hash Join + Output: a."C 1", a.c2, a.c3, a."time", a.c6, a.c7, a.c8, b.c1, b.c2, b.c3, b."time", b.c6, b.c7, b.c8 + Hash Cond: (b.c1 = a.c2) + -> Foreign Scan on public.ft2 b + Output: b.c1, b.c2, b.c3, b."time", b.c6, b.c7, b.c8 + InfluxDB query: SELECT "C 1", "c2", "c3", "c6", "c7", "c8" FROM "T1" + -> Hash + Output: a."C 1", a.c2, a.c3, a."time", a.c6, a.c7, a.c8 + -> Foreign Scan on "S 1"."T 1" a + Output: a."C 1", a.c2, a.c3, a."time", a.c6, a.c7, a.c8 + InfluxDB query: SELECT "C 1", "c2", "c3", "c6", "c7", "c8" FROM "T1" WHERE (("C 1" = 47)) +(11 rows) + +--Testcase 88: +SELECT * FROM "S 1"."T 1" a, ft2 b WHERE a."C 1" = 47 AND b.c1 = a.c2; + C 1 | c2 | c3 | time | c6 | c7 | c8 | c1 | c2 | c3 | time | c6 | c7 | c8 +-----+----+-------+------------------------------+----+------------+-----+----+----+-------+------------------------------+----+------------+----- + 47 | 7 | 00047 | Tue Feb 17 00:00:00 1970 PST | 7 | 7 | foo | 7 | 7 | 00007 | Thu Jan 08 00:00:00 1970 PST | 7 | 7 | foo +(1 row) + +-- check both safe and unsafe join conditions +--Testcase 89: +EXPLAIN (VERBOSE, COSTS OFF) + SELECT * FROM ft2 a, ft2 b + WHERE a.c2 = 6 AND b.c1 = a.c1 AND a.c8 = 'foo' AND b.c7 = upper(a.c7); + QUERY PLAN +---------------------------------------------------------------------------------------------------------------------------- + Hash Join + Output: a.c1, a.c2, a.c3, a."time", a.c6, a.c7, a.c8, b.c1, b.c2, b.c3, b."time", b.c6, b.c7, b.c8 + Hash Cond: ((b.c1 = a.c1) AND ((b.c7)::text = upper((a.c7)::text))) + -> Foreign Scan on public.ft2 b + Output: b.c1, b.c2, b.c3, b."time", b.c6, b.c7, b.c8 + InfluxDB query: SELECT "C 1", "c2", "c3", "c6", "c7", "c8" FROM "T1" + -> Hash + Output: a.c1, a.c2, a.c3, a."time", a.c6, a.c7, a.c8 + -> Foreign Scan on public.ft2 a + Output: a.c1, a.c2, a.c3, a."time", a.c6, a.c7, a.c8 + InfluxDB query: SELECT "C 1", "c2", "c3", "c6", "c7", "c8" FROM "T1" WHERE (("c2" = 6)) AND (("c8" = 'foo')) +(11 rows) + +--Testcase 90: +SELECT * FROM ft2 a, ft2 b +WHERE a.c2 = 6 AND b.c1 = a.c1 AND a.c8 = 'foo' AND b.c7 = upper(a.c7) ORDER BY a.c1; + c1 | c2 | c3 | time | c6 | c7 | c8 | c1 | c2 | c3 | time | c6 | c7 | c8 +-----+----+-------+------------------------------+----+------------+-----+-----+----+-------+------------------------------+----+------------+----- + 6 | 6 | 00006 | Wed Jan 07 00:00:00 1970 PST | 6 | 6 | foo | 6 | 6 | 00006 | Wed Jan 07 00:00:00 1970 PST | 6 | 6 | foo + 16 | 6 | 00016 | Sat Jan 17 00:00:00 1970 PST | 6 | 6 | foo | 16 | 6 | 00016 | Sat Jan 17 00:00:00 1970 PST | 6 | 6 | foo + 26 | 6 | 00026 | Tue Jan 27 00:00:00 1970 PST | 6 | 6 | foo | 26 | 6 | 00026 | Tue Jan 27 00:00:00 1970 PST | 6 | 6 | foo + 36 | 6 | 00036 | Fri Feb 06 00:00:00 1970 PST | 6 | 6 | foo | 36 | 6 | 00036 | Fri Feb 06 00:00:00 1970 PST | 6 | 6 | foo + 46 | 6 | 00046 | Mon Feb 16 00:00:00 1970 PST | 6 | 6 | foo | 46 | 6 | 00046 | Mon Feb 16 00:00:00 1970 PST | 6 | 6 | foo + 56 | 6 | 00056 | Thu Feb 26 00:00:00 1970 PST | 6 | 6 | foo | 56 | 6 | 00056 | Thu Feb 26 00:00:00 1970 PST | 6 | 6 | foo + 66 | 6 | 00066 | Sun Mar 08 00:00:00 1970 PST | 6 | 6 | foo | 66 | 6 | 00066 | Sun Mar 08 00:00:00 1970 PST | 6 | 6 | foo + 76 | 6 | 00076 | Wed Mar 18 00:00:00 1970 PST | 6 | 6 | foo | 76 | 6 | 00076 | Wed Mar 18 00:00:00 1970 PST | 6 | 6 | foo + 86 | 6 | 00086 | Sat Mar 28 00:00:00 1970 PST | 6 | 6 | foo | 86 | 6 | 00086 | Sat Mar 28 00:00:00 1970 PST | 6 | 6 | foo + 96 | 6 | 00096 | Tue Apr 07 00:00:00 1970 PST | 6 | 6 | foo | 96 | 6 | 00096 | Tue Apr 07 00:00:00 1970 PST | 6 | 6 | foo + 106 | 6 | 00106 | Wed Jan 07 00:00:00 1970 PST | 6 | 6 | foo | 106 | 6 | 00106 | Wed Jan 07 00:00:00 1970 PST | 6 | 6 | foo + 116 | 6 | 00116 | Sat Jan 17 00:00:00 1970 PST | 6 | 6 | foo | 116 | 6 | 00116 | Sat Jan 17 00:00:00 1970 PST | 6 | 6 | foo + 126 | 6 | 00126 | Tue Jan 27 00:00:00 1970 PST | 6 | 6 | foo | 126 | 6 | 00126 | Tue Jan 27 00:00:00 1970 PST | 6 | 6 | foo + 136 | 6 | 00136 | Fri Feb 06 00:00:00 1970 PST | 6 | 6 | foo | 136 | 6 | 00136 | Fri Feb 06 00:00:00 1970 PST | 6 | 6 | foo + 146 | 6 | 00146 | Mon Feb 16 00:00:00 1970 PST | 6 | 6 | foo | 146 | 6 | 00146 | Mon Feb 16 00:00:00 1970 PST | 6 | 6 | foo + 156 | 6 | 00156 | Thu Feb 26 00:00:00 1970 PST | 6 | 6 | foo | 156 | 6 | 00156 | Thu Feb 26 00:00:00 1970 PST | 6 | 6 | foo + 166 | 6 | 00166 | Sun Mar 08 00:00:00 1970 PST | 6 | 6 | foo | 166 | 6 | 00166 | Sun Mar 08 00:00:00 1970 PST | 6 | 6 | foo + 176 | 6 | 00176 | Wed Mar 18 00:00:00 1970 PST | 6 | 6 | foo | 176 | 6 | 00176 | Wed Mar 18 00:00:00 1970 PST | 6 | 6 | foo + 186 | 6 | 00186 | Sat Mar 28 00:00:00 1970 PST | 6 | 6 | foo | 186 | 6 | 00186 | Sat Mar 28 00:00:00 1970 PST | 6 | 6 | foo + 196 | 6 | 00196 | Tue Apr 07 00:00:00 1970 PST | 6 | 6 | foo | 196 | 6 | 00196 | Tue Apr 07 00:00:00 1970 PST | 6 | 6 | foo + 206 | 6 | 00206 | Wed Jan 07 00:00:00 1970 PST | 6 | 6 | foo | 206 | 6 | 00206 | Wed Jan 07 00:00:00 1970 PST | 6 | 6 | foo + 216 | 6 | 00216 | Sat Jan 17 00:00:00 1970 PST | 6 | 6 | foo | 216 | 6 | 00216 | Sat Jan 17 00:00:00 1970 PST | 6 | 6 | foo + 226 | 6 | 00226 | Tue Jan 27 00:00:00 1970 PST | 6 | 6 | foo | 226 | 6 | 00226 | Tue Jan 27 00:00:00 1970 PST | 6 | 6 | foo + 236 | 6 | 00236 | Fri Feb 06 00:00:00 1970 PST | 6 | 6 | foo | 236 | 6 | 00236 | Fri Feb 06 00:00:00 1970 PST | 6 | 6 | foo + 246 | 6 | 00246 | Mon Feb 16 00:00:00 1970 PST | 6 | 6 | foo | 246 | 6 | 00246 | Mon Feb 16 00:00:00 1970 PST | 6 | 6 | foo + 256 | 6 | 00256 | Thu Feb 26 00:00:00 1970 PST | 6 | 6 | foo | 256 | 6 | 00256 | Thu Feb 26 00:00:00 1970 PST | 6 | 6 | foo + 266 | 6 | 00266 | Sun Mar 08 00:00:00 1970 PST | 6 | 6 | foo | 266 | 6 | 00266 | Sun Mar 08 00:00:00 1970 PST | 6 | 6 | foo + 276 | 6 | 00276 | Wed Mar 18 00:00:00 1970 PST | 6 | 6 | foo | 276 | 6 | 00276 | Wed Mar 18 00:00:00 1970 PST | 6 | 6 | foo + 286 | 6 | 00286 | Sat Mar 28 00:00:00 1970 PST | 6 | 6 | foo | 286 | 6 | 00286 | Sat Mar 28 00:00:00 1970 PST | 6 | 6 | foo + 296 | 6 | 00296 | Tue Apr 07 00:00:00 1970 PST | 6 | 6 | foo | 296 | 6 | 00296 | Tue Apr 07 00:00:00 1970 PST | 6 | 6 | foo + 306 | 6 | 00306 | Wed Jan 07 00:00:00 1970 PST | 6 | 6 | foo | 306 | 6 | 00306 | Wed Jan 07 00:00:00 1970 PST | 6 | 6 | foo + 316 | 6 | 00316 | Sat Jan 17 00:00:00 1970 PST | 6 | 6 | foo | 316 | 6 | 00316 | Sat Jan 17 00:00:00 1970 PST | 6 | 6 | foo + 326 | 6 | 00326 | Tue Jan 27 00:00:00 1970 PST | 6 | 6 | foo | 326 | 6 | 00326 | Tue Jan 27 00:00:00 1970 PST | 6 | 6 | foo + 336 | 6 | 00336 | Fri Feb 06 00:00:00 1970 PST | 6 | 6 | foo | 336 | 6 | 00336 | Fri Feb 06 00:00:00 1970 PST | 6 | 6 | foo + 346 | 6 | 00346 | Mon Feb 16 00:00:00 1970 PST | 6 | 6 | foo | 346 | 6 | 00346 | Mon Feb 16 00:00:00 1970 PST | 6 | 6 | foo + 356 | 6 | 00356 | Thu Feb 26 00:00:00 1970 PST | 6 | 6 | foo | 356 | 6 | 00356 | Thu Feb 26 00:00:00 1970 PST | 6 | 6 | foo + 366 | 6 | 00366 | Sun Mar 08 00:00:00 1970 PST | 6 | 6 | foo | 366 | 6 | 00366 | Sun Mar 08 00:00:00 1970 PST | 6 | 6 | foo + 376 | 6 | 00376 | Wed Mar 18 00:00:00 1970 PST | 6 | 6 | foo | 376 | 6 | 00376 | Wed Mar 18 00:00:00 1970 PST | 6 | 6 | foo + 386 | 6 | 00386 | Sat Mar 28 00:00:00 1970 PST | 6 | 6 | foo | 386 | 6 | 00386 | Sat Mar 28 00:00:00 1970 PST | 6 | 6 | foo + 396 | 6 | 00396 | Tue Apr 07 00:00:00 1970 PST | 6 | 6 | foo | 396 | 6 | 00396 | Tue Apr 07 00:00:00 1970 PST | 6 | 6 | foo + 406 | 6 | 00406 | Wed Jan 07 00:00:00 1970 PST | 6 | 6 | foo | 406 | 6 | 00406 | Wed Jan 07 00:00:00 1970 PST | 6 | 6 | foo + 416 | 6 | 00416 | Sat Jan 17 00:00:00 1970 PST | 6 | 6 | foo | 416 | 6 | 00416 | Sat Jan 17 00:00:00 1970 PST | 6 | 6 | foo + 426 | 6 | 00426 | Tue Jan 27 00:00:00 1970 PST | 6 | 6 | foo | 426 | 6 | 00426 | Tue Jan 27 00:00:00 1970 PST | 6 | 6 | foo + 436 | 6 | 00436 | Fri Feb 06 00:00:00 1970 PST | 6 | 6 | foo | 436 | 6 | 00436 | Fri Feb 06 00:00:00 1970 PST | 6 | 6 | foo + 446 | 6 | 00446 | Mon Feb 16 00:00:00 1970 PST | 6 | 6 | foo | 446 | 6 | 00446 | Mon Feb 16 00:00:00 1970 PST | 6 | 6 | foo + 456 | 6 | 00456 | Thu Feb 26 00:00:00 1970 PST | 6 | 6 | foo | 456 | 6 | 00456 | Thu Feb 26 00:00:00 1970 PST | 6 | 6 | foo + 466 | 6 | 00466 | Sun Mar 08 00:00:00 1970 PST | 6 | 6 | foo | 466 | 6 | 00466 | Sun Mar 08 00:00:00 1970 PST | 6 | 6 | foo + 476 | 6 | 00476 | Wed Mar 18 00:00:00 1970 PST | 6 | 6 | foo | 476 | 6 | 00476 | Wed Mar 18 00:00:00 1970 PST | 6 | 6 | foo + 486 | 6 | 00486 | Sat Mar 28 00:00:00 1970 PST | 6 | 6 | foo | 486 | 6 | 00486 | Sat Mar 28 00:00:00 1970 PST | 6 | 6 | foo + 496 | 6 | 00496 | Tue Apr 07 00:00:00 1970 PST | 6 | 6 | foo | 496 | 6 | 00496 | Tue Apr 07 00:00:00 1970 PST | 6 | 6 | foo + 506 | 6 | 00506 | Wed Jan 07 00:00:00 1970 PST | 6 | 6 | foo | 506 | 6 | 00506 | Wed Jan 07 00:00:00 1970 PST | 6 | 6 | foo + 516 | 6 | 00516 | Sat Jan 17 00:00:00 1970 PST | 6 | 6 | foo | 516 | 6 | 00516 | Sat Jan 17 00:00:00 1970 PST | 6 | 6 | foo + 526 | 6 | 00526 | Tue Jan 27 00:00:00 1970 PST | 6 | 6 | foo | 526 | 6 | 00526 | Tue Jan 27 00:00:00 1970 PST | 6 | 6 | foo + 536 | 6 | 00536 | Fri Feb 06 00:00:00 1970 PST | 6 | 6 | foo | 536 | 6 | 00536 | Fri Feb 06 00:00:00 1970 PST | 6 | 6 | foo + 546 | 6 | 00546 | Mon Feb 16 00:00:00 1970 PST | 6 | 6 | foo | 546 | 6 | 00546 | Mon Feb 16 00:00:00 1970 PST | 6 | 6 | foo + 556 | 6 | 00556 | Thu Feb 26 00:00:00 1970 PST | 6 | 6 | foo | 556 | 6 | 00556 | Thu Feb 26 00:00:00 1970 PST | 6 | 6 | foo + 566 | 6 | 00566 | Sun Mar 08 00:00:00 1970 PST | 6 | 6 | foo | 566 | 6 | 00566 | Sun Mar 08 00:00:00 1970 PST | 6 | 6 | foo + 576 | 6 | 00576 | Wed Mar 18 00:00:00 1970 PST | 6 | 6 | foo | 576 | 6 | 00576 | Wed Mar 18 00:00:00 1970 PST | 6 | 6 | foo + 586 | 6 | 00586 | Sat Mar 28 00:00:00 1970 PST | 6 | 6 | foo | 586 | 6 | 00586 | Sat Mar 28 00:00:00 1970 PST | 6 | 6 | foo + 596 | 6 | 00596 | Tue Apr 07 00:00:00 1970 PST | 6 | 6 | foo | 596 | 6 | 00596 | Tue Apr 07 00:00:00 1970 PST | 6 | 6 | foo + 606 | 6 | 00606 | Wed Jan 07 00:00:00 1970 PST | 6 | 6 | foo | 606 | 6 | 00606 | Wed Jan 07 00:00:00 1970 PST | 6 | 6 | foo + 616 | 6 | 00616 | Sat Jan 17 00:00:00 1970 PST | 6 | 6 | foo | 616 | 6 | 00616 | Sat Jan 17 00:00:00 1970 PST | 6 | 6 | foo + 626 | 6 | 00626 | Tue Jan 27 00:00:00 1970 PST | 6 | 6 | foo | 626 | 6 | 00626 | Tue Jan 27 00:00:00 1970 PST | 6 | 6 | foo + 636 | 6 | 00636 | Fri Feb 06 00:00:00 1970 PST | 6 | 6 | foo | 636 | 6 | 00636 | Fri Feb 06 00:00:00 1970 PST | 6 | 6 | foo + 646 | 6 | 00646 | Mon Feb 16 00:00:00 1970 PST | 6 | 6 | foo | 646 | 6 | 00646 | Mon Feb 16 00:00:00 1970 PST | 6 | 6 | foo + 656 | 6 | 00656 | Thu Feb 26 00:00:00 1970 PST | 6 | 6 | foo | 656 | 6 | 00656 | Thu Feb 26 00:00:00 1970 PST | 6 | 6 | foo + 666 | 6 | 00666 | Sun Mar 08 00:00:00 1970 PST | 6 | 6 | foo | 666 | 6 | 00666 | Sun Mar 08 00:00:00 1970 PST | 6 | 6 | foo + 676 | 6 | 00676 | Wed Mar 18 00:00:00 1970 PST | 6 | 6 | foo | 676 | 6 | 00676 | Wed Mar 18 00:00:00 1970 PST | 6 | 6 | foo + 686 | 6 | 00686 | Sat Mar 28 00:00:00 1970 PST | 6 | 6 | foo | 686 | 6 | 00686 | Sat Mar 28 00:00:00 1970 PST | 6 | 6 | foo + 696 | 6 | 00696 | Tue Apr 07 00:00:00 1970 PST | 6 | 6 | foo | 696 | 6 | 00696 | Tue Apr 07 00:00:00 1970 PST | 6 | 6 | foo + 706 | 6 | 00706 | Wed Jan 07 00:00:00 1970 PST | 6 | 6 | foo | 706 | 6 | 00706 | Wed Jan 07 00:00:00 1970 PST | 6 | 6 | foo + 716 | 6 | 00716 | Sat Jan 17 00:00:00 1970 PST | 6 | 6 | foo | 716 | 6 | 00716 | Sat Jan 17 00:00:00 1970 PST | 6 | 6 | foo + 726 | 6 | 00726 | Tue Jan 27 00:00:00 1970 PST | 6 | 6 | foo | 726 | 6 | 00726 | Tue Jan 27 00:00:00 1970 PST | 6 | 6 | foo + 736 | 6 | 00736 | Fri Feb 06 00:00:00 1970 PST | 6 | 6 | foo | 736 | 6 | 00736 | Fri Feb 06 00:00:00 1970 PST | 6 | 6 | foo + 746 | 6 | 00746 | Mon Feb 16 00:00:00 1970 PST | 6 | 6 | foo | 746 | 6 | 00746 | Mon Feb 16 00:00:00 1970 PST | 6 | 6 | foo + 756 | 6 | 00756 | Thu Feb 26 00:00:00 1970 PST | 6 | 6 | foo | 756 | 6 | 00756 | Thu Feb 26 00:00:00 1970 PST | 6 | 6 | foo + 766 | 6 | 00766 | Sun Mar 08 00:00:00 1970 PST | 6 | 6 | foo | 766 | 6 | 00766 | Sun Mar 08 00:00:00 1970 PST | 6 | 6 | foo + 776 | 6 | 00776 | Wed Mar 18 00:00:00 1970 PST | 6 | 6 | foo | 776 | 6 | 00776 | Wed Mar 18 00:00:00 1970 PST | 6 | 6 | foo + 786 | 6 | 00786 | Sat Mar 28 00:00:00 1970 PST | 6 | 6 | foo | 786 | 6 | 00786 | Sat Mar 28 00:00:00 1970 PST | 6 | 6 | foo + 796 | 6 | 00796 | Tue Apr 07 00:00:00 1970 PST | 6 | 6 | foo | 796 | 6 | 00796 | Tue Apr 07 00:00:00 1970 PST | 6 | 6 | foo + 806 | 6 | 00806 | Wed Jan 07 00:00:00 1970 PST | 6 | 6 | foo | 806 | 6 | 00806 | Wed Jan 07 00:00:00 1970 PST | 6 | 6 | foo + 816 | 6 | 00816 | Sat Jan 17 00:00:00 1970 PST | 6 | 6 | foo | 816 | 6 | 00816 | Sat Jan 17 00:00:00 1970 PST | 6 | 6 | foo + 826 | 6 | 00826 | Tue Jan 27 00:00:00 1970 PST | 6 | 6 | foo | 826 | 6 | 00826 | Tue Jan 27 00:00:00 1970 PST | 6 | 6 | foo + 836 | 6 | 00836 | Fri Feb 06 00:00:00 1970 PST | 6 | 6 | foo | 836 | 6 | 00836 | Fri Feb 06 00:00:00 1970 PST | 6 | 6 | foo + 846 | 6 | 00846 | Mon Feb 16 00:00:00 1970 PST | 6 | 6 | foo | 846 | 6 | 00846 | Mon Feb 16 00:00:00 1970 PST | 6 | 6 | foo + 856 | 6 | 00856 | Thu Feb 26 00:00:00 1970 PST | 6 | 6 | foo | 856 | 6 | 00856 | Thu Feb 26 00:00:00 1970 PST | 6 | 6 | foo + 866 | 6 | 00866 | Sun Mar 08 00:00:00 1970 PST | 6 | 6 | foo | 866 | 6 | 00866 | Sun Mar 08 00:00:00 1970 PST | 6 | 6 | foo + 876 | 6 | 00876 | Wed Mar 18 00:00:00 1970 PST | 6 | 6 | foo | 876 | 6 | 00876 | Wed Mar 18 00:00:00 1970 PST | 6 | 6 | foo + 886 | 6 | 00886 | Sat Mar 28 00:00:00 1970 PST | 6 | 6 | foo | 886 | 6 | 00886 | Sat Mar 28 00:00:00 1970 PST | 6 | 6 | foo + 896 | 6 | 00896 | Tue Apr 07 00:00:00 1970 PST | 6 | 6 | foo | 896 | 6 | 00896 | Tue Apr 07 00:00:00 1970 PST | 6 | 6 | foo + 906 | 6 | 00906 | Wed Jan 07 00:00:00 1970 PST | 6 | 6 | foo | 906 | 6 | 00906 | Wed Jan 07 00:00:00 1970 PST | 6 | 6 | foo + 916 | 6 | 00916 | Sat Jan 17 00:00:00 1970 PST | 6 | 6 | foo | 916 | 6 | 00916 | Sat Jan 17 00:00:00 1970 PST | 6 | 6 | foo + 926 | 6 | 00926 | Tue Jan 27 00:00:00 1970 PST | 6 | 6 | foo | 926 | 6 | 00926 | Tue Jan 27 00:00:00 1970 PST | 6 | 6 | foo + 936 | 6 | 00936 | Fri Feb 06 00:00:00 1970 PST | 6 | 6 | foo | 936 | 6 | 00936 | Fri Feb 06 00:00:00 1970 PST | 6 | 6 | foo + 946 | 6 | 00946 | Mon Feb 16 00:00:00 1970 PST | 6 | 6 | foo | 946 | 6 | 00946 | Mon Feb 16 00:00:00 1970 PST | 6 | 6 | foo + 956 | 6 | 00956 | Thu Feb 26 00:00:00 1970 PST | 6 | 6 | foo | 956 | 6 | 00956 | Thu Feb 26 00:00:00 1970 PST | 6 | 6 | foo + 966 | 6 | 00966 | Sun Mar 08 00:00:00 1970 PST | 6 | 6 | foo | 966 | 6 | 00966 | Sun Mar 08 00:00:00 1970 PST | 6 | 6 | foo + 976 | 6 | 00976 | Wed Mar 18 00:00:00 1970 PST | 6 | 6 | foo | 976 | 6 | 00976 | Wed Mar 18 00:00:00 1970 PST | 6 | 6 | foo + 986 | 6 | 00986 | Sat Mar 28 00:00:00 1970 PST | 6 | 6 | foo | 986 | 6 | 00986 | Sat Mar 28 00:00:00 1970 PST | 6 | 6 | foo + 996 | 6 | 00996 | Tue Apr 07 00:00:00 1970 PST | 6 | 6 | foo | 996 | 6 | 00996 | Tue Apr 07 00:00:00 1970 PST | 6 | 6 | foo +(100 rows) + +-- bug before 9.3.5 due to sloppy handling of remote-estimate parameters +--Testcase 91: +SELECT * FROM ft1 WHERE c1 = ANY (ARRAY(SELECT c1 FROM ft2 WHERE c1 < 5)); + c1 | c2 | c3 | time | c6 | c7 | c8 +----+----+-------+------------------------------+----+------------+----- + 1 | 1 | 00001 | Fri Jan 02 00:00:00 1970 PST | 1 | 1 | foo + 2 | 2 | 00002 | Sat Jan 03 00:00:00 1970 PST | 2 | 2 | foo + 3 | 3 | 00003 | Sun Jan 04 00:00:00 1970 PST | 3 | 3 | foo + 4 | 4 | 00004 | Mon Jan 05 00:00:00 1970 PST | 4 | 4 | foo +(4 rows) + +--Testcase 92: +SELECT * FROM ft2 WHERE c1 = ANY (ARRAY(SELECT c1 FROM ft1 WHERE c1 < 5)); + c1 | c2 | c3 | time | c6 | c7 | c8 +----+----+-------+------------------------------+----+------------+----- + 1 | 1 | 00001 | Fri Jan 02 00:00:00 1970 PST | 1 | 1 | foo + 2 | 2 | 00002 | Sat Jan 03 00:00:00 1970 PST | 2 | 2 | foo + 3 | 3 | 00003 | Sun Jan 04 00:00:00 1970 PST | 3 | 3 | foo + 4 | 4 | 00004 | Mon Jan 05 00:00:00 1970 PST | 4 | 4 | foo +(4 rows) + +-- we should not push order by clause with volatile expressions or unsafe +-- collations +--Testcase 93: +EXPLAIN (VERBOSE, COSTS OFF) + SELECT * FROM ft2 ORDER BY ft2.c1, random(); + QUERY PLAN +------------------------------------------------------------------------------ + Sort + Output: c1, c2, c3, "time", c6, c7, c8, (random()) + Sort Key: ft2.c1, (random()) + -> Foreign Scan on public.ft2 + Output: c1, c2, c3, "time", c6, c7, c8, random() + InfluxDB query: SELECT "C 1", "c2", "c3", "c6", "c7", "c8" FROM "T1" +(6 rows) + +--Testcase 94: +EXPLAIN (VERBOSE, COSTS OFF) + SELECT * FROM ft2 ORDER BY ft2.c1, ft2.c3 collate "C"; + QUERY PLAN +------------------------------------------------------------------------------ + Sort + Output: c1, c2, c3, "time", c6, c7, c8, ((c3)::text) + Sort Key: ft2.c1, ft2.c3 COLLATE "C" + -> Foreign Scan on public.ft2 + Output: c1, c2, c3, "time", c6, c7, c8, c3 + InfluxDB query: SELECT "C 1", "c2", "c3", "c6", "c7", "c8" FROM "T1" +(6 rows) + +-- user-defined operator/function +--Testcase 95: +CREATE FUNCTION influxdb_fdw_abs(int) RETURNS int AS $$ +BEGIN +RETURN abs($1); +END +$$ LANGUAGE plpgsql IMMUTABLE; +--Testcase 96: +CREATE OPERATOR === ( + LEFTARG = int, + RIGHTARG = int, + PROCEDURE = int4eq, + COMMUTATOR = === +); +-- built-in operators and functions can be shipped for remote execution +--Testcase 97: +EXPLAIN (VERBOSE, COSTS OFF) + SELECT count(c3) FROM ft1 t1 WHERE t1.c1 = abs(t1.c2); + QUERY PLAN +---------------------------------------------------------------------------------- + Aggregate + Output: count(c3) + -> Foreign Scan on public.ft1 t1 + Output: c3 + InfluxDB query: SELECT "c3", "C 1" FROM "T1" WHERE (("C 1" = abs("c2"))) +(5 rows) + +--Testcase 98: +SELECT count(c3) FROM ft1 t1 WHERE t1.c1 = abs(t1.c2); + count +------- + 9 +(1 row) + +--Testcase 99: +EXPLAIN (VERBOSE, COSTS OFF) + SELECT count(c3) FROM ft1 t1 WHERE t1.c1 = t1.c2; + QUERY PLAN +----------------------------------------------------------------------------- + Aggregate + Output: count(c3) + -> Foreign Scan on public.ft1 t1 + Output: c3 + InfluxDB query: SELECT "c3", "C 1" FROM "T1" WHERE (("C 1" = "c2")) +(5 rows) + +--Testcase 100: +SELECT count(c3) FROM ft1 t1 WHERE t1.c1 = t1.c2; + count +------- + 9 +(1 row) + +-- by default, user-defined ones cannot +--Testcase 101: +EXPLAIN (VERBOSE, COSTS OFF) + SELECT count(c3) FROM ft1 t1 WHERE t1.c1 = influxdb_fdw_abs(t1.c2); + QUERY PLAN +------------------------------------------------------------ + Aggregate + Output: count(c3) + -> Foreign Scan on public.ft1 t1 + Output: c3 + Filter: (t1.c1 = influxdb_fdw_abs(t1.c2)) + InfluxDB query: SELECT "C 1", "c2", "c3" FROM "T1" +(6 rows) + +--Testcase 102: +SELECT count(c3) FROM ft1 t1 WHERE t1.c1 = influxdb_fdw_abs(t1.c2); + count +------- + 9 +(1 row) + +--Testcase 103: +EXPLAIN (VERBOSE, COSTS OFF) + SELECT count(c3) FROM ft1 t1 WHERE t1.c1 === t1.c2; + QUERY PLAN +------------------------------------------------------------ + Aggregate + Output: count(c3) + -> Foreign Scan on public.ft1 t1 + Output: c3 + Filter: (t1.c1 === t1.c2) + InfluxDB query: SELECT "C 1", "c2", "c3" FROM "T1" +(6 rows) + +--Testcase 104: +SELECT count(c3) FROM ft1 t1 WHERE t1.c1 === t1.c2; + count +------- + 9 +(1 row) + +-- ORDER BY can be shipped, though +--Testcase 105: +EXPLAIN (VERBOSE, COSTS OFF) + SELECT * FROM ft1 t1 WHERE t1.c1 === t1.c2 order by t1.c2 limit 1; + QUERY PLAN +------------------------------------------------------------------------------------ + Limit + Output: c1, c2, c3, "time", c6, c7, c8 + -> Sort + Output: c1, c2, c3, "time", c6, c7, c8 + Sort Key: t1.c2 + -> Foreign Scan on public.ft1 t1 + Output: c1, c2, c3, "time", c6, c7, c8 + Filter: (t1.c1 === t1.c2) + InfluxDB query: SELECT "C 1", "c2", "c3", "c6", "c7", "c8" FROM "T1" +(9 rows) + +--Testcase 106: +SELECT * FROM ft1 t1 WHERE t1.c1 === t1.c2 order by t1.c2 limit 1; + c1 | c2 | c3 | time | c6 | c7 | c8 +----+----+-------+------------------------------+----+------------+----- + 1 | 1 | 00001 | Fri Jan 02 00:00:00 1970 PST | 1 | 1 | foo +(1 row) + +-- but let's put them in an extension ... +--Testcase 107: +ALTER EXTENSION influxdb_fdw ADD FUNCTION influxdb_fdw_abs(int); +--Testcase 108: +ALTER EXTENSION influxdb_fdw ADD OPERATOR === (int, int); +-- ALTER SERVER loopback OPTIONS (ADD extensions 'influxdb_fdw'); +-- ... now they can be shipped +--Testcase 109: +EXPLAIN (VERBOSE, COSTS OFF) + SELECT count(c3) FROM ft1 t1 WHERE t1.c1 = influxdb_fdw_abs(t1.c2); + QUERY PLAN +------------------------------------------------------------ + Aggregate + Output: count(c3) + -> Foreign Scan on public.ft1 t1 + Output: c3 + Filter: (t1.c1 = influxdb_fdw_abs(t1.c2)) + InfluxDB query: SELECT "C 1", "c2", "c3" FROM "T1" +(6 rows) + +--Testcase 110: +SELECT count(c3) FROM ft1 t1 WHERE t1.c1 = influxdb_fdw_abs(t1.c2); + count +------- + 9 +(1 row) + +--Testcase 111: +EXPLAIN (VERBOSE, COSTS OFF) + SELECT count(c3) FROM ft1 t1 WHERE t1.c1 === t1.c2; + QUERY PLAN +------------------------------------------------------------ + Aggregate + Output: count(c3) + -> Foreign Scan on public.ft1 t1 + Output: c3 + Filter: (t1.c1 === t1.c2) + InfluxDB query: SELECT "C 1", "c2", "c3" FROM "T1" +(6 rows) + +--Testcase 112: +SELECT count(c3) FROM ft1 t1 WHERE t1.c1 === t1.c2; + count +------- + 9 +(1 row) + +-- and both ORDER BY and LIMIT can be shipped +--Testcase 113: +EXPLAIN (VERBOSE, COSTS OFF) + SELECT * FROM ft1 t1 WHERE t1.c1 === t1.c2 order by t1.c2 limit 1; + QUERY PLAN +------------------------------------------------------------------------------------ + Limit + Output: c1, c2, c3, "time", c6, c7, c8 + -> Sort + Output: c1, c2, c3, "time", c6, c7, c8 + Sort Key: t1.c2 + -> Foreign Scan on public.ft1 t1 + Output: c1, c2, c3, "time", c6, c7, c8 + Filter: (t1.c1 === t1.c2) + InfluxDB query: SELECT "C 1", "c2", "c3", "c6", "c7", "c8" FROM "T1" +(9 rows) + +--Testcase 114: +SELECT * FROM ft1 t1 WHERE t1.c1 === t1.c2 order by t1.c2 limit 1; + c1 | c2 | c3 | time | c6 | c7 | c8 +----+----+-------+------------------------------+----+------------+----- + 1 | 1 | 00001 | Fri Jan 02 00:00:00 1970 PST | 1 | 1 | foo +(1 row) + +-- Test CASE pushdown +-- InfluxDB not support CASE expressions. +--Testcase 813: +EXPLAIN (VERBOSE, COSTS OFF) +SELECT c1,c2,c3 FROM ft2 WHERE CASE WHEN c1 > 990 THEN c1 END < 1000 ORDER BY c1; + QUERY PLAN +-------------------------------------------------------------------------------------- + Sort + Output: c1, c2, c3 + Sort Key: ft2.c1 + -> Foreign Scan on public.ft2 + Output: c1, c2, c3 + Filter: (CASE WHEN (ft2.c1 > 990) THEN ft2.c1 ELSE NULL::integer END < 1000) + InfluxDB query: SELECT "C 1", "c2", "c3" FROM "T1" +(7 rows) + +--Testcase 814: +SELECT c1,c2,c3 FROM ft2 WHERE CASE WHEN c1 > 990 THEN c1 END < 1000 ORDER BY c1; + c1 | c2 | c3 +-----+----+------- + 991 | 1 | 00991 + 992 | 2 | 00992 + 993 | 3 | 00993 + 994 | 4 | 00994 + 995 | 5 | 00995 + 996 | 6 | 00996 + 997 | 7 | 00997 + 998 | 8 | 00998 + 999 | 9 | 00999 +(9 rows) + +-- Nested CASE +--Testcase 815: +EXPLAIN (VERBOSE, COSTS OFF) +SELECT c1,c2,c3 FROM ft2 WHERE CASE CASE WHEN c2 > 0 THEN c2 END WHEN 100 THEN 601 WHEN c2 THEN c2 ELSE 0 END > 600 ORDER BY c1; + QUERY PLAN +--------------------------------------------------------------------------------------------------------------------------------------------- + Sort + Output: c1, c2, c3 + Sort Key: ft2.c1 + -> Foreign Scan on public.ft2 + Output: c1, c2, c3 + Filter: (CASE CASE WHEN (ft2.c2 > 0) THEN ft2.c2 ELSE NULL::integer END WHEN 100 THEN 601 WHEN ft2.c2 THEN ft2.c2 ELSE 0 END > 600) + InfluxDB query: SELECT "C 1", "c2", "c3" FROM "T1" +(7 rows) + +--Testcase 816: +SELECT c1,c2,c3 FROM ft2 WHERE CASE CASE WHEN c2 > 0 THEN c2 END WHEN 100 THEN 601 WHEN c2 THEN c2 ELSE 0 END > 600 ORDER BY c1; + c1 | c2 | c3 +----+----+---- +(0 rows) + +-- CASE arg WHEN +--Testcase 817: +EXPLAIN (VERBOSE, COSTS OFF) +SELECT * FROM ft1 WHERE c1 > (CASE mod(c1, 4) WHEN 0 THEN 1 WHEN 2 THEN 50 ELSE 100 END); + QUERY PLAN +------------------------------------------------------------------------------------ + Foreign Scan on public.ft1 + Output: c1, c2, c3, "time", c6, c7, c8 + Filter: (ft1.c1 > CASE mod(ft1.c1, 4) WHEN 0 THEN 1 WHEN 2 THEN 50 ELSE 100 END) + InfluxDB query: SELECT "C 1", "c2", "c3", "c6", "c7", "c8" FROM "T1" +(4 rows) + +-- CASE cannot be pushed down because of unshippable arg clause +--Testcase 818: +EXPLAIN (VERBOSE, COSTS OFF) +SELECT * FROM ft1 WHERE c1 > (CASE random()::integer WHEN 0 THEN 1 WHEN 2 THEN 50 ELSE 100 END); + QUERY PLAN +----------------------------------------------------------------------------------------- + Foreign Scan on public.ft1 + Output: c1, c2, c3, "time", c6, c7, c8 + Filter: (ft1.c1 > CASE (random())::integer WHEN 0 THEN 1 WHEN 2 THEN 50 ELSE 100 END) + InfluxDB query: SELECT "C 1", "c2", "c3", "c6", "c7", "c8" FROM "T1" +(4 rows) + +-- these are shippable +--Testcase 819: +EXPLAIN (VERBOSE, COSTS OFF) +SELECT * FROM ft1 WHERE CASE c6 WHEN 'foo' THEN true ELSE c3 < 'bar' END; + QUERY PLAN +---------------------------------------------------------------------------------- + Foreign Scan on public.ft1 + Output: c1, c2, c3, "time", c6, c7, c8 + Filter: CASE ft1.c6 WHEN 'foo'::text THEN true ELSE (ft1.c3 < 'bar'::text) END + InfluxDB query: SELECT "C 1", "c2", "c3", "c6", "c7", "c8" FROM "T1" +(4 rows) + +--Testcase 820: +EXPLAIN (VERBOSE, COSTS OFF) +SELECT * FROM ft1 WHERE CASE c3 WHEN c6 THEN true ELSE c3 < 'bar' END; + QUERY PLAN +----------------------------------------------------------------------------- + Foreign Scan on public.ft1 + Output: c1, c2, c3, "time", c6, c7, c8 + Filter: CASE ft1.c3 WHEN ft1.c6 THEN true ELSE (ft1.c3 < 'bar'::text) END + InfluxDB query: SELECT "C 1", "c2", "c3", "c6", "c7", "c8" FROM "T1" +(4 rows) + +-- but this is not because of collation +--Testcase 821: +EXPLAIN (VERBOSE, COSTS OFF) +SELECT * FROM ft1 WHERE CASE c3 COLLATE "C" WHEN c6 THEN true ELSE c3 < 'bar' END; + QUERY PLAN +------------------------------------------------------------------------------------- + Foreign Scan on public.ft1 + Output: c1, c2, c3, "time", c6, c7, c8 + Filter: CASE (ft1.c3)::text WHEN ft1.c6 THEN true ELSE (ft1.c3 < 'bar'::text) END + InfluxDB query: SELECT "C 1", "c2", "c3", "c6", "c7", "c8" FROM "T1" +(4 rows) + +-- a regconfig constant referring to this text search configuration +-- is initially unshippable +--Testcase 822: +CREATE TEXT SEARCH CONFIGURATION public.custom_search + (COPY = pg_catalog.english); +--Testcase 823: +EXPLAIN (VERBOSE, COSTS OFF) +SELECT c1, to_tsvector('custom_search'::regconfig, c3) FROM ft1 +WHERE c1 = 642 AND length(to_tsvector('custom_search'::regconfig, c3)) > 0; + QUERY PLAN +------------------------------------------------------------------------- + Foreign Scan on public.ft1 + Output: c1, to_tsvector('custom_search'::regconfig, c3) + Filter: (length(to_tsvector('custom_search'::regconfig, ft1.c3)) > 0) + InfluxDB query: SELECT "C 1", "c3" FROM "T1" WHERE (("C 1" = 642)) +(4 rows) + +--Testcase 824: +SELECT c1, to_tsvector('custom_search'::regconfig, c3) FROM ft1 +WHERE c1 = 642 AND length(to_tsvector('custom_search'::regconfig, c3)) > 0; + c1 | to_tsvector +-----+------------- + 642 | '00642':1 +(1 row) + +-- but if it's in a shippable extension, it can be shipped +ALTER EXTENSION influxdb_fdw ADD TEXT SEARCH CONFIGURATION public.custom_search; +-- however, that doesn't flush the shippability cache, so do a quick reconnect +\c - +EXPLAIN (VERBOSE, COSTS OFF) +SELECT c1, to_tsvector('custom_search'::regconfig, c3) FROM ft1 +WHERE c1 = 642 AND length(to_tsvector('custom_search'::regconfig, c3)) > 0; + QUERY PLAN +------------------------------------------------------------------------- + Foreign Scan on public.ft1 + Output: c1, to_tsvector('custom_search'::regconfig, c3) + Filter: (length(to_tsvector('custom_search'::regconfig, ft1.c3)) > 0) + InfluxDB query: SELECT "C 1", "c3" FROM "T1" WHERE (("C 1" = 642)) +(4 rows) + +SELECT c1, to_tsvector('custom_search'::regconfig, c3) FROM ft1 +WHERE c1 = 642 AND length(to_tsvector('custom_search'::regconfig, c3)) > 0; + c1 | to_tsvector +-----+------------- + 642 | '00642':1 +(1 row) + +-- =================================================================== +-- JOIN queries +-- =================================================================== +-- join two tables +--Testcase 115: +EXPLAIN (VERBOSE, COSTS OFF) +SELECT t1.c1, t2.c1 FROM ft1 t1 JOIN ft2 t2 ON (t1.c1 = t2.c1) ORDER BY t1.c3, t1.c1 OFFSET 100 LIMIT 10; + QUERY PLAN +------------------------------------------------------------------------ + Limit + Output: t1.c1, t2.c1, t1.c3 + -> Sort + Output: t1.c1, t2.c1, t1.c3 + Sort Key: t1.c3, t1.c1 + -> Merge Join + Output: t1.c1, t2.c1, t1.c3 + Merge Cond: (t1.c1 = t2.c1) + -> Sort + Output: t1.c1, t1.c3 + Sort Key: t1.c1 + -> Foreign Scan on public.ft1 t1 + Output: t1.c1, t1.c3 + InfluxDB query: SELECT "C 1", "c3" FROM "T1" + -> Sort + Output: t2.c1 + Sort Key: t2.c1 + -> Foreign Scan on public.ft2 t2 + Output: t2.c1 + InfluxDB query: SELECT "C 1" FROM "T1" +(20 rows) + +--Testcase 116: +SELECT t1.c1, t2.c1 FROM ft1 t1 JOIN ft2 t2 ON (t1.c1 = t2.c1) ORDER BY t1.c3, t1.c1 OFFSET 100 LIMIT 10; + c1 | c1 +-----+----- + 101 | 101 + 102 | 102 + 103 | 103 + 104 | 104 + 105 | 105 + 106 | 106 + 107 | 107 + 108 | 108 + 109 | 109 + 110 | 110 +(10 rows) + +-- join three tables +--Testcase 117: +EXPLAIN (VERBOSE, COSTS OFF) +SELECT t1.c1, t2.c2, t3.c3 FROM ft1 t1 JOIN ft2 t2 ON (t1.c1 = t2.c1) JOIN ft4 t3 ON (t3.c1 = t1.c1) ORDER BY t1.c3, t1.c1 OFFSET 10 LIMIT 10; + QUERY PLAN +------------------------------------------------------------------------------------ + Limit + Output: t1.c1, t2.c2, t3.c3, t1.c3 + -> Sort + Output: t1.c1, t2.c2, t3.c3, t1.c3 + Sort Key: t1.c3, t1.c1 + -> Merge Join + Output: t1.c1, t2.c2, t3.c3, t1.c3 + Merge Cond: (t2.c1 = t1.c1) + -> Sort + Output: t2.c2, t2.c1 + Sort Key: t2.c1 + -> Foreign Scan on public.ft2 t2 + Output: t2.c2, t2.c1 + InfluxDB query: SELECT "C 1", "c2" FROM "T1" + -> Materialize + Output: t1.c1, t1.c3, t3.c3, t3.c1 + -> Merge Join + Output: t1.c1, t1.c3, t3.c3, t3.c1 + Merge Cond: (t1.c1 = t3.c1) + -> Sort + Output: t1.c1, t1.c3 + Sort Key: t1.c1 + -> Foreign Scan on public.ft1 t1 + Output: t1.c1, t1.c3 + InfluxDB query: SELECT "C 1", "c3" FROM "T1" + -> Sort + Output: t3.c3, t3.c1 + Sort Key: t3.c1 + -> Foreign Scan on public.ft4 t3 + Output: t3.c3, t3.c1 + InfluxDB query: SELECT "c1", "c3" FROM "T3" +(31 rows) + +--Testcase 118: +SELECT t1.c1, t2.c2, t3.c3 FROM ft1 t1 JOIN ft2 t2 ON (t1.c1 = t2.c1) JOIN ft4 t3 ON (t3.c1 = t1.c1) ORDER BY t1.c3, t1.c1 OFFSET 10 LIMIT 10; + c1 | c2 | c3 +----+----+-------- + 22 | 2 | AAA022 + 24 | 4 | AAA024 + 26 | 6 | AAA026 + 28 | 8 | AAA028 + 30 | 0 | AAA030 + 32 | 2 | AAA032 + 34 | 4 | AAA034 + 36 | 6 | AAA036 + 38 | 8 | AAA038 + 40 | 0 | AAA040 +(10 rows) + +-- left outer join +--Testcase 119: +EXPLAIN (VERBOSE, COSTS OFF) +SELECT t1.c1, t2.c1 FROM ft4 t1 LEFT JOIN ft5 t2 ON (t1.c1 = t2.c1) ORDER BY t1.c1, t2.c1 OFFSET 10 LIMIT 10; + QUERY PLAN +----------------------------------------------------------------- + Limit + Output: t1.c1, t2.c1 + -> Incremental Sort + Output: t1.c1, t2.c1 + Sort Key: t1.c1, t2.c1 + Presorted Key: t1.c1 + -> Merge Left Join + Output: t1.c1, t2.c1 + Merge Cond: (t1.c1 = t2.c1) + -> Sort + Output: t1.c1 + Sort Key: t1.c1 + -> Foreign Scan on public.ft4 t1 + Output: t1.c1 + InfluxDB query: SELECT "c1" FROM "T3" + -> Sort + Output: t2.c1 + Sort Key: t2.c1 + -> Foreign Scan on public.ft5 t2 + Output: t2.c1 + InfluxDB query: SELECT "c1" FROM "T4" +(21 rows) + +--Testcase 120: +SELECT t1.c1, t2.c1 FROM ft4 t1 LEFT JOIN ft5 t2 ON (t1.c1 = t2.c1) ORDER BY t1.c1, t2.c1 OFFSET 10 LIMIT 10; + c1 | c1 +----+---- + 22 | + 24 | 24 + 26 | + 28 | + 30 | 30 + 32 | + 34 | + 36 | 36 + 38 | + 40 | +(10 rows) + +-- left outer join three tables +--Testcase 121: +EXPLAIN (VERBOSE, COSTS OFF) +SELECT t1.c1, t2.c2, t3.c3 FROM ft2 t1 LEFT JOIN ft2 t2 ON (t1.c1 = t2.c1) LEFT JOIN ft4 t3 ON (t2.c1 = t3.c1) OFFSET 10 LIMIT 10; + QUERY PLAN +------------------------------------------------------------------------ + Limit + Output: t1.c1, t2.c2, t3.c3 + -> Nested Loop Left Join + Output: t1.c1, t2.c2, t3.c3 + Join Filter: (t2.c1 = t3.c1) + -> Nested Loop Left Join + Output: t1.c1, t2.c2, t2.c1 + Join Filter: (t1.c1 = t2.c1) + -> Foreign Scan on public.ft2 t1 + Output: t1.c1 + InfluxDB query: SELECT "C 1" FROM "T1" + -> Materialize + Output: t2.c2, t2.c1 + -> Foreign Scan on public.ft2 t2 + Output: t2.c2, t2.c1 + InfluxDB query: SELECT "C 1", "c2" FROM "T1" + -> Materialize + Output: t3.c3, t3.c1 + -> Foreign Scan on public.ft4 t3 + Output: t3.c3, t3.c1 + InfluxDB query: SELECT "c1", "c3" FROM "T3" +(21 rows) + +--Testcase 122: +SELECT t1.c1, t2.c2, t3.c3 FROM ft2 t1 LEFT JOIN ft2 t2 ON (t1.c1 = t2.c1) LEFT JOIN ft4 t3 ON (t2.c1 = t3.c1) ORDER BY t1.c1 OFFSET 10 LIMIT 10; + c1 | c2 | c3 +----+----+-------- + 11 | 1 | + 12 | 2 | AAA012 + 13 | 3 | + 14 | 4 | AAA014 + 15 | 5 | + 16 | 6 | AAA016 + 17 | 7 | + 18 | 8 | AAA018 + 19 | 9 | + 20 | 0 | AAA020 +(10 rows) + +-- left outer join + placement of clauses. +-- clauses within the nullable side are not pulled up, but top level clause on +-- non-nullable side is pushed into non-nullable side +--Testcase 123: +EXPLAIN (VERBOSE, COSTS OFF) +SELECT t1.c1, t1.c2, t2.c1, t2.c2 FROM ft4 t1 LEFT JOIN (SELECT * FROM ft5 WHERE c1 < 10) t2 ON (t1.c1 = t2.c1) WHERE t1.c1 < 10; + QUERY PLAN +------------------------------------------------------------------------------- + Hash Left Join + Output: t1.c1, t1.c2, ft5.c1, ft5.c2 + Hash Cond: (t1.c1 = ft5.c1) + -> Foreign Scan on public.ft4 t1 + Output: t1.c1, t1.c2, t1.c3 + InfluxDB query: SELECT "c1", "c2" FROM "T3" WHERE (("c1" < 10)) + -> Hash + Output: ft5.c1, ft5.c2 + -> Foreign Scan on public.ft5 + Output: ft5.c1, ft5.c2 + InfluxDB query: SELECT "c1", "c2" FROM "T4" WHERE (("c1" < 10)) +(11 rows) + +--Testcase 124: +SELECT t1.c1, t1.c2, t2.c1, t2.c2 FROM ft4 t1 LEFT JOIN (SELECT * FROM ft5 WHERE c1 < 10) t2 ON (t1.c1 = t2.c1) WHERE t1.c1 < 10; + c1 | c2 | c1 | c2 +----+----+----+---- + 2 | 3 | | + 4 | 5 | | + 6 | 7 | 6 | 7 + 8 | 9 | | +(4 rows) + +-- clauses within the nullable side are not pulled up, but the top level clause +-- on nullable side is not pushed down into nullable side +--Testcase 125: +EXPLAIN (VERBOSE, COSTS OFF) +SELECT t1.c1, t1.c2, t2.c1, t2.c2 FROM ft4 t1 LEFT JOIN (SELECT * FROM ft5 WHERE c1 < 10) t2 ON (t1.c1 = t2.c1) + WHERE (t2.c1 < 10 OR t2.c1 IS NULL) AND t1.c1 < 10; + QUERY PLAN +------------------------------------------------------------------------------- + Hash Left Join + Output: t1.c1, t1.c2, ft5.c1, ft5.c2 + Hash Cond: (t1.c1 = ft5.c1) + Filter: ((ft5.c1 < 10) OR (ft5.c1 IS NULL)) + -> Foreign Scan on public.ft4 t1 + Output: t1.c1, t1.c2, t1.c3 + InfluxDB query: SELECT "c1", "c2" FROM "T3" WHERE (("c1" < 10)) + -> Hash + Output: ft5.c1, ft5.c2 + -> Foreign Scan on public.ft5 + Output: ft5.c1, ft5.c2 + InfluxDB query: SELECT "c1", "c2" FROM "T4" WHERE (("c1" < 10)) +(12 rows) + +--Testcase 126: +SELECT t1.c1, t1.c2, t2.c1, t2.c2 FROM ft4 t1 LEFT JOIN (SELECT * FROM ft5 WHERE c1 < 10) t2 ON (t1.c1 = t2.c1) + WHERE (t2.c1 < 10 OR t2.c1 IS NULL) AND t1.c1 < 10; + c1 | c2 | c1 | c2 +----+----+----+---- + 2 | 3 | | + 4 | 5 | | + 6 | 7 | 6 | 7 + 8 | 9 | | +(4 rows) + +-- right outer join +--Testcase 127: +EXPLAIN (VERBOSE, COSTS OFF) +SELECT t1.c1, t2.c1 FROM ft5 t1 RIGHT JOIN ft4 t2 ON (t1.c1 = t2.c1) ORDER BY t2.c1, t1.c1 OFFSET 10 LIMIT 10; + QUERY PLAN +----------------------------------------------------------------- + Limit + Output: t1.c1, t2.c1 + -> Incremental Sort + Output: t1.c1, t2.c1 + Sort Key: t2.c1, t1.c1 + Presorted Key: t2.c1 + -> Merge Left Join + Output: t1.c1, t2.c1 + Merge Cond: (t2.c1 = t1.c1) + -> Sort + Output: t2.c1 + Sort Key: t2.c1 + -> Foreign Scan on public.ft4 t2 + Output: t2.c1 + InfluxDB query: SELECT "c1" FROM "T3" + -> Sort + Output: t1.c1 + Sort Key: t1.c1 + -> Foreign Scan on public.ft5 t1 + Output: t1.c1 + InfluxDB query: SELECT "c1" FROM "T4" +(21 rows) + +--Testcase 128: +SELECT t1.c1, t2.c1 FROM ft5 t1 RIGHT JOIN ft4 t2 ON (t1.c1 = t2.c1) ORDER BY t2.c1, t1.c1 OFFSET 10 LIMIT 10; + c1 | c1 +----+---- + | 22 + 24 | 24 + | 26 + | 28 + 30 | 30 + | 32 + | 34 + 36 | 36 + | 38 + | 40 +(10 rows) + +-- right outer join three tables +--Testcase 129: +EXPLAIN (VERBOSE, COSTS OFF) +SELECT t1.c1, t2.c2, t3.c3 FROM ft2 t1 RIGHT JOIN ft2 t2 ON (t1.c1 = t2.c1) RIGHT JOIN ft4 t3 ON (t2.c1 = t3.c1) OFFSET 10 LIMIT 10; + QUERY PLAN +------------------------------------------------------------------------ + Limit + Output: t1.c1, t2.c2, t3.c3 + -> Nested Loop Left Join + Output: t1.c1, t2.c2, t3.c3 + Join Filter: (t1.c1 = t2.c1) + -> Nested Loop Left Join + Output: t3.c3, t2.c2, t2.c1 + Join Filter: (t2.c1 = t3.c1) + -> Foreign Scan on public.ft4 t3 + Output: t3.c1, t3.c2, t3.c3 + InfluxDB query: SELECT "c1", "c3" FROM "T3" + -> Materialize + Output: t2.c2, t2.c1 + -> Foreign Scan on public.ft2 t2 + Output: t2.c2, t2.c1 + InfluxDB query: SELECT "C 1", "c2" FROM "T1" + -> Materialize + Output: t1.c1 + -> Foreign Scan on public.ft2 t1 + Output: t1.c1 + InfluxDB query: SELECT "C 1" FROM "T1" +(21 rows) + +--Testcase 130: +SELECT t1.c1, t2.c2, t3.c3 FROM ft2 t1 RIGHT JOIN ft2 t2 ON (t1.c1 = t2.c1) RIGHT JOIN ft4 t3 ON (t2.c1 = t3.c1) OFFSET 10 LIMIT 10; + c1 | c2 | c3 +----+----+-------- + 22 | 2 | AAA022 + 24 | 4 | AAA024 + 26 | 6 | AAA026 + 28 | 8 | AAA028 + 30 | 0 | AAA030 + 32 | 2 | AAA032 + 34 | 4 | AAA034 + 36 | 6 | AAA036 + 38 | 8 | AAA038 + 40 | 0 | AAA040 +(10 rows) + +-- full outer join +--Testcase 131: +EXPLAIN (VERBOSE, COSTS OFF) +SELECT t1.c1, t2.c1 FROM ft4 t1 FULL JOIN ft5 t2 ON (t1.c1 = t2.c1) ORDER BY t1.c1, t2.c1 OFFSET 45 LIMIT 10; + QUERY PLAN +----------------------------------------------------------------- + Limit + Output: t1.c1, t2.c1 + -> Sort + Output: t1.c1, t2.c1 + Sort Key: t1.c1, t2.c1 + -> Merge Full Join + Output: t1.c1, t2.c1 + Merge Cond: (t1.c1 = t2.c1) + -> Sort + Output: t1.c1 + Sort Key: t1.c1 + -> Foreign Scan on public.ft4 t1 + Output: t1.c1 + InfluxDB query: SELECT "c1" FROM "T3" + -> Sort + Output: t2.c1 + Sort Key: t2.c1 + -> Foreign Scan on public.ft5 t2 + Output: t2.c1 + InfluxDB query: SELECT "c1" FROM "T4" +(20 rows) + +--Testcase 132: +SELECT t1.c1, t2.c1 FROM ft4 t1 FULL JOIN ft5 t2 ON (t1.c1 = t2.c1) ORDER BY t1.c1, t2.c1 OFFSET 45 LIMIT 10; + c1 | c1 +-----+---- + 92 | + 94 | + 96 | 96 + 98 | + 100 | + | 3 + | 9 + | 15 + | 21 + | 27 +(10 rows) + +-- full outer join with restrictions on the joining relations +-- a. the joining relations are both base relations +--Testcase 133: +EXPLAIN (VERBOSE, COSTS OFF) +SELECT t1.c1, t2.c1 FROM (SELECT c1 FROM ft4 WHERE c1 between 50 and 60) t1 FULL JOIN (SELECT c1 FROM ft5 WHERE c1 between 50 and 60) t2 ON (t1.c1 = t2.c1) ORDER BY t1.c1, t2.c1; + QUERY PLAN +--------------------------------------------------------------------------------------------------- + Sort + Output: ft4.c1, ft5.c1 + Sort Key: ft4.c1, ft5.c1 + -> Hash Full Join + Output: ft4.c1, ft5.c1 + Hash Cond: (ft4.c1 = ft5.c1) + -> Foreign Scan on public.ft4 + Output: ft4.c1, ft4.c2, ft4.c3 + InfluxDB query: SELECT "c1" FROM "T3" WHERE (("c1" >= 50)) AND (("c1" <= 60)) + -> Hash + Output: ft5.c1 + -> Foreign Scan on public.ft5 + Output: ft5.c1 + InfluxDB query: SELECT "c1" FROM "T4" WHERE (("c1" >= 50)) AND (("c1" <= 60)) +(14 rows) + +--Testcase 134: +SELECT t1.c1, t2.c1 FROM (SELECT c1 FROM ft4 WHERE c1 between 50 and 60) t1 FULL JOIN (SELECT c1 FROM ft5 WHERE c1 between 50 and 60) t2 ON (t1.c1 = t2.c1) ORDER BY t1.c1, t2.c1; + c1 | c1 +----+---- + 50 | + 52 | + 54 | 54 + 56 | + 58 | + 60 | 60 + | 51 + | 57 +(8 rows) + +--Testcase 135: +EXPLAIN (VERBOSE, COSTS OFF) +SELECT 1 FROM (SELECT c1 FROM ft4 WHERE c1 between 50 and 60) t1 FULL JOIN (SELECT c1 FROM ft5 WHERE c1 between 50 and 60) t2 ON (TRUE) OFFSET 10 LIMIT 10; + QUERY PLAN +------------------------------------------------------------------------------------------------ + Limit + Output: 1 + -> Merge Full Join + Output: 1 + -> Foreign Scan on public.ft4 + Output: ft4.c1, ft4.c2, ft4.c3 + InfluxDB query: SELECT * FROM "T3" WHERE (("c1" >= 50)) AND (("c1" <= 60)) + -> Materialize + Output: ft5.c1, ft5.c2, ft5.c3 + -> Foreign Scan on public.ft5 + Output: ft5.c1, ft5.c2, ft5.c3 + InfluxDB query: SELECT * FROM "T4" WHERE (("c1" >= 50)) AND (("c1" <= 60)) +(12 rows) + +--Testcase 136: +SELECT 1 FROM (SELECT c1 FROM ft4 WHERE c1 between 50 and 60) t1 FULL JOIN (SELECT c1 FROM ft5 WHERE c1 between 50 and 60) t2 ON (TRUE) OFFSET 10 LIMIT 10; + ?column? +---------- + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 1 +(10 rows) + +-- b. one of the joining relations is a base relation and the other is a join +-- relation +--Testcase 137: +EXPLAIN (VERBOSE, COSTS OFF) +SELECT t1.c1, ss.a, ss.b FROM (SELECT c1 FROM ft4 WHERE c1 between 50 and 60) t1 FULL JOIN (SELECT t2.c1, t3.c1 FROM ft4 t2 LEFT JOIN ft5 t3 ON (t2.c1 = t3.c1) WHERE (t2.c1 between 50 and 60)) ss(a, b) ON (t1.c1 = ss.a) ORDER BY t1.c1, ss.a, ss.b; + QUERY PLAN +--------------------------------------------------------------------------------------------------------- + Sort + Output: ft4.c1, t2.c1, t3.c1 + Sort Key: ft4.c1, t2.c1, t3.c1 + -> Hash Full Join + Output: ft4.c1, t2.c1, t3.c1 + Hash Cond: (t2.c1 = ft4.c1) + -> Hash Right Join + Output: t2.c1, t3.c1 + Hash Cond: (t3.c1 = t2.c1) + -> Foreign Scan on public.ft5 t3 + Output: t3.c1, t3.c2, t3.c3 + InfluxDB query: SELECT "c1" FROM "T4" + -> Hash + Output: t2.c1 + -> Foreign Scan on public.ft4 t2 + Output: t2.c1 + InfluxDB query: SELECT "c1" FROM "T3" WHERE (("c1" >= 50)) AND (("c1" <= 60)) + -> Hash + Output: ft4.c1 + -> Foreign Scan on public.ft4 + Output: ft4.c1 + InfluxDB query: SELECT "c1" FROM "T3" WHERE (("c1" >= 50)) AND (("c1" <= 60)) +(22 rows) + +--Testcase 138: +SELECT t1.c1, ss.a, ss.b FROM (SELECT c1 FROM ft4 WHERE c1 between 50 and 60) t1 FULL JOIN (SELECT t2.c1, t3.c1 FROM ft4 t2 LEFT JOIN ft5 t3 ON (t2.c1 = t3.c1) WHERE (t2.c1 between 50 and 60)) ss(a, b) ON (t1.c1 = ss.a) ORDER BY t1.c1, ss.a, ss.b; + c1 | a | b +----+----+---- + 50 | 50 | + 52 | 52 | + 54 | 54 | 54 + 56 | 56 | + 58 | 58 | + 60 | 60 | 60 +(6 rows) + +-- c. test deparsing the remote query as nested subqueries +--Testcase 139: +EXPLAIN (VERBOSE, COSTS OFF) +SELECT t1.c1, ss.a, ss.b FROM (SELECT c1 FROM ft4 WHERE c1 between 50 and 60) t1 FULL JOIN (SELECT t2.c1, t3.c1 FROM (SELECT c1 FROM ft4 WHERE c1 between 50 and 60) t2 FULL JOIN (SELECT c1 FROM ft5 WHERE c1 between 50 and 60) t3 ON (t2.c1 = t3.c1) WHERE t2.c1 IS NULL OR t2.c1 IS NOT NULL) ss(a, b) ON (t1.c1 = ss.a) ORDER BY t1.c1, ss.a, ss.b; + QUERY PLAN +--------------------------------------------------------------------------------------------------------- + Sort + Output: ft4.c1, ft4_1.c1, ft5.c1 + Sort Key: ft4.c1, ft4_1.c1, ft5.c1 + -> Hash Full Join + Output: ft4.c1, ft4_1.c1, ft5.c1 + Hash Cond: (ft4_1.c1 = ft4.c1) + -> Hash Full Join + Output: ft4_1.c1, ft5.c1 + Hash Cond: (ft4_1.c1 = ft5.c1) + Filter: ((ft4_1.c1 IS NULL) OR (ft4_1.c1 IS NOT NULL)) + -> Foreign Scan on public.ft4 ft4_1 + Output: ft4_1.c1, ft4_1.c2, ft4_1.c3 + InfluxDB query: SELECT "c1" FROM "T3" WHERE (("c1" >= 50)) AND (("c1" <= 60)) + -> Hash + Output: ft5.c1 + -> Foreign Scan on public.ft5 + Output: ft5.c1 + InfluxDB query: SELECT "c1" FROM "T4" WHERE (("c1" >= 50)) AND (("c1" <= 60)) + -> Hash + Output: ft4.c1 + -> Foreign Scan on public.ft4 + Output: ft4.c1 + InfluxDB query: SELECT "c1" FROM "T3" WHERE (("c1" >= 50)) AND (("c1" <= 60)) +(23 rows) + +--Testcase 140: +SELECT t1.c1, ss.a, ss.b FROM (SELECT c1 FROM ft4 WHERE c1 between 50 and 60) t1 FULL JOIN (SELECT t2.c1, t3.c1 FROM (SELECT c1 FROM ft4 WHERE c1 between 50 and 60) t2 FULL JOIN (SELECT c1 FROM ft5 WHERE c1 between 50 and 60) t3 ON (t2.c1 = t3.c1) WHERE t2.c1 IS NULL OR t2.c1 IS NOT NULL) ss(a, b) ON (t1.c1 = ss.a) ORDER BY t1.c1, ss.a, ss.b; + c1 | a | b +----+----+---- + 50 | 50 | + 52 | 52 | + 54 | 54 | 54 + 56 | 56 | + 58 | 58 | + 60 | 60 | 60 + | | 51 + | | 57 +(8 rows) + +-- d. test deparsing rowmarked relations as subqueries +--Testcase 141: +EXPLAIN (VERBOSE, COSTS OFF) +SELECT t1.c1, ss.a, ss.b FROM (SELECT c1 FROM "S 1"."T 3" WHERE c1 = 50) t1 INNER JOIN (SELECT t2.c1, t3.c1 FROM (SELECT c1 FROM ft4 WHERE c1 between 50 and 60) t2 FULL JOIN (SELECT c1 FROM ft5 WHERE c1 between 50 and 60) t3 ON (t2.c1 = t3.c1) WHERE t2.c1 IS NULL OR t2.c1 IS NOT NULL) ss(a, b) ON (TRUE) ORDER BY t1.c1, ss.a, ss.b FOR UPDATE OF t1; + QUERY PLAN +--------------------------------------------------------------------------------------------------------------------------------- + LockRows + Output: "T 3".c1, ft4.c1, ft5.c1, "T 3".*, ft4.*, ft5.* + -> Sort + Output: "T 3".c1, ft4.c1, ft5.c1, "T 3".*, ft4.*, ft5.* + Sort Key: ft4.c1, ft5.c1 + -> Nested Loop + Output: "T 3".c1, ft4.c1, ft5.c1, "T 3".*, ft4.*, ft5.* + -> Foreign Scan on "S 1"."T 3" + Output: "T 3".c1, "T 3".* + InfluxDB query: SELECT "c1", "c2", "c3" FROM "T3" WHERE (("c1" = 50)) + -> Materialize + Output: ft4.c1, ft4.*, ft5.c1, ft5.* + -> Merge Full Join + Output: ft4.c1, ft4.*, ft5.c1, ft5.* + Merge Cond: (ft4.c1 = ft5.c1) + Filter: ((ft4.c1 IS NULL) OR (ft4.c1 IS NOT NULL)) + -> Sort + Output: ft4.c1, ft4.* + Sort Key: ft4.c1 + -> Foreign Scan on public.ft4 + Output: ft4.c1, ft4.* + InfluxDB query: SELECT "c1", "c2", "c3" FROM "T3" WHERE (("c1" >= 50)) AND (("c1" <= 60)) + -> Sort + Output: ft5.c1, ft5.* + Sort Key: ft5.c1 + -> Foreign Scan on public.ft5 + Output: ft5.c1, ft5.* + InfluxDB query: SELECT "c1", "c2", "c3" FROM "T4" WHERE (("c1" >= 50)) AND (("c1" <= 60)) +(28 rows) + +--Testcase 142: +SELECT t1.c1, ss.a, ss.b FROM (SELECT c1 FROM "S 1"."T 3" WHERE c1 = 50) t1 INNER JOIN (SELECT t2.c1, t3.c1 FROM (SELECT c1 FROM ft4 WHERE c1 between 50 and 60) t2 FULL JOIN (SELECT c1 FROM ft5 WHERE c1 between 50 and 60) t3 ON (t2.c1 = t3.c1) WHERE t2.c1 IS NULL OR t2.c1 IS NOT NULL) ss(a, b) ON (TRUE) ORDER BY t1.c1, ss.a, ss.b FOR UPDATE OF t1; + c1 | a | b +----+----+---- + 50 | 50 | + 50 | 52 | + 50 | 54 | 54 + 50 | 56 | + 50 | 58 | + 50 | 60 | 60 + 50 | | 51 + 50 | | 57 +(8 rows) + +-- full outer join + inner join +--Testcase 143: +EXPLAIN (VERBOSE, COSTS OFF) +SELECT t1.c1, t2.c1, t3.c1 FROM ft4 t1 INNER JOIN ft5 t2 ON (t1.c1 = t2.c1 + 1 and t1.c1 between 50 and 60) FULL JOIN ft4 t3 ON (t2.c1 = t3.c1) ORDER BY t1.c1, t2.c1, t3.c1 LIMIT 10; + QUERY PLAN +--------------------------------------------------------------------------------------------------------------------- + Limit + Output: t1.c1, t2.c1, t3.c1 + -> Sort + Output: t1.c1, t2.c1, t3.c1 + Sort Key: t1.c1, t2.c1, t3.c1 + -> Hash Full Join + Output: t1.c1, t2.c1, t3.c1 + Hash Cond: (t3.c1 = t2.c1) + -> Foreign Scan on public.ft4 t3 + Output: t3.c1, t3.c2, t3.c3 + InfluxDB query: SELECT "c1" FROM "T3" + -> Hash + Output: t1.c1, t2.c1 + -> Hash Join + Output: t1.c1, t2.c1 + Hash Cond: ((t2.c1 + 1) = t1.c1) + -> Foreign Scan on public.ft5 t2 + Output: t2.c1, t2.c2, t2.c3 + InfluxDB query: SELECT "c1" FROM "T4" + -> Hash + Output: t1.c1 + -> Foreign Scan on public.ft4 t1 + Output: t1.c1 + InfluxDB query: SELECT "c1" FROM "T3" WHERE (("c1" >= 50)) AND (("c1" <= 60)) +(24 rows) + +--Testcase 144: +SELECT t1.c1, t2.c1, t3.c1 FROM ft4 t1 INNER JOIN ft5 t2 ON (t1.c1 = t2.c1 + 1 and t1.c1 between 50 and 60) FULL JOIN ft4 t3 ON (t2.c1 = t3.c1) ORDER BY t1.c1, t2.c1, t3.c1 LIMIT 10; + c1 | c1 | c1 +----+----+---- + 52 | 51 | + 58 | 57 | + | | 2 + | | 4 + | | 6 + | | 8 + | | 10 + | | 12 + | | 14 + | | 16 +(10 rows) + +-- full outer join three tables +--Testcase 145: +EXPLAIN (VERBOSE, COSTS OFF) +SELECT t1.c1, t2.c2, t3.c3 FROM ft2 t1 FULL JOIN ft2 t2 ON (t1.c1 = t2.c1) FULL JOIN ft4 t3 ON (t2.c1 = t3.c1) OFFSET 10 LIMIT 10; + QUERY PLAN +------------------------------------------------------------------------ + Limit + Output: t1.c1, t2.c2, t3.c3 + -> Hash Full Join + Output: t1.c1, t2.c2, t3.c3 + Hash Cond: (t2.c1 = t3.c1) + -> Hash Full Join + Output: t1.c1, t2.c2, t2.c1 + Hash Cond: (t1.c1 = t2.c1) + -> Foreign Scan on public.ft2 t1 + Output: t1.c1 + InfluxDB query: SELECT "C 1" FROM "T1" + -> Hash + Output: t2.c2, t2.c1 + -> Foreign Scan on public.ft2 t2 + Output: t2.c2, t2.c1 + InfluxDB query: SELECT "C 1", "c2" FROM "T1" + -> Hash + Output: t3.c3, t3.c1 + -> Foreign Scan on public.ft4 t3 + Output: t3.c3, t3.c1 + InfluxDB query: SELECT "c1", "c3" FROM "T3" +(21 rows) + +--Testcase 146: +SELECT t1.c1, t2.c2, t3.c3 FROM ft2 t1 FULL JOIN ft2 t2 ON (t1.c1 = t2.c1) FULL JOIN ft4 t3 ON (t2.c1 = t3.c1) ORDER BY t1.c1 OFFSET 10 LIMIT 10; + c1 | c2 | c3 +----+----+-------- + 11 | 1 | + 12 | 2 | AAA012 + 13 | 3 | + 14 | 4 | AAA014 + 15 | 5 | + 16 | 6 | AAA016 + 17 | 7 | + 18 | 8 | AAA018 + 19 | 9 | + 20 | 0 | AAA020 +(10 rows) + +-- full outer join + right outer join +--Testcase 147: +EXPLAIN (VERBOSE, COSTS OFF) +SELECT t1.c1, t2.c2, t3.c3 FROM ft2 t1 FULL JOIN ft2 t2 ON (t1.c1 = t2.c1) RIGHT JOIN ft4 t3 ON (t2.c1 = t3.c1) OFFSET 10 LIMIT 10; + QUERY PLAN +------------------------------------------------------------------------ + Limit + Output: t1.c1, t2.c2, t3.c3 + -> Nested Loop Left Join + Output: t1.c1, t2.c2, t3.c3 + Join Filter: (t1.c1 = t2.c1) + -> Nested Loop Left Join + Output: t3.c3, t2.c2, t2.c1 + Join Filter: (t2.c1 = t3.c1) + -> Foreign Scan on public.ft4 t3 + Output: t3.c1, t3.c2, t3.c3 + InfluxDB query: SELECT "c1", "c3" FROM "T3" + -> Materialize + Output: t2.c2, t2.c1 + -> Foreign Scan on public.ft2 t2 + Output: t2.c2, t2.c1 + InfluxDB query: SELECT "C 1", "c2" FROM "T1" + -> Materialize + Output: t1.c1 + -> Foreign Scan on public.ft2 t1 + Output: t1.c1 + InfluxDB query: SELECT "C 1" FROM "T1" +(21 rows) + +--Testcase 148: +SELECT t1.c1, t2.c2, t3.c3 FROM ft2 t1 FULL JOIN ft2 t2 ON (t1.c1 = t2.c1) RIGHT JOIN ft4 t3 ON (t2.c1 = t3.c1) OFFSET 10 LIMIT 10; + c1 | c2 | c3 +----+----+-------- + 22 | 2 | AAA022 + 24 | 4 | AAA024 + 26 | 6 | AAA026 + 28 | 8 | AAA028 + 30 | 0 | AAA030 + 32 | 2 | AAA032 + 34 | 4 | AAA034 + 36 | 6 | AAA036 + 38 | 8 | AAA038 + 40 | 0 | AAA040 +(10 rows) + +-- right outer join + full outer join +--Testcase 149: +EXPLAIN (VERBOSE, COSTS OFF) +SELECT t1.c1, t2.c2, t3.c3 FROM ft2 t1 RIGHT JOIN ft2 t2 ON (t1.c1 = t2.c1) FULL JOIN ft4 t3 ON (t2.c1 = t3.c1) OFFSET 10 LIMIT 10; + QUERY PLAN +------------------------------------------------------------------ + Limit + Output: t1.c1, t2.c2, t3.c3 + -> Hash Full Join + Output: t1.c1, t2.c2, t3.c3 + Hash Cond: (t2.c1 = t3.c1) + -> Nested Loop Left Join + Output: t2.c2, t2.c1, t1.c1 + Join Filter: (t1.c1 = t2.c1) + -> Foreign Scan on public.ft2 t2 + Output: t2.c2, t2.c1 + InfluxDB query: SELECT "C 1", "c2" FROM "T1" + -> Materialize + Output: t1.c1 + -> Foreign Scan on public.ft2 t1 + Output: t1.c1 + InfluxDB query: SELECT "C 1" FROM "T1" + -> Hash + Output: t3.c3, t3.c1 + -> Foreign Scan on public.ft4 t3 + Output: t3.c3, t3.c1 + InfluxDB query: SELECT "c1", "c3" FROM "T3" +(21 rows) + +--Testcase 150: +SELECT t1.c1, t2.c2, t3.c3 FROM ft2 t1 RIGHT JOIN ft2 t2 ON (t1.c1 = t2.c1) FULL JOIN ft4 t3 ON (t2.c1 = t3.c1) ORDER BY t1.c1 OFFSET 10 LIMIT 10; + c1 | c2 | c3 +----+----+-------- + 11 | 1 | + 12 | 2 | AAA012 + 13 | 3 | + 14 | 4 | AAA014 + 15 | 5 | + 16 | 6 | AAA016 + 17 | 7 | + 18 | 8 | AAA018 + 19 | 9 | + 20 | 0 | AAA020 +(10 rows) + +-- full outer join + left outer join +--Testcase 151: +EXPLAIN (VERBOSE, COSTS OFF) +SELECT t1.c1, t2.c2, t3.c3 FROM ft2 t1 FULL JOIN ft2 t2 ON (t1.c1 = t2.c1) LEFT JOIN ft4 t3 ON (t2.c1 = t3.c1) OFFSET 10 LIMIT 10; + QUERY PLAN +------------------------------------------------------------------------ + Limit + Output: t1.c1, t2.c2, t3.c3 + -> Nested Loop Left Join + Output: t1.c1, t2.c2, t3.c3 + Join Filter: (t2.c1 = t3.c1) + -> Hash Full Join + Output: t1.c1, t2.c2, t2.c1 + Hash Cond: (t1.c1 = t2.c1) + -> Foreign Scan on public.ft2 t1 + Output: t1.c1 + InfluxDB query: SELECT "C 1" FROM "T1" + -> Hash + Output: t2.c2, t2.c1 + -> Foreign Scan on public.ft2 t2 + Output: t2.c2, t2.c1 + InfluxDB query: SELECT "C 1", "c2" FROM "T1" + -> Materialize + Output: t3.c3, t3.c1 + -> Foreign Scan on public.ft4 t3 + Output: t3.c3, t3.c1 + InfluxDB query: SELECT "c1", "c3" FROM "T3" +(21 rows) + +--Testcase 152: +SELECT t1.c1, t2.c2, t3.c3 FROM ft2 t1 FULL JOIN ft2 t2 ON (t1.c1 = t2.c1) LEFT JOIN ft4 t3 ON (t2.c1 = t3.c1) ORDER BY t1.c1 OFFSET 10 LIMIT 10; + c1 | c2 | c3 +----+----+-------- + 11 | 1 | + 12 | 2 | AAA012 + 13 | 3 | + 14 | 4 | AAA014 + 15 | 5 | + 16 | 6 | AAA016 + 17 | 7 | + 18 | 8 | AAA018 + 19 | 9 | + 20 | 0 | AAA020 +(10 rows) + +-- left outer join + full outer join +--Testcase 153: +EXPLAIN (VERBOSE, COSTS OFF) +SELECT t1.c1, t2.c2, t3.c3 FROM ft2 t1 LEFT JOIN ft2 t2 ON (t1.c1 = t2.c1) FULL JOIN ft4 t3 ON (t2.c1 = t3.c1) OFFSET 10 LIMIT 10; + QUERY PLAN +------------------------------------------------------------------------ + Limit + Output: t1.c1, t2.c2, t3.c3 + -> Hash Full Join + Output: t1.c1, t2.c2, t3.c3 + Hash Cond: (t2.c1 = t3.c1) + -> Nested Loop Left Join + Output: t1.c1, t2.c2, t2.c1 + Join Filter: (t1.c1 = t2.c1) + -> Foreign Scan on public.ft2 t1 + Output: t1.c1 + InfluxDB query: SELECT "C 1" FROM "T1" + -> Materialize + Output: t2.c2, t2.c1 + -> Foreign Scan on public.ft2 t2 + Output: t2.c2, t2.c1 + InfluxDB query: SELECT "C 1", "c2" FROM "T1" + -> Hash + Output: t3.c3, t3.c1 + -> Foreign Scan on public.ft4 t3 + Output: t3.c3, t3.c1 + InfluxDB query: SELECT "c1", "c3" FROM "T3" +(21 rows) + +--Testcase 154: +SELECT t1.c1, t2.c2, t3.c3 FROM ft2 t1 LEFT JOIN ft2 t2 ON (t1.c1 = t2.c1) FULL JOIN ft4 t3 ON (t2.c1 = t3.c1) ORDER BY t1.c1 OFFSET 10 LIMIT 10; + c1 | c2 | c3 +----+----+-------- + 11 | 1 | + 12 | 2 | AAA012 + 13 | 3 | + 14 | 4 | AAA014 + 15 | 5 | + 16 | 6 | AAA016 + 17 | 7 | + 18 | 8 | AAA018 + 19 | 9 | + 20 | 0 | AAA020 +(10 rows) + +--Testcase 155: +SET enable_memoize TO off; +-- right outer join + left outer join +--Testcase 156: +EXPLAIN (VERBOSE, COSTS OFF) +SELECT t1.c1, t2.c2, t3.c3 FROM ft2 t1 RIGHT JOIN ft2 t2 ON (t1.c1 = t2.c1) LEFT JOIN ft4 t3 ON (t2.c1 = t3.c1) OFFSET 10 LIMIT 10; + QUERY PLAN +----------------------------------------------------------------------- + Limit + Output: t1.c1, t2.c2, t3.c3 + -> Nested Loop Left Join + Output: t1.c1, t2.c2, t3.c3 + Join Filter: (t1.c1 = t2.c1) + -> Nested Loop Left Join + Output: t2.c2, t2.c1, t3.c3 + Join Filter: (t2.c1 = t3.c1) + -> Foreign Scan on public.ft2 t2 + Output: t2.c2, t2.c1 + InfluxDB query: SELECT "C 1", "c2" FROM "T1" + -> Materialize + Output: t3.c3, t3.c1 + -> Foreign Scan on public.ft4 t3 + Output: t3.c3, t3.c1 + InfluxDB query: SELECT "c1", "c3" FROM "T3" + -> Materialize + Output: t1.c1 + -> Foreign Scan on public.ft2 t1 + Output: t1.c1 + InfluxDB query: SELECT "C 1" FROM "T1" +(21 rows) + +--Testcase 157: +SELECT t1.c1, t2.c2, t3.c3 FROM ft2 t1 RIGHT JOIN ft2 t2 ON (t1.c1 = t2.c1) LEFT JOIN ft4 t3 ON (t2.c1 = t3.c1) ORDER BY t1.c1 OFFSET 10 LIMIT 10; + c1 | c2 | c3 +----+----+-------- + 11 | 1 | + 12 | 2 | AAA012 + 13 | 3 | + 14 | 4 | AAA014 + 15 | 5 | + 16 | 6 | AAA016 + 17 | 7 | + 18 | 8 | AAA018 + 19 | 9 | + 20 | 0 | AAA020 +(10 rows) + +--Testcase 158: +RESET enable_memoize; +-- left outer join + right outer join +--Testcase 159: +EXPLAIN (VERBOSE, COSTS OFF) +SELECT t1.c1, t2.c2, t3.c3 FROM ft2 t1 LEFT JOIN ft2 t2 ON (t1.c1 = t2.c1) RIGHT JOIN ft4 t3 ON (t2.c1 = t3.c1) OFFSET 10 LIMIT 10; + QUERY PLAN +------------------------------------------------------------------------ + Limit + Output: t1.c1, t2.c2, t3.c3 + -> Hash Right Join + Output: t1.c1, t2.c2, t3.c3 + Hash Cond: (t2.c1 = t3.c1) + -> Nested Loop + Output: t1.c1, t2.c2, t2.c1 + Join Filter: (t1.c1 = t2.c1) + -> Foreign Scan on public.ft2 t1 + Output: t1.c1 + InfluxDB query: SELECT "C 1" FROM "T1" + -> Materialize + Output: t2.c2, t2.c1 + -> Foreign Scan on public.ft2 t2 + Output: t2.c2, t2.c1 + InfluxDB query: SELECT "C 1", "c2" FROM "T1" + -> Hash + Output: t3.c3, t3.c1 + -> Foreign Scan on public.ft4 t3 + Output: t3.c3, t3.c1 + InfluxDB query: SELECT "c1", "c3" FROM "T3" +(21 rows) + +--Testcase 160: +SELECT t1.c1, t2.c2, t3.c3 FROM ft2 t1 LEFT JOIN ft2 t2 ON (t1.c1 = t2.c1) RIGHT JOIN ft4 t3 ON (t2.c1 = t3.c1) ORDER BY t1.c1 OFFSET 10 LIMIT 10; + c1 | c2 | c3 +----+----+-------- + 22 | 2 | AAA022 + 24 | 4 | AAA024 + 26 | 6 | AAA026 + 28 | 8 | AAA028 + 30 | 0 | AAA030 + 32 | 2 | AAA032 + 34 | 4 | AAA034 + 36 | 6 | AAA036 + 38 | 8 | AAA038 + 40 | 0 | AAA040 +(10 rows) + +-- full outer join + WHERE clause, only matched rows +--Testcase 161: +EXPLAIN (VERBOSE, COSTS OFF) +SELECT t1.c1, t2.c1 FROM ft4 t1 FULL JOIN ft5 t2 ON (t1.c1 = t2.c1) WHERE (t1.c1 = t2.c1 OR t1.c1 IS NULL) ORDER BY t1.c1, t2.c1 OFFSET 10 LIMIT 10; + QUERY PLAN +----------------------------------------------------------------- + Limit + Output: t1.c1, t2.c1 + -> Sort + Output: t1.c1, t2.c1 + Sort Key: t1.c1, t2.c1 + -> Merge Full Join + Output: t1.c1, t2.c1 + Merge Cond: (t1.c1 = t2.c1) + Filter: ((t1.c1 = t2.c1) OR (t1.c1 IS NULL)) + -> Sort + Output: t1.c1 + Sort Key: t1.c1 + -> Foreign Scan on public.ft4 t1 + Output: t1.c1 + InfluxDB query: SELECT "c1" FROM "T3" + -> Sort + Output: t2.c1 + Sort Key: t2.c1 + -> Foreign Scan on public.ft5 t2 + Output: t2.c1 + InfluxDB query: SELECT "c1" FROM "T4" +(21 rows) + +--Testcase 162: +SELECT t1.c1, t2.c1 FROM ft4 t1 FULL JOIN ft5 t2 ON (t1.c1 = t2.c1) WHERE (t1.c1 = t2.c1 OR t1.c1 IS NULL) ORDER BY t1.c1, t2.c1 OFFSET 10 LIMIT 10; + c1 | c1 +----+---- + 66 | 66 + 72 | 72 + 78 | 78 + 84 | 84 + 90 | 90 + 96 | 96 + | 3 + | 9 + | 15 + | 21 +(10 rows) + +-- full outer join + WHERE clause with shippable extensions set +--Testcase 163: +EXPLAIN (VERBOSE, COSTS OFF) +SELECT t1.c1, t2.c2, t1.c3 FROM ft1 t1 FULL JOIN ft2 t2 ON (t1.c1 = t2.c1) WHERE influxdb_fdw_abs(t1.c1) > 0 OFFSET 10 LIMIT 10; + QUERY PLAN +------------------------------------------------------------------ + Limit + Output: t1.c1, t2.c2, t1.c3 + -> Hash Full Join + Output: t1.c1, t2.c2, t1.c3 + Hash Cond: (t2.c1 = t1.c1) + Filter: (influxdb_fdw_abs(t1.c1) > 0) + -> Foreign Scan on public.ft2 t2 + Output: t2.c2, t2.c1 + InfluxDB query: SELECT "C 1", "c2" FROM "T1" + -> Hash + Output: t1.c1, t1.c3 + -> Foreign Scan on public.ft1 t1 + Output: t1.c1, t1.c3 + InfluxDB query: SELECT "C 1", "c3" FROM "T1" +(14 rows) + +-- skip, influxdb does not have option 'extensions' +-- ALTER SERVER influxdb_svr OPTIONS (DROP extensions); +-- full outer join + WHERE clause with shippable extensions not set +-- EXPLAIN (VERBOSE, COSTS OFF) +-- SELECT t1.c1, t2.c2, t1.c3 FROM ft1 t1 FULL JOIN ft2 t2 ON (t1.c1 = t2.c1) WHERE influxdb_fdw_abs(t1.c1) > 0 OFFSET 10 LIMIT 10; +-- ALTER SERVER loopback OPTIONS (ADD extensions 'influxdb_fdw'); +-- join two tables with FOR UPDATE clause +-- tests whole-row reference for row marks +--Testcase 164: +EXPLAIN (VERBOSE, COSTS OFF) +SELECT t1.c1, t2.c1 FROM ft1 t1 JOIN ft2 t2 ON (t1.c1 = t2.c1) ORDER BY t1.c3, t1.c1 OFFSET 100 LIMIT 10 FOR UPDATE OF t1; + QUERY PLAN +------------------------------------------------------------------------------------------------------ + Limit + Output: t1.c1, t2.c1, t1.c3, t1.*, t2.* + -> LockRows + Output: t1.c1, t2.c1, t1.c3, t1.*, t2.* + -> Sort + Output: t1.c1, t2.c1, t1.c3, t1.*, t2.* + Sort Key: t1.c3, t1.c1 + -> Hash Join + Output: t1.c1, t2.c1, t1.c3, t1.*, t2.* + Hash Cond: (t2.c1 = t1.c1) + -> Foreign Scan on public.ft2 t2 + Output: t2.c1, t2.* + InfluxDB query: SELECT "C 1", "c2", "c3", "c6", "c7", "c8" FROM "T1" + -> Hash + Output: t1.c1, t1.c3, t1.* + -> Foreign Scan on public.ft1 t1 + Output: t1.c1, t1.c3, t1.* + InfluxDB query: SELECT "C 1", "c2", "c3", "c6", "c7", "c8" FROM "T1" +(18 rows) + +--Testcase 165: +SELECT t1.c1, t2.c1 FROM ft1 t1 JOIN ft2 t2 ON (t1.c1 = t2.c1) ORDER BY t1.c3, t1.c1 OFFSET 100 LIMIT 10 FOR UPDATE OF t1; + c1 | c1 +-----+----- + 101 | 101 + 102 | 102 + 103 | 103 + 104 | 104 + 105 | 105 + 106 | 106 + 107 | 107 + 108 | 108 + 109 | 109 + 110 | 110 +(10 rows) + +--Testcase 166: +EXPLAIN (VERBOSE, COSTS OFF) +SELECT t1.c1, t2.c1 FROM ft1 t1 JOIN ft2 t2 ON (t1.c1 = t2.c1) ORDER BY t1.c3, t1.c1 OFFSET 100 LIMIT 10 FOR UPDATE; + QUERY PLAN +------------------------------------------------------------------------------------------------------ + Limit + Output: t1.c1, t2.c1, t1.c3, t1.*, t2.* + -> LockRows + Output: t1.c1, t2.c1, t1.c3, t1.*, t2.* + -> Sort + Output: t1.c1, t2.c1, t1.c3, t1.*, t2.* + Sort Key: t1.c3, t1.c1 + -> Hash Join + Output: t1.c1, t2.c1, t1.c3, t1.*, t2.* + Hash Cond: (t2.c1 = t1.c1) + -> Foreign Scan on public.ft2 t2 + Output: t2.c1, t2.* + InfluxDB query: SELECT "C 1", "c2", "c3", "c6", "c7", "c8" FROM "T1" + -> Hash + Output: t1.c1, t1.c3, t1.* + -> Foreign Scan on public.ft1 t1 + Output: t1.c1, t1.c3, t1.* + InfluxDB query: SELECT "C 1", "c2", "c3", "c6", "c7", "c8" FROM "T1" +(18 rows) + +--Testcase 167: +SELECT t1.c1, t2.c1 FROM ft1 t1 JOIN ft2 t2 ON (t1.c1 = t2.c1) ORDER BY t1.c3, t1.c1 OFFSET 100 LIMIT 10 FOR UPDATE; + c1 | c1 +-----+----- + 101 | 101 + 102 | 102 + 103 | 103 + 104 | 104 + 105 | 105 + 106 | 106 + 107 | 107 + 108 | 108 + 109 | 109 + 110 | 110 +(10 rows) + +-- join two tables with FOR SHARE clause +--Testcase 168: +EXPLAIN (VERBOSE, COSTS OFF) +SELECT t1.c1, t2.c1 FROM ft1 t1 JOIN ft2 t2 ON (t1.c1 = t2.c1) ORDER BY t1.c3, t1.c1 OFFSET 100 LIMIT 10 FOR SHARE OF t1; + QUERY PLAN +------------------------------------------------------------------------------------------------------ + Limit + Output: t1.c1, t2.c1, t1.c3, t1.*, t2.* + -> LockRows + Output: t1.c1, t2.c1, t1.c3, t1.*, t2.* + -> Sort + Output: t1.c1, t2.c1, t1.c3, t1.*, t2.* + Sort Key: t1.c3, t1.c1 + -> Hash Join + Output: t1.c1, t2.c1, t1.c3, t1.*, t2.* + Hash Cond: (t2.c1 = t1.c1) + -> Foreign Scan on public.ft2 t2 + Output: t2.c1, t2.* + InfluxDB query: SELECT "C 1", "c2", "c3", "c6", "c7", "c8" FROM "T1" + -> Hash + Output: t1.c1, t1.c3, t1.* + -> Foreign Scan on public.ft1 t1 + Output: t1.c1, t1.c3, t1.* + InfluxDB query: SELECT "C 1", "c2", "c3", "c6", "c7", "c8" FROM "T1" +(18 rows) + +--Testcase 169: +SELECT t1.c1, t2.c1 FROM ft1 t1 JOIN ft2 t2 ON (t1.c1 = t2.c1) ORDER BY t1.c3, t1.c1 OFFSET 100 LIMIT 10 FOR SHARE OF t1; + c1 | c1 +-----+----- + 101 | 101 + 102 | 102 + 103 | 103 + 104 | 104 + 105 | 105 + 106 | 106 + 107 | 107 + 108 | 108 + 109 | 109 + 110 | 110 +(10 rows) + +--Testcase 170: +EXPLAIN (VERBOSE, COSTS OFF) +SELECT t1.c1, t2.c1 FROM ft1 t1 JOIN ft2 t2 ON (t1.c1 = t2.c1) ORDER BY t1.c3, t1.c1 OFFSET 100 LIMIT 10 FOR SHARE; + QUERY PLAN +------------------------------------------------------------------------------------------------------ + Limit + Output: t1.c1, t2.c1, t1.c3, t1.*, t2.* + -> LockRows + Output: t1.c1, t2.c1, t1.c3, t1.*, t2.* + -> Sort + Output: t1.c1, t2.c1, t1.c3, t1.*, t2.* + Sort Key: t1.c3, t1.c1 + -> Hash Join + Output: t1.c1, t2.c1, t1.c3, t1.*, t2.* + Hash Cond: (t2.c1 = t1.c1) + -> Foreign Scan on public.ft2 t2 + Output: t2.c1, t2.* + InfluxDB query: SELECT "C 1", "c2", "c3", "c6", "c7", "c8" FROM "T1" + -> Hash + Output: t1.c1, t1.c3, t1.* + -> Foreign Scan on public.ft1 t1 + Output: t1.c1, t1.c3, t1.* + InfluxDB query: SELECT "C 1", "c2", "c3", "c6", "c7", "c8" FROM "T1" +(18 rows) + +--Testcase 171: +SELECT t1.c1, t2.c1 FROM ft1 t1 JOIN ft2 t2 ON (t1.c1 = t2.c1) ORDER BY t1.c3, t1.c1 OFFSET 100 LIMIT 10 FOR SHARE; + c1 | c1 +-----+----- + 101 | 101 + 102 | 102 + 103 | 103 + 104 | 104 + 105 | 105 + 106 | 106 + 107 | 107 + 108 | 108 + 109 | 109 + 110 | 110 +(10 rows) + +-- join in CTE +--Testcase 172: +EXPLAIN (VERBOSE, COSTS OFF) +WITH t (c1_1, c1_3, c2_1) AS MATERIALIZED (SELECT t1.c1, t1.c3, t2.c1 FROM ft1 t1 JOIN ft2 t2 ON (t1.c1 = t2.c1)) SELECT c1_1, c2_1 FROM t ORDER BY c1_3, c1_1 OFFSET 100 LIMIT 10; + QUERY PLAN +-------------------------------------------------------------------- + Limit + Output: t.c1_1, t.c2_1, t.c1_3 + CTE t + -> Merge Join + Output: t1.c1, t1.c3, t2.c1 + Merge Cond: (t1.c1 = t2.c1) + -> Sort + Output: t1.c1, t1.c3 + Sort Key: t1.c1 + -> Foreign Scan on public.ft1 t1 + Output: t1.c1, t1.c3 + InfluxDB query: SELECT "C 1", "c3" FROM "T1" + -> Sort + Output: t2.c1 + Sort Key: t2.c1 + -> Foreign Scan on public.ft2 t2 + Output: t2.c1 + InfluxDB query: SELECT "C 1" FROM "T1" + -> Sort + Output: t.c1_1, t.c2_1, t.c1_3 + Sort Key: t.c1_3, t.c1_1 + -> CTE Scan on t + Output: t.c1_1, t.c2_1, t.c1_3 +(23 rows) + +--Testcase 173: +WITH t (c1_1, c1_3, c2_1) AS MATERIALIZED (SELECT t1.c1, t1.c3, t2.c1 FROM ft1 t1 JOIN ft2 t2 ON (t1.c1 = t2.c1)) SELECT c1_1, c2_1 FROM t ORDER BY c1_3, c1_1 OFFSET 100 LIMIT 10; + c1_1 | c2_1 +------+------ + 101 | 101 + 102 | 102 + 103 | 103 + 104 | 104 + 105 | 105 + 106 | 106 + 107 | 107 + 108 | 108 + 109 | 109 + 110 | 110 +(10 rows) + +-- ctid with whole-row reference +--Testcase 174: +EXPLAIN (VERBOSE, COSTS OFF) +SELECT t1.ctid, t1, t2, t1.c1 FROM ft1 t1 JOIN ft2 t2 ON (t1.c1 = t2.c1) ORDER BY t1.c3, t1.c1 OFFSET 100 LIMIT 10; + QUERY PLAN +------------------------------------------------------------------------------------------------ + Limit + Output: t1.ctid, t1.*, t2.*, t1.c1, t1.c3 + -> Sort + Output: t1.ctid, t1.*, t2.*, t1.c1, t1.c3 + Sort Key: t1.c3, t1.c1 + -> Hash Join + Output: t1.ctid, t1.*, t2.*, t1.c1, t1.c3 + Hash Cond: (t2.c1 = t1.c1) + -> Foreign Scan on public.ft2 t2 + Output: t2.*, t2.c1 + InfluxDB query: SELECT "C 1", "c2", "c3", "c6", "c7", "c8" FROM "T1" + -> Hash + Output: t1.ctid, t1.*, t1.c1, t1.c3 + -> Foreign Scan on public.ft1 t1 + Output: t1.ctid, t1.*, t1.c1, t1.c3 + InfluxDB query: SELECT "C 1", "c2", "c3", "c6", "c7", "c8" FROM "T1" +(16 rows) + +-- SEMI JOIN, not pushed down +--Testcase 175: +EXPLAIN (VERBOSE, COSTS OFF) +SELECT t1.c1 FROM ft1 t1 WHERE EXISTS (SELECT 1 FROM ft2 t2 WHERE t1.c1 = t2.c1) ORDER BY t1.c1 OFFSET 100 LIMIT 10; + QUERY PLAN +------------------------------------------------------------------------ + Limit + Output: t1.c1 + -> Sort + Output: t1.c1 + Sort Key: t1.c1 + -> Hash Join + Output: t1.c1 + Inner Unique: true + Hash Cond: (t1.c1 = t2.c1) + -> Foreign Scan on public.ft1 t1 + Output: t1.c1 + InfluxDB query: SELECT "C 1" FROM "T1" + -> Hash + Output: t2.c1 + -> HashAggregate + Output: t2.c1 + Group Key: t2.c1 + -> Foreign Scan on public.ft2 t2 + Output: t2.c1 + InfluxDB query: SELECT "C 1" FROM "T1" +(20 rows) + +--Testcase 176: +SELECT t1.c1 FROM ft1 t1 WHERE EXISTS (SELECT 1 FROM ft2 t2 WHERE t1.c1 = t2.c1) ORDER BY t1.c1 OFFSET 100 LIMIT 10; + c1 +----- + 101 + 102 + 103 + 104 + 105 + 106 + 107 + 108 + 109 + 110 +(10 rows) + +-- ANTI JOIN, not pushed down +--Testcase 177: +EXPLAIN (VERBOSE, COSTS OFF) +SELECT t1.c1 FROM ft1 t1 WHERE NOT EXISTS (SELECT 1 FROM ft2 t2 WHERE t1.c1 = t2.c2) ORDER BY t1.c1 OFFSET 100 LIMIT 10; + QUERY PLAN +----------------------------------------------------------------- + Limit + Output: t1.c1 + -> Sort + Output: t1.c1 + Sort Key: t1.c1 + -> Hash Anti Join + Output: t1.c1 + Hash Cond: (t1.c1 = t2.c2) + -> Foreign Scan on public.ft1 t1 + Output: t1.c1 + InfluxDB query: SELECT "C 1" FROM "T1" + -> Hash + Output: t2.c2 + -> Foreign Scan on public.ft2 t2 + Output: t2.c2 + InfluxDB query: SELECT "c2" FROM "T1" +(16 rows) + +--Testcase 178: +SELECT t1.c1 FROM ft1 t1 WHERE NOT EXISTS (SELECT 1 FROM ft2 t2 WHERE t1.c1 = t2.c2) ORDER BY t1.c1 OFFSET 100 LIMIT 10; + c1 +----- + 110 + 111 + 112 + 113 + 114 + 115 + 116 + 117 + 118 + 119 +(10 rows) + +-- CROSS JOIN can be pushed down +--Testcase 179: +EXPLAIN (VERBOSE, COSTS OFF) +SELECT t1.c1, t2.c1 FROM ft1 t1 CROSS JOIN ft2 t2 ORDER BY t1.c1, t2.c1 OFFSET 100 LIMIT 10; + QUERY PLAN +------------------------------------------------------------------ + Limit + Output: t1.c1, t2.c1 + -> Sort + Output: t1.c1, t2.c1 + Sort Key: t1.c1, t2.c1 + -> Nested Loop + Output: t1.c1, t2.c1 + -> Foreign Scan on public.ft1 t1 + Output: t1.c1 + InfluxDB query: SELECT "C 1" FROM "T1" + -> Materialize + Output: t2.c1 + -> Foreign Scan on public.ft2 t2 + Output: t2.c1 + InfluxDB query: SELECT "C 1" FROM "T1" +(15 rows) + +--Testcase 180: +SELECT t1.c1, t2.c1 FROM ft1 t1 CROSS JOIN ft2 t2 ORDER BY t1.c1, t2.c1 OFFSET 100 LIMIT 10; + c1 | c1 +----+----- + 1 | 101 + 1 | 102 + 1 | 103 + 1 | 104 + 1 | 105 + 1 | 106 + 1 | 107 + 1 | 108 + 1 | 109 + 1 | 110 +(10 rows) + +-- different server, not pushed down. No result expected. +--Testcase 181: +EXPLAIN (VERBOSE, COSTS OFF) +SELECT t1.c1, t2.c1 FROM ft5 t1 JOIN ft6 t2 ON (t1.c1 = t2.c1) ORDER BY t1.c1, t2.c1 OFFSET 100 LIMIT 10; + QUERY PLAN +----------------------------------------------------------- + Limit + Output: t1.c1, t2.c1 + -> Merge Join + Output: t1.c1, t2.c1 + Merge Cond: (t1.c1 = t2.c1) + -> Sort + Output: t1.c1 + Sort Key: t1.c1 + -> Foreign Scan on public.ft5 t1 + Output: t1.c1 + InfluxDB query: SELECT "c1" FROM "T4" + -> Sort + Output: t2.c1 + Sort Key: t2.c1 + -> Foreign Scan on public.ft6 t2 + Output: t2.c1 + InfluxDB query: SELECT "c1" FROM "T4" +(17 rows) + +--Testcase 182: +SELECT t1.c1, t2.c1 FROM ft5 t1 JOIN ft6 t2 ON (t1.c1 = t2.c1) ORDER BY t1.c1, t2.c1 OFFSET 100 LIMIT 10; + c1 | c1 +----+---- +(0 rows) + +-- unsafe join conditions (c8 has a UDT), not pushed down. Practically a CROSS +-- JOIN since c8 in both tables has same value. +--Testcase 183: +EXPLAIN (VERBOSE, COSTS OFF) +SELECT t1.c1, t2.c1 FROM ft1 t1 LEFT JOIN ft2 t2 ON (t1.c8 = t2.c8) ORDER BY t1.c1, t2.c1 OFFSET 100 LIMIT 10; + QUERY PLAN +------------------------------------------------------------------------ + Limit + Output: t1.c1, t2.c1 + -> Sort + Output: t1.c1, t2.c1 + Sort Key: t1.c1, t2.c1 + -> Merge Left Join + Output: t1.c1, t2.c1 + Merge Cond: (t1.c8 = t2.c8) + -> Sort + Output: t1.c1, t1.c8 + Sort Key: t1.c8 + -> Foreign Scan on public.ft1 t1 + Output: t1.c1, t1.c8 + InfluxDB query: SELECT "C 1", "c8" FROM "T1" + -> Sort + Output: t2.c1, t2.c8 + Sort Key: t2.c8 + -> Foreign Scan on public.ft2 t2 + Output: t2.c1, t2.c8 + InfluxDB query: SELECT "C 1", "c8" FROM "T1" +(20 rows) + +--Testcase 184: +SELECT t1.c1, t2.c1 FROM ft1 t1 LEFT JOIN ft2 t2 ON (t1.c8 = t2.c8) ORDER BY t1.c1, t2.c1 OFFSET 100 LIMIT 10; + c1 | c1 +----+----- + 1 | 101 + 1 | 102 + 1 | 103 + 1 | 104 + 1 | 105 + 1 | 106 + 1 | 107 + 1 | 108 + 1 | 109 + 1 | 110 +(10 rows) + +-- unsafe conditions on one side (c8 has a UDT), not pushed down. +--Testcase 185: +EXPLAIN (VERBOSE, COSTS OFF) +SELECT t1.c1, t2.c1 FROM ft1 t1 LEFT JOIN ft2 t2 ON (t1.c1 = t2.c1) WHERE t1.c8 = 'foo' ORDER BY t1.c3, t1.c1 OFFSET 100 LIMIT 10; + QUERY PLAN +----------------------------------------------------------------------------------------------- + Limit + Output: t1.c1, t2.c1, t1.c3 + -> Sort + Output: t1.c1, t2.c1, t1.c3 + Sort Key: t1.c3, t1.c1 + -> Hash Right Join + Output: t1.c1, t2.c1, t1.c3 + Hash Cond: (t2.c1 = t1.c1) + -> Foreign Scan on public.ft2 t2 + Output: t2.c1 + InfluxDB query: SELECT "C 1" FROM "T1" + -> Hash + Output: t1.c1, t1.c3 + -> Foreign Scan on public.ft1 t1 + Output: t1.c1, t1.c3 + InfluxDB query: SELECT "C 1", "c3" FROM "T1" WHERE (("c8" = 'foo')) +(16 rows) + +--Testcase 186: +SELECT t1.c1, t2.c1 FROM ft1 t1 LEFT JOIN ft2 t2 ON (t1.c1 = t2.c1) WHERE t1.c8 = 'foo' ORDER BY t1.c3, t1.c1 OFFSET 100 LIMIT 10; + c1 | c1 +-----+----- + 101 | 101 + 102 | 102 + 103 | 103 + 104 | 104 + 105 | 105 + 106 | 106 + 107 | 107 + 108 | 108 + 109 | 109 + 110 | 110 +(10 rows) + +-- join where unsafe to pushdown condition in WHERE clause has a column not +-- in the SELECT clause. In this test unsafe clause needs to have column +-- references from both joining sides so that the clause is not pushed down +-- into one of the joining sides. +--Testcase 187: +EXPLAIN (VERBOSE, COSTS OFF) +SELECT t1.c1, t2.c1 FROM ft1 t1 JOIN ft2 t2 ON (t1.c1 = t2.c1) WHERE t1.c8 = t2.c8 ORDER BY t1.c3, t1.c1 OFFSET 100 LIMIT 10; + QUERY PLAN +------------------------------------------------------------------------------ + Limit + Output: t1.c1, t2.c1, t1.c3 + -> Sort + Output: t1.c1, t2.c1, t1.c3 + Sort Key: t1.c3, t1.c1 + -> Merge Join + Output: t1.c1, t2.c1, t1.c3 + Merge Cond: ((t1.c1 = t2.c1) AND (t1.c8 = t2.c8)) + -> Sort + Output: t1.c1, t1.c3, t1.c8 + Sort Key: t1.c1, t1.c8 + -> Foreign Scan on public.ft1 t1 + Output: t1.c1, t1.c3, t1.c8 + InfluxDB query: SELECT "C 1", "c3", "c8" FROM "T1" + -> Sort + Output: t2.c1, t2.c8 + Sort Key: t2.c1, t2.c8 + -> Foreign Scan on public.ft2 t2 + Output: t2.c1, t2.c8 + InfluxDB query: SELECT "C 1", "c8" FROM "T1" +(20 rows) + +--Testcase 188: +SELECT t1.c1, t2.c1 FROM ft1 t1 JOIN ft2 t2 ON (t1.c1 = t2.c1) WHERE t1.c8 = t2.c8 ORDER BY t1.c3, t1.c1 OFFSET 100 LIMIT 10; + c1 | c1 +-----+----- + 101 | 101 + 102 | 102 + 103 | 103 + 104 | 104 + 105 | 105 + 106 | 106 + 107 | 107 + 108 | 108 + 109 | 109 + 110 | 110 +(10 rows) + +-- Aggregate after UNION, for testing setrefs +--Testcase 189: +EXPLAIN (VERBOSE, COSTS OFF) +SELECT t1c1, avg(t1c1 + t2c1) FROM (SELECT t1.c1, t2.c1 FROM ft1 t1 JOIN ft2 t2 ON (t1.c1 = t2.c1) UNION SELECT t1.c1, t2.c1 FROM ft1 t1 JOIN ft2 t2 ON (t1.c1 = t2.c1)) AS t (t1c1, t2c1) GROUP BY t1c1 ORDER BY t1c1 OFFSET 100 LIMIT 10; + QUERY PLAN +------------------------------------------------------------------------------------ + Limit + Output: t1.c1, (avg((t1.c1 + t2.c1))) + -> Sort + Output: t1.c1, (avg((t1.c1 + t2.c1))) + Sort Key: t1.c1 + -> HashAggregate + Output: t1.c1, avg((t1.c1 + t2.c1)) + Group Key: t1.c1 + -> HashAggregate + Output: t1.c1, t2.c1 + Group Key: t1.c1, t2.c1 + -> Append + -> Merge Join + Output: t1.c1, t2.c1 + Merge Cond: (t1.c1 = t2.c1) + -> Sort + Output: t1.c1 + Sort Key: t1.c1 + -> Foreign Scan on public.ft1 t1 + Output: t1.c1 + InfluxDB query: SELECT "C 1" FROM "T1" + -> Sort + Output: t2.c1 + Sort Key: t2.c1 + -> Foreign Scan on public.ft2 t2 + Output: t2.c1 + InfluxDB query: SELECT "C 1" FROM "T1" + -> Merge Join + Output: t1_1.c1, t2_1.c1 + Merge Cond: (t1_1.c1 = t2_1.c1) + -> Sort + Output: t1_1.c1 + Sort Key: t1_1.c1 + -> Foreign Scan on public.ft1 t1_1 + Output: t1_1.c1 + InfluxDB query: SELECT "C 1" FROM "T1" + -> Sort + Output: t2_1.c1 + Sort Key: t2_1.c1 + -> Foreign Scan on public.ft2 t2_1 + Output: t2_1.c1 + InfluxDB query: SELECT "C 1" FROM "T1" +(42 rows) + +--Testcase 190: +SELECT t1c1, avg(t1c1 + t2c1) FROM (SELECT t1.c1, t2.c1 FROM ft1 t1 JOIN ft2 t2 ON (t1.c1 = t2.c1) UNION SELECT t1.c1, t2.c1 FROM ft1 t1 JOIN ft2 t2 ON (t1.c1 = t2.c1)) AS t (t1c1, t2c1) GROUP BY t1c1 ORDER BY t1c1 OFFSET 100 LIMIT 10; + t1c1 | avg +------+---------------------- + 101 | 202.0000000000000000 + 102 | 204.0000000000000000 + 103 | 206.0000000000000000 + 104 | 208.0000000000000000 + 105 | 210.0000000000000000 + 106 | 212.0000000000000000 + 107 | 214.0000000000000000 + 108 | 216.0000000000000000 + 109 | 218.0000000000000000 + 110 | 220.0000000000000000 +(10 rows) + +-- join with lateral reference +--Testcase 191: +EXPLAIN (VERBOSE, COSTS OFF) +SELECT t1."C 1" FROM "S 1"."T 1" t1, LATERAL (SELECT DISTINCT t2.c1, t3.c1 FROM ft1 t2, ft2 t3 WHERE t2.c1 = t3.c1 AND t2.c2 = t1.c2) q ORDER BY t1."C 1" OFFSET 10 LIMIT 10; + QUERY PLAN +-------------------------------------------------------------------------------------------------------- + Limit + Output: t1."C 1" + -> Sort + Output: t1."C 1" + Sort Key: t1."C 1" + -> Nested Loop + Output: t1."C 1" + -> Foreign Scan on "S 1"."T 1" t1 + Output: t1."C 1", t1.c2, t1.c3, t1."time", t1.c6, t1.c7, t1.c8 + InfluxDB query: SELECT "C 1", "c2" FROM "T1" + -> Unique + Output: t2.c1, t3.c1 + -> Sort + Output: t2.c1, t3.c1 + Sort Key: t2.c1 + -> Hash Join + Output: t2.c1, t3.c1 + Hash Cond: (t3.c1 = t2.c1) + -> Foreign Scan on public.ft2 t3 + Output: t3.c1 + InfluxDB query: SELECT "C 1" FROM "T1" + -> Hash + Output: t2.c1 + -> Foreign Scan on public.ft1 t2 + Output: t2.c1 + InfluxDB query: SELECT "C 1" FROM "T1" WHERE (("c2" = $1)) +(26 rows) + +--Testcase 192: +SELECT t1."C 1" FROM "S 1"."T 1" t1, LATERAL (SELECT DISTINCT t2.c1, t3.c1 FROM ft1 t2, ft2 t3 WHERE t2.c1 = t3.c1 AND t2.c2 = t1.c2) q ORDER BY t1."C 1" OFFSET 10 LIMIT 10; + C 1 +----- + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 1 +(10 rows) + +-- join with pseudoconstant quals, not pushed down. +EXPLAIN (VERBOSE, COSTS OFF) +SELECT t1.c1, t2.c1 FROM ft1 t1 JOIN ft2 t2 ON (t1.c1 = t2.c1 AND CURRENT_USER = SESSION_USER) ORDER BY t1.c3, t1.c1 OFFSET 100 LIMIT 10; + QUERY PLAN +------------------------------------------------------------------------------ + Limit + Output: t1.c1, t2.c1, t1.c3 + -> Sort + Output: t1.c1, t2.c1, t1.c3 + Sort Key: t1.c3, t1.c1 + -> Result + Output: t1.c1, t2.c1, t1.c3 + One-Time Filter: (CURRENT_USER = SESSION_USER) + -> Merge Join + Output: t1.c1, t1.c3, t2.c1 + Merge Cond: (t1.c1 = t2.c1) + -> Sort + Output: t1.c1, t1.c3 + Sort Key: t1.c1 + -> Foreign Scan on public.ft1 t1 + Output: t1.c1, t1.c3 + InfluxDB query: SELECT "C 1", "c3" FROM "T1" + -> Sort + Output: t2.c1 + Sort Key: t2.c1 + -> Foreign Scan on public.ft2 t2 + Output: t2.c1 + InfluxDB query: SELECT "C 1" FROM "T1" +(23 rows) + +-- non-Var items in targetlist of the nullable rel of a join preventing +-- push-down in some cases +-- unable to push {ft1, ft2} +--Testcase 193: +EXPLAIN (VERBOSE, COSTS OFF) +SELECT q.a, ft2.c1 FROM (SELECT 13 FROM ft1 WHERE c1 = 13) q(a) RIGHT JOIN ft2 ON (q.a = ft2.c1) WHERE ft2.c1 BETWEEN 10 AND 15; + QUERY PLAN +------------------------------------------------------------------------------------------ + Nested Loop Left Join + Output: (13), ft2.c1 + Join Filter: (13 = ft2.c1) + -> Foreign Scan on public.ft2 + Output: ft2.c1 + InfluxDB query: SELECT "C 1" FROM "T1" WHERE (("C 1" >= 10)) AND (("C 1" <= 15)) + -> Materialize + Output: (13) + -> Foreign Scan on public.ft1 + Output: 13 + InfluxDB query: SELECT * FROM "T1" WHERE (("C 1" = 13)) +(11 rows) + +--Testcase 194: +SELECT q.a, ft2.c1 FROM (SELECT 13 FROM ft1 WHERE c1 = 13) q(a) RIGHT JOIN ft2 ON (q.a = ft2.c1) WHERE ft2.c1 BETWEEN 10 AND 15; + a | c1 +----+---- + | 10 + | 11 + | 12 + 13 | 13 + | 14 + | 15 +(6 rows) + +-- ok to push {ft1, ft2} but not {ft1, ft2, ft4} +--Testcase 195: +EXPLAIN (VERBOSE, COSTS OFF) +SELECT ft4.c1, q.* FROM ft4 LEFT JOIN (SELECT 13, ft1.c1, ft2.c1 FROM ft1 RIGHT JOIN ft2 ON (ft1.c1 = ft2.c1) WHERE ft1.c1 = 12) q(a, b, c) ON (ft4.c1 = q.b) WHERE ft4.c1 BETWEEN 10 AND 15; + QUERY PLAN +--------------------------------------------------------------------------------------------- + Hash Right Join + Output: ft4.c1, (13), ft1.c1, ft2.c1 + Hash Cond: (ft1.c1 = ft4.c1) + -> Nested Loop + Output: ft1.c1, ft2.c1, 13 + -> Foreign Scan on public.ft1 + Output: ft1.c1 + InfluxDB query: SELECT "C 1" FROM "T1" WHERE (("C 1" = 12)) + -> Materialize + Output: ft2.c1 + -> Foreign Scan on public.ft2 + Output: ft2.c1 + InfluxDB query: SELECT "C 1" FROM "T1" WHERE (("C 1" = 12)) + -> Hash + Output: ft4.c1 + -> Foreign Scan on public.ft4 + Output: ft4.c1 + InfluxDB query: SELECT "c1" FROM "T3" WHERE (("c1" >= 10)) AND (("c1" <= 15)) +(18 rows) + +--Testcase 196: +SELECT ft4.c1, q.* FROM ft4 LEFT JOIN (SELECT 13, ft1.c1, ft2.c1 FROM ft1 RIGHT JOIN ft2 ON (ft1.c1 = ft2.c1) WHERE ft1.c1 = 12) q(a, b, c) ON (ft4.c1 = q.b) WHERE ft4.c1 BETWEEN 10 AND 15 ORDER BY ft4.c1; + c1 | a | b | c +----+----+----+---- + 10 | | | + 12 | 13 | 12 | 12 + 14 | | | +(3 rows) + +-- join with nullable side with some columns with null values +-- influxdb_fdw does not support UPDATE +-- UPDATE ft5 SET c3 = null where c1 % 9 = 0; +--Testcase 197: +EXPLAIN (VERBOSE, COSTS OFF) +SELECT ft5, ft5.c1, ft5.c2, ft5.c3, ft4.c1, ft4.c2 FROM ft5 left join ft4 on ft5.c1 = ft4.c1 WHERE ft4.c1 BETWEEN 10 and 30 ORDER BY ft5.c1, ft4.c1; + QUERY PLAN +--------------------------------------------------------------------------------------------------------- + Sort + Output: ft5.*, ft5.c1, ft5.c2, ft5.c3, ft4.c1, ft4.c2 + Sort Key: ft5.c1 + -> Hash Join + Output: ft5.*, ft5.c1, ft5.c2, ft5.c3, ft4.c1, ft4.c2 + Hash Cond: (ft5.c1 = ft4.c1) + -> Foreign Scan on public.ft5 + Output: ft5.*, ft5.c1, ft5.c2, ft5.c3 + InfluxDB query: SELECT "c1", "c2", "c3" FROM "T4" + -> Hash + Output: ft4.c1, ft4.c2 + -> Foreign Scan on public.ft4 + Output: ft4.c1, ft4.c2 + InfluxDB query: SELECT "c1", "c2" FROM "T3" WHERE (("c1" >= 10)) AND (("c1" <= 30)) +(14 rows) + +--Testcase 198: +SELECT ft5, ft5.c1, ft5.c2, ft5.c3, ft4.c1, ft4.c2 FROM ft5 left join ft4 on ft5.c1 = ft4.c1 WHERE ft4.c1 BETWEEN 10 and 30 ORDER BY ft5.c1, ft4.c1; + ft5 | c1 | c2 | c3 | c1 | c2 +----------------+----+----+--------+----+---- + (12,13,AAA012) | 12 | 13 | AAA012 | 12 | 13 + (18,19,AAA018) | 18 | 19 | AAA018 | 18 | 19 + (24,25,AAA024) | 24 | 25 | AAA024 | 24 | 25 + (30,31,AAA030) | 30 | 31 | AAA030 | 30 | 31 +(4 rows) + +-- multi-way join involving multiple merge joins +-- (this case used to have EPQ-related planning problems) +--Testcase 199: +CREATE FOREIGN TABLE local_tbl (c1 int NOT NULL, c2 int NOT NULL, c3 text) SERVER influxdb_svr OPTIONS (table 'local_tbl'); +--Testcase 200: +INSERT INTO local_tbl SELECT id, id % 10, to_char(id, 'FM0000') FROM generate_series(1, 1000) id; +--ANALYZE local_tbl; +--Testcase 201: +SET enable_nestloop TO false; +--Testcase 202: +SET enable_hashjoin TO false; +--Testcase 203: +EXPLAIN (VERBOSE, COSTS OFF) +SELECT * FROM ft1, ft2, ft4, ft5, local_tbl WHERE ft1.c1 = ft2.c1 AND ft1.c2 = ft4.c1 + AND ft1.c2 = ft5.c1 AND ft1.c2 = local_tbl.c1 AND ft1.c1 < 100 AND ft2.c1 < 100 ORDER BY ft1.c1 FOR UPDATE; + QUERY PLAN +--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- + LockRows + Output: ft1.c1, ft1.c2, ft1.c3, ft1."time", ft1.c6, ft1.c7, ft1.c8, ft2.c1, ft2.c2, ft2.c3, ft2."time", ft2.c6, ft2.c7, ft2.c8, ft4.c1, ft4.c2, ft4.c3, ft5.c1, ft5.c2, ft5.c3, local_tbl.c1, local_tbl.c2, local_tbl.c3, ft1.*, ft2.*, ft4.*, ft5.*, local_tbl.* + -> Sort + Output: ft1.c1, ft1.c2, ft1.c3, ft1."time", ft1.c6, ft1.c7, ft1.c8, ft2.c1, ft2.c2, ft2.c3, ft2."time", ft2.c6, ft2.c7, ft2.c8, ft4.c1, ft4.c2, ft4.c3, ft5.c1, ft5.c2, ft5.c3, local_tbl.c1, local_tbl.c2, local_tbl.c3, ft1.*, ft2.*, ft4.*, ft5.*, local_tbl.* + Sort Key: ft1.c1 + -> Merge Join + Output: ft1.c1, ft1.c2, ft1.c3, ft1."time", ft1.c6, ft1.c7, ft1.c8, ft2.c1, ft2.c2, ft2.c3, ft2."time", ft2.c6, ft2.c7, ft2.c8, ft4.c1, ft4.c2, ft4.c3, ft5.c1, ft5.c2, ft5.c3, local_tbl.c1, local_tbl.c2, local_tbl.c3, ft1.*, ft2.*, ft4.*, ft5.*, local_tbl.* + Merge Cond: (ft1.c2 = local_tbl.c1) + -> Merge Join + Output: ft1.c1, ft1.c2, ft1.c3, ft1."time", ft1.c6, ft1.c7, ft1.c8, ft1.*, ft2.c1, ft2.c2, ft2.c3, ft2."time", ft2.c6, ft2.c7, ft2.c8, ft2.*, ft4.c1, ft4.c2, ft4.c3, ft4.*, ft5.c1, ft5.c2, ft5.c3, ft5.* + Merge Cond: (ft1.c2 = ft5.c1) + -> Merge Join + Output: ft1.c1, ft1.c2, ft1.c3, ft1."time", ft1.c6, ft1.c7, ft1.c8, ft1.*, ft2.c1, ft2.c2, ft2.c3, ft2."time", ft2.c6, ft2.c7, ft2.c8, ft2.*, ft4.c1, ft4.c2, ft4.c3, ft4.* + Merge Cond: (ft1.c2 = ft4.c1) + -> Sort + Output: ft1.c1, ft1.c2, ft1.c3, ft1."time", ft1.c6, ft1.c7, ft1.c8, ft1.*, ft2.c1, ft2.c2, ft2.c3, ft2."time", ft2.c6, ft2.c7, ft2.c8, ft2.* + Sort Key: ft1.c2 + -> Merge Join + Output: ft1.c1, ft1.c2, ft1.c3, ft1."time", ft1.c6, ft1.c7, ft1.c8, ft1.*, ft2.c1, ft2.c2, ft2.c3, ft2."time", ft2.c6, ft2.c7, ft2.c8, ft2.* + Merge Cond: (ft1.c1 = ft2.c1) + -> Sort + Output: ft1.c1, ft1.c2, ft1.c3, ft1."time", ft1.c6, ft1.c7, ft1.c8, ft1.* + Sort Key: ft1.c1 + -> Foreign Scan on public.ft1 + Output: ft1.c1, ft1.c2, ft1.c3, ft1."time", ft1.c6, ft1.c7, ft1.c8, ft1.* + InfluxDB query: SELECT "C 1", "c2", "c3", "c6", "c7", "c8" FROM "T1" WHERE (("C 1" < 100)) + -> Sort + Output: ft2.c1, ft2.c2, ft2.c3, ft2."time", ft2.c6, ft2.c7, ft2.c8, ft2.* + Sort Key: ft2.c1 + -> Foreign Scan on public.ft2 + Output: ft2.c1, ft2.c2, ft2.c3, ft2."time", ft2.c6, ft2.c7, ft2.c8, ft2.* + InfluxDB query: SELECT "C 1", "c2", "c3", "c6", "c7", "c8" FROM "T1" WHERE (("C 1" < 100)) + -> Sort + Output: ft4.c1, ft4.c2, ft4.c3, ft4.* + Sort Key: ft4.c1 + -> Foreign Scan on public.ft4 + Output: ft4.c1, ft4.c2, ft4.c3, ft4.* + InfluxDB query: SELECT "c1", "c2", "c3" FROM "T3" + -> Sort + Output: ft5.c1, ft5.c2, ft5.c3, ft5.* + Sort Key: ft5.c1 + -> Foreign Scan on public.ft5 + Output: ft5.c1, ft5.c2, ft5.c3, ft5.* + InfluxDB query: SELECT "c1", "c2", "c3" FROM "T4" + -> Sort + Output: local_tbl.c1, local_tbl.c2, local_tbl.c3, local_tbl.* + Sort Key: local_tbl.c1 + -> Foreign Scan on public.local_tbl + Output: local_tbl.c1, local_tbl.c2, local_tbl.c3, local_tbl.* + InfluxDB query: SELECT "c1", "c2", "c3" FROM "local_tbl" +(50 rows) + +--Testcase 204: +SELECT * FROM ft1, ft2, ft4, ft5, local_tbl WHERE ft1.c1 = ft2.c1 AND ft1.c2 = ft4.c1 + AND ft1.c2 = ft5.c1 AND ft1.c2 = local_tbl.c1 AND ft1.c1 < 100 AND ft2.c1 < 100 ORDER BY ft1.c1 FOR UPDATE; + c1 | c2 | c3 | time | c6 | c7 | c8 | c1 | c2 | c3 | time | c6 | c7 | c8 | c1 | c2 | c3 | c1 | c2 | c3 | c1 | c2 | c3 +----+----+-------+------------------------------+----+------------+-----+----+----+-------+------------------------------+----+------------+-----+----+----+--------+----+----+--------+----+----+------ + 6 | 6 | 00006 | Wed Jan 07 00:00:00 1970 PST | 6 | 6 | foo | 6 | 6 | 00006 | Wed Jan 07 00:00:00 1970 PST | 6 | 6 | foo | 6 | 7 | AAA006 | 6 | 7 | AAA006 | 6 | 6 | 0006 + 16 | 6 | 00016 | Sat Jan 17 00:00:00 1970 PST | 6 | 6 | foo | 16 | 6 | 00016 | Sat Jan 17 00:00:00 1970 PST | 6 | 6 | foo | 6 | 7 | AAA006 | 6 | 7 | AAA006 | 6 | 6 | 0006 + 26 | 6 | 00026 | Tue Jan 27 00:00:00 1970 PST | 6 | 6 | foo | 26 | 6 | 00026 | Tue Jan 27 00:00:00 1970 PST | 6 | 6 | foo | 6 | 7 | AAA006 | 6 | 7 | AAA006 | 6 | 6 | 0006 + 36 | 6 | 00036 | Fri Feb 06 00:00:00 1970 PST | 6 | 6 | foo | 36 | 6 | 00036 | Fri Feb 06 00:00:00 1970 PST | 6 | 6 | foo | 6 | 7 | AAA006 | 6 | 7 | AAA006 | 6 | 6 | 0006 + 46 | 6 | 00046 | Mon Feb 16 00:00:00 1970 PST | 6 | 6 | foo | 46 | 6 | 00046 | Mon Feb 16 00:00:00 1970 PST | 6 | 6 | foo | 6 | 7 | AAA006 | 6 | 7 | AAA006 | 6 | 6 | 0006 + 56 | 6 | 00056 | Thu Feb 26 00:00:00 1970 PST | 6 | 6 | foo | 56 | 6 | 00056 | Thu Feb 26 00:00:00 1970 PST | 6 | 6 | foo | 6 | 7 | AAA006 | 6 | 7 | AAA006 | 6 | 6 | 0006 + 66 | 6 | 00066 | Sun Mar 08 00:00:00 1970 PST | 6 | 6 | foo | 66 | 6 | 00066 | Sun Mar 08 00:00:00 1970 PST | 6 | 6 | foo | 6 | 7 | AAA006 | 6 | 7 | AAA006 | 6 | 6 | 0006 + 76 | 6 | 00076 | Wed Mar 18 00:00:00 1970 PST | 6 | 6 | foo | 76 | 6 | 00076 | Wed Mar 18 00:00:00 1970 PST | 6 | 6 | foo | 6 | 7 | AAA006 | 6 | 7 | AAA006 | 6 | 6 | 0006 + 86 | 6 | 00086 | Sat Mar 28 00:00:00 1970 PST | 6 | 6 | foo | 86 | 6 | 00086 | Sat Mar 28 00:00:00 1970 PST | 6 | 6 | foo | 6 | 7 | AAA006 | 6 | 7 | AAA006 | 6 | 6 | 0006 + 96 | 6 | 00096 | Tue Apr 07 00:00:00 1970 PST | 6 | 6 | foo | 96 | 6 | 00096 | Tue Apr 07 00:00:00 1970 PST | 6 | 6 | foo | 6 | 7 | AAA006 | 6 | 7 | AAA006 | 6 | 6 | 0006 +(10 rows) + +--Testcase 205: +RESET enable_nestloop; +--Testcase 206: +RESET enable_hashjoin; +-- test that add_paths_with_pathkeys_for_rel() arranges for the epq_path to +-- return columns needed by the parent ForeignScan node +--Testcase 825: +EXPLAIN (VERBOSE, COSTS OFF) +SELECT * FROM local_tbl LEFT JOIN (SELECT ft1.*, COALESCE(ft1.c3 || ft2.c3, 'foobar') FROM ft1 INNER JOIN ft2 ON (ft1.c1 = ft2.c1 AND ft1.c1 < 100)) ss ON (local_tbl.c1 = ss.c1) ORDER BY local_tbl.c1 FOR UPDATE OF local_tbl; + QUERY PLAN +------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- + LockRows + Output: local_tbl.c1, local_tbl.c2, local_tbl.c3, ft1.c1, ft1.c2, ft1.c3, ft1."time", ft1.c6, ft1.c7, ft1.c8, (COALESCE((ft1.c3 || ft2.c3), 'foobar'::text)), local_tbl.*, ft1.*, ft2.* + -> Merge Left Join + Output: local_tbl.c1, local_tbl.c2, local_tbl.c3, ft1.c1, ft1.c2, ft1.c3, ft1."time", ft1.c6, ft1.c7, ft1.c8, (COALESCE((ft1.c3 || ft2.c3), 'foobar'::text)), local_tbl.*, ft1.*, ft2.* + Merge Cond: (local_tbl.c1 = ft1.c1) + -> Sort + Output: local_tbl.c1, local_tbl.c2, local_tbl.c3, local_tbl.* + Sort Key: local_tbl.c1 + -> Foreign Scan on public.local_tbl + Output: local_tbl.c1, local_tbl.c2, local_tbl.c3, local_tbl.* + InfluxDB query: SELECT "c1", "c2", "c3" FROM "local_tbl" + -> Sort + Output: ft1.c1, ft1.c2, ft1.c3, ft1."time", ft1.c6, ft1.c7, ft1.c8, ft1.*, ft2.*, (COALESCE((ft1.c3 || ft2.c3), 'foobar'::text)) + Sort Key: ft1.c1 + -> Hash Join + Output: ft1.c1, ft1.c2, ft1.c3, ft1."time", ft1.c6, ft1.c7, ft1.c8, ft1.*, ft2.*, COALESCE((ft1.c3 || ft2.c3), 'foobar'::text) + Hash Cond: (ft2.c1 = ft1.c1) + -> Foreign Scan on public.ft2 + Output: ft2.*, ft2.c1, ft2.c3 + InfluxDB query: SELECT "C 1", "c2", "c3", "c6", "c7", "c8" FROM "T1" + -> Hash + Output: ft1.c1, ft1.c2, ft1.c3, ft1."time", ft1.c6, ft1.c7, ft1.c8, ft1.* + -> Foreign Scan on public.ft1 + Output: ft1.c1, ft1.c2, ft1.c3, ft1."time", ft1.c6, ft1.c7, ft1.c8, ft1.* + InfluxDB query: SELECT "C 1", "c2", "c3", "c6", "c7", "c8" FROM "T1" WHERE (("C 1" < 100)) +(25 rows) + +-- ALTER SERVER loopback OPTIONS (DROP extensions); +-- ALTER SERVER loopback OPTIONS (ADD fdw_startup_cost '10000.0'); +--Testcase 826: +EXPLAIN (VERBOSE, COSTS OFF) +SELECT * FROM local_tbl LEFT JOIN (SELECT ft1.* FROM ft1 INNER JOIN ft2 ON (ft1.c1 = ft2.c1 AND ft1.c1 < 100 AND (ft1.c1 - influxdb_fdw_abs(ft2.c2)) = 0)) ss ON (local_tbl.c3 = ss.c3) ORDER BY local_tbl.c1 FOR UPDATE OF local_tbl; + QUERY PLAN +------------------------------------------------------------------------------------------------------------------------------------------------------- + LockRows + Output: local_tbl.c1, local_tbl.c2, local_tbl.c3, ft1.c1, ft1.c2, ft1.c3, ft1."time", ft1.c6, ft1.c7, ft1.c8, local_tbl.*, ft1.*, ft2.* + -> Sort + Output: local_tbl.c1, local_tbl.c2, local_tbl.c3, ft1.c1, ft1.c2, ft1.c3, ft1."time", ft1.c6, ft1.c7, ft1.c8, local_tbl.*, ft1.*, ft2.* + Sort Key: local_tbl.c1 + -> Nested Loop Left Join + Output: local_tbl.c1, local_tbl.c2, local_tbl.c3, ft1.c1, ft1.c2, ft1.c3, ft1."time", ft1.c6, ft1.c7, ft1.c8, local_tbl.*, ft1.*, ft2.* + Join Filter: (local_tbl.c3 = ft1.c3) + -> Foreign Scan on public.local_tbl + Output: local_tbl.c1, local_tbl.c2, local_tbl.c3, local_tbl.* + InfluxDB query: SELECT "c1", "c2", "c3" FROM "local_tbl" + -> Materialize + Output: ft1.c1, ft1.c2, ft1.c3, ft1."time", ft1.c6, ft1.c7, ft1.c8, ft1.*, ft2.* + -> Hash Join + Output: ft1.c1, ft1.c2, ft1.c3, ft1."time", ft1.c6, ft1.c7, ft1.c8, ft1.*, ft2.* + Hash Cond: (ft2.c1 = ft1.c1) + Join Filter: ((ft1.c1 - influxdb_fdw_abs(ft2.c2)) = 0) + -> Foreign Scan on public.ft2 + Output: ft2.*, ft2.c1, ft2.c2 + InfluxDB query: SELECT "C 1", "c2", "c3", "c6", "c7", "c8" FROM "T1" + -> Hash + Output: ft1.c1, ft1.c2, ft1.c3, ft1."time", ft1.c6, ft1.c7, ft1.c8, ft1.* + -> Foreign Scan on public.ft1 + Output: ft1.c1, ft1.c2, ft1.c3, ft1."time", ft1.c6, ft1.c7, ft1.c8, ft1.* + InfluxDB query: SELECT "C 1", "c2", "c3", "c6", "c7", "c8" FROM "T1" WHERE (("C 1" < 100)) +(25 rows) + +-- ALTER SERVER loopback OPTIONS (DROP fdw_startup_cost); +-- ALTER SERVER loopback OPTIONS (ADD extensions 'influxdb_fdw'); +--Testcase 207: +DELETE FROM local_tbl; +--Testcase 783: +DROP FOREIGN TABLE local_tbl; +-- check join pushdown in situations where multiple userids are involved +--Testcase 208: +CREATE ROLE regress_view_owner SUPERUSER; +--Testcase 209: +CREATE USER MAPPING FOR regress_view_owner SERVER influxdb_svr OPTIONS (:AUTHENTICATION); +GRANT SELECT ON ft4 TO regress_view_owner; +GRANT SELECT ON ft5 TO regress_view_owner; +--Testcase 210: +CREATE VIEW v4 AS SELECT * FROM ft4; +--Testcase 211: +CREATE VIEW v5 AS SELECT * FROM ft5; +--Testcase 212: +ALTER VIEW v5 OWNER TO regress_view_owner; +--Testcase 213: +EXPLAIN (VERBOSE, COSTS OFF) +SELECT t1.c1, t2.c2 FROM v4 t1 LEFT JOIN v5 t2 ON (t1.c1 = t2.c1) ORDER BY t1.c1, t2.c1 OFFSET 10 LIMIT 10; -- can't be pushed down, different view owners + QUERY PLAN +----------------------------------------------------------------------- + Limit + Output: ft4.c1, ft5.c2, ft5.c1 + -> Incremental Sort + Output: ft4.c1, ft5.c2, ft5.c1 + Sort Key: ft4.c1, ft5.c1 + Presorted Key: ft4.c1 + -> Merge Left Join + Output: ft4.c1, ft5.c2, ft5.c1 + Merge Cond: (ft4.c1 = ft5.c1) + -> Sort + Output: ft4.c1 + Sort Key: ft4.c1 + -> Foreign Scan on public.ft4 + Output: ft4.c1 + InfluxDB query: SELECT "c1" FROM "T3" + -> Sort + Output: ft5.c2, ft5.c1 + Sort Key: ft5.c1 + -> Foreign Scan on public.ft5 + Output: ft5.c2, ft5.c1 + InfluxDB query: SELECT "c1", "c2" FROM "T4" +(21 rows) + +--Testcase 214: +SELECT t1.c1, t2.c2 FROM v4 t1 LEFT JOIN v5 t2 ON (t1.c1 = t2.c1) ORDER BY t1.c1, t2.c1 OFFSET 10 LIMIT 10; + c1 | c2 +----+---- + 22 | + 24 | 25 + 26 | + 28 | + 30 | 31 + 32 | + 34 | + 36 | 37 + 38 | + 40 | +(10 rows) + +--Testcase 215: +ALTER VIEW v4 OWNER TO regress_view_owner; +--Testcase 216: +EXPLAIN (VERBOSE, COSTS OFF) +SELECT t1.c1, t2.c2 FROM v4 t1 LEFT JOIN v5 t2 ON (t1.c1 = t2.c1) ORDER BY t1.c1, t2.c1 OFFSET 10 LIMIT 10; -- can be pushed down + QUERY PLAN +----------------------------------------------------------------------- + Limit + Output: ft4.c1, ft5.c2, ft5.c1 + -> Incremental Sort + Output: ft4.c1, ft5.c2, ft5.c1 + Sort Key: ft4.c1, ft5.c1 + Presorted Key: ft4.c1 + -> Merge Left Join + Output: ft4.c1, ft5.c2, ft5.c1 + Merge Cond: (ft4.c1 = ft5.c1) + -> Sort + Output: ft4.c1 + Sort Key: ft4.c1 + -> Foreign Scan on public.ft4 + Output: ft4.c1 + InfluxDB query: SELECT "c1" FROM "T3" + -> Sort + Output: ft5.c2, ft5.c1 + Sort Key: ft5.c1 + -> Foreign Scan on public.ft5 + Output: ft5.c2, ft5.c1 + InfluxDB query: SELECT "c1", "c2" FROM "T4" +(21 rows) + +--Testcase 217: +SELECT t1.c1, t2.c2 FROM v4 t1 LEFT JOIN v5 t2 ON (t1.c1 = t2.c1) ORDER BY t1.c1, t2.c1 OFFSET 10 LIMIT 10; + c1 | c2 +----+---- + 22 | + 24 | 25 + 26 | + 28 | + 30 | 31 + 32 | + 34 | + 36 | 37 + 38 | + 40 | +(10 rows) + +--Testcase 218: +EXPLAIN (VERBOSE, COSTS OFF) +SELECT t1.c1, t2.c2 FROM v4 t1 LEFT JOIN ft5 t2 ON (t1.c1 = t2.c1) ORDER BY t1.c1, t2.c1 OFFSET 10 LIMIT 10; -- can't be pushed down, view owner not current user + QUERY PLAN +----------------------------------------------------------------------- + Limit + Output: ft4.c1, t2.c2, t2.c1 + -> Incremental Sort + Output: ft4.c1, t2.c2, t2.c1 + Sort Key: ft4.c1, t2.c1 + Presorted Key: ft4.c1 + -> Merge Left Join + Output: ft4.c1, t2.c2, t2.c1 + Merge Cond: (ft4.c1 = t2.c1) + -> Sort + Output: ft4.c1 + Sort Key: ft4.c1 + -> Foreign Scan on public.ft4 + Output: ft4.c1 + InfluxDB query: SELECT "c1" FROM "T3" + -> Sort + Output: t2.c2, t2.c1 + Sort Key: t2.c1 + -> Foreign Scan on public.ft5 t2 + Output: t2.c2, t2.c1 + InfluxDB query: SELECT "c1", "c2" FROM "T4" +(21 rows) + +--Testcase 219: +SELECT t1.c1, t2.c2 FROM v4 t1 LEFT JOIN ft5 t2 ON (t1.c1 = t2.c1) ORDER BY t1.c1, t2.c1 OFFSET 10 LIMIT 10; + c1 | c2 +----+---- + 22 | + 24 | 25 + 26 | + 28 | + 30 | 31 + 32 | + 34 | + 36 | 37 + 38 | + 40 | +(10 rows) + +--Testcase 220: +ALTER VIEW v4 OWNER TO CURRENT_USER; +--Testcase 221: +EXPLAIN (VERBOSE, COSTS OFF) +SELECT t1.c1, t2.c2 FROM v4 t1 LEFT JOIN ft5 t2 ON (t1.c1 = t2.c1) ORDER BY t1.c1, t2.c1 OFFSET 10 LIMIT 10; -- can be pushed down + QUERY PLAN +----------------------------------------------------------------------- + Limit + Output: ft4.c1, t2.c2, t2.c1 + -> Incremental Sort + Output: ft4.c1, t2.c2, t2.c1 + Sort Key: ft4.c1, t2.c1 + Presorted Key: ft4.c1 + -> Merge Left Join + Output: ft4.c1, t2.c2, t2.c1 + Merge Cond: (ft4.c1 = t2.c1) + -> Sort + Output: ft4.c1 + Sort Key: ft4.c1 + -> Foreign Scan on public.ft4 + Output: ft4.c1 + InfluxDB query: SELECT "c1" FROM "T3" + -> Sort + Output: t2.c2, t2.c1 + Sort Key: t2.c1 + -> Foreign Scan on public.ft5 t2 + Output: t2.c2, t2.c1 + InfluxDB query: SELECT "c1", "c2" FROM "T4" +(21 rows) + +--Testcase 222: +SELECT t1.c1, t2.c2 FROM v4 t1 LEFT JOIN ft5 t2 ON (t1.c1 = t2.c1) ORDER BY t1.c1, t2.c1 OFFSET 10 LIMIT 10; + c1 | c2 +----+---- + 22 | + 24 | 25 + 26 | + 28 | + 30 | 31 + 32 | + 34 | + 36 | 37 + 38 | + 40 | +(10 rows) + +--Testcase 223: +ALTER VIEW v4 OWNER TO regress_view_owner; +-- ==================================================================== +-- Check that userid to use when querying the remote table is correctly +-- propagated into foreign rels present in subqueries under an UNION ALL +-- ==================================================================== +CREATE ROLE regress_view_owner_another; +ALTER VIEW v4 OWNER TO regress_view_owner_another; +GRANT SELECT ON ft4 TO regress_view_owner_another; +-- ALTER FOREIGN TABLE ft4 OPTIONS (ADD use_remote_estimate 'true'); +-- The following should query the remote backing table of ft4 as user +-- regress_view_owner_another, the view owner, though it fails as expected +-- due to the lack of a user mapping for that user. +EXPLAIN (VERBOSE, COSTS OFF) SELECT * FROM v4; +ERROR: user mapping not found for "regress_view_owner_another" +-- Likewise, but with the query under an UNION ALL +EXPLAIN (VERBOSE, COSTS OFF) SELECT * FROM (SELECT * FROM v4 UNION ALL SELECT * FROM v4); +ERROR: user mapping not found for "regress_view_owner_another" +-- Should not get that error once a user mapping is created +CREATE USER MAPPING FOR regress_view_owner_another SERVER influxdb_svr OPTIONS (:AUTHENTICATION); +EXPLAIN (VERBOSE, COSTS OFF) SELECT * FROM v4; + QUERY PLAN +----------------------------------------------------- + Foreign Scan on public.ft4 + Output: ft4.c1, ft4.c2, ft4.c3 + InfluxDB query: SELECT "c1", "c2", "c3" FROM "T3" +(3 rows) + +EXPLAIN (VERBOSE, COSTS OFF) SELECT * FROM (SELECT * FROM v4 UNION ALL SELECT * FROM v4); + QUERY PLAN +----------------------------------------------------------- + Append + -> Foreign Scan on public.ft4 + Output: ft4.c1, ft4.c2, ft4.c3 + InfluxDB query: SELECT "c1", "c2", "c3" FROM "T3" + -> Foreign Scan on public.ft4 ft4_1 + Output: ft4_1.c1, ft4_1.c2, ft4_1.c3 + InfluxDB query: SELECT "c1", "c2", "c3" FROM "T3" +(7 rows) + +DROP USER MAPPING FOR regress_view_owner_another SERVER influxdb_svr; +DROP OWNED BY regress_view_owner_another; +DROP ROLE regress_view_owner_another; +-- ALTER FOREIGN TABLE ft4 OPTIONS (SET use_remote_estimate 'false'); +-- cleanup +--Testcase 224: +DROP OWNED BY regress_view_owner; +--Testcase 225: +DROP ROLE regress_view_owner; +-- =================================================================== +-- Aggregate and grouping queries +-- =================================================================== +-- Simple aggregates +--Testcase 226: +explain (verbose, costs off) +select count(c6), sum(c1), avg(c1), min(c2), max(c1), stddev(c2), sum(c1) * (random() <= 1)::int as sum2 from ft1 where c2 < 5 group by c2 order by 1, 2; + QUERY PLAN +--------------------------------------------------------------------------------------------------------------------------------------------------- + Result + Output: (count(c6)), (sum(c1)), (avg(c1)), (min(c2)), (max(c1)), (stddev(c2)), ((sum(c1)) * ((random() <= '1'::double precision))::integer), c2 + -> Sort + Output: (count(c6)), (sum(c1)), (avg(c1)), (min(c2)), (max(c1)), (stddev(c2)), c2 + Sort Key: (count(ft1.c6)), (sum(ft1.c1)) + -> HashAggregate + Output: count(c6), sum(c1), avg(c1), min(c2), max(c1), stddev(c2), c2 + Group Key: ft1.c2 + -> Foreign Scan on public.ft1 + Output: c6, c1, c2 + InfluxDB query: SELECT "C 1", "c2", "c6" FROM "T1" WHERE (("c2" < 5)) +(11 rows) + +--Testcase 227: +select count(c6), sum(c1), avg(c1), min(c2), max(c1), stddev(c2), sum(c1) * (random() <= 1)::int as sum2 from ft1 where c2 < 5 group by c2 order by 1, 2; + count | sum | avg | min | max | stddev | sum2 +-------+-------+----------------------+-----+------+--------+------- + 100 | 49600 | 496.0000000000000000 | 1 | 991 | 0 | 49600 + 100 | 49700 | 497.0000000000000000 | 2 | 992 | 0 | 49700 + 100 | 49800 | 498.0000000000000000 | 3 | 993 | 0 | 49800 + 100 | 49900 | 499.0000000000000000 | 4 | 994 | 0 | 49900 + 100 | 50500 | 505.0000000000000000 | 0 | 1000 | 0 | 50500 +(5 rows) + +--Testcase 228: +explain (verbose, costs off) +select count(c6), sum(c1), avg(c1), min(c2), max(c1), stddev(c2), sum(c1) * (random() <= 1)::int as sum2 from ft1 where c2 < 5 group by c2 order by 1, 2 limit 1; + QUERY PLAN +--------------------------------------------------------------------------------------------------------------------------------------------------------- + Limit + Output: (count(c6)), (sum(c1)), (avg(c1)), (min(c2)), (max(c1)), (stddev(c2)), (((sum(c1)) * ((random() <= '1'::double precision))::integer)), c2 + -> Result + Output: (count(c6)), (sum(c1)), (avg(c1)), (min(c2)), (max(c1)), (stddev(c2)), ((sum(c1)) * ((random() <= '1'::double precision))::integer), c2 + -> Sort + Output: (count(c6)), (sum(c1)), (avg(c1)), (min(c2)), (max(c1)), (stddev(c2)), c2 + Sort Key: (count(ft1.c6)), (sum(ft1.c1)) + -> HashAggregate + Output: count(c6), sum(c1), avg(c1), min(c2), max(c1), stddev(c2), c2 + Group Key: ft1.c2 + -> Foreign Scan on public.ft1 + Output: c6, c1, c2 + InfluxDB query: SELECT "C 1", "c2", "c6" FROM "T1" WHERE (("c2" < 5)) +(13 rows) + +--Testcase 229: +select count(c6), sum(c1), avg(c1), min(c2), max(c1), stddev(c2), sum(c1) * (random() <= 1)::int as sum2 from ft1 where c2 < 5 group by c2 order by 1, 2 limit 1; + count | sum | avg | min | max | stddev | sum2 +-------+-------+----------------------+-----+-----+--------+------- + 100 | 49600 | 496.0000000000000000 | 1 | 991 | 0 | 49600 +(1 row) + +-- Aggregate is not pushed down as aggregation contains random() +--Testcase 230: +explain (verbose, costs off) +select sum(c1 * (random() <= 1)::int) as sum, avg(c1) from ft1; + QUERY PLAN +------------------------------------------------------------------------------- + Aggregate + Output: sum((c1 * ((random() <= '1'::double precision))::integer)), avg(c1) + -> Foreign Scan on public.ft1 + Output: c1 + InfluxDB query: SELECT "C 1" FROM "T1" +(5 rows) + +-- Aggregate over join query +--Testcase 231: +explain (verbose, costs off) +select count(*), sum(t1.c1), avg(t2.c1) from ft1 t1 inner join ft1 t2 on (t1.c2 = t2.c2) where t1.c2 = 6; + QUERY PLAN +------------------------------------------------------------------------------------- + Aggregate + Output: count(*), sum(t1.c1), avg(t2.c1) + -> Nested Loop + Output: t1.c1, t2.c1 + -> Foreign Scan on public.ft1 t1 + Output: t1.c1, t1.c2 + InfluxDB query: SELECT "C 1", "c2" FROM "T1" WHERE (("c2" = 6)) + -> Materialize + Output: t2.c1, t2.c2 + -> Foreign Scan on public.ft1 t2 + Output: t2.c1, t2.c2 + InfluxDB query: SELECT "C 1", "c2" FROM "T1" WHERE (("c2" = 6)) +(12 rows) + +--Testcase 232: +select count(*), sum(t1.c1), avg(t2.c1) from ft1 t1 inner join ft1 t2 on (t1.c2 = t2.c2) where t1.c2 = 6; + count | sum | avg +-------+---------+---------------------- + 10000 | 5010000 | 501.0000000000000000 +(1 row) + +-- Not pushed down due to local conditions present in underneath input rel +--Testcase 233: +explain (verbose, costs off) +select sum(t1.c1), count(t2.c1) from ft1 t1 inner join ft2 t2 on (t1.c1 = t2.c1) where ((t1.c1 * t2.c1)/(t1.c1 * t2.c1)) * random() <= 1; + QUERY PLAN +---------------------------------------------------------------------------------------------------------------------- + Aggregate + Output: sum(t1.c1), count(t2.c1) + -> Merge Join + Output: t1.c1, t2.c1 + Merge Cond: (t1.c1 = t2.c1) + Join Filter: (((((t1.c1 * t2.c1) / (t1.c1 * t2.c1)))::double precision * random()) <= '1'::double precision) + -> Sort + Output: t1.c1 + Sort Key: t1.c1 + -> Foreign Scan on public.ft1 t1 + Output: t1.c1 + InfluxDB query: SELECT "C 1" FROM "T1" + -> Sort + Output: t2.c1 + Sort Key: t2.c1 + -> Foreign Scan on public.ft2 t2 + Output: t2.c1 + InfluxDB query: SELECT "C 1" FROM "T1" +(18 rows) + +-- GROUP BY clause having expressions +--Testcase 234: +explain (verbose, costs off) +select c2/2, sum(c2) * (c2/2) from ft1 group by c2/2 order by c2/2; + QUERY PLAN +----------------------------------------------------- + Sort + Output: ((c2 / 2)), ((sum(c2) * ((c2 / 2)))) + Sort Key: ((ft1.c2 / 2)) + -> HashAggregate + Output: ((c2 / 2)), (sum(c2) * ((c2 / 2))) + Group Key: (ft1.c2 / 2) + -> Foreign Scan on public.ft1 + Output: (c2 / 2), c2 + InfluxDB query: SELECT "c2" FROM "T1" +(9 rows) + +--Testcase 235: +select c2/2, sum(c2) * (c2/2) from ft1 group by c2/2 order by c2/2; + ?column? | ?column? +----------+---------- + 0 | 0 + 1 | 500 + 2 | 1800 + 3 | 3900 + 4 | 6800 +(5 rows) + +-- Aggregates in subquery are pushed down. +set enable_incremental_sort = off; +--Testcase 236: +explain (verbose, costs off) +select count(x.a), sum(x.a) from (select c2 a, sum(c1) b from ft1 group by c2, sqrt(c1) order by 1, 2) x; + QUERY PLAN +------------------------------------------------------------------------------- + Aggregate + Output: count(ft1.c2), sum(ft1.c2) + -> Sort + Output: ft1.c2, (sum(ft1.c1)), (sqrt((ft1.c1)::double precision)) + Sort Key: ft1.c2, (sum(ft1.c1)) + -> HashAggregate + Output: ft1.c2, sum(ft1.c1), (sqrt((ft1.c1)::double precision)) + Group Key: ft1.c2, sqrt((ft1.c1)::double precision) + -> Foreign Scan on public.ft1 + Output: ft1.c2, sqrt((ft1.c1)::double precision), ft1.c1 + InfluxDB query: SELECT "C 1", "c2" FROM "T1" +(11 rows) + +--Testcase 237: +select count(x.a), sum(x.a) from (select c2 a, sum(c1) b from ft1 group by c2, sqrt(c1) order by 1, 2) x; + count | sum +-------+------ + 1000 | 4500 +(1 row) + +reset enable_incremental_sort; +-- Aggregate is still pushed down by taking unshippable expression out +--Testcase 238: +explain (verbose, costs off) +select c2 * (random() <= 1)::int as sum1, sum(c1) * c2 as sum2 from ft1 group by c2 order by 1, 2; + QUERY PLAN +--------------------------------------------------------------------------------------------------- + Sort + Output: ((c2 * ((random() <= '1'::double precision))::integer)), ((sum(c1) * c2)), c2 + Sort Key: ((ft1.c2 * ((random() <= '1'::double precision))::integer)), ((sum(ft1.c1) * ft1.c2)) + -> HashAggregate + Output: (c2 * ((random() <= '1'::double precision))::integer), (sum(c1) * c2), c2 + Group Key: ft1.c2 + -> Foreign Scan on public.ft1 + Output: c2, c1 + InfluxDB query: SELECT "C 1", "c2" FROM "T1" +(9 rows) + +--Testcase 239: +select c2 * (random() <= 1)::int as sum1, sum(c1) * c2 as sum2 from ft1 group by c2 order by 1, 2; + sum1 | sum2 +------+-------- + 0 | 0 + 1 | 49600 + 2 | 99400 + 3 | 149400 + 4 | 199600 + 5 | 250000 + 6 | 300600 + 7 | 351400 + 8 | 402400 + 9 | 453600 +(10 rows) + +-- Aggregate with unshippable GROUP BY clause are not pushed +--Testcase 240: +explain (verbose, costs off) +select c2 * (random() <= 1)::int as c2 from ft2 group by c2 * (random() <= 1)::int order by 1; + QUERY PLAN +------------------------------------------------------------------------------ + Sort + Output: ((c2 * ((random() <= '1'::double precision))::integer)) + Sort Key: ((ft2.c2 * ((random() <= '1'::double precision))::integer)) + -> HashAggregate + Output: ((c2 * ((random() <= '1'::double precision))::integer)) + Group Key: (ft2.c2 * ((random() <= '1'::double precision))::integer) + -> Foreign Scan on public.ft2 + Output: (c2 * ((random() <= '1'::double precision))::integer) + InfluxDB query: SELECT "c2" FROM "T1" +(9 rows) + +-- GROUP BY clause in various forms, cardinal, alias and constant expression +--Testcase 241: +explain (verbose, costs off) +select count(c2) w, c2 x, 5 y, 7.0 z from ft1 group by 2, y, 9.0::int order by 2; + QUERY PLAN +----------------------------------------------------- + Sort + Output: (count(c2)), c2, 5, 7.0, 9 + Sort Key: ft1.c2 + -> HashAggregate + Output: count(c2), c2, 5, 7.0, 9 + Group Key: ft1.c2 + -> Foreign Scan on public.ft1 + Output: c2 + InfluxDB query: SELECT "c2" FROM "T1" +(9 rows) + +--Testcase 242: +select count(c2) w, c2 x, 5 y, 7.0 z from ft1 group by 2, y, 9.0::int order by 2; + w | x | y | z +-----+---+---+----- + 100 | 0 | 5 | 7.0 + 100 | 1 | 5 | 7.0 + 100 | 2 | 5 | 7.0 + 100 | 3 | 5 | 7.0 + 100 | 4 | 5 | 7.0 + 100 | 5 | 5 | 7.0 + 100 | 6 | 5 | 7.0 + 100 | 7 | 5 | 7.0 + 100 | 8 | 5 | 7.0 + 100 | 9 | 5 | 7.0 +(10 rows) + +-- GROUP BY clause referring to same column multiple times +-- Also, ORDER BY contains an aggregate function +--Testcase 243: +explain (verbose, costs off) +select c2, c2 from ft1 where c2 > 6 group by 1, 2 order by sum(c1); + QUERY PLAN +------------------------------------------------------------------------------- + Sort + Output: c2, c2, (sum(c1)) + Sort Key: (sum(ft1.c1)) + -> HashAggregate + Output: c2, c2, sum(c1) + Group Key: ft1.c2 + -> Foreign Scan on public.ft1 + Output: c2, c1 + InfluxDB query: SELECT "C 1", "c2" FROM "T1" WHERE (("c2" > 6)) +(9 rows) + +--Testcase 244: +select c2, c2 from ft1 where c2 > 6 group by 1, 2 order by sum(c1); + c2 | c2 +----+---- + 7 | 7 + 8 | 8 + 9 | 9 +(3 rows) + +-- Testing HAVING clause shippability +--Testcase 245: +explain (verbose, costs off) +select c2, sum(c1) from ft2 group by c2 having avg(c1) < 500 and sum(c1) < 49800 order by c2; + QUERY PLAN +---------------------------------------------------------------------------- + Sort + Output: c2, (sum(c1)) + Sort Key: ft2.c2 + -> HashAggregate + Output: c2, sum(c1) + Group Key: ft2.c2 + Filter: ((avg(ft2.c1) < '500'::numeric) AND (sum(ft2.c1) < 49800)) + -> Foreign Scan on public.ft2 + Output: c2, c1 + InfluxDB query: SELECT "C 1", "c2" FROM "T1" +(10 rows) + +--Testcase 246: +select c2, sum(c1) from ft2 group by c2 having avg(c1) < 500 and sum(c1) < 49800 order by c2; + c2 | sum +----+------- + 1 | 49600 + 2 | 49700 +(2 rows) + +-- Unshippable HAVING clause will be evaluated locally, and other qual in HAVING clause is pushed down +--Testcase 247: +explain (verbose, costs off) +select count(*) from (select time, count(c1) from ft1 group by time, sqrt(c2) having (avg(c1) / avg(c1)) * random() <= 1 and avg(c1) < 500) x; + QUERY PLAN +---------------------------------------------------------------------------------------------------------------------------------------------- + Aggregate + Output: count(*) + -> HashAggregate + Output: ft1."time", NULL::bigint, (sqrt((ft1.c2)::double precision)) + Group Key: ft1."time", sqrt((ft1.c2)::double precision) + Filter: ((avg(ft1.c1) < '500'::numeric) AND ((((avg(ft1.c1) / avg(ft1.c1)))::double precision * random()) <= '1'::double precision)) + -> Foreign Scan on public.ft1 + Output: ft1."time", sqrt((ft1.c2)::double precision), ft1.c1 + InfluxDB query: SELECT "C 1", "c2" FROM "T1" +(9 rows) + +--Testcase 248: +select count(*) from (select time, count(c1) from ft1 group by time, sqrt(c2) having (avg(c1) / avg(c1)) * random() <= 1 and avg(c1) < 500) x; + count +------- + 49 +(1 row) + +-- Aggregate in HAVING clause is not pushable, and thus aggregation is not pushed down +--Testcase 249: +explain (verbose, costs off) +select sum(c1) from ft1 group by c2 having avg(c1 * (random() <= 1)::int) > 100 order by 1; + QUERY PLAN +--------------------------------------------------------------------------------------------------- + Sort + Output: (sum(c1)), c2 + Sort Key: (sum(ft1.c1)) + -> HashAggregate + Output: sum(c1), c2 + Group Key: ft1.c2 + Filter: (avg((ft1.c1 * ((random() <= '1'::double precision))::integer)) > '100'::numeric) + -> Foreign Scan on public.ft1 + Output: c1, c2 + InfluxDB query: SELECT "C 1", "c2" FROM "T1" +(10 rows) + +-- Remote aggregate in combination with a local Param (for the output +-- of an initplan) can be trouble, per bug #15781 +--Testcase 250: +explain (verbose, costs off) +select exists(select 1 from pg_enum), sum(c1) from ft1; + QUERY PLAN +----------------------------------------------- + Foreign Scan + Output: $0, (sum(ft1.c1)) + InfluxDB query: SELECT sum("C 1") FROM "T1" + InitPlan 1 (returns $0) + -> Seq Scan on pg_catalog.pg_enum +(5 rows) + +--Testcase 251: +select exists(select 1 from pg_enum), sum(c1) from ft1; + exists | sum +--------+-------- + t | 500500 +(1 row) + +--Testcase 252: +explain (verbose, costs off) +select exists(select 1 from pg_enum), sum(c1) from ft1 group by 1; + QUERY PLAN +------------------------------------------------ + GroupAggregate + Output: $0, sum(ft1.c1) + InitPlan 1 (returns $0) + -> Seq Scan on pg_catalog.pg_enum + -> Foreign Scan on public.ft1 + Output: ft1.c1 + InfluxDB query: SELECT "C 1" FROM "T1" +(7 rows) + +--Testcase 253: +select exists(select 1 from pg_enum), sum(c1) from ft1 group by 1; + exists | sum +--------+-------- + t | 500500 +(1 row) + +-- Testing ORDER BY, DISTINCT, FILTER, Ordered-sets and VARIADIC within aggregates +-- ORDER BY within aggregate, same column used to order +--Testcase 254: +explain (verbose, costs off) +select array_agg(c1 order by c1) from ft1 where c1 < 100 group by c2 order by 1; + QUERY PLAN +---------------------------------------------------------------------------------------- + Sort + Output: (array_agg(c1 ORDER BY c1)), c2 + Sort Key: (array_agg(ft1.c1 ORDER BY ft1.c1)) + -> GroupAggregate + Output: array_agg(c1 ORDER BY c1), c2 + Group Key: ft1.c2 + -> Sort + Output: c2, c1 + Sort Key: ft1.c2, ft1.c1 + -> Foreign Scan on public.ft1 + Output: c2, c1 + InfluxDB query: SELECT "C 1", "c2" FROM "T1" WHERE (("C 1" < 100)) +(12 rows) + +--Testcase 255: +select array_agg(c1 order by c1) from ft1 where c1 < 100 group by c2 order by 1; + array_agg +-------------------------------- + {1,11,21,31,41,51,61,71,81,91} + {2,12,22,32,42,52,62,72,82,92} + {3,13,23,33,43,53,63,73,83,93} + {4,14,24,34,44,54,64,74,84,94} + {5,15,25,35,45,55,65,75,85,95} + {6,16,26,36,46,56,66,76,86,96} + {7,17,27,37,47,57,67,77,87,97} + {8,18,28,38,48,58,68,78,88,98} + {9,19,29,39,49,59,69,79,89,99} + {10,20,30,40,50,60,70,80,90} +(10 rows) + +-- ORDER BY within aggregate, different column used to order also using DESC +--Testcase 256: +explain (verbose, costs off) +select array_agg(time order by c1 desc) from ft2 where c2 = 6 and c1 < 50; + QUERY PLAN +-------------------------------------------------------------------------------------------- + Aggregate + Output: array_agg("time" ORDER BY c1 DESC) + -> Sort + Output: "time", c1 + Sort Key: ft2.c1 DESC + -> Foreign Scan on public.ft2 + Output: "time", c1 + InfluxDB query: SELECT "C 1" FROM "T1" WHERE (("C 1" < 50)) AND (("c2" = 6)) +(8 rows) + +--Testcase 257: +select array_agg(time order by c1 desc) from ft2 where c2 = 6 and c1 < 50; + array_agg +-------------------------------------------------------------------------------------------------------------------------------------------------------------- + {"Mon Feb 16 00:00:00 1970 PST","Fri Feb 06 00:00:00 1970 PST","Tue Jan 27 00:00:00 1970 PST","Sat Jan 17 00:00:00 1970 PST","Wed Jan 07 00:00:00 1970 PST"} +(1 row) + +-- DISTINCT within aggregate +--Testcase 258: +explain (verbose, costs off) +select array_agg(distinct (t1.c1)%5) from ft4 t1 full join ft5 t2 on (t1.c1 = t2.c1) where t1.c1 < 20 or (t1.c1 is null and t2.c1 < 5) group by (t2.c1)%3 order by 1; + QUERY PLAN +--------------------------------------------------------------------------------- + Sort + Output: (array_agg(DISTINCT ((t1.c1 % 5)))), ((t2.c1 % 3)) + Sort Key: (array_agg(DISTINCT ((t1.c1 % 5)))) + -> GroupAggregate + Output: array_agg(DISTINCT ((t1.c1 % 5))), ((t2.c1 % 3)) + Group Key: ((t2.c1 % 3)) + -> Sort + Output: ((t2.c1 % 3)), t1.c1, ((t1.c1 % 5)) + Sort Key: ((t2.c1 % 3)), ((t1.c1 % 5)) + -> Merge Full Join + Output: (t2.c1 % 3), t1.c1, (t1.c1 % 5) + Merge Cond: (t1.c1 = t2.c1) + Filter: ((t1.c1 < 20) OR ((t1.c1 IS NULL) AND (t2.c1 < 5))) + -> Sort + Output: t1.c1 + Sort Key: t1.c1 + -> Foreign Scan on public.ft4 t1 + Output: t1.c1 + InfluxDB query: SELECT "c1" FROM "T3" + -> Sort + Output: t2.c1 + Sort Key: t2.c1 + -> Foreign Scan on public.ft5 t2 + Output: t2.c1 + InfluxDB query: SELECT "c1" FROM "T4" +(25 rows) + +--Testcase 259: +select array_agg(distinct (t1.c1)%5) from ft4 t1 full join ft5 t2 on (t1.c1 = t2.c1) where t1.c1 < 20 or (t1.c1 is null and t2.c1 < 5) group by (t2.c1)%3 order by 1; + array_agg +-------------- + {0,1,2,3,4} + {1,2,3,NULL} +(2 rows) + +-- DISTINCT combined with ORDER BY within aggregate +--Testcase 260: +explain (verbose, costs off) +select array_agg(distinct (t1.c1)%5 order by (t1.c1)%5) from ft4 t1 full join ft5 t2 on (t1.c1 = t2.c1) where t1.c1 < 20 or (t1.c1 is null and t2.c1 < 5) group by (t2.c1)%3 order by 1; + QUERY PLAN +----------------------------------------------------------------------------------------- + Sort + Output: (array_agg(DISTINCT ((t1.c1 % 5)) ORDER BY ((t1.c1 % 5)))), ((t2.c1 % 3)) + Sort Key: (array_agg(DISTINCT ((t1.c1 % 5)) ORDER BY ((t1.c1 % 5)))) + -> GroupAggregate + Output: array_agg(DISTINCT ((t1.c1 % 5)) ORDER BY ((t1.c1 % 5))), ((t2.c1 % 3)) + Group Key: ((t2.c1 % 3)) + -> Sort + Output: ((t2.c1 % 3)), t1.c1, ((t1.c1 % 5)) + Sort Key: ((t2.c1 % 3)), ((t1.c1 % 5)) + -> Merge Full Join + Output: (t2.c1 % 3), t1.c1, (t1.c1 % 5) + Merge Cond: (t1.c1 = t2.c1) + Filter: ((t1.c1 < 20) OR ((t1.c1 IS NULL) AND (t2.c1 < 5))) + -> Sort + Output: t1.c1 + Sort Key: t1.c1 + -> Foreign Scan on public.ft4 t1 + Output: t1.c1 + InfluxDB query: SELECT "c1" FROM "T3" + -> Sort + Output: t2.c1 + Sort Key: t2.c1 + -> Foreign Scan on public.ft5 t2 + Output: t2.c1 + InfluxDB query: SELECT "c1" FROM "T4" +(25 rows) + +--Testcase 261: +select array_agg(distinct (t1.c1)%5 order by (t1.c1)%5) from ft4 t1 full join ft5 t2 on (t1.c1 = t2.c1) where t1.c1 < 20 or (t1.c1 is null and t2.c1 < 5) group by (t2.c1)%3 order by 1; + array_agg +-------------- + {0,1,2,3,4} + {1,2,3,NULL} +(2 rows) + +--Testcase 262: +explain (verbose, costs off) +select array_agg(distinct (t1.c1)%5 order by (t1.c1)%5 desc nulls last) from ft4 t1 full join ft5 t2 on (t1.c1 = t2.c1) where t1.c1 < 20 or (t1.c1 is null and t2.c1 < 5) group by (t2.c1)%3 order by 1; + QUERY PLAN +--------------------------------------------------------------------------------------------------------- + Sort + Output: (array_agg(DISTINCT ((t1.c1 % 5)) ORDER BY ((t1.c1 % 5)) DESC NULLS LAST)), ((t2.c1 % 3)) + Sort Key: (array_agg(DISTINCT ((t1.c1 % 5)) ORDER BY ((t1.c1 % 5)) DESC NULLS LAST)) + -> GroupAggregate + Output: array_agg(DISTINCT ((t1.c1 % 5)) ORDER BY ((t1.c1 % 5)) DESC NULLS LAST), ((t2.c1 % 3)) + Group Key: ((t2.c1 % 3)) + -> Sort + Output: ((t2.c1 % 3)), t1.c1, ((t1.c1 % 5)) + Sort Key: ((t2.c1 % 3)), ((t1.c1 % 5)) DESC NULLS LAST + -> Merge Full Join + Output: (t2.c1 % 3), t1.c1, (t1.c1 % 5) + Merge Cond: (t1.c1 = t2.c1) + Filter: ((t1.c1 < 20) OR ((t1.c1 IS NULL) AND (t2.c1 < 5))) + -> Sort + Output: t1.c1 + Sort Key: t1.c1 + -> Foreign Scan on public.ft4 t1 + Output: t1.c1 + InfluxDB query: SELECT "c1" FROM "T3" + -> Sort + Output: t2.c1 + Sort Key: t2.c1 + -> Foreign Scan on public.ft5 t2 + Output: t2.c1 + InfluxDB query: SELECT "c1" FROM "T4" +(25 rows) + +--Testcase 263: +select array_agg(distinct (t1.c1)%5 order by (t1.c1)%5 desc nulls last) from ft4 t1 full join ft5 t2 on (t1.c1 = t2.c1) where t1.c1 < 20 or (t1.c1 is null and t2.c1 < 5) group by (t2.c1)%3 order by 1; + array_agg +-------------- + {3,2,1,NULL} + {4,3,2,1,0} +(2 rows) + +-- FILTER within aggregate +--Testcase 264: +explain (verbose, costs off) +select sum(c1) filter (where c1 < 100 and c2 > 5) from ft1 group by c2 order by 1 nulls last; + QUERY PLAN +---------------------------------------------------------------------------- + Sort + Output: (sum(c1) FILTER (WHERE ((c1 < 100) AND (c2 > 5)))), c2 + Sort Key: (sum(ft1.c1) FILTER (WHERE ((ft1.c1 < 100) AND (ft1.c2 > 5)))) + -> HashAggregate + Output: sum(c1) FILTER (WHERE ((c1 < 100) AND (c2 > 5))), c2 + Group Key: ft1.c2 + -> Foreign Scan on public.ft1 + Output: c1, c2 + InfluxDB query: SELECT "C 1", "c2" FROM "T1" +(9 rows) + +--Testcase 265: +select sum(c1) filter (where c1 < 100 and c2 > 5) from ft1 group by c2 order by 1 nulls last; + sum +----- + 510 + 520 + 530 + 540 + + + + + + +(10 rows) + +-- DISTINCT, ORDER BY and FILTER within aggregate +--Testcase 266: +explain (verbose, costs off) +select sum(c1%3), sum(distinct c1%3 order by c1%3) filter (where c1%3 < 2), c2 from ft1 where c2 = 6 group by c2; + QUERY PLAN +------------------------------------------------------------------------------------------------------------- + GroupAggregate + Output: sum(((c1 % 3))), sum(DISTINCT ((c1 % 3)) ORDER BY ((c1 % 3))) FILTER (WHERE (((c1 % 3)) < 2)), c2 + -> Sort + Output: c1, c2, ((c1 % 3)) + Sort Key: ((ft1.c1 % 3)) + -> Foreign Scan on public.ft1 + Output: c1, c2, (c1 % 3) + InfluxDB query: SELECT "C 1", "c2" FROM "T1" WHERE (("c2" = 6)) +(8 rows) + +--Testcase 267: +select sum(c1%3), sum(distinct c1%3 order by c1%3) filter (where c1%3 < 2), c2 from ft1 where c2 = 6 group by c2; + sum | sum | c2 +-----+-----+---- + 99 | 1 | 6 +(1 row) + +-- Outer query is aggregation query +--Testcase 268: +explain (verbose, costs off) +select distinct (select count(*) filter (where t2.c2 = 6 and t2.c1 < 10) from ft1 t1 where t1.c1 = 6) from ft2 t2 where t2.c2 % 6 = 0 order by 1; + QUERY PLAN +------------------------------------------------------------------------------------------- + Unique + Output: ((SubPlan 1)) + -> Sort + Output: ((SubPlan 1)) + Sort Key: ((SubPlan 1)) + -> Aggregate + Output: (SubPlan 1) + -> Foreign Scan on public.ft2 t2 + Output: t2.c2, t2.c1 + InfluxDB query: SELECT "C 1", "c2" FROM "T1" WHERE ((("c2" % 6) = 0)) + SubPlan 1 + -> Foreign Scan on public.ft1 t1 + Output: count(*) FILTER (WHERE ((t2.c2 = 6) AND (t2.c1 < 10))) + InfluxDB query: SELECT * FROM "T1" WHERE (("C 1" = 6)) +(14 rows) + +--Testcase 269: +select distinct (select count(*) filter (where t2.c2 = 6 and t2.c1 < 10) from ft1 t1 where t1.c1 = 6) from ft2 t2 where t2.c2 % 6 = 0 order by 1; + count +------- + 1 +(1 row) + +-- Inner query is aggregation query +--Testcase 270: +explain (verbose, costs off) +select distinct (select count(t1.c1) filter (where t2.c2 = 6 and t2.c1 < 10) from ft1 t1 where t1.c1 = 6) from ft2 t2 where t2.c2 % 6 = 0 order by 1; + QUERY PLAN +------------------------------------------------------------------------------------------ + Unique + Output: ((SubPlan 1)) + -> Sort + Output: ((SubPlan 1)) + Sort Key: ((SubPlan 1)) + -> Foreign Scan on public.ft2 t2 + Output: (SubPlan 1) + InfluxDB query: SELECT "C 1", "c2" FROM "T1" WHERE ((("c2" % 6) = 0)) + SubPlan 1 + -> Aggregate + Output: count(t1.c1) FILTER (WHERE ((t2.c2 = 6) AND (t2.c1 < 10))) + -> Foreign Scan on public.ft1 t1 + Output: t1.c1 + InfluxDB query: SELECT "C 1" FROM "T1" WHERE (("C 1" = 6)) +(14 rows) + +--Testcase 271: +select distinct (select count(t1.c1) filter (where t2.c2 = 6 and t2.c1 < 10) from ft1 t1 where t1.c1 = 6) from ft2 t2 where t2.c2 % 6 = 0 order by 1; + count +------- + 0 + 1 +(2 rows) + +-- Aggregate not pushed down as FILTER condition is not pushable +--Testcase 272: +explain (verbose, costs off) +select sum(c1) filter (where (c1 / c1) * random() <= 1) from ft1 group by c2 order by 1; + QUERY PLAN +------------------------------------------------------------------------------------------------------------------------ + Sort + Output: (sum(c1) FILTER (WHERE ((((c1 / c1))::double precision * random()) <= '1'::double precision))), c2 + Sort Key: (sum(ft1.c1) FILTER (WHERE ((((ft1.c1 / ft1.c1))::double precision * random()) <= '1'::double precision))) + -> HashAggregate + Output: sum(c1) FILTER (WHERE ((((c1 / c1))::double precision * random()) <= '1'::double precision)), c2 + Group Key: ft1.c2 + -> Foreign Scan on public.ft1 + Output: c1, c2 + InfluxDB query: SELECT "C 1", "c2" FROM "T1" +(9 rows) + +--Testcase 273: +explain (verbose, costs off) +select sum(c2) filter (where c2 in (select c2 from ft1 where c2 < 5)) from ft1; + QUERY PLAN +-------------------------------------------------------------------- + Aggregate + Output: sum(ft1.c2) FILTER (WHERE (hashed SubPlan 1)) + -> Foreign Scan on public.ft1 + Output: ft1.c2 + InfluxDB query: SELECT "c2" FROM "T1" + SubPlan 1 + -> Foreign Scan on public.ft1 ft1_1 + Output: ft1_1.c2 + InfluxDB query: SELECT "c2" FROM "T1" WHERE (("c2" < 5)) +(9 rows) + +-- Ordered-sets within aggregate +--Testcase 274: +explain (verbose, costs off) +select c2, rank('10'::varchar) within group (order by c6), percentile_cont(c2/10::numeric) within group (order by c1) from ft1 where c2 < 10 group by c2 having percentile_cont(c2/10::numeric) within group (order by c1) < 500 order by c2; + QUERY PLAN +----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- + GroupAggregate + Output: c2, rank('10'::character varying) WITHIN GROUP (ORDER BY c6), percentile_cont((((c2)::numeric / '10'::numeric))::double precision) WITHIN GROUP (ORDER BY ((c1)::double precision)) + Group Key: ft1.c2 + Filter: (percentile_cont((((ft1.c2)::numeric / '10'::numeric))::double precision) WITHIN GROUP (ORDER BY ((ft1.c1)::double precision)) < '500'::double precision) + -> Sort + Output: c2, c6, c1 + Sort Key: ft1.c2 + -> Foreign Scan on public.ft1 + Output: c2, c6, c1 + InfluxDB query: SELECT "C 1", "c2", "c6" FROM "T1" WHERE (("c2" < 10)) +(10 rows) + +--Testcase 275: +select c2, rank('10'::varchar) within group (order by c6), percentile_cont(c2/10::numeric) within group (order by c1) from ft1 where c2 < 10 group by c2 having percentile_cont(c2/10::numeric) within group (order by c1) < 500 order by c2; + c2 | rank | percentile_cont +----+------+----------------- + 0 | 101 | 10 + 1 | 101 | 100 + 2 | 1 | 200 + 3 | 1 | 300 + 4 | 1 | 400 +(5 rows) + +-- Using multiple arguments within aggregates +--Testcase 276: +explain (verbose, costs off) +select c1, rank(c1, c2) within group (order by c1, c2) from ft1 group by c1, c2 having c1 = 6 order by 1; + QUERY PLAN +-------------------------------------------------------------------------------- + GroupAggregate + Output: c1, rank(c1, c2) WITHIN GROUP (ORDER BY c1, c2), c2 + Group Key: ft1.c2 + -> Sort + Output: c2, c1 + Sort Key: ft1.c2 + -> Foreign Scan on public.ft1 + Output: c2, c1 + InfluxDB query: SELECT "C 1", "c2" FROM "T1" WHERE (("C 1" = 6)) +(9 rows) + +--Testcase 277: +select c1, rank(c1, c2) within group (order by c1, c2) from ft1 group by c1, c2 having c1 = 6 order by 1; + c1 | rank +----+------ + 6 | 1 +(1 row) + +-- User defined function for user defined aggregate, VARIADIC +--Testcase 278: +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)'; +--Testcase 279: +create aggregate least_agg(variadic items anyarray) ( + stype = anyelement, sfunc = least_accum +); +-- Disable hash aggregation for plan stability. +--Testcase 280: +set enable_hashagg to false; +-- Not pushed down due to user defined aggregate +--Testcase 281: +explain (verbose, costs off) +select c2, least_agg(c1) from ft1 group by c2 order by c2; + QUERY PLAN +------------------------------------------------------------ + GroupAggregate + Output: c2, least_agg(VARIADIC ARRAY[c1]) + Group Key: ft1.c2 + -> Sort + Output: c2, c1 + Sort Key: ft1.c2 + -> Foreign Scan on public.ft1 + Output: c2, c1 + InfluxDB query: SELECT "C 1", "c2" FROM "T1" +(9 rows) + +-- Add function and aggregate into extension +--Testcase 282: +alter extension influxdb_fdw add function least_accum(anyelement, variadic anyarray); +--Testcase 283: +alter extension influxdb_fdw add aggregate least_agg(variadic items anyarray); +-- Now aggregate will be pushed. Aggregate will display VARIADIC argument. +--Testcase 284: +explain (verbose, costs off) +select c2, least_agg(c1) from ft1 where c2 < 100 group by c2 order by c2; + QUERY PLAN +--------------------------------------------------------------------------------- + GroupAggregate + Output: c2, least_agg(VARIADIC ARRAY[c1]) + Group Key: ft1.c2 + -> Sort + Output: c2, c1 + Sort Key: ft1.c2 + -> Foreign Scan on public.ft1 + Output: c2, c1 + InfluxDB query: SELECT "C 1", "c2" FROM "T1" WHERE (("c2" < 100)) +(9 rows) + +--Testcase 285: +select c2, least_agg(c1) from ft1 where c2 < 100 group by c2 order by c2; + c2 | least_agg +----+----------- + 0 | 10 + 1 | 1 + 2 | 2 + 3 | 3 + 4 | 4 + 5 | 5 + 6 | 6 + 7 | 7 + 8 | 8 + 9 | 9 +(10 rows) + +-- Remove function and aggregate from extension +--Testcase 286: +alter extension influxdb_fdw drop function least_accum(anyelement, variadic anyarray); +--Testcase 287: +alter extension influxdb_fdw drop aggregate least_agg(variadic items anyarray); +-- Not pushed down as we have dropped objects from extension. +--Testcase 288: +explain (verbose, costs off) +select c2, least_agg(c1) from ft1 group by c2 order by c2; + QUERY PLAN +------------------------------------------------------------ + GroupAggregate + Output: c2, least_agg(VARIADIC ARRAY[c1]) + Group Key: ft1.c2 + -> Sort + Output: c2, c1 + Sort Key: ft1.c2 + -> Foreign Scan on public.ft1 + Output: c2, c1 + InfluxDB query: SELECT "C 1", "c2" FROM "T1" +(9 rows) + +-- Cleanup +--Testcase 289: +reset enable_hashagg; +--Testcase 290: +drop aggregate least_agg(variadic items anyarray); +--Testcase 291: +drop function least_accum(anyelement, variadic anyarray); +-- Testing USING OPERATOR() in ORDER BY within aggregate. +-- For this, we need user defined operators along with operator family and +-- operator class. Create those and then add them in extension. Note that +-- user defined objects are considered unshippable unless they are part of +-- the extension. +--Testcase 292: +create operator public.<^ ( + leftarg = int4, + rightarg = int4, + procedure = int4eq +); +--Testcase 293: +create operator public.=^ ( + leftarg = int4, + rightarg = int4, + procedure = int4lt +); +--Testcase 294: +create operator public.>^ ( + leftarg = int4, + rightarg = int4, + procedure = int4gt +); +--Testcase 295: +create operator family my_op_family using btree; +--Testcase 296: +create function my_op_cmp(a int, b int) returns int as + $$begin return btint4cmp(a, b); end $$ language plpgsql; +--Testcase 297: +create operator class my_op_class for type int using btree family my_op_family as + operator 1 public.<^, + operator 3 public.=^, + operator 5 public.>^, + function 1 my_op_cmp(int, int); +-- This will not be pushed as user defined sort operator is not part of the +-- extension yet. +--Testcase 298: +explain (verbose, costs off) +select array_agg(c1 order by c1 using operator(public.<^)) from ft2 where c2 = 6 and c1 < 100 group by c2; + QUERY PLAN +--------------------------------------------------------------------------------------------------- + GroupAggregate + Output: array_agg(c1 ORDER BY c1 USING <^ NULLS LAST), c2 + -> Sort + Output: c1, c2 + Sort Key: ft2.c1 USING <^ + -> Foreign Scan on public.ft2 + Output: c1, c2 + InfluxDB query: SELECT "C 1", "c2" FROM "T1" WHERE (("C 1" < 100)) AND (("c2" = 6)) +(8 rows) + +-- This should not be pushed either. +--Testcase 766: +explain (verbose, costs off) +select * from ft2 order by c1 using operator(public.<^); + QUERY PLAN +------------------------------------------------------------------------------ + Sort + Output: c1, c2, c3, "time", c6, c7, c8 + Sort Key: ft2.c1 USING <^ + -> Foreign Scan on public.ft2 + Output: c1, c2, c3, "time", c6, c7, c8 + InfluxDB query: SELECT "C 1", "c2", "c3", "c6", "c7", "c8" FROM "T1" +(6 rows) + +-- Update local stats on ft2 +--ANALYZE ft2; +-- Add into extension +--Testcase 299: +alter extension influxdb_fdw add operator class my_op_class using btree; +--Testcase 300: +alter extension influxdb_fdw add function my_op_cmp(a int, b int); +--Testcase 301: +alter extension influxdb_fdw add operator family my_op_family using btree; +--Testcase 302: +alter extension influxdb_fdw add operator public.<^(int, int); +--Testcase 303: +alter extension influxdb_fdw add operator public.=^(int, int); +--Testcase 304: +alter extension influxdb_fdw add operator public.>^(int, int); +-- Now this will be pushed as sort operator is part of the extension. +-- alter server loopback options (add fdw_tuple_cost '0.5'); +--Testcase 305: +explain (verbose, costs off) +select array_agg(c1 order by c1 using operator(public.<^)) from ft2 where c2 = 6 and c1 < 100 group by c2; + QUERY PLAN +--------------------------------------------------------------------------------------------------- + GroupAggregate + Output: array_agg(c1 ORDER BY c1 USING <^ NULLS LAST), c2 + -> Sort + Output: c1, c2 + Sort Key: ft2.c1 USING <^ + -> Foreign Scan on public.ft2 + Output: c1, c2 + InfluxDB query: SELECT "C 1", "c2" FROM "T1" WHERE (("C 1" < 100)) AND (("c2" = 6)) +(8 rows) + +--Testcase 306: +select array_agg(c1 order by c1 using operator(public.<^)) from ft2 where c2 = 6 and c1 < 100 group by c2; + array_agg +-------------------------------- + {6,16,26,36,46,56,66,76,86,96} +(1 row) + +-- alter server loopback options (drop fdw_tuple_cost); +-- This should be pushed too. +-- Influx not support user-defined operator +--Testcase 767: +explain (verbose, costs off) +select * from ft2 order by c1 using operator(public.<^); + QUERY PLAN +------------------------------------------------------------------------------ + Sort + Output: c1, c2, c3, "time", c6, c7, c8 + Sort Key: ft2.c1 USING <^ + -> Foreign Scan on public.ft2 + Output: c1, c2, c3, "time", c6, c7, c8 + InfluxDB query: SELECT "C 1", "c2", "c3", "c6", "c7", "c8" FROM "T1" +(6 rows) + +-- Remove from extension +--Testcase 307: +alter extension influxdb_fdw drop operator class my_op_class using btree; +--Testcase 308: +alter extension influxdb_fdw drop function my_op_cmp(a int, b int); +--Testcase 309: +alter extension influxdb_fdw drop operator family my_op_family using btree; +--Testcase 310: +alter extension influxdb_fdw drop operator public.<^(int, int); +--Testcase 311: +alter extension influxdb_fdw drop operator public.=^(int, int); +--Testcase 312: +alter extension influxdb_fdw drop operator public.>^(int, int); +-- This will not be pushed as sort operator is now removed from the extension. +--Testcase 313: +explain (verbose, costs off) +select array_agg(c1 order by c1 using operator(public.<^)) from ft2 where c2 = 6 and c1 < 100 group by c2; + QUERY PLAN +--------------------------------------------------------------------------------------------------- + GroupAggregate + Output: array_agg(c1 ORDER BY c1 USING <^ NULLS LAST), c2 + -> Sort + Output: c1, c2 + Sort Key: ft2.c1 USING <^ + -> Foreign Scan on public.ft2 + Output: c1, c2 + InfluxDB query: SELECT "C 1", "c2" FROM "T1" WHERE (("C 1" < 100)) AND (("c2" = 6)) +(8 rows) + +-- Cleanup +--Testcase 314: +drop operator class my_op_class using btree; +--Testcase 315: +drop function my_op_cmp(a int, b int); +--Testcase 316: +drop operator family my_op_family using btree; +--Testcase 317: +drop operator public.>^(int, int); +--Testcase 318: +drop operator public.=^(int, int); +--Testcase 319: +drop operator public.<^(int, int); +-- Input relation to aggregate push down hook is not safe to pushdown and thus +-- the aggregate cannot be pushed down to foreign server. +--Testcase 320: +explain (verbose, costs off) +select count(t1.c3) from ft2 t1 left join ft2 t2 on (t1.c1 = random() * t2.c2); + QUERY PLAN +------------------------------------------------------------------------------------------- + Aggregate + Output: count(t1.c3) + -> Nested Loop Left Join + Output: t1.c3 + Join Filter: ((t1.c1)::double precision = (random() * (t2.c2)::double precision)) + -> Foreign Scan on public.ft2 t1 + Output: t1.c3, t1.c1 + InfluxDB query: SELECT "C 1", "c3" FROM "T1" + -> Materialize + Output: t2.c2 + -> Foreign Scan on public.ft2 t2 + Output: t2.c2 + InfluxDB query: SELECT "c2" FROM "T1" +(13 rows) + +-- Subquery in FROM clause having aggregate +--Testcase 321: +explain (verbose, costs off) +select count(*), x.b from ft1, (select c2 a, sum(c1) b from ft1 group by c2) x where ft1.c2 = x.a group by x.b order by 1, 2; + QUERY PLAN +------------------------------------------------------------------------------------ + Sort + Output: (count(*)), x.b + Sort Key: (count(*)), x.b + -> HashAggregate + Output: count(*), x.b + Group Key: x.b + -> Hash Join + Output: x.b + Inner Unique: true + Hash Cond: (ft1.c2 = x.a) + -> Foreign Scan on public.ft1 + Output: ft1.c2 + InfluxDB query: SELECT "c2" FROM "T1" + -> Hash + Output: x.b, x.a + -> Subquery Scan on x + Output: x.b, x.a + -> HashAggregate + Output: ft1_1.c2, sum(ft1_1.c1) + Group Key: ft1_1.c2 + -> Foreign Scan on public.ft1 ft1_1 + Output: ft1_1.c2, ft1_1.c1 + InfluxDB query: SELECT "C 1", "c2" FROM "T1" +(23 rows) + +--Testcase 322: +select count(*), x.b from ft1, (select c2 a, sum(c1) b from ft1 group by c2) x where ft1.c2 = x.a group by x.b order by 1, 2; + count | b +-------+------- + 100 | 49600 + 100 | 49700 + 100 | 49800 + 100 | 49900 + 100 | 50000 + 100 | 50100 + 100 | 50200 + 100 | 50300 + 100 | 50400 + 100 | 50500 +(10 rows) + +-- FULL join with IS NULL check in HAVING +--Testcase 323: +explain (verbose, costs off) +select avg(t1.c1), sum(t2.c1) from ft4 t1 full join ft5 t2 on (t1.c1 = t2.c1) group by t2.c1 having (avg(t1.c1) is null and sum(t2.c1) < 10) or sum(t2.c1) is null order by 1 nulls last, 2; + QUERY PLAN +---------------------------------------------------------------------------------------- + Sort + Output: (avg(t1.c1)), (sum(t2.c1)), t2.c1 + Sort Key: (avg(t1.c1)), (sum(t2.c1)) + -> HashAggregate + Output: avg(t1.c1), sum(t2.c1), t2.c1 + Group Key: t2.c1 + Filter: (((avg(t1.c1) IS NULL) AND (sum(t2.c1) < 10)) OR (sum(t2.c1) IS NULL)) + -> Merge Full Join + Output: t2.c1, t1.c1 + Merge Cond: (t1.c1 = t2.c1) + -> Sort + Output: t1.c1 + Sort Key: t1.c1 + -> Foreign Scan on public.ft4 t1 + Output: t1.c1 + InfluxDB query: SELECT "c1" FROM "T3" + -> Sort + Output: t2.c1 + Sort Key: t2.c1 + -> Foreign Scan on public.ft5 t2 + Output: t2.c1 + InfluxDB query: SELECT "c1" FROM "T4" +(22 rows) + +--Testcase 324: +select avg(t1.c1), sum(t2.c1) from ft4 t1 full join ft5 t2 on (t1.c1 = t2.c1) group by t2.c1 having (avg(t1.c1) is null and sum(t2.c1) < 10) or sum(t2.c1) is null order by 1 nulls last, 2; + avg | sum +---------------------+----- + 51.0000000000000000 | + | 3 + | 9 +(3 rows) + +-- Aggregate over FULL join needing to deparse the joining relations as +-- subqueries. +--Testcase 325: +explain (verbose, costs off) +select count(*), sum(t1.c1), avg(t2.c1) from (select c1 from ft4 where c1 between 50 and 60) t1 full join (select c1 from ft5 where c1 between 50 and 60) t2 on (t1.c1 = t2.c1); + QUERY PLAN +--------------------------------------------------------------------------------------------------- + Aggregate + Output: count(*), sum(ft4.c1), avg(ft5.c1) + -> Hash Full Join + Output: ft4.c1, ft5.c1 + Hash Cond: (ft4.c1 = ft5.c1) + -> Foreign Scan on public.ft4 + Output: ft4.c1, ft4.c2, ft4.c3 + InfluxDB query: SELECT "c1" FROM "T3" WHERE (("c1" >= 50)) AND (("c1" <= 60)) + -> Hash + Output: ft5.c1 + -> Foreign Scan on public.ft5 + Output: ft5.c1 + InfluxDB query: SELECT "c1" FROM "T4" WHERE (("c1" >= 50)) AND (("c1" <= 60)) +(13 rows) + +--Testcase 326: +select count(*), sum(t1.c1), avg(t2.c1) from (select c1 from ft4 where c1 between 50 and 60) t1 full join (select c1 from ft5 where c1 between 50 and 60) t2 on (t1.c1 = t2.c1); + count | sum | avg +-------+-----+--------------------- + 8 | 330 | 55.5000000000000000 +(1 row) + +-- ORDER BY expression is part of the target list but not pushed down to +-- foreign server. +--Testcase 327: +explain (verbose, costs off) +select sum(c2) * (random() <= 1)::int as sum from ft1 order by 1; + QUERY PLAN +-------------------------------------------------------------------------------- + Sort + Output: (((sum(c2)) * ((random() <= '1'::double precision))::integer)) + Sort Key: (((sum(ft1.c2)) * ((random() <= '1'::double precision))::integer)) + -> Foreign Scan + Output: ((sum(c2)) * ((random() <= '1'::double precision))::integer) + InfluxDB query: SELECT sum("c2") FROM "T1" +(6 rows) + +--Testcase 328: +select sum(c2) * (random() <= 1)::int as sum from ft1 order by 1; + sum +------ + 4500 +(1 row) + +-- LATERAL join, with parameterization +--Testcase 329: +set enable_hashagg to false; +--Testcase 330: +explain (verbose, costs off) +select c2, sum from "S 1"."T 1" t1, lateral (select sum(t2.c1 + t1."C 1") sum from ft2 t2 group by t2.c1) qry where t1.c2 * 2 = qry.sum and t1.c2 < 3 and t1."C 1" < 100 order by 1; + QUERY PLAN +--------------------------------------------------------------------------------------------------- + Sort + Output: t1.c2, qry.sum + Sort Key: t1.c2 + -> Nested Loop + Output: t1.c2, qry.sum + -> Foreign Scan on "S 1"."T 1" t1 + Output: t1."C 1", t1.c2, t1.c3, t1."time", t1.c6, t1.c7, t1.c8 + InfluxDB query: SELECT "C 1", "c2" FROM "T1" WHERE (("c2" < 3)) AND (("C 1" < 100)) + -> Subquery Scan on qry + Output: qry.sum, t2.c1 + Filter: ((t1.c2 * 2) = qry.sum) + -> GroupAggregate + Output: sum((t2.c1 + t1."C 1")), t2.c1 + Group Key: t2.c1 + -> Sort + Output: t2.c1 + Sort Key: t2.c1 + -> Foreign Scan on public.ft2 t2 + Output: t2.c1 + InfluxDB query: SELECT "C 1" FROM "T1" +(20 rows) + +--Testcase 331: +select c2, sum from "S 1"."T 1" t1, lateral (select sum(t2.c1 + t1."C 1") sum from ft2 t2 group by t2.c1) qry where t1.c2 * 2 = qry.sum and t1.c2 < 3 and t1."C 1" < 100 order by 1; + c2 | sum +----+----- + 1 | 2 + 2 | 4 +(2 rows) + +--Testcase 332: +reset enable_hashagg; +-- bug #15613: bad plan for foreign table scan with lateral reference +--Testcase 333: +EXPLAIN (VERBOSE, COSTS OFF) +SELECT ref_0.c2, subq_1.* +FROM + "S 1"."T 1" AS ref_0, + LATERAL ( + SELECT ref_0."C 1" c1, subq_0.* + FROM (SELECT ref_0.c2, ref_1.c3 + FROM ft1 AS ref_1) AS subq_0 + RIGHT JOIN ft2 AS ref_3 ON (subq_0.c3 = ref_3.c3) + ) AS subq_1 +WHERE ref_0."C 1" < 10 AND subq_1.c3 = '00001' +ORDER BY ref_0."C 1"; + QUERY PLAN +--------------------------------------------------------------------------------------------------------- + Sort + Output: ref_0.c2, ref_0."C 1", (ref_0.c2), ref_1.c3, ref_0."C 1" + Sort Key: ref_0."C 1" + -> Nested Loop + Output: ref_0.c2, ref_0."C 1", (ref_0.c2), ref_1.c3, ref_0."C 1" + -> Nested Loop + Output: ref_0.c2, ref_0."C 1", ref_1.c3, (ref_0.c2) + -> Foreign Scan on "S 1"."T 1" ref_0 + Output: ref_0."C 1", ref_0.c2, ref_0.c3, ref_0."time", ref_0.c6, ref_0.c7, ref_0.c8 + InfluxDB query: SELECT "C 1", "c2" FROM "T1" WHERE (("C 1" < 10)) + -> Foreign Scan on public.ft1 ref_1 + Output: ref_1.c3, ref_0.c2 + InfluxDB query: SELECT "c3", "C 1" FROM "T1" WHERE (("c3" = '00001')) + -> Materialize + Output: ref_3.c3 + -> Foreign Scan on public.ft2 ref_3 + Output: ref_3.c3 + InfluxDB query: SELECT "c3", "C 1" FROM "T1" WHERE (("c3" = '00001')) +(18 rows) + +--Testcase 334: +SELECT ref_0.c2, subq_1.* +FROM + "S 1"."T 1" AS ref_0, + LATERAL ( + SELECT ref_0."C 1" c1, subq_0.* + FROM (SELECT ref_0.c2, ref_1.c3 + FROM ft1 AS ref_1) AS subq_0 + RIGHT JOIN ft2 AS ref_3 ON (subq_0.c3 = ref_3.c3) + ) AS subq_1 +WHERE ref_0."C 1" < 10 AND subq_1.c3 = '00001' +ORDER BY ref_0."C 1"; + c2 | c1 | c2 | c3 +----+----+----+------- + 1 | 1 | 1 | 00001 + 2 | 2 | 2 | 00001 + 3 | 3 | 3 | 00001 + 4 | 4 | 4 | 00001 + 5 | 5 | 5 | 00001 + 6 | 6 | 6 | 00001 + 7 | 7 | 7 | 00001 + 8 | 8 | 8 | 00001 + 9 | 9 | 9 | 00001 +(9 rows) + +-- Check with placeHolderVars +--Testcase 335: +explain (verbose, costs off) +select sum(q.a), count(q.b) from ft4 left join (select 13, avg(ft1.c1), sum(ft2.c1) from ft1 right join ft2 on (ft1.c1 = ft2.c1)) q(a, b, c) on (ft4.c1 <= q.b); + QUERY PLAN +------------------------------------------------------------------------------------ + Aggregate + Output: sum(q.a), count(q.b) + -> Nested Loop Left Join + Output: q.a, q.b + Inner Unique: true + Join Filter: ((ft4.c1)::numeric <= q.b) + -> Foreign Scan on public.ft4 + Output: ft4.c1, ft4.c2, ft4.c3 + InfluxDB query: SELECT "c1" FROM "T3" + -> Materialize + Output: q.a, q.b + -> Subquery Scan on q + Output: q.a, q.b + -> Aggregate + Output: 13, avg(ft1.c1), NULL::bigint + -> Merge Left Join + Output: ft1.c1 + Merge Cond: (ft2.c1 = ft1.c1) + -> Sort + Output: ft2.c1 + Sort Key: ft2.c1 + -> Foreign Scan on public.ft2 + Output: ft2.c1 + InfluxDB query: SELECT "C 1" FROM "T1" + -> Sort + Output: ft1.c1 + Sort Key: ft1.c1 + -> Foreign Scan on public.ft1 + Output: ft1.c1 + InfluxDB query: SELECT "C 1" FROM "T1" +(30 rows) + +--Testcase 336: +select sum(q.a), count(q.b) from ft4 left join (select 13, avg(ft1.c1), sum(ft2.c1) from ft1 right join ft2 on (ft1.c1 = ft2.c1)) q(a, b, c) on (ft4.c1 <= q.b); + sum | count +-----+------- + 650 | 50 +(1 row) + +-- Not supported cases +-- Grouping sets +--Testcase 337: +explain (verbose, costs off) +select c2, sum(c1) from ft1 where c2 < 3 group by rollup(c2) order by 1 nulls last; + QUERY PLAN +------------------------------------------------------------------------------- + Sort + Output: c2, (sum(c1)) + Sort Key: ft1.c2 + -> MixedAggregate + Output: c2, sum(c1) + Hash Key: ft1.c2 + Group Key: () + -> Foreign Scan on public.ft1 + Output: c2, c1 + InfluxDB query: SELECT "C 1", "c2" FROM "T1" WHERE (("c2" < 3)) +(10 rows) + +--Testcase 338: +select c2, sum(c1) from ft1 where c2 < 3 group by rollup(c2) order by 1 nulls last; + c2 | sum +----+-------- + 0 | 50500 + 1 | 49600 + 2 | 49700 + | 149800 +(4 rows) + +--Testcase 339: +explain (verbose, costs off) +select c2, sum(c1) from ft1 where c2 < 3 group by cube(c2) order by 1 nulls last; + QUERY PLAN +------------------------------------------------------------------------------- + Sort + Output: c2, (sum(c1)) + Sort Key: ft1.c2 + -> MixedAggregate + Output: c2, sum(c1) + Hash Key: ft1.c2 + Group Key: () + -> Foreign Scan on public.ft1 + Output: c2, c1 + InfluxDB query: SELECT "C 1", "c2" FROM "T1" WHERE (("c2" < 3)) +(10 rows) + +--Testcase 340: +select c2, sum(c1) from ft1 where c2 < 3 group by cube(c2) order by 1 nulls last; + c2 | sum +----+-------- + 0 | 50500 + 1 | 49600 + 2 | 49700 + | 149800 +(4 rows) + +--Testcase 341: +explain (verbose, costs off) +select c2, c6, sum(c1) from ft1 where c2 < 3 group by grouping sets(c2, c6) order by 1 nulls last, 2 nulls last; + QUERY PLAN +------------------------------------------------------------------------------------- + Sort + Output: c2, c6, (sum(c1)) + Sort Key: ft1.c2, ft1.c6 + -> HashAggregate + Output: c2, c6, sum(c1) + Hash Key: ft1.c2 + Hash Key: ft1.c6 + -> Foreign Scan on public.ft1 + Output: c2, c6, c1 + InfluxDB query: SELECT "C 1", "c2", "c6" FROM "T1" WHERE (("c2" < 3)) +(10 rows) + +--Testcase 342: +select c2, c6, sum(c1) from ft1 where c2 < 3 group by grouping sets(c2, c6) order by 1 nulls last, 2 nulls last; + c2 | c6 | sum +----+----+------- + 0 | | 50500 + 1 | | 49600 + 2 | | 49700 + | 0 | 50500 + | 1 | 49600 + | 2 | 49700 +(6 rows) + +--Testcase 343: +explain (verbose, costs off) +select c2, sum(c1), grouping(c2) from ft1 where c2 < 3 group by c2 order by 1 nulls last; + QUERY PLAN +------------------------------------------------------------------------------- + Sort + Output: c2, (sum(c1)), (GROUPING(c2)) + Sort Key: ft1.c2 + -> HashAggregate + Output: c2, sum(c1), GROUPING(c2) + Group Key: ft1.c2 + -> Foreign Scan on public.ft1 + Output: c2, c1 + InfluxDB query: SELECT "C 1", "c2" FROM "T1" WHERE (("c2" < 3)) +(9 rows) + +--Testcase 344: +select c2, sum(c1), grouping(c2) from ft1 where c2 < 3 group by c2 order by 1 nulls last; + c2 | sum | grouping +----+-------+---------- + 0 | 50500 | 0 + 1 | 49600 | 0 + 2 | 49700 | 0 +(3 rows) + +-- DISTINCT itself is not pushed down, whereas underneath aggregate is pushed +--Testcase 345: +explain (verbose, costs off) +select distinct sum(c1)/1000 s from ft2 where c2 < 6 group by c2 order by 1; + QUERY PLAN +------------------------------------------------------------------------------------- + Unique + Output: ((sum(c1) / 1000)), c2 + -> Sort + Output: ((sum(c1) / 1000)), c2 + Sort Key: ((sum(ft2.c1) / 1000)) + -> HashAggregate + Output: (sum(c1) / 1000), c2 + Group Key: ft2.c2 + -> Foreign Scan on public.ft2 + Output: c1, c2 + InfluxDB query: SELECT "C 1", "c2" FROM "T1" WHERE (("c2" < 6)) +(11 rows) + +--Testcase 346: +select distinct sum(c1)/1000 s from ft2 where c2 < 6 group by c2 order by 1; + s +---- + 49 + 50 +(2 rows) + +-- WindowAgg +--Testcase 347: +explain (verbose, costs off) +select c2, sum(c2), count(c2) over (partition by c2%2) from ft2 where c2 < 10 group by c2 order by 1; + QUERY PLAN +------------------------------------------------------------------------------------- + Sort + Output: c2, (sum(c2)), (count(c2) OVER (?)), ((c2 % 2)) + Sort Key: ft2.c2 + -> WindowAgg + Output: c2, (sum(c2)), count(c2) OVER (?), ((c2 % 2)) + -> Sort + Output: c2, ((c2 % 2)), (sum(c2)) + Sort Key: ((ft2.c2 % 2)) + -> HashAggregate + Output: c2, (c2 % 2), sum(c2) + Group Key: ft2.c2 + -> Foreign Scan on public.ft2 + Output: c2 + InfluxDB query: SELECT "c2" FROM "T1" WHERE (("c2" < 10)) +(14 rows) + +--Testcase 348: +select c2, sum(c2), count(c2) over (partition by c2%2) from ft2 where c2 < 10 group by c2 order by 1; + c2 | sum | count +----+-----+------- + 0 | 0 | 5 + 1 | 100 | 5 + 2 | 200 | 5 + 3 | 300 | 5 + 4 | 400 | 5 + 5 | 500 | 5 + 6 | 600 | 5 + 7 | 700 | 5 + 8 | 800 | 5 + 9 | 900 | 5 +(10 rows) + +--Testcase 349: +explain (verbose, costs off) +select c2, array_agg(c2) over (partition by c2%2 order by c2 desc) from ft1 where c2 < 10 group by c2 order by 1; + QUERY PLAN +------------------------------------------------------------------------------------- + Sort + Output: c2, (array_agg(c2) OVER (?)), ((c2 % 2)) + Sort Key: ft1.c2 + -> WindowAgg + Output: c2, array_agg(c2) OVER (?), ((c2 % 2)) + -> Sort + Output: c2, ((c2 % 2)) + Sort Key: ((ft1.c2 % 2)), ft1.c2 DESC + -> HashAggregate + Output: c2, (c2 % 2) + Group Key: ft1.c2 + -> Foreign Scan on public.ft1 + Output: c2 + InfluxDB query: SELECT "c2" FROM "T1" WHERE (("c2" < 10)) +(14 rows) + +--Testcase 350: +select c2, array_agg(c2) over (partition by c2%2 order by c2 desc) from ft1 where c2 < 10 group by c2 order by 1; + c2 | array_agg +----+------------- + 0 | {8,6,4,2,0} + 1 | {9,7,5,3,1} + 2 | {8,6,4,2} + 3 | {9,7,5,3} + 4 | {8,6,4} + 5 | {9,7,5} + 6 | {8,6} + 7 | {9,7} + 8 | {8} + 9 | {9} +(10 rows) + +--Testcase 351: +explain (verbose, costs off) +select c2, array_agg(c2) over (partition by c2%2 order by c2 range between current row and unbounded following) from ft1 where c2 < 10 group by c2 order by 1; + QUERY PLAN +------------------------------------------------------------------------------------- + Sort + Output: c2, (array_agg(c2) OVER (?)), ((c2 % 2)) + Sort Key: ft1.c2 + -> WindowAgg + Output: c2, array_agg(c2) OVER (?), ((c2 % 2)) + -> Sort + Output: c2, ((c2 % 2)) + Sort Key: ((ft1.c2 % 2)), ft1.c2 + -> HashAggregate + Output: c2, (c2 % 2) + Group Key: ft1.c2 + -> Foreign Scan on public.ft1 + Output: c2 + InfluxDB query: SELECT "c2" FROM "T1" WHERE (("c2" < 10)) +(14 rows) + +--Testcase 352: +select c2, array_agg(c2) over (partition by c2%2 order by c2 range between current row and unbounded following) from ft1 where c2 < 10 group by c2 order by 1; + c2 | array_agg +----+------------- + 0 | {0,2,4,6,8} + 1 | {1,3,5,7,9} + 2 | {2,4,6,8} + 3 | {3,5,7,9} + 4 | {4,6,8} + 5 | {5,7,9} + 6 | {6,8} + 7 | {7,9} + 8 | {8} + 9 | {9} +(10 rows) + +-- =================================================================== +-- parameterized queries +-- =================================================================== +-- simple join +--Testcase 353: +PREPARE st1(int, int) AS SELECT t1.c3, t2.c3 FROM ft1 t1, ft2 t2 WHERE t1.c1 = $1 AND t2.c1 = $2; +--Testcase 354: +EXPLAIN (VERBOSE, COSTS OFF) EXECUTE st1(1, 2); + QUERY PLAN +-------------------------------------------------------------------------------- + Nested Loop + Output: t1.c3, t2.c3 + -> Foreign Scan on public.ft1 t1 + Output: t1.c3 + InfluxDB query: SELECT "c3", "C 1" FROM "T1" WHERE (("C 1" = 1)) + -> Materialize + Output: t2.c3 + -> Foreign Scan on public.ft2 t2 + Output: t2.c3 + InfluxDB query: SELECT "c3", "C 1" FROM "T1" WHERE (("C 1" = 2)) +(10 rows) + +--Testcase 355: +EXECUTE st1(1, 1); + c3 | c3 +-------+------- + 00001 | 00001 +(1 row) + +--Testcase 356: +EXECUTE st1(101, 101); + c3 | c3 +-------+------- + 00101 | 00101 +(1 row) + +-- subquery using stable function (can't be sent to remote) +--Testcase 357: +PREPARE st2(int) AS SELECT * FROM ft1 t1 WHERE t1.c1 < $2 AND t1.c3 IN (SELECT c3 FROM ft2 t2 WHERE c1 > $1 AND date(time) = '1970-01-17'::date) ORDER BY c1; +--Testcase 358: +EXPLAIN (VERBOSE, COSTS OFF) EXECUTE st2(10, 20); + QUERY PLAN +--------------------------------------------------------------------------------------------------------- + Sort + Output: t1.c1, t1.c2, t1.c3, t1."time", t1.c6, t1.c7, t1.c8 + Sort Key: t1.c1 + -> Hash Semi Join + Output: t1.c1, t1.c2, t1.c3, t1."time", t1.c6, t1.c7, t1.c8 + Hash Cond: (t1.c3 = t2.c3) + -> Foreign Scan on public.ft1 t1 + Output: t1.c1, t1.c2, t1.c3, t1."time", t1.c6, t1.c7, t1.c8 + InfluxDB query: SELECT "C 1", "c2", "c3", "c6", "c7", "c8" FROM "T1" WHERE (("C 1" < 20)) + -> Hash + Output: t2.c3 + -> Foreign Scan on public.ft2 t2 + Output: t2.c3 + Filter: (date(t2."time") = '01-17-1970'::date) + InfluxDB query: SELECT "c3", "C 1" FROM "T1" WHERE (("C 1" > 10)) +(15 rows) + +--Testcase 359: +EXECUTE st2(10, 20); + c1 | c2 | c3 | time | c6 | c7 | c8 +----+----+-------+------------------------------+----+------------+----- + 16 | 6 | 00016 | Sat Jan 17 00:00:00 1970 PST | 6 | 6 | foo +(1 row) + +--Testcase 360: +EXECUTE st2(101, 121); + c1 | c2 | c3 | time | c6 | c7 | c8 +-----+----+-------+------------------------------+----+------------+----- + 116 | 6 | 00116 | Sat Jan 17 00:00:00 1970 PST | 6 | 6 | foo +(1 row) + +-- subquery using immutable function (can be sent to remote) +--Testcase 361: +PREPARE st3(int) AS SELECT * FROM ft1 t1 WHERE t1.c1 < $2 AND t1.c3 IN (SELECT c3 FROM ft2 t2 WHERE c1 > $1 AND date(time) = '1970-01-17'::date) ORDER BY c1; +--Testcase 362: +EXPLAIN (VERBOSE, COSTS OFF) EXECUTE st3(10, 20); + QUERY PLAN +--------------------------------------------------------------------------------------------------------- + Sort + Output: t1.c1, t1.c2, t1.c3, t1."time", t1.c6, t1.c7, t1.c8 + Sort Key: t1.c1 + -> Hash Semi Join + Output: t1.c1, t1.c2, t1.c3, t1."time", t1.c6, t1.c7, t1.c8 + Hash Cond: (t1.c3 = t2.c3) + -> Foreign Scan on public.ft1 t1 + Output: t1.c1, t1.c2, t1.c3, t1."time", t1.c6, t1.c7, t1.c8 + InfluxDB query: SELECT "C 1", "c2", "c3", "c6", "c7", "c8" FROM "T1" WHERE (("C 1" < 20)) + -> Hash + Output: t2.c3 + -> Foreign Scan on public.ft2 t2 + Output: t2.c3 + Filter: (date(t2."time") = '01-17-1970'::date) + InfluxDB query: SELECT "c3", "C 1" FROM "T1" WHERE (("C 1" > 10)) +(15 rows) + +--Testcase 363: +EXECUTE st3(10, 20); + c1 | c2 | c3 | time | c6 | c7 | c8 +----+----+-------+------------------------------+----+------------+----- + 16 | 6 | 00016 | Sat Jan 17 00:00:00 1970 PST | 6 | 6 | foo +(1 row) + +--Testcase 364: +EXECUTE st3(20, 30); + c1 | c2 | c3 | time | c6 | c7 | c8 +----+----+----+------+----+----+---- +(0 rows) + +-- custom plan should be chosen initially +--Testcase 365: +PREPARE st4(int) AS SELECT * FROM ft1 t1 WHERE t1.c1 = $1; +--Testcase 366: +EXPLAIN (VERBOSE, COSTS OFF) EXECUTE st4(1); + QUERY PLAN +-------------------------------------------------------------------------------------------- + Foreign Scan on public.ft1 t1 + Output: c1, c2, c3, "time", c6, c7, c8 + InfluxDB query: SELECT "C 1", "c2", "c3", "c6", "c7", "c8" FROM "T1" WHERE (("C 1" = 1)) +(3 rows) + +--Testcase 367: +EXPLAIN (VERBOSE, COSTS OFF) EXECUTE st4(1); + QUERY PLAN +-------------------------------------------------------------------------------------------- + Foreign Scan on public.ft1 t1 + Output: c1, c2, c3, "time", c6, c7, c8 + InfluxDB query: SELECT "C 1", "c2", "c3", "c6", "c7", "c8" FROM "T1" WHERE (("C 1" = 1)) +(3 rows) + +--Testcase 368: +EXPLAIN (VERBOSE, COSTS OFF) EXECUTE st4(1); + QUERY PLAN +-------------------------------------------------------------------------------------------- + Foreign Scan on public.ft1 t1 + Output: c1, c2, c3, "time", c6, c7, c8 + InfluxDB query: SELECT "C 1", "c2", "c3", "c6", "c7", "c8" FROM "T1" WHERE (("C 1" = 1)) +(3 rows) + +--Testcase 369: +EXPLAIN (VERBOSE, COSTS OFF) EXECUTE st4(1); + QUERY PLAN +-------------------------------------------------------------------------------------------- + Foreign Scan on public.ft1 t1 + Output: c1, c2, c3, "time", c6, c7, c8 + InfluxDB query: SELECT "C 1", "c2", "c3", "c6", "c7", "c8" FROM "T1" WHERE (("C 1" = 1)) +(3 rows) + +--Testcase 370: +EXPLAIN (VERBOSE, COSTS OFF) EXECUTE st4(1); + QUERY PLAN +-------------------------------------------------------------------------------------------- + Foreign Scan on public.ft1 t1 + Output: c1, c2, c3, "time", c6, c7, c8 + InfluxDB query: SELECT "C 1", "c2", "c3", "c6", "c7", "c8" FROM "T1" WHERE (("C 1" = 1)) +(3 rows) + +-- once we try it enough times, should switch to generic plan +--Testcase 371: +EXPLAIN (VERBOSE, COSTS OFF) EXECUTE st4(1); + QUERY PLAN +--------------------------------------------------------------------------------------------- + Foreign Scan on public.ft1 t1 + Output: c1, c2, c3, "time", c6, c7, c8 + InfluxDB query: SELECT "C 1", "c2", "c3", "c6", "c7", "c8" FROM "T1" WHERE (("C 1" = $1)) +(3 rows) + +-- value of $1 should not be sent to remote +--Testcase 372: +PREPARE st5(text,int) AS SELECT * FROM ft1 t1 WHERE c8 = $1 and c1 = $2; +--Testcase 373: +EXPLAIN (VERBOSE, COSTS OFF) EXECUTE st5('foo', 1); + QUERY PLAN +----------------------------------------------------------------------------------------------------------------- + Foreign Scan on public.ft1 t1 + Output: c1, c2, c3, "time", c6, c7, c8 + InfluxDB query: SELECT "C 1", "c2", "c3", "c6", "c7", "c8" FROM "T1" WHERE (("c8" = 'foo')) AND (("C 1" = 1)) +(3 rows) + +--Testcase 374: +EXPLAIN (VERBOSE, COSTS OFF) EXECUTE st5('foo', 1); + QUERY PLAN +----------------------------------------------------------------------------------------------------------------- + Foreign Scan on public.ft1 t1 + Output: c1, c2, c3, "time", c6, c7, c8 + InfluxDB query: SELECT "C 1", "c2", "c3", "c6", "c7", "c8" FROM "T1" WHERE (("c8" = 'foo')) AND (("C 1" = 1)) +(3 rows) + +--Testcase 375: +EXPLAIN (VERBOSE, COSTS OFF) EXECUTE st5('foo', 1); + QUERY PLAN +----------------------------------------------------------------------------------------------------------------- + Foreign Scan on public.ft1 t1 + Output: c1, c2, c3, "time", c6, c7, c8 + InfluxDB query: SELECT "C 1", "c2", "c3", "c6", "c7", "c8" FROM "T1" WHERE (("c8" = 'foo')) AND (("C 1" = 1)) +(3 rows) + +--Testcase 376: +EXPLAIN (VERBOSE, COSTS OFF) EXECUTE st5('foo', 1); + QUERY PLAN +----------------------------------------------------------------------------------------------------------------- + Foreign Scan on public.ft1 t1 + Output: c1, c2, c3, "time", c6, c7, c8 + InfluxDB query: SELECT "C 1", "c2", "c3", "c6", "c7", "c8" FROM "T1" WHERE (("c8" = 'foo')) AND (("C 1" = 1)) +(3 rows) + +--Testcase 377: +EXPLAIN (VERBOSE, COSTS OFF) EXECUTE st5('foo', 1); + QUERY PLAN +----------------------------------------------------------------------------------------------------------------- + Foreign Scan on public.ft1 t1 + Output: c1, c2, c3, "time", c6, c7, c8 + InfluxDB query: SELECT "C 1", "c2", "c3", "c6", "c7", "c8" FROM "T1" WHERE (("c8" = 'foo')) AND (("C 1" = 1)) +(3 rows) + +--Testcase 378: +EXPLAIN (VERBOSE, COSTS OFF) EXECUTE st5('foo', 1); + QUERY PLAN +--------------------------------------------------------------------------------------------------------------- + Foreign Scan on public.ft1 t1 + Output: c1, c2, c3, "time", c6, c7, c8 + InfluxDB query: SELECT "C 1", "c2", "c3", "c6", "c7", "c8" FROM "T1" WHERE (("c8" = $1)) AND (("C 1" = $2)) +(3 rows) + +--Testcase 379: +EXECUTE st5('foo', 1); + c1 | c2 | c3 | time | c6 | c7 | c8 +----+----+-------+------------------------------+----+------------+----- + 1 | 1 | 00001 | Fri Jan 02 00:00:00 1970 PST | 1 | 1 | foo +(1 row) + +-- altering FDW options requires replanning +--Testcase 380: +PREPARE st6 AS SELECT * FROM ft1 t1 WHERE t1.c1 = t1.c2; +--Testcase 381: +EXPLAIN (VERBOSE, COSTS OFF) EXECUTE st6; + QUERY PLAN +----------------------------------------------------------------------------------------------- + Foreign Scan on public.ft1 t1 + Output: c1, c2, c3, "time", c6, c7, c8 + InfluxDB query: SELECT "C 1", "c2", "c3", "c6", "c7", "c8" FROM "T1" WHERE (("C 1" = "c2")) +(3 rows) + +--Testcase 382: +PREPARE st7 AS INSERT INTO ft1 (c1,c2,c3) VALUES (1001,101,'foo'); +--Testcase 383: +EXPLAIN (VERBOSE, COSTS OFF) EXECUTE st7; + QUERY PLAN +--------------------------------------------------------------------------------------------------------------------------------------------------------- + Insert on public.ft1 + Batch Size: 1 + -> Result + Output: NULL::integer, 1001, 101, 'foo'::text, NULL::timestamp with time zone, NULL::character varying, 'ft1 '::character(10), NULL::text +(4 rows) + +--Testcase 384: +INSERT INTO "S 1"."T 0" SELECT * FROM "S 1"."T 1"; +--Testcase 385: +ALTER FOREIGN TABLE ft1 OPTIONS (SET table 'T0'); +--Testcase 386: +EXPLAIN (VERBOSE, COSTS OFF) EXECUTE st6; + QUERY PLAN +----------------------------------------------------------------------------------------------- + Foreign Scan on public.ft1 t1 + Output: c1, c2, c3, "time", c6, c7, c8 + InfluxDB query: SELECT "C 1", "c2", "c3", "c6", "c7", "c8" FROM "T0" WHERE (("C 1" = "c2")) +(3 rows) + +--Testcase 387: +EXECUTE st6; + c1 | c2 | c3 | time | c6 | c7 | c8 +----+----+-------+------------------------------+----+------------+----- + 1 | 1 | 00001 | Fri Jan 02 00:00:00 1970 PST | 1 | 1 | foo + 2 | 2 | 00002 | Sat Jan 03 00:00:00 1970 PST | 2 | 2 | foo + 3 | 3 | 00003 | Sun Jan 04 00:00:00 1970 PST | 3 | 3 | foo + 4 | 4 | 00004 | Mon Jan 05 00:00:00 1970 PST | 4 | 4 | foo + 5 | 5 | 00005 | Tue Jan 06 00:00:00 1970 PST | 5 | 5 | foo + 6 | 6 | 00006 | Wed Jan 07 00:00:00 1970 PST | 6 | 6 | foo + 7 | 7 | 00007 | Thu Jan 08 00:00:00 1970 PST | 7 | 7 | foo + 8 | 8 | 00008 | Fri Jan 09 00:00:00 1970 PST | 8 | 8 | foo + 9 | 9 | 00009 | Sat Jan 10 00:00:00 1970 PST | 9 | 9 | foo +(9 rows) + +--Testcase 388: +EXPLAIN (VERBOSE, COSTS OFF) EXECUTE st7; + QUERY PLAN +--------------------------------------------------------------------------------------------------------------------------------------------------------- + Insert on public.ft1 + Batch Size: 1 + -> Result + Output: NULL::integer, 1001, 101, 'foo'::text, NULL::timestamp with time zone, NULL::character varying, 'ft1 '::character(10), NULL::text +(4 rows) + +--Testcase 389: +DELETE FROM "S 1"."T 0"; +--Testcase 390: +ALTER FOREIGN TABLE ft1 OPTIONS (SET table 'T1'); +--Testcase 391: +PREPARE st8 AS SELECT count(c3) FROM ft1 t1 WHERE t1.c1 === t1.c2; +--Testcase 392: +EXPLAIN (VERBOSE, COSTS OFF) EXECUTE st8; + QUERY PLAN +------------------------------------------------------------ + Aggregate + Output: count(c3) + -> Foreign Scan on public.ft1 t1 + Output: c3 + Filter: (t1.c1 === t1.c2) + InfluxDB query: SELECT "C 1", "c2", "c3" FROM "T1" +(6 rows) + +-- Skip, influxdb_fdw does not support extensions +-- ALTER SERVER loopback OPTIONS (DROP extensions); +--Testcase 393: +EXPLAIN (VERBOSE, COSTS OFF) EXECUTE st8; + QUERY PLAN +------------------------------------------------------------ + Aggregate + Output: count(c3) + -> Foreign Scan on public.ft1 t1 + Output: c3 + Filter: (t1.c1 === t1.c2) + InfluxDB query: SELECT "C 1", "c2", "c3" FROM "T1" +(6 rows) + +--Testcase 394: +EXECUTE st8; + count +------- + 9 +(1 row) + +-- ALTER SERVER loopback OPTIONS (ADD extensions 'influxdb_fdw'); +-- cleanup +DEALLOCATE st1; +DEALLOCATE st2; +DEALLOCATE st3; +DEALLOCATE st4; +DEALLOCATE st5; +DEALLOCATE st6; +DEALLOCATE st7; +DEALLOCATE st8; +-- System columns, except ctid and oid, should not be sent to remote +--Testcase 395: +EXPLAIN (VERBOSE, COSTS OFF) +SELECT * FROM ft1 t1 WHERE t1.tableoid = 'pg_class'::regclass LIMIT 1; + QUERY PLAN +------------------------------------------------------------------------------ + Limit + Output: c1, c2, c3, "time", c6, c7, c8 + -> Foreign Scan on public.ft1 t1 + Output: c1, c2, c3, "time", c6, c7, c8 + Filter: (t1.tableoid = '1259'::oid) + InfluxDB query: SELECT "C 1", "c2", "c3", "c6", "c7", "c8" FROM "T1" +(6 rows) + +--Testcase 396: +SELECT * FROM ft1 t1 WHERE t1.tableoid = 'ft1'::regclass ORDER BY c1 LIMIT 1; + c1 | c2 | c3 | time | c6 | c7 | c8 +----+----+-------+------------------------------+----+------------+----- + 1 | 1 | 00001 | Fri Jan 02 00:00:00 1970 PST | 1 | 1 | foo +(1 row) + +--Testcase 397: +EXPLAIN (VERBOSE, COSTS OFF) +SELECT tableoid::regclass, * FROM ft1 t1 LIMIT 1; + QUERY PLAN +-------------------------------------------------------------------------------- + Foreign Scan on public.ft1 t1 + Output: (tableoid)::regclass, c1, c2, c3, "time", c6, c7, c8 + InfluxDB query: SELECT "C 1", "c2", "c3", "c6", "c7", "c8" FROM "T1" LIMIT 1 +(3 rows) + +--Testcase 398: +SELECT tableoid::regclass, * FROM ft1 t1 ORDER BY c1 LIMIT 1; + tableoid | c1 | c2 | c3 | time | c6 | c7 | c8 +----------+----+----+-------+------------------------------+----+------------+----- + ft1 | 1 | 1 | 00001 | Fri Jan 02 00:00:00 1970 PST | 1 | 1 | foo +(1 row) + +--Testcase 399: +EXPLAIN (VERBOSE, COSTS OFF) +SELECT * FROM ft1 t1 WHERE t1.ctid = '(0,2)'; + QUERY PLAN +------------------------------------------------------------------------ + Foreign Scan on public.ft1 t1 + Output: c1, c2, c3, "time", c6, c7, c8 + Filter: (t1.ctid = '(0,2)'::tid) + InfluxDB query: SELECT "C 1", "c2", "c3", "c6", "c7", "c8" FROM "T1" +(4 rows) + +--Testcase 400: +SELECT * FROM ft1 t1 WHERE t1.ctid = '(0,2)'; + c1 | c2 | c3 | time | c6 | c7 | c8 +----+----+----+------+----+----+---- +(0 rows) + +--Testcase 401: +EXPLAIN (VERBOSE, COSTS OFF) +SELECT ctid, * FROM ft1 t1 LIMIT 1; + QUERY PLAN +-------------------------------------------------------------------------------- + Foreign Scan on public.ft1 t1 + Output: ctid, c1, c2, c3, "time", c6, c7, c8 + InfluxDB query: SELECT "C 1", "c2", "c3", "c6", "c7", "c8" FROM "T1" LIMIT 1 +(3 rows) + +--Testcase 402: +SELECT ctid, * FROM ft1 t1 ORDER BY c1 LIMIT 1; + ctid | c1 | c2 | c3 | time | c6 | c7 | c8 +----------------+----+----+-------+------------------------------+----+------------+----- + (4294967295,0) | 1 | 1 | 00001 | Fri Jan 02 00:00:00 1970 PST | 1 | 1 | foo +(1 row) + +-- =================================================================== +-- used in PL/pgSQL function +-- =================================================================== +--Testcase 403: +CREATE OR REPLACE FUNCTION f_test(p_c1 int) RETURNS int AS $$ +DECLARE + v_c1 int; +BEGIN +--Testcase 404: + SELECT c1 INTO v_c1 FROM ft1 WHERE c1 = p_c1 LIMIT 1; + PERFORM c1 FROM ft1 WHERE c1 = p_c1 AND p_c1 = v_c1 LIMIT 1; + RETURN v_c1; +END; +$$ LANGUAGE plpgsql; +--Testcase 405: +SELECT f_test(100); + f_test +-------- + 100 +(1 row) + +--Testcase 406: +DROP FUNCTION f_test(int); +-- =================================================================== +-- REINDEX +-- =================================================================== +-- remote table is not created here +--Testcase 407: +CREATE FOREIGN TABLE reindex_foreign (c1 int, c2 int) + SERVER influxdb_svr2 OPTIONS (table 'reindex_local'); +REINDEX TABLE reindex_foreign; -- error +ERROR: "reindex_foreign" is not a table or materialized view +REINDEX TABLE CONCURRENTLY reindex_foreign; -- error +ERROR: "reindex_foreign" is not a table or materialized view +--Testcase 408: +DROP FOREIGN TABLE reindex_foreign; +-- partitions and foreign tables +--Testcase 409: +CREATE TABLE reind_fdw_parent (c1 int) PARTITION BY RANGE (c1); +--Testcase 410: +CREATE TABLE reind_fdw_0_10 PARTITION OF reind_fdw_parent + FOR VALUES FROM (0) TO (10); +--Testcase 411: +CREATE FOREIGN TABLE reind_fdw_10_20 PARTITION OF reind_fdw_parent + FOR VALUES FROM (10) TO (20) + SERVER influxdb_svr OPTIONS (table 'reind_local_10_20'); +REINDEX TABLE reind_fdw_parent; -- ok +REINDEX TABLE CONCURRENTLY reind_fdw_parent; -- ok +--Testcase 412: +DROP TABLE reind_fdw_parent; +-- =================================================================== +-- conversion error +-- =================================================================== +--Testcase 413: +ALTER FOREIGN TABLE ft1 ALTER COLUMN c8 TYPE int; +--Testcase 414: +SELECT * FROM ft1 ftx(x1,x2,x3,x4,x6,x7,x8) WHERE x1 = 1; -- ERROR +ERROR: invalid input syntax for type integer: "foo" +--Testcase 415: +SELECT ftx.x1, ft2.c2, ftx.x8 FROM ft1 ftx(x1,x2,x3,x4,x6,x7,x8), ft2 + WHERE ftx.x1 = ft2.c1 AND ftx.x1 = 1; -- ERROR +ERROR: invalid input syntax for type integer: "foo" +--Testcase 416: +SELECT ftx.x1, ft2.c2, ftx FROM ft1 ftx(x1,x2,x3,x4,x6,x7,x8), ft2 + WHERE ftx.x1 = ft2.c1 AND ftx.x1 = 1; -- ERROR +ERROR: invalid input syntax for type integer: "foo" +--Testcase 417: +SELECT sum(c2), array_agg(c8) FROM ft1 GROUP BY c8; -- ERROR +ERROR: invalid input syntax for type integer: "foo" +-- ANALYZE ft1; -- ERROR +ALTER FOREIGN TABLE ft1 ALTER COLUMN c8 TYPE user_enum; +-- =================================================================== +-- local type can be different from remote type in some cases, +-- in particular if similarly-named operators do equivalent things +-- =================================================================== +-- Testcase 418: +ALTER FOREIGN TABLE ft1 ALTER COLUMN c8 TYPE text; +-- Testcase 768: +EXPLAIN (VERBOSE, COSTS OFF) +SELECT * FROM ft1 WHERE c8 = 'foo' LIMIT 1; + QUERY PLAN +------------------------------------------------------------------------------------------------------- + Foreign Scan on public.ft1 + Output: c1, c2, c3, "time", c6, c7, c8 + InfluxDB query: SELECT "C 1", "c2", "c3", "c6", "c7", "c8" FROM "T1" WHERE (("c8" = 'foo')) LIMIT 1 +(3 rows) + +-- Testcase 769: +SELECT * FROM ft1 WHERE c8 = 'foo' LIMIT 1; + c1 | c2 | c3 | time | c6 | c7 | c8 +-----+----+-------+------------------------------+----+------------+----- + 100 | 0 | 00100 | Thu Jan 01 00:00:00 1970 PST | 0 | 0 | foo +(1 row) + +-- Testcase 770: +EXPLAIN (VERBOSE, COSTS OFF) +SELECT * FROM ft1 WHERE 'foo' = c8 LIMIT 1; + QUERY PLAN +------------------------------------------------------------------------------------------------------- + Foreign Scan on public.ft1 + Output: c1, c2, c3, "time", c6, c7, c8 + InfluxDB query: SELECT "C 1", "c2", "c3", "c6", "c7", "c8" FROM "T1" WHERE (('foo' = "c8")) LIMIT 1 +(3 rows) + +-- Testcase 771: +SELECT * FROM ft1 WHERE 'foo' = c8 LIMIT 1; + c1 | c2 | c3 | time | c6 | c7 | c8 +-----+----+-------+------------------------------+----+------------+----- + 100 | 0 | 00100 | Thu Jan 01 00:00:00 1970 PST | 0 | 0 | foo +(1 row) + +-- we declared c8 to be text locally, but it's still the same type on +-- the remote which will balk if we try to do anything incompatible +-- with that remote type +-- Can not create user define type in InfluxDB. +-- Type c8 of foreign table ft1 and remote table T1 are +-- match. These case below not error with influxdb_fdw. +-- Testcase 772: +SELECT * FROM ft1 WHERE c8 LIKE 'foo' LIMIT 1; -- ERROR + c1 | c2 | c3 | time | c6 | c7 | c8 +-----+----+-------+------------------------------+----+------------+----- + 100 | 0 | 00100 | Thu Jan 01 00:00:00 1970 PST | 0 | 0 | foo +(1 row) + +-- Testcase 773: +SELECT * FROM ft1 WHERE c8::text LIKE 'foo' LIMIT 1; -- ERROR; cast not pushed down + c1 | c2 | c3 | time | c6 | c7 | c8 +-----+----+-------+------------------------------+----+------------+----- + 100 | 0 | 00100 | Thu Jan 01 00:00:00 1970 PST | 0 | 0 | foo +(1 row) + +/* +-- influxdb_fdw does not support transactions +-- =================================================================== +-- subtransaction +-- + local/remote error doesn't break cursor +-- =================================================================== +BEGIN; +DECLARE c CURSOR FOR SELECT * FROM ft1 ORDER BY c1; +FETCH c; +SAVEPOINT s; +ERROR OUT; -- ERROR +ROLLBACK TO s; +FETCH c; +SAVEPOINT s; +SELECT * FROM ft1 WHERE 1 / (c1 - 1) > 0; -- ERROR +ROLLBACK TO s; +FETCH c; +SELECT * FROM ft1 ORDER BY c1 LIMIT 1; +COMMIT; +*/ +-- =================================================================== +-- test handling of collations +-- =================================================================== +--Testcase 419: +create foreign table loct3 (f1 text collate "C", f2 text, f3 varchar(10)) server influxdb_svr options (table 'loct3'); +--Testcase 420: +create foreign table ft3 (f1 text collate "C", f2 text, f3 varchar(10)) + server influxdb_svr options (table 'loct3'); +-- can be sent to remote +--Testcase 421: +explain (verbose, costs off) select * from ft3 where f1 = 'foo'; + QUERY PLAN +------------------------------------------------------------------------------- + Foreign Scan on public.ft3 + Output: f1, f2, f3 + InfluxDB query: SELECT "f1", "f2", "f3" FROM "loct3" WHERE (("f1" = 'foo')) +(3 rows) + +--Testcase 422: +explain (verbose, costs off) select * from ft3 where f1 COLLATE "C" = 'foo'; + QUERY PLAN +------------------------------------------------------------------------------- + Foreign Scan on public.ft3 + Output: f1, f2, f3 + InfluxDB query: SELECT "f1", "f2", "f3" FROM "loct3" WHERE (("f1" = 'foo')) +(3 rows) + +--Testcase 423: +explain (verbose, costs off) select * from ft3 where f2 = 'foo'; + QUERY PLAN +------------------------------------------------------------------------------- + Foreign Scan on public.ft3 + Output: f1, f2, f3 + InfluxDB query: SELECT "f1", "f2", "f3" FROM "loct3" WHERE (("f2" = 'foo')) +(3 rows) + +--Testcase 424: +explain (verbose, costs off) select * from ft3 where f3 = 'foo'; + QUERY PLAN +------------------------------------------------------------------------------- + Foreign Scan on public.ft3 + Output: f1, f2, f3 + InfluxDB query: SELECT "f1", "f2", "f3" FROM "loct3" WHERE (("f3" = 'foo')) +(3 rows) + +--Testcase 425: +explain (verbose, costs off) select * from ft3 f, loct3 l + where f.f3 = l.f3 and l.f1 = 'foo'; + QUERY PLAN +------------------------------------------------------------------------------------------- + Hash Join + Output: f.f1, f.f2, f.f3, l.f1, l.f2, l.f3 + Hash Cond: ((f.f3)::text = (l.f3)::text) + -> Foreign Scan on public.ft3 f + Output: f.f1, f.f2, f.f3 + InfluxDB query: SELECT "f1", "f2", "f3" FROM "loct3" + -> Hash + Output: l.f1, l.f2, l.f3 + -> Foreign Scan on public.loct3 l + Output: l.f1, l.f2, l.f3 + InfluxDB query: SELECT "f1", "f2", "f3" FROM "loct3" WHERE (("f1" = 'foo')) +(11 rows) + +-- can't be sent to remote +--Testcase 426: +explain (verbose, costs off) select * from ft3 where f1 COLLATE "POSIX" = 'foo'; + QUERY PLAN +-------------------------------------------------------- + Foreign Scan on public.ft3 + Output: f1, f2, f3 + Filter: ((ft3.f1)::text = 'foo'::text) + InfluxDB query: SELECT "f1", "f2", "f3" FROM "loct3" +(4 rows) + +--Testcase 427: +explain (verbose, costs off) select * from ft3 where f1 = 'foo' COLLATE "C"; + QUERY PLAN +-------------------------------------------------------- + Foreign Scan on public.ft3 + Output: f1, f2, f3 + Filter: (ft3.f1 = 'foo'::text COLLATE "C") + InfluxDB query: SELECT "f1", "f2", "f3" FROM "loct3" +(4 rows) + +--Testcase 428: +explain (verbose, costs off) select * from ft3 where f2 COLLATE "C" = 'foo'; + QUERY PLAN +-------------------------------------------------------- + Foreign Scan on public.ft3 + Output: f1, f2, f3 + Filter: ((ft3.f2)::text = 'foo'::text) + InfluxDB query: SELECT "f1", "f2", "f3" FROM "loct3" +(4 rows) + +--Testcase 429: +explain (verbose, costs off) select * from ft3 where f2 = 'foo' COLLATE "C"; + QUERY PLAN +-------------------------------------------------------- + Foreign Scan on public.ft3 + Output: f1, f2, f3 + Filter: (ft3.f2 = 'foo'::text COLLATE "C") + InfluxDB query: SELECT "f1", "f2", "f3" FROM "loct3" +(4 rows) + +--Testcase 430: +explain (verbose, costs off) select * from ft3 f, loct3 l + where f.f3 = l.f3 COLLATE "POSIX" and l.f1 = 'foo'; + QUERY PLAN +------------------------------------------------------------------------------------------- + Hash Join + Output: f.f1, f.f2, f.f3, l.f1, l.f2, l.f3 + Hash Cond: ((f.f3)::text = (l.f3)::text) + -> Foreign Scan on public.ft3 f + Output: f.f1, f.f2, f.f3 + InfluxDB query: SELECT "f1", "f2", "f3" FROM "loct3" + -> Hash + Output: l.f1, l.f2, l.f3 + -> Foreign Scan on public.loct3 l + Output: l.f1, l.f2, l.f3 + InfluxDB query: SELECT "f1", "f2", "f3" FROM "loct3" WHERE (("f1" = 'foo')) +(11 rows) + +-- influxdb_fdw does not support UPDATE +-- =================================================================== +-- test writable foreign table stuff +-- =================================================================== +--Testcase 431: +EXPLAIN (verbose, costs off) +INSERT INTO ft2 (c1,c2,c3) SELECT c1+1000,c2+100, c3 || c3 FROM ft2 ORDER BY c1 LIMIT 20; + QUERY PLAN +---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- + Insert on public.ft2 + Batch Size: 1 + -> Subquery Scan on "*SELECT*" + Output: "*SELECT*"."?column?", "*SELECT*"."?column?_1", NULL::integer, "*SELECT*"."?column?_2", NULL::timestamp with time zone, NULL::character varying, 'ft2 '::character(10), NULL::text + -> Limit + Output: ((ft2_1.c1 + 1000)), ((ft2_1.c2 + 100)), ((ft2_1.c3 || ft2_1.c3)), ft2_1.c1 + -> Sort + Output: ((ft2_1.c1 + 1000)), ((ft2_1.c2 + 100)), ((ft2_1.c3 || ft2_1.c3)), ft2_1.c1 + Sort Key: ft2_1.c1 + -> Foreign Scan on public.ft2 ft2_1 + Output: (ft2_1.c1 + 1000), (ft2_1.c2 + 100), (ft2_1.c3 || ft2_1.c3), ft2_1.c1 + InfluxDB query: SELECT "C 1", "c2", "c3" FROM "T1" +(12 rows) + +--Testcase 432: +INSERT INTO ft2 (c1,c2,c3) SELECT c1+1000,c2+100, c3 || c3 FROM ft2 ORDER BY c1 LIMIT 20; +--Testcase 433: +INSERT INTO ft2 (c1,c2,c3) VALUES (1101,201,'aaa'), (1102,202,'bbb'), (1103,203,'ccc'); +--Testcase 434: +SELECT c1, c2, c3, c6, c7, c8 FROM ft2 WHERE c2 > 200; + c1 | c2 | c3 | c6 | c7 | c8 +------+-----+-----+----+------------+---- + 1101 | 201 | aaa | | ft2 | + 1102 | 202 | bbb | | ft2 | + 1103 | 203 | ccc | | ft2 | +(3 rows) + +--Testcase 435: +INSERT INTO ft2 (c1,c2,c3) VALUES (1104,204,'ddd'), (1105,205,'eee'); +--EXPLAIN (verbose, costs off) +--UPDATE ft2 SET c2 = c2 + 300, c3 = c3 || '_update3' WHERE c1 % 10 = 3; -- can be pushed down +--UPDATE ft2 SET c2 = c2 + 300, c3 = c3 || '_update3' WHERE c1 % 10 = 3; +--EXPLAIN (verbose, costs off) +--UPDATE ft2 SET c2 = c2 + 400, c3 = c3 || '_update7' WHERE c1 % 10 = 7 RETURNING *; -- can be pushed down +--UPDATE ft2 SET c2 = c2 + 400, c3 = c3 || '_update7' WHERE c1 % 10 = 7 RETURNING *; +--EXPLAIN (verbose, costs off) +--UPDATE ft2 SET c2 = ft2.c2 + 500, c3 = ft2.c3 || '_update9', c7 = DEFAULT +-- FROM ft1 WHERE ft1.c1 = ft2.c2 AND ft1.c1 % 10 = 9; -- can be pushed down +--UPDATE ft2 SET c2 = ft2.c2 + 500, c3 = ft2.c3 || '_update9', c7 = DEFAULT +-- FROM ft1 WHERE ft1.c1 = ft2.c2 AND ft1.c1 % 10 = 9; +--Testcase 436: +EXPLAIN (verbose, costs off) + DELETE FROM ft2 WHERE c1 % 10 = 5; -- can be pushed down + QUERY PLAN +--------------------------------------------------------------------------------- + Delete on public.ft2 + -> Foreign Scan on public.ft2 + Output: c3, "time" + InfluxDB query: SELECT "c3", "C 1" FROM "T1" WHERE ((("C 1" % 10) = 5)) +(4 rows) + +--Testcase 437: +SELECT c1 FROM ft2 WHERE c1 % 10 = 5 ORDER BY c1; + c1 +------ + 5 + 15 + 25 + 35 + 45 + 55 + 65 + 75 + 85 + 95 + 105 + 115 + 125 + 135 + 145 + 155 + 165 + 175 + 185 + 195 + 205 + 215 + 225 + 235 + 245 + 255 + 265 + 275 + 285 + 295 + 305 + 315 + 325 + 335 + 345 + 355 + 365 + 375 + 385 + 395 + 405 + 415 + 425 + 435 + 445 + 455 + 465 + 475 + 485 + 495 + 505 + 515 + 525 + 535 + 545 + 555 + 565 + 575 + 585 + 595 + 605 + 615 + 625 + 635 + 645 + 655 + 665 + 675 + 685 + 695 + 705 + 715 + 725 + 735 + 745 + 755 + 765 + 775 + 785 + 795 + 805 + 815 + 825 + 835 + 845 + 855 + 865 + 875 + 885 + 895 + 905 + 915 + 925 + 935 + 945 + 955 + 965 + 975 + 985 + 995 + 1005 + 1015 + 1105 +(103 rows) + +--Testcase 438: +DELETE FROM ft2 WHERE c1 % 10 = 5; +--Testcase 439: +SELECT c1 FROM ft2 WHERE c1 % 10 = 5; + c1 +---- +(0 rows) + +--Testcase 440: +EXPLAIN (verbose, costs off) +DELETE FROM ft2 USING ft1 WHERE ft1.c1 = ft2.c2 AND ft1.c1 % 10 = 2; + QUERY PLAN +--------------------------------------------------------------------------------------------------------------------- + Delete on public.ft2 + -> Hash Join + Output: ft2.c3, ft2."time", ft1.* + Hash Cond: (ft2.c2 = ft1.c1) + -> Foreign Scan on public.ft2 + Output: ft2.c3, ft2."time", ft2.c2 + InfluxDB query: SELECT "c2", "c3" FROM "T1" + -> Hash + Output: ft1.*, ft1.c1 + -> Foreign Scan on public.ft1 + Output: ft1.*, ft1.c1 + InfluxDB query: SELECT "C 1", "c2", "c3", "c6", "c7", "c8" FROM "T1" WHERE ((("C 1" % 10) = 2)) +(12 rows) + +--Testcase 441: +DELETE FROM ft2 USING ft1 WHERE ft1.c1 = ft2.c2 AND ft1.c1 % 10 = 2; +--Testcase 442: +SELECT c1,c2,c3 FROM ft2 ORDER BY c1; + c1 | c2 | c3 +------+-----+------------ + 1 | 1 | 00001 + 3 | 3 | 00003 + 4 | 4 | 00004 + 6 | 6 | 00006 + 7 | 7 | 00007 + 8 | 8 | 00008 + 9 | 9 | 00009 + 10 | 0 | 00010 + 11 | 1 | 00011 + 13 | 3 | 00013 + 14 | 4 | 00014 + 16 | 6 | 00016 + 17 | 7 | 00017 + 18 | 8 | 00018 + 19 | 9 | 00019 + 20 | 0 | 00020 + 21 | 1 | 00021 + 23 | 3 | 00023 + 24 | 4 | 00024 + 26 | 6 | 00026 + 27 | 7 | 00027 + 28 | 8 | 00028 + 29 | 9 | 00029 + 30 | 0 | 00030 + 31 | 1 | 00031 + 33 | 3 | 00033 + 34 | 4 | 00034 + 36 | 6 | 00036 + 37 | 7 | 00037 + 38 | 8 | 00038 + 39 | 9 | 00039 + 40 | 0 | 00040 + 41 | 1 | 00041 + 43 | 3 | 00043 + 44 | 4 | 00044 + 46 | 6 | 00046 + 47 | 7 | 00047 + 48 | 8 | 00048 + 49 | 9 | 00049 + 50 | 0 | 00050 + 51 | 1 | 00051 + 53 | 3 | 00053 + 54 | 4 | 00054 + 56 | 6 | 00056 + 57 | 7 | 00057 + 58 | 8 | 00058 + 59 | 9 | 00059 + 60 | 0 | 00060 + 61 | 1 | 00061 + 63 | 3 | 00063 + 64 | 4 | 00064 + 66 | 6 | 00066 + 67 | 7 | 00067 + 68 | 8 | 00068 + 69 | 9 | 00069 + 70 | 0 | 00070 + 71 | 1 | 00071 + 73 | 3 | 00073 + 74 | 4 | 00074 + 76 | 6 | 00076 + 77 | 7 | 00077 + 78 | 8 | 00078 + 79 | 9 | 00079 + 80 | 0 | 00080 + 81 | 1 | 00081 + 83 | 3 | 00083 + 84 | 4 | 00084 + 86 | 6 | 00086 + 87 | 7 | 00087 + 88 | 8 | 00088 + 89 | 9 | 00089 + 90 | 0 | 00090 + 91 | 1 | 00091 + 93 | 3 | 00093 + 94 | 4 | 00094 + 96 | 6 | 00096 + 97 | 7 | 00097 + 98 | 8 | 00098 + 99 | 9 | 00099 + 100 | 0 | 00100 + 101 | 1 | 00101 + 103 | 3 | 00103 + 104 | 4 | 00104 + 106 | 6 | 00106 + 107 | 7 | 00107 + 108 | 8 | 00108 + 109 | 9 | 00109 + 110 | 0 | 00110 + 111 | 1 | 00111 + 113 | 3 | 00113 + 114 | 4 | 00114 + 116 | 6 | 00116 + 117 | 7 | 00117 + 118 | 8 | 00118 + 119 | 9 | 00119 + 120 | 0 | 00120 + 121 | 1 | 00121 + 123 | 3 | 00123 + 124 | 4 | 00124 + 126 | 6 | 00126 + 127 | 7 | 00127 + 128 | 8 | 00128 + 129 | 9 | 00129 + 130 | 0 | 00130 + 131 | 1 | 00131 + 133 | 3 | 00133 + 134 | 4 | 00134 + 136 | 6 | 00136 + 137 | 7 | 00137 + 138 | 8 | 00138 + 139 | 9 | 00139 + 140 | 0 | 00140 + 141 | 1 | 00141 + 143 | 3 | 00143 + 144 | 4 | 00144 + 146 | 6 | 00146 + 147 | 7 | 00147 + 148 | 8 | 00148 + 149 | 9 | 00149 + 150 | 0 | 00150 + 151 | 1 | 00151 + 153 | 3 | 00153 + 154 | 4 | 00154 + 156 | 6 | 00156 + 157 | 7 | 00157 + 158 | 8 | 00158 + 159 | 9 | 00159 + 160 | 0 | 00160 + 161 | 1 | 00161 + 163 | 3 | 00163 + 164 | 4 | 00164 + 166 | 6 | 00166 + 167 | 7 | 00167 + 168 | 8 | 00168 + 169 | 9 | 00169 + 170 | 0 | 00170 + 171 | 1 | 00171 + 173 | 3 | 00173 + 174 | 4 | 00174 + 176 | 6 | 00176 + 177 | 7 | 00177 + 178 | 8 | 00178 + 179 | 9 | 00179 + 180 | 0 | 00180 + 181 | 1 | 00181 + 183 | 3 | 00183 + 184 | 4 | 00184 + 186 | 6 | 00186 + 187 | 7 | 00187 + 188 | 8 | 00188 + 189 | 9 | 00189 + 190 | 0 | 00190 + 191 | 1 | 00191 + 193 | 3 | 00193 + 194 | 4 | 00194 + 196 | 6 | 00196 + 197 | 7 | 00197 + 198 | 8 | 00198 + 199 | 9 | 00199 + 200 | 0 | 00200 + 201 | 1 | 00201 + 203 | 3 | 00203 + 204 | 4 | 00204 + 206 | 6 | 00206 + 207 | 7 | 00207 + 208 | 8 | 00208 + 209 | 9 | 00209 + 210 | 0 | 00210 + 211 | 1 | 00211 + 213 | 3 | 00213 + 214 | 4 | 00214 + 216 | 6 | 00216 + 217 | 7 | 00217 + 218 | 8 | 00218 + 219 | 9 | 00219 + 220 | 0 | 00220 + 221 | 1 | 00221 + 223 | 3 | 00223 + 224 | 4 | 00224 + 226 | 6 | 00226 + 227 | 7 | 00227 + 228 | 8 | 00228 + 229 | 9 | 00229 + 230 | 0 | 00230 + 231 | 1 | 00231 + 233 | 3 | 00233 + 234 | 4 | 00234 + 236 | 6 | 00236 + 237 | 7 | 00237 + 238 | 8 | 00238 + 239 | 9 | 00239 + 240 | 0 | 00240 + 241 | 1 | 00241 + 243 | 3 | 00243 + 244 | 4 | 00244 + 246 | 6 | 00246 + 247 | 7 | 00247 + 248 | 8 | 00248 + 249 | 9 | 00249 + 250 | 0 | 00250 + 251 | 1 | 00251 + 253 | 3 | 00253 + 254 | 4 | 00254 + 256 | 6 | 00256 + 257 | 7 | 00257 + 258 | 8 | 00258 + 259 | 9 | 00259 + 260 | 0 | 00260 + 261 | 1 | 00261 + 263 | 3 | 00263 + 264 | 4 | 00264 + 266 | 6 | 00266 + 267 | 7 | 00267 + 268 | 8 | 00268 + 269 | 9 | 00269 + 270 | 0 | 00270 + 271 | 1 | 00271 + 273 | 3 | 00273 + 274 | 4 | 00274 + 276 | 6 | 00276 + 277 | 7 | 00277 + 278 | 8 | 00278 + 279 | 9 | 00279 + 280 | 0 | 00280 + 281 | 1 | 00281 + 283 | 3 | 00283 + 284 | 4 | 00284 + 286 | 6 | 00286 + 287 | 7 | 00287 + 288 | 8 | 00288 + 289 | 9 | 00289 + 290 | 0 | 00290 + 291 | 1 | 00291 + 293 | 3 | 00293 + 294 | 4 | 00294 + 296 | 6 | 00296 + 297 | 7 | 00297 + 298 | 8 | 00298 + 299 | 9 | 00299 + 300 | 0 | 00300 + 301 | 1 | 00301 + 303 | 3 | 00303 + 304 | 4 | 00304 + 306 | 6 | 00306 + 307 | 7 | 00307 + 308 | 8 | 00308 + 309 | 9 | 00309 + 310 | 0 | 00310 + 311 | 1 | 00311 + 313 | 3 | 00313 + 314 | 4 | 00314 + 316 | 6 | 00316 + 317 | 7 | 00317 + 318 | 8 | 00318 + 319 | 9 | 00319 + 320 | 0 | 00320 + 321 | 1 | 00321 + 323 | 3 | 00323 + 324 | 4 | 00324 + 326 | 6 | 00326 + 327 | 7 | 00327 + 328 | 8 | 00328 + 329 | 9 | 00329 + 330 | 0 | 00330 + 331 | 1 | 00331 + 333 | 3 | 00333 + 334 | 4 | 00334 + 336 | 6 | 00336 + 337 | 7 | 00337 + 338 | 8 | 00338 + 339 | 9 | 00339 + 340 | 0 | 00340 + 341 | 1 | 00341 + 343 | 3 | 00343 + 344 | 4 | 00344 + 346 | 6 | 00346 + 347 | 7 | 00347 + 348 | 8 | 00348 + 349 | 9 | 00349 + 350 | 0 | 00350 + 351 | 1 | 00351 + 353 | 3 | 00353 + 354 | 4 | 00354 + 356 | 6 | 00356 + 357 | 7 | 00357 + 358 | 8 | 00358 + 359 | 9 | 00359 + 360 | 0 | 00360 + 361 | 1 | 00361 + 363 | 3 | 00363 + 364 | 4 | 00364 + 366 | 6 | 00366 + 367 | 7 | 00367 + 368 | 8 | 00368 + 369 | 9 | 00369 + 370 | 0 | 00370 + 371 | 1 | 00371 + 373 | 3 | 00373 + 374 | 4 | 00374 + 376 | 6 | 00376 + 377 | 7 | 00377 + 378 | 8 | 00378 + 379 | 9 | 00379 + 380 | 0 | 00380 + 381 | 1 | 00381 + 383 | 3 | 00383 + 384 | 4 | 00384 + 386 | 6 | 00386 + 387 | 7 | 00387 + 388 | 8 | 00388 + 389 | 9 | 00389 + 390 | 0 | 00390 + 391 | 1 | 00391 + 393 | 3 | 00393 + 394 | 4 | 00394 + 396 | 6 | 00396 + 397 | 7 | 00397 + 398 | 8 | 00398 + 399 | 9 | 00399 + 400 | 0 | 00400 + 401 | 1 | 00401 + 403 | 3 | 00403 + 404 | 4 | 00404 + 406 | 6 | 00406 + 407 | 7 | 00407 + 408 | 8 | 00408 + 409 | 9 | 00409 + 410 | 0 | 00410 + 411 | 1 | 00411 + 413 | 3 | 00413 + 414 | 4 | 00414 + 416 | 6 | 00416 + 417 | 7 | 00417 + 418 | 8 | 00418 + 419 | 9 | 00419 + 420 | 0 | 00420 + 421 | 1 | 00421 + 423 | 3 | 00423 + 424 | 4 | 00424 + 426 | 6 | 00426 + 427 | 7 | 00427 + 428 | 8 | 00428 + 429 | 9 | 00429 + 430 | 0 | 00430 + 431 | 1 | 00431 + 433 | 3 | 00433 + 434 | 4 | 00434 + 436 | 6 | 00436 + 437 | 7 | 00437 + 438 | 8 | 00438 + 439 | 9 | 00439 + 440 | 0 | 00440 + 441 | 1 | 00441 + 443 | 3 | 00443 + 444 | 4 | 00444 + 446 | 6 | 00446 + 447 | 7 | 00447 + 448 | 8 | 00448 + 449 | 9 | 00449 + 450 | 0 | 00450 + 451 | 1 | 00451 + 453 | 3 | 00453 + 454 | 4 | 00454 + 456 | 6 | 00456 + 457 | 7 | 00457 + 458 | 8 | 00458 + 459 | 9 | 00459 + 460 | 0 | 00460 + 461 | 1 | 00461 + 463 | 3 | 00463 + 464 | 4 | 00464 + 466 | 6 | 00466 + 467 | 7 | 00467 + 468 | 8 | 00468 + 469 | 9 | 00469 + 470 | 0 | 00470 + 471 | 1 | 00471 + 473 | 3 | 00473 + 474 | 4 | 00474 + 476 | 6 | 00476 + 477 | 7 | 00477 + 478 | 8 | 00478 + 479 | 9 | 00479 + 480 | 0 | 00480 + 481 | 1 | 00481 + 483 | 3 | 00483 + 484 | 4 | 00484 + 486 | 6 | 00486 + 487 | 7 | 00487 + 488 | 8 | 00488 + 489 | 9 | 00489 + 490 | 0 | 00490 + 491 | 1 | 00491 + 493 | 3 | 00493 + 494 | 4 | 00494 + 496 | 6 | 00496 + 497 | 7 | 00497 + 498 | 8 | 00498 + 499 | 9 | 00499 + 500 | 0 | 00500 + 501 | 1 | 00501 + 503 | 3 | 00503 + 504 | 4 | 00504 + 506 | 6 | 00506 + 507 | 7 | 00507 + 508 | 8 | 00508 + 509 | 9 | 00509 + 510 | 0 | 00510 + 511 | 1 | 00511 + 513 | 3 | 00513 + 514 | 4 | 00514 + 516 | 6 | 00516 + 517 | 7 | 00517 + 518 | 8 | 00518 + 519 | 9 | 00519 + 520 | 0 | 00520 + 521 | 1 | 00521 + 523 | 3 | 00523 + 524 | 4 | 00524 + 526 | 6 | 00526 + 527 | 7 | 00527 + 528 | 8 | 00528 + 529 | 9 | 00529 + 530 | 0 | 00530 + 531 | 1 | 00531 + 533 | 3 | 00533 + 534 | 4 | 00534 + 536 | 6 | 00536 + 537 | 7 | 00537 + 538 | 8 | 00538 + 539 | 9 | 00539 + 540 | 0 | 00540 + 541 | 1 | 00541 + 543 | 3 | 00543 + 544 | 4 | 00544 + 546 | 6 | 00546 + 547 | 7 | 00547 + 548 | 8 | 00548 + 549 | 9 | 00549 + 550 | 0 | 00550 + 551 | 1 | 00551 + 553 | 3 | 00553 + 554 | 4 | 00554 + 556 | 6 | 00556 + 557 | 7 | 00557 + 558 | 8 | 00558 + 559 | 9 | 00559 + 560 | 0 | 00560 + 561 | 1 | 00561 + 563 | 3 | 00563 + 564 | 4 | 00564 + 566 | 6 | 00566 + 567 | 7 | 00567 + 568 | 8 | 00568 + 569 | 9 | 00569 + 570 | 0 | 00570 + 571 | 1 | 00571 + 573 | 3 | 00573 + 574 | 4 | 00574 + 576 | 6 | 00576 + 577 | 7 | 00577 + 578 | 8 | 00578 + 579 | 9 | 00579 + 580 | 0 | 00580 + 581 | 1 | 00581 + 583 | 3 | 00583 + 584 | 4 | 00584 + 586 | 6 | 00586 + 587 | 7 | 00587 + 588 | 8 | 00588 + 589 | 9 | 00589 + 590 | 0 | 00590 + 591 | 1 | 00591 + 593 | 3 | 00593 + 594 | 4 | 00594 + 596 | 6 | 00596 + 597 | 7 | 00597 + 598 | 8 | 00598 + 599 | 9 | 00599 + 600 | 0 | 00600 + 601 | 1 | 00601 + 603 | 3 | 00603 + 604 | 4 | 00604 + 606 | 6 | 00606 + 607 | 7 | 00607 + 608 | 8 | 00608 + 609 | 9 | 00609 + 610 | 0 | 00610 + 611 | 1 | 00611 + 613 | 3 | 00613 + 614 | 4 | 00614 + 616 | 6 | 00616 + 617 | 7 | 00617 + 618 | 8 | 00618 + 619 | 9 | 00619 + 620 | 0 | 00620 + 621 | 1 | 00621 + 623 | 3 | 00623 + 624 | 4 | 00624 + 626 | 6 | 00626 + 627 | 7 | 00627 + 628 | 8 | 00628 + 629 | 9 | 00629 + 630 | 0 | 00630 + 631 | 1 | 00631 + 633 | 3 | 00633 + 634 | 4 | 00634 + 636 | 6 | 00636 + 637 | 7 | 00637 + 638 | 8 | 00638 + 639 | 9 | 00639 + 640 | 0 | 00640 + 641 | 1 | 00641 + 643 | 3 | 00643 + 644 | 4 | 00644 + 646 | 6 | 00646 + 647 | 7 | 00647 + 648 | 8 | 00648 + 649 | 9 | 00649 + 650 | 0 | 00650 + 651 | 1 | 00651 + 653 | 3 | 00653 + 654 | 4 | 00654 + 656 | 6 | 00656 + 657 | 7 | 00657 + 658 | 8 | 00658 + 659 | 9 | 00659 + 660 | 0 | 00660 + 661 | 1 | 00661 + 663 | 3 | 00663 + 664 | 4 | 00664 + 666 | 6 | 00666 + 667 | 7 | 00667 + 668 | 8 | 00668 + 669 | 9 | 00669 + 670 | 0 | 00670 + 671 | 1 | 00671 + 673 | 3 | 00673 + 674 | 4 | 00674 + 676 | 6 | 00676 + 677 | 7 | 00677 + 678 | 8 | 00678 + 679 | 9 | 00679 + 680 | 0 | 00680 + 681 | 1 | 00681 + 683 | 3 | 00683 + 684 | 4 | 00684 + 686 | 6 | 00686 + 687 | 7 | 00687 + 688 | 8 | 00688 + 689 | 9 | 00689 + 690 | 0 | 00690 + 691 | 1 | 00691 + 693 | 3 | 00693 + 694 | 4 | 00694 + 696 | 6 | 00696 + 697 | 7 | 00697 + 698 | 8 | 00698 + 699 | 9 | 00699 + 700 | 0 | 00700 + 701 | 1 | 00701 + 703 | 3 | 00703 + 704 | 4 | 00704 + 706 | 6 | 00706 + 707 | 7 | 00707 + 708 | 8 | 00708 + 709 | 9 | 00709 + 710 | 0 | 00710 + 711 | 1 | 00711 + 713 | 3 | 00713 + 714 | 4 | 00714 + 716 | 6 | 00716 + 717 | 7 | 00717 + 718 | 8 | 00718 + 719 | 9 | 00719 + 720 | 0 | 00720 + 721 | 1 | 00721 + 723 | 3 | 00723 + 724 | 4 | 00724 + 726 | 6 | 00726 + 727 | 7 | 00727 + 728 | 8 | 00728 + 729 | 9 | 00729 + 730 | 0 | 00730 + 731 | 1 | 00731 + 733 | 3 | 00733 + 734 | 4 | 00734 + 736 | 6 | 00736 + 737 | 7 | 00737 + 738 | 8 | 00738 + 739 | 9 | 00739 + 740 | 0 | 00740 + 741 | 1 | 00741 + 743 | 3 | 00743 + 744 | 4 | 00744 + 746 | 6 | 00746 + 747 | 7 | 00747 + 748 | 8 | 00748 + 749 | 9 | 00749 + 750 | 0 | 00750 + 751 | 1 | 00751 + 753 | 3 | 00753 + 754 | 4 | 00754 + 756 | 6 | 00756 + 757 | 7 | 00757 + 758 | 8 | 00758 + 759 | 9 | 00759 + 760 | 0 | 00760 + 761 | 1 | 00761 + 763 | 3 | 00763 + 764 | 4 | 00764 + 766 | 6 | 00766 + 767 | 7 | 00767 + 768 | 8 | 00768 + 769 | 9 | 00769 + 770 | 0 | 00770 + 771 | 1 | 00771 + 773 | 3 | 00773 + 774 | 4 | 00774 + 776 | 6 | 00776 + 777 | 7 | 00777 + 778 | 8 | 00778 + 779 | 9 | 00779 + 780 | 0 | 00780 + 781 | 1 | 00781 + 783 | 3 | 00783 + 784 | 4 | 00784 + 786 | 6 | 00786 + 787 | 7 | 00787 + 788 | 8 | 00788 + 789 | 9 | 00789 + 790 | 0 | 00790 + 791 | 1 | 00791 + 793 | 3 | 00793 + 794 | 4 | 00794 + 796 | 6 | 00796 + 797 | 7 | 00797 + 798 | 8 | 00798 + 799 | 9 | 00799 + 800 | 0 | 00800 + 801 | 1 | 00801 + 803 | 3 | 00803 + 804 | 4 | 00804 + 806 | 6 | 00806 + 807 | 7 | 00807 + 808 | 8 | 00808 + 809 | 9 | 00809 + 810 | 0 | 00810 + 811 | 1 | 00811 + 813 | 3 | 00813 + 814 | 4 | 00814 + 816 | 6 | 00816 + 817 | 7 | 00817 + 818 | 8 | 00818 + 819 | 9 | 00819 + 820 | 0 | 00820 + 821 | 1 | 00821 + 823 | 3 | 00823 + 824 | 4 | 00824 + 826 | 6 | 00826 + 827 | 7 | 00827 + 828 | 8 | 00828 + 829 | 9 | 00829 + 830 | 0 | 00830 + 831 | 1 | 00831 + 833 | 3 | 00833 + 834 | 4 | 00834 + 836 | 6 | 00836 + 837 | 7 | 00837 + 838 | 8 | 00838 + 839 | 9 | 00839 + 840 | 0 | 00840 + 841 | 1 | 00841 + 843 | 3 | 00843 + 844 | 4 | 00844 + 846 | 6 | 00846 + 847 | 7 | 00847 + 848 | 8 | 00848 + 849 | 9 | 00849 + 850 | 0 | 00850 + 851 | 1 | 00851 + 853 | 3 | 00853 + 854 | 4 | 00854 + 856 | 6 | 00856 + 857 | 7 | 00857 + 858 | 8 | 00858 + 859 | 9 | 00859 + 860 | 0 | 00860 + 861 | 1 | 00861 + 863 | 3 | 00863 + 864 | 4 | 00864 + 866 | 6 | 00866 + 867 | 7 | 00867 + 868 | 8 | 00868 + 869 | 9 | 00869 + 870 | 0 | 00870 + 871 | 1 | 00871 + 873 | 3 | 00873 + 874 | 4 | 00874 + 876 | 6 | 00876 + 877 | 7 | 00877 + 878 | 8 | 00878 + 879 | 9 | 00879 + 880 | 0 | 00880 + 881 | 1 | 00881 + 883 | 3 | 00883 + 884 | 4 | 00884 + 886 | 6 | 00886 + 887 | 7 | 00887 + 888 | 8 | 00888 + 889 | 9 | 00889 + 890 | 0 | 00890 + 891 | 1 | 00891 + 893 | 3 | 00893 + 894 | 4 | 00894 + 896 | 6 | 00896 + 897 | 7 | 00897 + 898 | 8 | 00898 + 899 | 9 | 00899 + 900 | 0 | 00900 + 901 | 1 | 00901 + 903 | 3 | 00903 + 904 | 4 | 00904 + 906 | 6 | 00906 + 907 | 7 | 00907 + 908 | 8 | 00908 + 909 | 9 | 00909 + 910 | 0 | 00910 + 911 | 1 | 00911 + 913 | 3 | 00913 + 914 | 4 | 00914 + 916 | 6 | 00916 + 917 | 7 | 00917 + 918 | 8 | 00918 + 919 | 9 | 00919 + 920 | 0 | 00920 + 921 | 1 | 00921 + 923 | 3 | 00923 + 924 | 4 | 00924 + 926 | 6 | 00926 + 927 | 7 | 00927 + 928 | 8 | 00928 + 929 | 9 | 00929 + 930 | 0 | 00930 + 931 | 1 | 00931 + 933 | 3 | 00933 + 934 | 4 | 00934 + 936 | 6 | 00936 + 937 | 7 | 00937 + 938 | 8 | 00938 + 939 | 9 | 00939 + 940 | 0 | 00940 + 941 | 1 | 00941 + 943 | 3 | 00943 + 944 | 4 | 00944 + 946 | 6 | 00946 + 947 | 7 | 00947 + 948 | 8 | 00948 + 949 | 9 | 00949 + 950 | 0 | 00950 + 951 | 1 | 00951 + 953 | 3 | 00953 + 954 | 4 | 00954 + 956 | 6 | 00956 + 957 | 7 | 00957 + 958 | 8 | 00958 + 959 | 9 | 00959 + 960 | 0 | 00960 + 961 | 1 | 00961 + 963 | 3 | 00963 + 964 | 4 | 00964 + 966 | 6 | 00966 + 967 | 7 | 00967 + 968 | 8 | 00968 + 969 | 9 | 00969 + 970 | 0 | 00970 + 971 | 1 | 00971 + 973 | 3 | 00973 + 974 | 4 | 00974 + 976 | 6 | 00976 + 977 | 7 | 00977 + 978 | 8 | 00978 + 979 | 9 | 00979 + 980 | 0 | 00980 + 981 | 1 | 00981 + 983 | 3 | 00983 + 984 | 4 | 00984 + 986 | 6 | 00986 + 987 | 7 | 00987 + 988 | 8 | 00988 + 989 | 9 | 00989 + 990 | 0 | 00990 + 991 | 1 | 00991 + 993 | 3 | 00993 + 994 | 4 | 00994 + 996 | 6 | 00996 + 997 | 7 | 00997 + 998 | 8 | 00998 + 999 | 9 | 00999 + 1000 | 0 | 01000 + 1001 | 101 | 0000100001 + 1003 | 103 | 0000300003 + 1004 | 104 | 0000400004 + 1006 | 106 | 0000600006 + 1007 | 107 | 0000700007 + 1008 | 108 | 0000800008 + 1009 | 109 | 0000900009 + 1010 | 100 | 0001000010 + 1011 | 101 | 0001100011 + 1013 | 103 | 0001300013 + 1014 | 104 | 0001400014 + 1016 | 106 | 0001600016 + 1017 | 107 | 0001700017 + 1018 | 108 | 0001800018 + 1019 | 109 | 0001900019 + 1020 | 100 | 0002000020 + 1101 | 201 | aaa + 1103 | 203 | ccc + 1104 | 204 | ddd +(819 rows) + +--Testcase 443: +EXPLAIN (verbose, costs off) +INSERT INTO ft2 (c1,c2,c3) VALUES (1200,999,'foo'); + QUERY PLAN +--------------------------------------------------------------------------------------------------------------------------------------------------------- + Insert on public.ft2 + Batch Size: 1 + -> Result + Output: 1200, 999, NULL::integer, 'foo'::text, NULL::timestamp with time zone, NULL::character varying, 'ft2 '::character(10), NULL::text +(4 rows) + +--Testcase 444: +INSERT INTO ft2 (c1,c2,c3) VALUES (1200,999,'foo'); +--Testcase 445: +SELECT c1 FROM ft2 WHERE c1 = 1200 AND c2 = 999; + c1 +------ + 1200 +(1 row) + +--EXPLAIN (verbose, costs off) +--UPDATE ft2 SET c3 = 'bar' WHERE c1 = 1200 RETURNING tableoid::regclass; -- can be pushed down +--UPDATE ft2 SET c3 = 'bar' WHERE c1 = 1200 RETURNING tableoid::regclass; +--Testcase 446: +EXPLAIN (verbose, costs off) +DELETE FROM ft2 WHERE c1 = 1200; + QUERY PLAN +----------------------------------------------------------------------------- + Delete on public.ft2 + -> Foreign Scan on public.ft2 + Output: c3, "time" + InfluxDB query: SELECT "c3", "C 1" FROM "T1" WHERE (("C 1" = 1200)) +(4 rows) + +--Testcase 447: +SELECT c1 FROM ft2 WHERE c1 = 1200; + c1 +------ + 1200 +(1 row) + +--Testcase 448: +DELETE FROM ft2 WHERE c1 = 1200; +--Testcase 449: +SELECT c1 FROM ft2 WHERE c1 = 1200; + c1 +---- +(0 rows) + +-- Test UPDATE/DELETE with RETURNING on a three-table join +--Testcase 450: +INSERT INTO ft2 (c1,c2,c3) + SELECT id, id - 1200, to_char(id, 'FM00000') FROM generate_series(1201, 1300) id; +--EXPLAIN (verbose, costs off) +--UPDATE ft2 SET c3 = 'foo' +-- FROM ft4 INNER JOIN ft5 ON (ft4.c1 = ft5.c1) +-- WHERE ft2.c1 > 1200 AND ft2.c2 = ft4.c1 +-- RETURNING ft2, ft2.*, ft4, ft4.*; -- can be pushed down +--UPDATE ft2 SET c3 = 'foo' +-- FROM ft4 INNER JOIN ft5 ON (ft4.c1 = ft5.c1) +-- WHERE ft2.c1 > 1200 AND ft2.c2 = ft4.c1 +-- RETURNING ft2, ft2.*, ft4, ft4.*; +--Testcase 451: +EXPLAIN (verbose, costs off) +DELETE FROM ft2 + USING ft4 LEFT JOIN ft5 ON (ft4.c1 = ft5.c1) + WHERE ft2.c1 > 1200 AND ft2.c1 % 10 = 0 AND ft2.c2 = ft4.c1; -- can be pushed down + QUERY PLAN +----------------------------------------------------------------------------------------------------------------------------- + Delete on public.ft2 + -> Hash Right Join + Output: ft2.c3, ft2."time", ft4.*, ft5.* + Hash Cond: (ft5.c1 = ft4.c1) + -> Foreign Scan on public.ft5 + Output: ft5.*, ft5.c1 + InfluxDB query: SELECT "c1", "c2", "c3" FROM "T4" + -> Hash + Output: ft2.c3, ft2."time", ft4.*, ft4.c1 + -> Hash Join + Output: ft2.c3, ft2."time", ft4.*, ft4.c1 + Hash Cond: (ft4.c1 = ft2.c2) + -> Foreign Scan on public.ft4 + Output: ft4.*, ft4.c1 + InfluxDB query: SELECT "c1", "c2", "c3" FROM "T3" + -> Hash + Output: ft2.c3, ft2."time", ft2.c2 + -> Foreign Scan on public.ft2 + Output: ft2.c3, ft2."time", ft2.c2 + InfluxDB query: SELECT "c2", "c3" FROM "T1" WHERE (("C 1" > 1200)) AND ((("C 1" % 10) = 0)) +(20 rows) + +--Testcase 452: +SELECT 100 FROM ft2, + ft4 LEFT JOIN ft5 ON (ft4.c1 = ft5.c1) + WHERE ft2.c1 > 1200 AND ft2.c1 % 10 = 0 AND ft2.c2 = ft4.c1; + ?column? +---------- + 100 + 100 + 100 + 100 + 100 + 100 + 100 + 100 + 100 + 100 +(10 rows) + +--Testcase 453: +DELETE FROM ft2 + USING ft4 LEFT JOIN ft5 ON (ft4.c1 = ft5.c1) + WHERE ft2.c1 > 1200 AND ft2.c1 % 10 = 0 AND ft2.c2 = ft4.c1; +--Testcase 454: +SELECT 100 FROM ft2, + ft4 LEFT JOIN ft5 ON (ft4.c1 = ft5.c1) + WHERE ft2.c1 > 1200 AND ft2.c1 % 10 = 0 AND ft2.c2 = ft4.c1; + ?column? +---------- +(0 rows) + +--Testcase 455: +DELETE FROM ft2 WHERE ft2.c1 > 1200; +-- Test UPDATE with a MULTIEXPR sub-select +-- (maybe someday this'll be remotely executable, but not today) +--EXPLAIN (verbose, costs off) +--UPDATE ft2 AS target SET (c2, c7) = ( +-- SELECT c2 * 10, c7 +-- FROM ft2 AS src +-- WHERE target.c1 = src.c1 +--) WHERE c1 > 1100; +--UPDATE ft2 AS target SET (c2, c7) = ( +-- SELECT c2 * 10, c7 +-- FROM ft2 AS src +-- WHERE targ--et.c1 = src.c1 +--) WHERE c1 > 1100; +--UPDATE ft2 AS target SET (c2) = ( +-- SELECT c2 / 10 +-- FROM ft2 AS src +-- WHERE targ--et.c1 = src.c1 +--) WHERE c1 > 1100; +-- Test UPDATE involving a join that can be pushed down, +-- but a SET clause that can't be +-- EXPLAIN (VERBOSE, COSTS OFF) +-- UPDATE ft2 d SET c2 = CASE WHEN random() >= 0 THEN d.c2 ELSE 0 END +-- FROM ft2 AS t WHERE d.c1 = t.c1 AND d.c1 > 1000; +-- UPDATE ft2 d SET c2 = CASE WHEN random() >= 0 THEN d.c2 ELSE 0 END +-- FROM ft2 AS t WHERE d.c1 = t.c1 AND d.c1 > 1000; +-- Test UPDATE/DELETE with WHERE or JOIN/ON conditions containing +-- user-defined operators/functions +--Testcase 456: +INSERT INTO ft2 (c1,c2,c3) + SELECT id, id % 10, to_char(id, 'FM00000') FROM generate_series(2001, 2010) id; +--EXPLAIN (verbose, costs off) +--UPDATE ft2 SET c3 = 'bar' WHERE influxdb_fdw_abs(c1) > 2000 RETURNING *; -- can't be pushed down +--UPDATE ft2 SET c3 = 'bar' WHERE influxdb_fdw_abs(c1) > 2000 RETURNING *; +--EXPLAIN (verbose, costs off) +--UPDATE ft2 SET c3 = 'baz' +-- FROM ft4 INNER JOIN ft5 ON (ft4.c1 = ft5.c1) +-- WHERE ft2.c1 > 2000 AND ft2.c2 === ft4.c1 +-- RETURNING ft2.*, ft4.*, ft5.*; -- can't be pushed down +--UPDATE ft2 SET c3 = 'baz' +-- FROM ft4 INNER JOIN ft5 ON (ft4.c1 = ft5.c1) +-- WHERE ft2.c1 > 2000 AND ft2.c2 === ft4.c1 +-- RETURNING ft2.*, ft4.*, ft5.*; +--Testcase 457: +EXPLAIN (verbose, costs off) +DELETE FROM ft2 + USING ft4 INNER JOIN ft5 ON (ft4.c1 === ft5.c1) + WHERE ft2.c1 > 2000 AND ft2.c2 = ft4.c1; -- can't be pushed down + QUERY PLAN +---------------------------------------------------------------------------------------------- + Delete on public.ft2 + -> Nested Loop + Output: ft2.c3, ft2."time", ft4.*, ft5.* + Join Filter: (ft4.c1 === ft5.c1) + -> Hash Join + Output: ft2.c3, ft2."time", ft4.*, ft4.c1 + Hash Cond: (ft4.c1 = ft2.c2) + -> Foreign Scan on public.ft4 + Output: ft4.*, ft4.c1 + InfluxDB query: SELECT "c1", "c2", "c3" FROM "T3" + -> Hash + Output: ft2.c3, ft2."time", ft2.c2 + -> Foreign Scan on public.ft2 + Output: ft2.c3, ft2."time", ft2.c2 + InfluxDB query: SELECT "c2", "c3" FROM "T1" WHERE (("C 1" > 2000)) + -> Materialize + Output: ft5.*, ft5.c1 + -> Foreign Scan on public.ft5 + Output: ft5.*, ft5.c1 + InfluxDB query: SELECT "c1", "c2", "c3" FROM "T4" +(20 rows) + +--Testcase 458: +SELECT ft2.c1, ft2.c2, ft2.c3 + FROM ft2, ft4 INNER JOIN ft5 ON (ft4.c1 === ft5.c1) + WHERE ft2.c1 > 2000 AND ft2.c2 = ft4.c1; + c1 | c2 | c3 +------+----+------- + 2006 | 6 | 02006 +(1 row) + +--Testcase 459: +DELETE FROM ft2 + USING ft4 INNER JOIN ft5 ON (ft4.c1 === ft5.c1) + WHERE ft2.c1 > 2000 AND ft2.c2 = ft4.c1; +--Testcase 460: +SELECT ft2.c1, ft2.c2, ft2.c3 + FROM ft2, ft4 INNER JOIN ft5 ON (ft4.c1 === ft5.c1) + WHERE ft2.c1 > 2000 AND ft2.c2 = ft4.c1; + c1 | c2 | c3 +----+----+---- +(0 rows) + +--Testcase 461: +DELETE FROM ft2 WHERE ft2.c1 > 2000; +-- Test that trigger on remote table works as expected +--Testcase 462: +CREATE OR REPLACE FUNCTION "S 1".F_BRTRIG() RETURNS trigger AS $$ +BEGIN + NEW.c3 = NEW.c3 || '_trig_update'; + RETURN NEW; +END; +$$ LANGUAGE plpgsql; +--Testcase 463: +CREATE TRIGGER t1_br_insert BEFORE INSERT OR UPDATE + ON "S 1"."T 1" FOR EACH ROW EXECUTE PROCEDURE "S 1".F_BRTRIG(); +--Testcase 464: +INSERT INTO ft2 (c1,c2,c3) VALUES (1208, 818, 'fff'); +--Testcase 465: +SELECT c1, c2, c3, c6, c7, c8 FROM ft2 WHERE c1 = 1208; + c1 | c2 | c3 | c6 | c7 | c8 +------+-----+-----+----+------------+---- + 1208 | 818 | fff | | ft2 | +(1 row) + +--Testcase 466: +INSERT INTO ft2 (c1,c2,c3,c6) VALUES (1218, 818, 'ggg', '(--;'); +--Testcase 467: +SELECT c1, c2, c3, c6, c7, c8 FROM ft2 WHERE c1 = 1218; + c1 | c2 | c3 | c6 | c7 | c8 +------+-----+-----+------+------------+---- + 1218 | 818 | ggg | (--; | ft2 | +(1 row) + +--UPDATE ft2 SET c2 = c2 + 600 WHERE c1 % 10 = 8 AND c1 < 1200 RETURNING *; +-- Test errors thrown on remote side during update +--Testcase 468: +ALTER TABLE "S 1"."T 1" ADD CONSTRAINT c2positive CHECK (c2 >= 0); +-- influxdb_fdw does not support key, ON CONFLICT +--INSERT INTO ft1(c1, c2) VALUES(11, 12); -- duplicate key +--Testcase 469: +INSERT INTO ft1(c1, c2) VALUES(11, 12) ON CONFLICT DO NOTHING; -- works +ERROR: ON CONFLICT is not supported +--Testcase 470: +INSERT INTO ft1(c1, c2) VALUES(11, 12) ON CONFLICT (c1, c2) DO NOTHING; -- unsupported +ERROR: there is no unique or exclusion constraint matching the ON CONFLICT specification +--Testcase 471: +INSERT INTO ft1(c1, c2) VALUES(11, 12) ON CONFLICT (c1, c2) DO UPDATE SET c3 = 'ffg'; -- unsupported +ERROR: there is no unique or exclusion constraint matching the ON CONFLICT specification +--INSERT INTO ft1(c1, c2) VALUES(1111, -2); -- c2positive +--UPDATE ft1 SET c2 = -c2 WHERE c1 = 1; -- c2positive +/* +-- influxdb_fdw does not support transactions +-- Test savepoint/rollback behavior +select c2, count(*) from ft2 where c2 < 500 group by 1 order by 1; +select c2, count(*) from "S 1"."T 1" where c2 < 500 group by 1 order by 1; +begin; +update ft2 set c2 = 42 where c2 = 0; +select c2, count(*) from ft2 where c2 < 500 group by 1 order by 1; +savepoint s1; +update ft2 set c2 = 44 where c2 = 4; +select c2, count(*) from ft2 where c2 < 500 group by 1 order by 1; +release savepoint s1; +select c2, count(*) from ft2 where c2 < 500 group by 1 order by 1; +savepoint s2; +update ft2 set c2 = 46 where c2 = 6; +select c2, count(*) from ft2 where c2 < 500 group by 1 order by 1; +rollback to savepoint s2; +select c2, count(*) from ft2 where c2 < 500 group by 1 order by 1; +release savepoint s2; +select c2, count(*) from ft2 where c2 < 500 group by 1 order by 1; +savepoint s3; +update ft2 set c2 = -2 where c2 = 42 and c1 = 10; -- fail on remote side +rollback to savepoint s3; +select c2, count(*) from ft2 where c2 < 500 group by 1 order by 1; +release savepoint s3; +select c2, count(*) from ft2 where c2 < 500 group by 1 order by 1; +-- none of the above is committed yet remotely +select c2, count(*) from "S 1"."T 1" where c2 < 500 group by 1 order by 1; +commit; +select c2, count(*) from ft2 where c2 < 500 group by 1 order by 1; +select c2, count(*) from "S 1"."T 1" where c2 < 500 group by 1 order by 1; +*/ +-- Above DMLs add data with c6 as NULL in ft1, so test ORDER BY NULLS LAST and NULLs +-- FIRST behavior here. +-- ORDER BY DESC NULLS LAST options +--Testcase 472: +EXPLAIN (VERBOSE, COSTS OFF) SELECT * FROM ft1 ORDER BY c6 DESC NULLS LAST, c1 OFFSET 795 LIMIT 10; + QUERY PLAN +------------------------------------------------------------------------------------ + Limit + Output: c1, c2, c3, "time", c6, c7, c8 + -> Sort + Output: c1, c2, c3, "time", c6, c7, c8 + Sort Key: ft1.c6 DESC NULLS LAST, ft1.c1 + -> Foreign Scan on public.ft1 + Output: c1, c2, c3, "time", c6, c7, c8 + InfluxDB query: SELECT "C 1", "c2", "c3", "c6", "c7", "c8" FROM "T1" +(8 rows) + +--Testcase 473: +SELECT c1, c2, c3, c6, c7, c8 FROM ft1 ORDER BY c6 DESC NULLS LAST, c1 OFFSET 795 LIMIT 10; + c1 | c2 | c3 | c6 | c7 | c8 +------+-----+------------+------+------------+----- + 960 | 0 | 00960 | 0 | 0 | foo + 970 | 0 | 00970 | 0 | 0 | foo + 980 | 0 | 00980 | 0 | 0 | foo + 990 | 0 | 00990 | 0 | 0 | foo + 1000 | 0 | 01000 | 0 | 0 | foo + 1218 | 818 | ggg | (--; | ft2 | + 1001 | 101 | 0000100001 | | ft2 | + 1003 | 103 | 0000300003 | | ft2 | + 1004 | 104 | 0000400004 | | ft2 | + 1006 | 106 | 0000600006 | | ft2 | +(10 rows) + +-- ORDER BY DESC NULLS FIRST options +--Testcase 474: +EXPLAIN (VERBOSE, COSTS OFF) SELECT * FROM ft1 ORDER BY c6 DESC NULLS FIRST, c1 OFFSET 15 LIMIT 10; + QUERY PLAN +------------------------------------------------------------------------------------ + Limit + Output: c1, c2, c3, "time", c6, c7, c8 + -> Sort + Output: c1, c2, c3, "time", c6, c7, c8 + Sort Key: ft1.c6 DESC, ft1.c1 + -> Foreign Scan on public.ft1 + Output: c1, c2, c3, "time", c6, c7, c8 + InfluxDB query: SELECT "C 1", "c2", "c3", "c6", "c7", "c8" FROM "T1" +(8 rows) + +--Testcase 475: +SELECT c1, c2, c3, c6, c7, c8 FROM ft1 ORDER BY c6 DESC NULLS FIRST, c1 OFFSET 15 LIMIT 10; + c1 | c2 | c3 | c6 | c7 | c8 +------+-----+------------+----+------------+----- + 1020 | 100 | 0002000020 | | ft2 | + 1101 | 201 | aaa | | ft2 | + 1103 | 203 | ccc | | ft2 | + 1104 | 204 | ddd | | ft2 | + 1208 | 818 | fff | | ft2 | + 9 | 9 | 00009 | 9 | 9 | foo + 19 | 9 | 00019 | 9 | 9 | foo + 29 | 9 | 00029 | 9 | 9 | foo + 39 | 9 | 00039 | 9 | 9 | foo + 49 | 9 | 00049 | 9 | 9 | foo +(10 rows) + +-- ORDER BY ASC NULLS FIRST options +--Testcase 476: +EXPLAIN (VERBOSE, COSTS OFF) SELECT * FROM ft1 ORDER BY c6 ASC NULLS FIRST, c1 OFFSET 15 LIMIT 10; + QUERY PLAN +------------------------------------------------------------------------------------ + Limit + Output: c1, c2, c3, "time", c6, c7, c8 + -> Sort + Output: c1, c2, c3, "time", c6, c7, c8 + Sort Key: ft1.c6 NULLS FIRST, ft1.c1 + -> Foreign Scan on public.ft1 + Output: c1, c2, c3, "time", c6, c7, c8 + InfluxDB query: SELECT "C 1", "c2", "c3", "c6", "c7", "c8" FROM "T1" +(8 rows) + +--Testcase 477: +SELECT c1, c2, c3, c6, c7, c8 FROM ft1 ORDER BY c6 ASC NULLS FIRST, c1 OFFSET 15 LIMIT 10; + c1 | c2 | c3 | c6 | c7 | c8 +------+-----+------------+------+------------+----- + 1020 | 100 | 0002000020 | | ft2 | + 1101 | 201 | aaa | | ft2 | + 1103 | 203 | ccc | | ft2 | + 1104 | 204 | ddd | | ft2 | + 1208 | 818 | fff | | ft2 | + 1218 | 818 | ggg | (--; | ft2 | + 10 | 0 | 00010 | 0 | 0 | foo + 20 | 0 | 00020 | 0 | 0 | foo + 30 | 0 | 00030 | 0 | 0 | foo + 40 | 0 | 00040 | 0 | 0 | foo +(10 rows) + +-- =================================================================== +-- test check constraints +-- =================================================================== +-- Consistent check constraints provide consistent results +--Testcase 478: +ALTER FOREIGN TABLE ft1 ADD CONSTRAINT ft1_c2positive CHECK (c2 >= 0); +--Testcase 479: +EXPLAIN (VERBOSE, COSTS OFF) SELECT count(*) FROM ft1 WHERE c2 < 0; + QUERY PLAN +---------------------------------------------------------------- + Foreign Scan + Output: (count(*)) + InfluxDB query: SELECT count(*) FROM "T1" WHERE (("c2" < 0)) +(3 rows) + +-- InfluxDB return null value because it does not have any record. +--Testcase 480: +SELECT count(*) FROM ft1 WHERE c2 < 0; + count +------- +(0 rows) + +--Testcase 481: +SET constraint_exclusion = 'on'; +--Testcase 482: +EXPLAIN (VERBOSE, COSTS OFF) SELECT count(*) FROM ft1 WHERE c2 < 0; + QUERY PLAN +-------------------------------- + Aggregate + Output: count(*) + -> Result + One-Time Filter: false +(4 rows) + +--Testcase 483: +SELECT count(*) FROM ft1 WHERE c2 < 0; + count +------- + 0 +(1 row) + +--Testcase 484: +RESET constraint_exclusion; +-- check constraint is enforced on the remote side, not locally +-- INSERT INTO ft1(c1, c2) VALUES(1111, -2); -- c2positive +-- UPDATE ft1 SET c2 = -c2 WHERE c1 = 1; -- c2positive +--Testcase 485: +ALTER FOREIGN TABLE ft1 DROP CONSTRAINT ft1_c2positive; +-- But inconsistent check constraints provide inconsistent results +--Testcase 486: +ALTER FOREIGN TABLE ft1 ADD CONSTRAINT ft1_c2negative CHECK (c2 < 0); +--Testcase 487: +EXPLAIN (VERBOSE, COSTS OFF) SELECT count(*) FROM ft1 WHERE c2 >= 0; + QUERY PLAN +----------------------------------------------------------------- + Foreign Scan + Output: (count(*)) + InfluxDB query: SELECT count(*) FROM "T1" WHERE (("c2" >= 0)) +(3 rows) + +--Testcase 488: +SELECT count(*) FROM ft1 WHERE c2 >= 0; + count +------- + 821 +(1 row) + +--Testcase 489: +SET constraint_exclusion = 'on'; +--Testcase 490: +EXPLAIN (VERBOSE, COSTS OFF) SELECT count(*) FROM ft1 WHERE c2 >= 0; + QUERY PLAN +-------------------------------- + Aggregate + Output: count(*) + -> Result + One-Time Filter: false +(4 rows) + +--Testcase 491: +SELECT count(*) FROM ft1 WHERE c2 >= 0; + count +------- + 0 +(1 row) + +--Testcase 492: +RESET constraint_exclusion; +-- local check constraint is not actually enforced +--Testcase 493: +INSERT INTO ft1(c1, c2) VALUES(1111, 2); +-- UPDATE ft1 SET c2 = c2 + 1 WHERE c1 = 1; +--Testcase 494: +ALTER FOREIGN TABLE ft1 DROP CONSTRAINT ft1_c2negative; +-- influxdb_fdw does not support this feature +-- =================================================================== +-- test WITH CHECK OPTION constraints +-- =================================================================== +--Testcase 495: +CREATE FUNCTION row_before_insupd_trigfunc() RETURNS trigger AS $$BEGIN NEW.a := NEW.a + 10; RETURN NEW; END$$ LANGUAGE plpgsql; +--Testcase 496: +CREATE FOREIGN TABLE base_tbl (a int, b int) SERVER influxdb_svr OPTIONS (table 'base_tbl'); +--ALTER FOREIGN TABLE base_tbl SET (autovacuum_enabled = 'false'); +--Testcase 497: +CREATE TRIGGER row_before_insupd_trigger BEFORE INSERT OR UPDATE ON base_tbl FOR EACH ROW EXECUTE PROCEDURE row_before_insupd_trigfunc(); +--Testcase 498: +CREATE FOREIGN TABLE foreign_tbl (a int, b int) + SERVER influxdb_svr OPTIONS (table 'base_tbl'); +--Testcase 499: +CREATE VIEW rw_view AS SELECT * FROM base_tbl + WHERE a < b WITH CHECK OPTION; +--Testcase 500: +\d+ rw_view + View "public.rw_view" + Column | Type | Collation | Nullable | Default | Storage | Description +--------+---------+-----------+----------+---------+---------+------------- + a | integer | | | | plain | + b | integer | | | | plain | +View definition: + SELECT a, + b + FROM base_tbl + WHERE a < b; +Options: check_option=cascaded + +--Testcase 501: +EXPLAIN (VERBOSE, COSTS OFF) +INSERT INTO rw_view VALUES (0, 5); + QUERY PLAN +--------------------------- + Insert on public.base_tbl + Batch Size: 1 + -> Result + Output: 0, 5 +(4 rows) + +--Testcase 502: +INSERT INTO rw_view VALUES (0, 5); -- should fail +ERROR: new row violates check option for view "rw_view" +DETAIL: Failing row contains (10, 5). +--Testcase 503: +EXPLAIN (VERBOSE, COSTS OFF) +INSERT INTO rw_view VALUES (0, 15); + QUERY PLAN +--------------------------- + Insert on public.base_tbl + Batch Size: 1 + -> Result + Output: 0, 15 +(4 rows) + +--Testcase 504: +INSERT INTO rw_view VALUES (0, 15); -- ok +--Testcase 505: +SELECT * FROM foreign_tbl; + a | b +----+---- + 10 | 5 + 10 | 15 +(2 rows) + +--EXPLAIN (VERBOSE, COSTS OFF) +--UPDATE rw_view SET b = b + 5; +--UPDATE rw_view SET b = b + 5; -- should fail +--EXPLAIN (VERBOSE, COSTS OFF) +--UPDATE rw_view SET b = b + 15; +--UPDATE rw_view SET b = b + 15; -- ok +--SELECT * FROM foreign_tbl; +-- We don't allow batch insert when there are any WCO constraints +ALTER SERVER influxdb_svr OPTIONS (ADD batch_size '10'); +--Testcase 827: +EXPLAIN (VERBOSE, COSTS OFF) +INSERT INTO rw_view VALUES (0, 15), (0, 5); + QUERY PLAN +-------------------------------------------------------- + Insert on public.base_tbl + Batch Size: 1 + -> Values Scan on "*VALUES*" + Output: "*VALUES*".column1, "*VALUES*".column2 +(4 rows) + +--Testcase 828: +INSERT INTO rw_view VALUES (0, 15), (0, 5); -- should fail +ERROR: new row violates check option for view "rw_view" +DETAIL: Failing row contains (10, 5). +--Testcase 829: +SELECT * FROM foreign_tbl; + a | b +----+---- + 10 | 5 + 10 | 15 + 10 | 15 + 10 | 5 +(4 rows) + +ALTER SERVER influxdb_svr OPTIONS (DROP batch_size); +--Testcase 506: +DELETE FROM foreign_tbl; +--Testcase 784: +DROP FOREIGN TABLE foreign_tbl CASCADE; +--Testcase 507: +DROP TRIGGER row_before_insupd_trigger ON base_tbl; +--Testcase 508: +DROP FOREIGN TABLE base_tbl CASCADE; +NOTICE: drop cascades to view rw_view +-- influxdb_fdw does not support partitions +-- test WCO for partitions +--Testcase 509: +CREATE FOREIGN TABLE child_tbl (a int, b int) SERVER influxdb_svr OPTIONS (table 'child_tbl'); +--ALTER FOREIGN TABLE child_tbl SET (autovacuum_enabled = 'false'); +--Testcase 510: +CREATE TRIGGER row_before_insupd_trigger BEFORE INSERT OR UPDATE ON child_tbl FOR EACH ROW EXECUTE PROCEDURE row_before_insupd_trigfunc(); +--Testcase 511: +CREATE FOREIGN TABLE foreign_tbl (a int, b int) + SERVER influxdb_svr OPTIONS (table 'child_tbl'); +--Testcase 512: +CREATE TABLE parent_tbl (a int, b int) PARTITION BY RANGE(a); +--Testcase 513: +ALTER TABLE parent_tbl ATTACH PARTITION child_tbl FOR VALUES FROM (0) TO (100); +-- Detach and re-attach once, to stress the concurrent detach case. +--Testcase 774: +ALTER TABLE parent_tbl DETACH PARTITION child_tbl CONCURRENTLY; +--Testcase 775: +ALTER TABLE parent_tbl ATTACH PARTITION child_tbl FOR VALUES FROM (0) TO (100); +--Testcase 514: +CREATE VIEW rw_view AS SELECT * FROM parent_tbl + WHERE a < b WITH CHECK OPTION; +--Testcase 515: +\d+ rw_view + View "public.rw_view" + Column | Type | Collation | Nullable | Default | Storage | Description +--------+---------+-----------+----------+---------+---------+------------- + a | integer | | | | plain | + b | integer | | | | plain | +View definition: + SELECT a, + b + FROM parent_tbl + WHERE a < b; +Options: check_option=cascaded + +--Testcase 516: +EXPLAIN (VERBOSE, COSTS OFF) +INSERT INTO rw_view VALUES (0, 5); + QUERY PLAN +----------------------------- + Insert on public.parent_tbl + -> Result + Output: 0, 5 +(3 rows) + +--Testcase 517: +INSERT INTO rw_view VALUES (0, 5); -- should fail +ERROR: Not support partition insert +--Testcase 518: +EXPLAIN (VERBOSE, COSTS OFF) +INSERT INTO rw_view VALUES (0, 15); + QUERY PLAN +----------------------------- + Insert on public.parent_tbl + -> Result + Output: 0, 15 +(3 rows) + +--Testcase 519: +INSERT INTO rw_view VALUES (0, 15); -- ok +ERROR: Not support partition insert +--Testcase 520: +SELECT * FROM foreign_tbl; + a | b +---+--- +(0 rows) + +--EXPLAIN (VERBOSE, COSTS OFF) +--UPDATE rw_view SET b = b + 5; +--UPDATE rw_view SET b = b + 5; -- should fail +--EXPLAIN (VERBOSE, COSTS OFF) +--UPDATE rw_view SET b = b + 15; +--UPDATE rw_view SET b = b + 15; -- ok +--SELECT * FROM foreign_tbl; +-- We don't allow batch insert when there are any WCO constraints +ALTER SERVER influxdb_svr OPTIONS (ADD batch_size '10'); +--Testcase 830: +EXPLAIN (VERBOSE, COSTS OFF) +INSERT INTO rw_view VALUES (0, 15), (0, 5); + QUERY PLAN +-------------------------------------------------------- + Insert on public.parent_tbl + -> Values Scan on "*VALUES*" + Output: "*VALUES*".column1, "*VALUES*".column2 +(3 rows) + +--Testcase 831: +INSERT INTO rw_view VALUES (0, 15), (0, 5); -- should fail +ERROR: Not support partition insert +--Testcase 832: +SELECT * FROM foreign_tbl; + a | b +---+--- +(0 rows) + +ALTER SERVER influxdb_svr OPTIONS (DROP batch_size); +--Testcase 521: +DROP FOREIGN TABLE foreign_tbl CASCADE; +--Testcase 522: +DROP TRIGGER row_before_insupd_trigger ON child_tbl; +--Testcase 523: +DROP FOREIGN TABLE child_tbl CASCADE; +--Testcase 524: +DROP TABLE parent_tbl CASCADE; +NOTICE: drop cascades to view rw_view +--Testcase 525: +DROP FUNCTION row_before_insupd_trigfunc; +-- Try a more complex permutation of WCO where there are multiple levels of +-- partitioned tables with columns not all in the same order +CREATE TABLE parent_tbl (a int, b text, c numeric) PARTITION BY RANGE(a); +CREATE TABLE sub_parent (c numeric, a int, b text) PARTITION BY RANGE(a); +ALTER TABLE parent_tbl ATTACH PARTITION sub_parent FOR VALUES FROM (1) TO (10); +CREATE TABLE child_local (b text, c numeric, a int); +CREATE FOREIGN TABLE child_foreign (b text, c numeric, a int) + SERVER influxdb_svr OPTIONS (table 'child_local'); +ALTER TABLE sub_parent ATTACH PARTITION child_foreign FOR VALUES FROM (1) TO (10); +CREATE VIEW rw_view AS SELECT * FROM parent_tbl WHERE a < 5 WITH CHECK OPTION; +-- Not support partition insert +INSERT INTO parent_tbl (a) VALUES(1),(5); +ERROR: Not support partition insert +-- UPDATE is not supported +EXPLAIN (VERBOSE, COSTS OFF) +UPDATE rw_view SET b = 'text', c = 123.456; +ERROR: UPDATE is not supported +-- UPDATE is not supported +UPDATE rw_view SET b = 'text', c = 123.456; +ERROR: UPDATE is not supported +SELECT * FROM parent_tbl ORDER BY a; + a | b | c +---+---+--- +(0 rows) + +DROP VIEW rw_view; +DROP TABLE child_local; +DROP FOREIGN TABLE child_foreign; +DROP TABLE sub_parent; +DROP TABLE parent_tbl; +-- =================================================================== +-- test serial columns (ie, sequence-based defaults) +-- =================================================================== +--Testcase 526: +create foreign table loc1 (f1 serial, f2 text) + server influxdb_svr options(table 'loc1'); +--alter foreign table loc1 set (autovacuum_enabled = 'false'); +--Testcase 527: +create foreign table rem1 (f1 serial, f2 text) + server influxdb_svr options(table 'loc1'); +--Testcase 528: +select pg_catalog.setval('rem1_f1_seq', 10, false); + setval +-------- + 10 +(1 row) + +--Testcase 529: +insert into loc1(f2) values('hi'); +--Testcase 530: +insert into rem1(f2) values('hi remote'); +--Testcase 531: +insert into loc1(f2) values('bye'); +--Testcase 532: +insert into rem1(f2) values('bye remote'); +--Testcase 533: +select * from loc1; + f1 | f2 +----+------------ + 1 | hi + 10 | hi remote + 2 | bye + 11 | bye remote +(4 rows) + +--Testcase 534: +select * from rem1; + f1 | f2 +----+------------ + 1 | hi + 10 | hi remote + 2 | bye + 11 | bye remote +(4 rows) + +-- =================================================================== +-- test generated columns +-- =================================================================== +--Testcase 535: +create foreign table gloc1 ( + a int, + b int generated always as (a * 2) stored) + server influxdb_svr options(table 'gloc1'); +--alter foreign table gloc1 set (autovacuum_enabled = 'false'); +--Testcase 536: +create foreign table grem1 ( + a int, + b int generated always as (a * 2) stored) + server influxdb_svr options(table 'gloc1'); +--Testcase 537: +explain (verbose, costs off) +insert into grem1 (a) values (1), (22); + QUERY PLAN +--------------------------------------------------- + Insert on public.grem1 + Batch Size: 1 + -> Values Scan on "*VALUES*" + Output: "*VALUES*".column1, NULL::integer +(4 rows) + +--Testcase 765: +insert into grem1 (a) values (1), (22); +--explain (verbose, costs off) +--update grem1 set a = 22 where a = 2; +--update grem1 set a = 22 where a = 2; +--Testcase 538: +select * from gloc1; + a | b +----+---- + 1 | 2 + 22 | 44 +(2 rows) + +--Testcase 539: +select * from grem1; + a | b +----+---- + 1 | 2 + 22 | 44 +(2 rows) + +--Testcase 766: +delete from grem1; +/* +-- InfluxDB FDW does not support partition insert +-- test copy from +copy grem1 from stdin; +1 +2 +\. +select * from gloc1; +select * from grem1; +delete from grem1; +*/ +-- test batch insert +--Testcase 767: +alter server influxdb_svr options (add batch_size '10'); +--Testcase 768: +explain (verbose, costs off) +insert into grem1 (a) values (1), (2); + QUERY PLAN +--------------------------------------------------- + Insert on public.grem1 + Batch Size: 10 + -> Values Scan on "*VALUES*" + Output: "*VALUES*".column1, NULL::integer +(4 rows) + +--Testcase 769: +insert into grem1 (a) values (1), (2); +--Testcase 770: +select * from gloc1; + a | b +---+--- + 1 | 2 + 2 | 4 +(2 rows) + +--Testcase 771: +select * from grem1; + a | b +---+--- + 1 | 2 + 2 | 4 +(2 rows) + +--Testcase 772: +delete from grem1; +-- batch insert with foreign partitions. +-- This schema uses two partitions, one local and one remote with a modulo +-- to loop across all of them in batches. +create table tab_batch_local (id int, data text); +insert into tab_batch_local select i, 'test'|| i from generate_series(1, 45) i; +create table tab_batch_sharded (id int, data text) partition by hash(id); +create table tab_batch_sharded_p0 partition of tab_batch_sharded + for values with (modulus 2, remainder 0); +create table tab_batch_sharded_p1_remote (id int, data text); +create foreign table tab_batch_sharded_p1 partition of tab_batch_sharded + for values with (modulus 2, remainder 1) + server influxdb_svr options (table 'tab_batch_sharded_p1_remote'); +-- Not support partition insert +insert into tab_batch_sharded select * from tab_batch_local; +ERROR: Not support partition insert +select count(*) from tab_batch_sharded; + count +------- + 0 +(1 row) + +drop table tab_batch_local; +drop table tab_batch_sharded; +drop table tab_batch_sharded_p1_remote; +--Testcase 773: +alter server influxdb_svr options (drop batch_size); +-- =================================================================== +-- test local triggers +-- =================================================================== +-- Trigger functions "borrowed" from triggers regress test. +--Testcase 540: +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;$$; +--Testcase 541: +CREATE TRIGGER trig_stmt_before BEFORE DELETE OR INSERT OR UPDATE OR TRUNCATE ON rem1 + FOR EACH STATEMENT EXECUTE PROCEDURE trigger_func(); +--Testcase 542: +CREATE TRIGGER trig_stmt_after AFTER DELETE OR INSERT OR UPDATE OR TRUNCATE ON rem1 + FOR EACH STATEMENT EXECUTE PROCEDURE trigger_func(); +--Testcase 543: +CREATE OR REPLACE FUNCTION trigger_data() RETURNS trigger +LANGUAGE plpgsql AS $$ + +declare + oldnew text[]; + relid text; + argstr text; +begin + + relid := TG_relid::regclass; + argstr := ''; + 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 '%(%) % % % ON %', + tg_name, argstr, TG_when, TG_level, TG_OP, relid; + oldnew := '{}'::text[]; + if TG_OP != 'INSERT' then + oldnew := array_append(oldnew, format('OLD: %s', OLD)); + end if; + + if TG_OP != 'DELETE' then + oldnew := array_append(oldnew, format('NEW: %s', NEW)); + end if; + + RAISE NOTICE '%', array_to_string(oldnew, ','); + + if TG_OP = 'DELETE' then + return OLD; + else + return NEW; + end if; +end; +$$; +-- Test basic functionality +--Testcase 544: +CREATE TRIGGER trig_row_before +BEFORE INSERT OR UPDATE OR DELETE ON rem1 +FOR EACH ROW EXECUTE PROCEDURE trigger_data(23,'skidoo'); +--Testcase 545: +CREATE TRIGGER trig_row_after +AFTER INSERT OR UPDATE OR DELETE ON rem1 +FOR EACH ROW EXECUTE PROCEDURE trigger_data(23,'skidoo'); +--Testcase 546: +delete from rem1; +NOTICE: trigger_func() called: action = DELETE, when = BEFORE, level = STATEMENT +NOTICE: trig_row_before(23, skidoo) BEFORE ROW DELETE ON rem1 +NOTICE: OLD: (1,hi) +NOTICE: trig_row_before(23, skidoo) BEFORE ROW DELETE ON rem1 +NOTICE: OLD: (10,"hi remote") +NOTICE: trig_row_before(23, skidoo) BEFORE ROW DELETE ON rem1 +NOTICE: OLD: (2,bye) +NOTICE: trig_row_before(23, skidoo) BEFORE ROW DELETE ON rem1 +NOTICE: OLD: (11,"bye remote") +NOTICE: trig_row_after(23, skidoo) AFTER ROW DELETE ON rem1 +NOTICE: OLD: (1,hi) +NOTICE: trig_row_after(23, skidoo) AFTER ROW DELETE ON rem1 +NOTICE: OLD: (10,"hi remote") +NOTICE: trig_row_after(23, skidoo) AFTER ROW DELETE ON rem1 +NOTICE: OLD: (2,bye) +NOTICE: trig_row_after(23, skidoo) AFTER ROW DELETE ON rem1 +NOTICE: OLD: (11,"bye remote") +NOTICE: trigger_func() called: action = DELETE, when = AFTER, level = STATEMENT +--Testcase 547: +insert into rem1 values(1,'insert'); +NOTICE: trigger_func() called: action = INSERT, when = BEFORE, level = STATEMENT +NOTICE: trig_row_before(23, skidoo) BEFORE ROW INSERT ON rem1 +NOTICE: NEW: (1,insert) +NOTICE: trig_row_after(23, skidoo) AFTER ROW INSERT ON rem1 +NOTICE: NEW: (1,insert) +NOTICE: trigger_func() called: action = INSERT, when = AFTER, level = STATEMENT +--update rem1 set f2 = 'update' where f1 = 1; +--update rem1 set f2 = f2 || f2; +--truncate rem1; +-- cleanup +--Testcase 548: +DROP TRIGGER trig_row_before ON rem1; +--Testcase 549: +DROP TRIGGER trig_row_after ON rem1; +--Testcase 550: +DROP TRIGGER trig_stmt_before ON rem1; +--Testcase 551: +DROP TRIGGER trig_stmt_after ON rem1; +--Testcase 552: +DELETE from rem1; +-- Test multiple AFTER ROW triggers on a foreign table +--Testcase 553: +CREATE TRIGGER trig_row_after1 +AFTER INSERT OR UPDATE OR DELETE ON rem1 +FOR EACH ROW EXECUTE PROCEDURE trigger_data(23,'skidoo'); +--Testcase 554: +CREATE TRIGGER trig_row_after2 +AFTER INSERT OR UPDATE OR DELETE ON rem1 +FOR EACH ROW EXECUTE PROCEDURE trigger_data(23,'skidoo'); +--Testcase 555: +insert into rem1 values(1,'insert'); +NOTICE: trig_row_after1(23, skidoo) AFTER ROW INSERT ON rem1 +NOTICE: NEW: (1,insert) +NOTICE: trig_row_after2(23, skidoo) AFTER ROW INSERT ON rem1 +NOTICE: NEW: (1,insert) +--update rem1 set f2 = 'update' where f1 = 1; +--update rem1 set f2 = f2 || f2; +--Testcase 556: +delete from rem1; +NOTICE: trig_row_after1(23, skidoo) AFTER ROW DELETE ON rem1 +NOTICE: OLD: (1,insert) +NOTICE: trig_row_after2(23, skidoo) AFTER ROW DELETE ON rem1 +NOTICE: OLD: (1,insert) +-- cleanup +--Testcase 557: +DROP TRIGGER trig_row_after1 ON rem1; +--Testcase 558: +DROP TRIGGER trig_row_after2 ON rem1; +-- Test WHEN conditions +--Testcase 559: +CREATE TRIGGER trig_row_before_insupd +BEFORE INSERT OR UPDATE ON rem1 +FOR EACH ROW +WHEN (NEW.f2 like '%update%') +EXECUTE PROCEDURE trigger_data(23,'skidoo'); +--Testcase 560: +CREATE TRIGGER trig_row_after_insupd +AFTER INSERT OR UPDATE ON rem1 +FOR EACH ROW +WHEN (NEW.f2 like '%update%') +EXECUTE PROCEDURE trigger_data(23,'skidoo'); +-- Insert or update not matching: nothing happens +--Testcase 561: +INSERT INTO rem1 values(1, 'insert'); +--UPDATE rem1 set f2 = 'test'; +-- Insert or update matching: triggers are fired +--Testcase 562: +INSERT INTO rem1 values(2, 'update'); +NOTICE: trig_row_before_insupd(23, skidoo) BEFORE ROW INSERT ON rem1 +NOTICE: NEW: (2,update) +NOTICE: trig_row_after_insupd(23, skidoo) AFTER ROW INSERT ON rem1 +NOTICE: NEW: (2,update) +--UPDATE rem1 set f2 = 'update update' where f1 = '2'; +--Testcase 563: +CREATE TRIGGER trig_row_before_delete +BEFORE DELETE ON rem1 +FOR EACH ROW +WHEN (OLD.f2 like '%update%') +EXECUTE PROCEDURE trigger_data(23,'skidoo'); +--Testcase 564: +CREATE TRIGGER trig_row_after_delete +AFTER DELETE ON rem1 +FOR EACH ROW +WHEN (OLD.f2 like '%update%') +EXECUTE PROCEDURE trigger_data(23,'skidoo'); +-- Trigger is fired for f1=2, not for f1=1 +--Testcase 565: +DELETE FROM rem1; +NOTICE: trig_row_before_delete(23, skidoo) BEFORE ROW DELETE ON rem1 +NOTICE: OLD: (2,update) +NOTICE: trig_row_after_delete(23, skidoo) AFTER ROW DELETE ON rem1 +NOTICE: OLD: (2,update) +-- cleanup +--Testcase 566: +DROP TRIGGER trig_row_before_insupd ON rem1; +--Testcase 567: +DROP TRIGGER trig_row_after_insupd ON rem1; +--Testcase 568: +DROP TRIGGER trig_row_before_delete ON rem1; +--Testcase 569: +DROP TRIGGER trig_row_after_delete ON rem1; +-- Test various RETURN statements in BEFORE triggers. +--Testcase 570: +CREATE FUNCTION trig_row_before_insupdate() RETURNS TRIGGER AS $$ + BEGIN + NEW.f2 := NEW.f2 || ' triggered !'; + RETURN NEW; + END +$$ language plpgsql; +--Testcase 571: +CREATE TRIGGER trig_row_before_insupd +BEFORE INSERT OR UPDATE ON rem1 +FOR EACH ROW EXECUTE PROCEDURE trig_row_before_insupdate(); +-- The new values should have 'triggered' appended +--Testcase 572: +INSERT INTO rem1 values(1, 'insert'); +--Testcase 573: +SELECT * from loc1; + f1 | f2 +----+-------------------- + 1 | insert triggered ! +(1 row) + +--Testcase 574: +INSERT INTO rem1 values(2, 'insert'); +--Testcase 575: +SELECT f2 FROM rem1 WHERE f1 = 2; + f2 +-------------------- + insert triggered ! +(1 row) + +--Testcase 576: +SELECT * from loc1; + f1 | f2 +----+-------------------- + 1 | insert triggered ! + 2 | insert triggered ! +(2 rows) + +--UPDATE rem1 set f2 = ''; +--SELECT * from loc1; +--UPDATE rem1 set f2 = 'skidoo' RETURNING f2; +--SELECT * from loc1; +--EXPLAIN (verbose, costs off) +--UPDATE rem1 set f1 = 10; -- all columns should be transmitted +--UPDATE rem1 set f1 = 10; +--SELECT * from loc1; +--Testcase 577: +DELETE FROM rem1; +-- Add a second trigger, to check that the changes are propagated correctly +-- from trigger to trigger +--Testcase 578: +CREATE TRIGGER trig_row_before_insupd2 +BEFORE INSERT OR UPDATE ON rem1 +FOR EACH ROW EXECUTE PROCEDURE trig_row_before_insupdate(); +--Testcase 579: +INSERT INTO rem1 values(1, 'insert'); +--Testcase 580: +SELECT * from loc1; + f1 | f2 +----+-------------------------------- + 1 | insert triggered ! triggered ! +(1 row) + +--Testcase 581: +INSERT INTO rem1 values(2, 'insert'); +--Testcase 582: +SELECT f2 FROM rem1 WHERE f1 = 2; + f2 +-------------------------------- + insert triggered ! triggered ! +(1 row) + +--Testcase 583: +SELECT * from loc1; + f1 | f2 +----+-------------------------------- + 1 | insert triggered ! triggered ! + 2 | insert triggered ! triggered ! +(2 rows) + +--UPDATE rem1 set f2 = ''; +--SELECT * from loc1; +--UPDATE rem1 set f2 = 'skidoo' RETURNING f2; +--SELECT * from loc1; +--Testcase 584: +DROP TRIGGER trig_row_before_insupd ON rem1; +--Testcase 585: +DROP TRIGGER trig_row_before_insupd2 ON rem1; +--Testcase 586: +DELETE from rem1; +--Testcase 587: +INSERT INTO rem1 VALUES (1, 'test'); +-- Test with a trigger returning NULL +--Testcase 588: +CREATE FUNCTION trig_null() RETURNS TRIGGER AS $$ + BEGIN + RETURN NULL; + END +$$ language plpgsql; +--Testcase 589: +CREATE TRIGGER trig_null +BEFORE INSERT OR UPDATE OR DELETE ON rem1 +FOR EACH ROW EXECUTE PROCEDURE trig_null(); +-- Nothing should have changed. +--Testcase 590: +INSERT INTO rem1 VALUES (2, 'test2'); +--Testcase 591: +SELECT * from loc1; + f1 | f2 +----+------ + 1 | test +(1 row) + +--UPDATE rem1 SET f2 = 'test2'; +--SELECT * from loc1; +--Testcase 592: +DELETE from rem1; +--Testcase 593: +SELECT * from loc1; + f1 | f2 +----+------ + 1 | test +(1 row) + +--Testcase 594: +DROP TRIGGER trig_null ON rem1; +--Testcase 595: +DELETE from rem1; +-- Test a combination of local and remote triggers +--Testcase 596: +CREATE TRIGGER trig_row_before +BEFORE INSERT OR UPDATE OR DELETE ON rem1 +FOR EACH ROW EXECUTE PROCEDURE trigger_data(23,'skidoo'); +--Testcase 597: +CREATE TRIGGER trig_row_after +AFTER INSERT OR UPDATE OR DELETE ON rem1 +FOR EACH ROW EXECUTE PROCEDURE trigger_data(23,'skidoo'); +--Testcase 598: +CREATE TRIGGER trig_local_before BEFORE INSERT OR UPDATE ON loc1 +FOR EACH ROW EXECUTE PROCEDURE trig_row_before_insupdate(); +--Testcase 599: +INSERT INTO rem1(f2) VALUES ('test'); +NOTICE: trig_row_before(23, skidoo) BEFORE ROW INSERT ON rem1 +NOTICE: NEW: (12,test) +NOTICE: trig_row_after(23, skidoo) AFTER ROW INSERT ON rem1 +NOTICE: NEW: (12,test) +--UPDATE rem1 SET f2 = 'testo'; +-- Test returning a system attribute +--Testcase 600: +INSERT INTO rem1(f2) VALUES ('test'); +NOTICE: trig_row_before(23, skidoo) BEFORE ROW INSERT ON rem1 +NOTICE: NEW: (13,test) +NOTICE: trig_row_after(23, skidoo) AFTER ROW INSERT ON rem1 +NOTICE: NEW: (13,test) +--Testcase 601: +SELECT * FROM rem1 WHERE f2 = 'test'; + f1 | f2 +----+------ + 12 | test + 13 | test +(2 rows) + +-- cleanup +--Testcase 602: +DROP TRIGGER trig_row_before ON rem1; +--Testcase 603: +DROP TRIGGER trig_row_after ON rem1; +--Testcase 604: +DROP TRIGGER trig_local_before ON loc1; +-- Test direct foreign table modification functionality +--Testcase 774: +EXPLAIN (verbose, costs off) +DELETE FROM rem1; -- can be pushed down + QUERY PLAN +-------------------------------------------- + Delete on public.rem1 + -> Foreign Delete on public.rem1 + InfluxDB query: DELETE FROM "loc1" +(3 rows) + +--Testcase 775: +EXPLAIN (verbose, costs off) +DELETE FROM rem1 WHERE false; -- currently can't be pushed down + QUERY PLAN +-------------------------------- + Delete on public.rem1 + -> Result + One-Time Filter: false +(3 rows) + +-- Test with statement-level triggers +--Testcase 605: +CREATE TRIGGER trig_stmt_before + BEFORE DELETE OR INSERT OR UPDATE ON rem1 + FOR EACH STATEMENT EXECUTE PROCEDURE trigger_func(); +--EXPLAIN (verbose, costs off) +--UPDATE rem1 set f2 = ''; -- can be pushed down +--Testcase 606: +EXPLAIN (verbose, costs off) +DELETE FROM rem1; -- can be pushed down + QUERY PLAN +-------------------------------------------- + Delete on public.rem1 + -> Foreign Delete on public.rem1 + InfluxDB query: DELETE FROM "loc1" +(3 rows) + +--Testcase 607: +DROP TRIGGER trig_stmt_before ON rem1; +--Testcase 608: +CREATE TRIGGER trig_stmt_after + AFTER DELETE OR INSERT OR UPDATE ON rem1 + FOR EACH STATEMENT EXECUTE PROCEDURE trigger_func(); +--EXPLAIN (verbose, costs off) +--UPDATE rem1 set f2 = ''; -- can be pushed down +--Testcase 609: +EXPLAIN (verbose, costs off) +DELETE FROM rem1; -- can be pushed down + QUERY PLAN +-------------------------------------------- + Delete on public.rem1 + -> Foreign Delete on public.rem1 + InfluxDB query: DELETE FROM "loc1" +(3 rows) + +--Testcase 610: +DROP TRIGGER trig_stmt_after ON rem1; +-- Test with row-level ON INSERT triggers +--Testcase 611: +CREATE TRIGGER trig_row_before_insert +BEFORE INSERT ON rem1 +FOR EACH ROW EXECUTE PROCEDURE trigger_data(23,'skidoo'); +--EXPLAIN (verbose, costs off) +--UPDATE rem1 set f2 = ''; -- can be pushed down +--Testcase 612: +EXPLAIN (verbose, costs off) +DELETE FROM rem1; -- can be pushed down + QUERY PLAN +-------------------------------------------- + Delete on public.rem1 + -> Foreign Delete on public.rem1 + InfluxDB query: DELETE FROM "loc1" +(3 rows) + +--Testcase 613: +DROP TRIGGER trig_row_before_insert ON rem1; +--Testcase 614: +CREATE TRIGGER trig_row_after_insert +AFTER INSERT ON rem1 +FOR EACH ROW EXECUTE PROCEDURE trigger_data(23,'skidoo'); +--EXPLAIN (verbose, costs off) +--UPDATE rem1 set f2 = ''; -- can be pushed down +--Testcase 615: +EXPLAIN (verbose, costs off) +DELETE FROM rem1; -- can be pushed down + QUERY PLAN +-------------------------------------------- + Delete on public.rem1 + -> Foreign Delete on public.rem1 + InfluxDB query: DELETE FROM "loc1" +(3 rows) + +--Testcase 616: +DROP TRIGGER trig_row_after_insert ON rem1; +-- Test with row-level ON UPDATE triggers +--Testcase 617: +CREATE TRIGGER trig_row_before_update +BEFORE UPDATE ON rem1 +FOR EACH ROW EXECUTE PROCEDURE trigger_data(23,'skidoo'); +--EXPLAIN (verbose, costs off) +--UPDATE rem1 set f2 = ''; -- can't be pushed down +--Testcase 618: +EXPLAIN (verbose, costs off) +DELETE FROM rem1; -- can be pushed down + QUERY PLAN +-------------------------------------------- + Delete on public.rem1 + -> Foreign Delete on public.rem1 + InfluxDB query: DELETE FROM "loc1" +(3 rows) + +--Testcase 619: +DROP TRIGGER trig_row_before_update ON rem1; +--Testcase 620: +CREATE TRIGGER trig_row_after_update +AFTER UPDATE ON rem1 +FOR EACH ROW EXECUTE PROCEDURE trigger_data(23,'skidoo'); +--EXPLAIN (verbose, costs off) +--UPDATE rem1 set f2 = ''; -- can't be pushed down +--Testcase 621: +EXPLAIN (verbose, costs off) +DELETE FROM rem1; -- can be pushed down + QUERY PLAN +-------------------------------------------- + Delete on public.rem1 + -> Foreign Delete on public.rem1 + InfluxDB query: DELETE FROM "loc1" +(3 rows) + +--Testcase 622: +DROP TRIGGER trig_row_after_update ON rem1; +-- Test with row-level ON DELETE triggers +--Testcase 623: +CREATE TRIGGER trig_row_before_delete +BEFORE DELETE ON rem1 +FOR EACH ROW EXECUTE PROCEDURE trigger_data(23,'skidoo'); +--EXPLAIN (verbose, costs off) +--UPDATE rem1 set f2 = ''; -- can be pushed down +--Testcase 624: +EXPLAIN (verbose, costs off) +DELETE FROM rem1; -- can't be pushed down + QUERY PLAN +------------------------------------------------------- + Delete on public.rem1 + -> Foreign Scan on public.rem1 + Output: rem1.* + InfluxDB query: SELECT "f1", "f2" FROM "loc1" +(4 rows) + +--Testcase 625: +DROP TRIGGER trig_row_before_delete ON rem1; +--Testcase 626: +CREATE TRIGGER trig_row_after_delete +AFTER DELETE ON rem1 +FOR EACH ROW EXECUTE PROCEDURE trigger_data(23,'skidoo'); +--EXPLAIN (verbose, costs off) +--UPDATE rem1 set f2 = ''; -- can be pushed down +--Testcase 627: +EXPLAIN (verbose, costs off) +DELETE FROM rem1; -- can't be pushed down + QUERY PLAN +------------------------------------------------------- + Delete on public.rem1 + -> Foreign Scan on public.rem1 + Output: rem1.* + InfluxDB query: SELECT "f1", "f2" FROM "loc1" +(4 rows) + +--Testcase 628: +DROP TRIGGER trig_row_after_delete ON rem1; +-- =================================================================== +-- test inheritance features +-- =================================================================== +--Testcase 629: +CREATE TABLE a (aa TEXT); +--CREATE TABLE loct (aa TEXT, bb TEXT); +--Testcase 630: +ALTER TABLE a SET (autovacuum_enabled = 'false'); +--ALTER TABLE loct SET (autovacuum_enabled = 'false'); +-- Because influxdb_fdw does not support UPDATE, to test locally +-- we create local table. +--Testcase 631: +CREATE TABLE b (bb TEXT) INHERITS (a); +--Testcase 632: +INSERT INTO a(aa) VALUES('aaa'); +--Testcase 633: +INSERT INTO a(aa) VALUES('aaaa'); +--Testcase 634: +INSERT INTO a(aa) VALUES('aaaaa'); +--Testcase 635: +INSERT INTO b(aa) VALUES('bbb'); +--Testcase 636: +INSERT INTO b(aa) VALUES('bbbb'); +--Testcase 637: +INSERT INTO b(aa) VALUES('bbbbb'); +--Testcase 638: +SELECT tableoid::regclass, * FROM a; + tableoid | aa +----------+------- + a | aaa + a | aaaa + a | aaaaa + b | bbb + b | bbbb + b | bbbbb +(6 rows) + +--Testcase 639: +SELECT tableoid::regclass, * FROM b; + tableoid | aa | bb +----------+-------+---- + b | bbb | + b | bbbb | + b | bbbbb | +(3 rows) + +--Testcase 640: +SELECT tableoid::regclass, * FROM ONLY a; + tableoid | aa +----------+------- + a | aaa + a | aaaa + a | aaaaa +(3 rows) + +--Testcase 641: +UPDATE a SET aa = 'zzzzzz' WHERE aa LIKE 'aaaa%'; +--Testcase 642: +SELECT tableoid::regclass, * FROM a; + tableoid | aa +----------+-------- + a | aaa + a | zzzzzz + a | zzzzzz + b | bbb + b | bbbb + b | bbbbb +(6 rows) + +--Testcase 643: +SELECT tableoid::regclass, * FROM b; + tableoid | aa | bb +----------+-------+---- + b | bbb | + b | bbbb | + b | bbbbb | +(3 rows) + +--Testcase 644: +SELECT tableoid::regclass, * FROM ONLY a; + tableoid | aa +----------+-------- + a | aaa + a | zzzzzz + a | zzzzzz +(3 rows) + +--Testcase 645: +UPDATE b SET aa = 'new'; +--Testcase 646: +SELECT tableoid::regclass, * FROM a; + tableoid | aa +----------+-------- + a | aaa + a | zzzzzz + a | zzzzzz + b | new + b | new + b | new +(6 rows) + +--Testcase 647: +SELECT tableoid::regclass, * FROM b; + tableoid | aa | bb +----------+-----+---- + b | new | + b | new | + b | new | +(3 rows) + +--Testcase 648: +SELECT tableoid::regclass, * FROM ONLY a; + tableoid | aa +----------+-------- + a | aaa + a | zzzzzz + a | zzzzzz +(3 rows) + +--Testcase 649: +UPDATE a SET aa = 'newtoo'; +--Testcase 650: +SELECT tableoid::regclass, * FROM a; + tableoid | aa +----------+-------- + a | newtoo + a | newtoo + a | newtoo + b | newtoo + b | newtoo + b | newtoo +(6 rows) + +--Testcase 651: +SELECT tableoid::regclass, * FROM b; + tableoid | aa | bb +----------+--------+---- + b | newtoo | + b | newtoo | + b | newtoo | +(3 rows) + +--Testcase 652: +SELECT tableoid::regclass, * FROM ONLY a; + tableoid | aa +----------+-------- + a | newtoo + a | newtoo + a | newtoo +(3 rows) + +--Testcase 653: +DELETE FROM a; +--Testcase 654: +SELECT tableoid::regclass, * FROM a; + tableoid | aa +----------+---- +(0 rows) + +--Testcase 655: +SELECT tableoid::regclass, * FROM b; + tableoid | aa | bb +----------+----+---- +(0 rows) + +--Testcase 656: +SELECT tableoid::regclass, * FROM ONLY a; + tableoid | aa +----------+---- +(0 rows) + +--Testcase 657: +DROP TABLE a CASCADE; +NOTICE: drop cascades to table b +--DROP TABLE loct; +-- Check SELECT FOR UPDATE/SHARE with an inherited source table +--Testcase 658: +create foreign table loct1 (f1 int, f2 int, f3 int) server influxdb_svr options(table 'loct1'); +--Testcase 659: +create foreign table loct2 (f1 int, f2 int, f3 int) server influxdb_svr options(table 'loct2'); +--alter table loct1 set (autovacuum_enabled = 'false'); +--alter table loct2 set (autovacuum_enabled = 'false'); +--Testcase 660: +create foreign table foo (f1 int, f2 int) + server influxdb_svr options (table 'foo'); +--Testcase 661: +create foreign table foo2 (f3 int) inherits (foo) + server influxdb_svr options (table 'loct1'); +--Testcase 662: +create foreign table bar (f1 int, f2 int) + server influxdb_svr options (table 'bar'); +--Testcase 663: +create foreign table bar2 (f3 int) inherits (bar) + server influxdb_svr options (table 'loct2'); +--alter table foo set (autovacuum_enabled = 'false'); +--alter table bar set (autovacuum_enabled = 'false'); +--Testcase 664: +insert into foo values(1,1); +--Testcase 665: +insert into foo values(3,3); +--Testcase 666: +insert into foo2 values(2,2,2); +--Testcase 667: +insert into foo2 values(4,4,4); +--Testcase 668: +insert into bar values(1,11); +--Testcase 669: +insert into bar values(2,22); +--Testcase 670: +insert into bar values(6,66); +--Testcase 671: +insert into bar2 values(3,33,33); +--Testcase 672: +insert into bar2 values(4,44,44); +--Testcase 673: +insert into bar2 values(7,77,77); +--Testcase 674: +explain (verbose, costs off) +select * from bar where f1 in (select f1 from foo); + QUERY PLAN +-------------------------------------------------------------------- + Hash Join + Output: bar.f1, bar.f2 + Inner Unique: true + Hash Cond: (bar.f1 = foo.f1) + -> Append + -> Foreign Scan on public.bar bar_1 + Output: bar_1.f1, bar_1.f2 + InfluxDB query: SELECT "f1", "f2" FROM "bar" + -> Foreign Scan on public.bar2 bar_2 + Output: bar_2.f1, bar_2.f2 + InfluxDB query: SELECT "f1", "f2" FROM "loct2" + -> Hash + Output: foo.f1 + -> HashAggregate + Output: foo.f1 + Group Key: foo.f1 + -> Append + -> Foreign Scan on public.foo foo_1 + Output: foo_1.f1 + InfluxDB query: SELECT "f1" FROM "foo" + -> Foreign Scan on public.foo2 foo_2 + Output: foo_2.f1 + InfluxDB query: SELECT "f1" FROM "loct1" +(23 rows) + +--Testcase 675: +select * from bar where f1 in (select f1 from foo); + f1 | f2 +----+---- + 1 | 11 + 2 | 22 + 3 | 33 + 4 | 44 +(4 rows) + +--Testcase 676: +explain (verbose, costs off) +select * from bar where f1 in (select f1 from foo); + QUERY PLAN +-------------------------------------------------------------------- + Hash Join + Output: bar.f1, bar.f2 + Inner Unique: true + Hash Cond: (bar.f1 = foo.f1) + -> Append + -> Foreign Scan on public.bar bar_1 + Output: bar_1.f1, bar_1.f2 + InfluxDB query: SELECT "f1", "f2" FROM "bar" + -> Foreign Scan on public.bar2 bar_2 + Output: bar_2.f1, bar_2.f2 + InfluxDB query: SELECT "f1", "f2" FROM "loct2" + -> Hash + Output: foo.f1 + -> HashAggregate + Output: foo.f1 + Group Key: foo.f1 + -> Append + -> Foreign Scan on public.foo foo_1 + Output: foo_1.f1 + InfluxDB query: SELECT "f1" FROM "foo" + -> Foreign Scan on public.foo2 foo_2 + Output: foo_2.f1 + InfluxDB query: SELECT "f1" FROM "loct1" +(23 rows) + +--Testcase 677: +select * from bar where f1 in (select f1 from foo); + f1 | f2 +----+---- + 1 | 11 + 2 | 22 + 3 | 33 + 4 | 44 +(4 rows) + +-- Now check SELECT FOR UPDATE/SHARE with an inherited source table, +-- where the parent is itself a foreign table +--Testcase 678: +create foreign table foo2child (f3 int) inherits (foo2) + server influxdb_svr options (table 'loct4'); +NOTICE: moving and merging column "f3" with inherited definition +DETAIL: User-specified column moved to the position of the inherited column. +--Testcase 679: +explain (verbose, costs off) +select * from bar where f1 in (select f1 from foo2) for share; + QUERY PLAN +-------------------------------------------------------------------------------------- + LockRows + Output: bar.f1, bar.f2, bar.*, foo2.*, bar.tableoid, foo2.tableoid + -> Hash Join + Output: bar.f1, bar.f2, bar.*, foo2.*, bar.tableoid, foo2.tableoid + Inner Unique: true + Hash Cond: (bar.f1 = foo2.f1) + -> Append + -> Foreign Scan on public.bar bar_1 + Output: bar_1.f1, bar_1.f2, bar_1.*, bar_1.tableoid + InfluxDB query: SELECT "f1", "f2" FROM "bar" + -> Foreign Scan on public.bar2 bar_2 + Output: bar_2.f1, bar_2.f2, bar_2.*, bar_2.tableoid + InfluxDB query: SELECT "f1", "f2", "f3" FROM "loct2" + -> Hash + Output: foo2.*, foo2.f1, foo2.tableoid + -> HashAggregate + Output: foo2.*, foo2.f1, foo2.tableoid + Group Key: foo2.f1 + -> Append + -> Foreign Scan on public.foo2 foo2_1 + Output: foo2_1.*, foo2_1.f1, foo2_1.tableoid + InfluxDB query: SELECT "f1", "f2", "f3" FROM "loct1" + -> Foreign Scan on public.foo2child foo2_2 + Output: foo2_2.*, foo2_2.f1, foo2_2.tableoid + InfluxDB query: SELECT "f1", "f2", "f3" FROM "loct4" +(25 rows) + +--Testcase 680: +select * from bar where f1 in (select f1 from foo2) for share; + f1 | f2 +----+---- + 2 | 22 + 4 | 44 +(2 rows) + +--Testcase 681: +drop foreign table foo2child; +-- And with a local child relation of the foreign table parent +--Testcase 682: +create foreign table foo2child (f3 int) inherits (foo2) + server influxdb_svr options (table 'foo2child'); +NOTICE: moving and merging column "f3" with inherited definition +DETAIL: User-specified column moved to the position of the inherited column. +--Testcase 683: +explain (verbose, costs off) +select * from bar where f1 in (select f1 from foo2) for share; + QUERY PLAN +------------------------------------------------------------------------------------------ + LockRows + Output: bar.f1, bar.f2, bar.*, foo2.*, bar.tableoid, foo2.tableoid + -> Hash Join + Output: bar.f1, bar.f2, bar.*, foo2.*, bar.tableoid, foo2.tableoid + Inner Unique: true + Hash Cond: (bar.f1 = foo2.f1) + -> Append + -> Foreign Scan on public.bar bar_1 + Output: bar_1.f1, bar_1.f2, bar_1.*, bar_1.tableoid + InfluxDB query: SELECT "f1", "f2" FROM "bar" + -> Foreign Scan on public.bar2 bar_2 + Output: bar_2.f1, bar_2.f2, bar_2.*, bar_2.tableoid + InfluxDB query: SELECT "f1", "f2", "f3" FROM "loct2" + -> Hash + Output: foo2.*, foo2.f1, foo2.tableoid + -> HashAggregate + Output: foo2.*, foo2.f1, foo2.tableoid + Group Key: foo2.f1 + -> Append + -> Foreign Scan on public.foo2 foo2_1 + Output: foo2_1.*, foo2_1.f1, foo2_1.tableoid + InfluxDB query: SELECT "f1", "f2", "f3" FROM "loct1" + -> Foreign Scan on public.foo2child foo2_2 + Output: foo2_2.*, foo2_2.f1, foo2_2.tableoid + InfluxDB query: SELECT "f1", "f2", "f3" FROM "foo2child" +(25 rows) + +--Testcase 684: +select * from bar where f1 in (select f1 from foo2) for share; + f1 | f2 +----+---- + 2 | 22 + 4 | 44 +(2 rows) + +--Testcase 685: +drop foreign table foo2child; +/* +-- influxdb_fdw does not support UPDATE +-- Check UPDATE with inherited target and an inherited source table +explain (verbose, costs off) +update bar set f2 = f2 + 100 where f1 in (select f1 from foo); +update bar set f2 = f2 + 100 where f1 in (select f1 from foo); + +select tableoid::regclass, * from bar order by 1,2; + +-- Check UPDATE with inherited target and an appendrel subquery +explain (verbose, costs off) +update bar set f2 = f2 + 100 +from + ( select f1 from foo union all select f1+3 from foo ) ss +where bar.f1 = ss.f1; +update bar set f2 = f2 + 100 +from + ( select f1 from foo union all select f1+3 from foo ) ss +where bar.f1 = ss.f1; + +select tableoid::regclass, * from bar order by 1,2; + +-- Test forcing the remote server to produce sorted data for a merge join, +-- but the foreign table is an inheritance child. +truncate table loct1; +truncate table only foo; +\set num_rows_foo 2000 +insert into loct1 select generate_series(0, :num_rows_foo, 2), generate_series(0, :num_rows_foo, 2), generate_series(0, :num_rows_foo, 2); +insert into foo select generate_series(1, :num_rows_foo, 2), generate_series(1, :num_rows_foo, 2); +SET enable_hashjoin to false; +SET enable_nestloop to false; +alter foreign table foo2 options (use_remote_estimate 'true'); +create index i_loct1_f1 on loct1(f1); +create index i_foo_f1 on foo(f1); +analyze foo; +analyze loct1; +-- inner join; expressions in the clauses appear in the equivalence class list +explain (verbose, costs off) + select foo.f1, loct1.f1 from foo join loct1 on (foo.f1 = loct1.f1) order by foo.f2 offset 10 limit 10; +select foo.f1, loct1.f1 from foo join loct1 on (foo.f1 = loct1.f1) order by foo.f2 offset 10 limit 10; +-- outer join; expressions in the clauses do not appear in equivalence class +-- list but no output change as compared to the previous query +explain (verbose, costs off) + select foo.f1, loct1.f1 from foo left join loct1 on (foo.f1 = loct1.f1) order by foo.f2 offset 10 limit 10; +select foo.f1, loct1.f1 from foo left join loct1 on (foo.f1 = loct1.f1) order by foo.f2 offset 10 limit 10; +RESET enable_hashjoin; +RESET enable_nestloop; + +-- Test that WHERE CURRENT OF is not supported +begin; +declare c cursor for select * from bar where f1 = 7; +fetch from c; +update bar set f2 = null where current of c; +rollback; + +explain (verbose, costs off) +delete from foo where f1 < 5 returning *; +delete from foo where f1 < 5 returning *; +explain (verbose, costs off) +update bar set f2 = f2 + 100 returning *; +update bar set f2 = f2 + 100 returning *; + +-- Test that UPDATE/DELETE with inherited target works with row-level triggers +CREATE TRIGGER trig_row_before +BEFORE UPDATE OR DELETE ON bar2 +FOR EACH ROW EXECUTE PROCEDURE trigger_data(23,'skidoo'); + +CREATE TRIGGER trig_row_after +AFTER UPDATE OR DELETE ON bar2 +FOR EACH ROW EXECUTE PROCEDURE trigger_data(23,'skidoo'); + +explain (verbose, costs off) +update bar set f2 = f2 + 100; +update bar set f2 = f2 + 100; + +explain (verbose, costs off) +delete from bar where f2 < 400; +delete from bar where f2 < 400; + +-- cleanup +drop table foo cascade; +drop table bar cascade; +drop table loct1; +drop table loct2; + +-- Test pushing down UPDATE/DELETE joins to the remote server +create table parent (a int, b text); +create table loct1 (a int, b text); +create table loct2 (a int, b text); +create foreign table remt1 (a int, b text) + server influxdb_svr options (table 'loct1'); +create foreign table remt2 (a int, b text) + server influxdb_svr options (table 'loct2'); +alter foreign table remt1 inherit parent; + +insert into remt1 values (1, 'foo'); +insert into remt1 values (2, 'bar'); +insert into remt2 values (1, 'foo'); +insert into remt2 values (2, 'bar'); + +analyze remt1; +analyze remt2; + +explain (verbose, costs off) +update parent set b = parent.b || remt2.b from remt2 where parent.a = remt2.a returning *; +update parent set b = parent.b || remt2.b from remt2 where parent.a = remt2.a returning *; +explain (verbose, costs off) +delete from parent using remt2 where parent.a = remt2.a returning parent; +delete from parent using remt2 where parent.a = remt2.a returning parent; + +-- cleanup +drop foreign table remt1; +drop foreign table remt2; +drop table loct1; +drop table loct2; +drop table parent; +*/ +/* +-- Skip test because influxdb does not support partitions table, COPY +-- =================================================================== +-- test tuple routing for foreign-table partitions +-- =================================================================== + +-- Test insert tuple routing +create table itrtest (a int, b text) partition by list (a); +create table loct1 (a int check (a in (1)), b text); +create foreign table remp1 (a int check (a in (1)), b text) server loopback options (table_name 'loct1'); +create table loct2 (a int check (a in (2)), b text); +create foreign table remp2 (b text, a int check (a in (2))) server loopback options (table_name 'loct2'); +alter table itrtest attach partition remp1 for values in (1); +alter table itrtest attach partition remp2 for values in (2); + +insert into itrtest values (1, 'foo'); +insert into itrtest values (1, 'bar') returning *; +insert into itrtest values (2, 'baz'); +insert into itrtest values (2, 'qux') returning *; +insert into itrtest values (1, 'test1'), (2, 'test2') returning *; + +select tableoid::regclass, * FROM itrtest; +select tableoid::regclass, * FROM remp1; +select tableoid::regclass, * FROM remp2; + +delete from itrtest; + +-- MERGE ought to fail cleanly +merge into itrtest using (select 1, 'foo') as source on (true) + when matched then do nothing; + +create unique index loct1_idx on loct1 (a); + +-- DO NOTHING without an inference specification is supported +insert into itrtest values (1, 'foo') on conflict do nothing returning *; +insert into itrtest values (1, 'foo') on conflict do nothing returning *; + +-- But other cases are not supported +insert into itrtest values (1, 'bar') on conflict (a) do nothing; +insert into itrtest values (1, 'bar') on conflict (a) do update set b = excluded.b; + +select tableoid::regclass, * FROM itrtest; + +delete from itrtest; + +drop index loct1_idx; + +-- Test that remote triggers work with insert tuple routing +create function br_insert_trigfunc() returns trigger as $$ +begin + new.b := new.b || ' triggered !'; + return new; +end +$$ language plpgsql; +create trigger loct1_br_insert_trigger before insert on loct1 + for each row execute procedure br_insert_trigfunc(); +create trigger loct2_br_insert_trigger before insert on loct2 + for each row execute procedure br_insert_trigfunc(); + +-- The new values are concatenated with ' triggered !' +insert into itrtest values (1, 'foo') returning *; +insert into itrtest values (2, 'qux') returning *; +insert into itrtest values (1, 'test1'), (2, 'test2') returning *; +with result as (insert into itrtest values (1, 'test1'), (2, 'test2') returning *) select * from result; + +drop trigger loct1_br_insert_trigger on loct1; +drop trigger loct2_br_insert_trigger on loct2; + +drop table itrtest; +drop table loct1; +drop table loct2; + +-- Test update tuple routing +create table utrtest (a int, b text) partition by list (a); +create table loct (a int check (a in (1)), b text); +create foreign table remp (a int check (a in (1)), b text) server loopback options (table_name 'loct'); +create table locp (a int check (a in (2)), b text); +alter table utrtest attach partition remp for values in (1); +alter table utrtest attach partition locp for values in (2); + +insert into utrtest values (1, 'foo'); +insert into utrtest values (2, 'qux'); + +select tableoid::regclass, * FROM utrtest; +select tableoid::regclass, * FROM remp; +select tableoid::regclass, * FROM locp; + +-- It's not allowed to move a row from a partition that is foreign to another +update utrtest set a = 2 where b = 'foo' returning *; + +-- But the reverse is allowed +update utrtest set a = 1 where b = 'qux' returning *; + +select tableoid::regclass, * FROM utrtest; +select tableoid::regclass, * FROM remp; +select tableoid::regclass, * FROM locp; + +-- The executor should not let unexercised FDWs shut down +update utrtest set a = 1 where b = 'foo'; + +-- Test that remote triggers work with update tuple routing +create trigger loct_br_insert_trigger before insert on loct + for each row execute procedure br_insert_trigfunc(); + +delete from utrtest; +insert into utrtest values (2, 'qux'); + +-- Check case where the foreign partition is a subplan target rel +explain (verbose, costs off) +update utrtest set a = 1 where a = 1 or a = 2 returning *; +-- The new values are concatenated with ' triggered !' +update utrtest set a = 1 where a = 1 or a = 2 returning *; + +delete from utrtest; +insert into utrtest values (2, 'qux'); + +-- Check case where the foreign partition isn't a subplan target rel +explain (verbose, costs off) +update utrtest set a = 1 where a = 2 returning *; +-- The new values are concatenated with ' triggered !' +update utrtest set a = 1 where a = 2 returning *; + +drop trigger loct_br_insert_trigger on loct; + +-- We can move rows to a foreign partition that has been updated already, +-- but can't move rows to a foreign partition that hasn't been updated yet + +delete from utrtest; +insert into utrtest values (1, 'foo'); +insert into utrtest values (2, 'qux'); + +-- Test the former case: +-- with a direct modification plan +explain (verbose, costs off) +update utrtest set a = 1 returning *; +update utrtest set a = 1 returning *; + +delete from utrtest; +insert into utrtest values (1, 'foo'); +insert into utrtest values (2, 'qux'); + +-- with a non-direct modification plan +explain (verbose, costs off) +update utrtest set a = 1 from (values (1), (2)) s(x) where a = s.x returning *; +update utrtest set a = 1 from (values (1), (2)) s(x) where a = s.x returning *; + +-- Change the definition of utrtest so that the foreign partition get updated +-- after the local partition +delete from utrtest; +alter table utrtest detach partition remp; +drop foreign table remp; +alter table loct drop constraint loct_a_check; +alter table loct add check (a in (3)); +create foreign table remp (a int check (a in (3)), b text) server loopback options (table_name 'loct'); +alter table utrtest attach partition remp for values in (3); +insert into utrtest values (2, 'qux'); +insert into utrtest values (3, 'xyzzy'); + +-- Test the latter case: +-- with a direct modification plan +explain (verbose, costs off) +update utrtest set a = 3 returning *; +update utrtest set a = 3 returning *; -- ERROR + +-- with a non-direct modification plan +explain (verbose, costs off) +update utrtest set a = 3 from (values (2), (3)) s(x) where a = s.x returning *; +update utrtest set a = 3 from (values (2), (3)) s(x) where a = s.x returning *; -- ERROR + +drop table utrtest; +drop table loct; + +-- Test copy tuple routing +create table ctrtest (a int, b text) partition by list (a); +create table loct1 (a int check (a in (1)), b text); +create foreign table remp1 (a int check (a in (1)), b text) server loopback options (table_name 'loct1'); +create table loct2 (a int check (a in (2)), b text); +create foreign table remp2 (b text, a int check (a in (2))) server loopback options (table_name 'loct2'); +alter table ctrtest attach partition remp1 for values in (1); +alter table ctrtest attach partition remp2 for values in (2); + +copy ctrtest from stdin; +1 foo +2 qux +\. + +select tableoid::regclass, * FROM ctrtest; +select tableoid::regclass, * FROM remp1; +select tableoid::regclass, * FROM remp2; + +-- Copying into foreign partitions directly should work as well +copy remp1 from stdin; +1 bar +\. + +select tableoid::regclass, * FROM remp1; + +delete from ctrtest; + +-- Test copy tuple routing with the batch_size option enabled +alter server loopback options (add batch_size '2'); + +copy ctrtest from stdin; +1 foo +1 bar +2 baz +2 qux +1 test1 +2 test2 +\. + +select tableoid::regclass, * FROM ctrtest; +select tableoid::regclass, * FROM remp1; +select tableoid::regclass, * FROM remp2; + +delete from ctrtest; + +alter server loopback options (drop batch_size); + +drop table ctrtest; +drop table loct1; +drop table loct2; + +-- =================================================================== +-- test COPY FROM +-- =================================================================== + +create table loc2 (f1 int, f2 text); +alter table loc2 set (autovacuum_enabled = 'false'); +create foreign table rem2 (f1 int, f2 text) server loopback options(table_name 'loc2'); + +-- Test basic functionality +copy rem2 from stdin; +1 foo +2 bar +\. +select * from rem2; + +delete from rem2; + +-- Test check constraints +alter table loc2 add constraint loc2_f1positive check (f1 >= 0); +alter foreign table rem2 add constraint rem2_f1positive check (f1 >= 0); + +-- check constraint is enforced on the remote side, not locally +copy rem2 from stdin; +1 foo +2 bar +\. +copy rem2 from stdin; -- ERROR +-1 xyzzy +\. +select * from rem2; + +alter foreign table rem2 drop constraint rem2_f1positive; +alter table loc2 drop constraint loc2_f1positive; + +delete from rem2; + +-- Test local triggers +create trigger trig_stmt_before before insert on rem2 + for each statement execute procedure trigger_func(); +create trigger trig_stmt_after after insert on rem2 + for each statement execute procedure trigger_func(); +create trigger trig_row_before before insert on rem2 + for each row execute procedure trigger_data(23,'skidoo'); +create trigger trig_row_after after insert on rem2 + for each row execute procedure trigger_data(23,'skidoo'); + +copy rem2 from stdin; +1 foo +2 bar +\. +select * from rem2; + +drop trigger trig_row_before on rem2; +drop trigger trig_row_after on rem2; +drop trigger trig_stmt_before on rem2; +drop trigger trig_stmt_after on rem2; + +delete from rem2; + +create trigger trig_row_before_insert before insert on rem2 + for each row execute procedure trig_row_before_insupdate(); + +-- The new values are concatenated with ' triggered !' +copy rem2 from stdin; +1 foo +2 bar +\. +select * from rem2; + +drop trigger trig_row_before_insert on rem2; + +delete from rem2; + +create trigger trig_null before insert on rem2 + for each row execute procedure trig_null(); + +-- Nothing happens +copy rem2 from stdin; +1 foo +2 bar +\. +select * from rem2; + +drop trigger trig_null on rem2; + +delete from rem2; + +-- Test remote triggers +create trigger trig_row_before_insert before insert on loc2 + for each row execute procedure trig_row_before_insupdate(); + +-- The new values are concatenated with ' triggered !' +copy rem2 from stdin; +1 foo +2 bar +\. +select * from rem2; + +drop trigger trig_row_before_insert on loc2; + +delete from rem2; + +create trigger trig_null before insert on loc2 + for each row execute procedure trig_null(); + +-- Nothing happens +copy rem2 from stdin; +1 foo +2 bar +\. +select * from rem2; + +drop trigger trig_null on loc2; + +delete from rem2; + +-- Test a combination of local and remote triggers +create trigger rem2_trig_row_before before insert on rem2 + for each row execute procedure trigger_data(23,'skidoo'); +create trigger rem2_trig_row_after after insert on rem2 + for each row execute procedure trigger_data(23,'skidoo'); +create trigger loc2_trig_row_before_insert before insert on loc2 + for each row execute procedure trig_row_before_insupdate(); + +copy rem2 from stdin; +1 foo +2 bar +\. +select * from rem2; + +drop trigger rem2_trig_row_before on rem2; +drop trigger rem2_trig_row_after on rem2; +drop trigger loc2_trig_row_before_insert on loc2; + +delete from rem2; + +-- test COPY FROM with foreign table created in the same transaction +create table loc3 (f1 int, f2 text); +begin; +create foreign table rem3 (f1 int, f2 text) + server loopback options(table_name 'loc3'); +copy rem3 from stdin; +1 foo +2 bar +\. +commit; +select * from rem3; +drop foreign table rem3; +drop table loc3; + +-- Test COPY FROM with the batch_size option enabled +alter server loopback options (add batch_size '2'); + +-- Test basic functionality +copy rem2 from stdin; +1 foo +2 bar +3 baz +\. +select * from rem2; + +delete from rem2; + +-- Test check constraints +alter table loc2 add constraint loc2_f1positive check (f1 >= 0); +alter foreign table rem2 add constraint rem2_f1positive check (f1 >= 0); + +-- check constraint is enforced on the remote side, not locally +copy rem2 from stdin; +1 foo +2 bar +3 baz +\. +copy rem2 from stdin; -- ERROR +-1 xyzzy +\. +select * from rem2; + +alter foreign table rem2 drop constraint rem2_f1positive; +alter table loc2 drop constraint loc2_f1positive; + +delete from rem2; + +-- Test remote triggers +create trigger trig_row_before_insert before insert on loc2 + for each row execute procedure trig_row_before_insupdate(); + +-- The new values are concatenated with ' triggered !' +copy rem2 from stdin; +1 foo +2 bar +3 baz +\. +select * from rem2; + +drop trigger trig_row_before_insert on loc2; + +delete from rem2; + +create trigger trig_null before insert on loc2 + for each row execute procedure trig_null(); + +-- Nothing happens +copy rem2 from stdin; +1 foo +2 bar +3 baz +\. +select * from rem2; + +drop trigger trig_null on loc2; + +delete from rem2; + +-- Check with zero-column foreign table; batch insert will be disabled +alter table loc2 drop column f1; +alter table loc2 drop column f2; +alter table rem2 drop column f1; +alter table rem2 drop column f2; +copy rem2 from stdin; + + + +\. +select * from rem2; + +delete from rem2; + +alter server loopback options (drop batch_size); +*/ +/* +-- Skip test because influxdb does not support TRUNCATE +-- =================================================================== +-- test for TRUNCATE +-- =================================================================== +CREATE TABLE tru_rtable0 (id int primary key); +CREATE FOREIGN TABLE tru_ftable (id int) + SERVER loopback OPTIONS (table_name 'tru_rtable0'); +INSERT INTO tru_rtable0 (SELECT x FROM generate_series(1,10) x); + +CREATE TABLE tru_ptable (id int) PARTITION BY HASH(id); +CREATE TABLE tru_ptable__p0 PARTITION OF tru_ptable + FOR VALUES WITH (MODULUS 2, REMAINDER 0); +CREATE TABLE tru_rtable1 (id int primary key); +CREATE FOREIGN TABLE tru_ftable__p1 PARTITION OF tru_ptable + FOR VALUES WITH (MODULUS 2, REMAINDER 1) + SERVER loopback OPTIONS (table_name 'tru_rtable1'); +INSERT INTO tru_ptable (SELECT x FROM generate_series(11,20) x); + +CREATE TABLE tru_pk_table(id int primary key); +CREATE TABLE tru_fk_table(fkey int references tru_pk_table(id)); +INSERT INTO tru_pk_table (SELECT x FROM generate_series(1,10) x); +INSERT INTO tru_fk_table (SELECT x % 10 + 1 FROM generate_series(5,25) x); +CREATE FOREIGN TABLE tru_pk_ftable (id int) + SERVER loopback OPTIONS (table_name 'tru_pk_table'); + +CREATE TABLE tru_rtable_parent (id int); +CREATE TABLE tru_rtable_child (id int); +CREATE FOREIGN TABLE tru_ftable_parent (id int) + SERVER loopback OPTIONS (table_name 'tru_rtable_parent'); +CREATE FOREIGN TABLE tru_ftable_child () INHERITS (tru_ftable_parent) + SERVER loopback OPTIONS (table_name 'tru_rtable_child'); +INSERT INTO tru_rtable_parent (SELECT x FROM generate_series(1,8) x); +INSERT INTO tru_rtable_child (SELECT x FROM generate_series(10, 18) x); + +-- normal truncate +SELECT sum(id) FROM tru_ftable; -- 55 +TRUNCATE tru_ftable; +SELECT count(*) FROM tru_rtable0; -- 0 +SELECT count(*) FROM tru_ftable; -- 0 + +-- 'truncatable' option +ALTER SERVER loopback OPTIONS (ADD truncatable 'false'); +TRUNCATE tru_ftable; -- error +ALTER FOREIGN TABLE tru_ftable OPTIONS (ADD truncatable 'true'); +TRUNCATE tru_ftable; -- accepted +ALTER FOREIGN TABLE tru_ftable OPTIONS (SET truncatable 'false'); +TRUNCATE tru_ftable; -- error +ALTER SERVER loopback OPTIONS (DROP truncatable); +ALTER FOREIGN TABLE tru_ftable OPTIONS (SET truncatable 'false'); +TRUNCATE tru_ftable; -- error +ALTER FOREIGN TABLE tru_ftable OPTIONS (SET truncatable 'true'); +TRUNCATE tru_ftable; -- accepted + +-- partitioned table with both local and foreign tables as partitions +SELECT sum(id) FROM tru_ptable; -- 155 +TRUNCATE tru_ptable; +SELECT count(*) FROM tru_ptable; -- 0 +SELECT count(*) FROM tru_ptable__p0; -- 0 +SELECT count(*) FROM tru_ftable__p1; -- 0 +SELECT count(*) FROM tru_rtable1; -- 0 + +-- 'CASCADE' option +SELECT sum(id) FROM tru_pk_ftable; -- 55 +TRUNCATE tru_pk_ftable; -- failed by FK reference +TRUNCATE tru_pk_ftable CASCADE; +SELECT count(*) FROM tru_pk_ftable; -- 0 +SELECT count(*) FROM tru_fk_table; -- also truncated,0 + +-- truncate two tables at a command +INSERT INTO tru_ftable (SELECT x FROM generate_series(1,8) x); +INSERT INTO tru_pk_ftable (SELECT x FROM generate_series(3,10) x); +SELECT count(*) from tru_ftable; -- 8 +SELECT count(*) from tru_pk_ftable; -- 8 +TRUNCATE tru_ftable, tru_pk_ftable CASCADE; +SELECT count(*) from tru_ftable; -- 0 +SELECT count(*) from tru_pk_ftable; -- 0 + +-- truncate with ONLY clause +-- Since ONLY is specified, the table tru_ftable_child that inherits +-- tru_ftable_parent locally is not truncated. +TRUNCATE ONLY tru_ftable_parent; +SELECT sum(id) FROM tru_ftable_parent; -- 126 +TRUNCATE tru_ftable_parent; +SELECT count(*) FROM tru_ftable_parent; -- 0 + +-- in case when remote table has inherited children +CREATE TABLE tru_rtable0_child () INHERITS (tru_rtable0); +INSERT INTO tru_rtable0 (SELECT x FROM generate_series(5,9) x); +INSERT INTO tru_rtable0_child (SELECT x FROM generate_series(10,14) x); +SELECT sum(id) FROM tru_ftable; -- 95 + +-- Both parent and child tables in the foreign server are truncated +-- even though ONLY is specified because ONLY has no effect +-- when truncating a foreign table. +TRUNCATE ONLY tru_ftable; +SELECT count(*) FROM tru_ftable; -- 0 + +INSERT INTO tru_rtable0 (SELECT x FROM generate_series(21,25) x); +INSERT INTO tru_rtable0_child (SELECT x FROM generate_series(26,30) x); +SELECT sum(id) FROM tru_ftable; -- 255 +TRUNCATE tru_ftable; -- truncate both of parent and child +SELECT count(*) FROM tru_ftable; -- 0 + +-- cleanup +DROP FOREIGN TABLE tru_ftable_parent, tru_ftable_child, tru_pk_ftable,tru_ftable__p1,tru_ftable; +DROP TABLE tru_rtable0, tru_rtable1, tru_ptable, tru_ptable__p0, tru_pk_table, tru_fk_table, +tru_rtable_parent,tru_rtable_child, tru_rtable0_child; +*/ +-- =================================================================== +-- test IMPORT FOREIGN SCHEMA +-- =================================================================== +--Testcase 686: +CREATE SCHEMA import_influx1; +IMPORT FOREIGN SCHEMA public FROM SERVER influxdb_svr INTO import_influx1; +--Testcase 687: +\det+ import_influx1.* + List of foreign tables + Schema | Table | Server | FDW options | Description +----------------+-------+--------------+---------------------------+------------- + import_influx1 | T1 | influxdb_svr | ("table" 'T1', tags 'c3') | + import_influx1 | T2 | influxdb_svr | ("table" 'T2', tags 'c2') | + import_influx1 | T3 | influxdb_svr | ("table" 'T3', tags 'c3') | + import_influx1 | T4 | influxdb_svr | ("table" 'T4', tags 'c3') | + import_influx1 | bar | influxdb_svr | ("table" 'bar') | + import_influx1 | foo | influxdb_svr | ("table" 'foo') | + import_influx1 | loc1 | influxdb_svr | ("table" 'loc1') | + import_influx1 | loct1 | influxdb_svr | ("table" 'loct1') | + import_influx1 | loct2 | influxdb_svr | ("table" 'loct2') | +(9 rows) + +--Testcase 688: +\d import_influx1.* + Foreign table "import_influx1.T1" + Column | Type | Collation | Nullable | Default | FDW options +--------+--------------------------+-----------+----------+---------+------------- + time | timestamp with time zone | | | | + c3 | text | | | | + C 1 | bigint | | | | + c2 | bigint | | | | + c6 | text | | | | + c7 | text | | | | + c8 | text | | | | +Server: influxdb_svr +FDW options: ("table" 'T1', tags 'c3') + + Foreign table "import_influx1.T2" + Column | Type | Collation | Nullable | Default | FDW options +--------+--------------------------+-----------+----------+---------+------------- + time | timestamp with time zone | | | | + c2 | text | | | | + c1 | bigint | | | | +Server: influxdb_svr +FDW options: ("table" 'T2', tags 'c2') + + Foreign table "import_influx1.T3" + Column | Type | Collation | Nullable | Default | FDW options +--------+--------------------------+-----------+----------+---------+------------- + time | timestamp with time zone | | | | + c3 | text | | | | + c1 | bigint | | | | + c2 | bigint | | | | +Server: influxdb_svr +FDW options: ("table" 'T3', tags 'c3') + + Foreign table "import_influx1.T4" + Column | Type | Collation | Nullable | Default | FDW options +--------+--------------------------+-----------+----------+---------+------------- + time | timestamp with time zone | | | | + c3 | text | | | | + c1 | bigint | | | | + c2 | bigint | | | | +Server: influxdb_svr +FDW options: ("table" 'T4', tags 'c3') + + Foreign table "import_influx1.bar" + Column | Type | Collation | Nullable | Default | FDW options +--------+--------------------------+-----------+----------+---------+------------- + time | timestamp with time zone | | | | + f1 | bigint | | | | + f2 | bigint | | | | +Server: influxdb_svr +FDW options: ("table" 'bar') + + Foreign table "import_influx1.foo" + Column | Type | Collation | Nullable | Default | FDW options +--------+--------------------------+-----------+----------+---------+------------- + time | timestamp with time zone | | | | + f1 | bigint | | | | + f2 | bigint | | | | +Server: influxdb_svr +FDW options: ("table" 'foo') + + Foreign table "import_influx1.loc1" + Column | Type | Collation | Nullable | Default | FDW options +--------+--------------------------+-----------+----------+---------+------------- + time | timestamp with time zone | | | | + f1 | bigint | | | | + f2 | text | | | | +Server: influxdb_svr +FDW options: ("table" 'loc1') + + Foreign table "import_influx1.loct1" + Column | Type | Collation | Nullable | Default | FDW options +--------+--------------------------+-----------+----------+---------+------------- + time | timestamp with time zone | | | | + f1 | bigint | | | | + f2 | bigint | | | | + f3 | bigint | | | | +Server: influxdb_svr +FDW options: ("table" 'loct1') + + Foreign table "import_influx1.loct2" + Column | Type | Collation | Nullable | Default | FDW options +--------+--------------------------+-----------+----------+---------+------------- + time | timestamp with time zone | | | | + f1 | bigint | | | | + f2 | bigint | | | | + f3 | bigint | | | | +Server: influxdb_svr +FDW options: ("table" 'loct2') + +-- Options +--Testcase 689: +CREATE SCHEMA import_influx2; +IMPORT FOREIGN SCHEMA public FROM SERVER influxdb_svr INTO import_influx2 + OPTIONS (import_default 'true'); +ERROR: invalid option "import_default" +--Testcase 690: +\det+ import_influx2.* + List of foreign tables + Schema | Table | Server | FDW options | Description +--------+-------+--------+-------------+------------- +(0 rows) + +--Testcase 691: +\d import_influx2.* +--Testcase 692: +CREATE SCHEMA import_influx3; +IMPORT FOREIGN SCHEMA public FROM SERVER influxdb_svr INTO import_influx3 + OPTIONS (import_collate 'false', import_not_null 'false'); +ERROR: invalid option "import_collate" +--Testcase 693: +\det+ import_influx3.* + List of foreign tables + Schema | Table | Server | FDW options | Description +--------+-------+--------+-------------+------------- +(0 rows) + +--Testcase 694: +\d import_influx3.* +-- Check LIMIT TO and EXCEPT +--Testcase 695: +CREATE SCHEMA import_influx4; +IMPORT FOREIGN SCHEMA public LIMIT TO ("T1", loct, nonesuch) + FROM SERVER influxdb_svr INTO import_influx4; +--Testcase 696: +\det+ import_influx4.* + List of foreign tables + Schema | Table | Server | FDW options | Description +----------------+-------+--------------+---------------------------+------------- + import_influx4 | T1 | influxdb_svr | ("table" 'T1', tags 'c3') | +(1 row) + +IMPORT FOREIGN SCHEMA public EXCEPT ("T1", loct, nonesuch) + FROM SERVER influxdb_svr INTO import_influx4; +--Testcase 697: +\det+ import_influx4.* + List of foreign tables + Schema | Table | Server | FDW options | Description +----------------+-------+--------------+---------------------------+------------- + import_influx4 | T1 | influxdb_svr | ("table" 'T1', tags 'c3') | + import_influx4 | T2 | influxdb_svr | ("table" 'T2', tags 'c2') | + import_influx4 | T3 | influxdb_svr | ("table" 'T3', tags 'c3') | + import_influx4 | T4 | influxdb_svr | ("table" 'T4', tags 'c3') | + import_influx4 | bar | influxdb_svr | ("table" 'bar') | + import_influx4 | foo | influxdb_svr | ("table" 'foo') | + import_influx4 | loc1 | influxdb_svr | ("table" 'loc1') | + import_influx4 | loct1 | influxdb_svr | ("table" 'loct1') | + import_influx4 | loct2 | influxdb_svr | ("table" 'loct2') | +(9 rows) + +-- Assorted error cases +IMPORT FOREIGN SCHEMA public FROM SERVER influxdb_svr INTO import_influx4; +ERROR: relation "T1" already exists +CONTEXT: importing foreign table "T1" +IMPORT FOREIGN SCHEMA nonesuch FROM SERVER influxdb_svr INTO import_influx4; +ERROR: relation "T1" already exists +CONTEXT: importing foreign table "T1" +IMPORT FOREIGN SCHEMA nonesuch FROM SERVER influxdb_svr INTO notthere; +ERROR: schema "notthere" does not exist +IMPORT FOREIGN SCHEMA nonesuch FROM SERVER nowhere INTO notthere; +ERROR: server "nowhere" does not exist +/* +-- Skip these test, influxdb_fdw does not support fetch_size option, partition table +-- Check case of a type present only on the remote server. +-- We can fake this by dropping the type locally in our transaction. +CREATE TYPE "Colors" AS ENUM ('red', 'green', 'blue'); +CREATE TABLE import_source.t5 (c1 int, c2 text collate "C", "Col" "Colors"); + +CREATE SCHEMA import_dest5; +BEGIN; +DROP TYPE "Colors" CASCADE; +IMPORT FOREIGN SCHEMA import_source LIMIT TO (t5) + FROM SERVER loopback INTO import_dest5; -- ERROR + +ROLLBACK; + +BEGIN; + + +CREATE SERVER fetch101 FOREIGN DATA WRAPPER postgres_fdw OPTIONS( fetch_size '101' ); + +SELECT count(*) +FROM pg_foreign_server +WHERE srvname = 'fetch101' +AND srvoptions @> array['fetch_size=101']; + +ALTER SERVER fetch101 OPTIONS( SET fetch_size '202' ); + +SELECT count(*) +FROM pg_foreign_server +WHERE srvname = 'fetch101' +AND srvoptions @> array['fetch_size=101']; + +SELECT count(*) +FROM pg_foreign_server +WHERE srvname = 'fetch101' +AND srvoptions @> array['fetch_size=202']; + +CREATE FOREIGN TABLE table30000 ( x int ) SERVER fetch101 OPTIONS ( fetch_size '30000' ); + +SELECT COUNT(*) +FROM pg_foreign_table +WHERE ftrelid = 'table30000'::regclass +AND ftoptions @> array['fetch_size=30000']; + +ALTER FOREIGN TABLE table30000 OPTIONS ( SET fetch_size '60000'); + +SELECT COUNT(*) +FROM pg_foreign_table +WHERE ftrelid = 'table30000'::regclass +AND ftoptions @> array['fetch_size=30000']; + +SELECT COUNT(*) +FROM pg_foreign_table +WHERE ftrelid = 'table30000'::regclass +AND ftoptions @> array['fetch_size=60000']; + +ROLLBACK; + +-- =================================================================== +-- test partitionwise joins +-- =================================================================== +SET enable_partitionwise_join=on; + +CREATE TABLE fprt1 (a int, b int, c varchar) PARTITION BY RANGE(a); +CREATE TABLE fprt1_p1 (LIKE fprt1); +CREATE TABLE fprt1_p2 (LIKE fprt1); +ALTER TABLE fprt1_p1 SET (autovacuum_enabled = 'false'); +ALTER TABLE fprt1_p2 SET (autovacuum_enabled = 'false'); +INSERT INTO fprt1_p1 SELECT i, i, to_char(i/50, 'FM0000') FROM generate_series(0, 249, 2) i; +INSERT INTO fprt1_p2 SELECT i, i, to_char(i/50, 'FM0000') FROM generate_series(250, 499, 2) i; +CREATE FOREIGN TABLE ftprt1_p1 PARTITION OF fprt1 FOR VALUES FROM (0) TO (250) + SERVER loopback OPTIONS (table_name 'fprt1_p1', use_remote_estimate 'true'); +CREATE FOREIGN TABLE ftprt1_p2 PARTITION OF fprt1 FOR VALUES FROM (250) TO (500) + SERVER loopback OPTIONS (TABLE_NAME 'fprt1_p2'); +ANALYZE fprt1; +ANALYZE fprt1_p1; +ANALYZE fprt1_p2; + +CREATE TABLE fprt2 (a int, b int, c varchar) PARTITION BY RANGE(b); +CREATE TABLE fprt2_p1 (LIKE fprt2); +CREATE TABLE fprt2_p2 (LIKE fprt2); +ALTER TABLE fprt2_p1 SET (autovacuum_enabled = 'false'); +ALTER TABLE fprt2_p2 SET (autovacuum_enabled = 'false'); +INSERT INTO fprt2_p1 SELECT i, i, to_char(i/50, 'FM0000') FROM generate_series(0, 249, 3) i; +INSERT INTO fprt2_p2 SELECT i, i, to_char(i/50, 'FM0000') FROM generate_series(250, 499, 3) i; +CREATE FOREIGN TABLE ftprt2_p1 (b int, c varchar, a int) + SERVER loopback OPTIONS (table_name 'fprt2_p1', use_remote_estimate 'true'); +ALTER TABLE fprt2 ATTACH PARTITION ftprt2_p1 FOR VALUES FROM (0) TO (250); +CREATE FOREIGN TABLE ftprt2_p2 PARTITION OF fprt2 FOR VALUES FROM (250) TO (500) + SERVER loopback OPTIONS (table_name 'fprt2_p2', use_remote_estimate 'true'); +ANALYZE fprt2; +ANALYZE fprt2_p1; +ANALYZE fprt2_p2; + +-- inner join three tables +EXPLAIN (COSTS OFF) +SELECT t1.a,t2.b,t3.c FROM fprt1 t1 INNER JOIN fprt2 t2 ON (t1.a = t2.b) INNER JOIN fprt1 t3 ON (t2.b = t3.a) WHERE t1.a % 25 =0 ORDER BY 1,2,3; +SELECT t1.a,t2.b,t3.c FROM fprt1 t1 INNER JOIN fprt2 t2 ON (t1.a = t2.b) INNER JOIN fprt1 t3 ON (t2.b = t3.a) WHERE t1.a % 25 =0 ORDER BY 1,2,3; + +-- left outer join + nullable clause +EXPLAIN (VERBOSE, COSTS OFF) +SELECT t1.a,t2.b,t2.c FROM fprt1 t1 LEFT JOIN (SELECT * FROM fprt2 WHERE a < 10) t2 ON (t1.a = t2.b and t1.b = t2.a) WHERE t1.a < 10 ORDER BY 1,2,3; +SELECT t1.a,t2.b,t2.c FROM fprt1 t1 LEFT JOIN (SELECT * FROM fprt2 WHERE a < 10) t2 ON (t1.a = t2.b and t1.b = t2.a) WHERE t1.a < 10 ORDER BY 1,2,3; + +-- with whole-row reference; partitionwise join does not apply +EXPLAIN (COSTS OFF) +SELECT t1.wr, t2.wr FROM (SELECT t1 wr, a FROM fprt1 t1 WHERE t1.a % 25 = 0) t1 FULL JOIN (SELECT t2 wr, b FROM fprt2 t2 WHERE t2.b % 25 = 0) t2 ON (t1.a = t2.b) ORDER BY 1,2; +SELECT t1.wr, t2.wr FROM (SELECT t1 wr, a FROM fprt1 t1 WHERE t1.a % 25 = 0) t1 FULL JOIN (SELECT t2 wr, b FROM fprt2 t2 WHERE t2.b % 25 = 0) t2 ON (t1.a = t2.b) ORDER BY 1,2; + +-- join with lateral reference +EXPLAIN (COSTS OFF) +SELECT t1.a,t1.b FROM fprt1 t1, LATERAL (SELECT t2.a, t2.b FROM fprt2 t2 WHERE t1.a = t2.b AND t1.b = t2.a) q WHERE t1.a%25 = 0 ORDER BY 1,2; +SELECT t1.a,t1.b FROM fprt1 t1, LATERAL (SELECT t2.a, t2.b FROM fprt2 t2 WHERE t1.a = t2.b AND t1.b = t2.a) q WHERE t1.a%25 = 0 ORDER BY 1,2; + +-- with PHVs, partitionwise join selected but no join pushdown +EXPLAIN (COSTS OFF) +SELECT t1.a, t1.phv, t2.b, t2.phv FROM (SELECT 't1_phv' phv, * FROM fprt1 WHERE a % 25 = 0) t1 FULL JOIN (SELECT 't2_phv' phv, * FROM fprt2 WHERE b % 25 = 0) t2 ON (t1.a = t2.b) ORDER BY t1.a, t2.b; +SELECT t1.a, t1.phv, t2.b, t2.phv FROM (SELECT 't1_phv' phv, * FROM fprt1 WHERE a % 25 = 0) t1 FULL JOIN (SELECT 't2_phv' phv, * FROM fprt2 WHERE b % 25 = 0) t2 ON (t1.a = t2.b) ORDER BY t1.a, t2.b; + +-- test FOR UPDATE; partitionwise join does not apply +EXPLAIN (COSTS OFF) +SELECT t1.a, t2.b FROM fprt1 t1 INNER JOIN fprt2 t2 ON (t1.a = t2.b) WHERE t1.a % 25 = 0 ORDER BY 1,2 FOR UPDATE OF t1; +SELECT t1.a, t2.b FROM fprt1 t1 INNER JOIN fprt2 t2 ON (t1.a = t2.b) WHERE t1.a % 25 = 0 ORDER BY 1,2 FOR UPDATE OF t1; + +RESET enable_partitionwise_join; + + +-- =================================================================== +-- test partitionwise aggregates +-- =================================================================== + +CREATE TABLE pagg_tab (a int, b int, c text) PARTITION BY RANGE(a); + +CREATE TABLE pagg_tab_p1 (LIKE pagg_tab); +CREATE TABLE pagg_tab_p2 (LIKE pagg_tab); +CREATE TABLE pagg_tab_p3 (LIKE pagg_tab); + +INSERT INTO pagg_tab_p1 SELECT i % 30, i % 50, to_char(i/30, 'FM0000') FROM generate_series(1, 3000) i WHERE (i % 30) < 10; +INSERT INTO pagg_tab_p2 SELECT i % 30, i % 50, to_char(i/30, 'FM0000') FROM generate_series(1, 3000) i WHERE (i % 30) < 20 and (i % 30) >= 10; +INSERT INTO pagg_tab_p3 SELECT i % 30, i % 50, to_char(i/30, 'FM0000') FROM generate_series(1, 3000) i WHERE (i % 30) < 30 and (i % 30) >= 20; + +-- Create foreign partitions +CREATE FOREIGN TABLE fpagg_tab_p1 PARTITION OF pagg_tab FOR VALUES FROM (0) TO (10) SERVER loopback OPTIONS (table_name 'pagg_tab_p1'); +CREATE FOREIGN TABLE fpagg_tab_p2 PARTITION OF pagg_tab FOR VALUES FROM (10) TO (20) SERVER loopback OPTIONS (table_name 'pagg_tab_p2'); +CREATE FOREIGN TABLE fpagg_tab_p3 PARTITION OF pagg_tab FOR VALUES FROM (20) TO (30) SERVER loopback OPTIONS (table_name 'pagg_tab_p3'); + +ANALYZE pagg_tab; +ANALYZE fpagg_tab_p1; +ANALYZE fpagg_tab_p2; +ANALYZE fpagg_tab_p3; + +-- When GROUP BY clause matches with PARTITION KEY. +-- Plan with partitionwise aggregates is disabled +SET enable_partitionwise_aggregate TO false; +EXPLAIN (COSTS OFF) +SELECT a, sum(b), min(b), count(*) FROM pagg_tab GROUP BY a HAVING avg(b) < 22 ORDER BY 1; + +-- Plan with partitionwise aggregates is enabled +SET enable_partitionwise_aggregate TO true; +EXPLAIN (COSTS OFF) +SELECT a, sum(b), min(b), count(*) FROM pagg_tab GROUP BY a HAVING avg(b) < 22 ORDER BY 1; +SELECT a, sum(b), min(b), count(*) FROM pagg_tab GROUP BY a HAVING avg(b) < 22 ORDER BY 1; + +-- Check with whole-row reference +-- Should have all the columns in the target list for the given relation +EXPLAIN (VERBOSE, COSTS OFF) +SELECT a, count(t1) FROM pagg_tab t1 GROUP BY a HAVING avg(b) < 22 ORDER BY 1; +SELECT a, count(t1) FROM pagg_tab t1 GROUP BY a HAVING avg(b) < 22 ORDER BY 1; + +-- When GROUP BY clause does not match with PARTITION KEY. +EXPLAIN (COSTS OFF) +SELECT b, avg(a), max(a), count(*) FROM pagg_tab GROUP BY b HAVING sum(a) < 700 ORDER BY 1; +*/ +/* +-- Skip test, influxdb_fdw does not support nosuperuser +-- =================================================================== +-- access rights and superuser +-- =================================================================== + +-- Non-superuser cannot create a FDW without a password in the connstr +CREATE ROLE regress_nosuper NOSUPERUSER; + +GRANT USAGE ON FOREIGN DATA WRAPPER influxdb_fdw TO regress_nosuper; + +SET ROLE regress_nosuper; + +SHOW is_superuser; + +-- This will be OK, we can create the FDW +DO $d$ + BEGIN + EXECUTE $$CREATE SERVER loopback_nopw FOREIGN DATA WRAPPER influxdb_fdw + OPTIONS (dbname '$$||current_database()||$$', + port '$$||current_setting('port')||$$' + )$$; + END; +$d$; + +-- But creation of user mappings for non-superusers should fail +CREATE USER MAPPING FOR public SERVER loopback_nopw; +CREATE USER MAPPING FOR CURRENT_USER SERVER loopback_nopw; + +CREATE FOREIGN TABLE pg_temp.ft1_nopw ( + c1 int NOT NULL, + c2 int NOT NULL, + c3 text, + c4 timestamptz, + c5 timestamptz, + c6 varchar(10), + c7 char(10) default 'ft1', + c8 user_enum +) SERVER loopback_nopw OPTIONS (schema_name 'public', table_name 'ft1'); + +SELECT 1 FROM ft1_nopw LIMIT 1; + +-- If we add a password to the connstr it'll fail, because we don't allow passwords +-- in connstrs only in user mappings. + +ALTER SERVER loopback_nopw OPTIONS (ADD password 'dummypw'); + +-- If we add a password for our user mapping instead, we should get a different +-- error because the password wasn't actually *used* when we run with trust auth. +-- +-- This won't work with installcheck, but neither will most of the FDW checks. + +ALTER USER MAPPING FOR CURRENT_USER SERVER loopback_nopw OPTIONS (ADD password 'dummypw'); + +SELECT 1 FROM ft1_nopw LIMIT 1; + +-- Unpriv user cannot make the mapping passwordless +ALTER USER MAPPING FOR CURRENT_USER SERVER loopback_nopw OPTIONS (ADD password_required 'false'); + + +SELECT 1 FROM ft1_nopw LIMIT 1; + +RESET ROLE; + +-- But the superuser can +ALTER USER MAPPING FOR regress_nosuper SERVER loopback_nopw OPTIONS (ADD password_required 'false'); + +SET ROLE regress_nosuper; + +-- Should finally work now +SELECT 1 FROM ft1_nopw LIMIT 1; + +-- unpriv user also cannot set sslcert / sslkey on the user mapping +-- first set password_required so we see the right error messages +ALTER USER MAPPING FOR CURRENT_USER SERVER loopback_nopw OPTIONS (SET password_required 'true'); +ALTER USER MAPPING FOR CURRENT_USER SERVER loopback_nopw OPTIONS (ADD sslcert 'foo.crt'); +ALTER USER MAPPING FOR CURRENT_USER SERVER loopback_nopw OPTIONS (ADD sslkey 'foo.key'); + +-- We're done with the role named after a specific user and need to check the +-- changes to the public mapping. +DROP USER MAPPING FOR CURRENT_USER SERVER loopback_nopw; + +-- This will fail again as it'll resolve the user mapping for public, which +-- lacks password_required=false +SELECT 1 FROM ft1_nopw LIMIT 1; + +RESET ROLE; + +-- The user mapping for public is passwordless and lacks the password_required=false +-- mapping option, but will work because the current user is a superuser. +SELECT 1 FROM ft1_nopw LIMIT 1; + +-- cleanup +DROP USER MAPPING FOR public SERVER loopback_nopw; +DROP OWNED BY regress_nosuper; +DROP ROLE regress_nosuper; +*/ +-- influxdb_fdw does not support transactions +-- Two-phase transactions are not supported. +--BEGIN; +--Testcase 698: +SELECT count(*) FROM ft1; + count +------- + 822 +(1 row) + +-- error here +--PREPARE TRANSACTION 'fdw_tpc'; +--ROLLBACK; +/* +-- Influxdb_fdw does not use connection, and does not support connection functions +-- =================================================================== +-- reestablish new connection +-- =================================================================== + +-- Change application_name of remote connection to special one +-- so that we can easily terminate the connection later. +ALTER SERVER loopback OPTIONS (application_name 'fdw_retry_check'); + +-- Make sure we have a remote connection. +SELECT 1 FROM ft1 LIMIT 1; + +-- Terminate the remote connection and wait for the termination to complete. +-- (If a cache flush happens, the remote connection might have already been +-- dropped; so code this step in a way that doesn't fail if no connection.) +DO $$ BEGIN +PERFORM pg_terminate_backend(pid, 180000) FROM pg_stat_activity + WHERE application_name = 'fdw_retry_check'; +END $$; + +-- This query should detect the broken connection when starting new remote +-- transaction, reestablish new connection, and then succeed. +BEGIN; +SELECT 1 FROM ft1 LIMIT 1; + +-- If we detect the broken connection when starting a new remote +-- subtransaction, we should fail instead of establishing a new connection. +-- Terminate the remote connection and wait for the termination to complete. +DO $$ BEGIN +PERFORM pg_terminate_backend(pid, 180000) FROM pg_stat_activity + WHERE application_name = 'fdw_retry_check'; +END $$; +SAVEPOINT s; +-- The text of the error might vary across platforms, so only show SQLSTATE. +\set VERBOSITY sqlstate +SELECT 1 FROM ft1 LIMIT 1; -- should fail +\set VERBOSITY default +COMMIT; + +-- ============================================================================= +-- test connection invalidation cases and postgres_fdw_get_connections function +-- ============================================================================= +-- Let's ensure to close all the existing cached connections. +SELECT 1 FROM postgres_fdw_disconnect_all(); +-- No cached connections, so no records should be output. +SELECT server_name FROM postgres_fdw_get_connections() ORDER BY 1; +-- This test case is for closing the connection in pgfdw_xact_callback +BEGIN; +-- Connection xact depth becomes 1 i.e. the connection is in midst of the xact. +SELECT 1 FROM ft1 LIMIT 1; +SELECT 1 FROM ft7 LIMIT 1; +-- List all the existing cached connections. loopback and loopback3 should be +-- output. +SELECT server_name FROM postgres_fdw_get_connections() ORDER BY 1; +-- Connections are not closed at the end of the alter and drop statements. +-- That's because the connections are in midst of this xact, +-- they are just marked as invalid in pgfdw_inval_callback. +ALTER SERVER loopback OPTIONS (ADD use_remote_estimate 'off'); +DROP SERVER loopback3 CASCADE; +-- List all the existing cached connections. loopback and loopback3 +-- should be output as invalid connections. Also the server name for +-- loopback3 should be NULL because the server was dropped. +SELECT * FROM postgres_fdw_get_connections() ORDER BY 1; +-- The invalid connections get closed in pgfdw_xact_callback during commit. +COMMIT; +-- All cached connections were closed while committing above xact, so no +-- records should be output. +SELECT server_name FROM postgres_fdw_get_connections() ORDER BY 1; + +-- ======================================================================= +-- test postgres_fdw_disconnect and postgres_fdw_disconnect_all functions +-- ======================================================================= +BEGIN; +-- Ensure to cache loopback connection. +SELECT 1 FROM ft1 LIMIT 1; +-- Ensure to cache loopback2 connection. +SELECT 1 FROM ft6 LIMIT 1; +-- List all the existing cached connections. loopback and loopback2 should be +-- output. +SELECT server_name FROM postgres_fdw_get_connections() ORDER BY 1; +-- Issue a warning and return false as loopback connection is still in use and +-- can not be closed. +SELECT postgres_fdw_disconnect('loopback'); +-- List all the existing cached connections. loopback and loopback2 should be +-- output. +SELECT server_name FROM postgres_fdw_get_connections() ORDER BY 1; +-- Return false as connections are still in use, warnings are issued. +-- But disable warnings temporarily because the order of them is not stable. +SET client_min_messages = 'ERROR'; +SELECT postgres_fdw_disconnect_all(); +RESET client_min_messages; +COMMIT; +-- Ensure that loopback2 connection is closed. +SELECT 1 FROM postgres_fdw_disconnect('loopback2'); +SELECT server_name FROM postgres_fdw_get_connections() WHERE server_name = 'loopback2'; +-- Return false as loopback2 connection is closed already. +SELECT postgres_fdw_disconnect('loopback2'); +-- Return an error as there is no foreign server with given name. +SELECT postgres_fdw_disconnect('unknownserver'); +-- Let's ensure to close all the existing cached connections. +SELECT 1 FROM postgres_fdw_disconnect_all(); +-- No cached connections, so no records should be output. +SELECT server_name FROM postgres_fdw_get_connections() ORDER BY 1; + +-- ============================================================================= +-- test case for having multiple cached connections for a foreign server +-- ============================================================================= +CREATE ROLE regress_multi_conn_user1 SUPERUSER; +CREATE ROLE regress_multi_conn_user2 SUPERUSER; +CREATE USER MAPPING FOR regress_multi_conn_user1 SERVER loopback; +CREATE USER MAPPING FOR regress_multi_conn_user2 SERVER loopback; + +BEGIN; +-- Will cache loopback connection with user mapping for regress_multi_conn_user1 +SET ROLE regress_multi_conn_user1; +SELECT 1 FROM ft1 LIMIT 1; +RESET ROLE; + +-- Will cache loopback connection with user mapping for regress_multi_conn_user2 +SET ROLE regress_multi_conn_user2; +SELECT 1 FROM ft1 LIMIT 1; +RESET ROLE; + +-- Should output two connections for loopback server +SELECT server_name FROM postgres_fdw_get_connections() ORDER BY 1; +COMMIT; +-- Let's ensure to close all the existing cached connections. +SELECT 1 FROM postgres_fdw_disconnect_all(); +-- No cached connections, so no records should be output. +SELECT server_name FROM postgres_fdw_get_connections() ORDER BY 1; + +-- Clean up +DROP USER MAPPING FOR regress_multi_conn_user1 SERVER loopback; +DROP USER MAPPING FOR regress_multi_conn_user2 SERVER loopback; +DROP ROLE regress_multi_conn_user1; +DROP ROLE regress_multi_conn_user2; + +-- =================================================================== +-- Test foreign server level option keep_connections +-- =================================================================== +-- By default, the connections associated with foreign server are cached i.e. +-- keep_connections option is on. Set it to off. +ALTER SERVER loopback OPTIONS (keep_connections 'off'); +-- connection to loopback server is closed at the end of xact +-- as keep_connections was set to off. +SELECT 1 FROM ft1 LIMIT 1; +-- No cached connections, so no records should be output. +SELECT server_name FROM postgres_fdw_get_connections() ORDER BY 1; +ALTER SERVER loopback OPTIONS (SET keep_connections 'on'); +*/ +-- =================================================================== +-- batch insert +-- =================================================================== +BEGIN; +--Testcase 699: +CREATE SERVER batch10 FOREIGN DATA WRAPPER influxdb_fdw + OPTIONS(dbname 'postdb', :SERVER, batch_size '10' ); +--Testcase 700: +SELECT count(*) +FROM pg_foreign_server +WHERE srvname = 'batch10' +AND srvoptions @> array['batch_size=10']; + count +------- + 1 +(1 row) + +--Testcase 701: +ALTER SERVER batch10 OPTIONS( SET batch_size '20' ); +--Testcase 702: +SELECT count(*) +FROM pg_foreign_server +WHERE srvname = 'batch10' +AND srvoptions @> array['batch_size=10']; + count +------- + 0 +(1 row) + +--Testcase 703: +SELECT count(*) +FROM pg_foreign_server +WHERE srvname = 'batch10' +AND srvoptions @> array['batch_size=20']; + count +------- + 1 +(1 row) + +--Testcase 704: +CREATE FOREIGN TABLE table30 ( x int ) SERVER batch10 OPTIONS ( batch_size '30' ); +--Testcase 705: +SELECT COUNT(*) +FROM pg_foreign_table +WHERE ftrelid = 'table30'::regclass +AND ftoptions @> array['batch_size=30']; + count +------- + 1 +(1 row) + +--Testcase 706: +ALTER FOREIGN TABLE table30 OPTIONS ( SET batch_size '40'); +--Testcase 707: +SELECT COUNT(*) +FROM pg_foreign_table +WHERE ftrelid = 'table30'::regclass +AND ftoptions @> array['batch_size=30']; + count +------- + 0 +(1 row) + +--Testcase 708: +SELECT COUNT(*) +FROM pg_foreign_table +WHERE ftrelid = 'table30'::regclass +AND ftoptions @> array['batch_size=40']; + count +------- + 1 +(1 row) + +ROLLBACK; +--Testcase 709: +CREATE FOREIGN TABLE batch_table ( x int ) SERVER influxdb_svr; +--Testcase 710: +CREATE FOREIGN TABLE ftable ( x int ) SERVER influxdb_svr OPTIONS ( table 'batch_table', batch_size '10' ); +--Testcase 711: +EXPLAIN (VERBOSE, COSTS OFF) INSERT INTO ftable SELECT * FROM generate_series(1, 10) i; + QUERY PLAN +----------------------------------------------------- + Insert on public.ftable + Batch Size: 10 + -> Function Scan on pg_catalog.generate_series i + Output: i.i + Function Call: generate_series(1, 10) +(5 rows) + +--Testcase 712: +INSERT INTO ftable SELECT * FROM generate_series(1, 10) i; +--Testcase 713: +INSERT INTO ftable SELECT * FROM generate_series(11, 31) i; +--Testcase 714: +INSERT INTO ftable VALUES (32); +--Testcase 715: +INSERT INTO ftable VALUES (33), (34); +--Testcase 721: +SELECT COUNT(*) FROM ftable; + count +------- + 34 +(1 row) + +--Testcase 722: +DELETE FROM batch_table; +--Testcase 723: +DROP FOREIGN TABLE ftable; +-- Disable batch insert +--Testcase 724: +CREATE FOREIGN TABLE ftable ( x int ) SERVER influxdb_svr OPTIONS ( table 'batch_table', batch_size '1' ); +--Testcase 725: +EXPLAIN (VERBOSE, COSTS OFF) INSERT INTO ftable VALUES (1), (2); + QUERY PLAN +------------------------------------ + Insert on public.ftable + Batch Size: 1 + -> Values Scan on "*VALUES*" + Output: "*VALUES*".column1 +(4 rows) + +--Testcase 726: +INSERT INTO ftable VALUES (1), (2); +--Testcase 727: +SELECT COUNT(*) FROM ftable; + count +------- + 2 +(1 row) + +-- Disable batch inserting into foreign tables with BEFORE ROW INSERT triggers +-- even if the batch_size option is enabled. +--Testcase 776: +ALTER FOREIGN TABLE ftable OPTIONS ( SET batch_size '10' ); +--Testcase 777: +CREATE TRIGGER trig_row_before BEFORE INSERT ON ftable +FOR EACH ROW EXECUTE PROCEDURE trigger_data(23,'skidoo'); +--Testcase 778: +EXPLAIN (VERBOSE, COSTS OFF) INSERT INTO ftable VALUES (3), (4); + QUERY PLAN +------------------------------------ + Insert on public.ftable + Batch Size: 1 + -> Values Scan on "*VALUES*" + Output: "*VALUES*".column1 +(4 rows) + +--Testcase 779: +INSERT INTO ftable VALUES (3), (4); +NOTICE: trig_row_before(23, skidoo) BEFORE ROW INSERT ON ftable +NOTICE: NEW: (3) +NOTICE: trig_row_before(23, skidoo) BEFORE ROW INSERT ON ftable +NOTICE: NEW: (4) +--Testcase 780: +SELECT COUNT(*) FROM ftable; + count +------- + 4 +(1 row) + +-- Clean up +--Testcase 781: +DROP TRIGGER trig_row_before ON ftable; +--Testcase 728: +DROP FOREIGN TABLE ftable; +--Testcase 729: +DELETE FROM batch_table; +--Testcase 785: +DROP FOREIGN TABLE batch_table; +-- influxdb_fdw does not support partition insert +-- Use partitioning +--Testcase 730: +CREATE TABLE batch_table ( x int ) PARTITION BY HASH (x); +--Testcase 731: +CREATE TABLE batch_table_p0 (LIKE batch_table); +--Testcase 732: +CREATE FOREIGN TABLE batch_table_p0f + PARTITION OF batch_table + FOR VALUES WITH (MODULUS 3, REMAINDER 0) + SERVER influxdb_svr + OPTIONS (table 'batch_table_p0', batch_size '10'); +--Testcase 733: +CREATE TABLE batch_table_p1 (LIKE batch_table); +--Testcase 734: +CREATE FOREIGN TABLE batch_table_p1f + PARTITION OF batch_table + FOR VALUES WITH (MODULUS 3, REMAINDER 1) + SERVER influxdb_svr + OPTIONS (table 'batch_table_p1', batch_size '1'); +--Testcase 735: +CREATE TABLE batch_table_p2 + PARTITION OF batch_table + FOR VALUES WITH (MODULUS 3, REMAINDER 2); +--Testcase 736: +INSERT INTO batch_table SELECT * FROM generate_series(1, 66) i; +ERROR: Not support partition insert +--Testcase 737: +SELECT COUNT(*) FROM batch_table; + count +------- + 0 +(1 row) + +-- Clean up +DROP TABLE batch_table; +DROP TABLE batch_table_p0; +DROP TABLE batch_table_p1; +-- Check that batched mode also works for some inserts made during +-- cross-partition updates +--Testcase 738: +CREATE TABLE batch_cp_upd_test (a int) PARTITION BY LIST (a); +--Testcase 739: +CREATE TABLE batch_cp_upd_test1 (LIKE batch_cp_upd_test); +--Testcase 740: +CREATE FOREIGN TABLE batch_cp_upd_test1_f + PARTITION OF batch_cp_upd_test + FOR VALUES IN (1) + SERVER influxdb_svr + OPTIONS (table 'batch_cp_upd_test1', batch_size '10'); +--Testcase 741: +CREATE TABLE batch_cp_upd_test2 PARTITION OF batch_cp_upd_test + FOR VALUES IN (2); +--Testcase 742: +CREATE TABLE batch_cp_upd_test3 (LIKE batch_cp_upd_test); +CREATE FOREIGN TABLE batch_cp_upd_test3_f + PARTITION OF batch_cp_upd_test + FOR VALUES IN (3) + SERVER influxdb_svr + OPTIONS (table 'batch_cp_upd_test3', batch_size '1'); +-- Create statement triggers on remote tables that "log" any INSERTs +-- performed on them. +CREATE TABLE cmdlog (cmd text); +CREATE FUNCTION log_stmt() RETURNS TRIGGER LANGUAGE plpgsql AS $$ + BEGIN INSERT INTO public.cmdlog VALUES (TG_OP || ' on ' || TG_RELNAME); RETURN NULL; END; +$$; +CREATE TRIGGER stmt_trig AFTER INSERT ON batch_cp_upd_test1 + FOR EACH STATEMENT EXECUTE FUNCTION log_stmt(); +CREATE TRIGGER stmt_trig AFTER INSERT ON batch_cp_upd_test3 + FOR EACH STATEMENT EXECUTE FUNCTION log_stmt(); +-- This update moves rows from the local partition 'batch_cp_upd_test2' to the +-- foreign partition 'batch_cp_upd_test1', one that has insert batching +-- enabled, so a single INSERT for both rows. +INSERT INTO batch_cp_upd_test VALUES (2), (2); +-- influxdb_fdw does not support update +-- UPDATE batch_cp_upd_test t SET a = 1 FROM (VALUES (1), (2)) s(a) WHERE t.a = s.a AND s.a = 2; +-- This one moves rows from the local partition 'batch_cp_upd_test2' to the +-- foreign partition 'batch_cp_upd_test2', one that has insert batching +-- disabled, so separate INSERTs for the two rows. +INSERT INTO batch_cp_upd_test VALUES (2), (2); +-- UPDATE batch_cp_upd_test t SET a = 3 FROM (VALUES (1), (2)) s(a) WHERE t.a = s.a AND s.a = 2; +SELECT tableoid::regclass, * FROM batch_cp_upd_test ORDER BY 1; + tableoid | a +--------------------+--- + batch_cp_upd_test2 | 2 + batch_cp_upd_test2 | 2 + batch_cp_upd_test2 | 2 + batch_cp_upd_test2 | 2 +(4 rows) + +-- Should see 1 INSERT on batch_cp_upd_test1 and 2 on batch_cp_upd_test3 as +-- described above. +SELECT * FROM cmdlog ORDER BY 1; + cmd +----- +(0 rows) + +-- Clean up +DROP TABLE batch_cp_upd_test; +DROP TABLE batch_cp_upd_test1; +DROP TABLE batch_cp_upd_test3; +DROP TABLE cmdlog; +DROP FUNCTION log_stmt(); +-- influxdb_fdw does not support partition insert +-- Use partitioning +--Testcase 745: +ALTER SERVER influxdb_svr OPTIONS (ADD batch_size '10'); +--Testcase 746: +CREATE TABLE batch_table ( x int, field1 text, field2 text) PARTITION BY HASH (x); +--Testcase 747: +CREATE TABLE batch_table_p0 (LIKE batch_table); +--Testcase 748: +ALTER TABLE batch_table_p0 ADD CONSTRAINT p0_pkey PRIMARY KEY (x); +--Testcase 749: +CREATE FOREIGN TABLE batch_table_p0f + PARTITION OF batch_table + FOR VALUES WITH (MODULUS 2, REMAINDER 0) + SERVER influxdb_svr + OPTIONS (table 'batch_table_p0'); +--Testcase 750: +CREATE TABLE batch_table_p1 (LIKE batch_table); +--Testcase 751: +ALTER TABLE batch_table_p1 ADD CONSTRAINT p1_pkey PRIMARY KEY (x); +--Testcase 752: +CREATE FOREIGN TABLE batch_table_p1f + PARTITION OF batch_table + FOR VALUES WITH (MODULUS 2, REMAINDER 1) + SERVER influxdb_svr + OPTIONS (table 'batch_table_p1'); +--Testcase 753: +INSERT INTO batch_table SELECT i, 'test'||i, 'test'|| i FROM generate_series(1, 50) i; +ERROR: Not support partition insert +--Testcase 754: +SELECT COUNT(*) FROM batch_table; + count +------- + 0 +(1 row) + +--Testcase 755: +SELECT * FROM batch_table ORDER BY x; + x | field1 | field2 +---+--------+-------- +(0 rows) + +-- Clean up +DROP TABLE batch_table; +DROP TABLE batch_table_p0; +DROP TABLE batch_table_p1; +--Testcase 756: +ALTER SERVER influxdb_svr OPTIONS (DROP batch_size); +-- Test that pending inserts are handled properly when needed +CREATE TABLE batch_table (a text, b int); +CREATE FOREIGN TABLE ftable (a text, b int) + SERVER influxdb_svr + OPTIONS (table 'batch_table', batch_size '2'); +CREATE TABLE ltable (a text, b int); +CREATE FUNCTION ftable_rowcount_trigf() RETURNS trigger LANGUAGE plpgsql AS +$$ +begin + raise notice '%: there are % rows in ftable', + TG_NAME, (SELECT count(*) FROM ftable); + if TG_OP = 'DELETE' then + return OLD; + else + return NEW; + end if; +end; +$$; +CREATE TRIGGER ftable_rowcount_trigger +BEFORE INSERT OR UPDATE OR DELETE ON ltable +FOR EACH ROW EXECUTE PROCEDURE ftable_rowcount_trigf(); +WITH t AS ( + INSERT INTO ltable VALUES ('AAA', 42), ('BBB', 42) RETURNING * +) +INSERT INTO ftable SELECT * FROM t; +NOTICE: ftable_rowcount_trigger: there are rows in ftable +NOTICE: ftable_rowcount_trigger: there are 1 rows in ftable +SELECT * FROM ltable; + a | b +-----+---- + AAA | 42 + BBB | 42 +(2 rows) + +SELECT * FROM ftable; + a | b +-----+---- + AAA | 42 + BBB | 42 +(2 rows) + +DELETE FROM ftable; +WITH t AS ( + UPDATE ltable SET b = b + 100 RETURNING * +) +INSERT INTO ftable SELECT * FROM t; +NOTICE: ftable_rowcount_trigger: there are rows in ftable +NOTICE: ftable_rowcount_trigger: there are 1 rows in ftable +SELECT * FROM ltable; + a | b +-----+----- + AAA | 142 + BBB | 142 +(2 rows) + +SELECT * FROM ftable; + a | b +-----+----- + AAA | 142 + BBB | 142 +(2 rows) + +DELETE FROM ftable; +WITH t AS ( + DELETE FROM ltable RETURNING * +) +INSERT INTO ftable SELECT * FROM t; +NOTICE: ftable_rowcount_trigger: there are rows in ftable +NOTICE: ftable_rowcount_trigger: there are 1 rows in ftable +SELECT * FROM ltable; + a | b +---+--- +(0 rows) + +SELECT * FROM ftable; + a | b +-----+----- + AAA | 142 + BBB | 142 +(2 rows) + +DELETE FROM ftable; +-- Clean up +DROP FOREIGN TABLE ftable; +DROP TABLE batch_table; +DROP TRIGGER ftable_rowcount_trigger ON ltable; +DROP TABLE ltable; +CREATE TABLE parent (a text, b int) PARTITION BY LIST (a); +CREATE TABLE batch_table (a text, b int); +CREATE FOREIGN TABLE ftable + PARTITION OF parent + FOR VALUES IN ('AAA') + SERVER influxdb_svr + OPTIONS (table 'batch_table', batch_size '2'); +CREATE TABLE ltable + PARTITION OF parent + FOR VALUES IN ('BBB'); +CREATE TRIGGER ftable_rowcount_trigger +BEFORE INSERT ON ltable +FOR EACH ROW EXECUTE PROCEDURE ftable_rowcount_trigf(); +-- Not support partition insert +INSERT INTO parent VALUES ('AAA', 42), ('BBB', 42), ('AAA', 42), ('BBB', 42); +ERROR: Not support partition insert +SELECT tableoid::regclass, * FROM parent; + tableoid | a | b +----------+---+--- +(0 rows) + +-- Clean up +DROP FOREIGN TABLE ftable; +DROP TABLE batch_table; +DROP TRIGGER ftable_rowcount_trigger ON ltable; +DROP TABLE ltable; +DROP TABLE parent; +DROP FUNCTION ftable_rowcount_trigf; +/* InfluxDB does not support partition table +-- =================================================================== +-- test asynchronous execution +-- =================================================================== + +ALTER SERVER loopback OPTIONS (DROP extensions); +ALTER SERVER loopback OPTIONS (ADD async_capable 'true'); +ALTER SERVER loopback2 OPTIONS (ADD async_capable 'true'); + +CREATE TABLE async_pt (a int, b int, c text) PARTITION BY RANGE (a); +CREATE TABLE base_tbl1 (a int, b int, c text); +CREATE TABLE base_tbl2 (a int, b int, c text); +CREATE FOREIGN TABLE async_p1 PARTITION OF async_pt FOR VALUES FROM (1000) TO (2000) + SERVER loopback OPTIONS (table_name 'base_tbl1'); +CREATE FOREIGN TABLE async_p2 PARTITION OF async_pt FOR VALUES FROM (2000) TO (3000) + SERVER loopback2 OPTIONS (table_name 'base_tbl2'); +INSERT INTO async_p1 SELECT 1000 + i, i, to_char(i, 'FM0000') FROM generate_series(0, 999, 5) i; +INSERT INTO async_p2 SELECT 2000 + i, i, to_char(i, 'FM0000') FROM generate_series(0, 999, 5) i; +ANALYZE async_pt; + +-- simple queries +CREATE TABLE result_tbl (a int, b int, c text); + +EXPLAIN (VERBOSE, COSTS OFF) +INSERT INTO result_tbl SELECT * FROM async_pt WHERE b % 100 = 0; +INSERT INTO result_tbl SELECT * FROM async_pt WHERE b % 100 = 0; + +SELECT * FROM result_tbl ORDER BY a; +DELETE FROM result_tbl; + +EXPLAIN (VERBOSE, COSTS OFF) +INSERT INTO result_tbl SELECT * FROM async_pt WHERE b === 505; +INSERT INTO result_tbl SELECT * FROM async_pt WHERE b === 505; + +SELECT * FROM result_tbl ORDER BY a; +DELETE FROM result_tbl; + +EXPLAIN (VERBOSE, COSTS OFF) +INSERT INTO result_tbl SELECT a, b, 'AAA' || c FROM async_pt WHERE b === 505; +INSERT INTO result_tbl SELECT a, b, 'AAA' || c FROM async_pt WHERE b === 505; + +SELECT * FROM result_tbl ORDER BY a; +DELETE FROM result_tbl; + +-- Check case where multiple partitions use the same connection +CREATE TABLE base_tbl3 (a int, b int, c text); +CREATE FOREIGN TABLE async_p3 PARTITION OF async_pt FOR VALUES FROM (3000) TO (4000) + SERVER loopback2 OPTIONS (table_name 'base_tbl3'); +INSERT INTO async_p3 SELECT 3000 + i, i, to_char(i, 'FM0000') FROM generate_series(0, 999, 5) i; +ANALYZE async_pt; + +EXPLAIN (VERBOSE, COSTS OFF) +INSERT INTO result_tbl SELECT * FROM async_pt WHERE b === 505; +INSERT INTO result_tbl SELECT * FROM async_pt WHERE b === 505; + +SELECT * FROM result_tbl ORDER BY a; +DELETE FROM result_tbl; + +DROP FOREIGN TABLE async_p3; +DROP TABLE base_tbl3; + +-- Check case where the partitioned table has local/remote partitions +CREATE TABLE async_p3 PARTITION OF async_pt FOR VALUES FROM (3000) TO (4000); +INSERT INTO async_p3 SELECT 3000 + i, i, to_char(i, 'FM0000') FROM generate_series(0, 999, 5) i; +ANALYZE async_pt; + +EXPLAIN (VERBOSE, COSTS OFF) +INSERT INTO result_tbl SELECT * FROM async_pt WHERE b === 505; +INSERT INTO result_tbl SELECT * FROM async_pt WHERE b === 505; + +SELECT * FROM result_tbl ORDER BY a; +DELETE FROM result_tbl; + +-- partitionwise joins +SET enable_partitionwise_join TO true; + +CREATE TABLE join_tbl (a1 int, b1 int, c1 text, a2 int, b2 int, c2 text); + +EXPLAIN (VERBOSE, COSTS OFF) +INSERT INTO join_tbl SELECT * FROM async_pt t1, async_pt t2 WHERE t1.a = t2.a AND t1.b = t2.b AND t1.b % 100 = 0; +INSERT INTO join_tbl SELECT * FROM async_pt t1, async_pt t2 WHERE t1.a = t2.a AND t1.b = t2.b AND t1.b % 100 = 0; + +SELECT * FROM join_tbl ORDER BY a1; +DELETE FROM join_tbl; + +EXPLAIN (VERBOSE, COSTS OFF) +INSERT INTO join_tbl SELECT t1.a, t1.b, 'AAA' || t1.c, t2.a, t2.b, 'AAA' || t2.c FROM async_pt t1, async_pt t2 WHERE t1.a = t2.a AND t1.b = t2.b AND t1.b % 100 = 0; +INSERT INTO join_tbl SELECT t1.a, t1.b, 'AAA' || t1.c, t2.a, t2.b, 'AAA' || t2.c FROM async_pt t1, async_pt t2 WHERE t1.a = t2.a AND t1.b = t2.b AND t1.b % 100 = 0; + +SELECT * FROM join_tbl ORDER BY a1; +DELETE FROM join_tbl; + +RESET enable_partitionwise_join; + +-- Test rescan of an async Append node with do_exec_prune=false +SET enable_hashjoin TO false; + +EXPLAIN (VERBOSE, COSTS OFF) +INSERT INTO join_tbl SELECT * FROM async_p1 t1, async_pt t2 WHERE t1.a = t2.a AND t1.b = t2.b AND t1.b % 100 = 0; +INSERT INTO join_tbl SELECT * FROM async_p1 t1, async_pt t2 WHERE t1.a = t2.a AND t1.b = t2.b AND t1.b % 100 = 0; + +SELECT * FROM join_tbl ORDER BY a1; +DELETE FROM join_tbl; + +RESET enable_hashjoin; + +-- Test interaction of async execution with plan-time partition pruning +EXPLAIN (VERBOSE, COSTS OFF) +SELECT * FROM async_pt WHERE a < 3000; + +EXPLAIN (VERBOSE, COSTS OFF) +SELECT * FROM async_pt WHERE a < 2000; + +-- Test interaction of async execution with run-time partition pruning +SET plan_cache_mode TO force_generic_plan; + +PREPARE async_pt_query (int, int) AS + INSERT INTO result_tbl SELECT * FROM async_pt WHERE a < $1 AND b === $2; + +EXPLAIN (VERBOSE, COSTS OFF) +EXECUTE async_pt_query (3000, 505); +EXECUTE async_pt_query (3000, 505); + +SELECT * FROM result_tbl ORDER BY a; +DELETE FROM result_tbl; + +EXPLAIN (VERBOSE, COSTS OFF) +EXECUTE async_pt_query (2000, 505); +EXECUTE async_pt_query (2000, 505); + +SELECT * FROM result_tbl ORDER BY a; +DELETE FROM result_tbl; + +RESET plan_cache_mode; + +CREATE TABLE local_tbl(a int, b int, c text); +INSERT INTO local_tbl VALUES (1505, 505, 'foo'), (2505, 505, 'bar'); +ANALYZE local_tbl; + +CREATE INDEX base_tbl1_idx ON base_tbl1 (a); +CREATE INDEX base_tbl2_idx ON base_tbl2 (a); +CREATE INDEX async_p3_idx ON async_p3 (a); +ANALYZE base_tbl1; +ANALYZE base_tbl2; +ANALYZE async_p3; + +ALTER FOREIGN TABLE async_p1 OPTIONS (use_remote_estimate 'true'); +ALTER FOREIGN TABLE async_p2 OPTIONS (use_remote_estimate 'true'); + +EXPLAIN (VERBOSE, COSTS OFF) +SELECT * FROM local_tbl, async_pt WHERE local_tbl.a = async_pt.a AND local_tbl.c = 'bar'; +EXPLAIN (ANALYZE, COSTS OFF, SUMMARY OFF, TIMING OFF) +SELECT * FROM local_tbl, async_pt WHERE local_tbl.a = async_pt.a AND local_tbl.c = 'bar'; +SELECT * FROM local_tbl, async_pt WHERE local_tbl.a = async_pt.a AND local_tbl.c = 'bar'; + +ALTER FOREIGN TABLE async_p1 OPTIONS (DROP use_remote_estimate); +ALTER FOREIGN TABLE async_p2 OPTIONS (DROP use_remote_estimate); + +DROP TABLE local_tbl; +DROP INDEX base_tbl1_idx; +DROP INDEX base_tbl2_idx; +DROP INDEX async_p3_idx; + +-- UNION queries +EXPLAIN (VERBOSE, COSTS OFF) +INSERT INTO result_tbl +(SELECT a, b, 'AAA' || c FROM async_p1 ORDER BY a LIMIT 10) +UNION +(SELECT a, b, 'AAA' || c FROM async_p2 WHERE b < 10); +INSERT INTO result_tbl +(SELECT a, b, 'AAA' || c FROM async_p1 ORDER BY a LIMIT 10) +UNION +(SELECT a, b, 'AAA' || c FROM async_p2 WHERE b < 10); + +SELECT * FROM result_tbl ORDER BY a; +DELETE FROM result_tbl; + +EXPLAIN (VERBOSE, COSTS OFF) +INSERT INTO result_tbl +(SELECT a, b, 'AAA' || c FROM async_p1 ORDER BY a LIMIT 10) +UNION ALL +(SELECT a, b, 'AAA' || c FROM async_p2 WHERE b < 10); +INSERT INTO result_tbl +(SELECT a, b, 'AAA' || c FROM async_p1 ORDER BY a LIMIT 10) +UNION ALL +(SELECT a, b, 'AAA' || c FROM async_p2 WHERE b < 10); + +SELECT * FROM result_tbl ORDER BY a; +DELETE FROM result_tbl; + +-- Disable async execution if we use gating Result nodes for pseudoconstant +-- quals +EXPLAIN (VERBOSE, COSTS OFF) +SELECT * FROM async_pt WHERE CURRENT_USER = SESSION_USER; + +EXPLAIN (VERBOSE, COSTS OFF) +(SELECT * FROM async_p1 WHERE CURRENT_USER = SESSION_USER) +UNION ALL +(SELECT * FROM async_p2 WHERE CURRENT_USER = SESSION_USER); + +EXPLAIN (VERBOSE, COSTS OFF) +SELECT * FROM ((SELECT * FROM async_p1 WHERE b < 10) UNION ALL (SELECT * FROM async_p2 WHERE b < 10)) s WHERE CURRENT_USER = SESSION_USER; + +-- Test that pending requests are processed properly +SET enable_mergejoin TO false; +SET enable_hashjoin TO false; + +EXPLAIN (VERBOSE, COSTS OFF) +SELECT * FROM async_pt t1, async_p2 t2 WHERE t1.a = t2.a AND t1.b === 505; +SELECT * FROM async_pt t1, async_p2 t2 WHERE t1.a = t2.a AND t1.b === 505; + +CREATE TABLE local_tbl (a int, b int, c text); +INSERT INTO local_tbl VALUES (1505, 505, 'foo'); +ANALYZE local_tbl; + +EXPLAIN (VERBOSE, COSTS OFF) +SELECT * FROM local_tbl t1 LEFT JOIN (SELECT *, (SELECT count(*) FROM async_pt WHERE a < 3000) FROM async_pt WHERE a < 3000) t2 ON t1.a = t2.a; +EXPLAIN (ANALYZE, COSTS OFF, SUMMARY OFF, TIMING OFF) +SELECT * FROM local_tbl t1 LEFT JOIN (SELECT *, (SELECT count(*) FROM async_pt WHERE a < 3000) FROM async_pt WHERE a < 3000) t2 ON t1.a = t2.a; +SELECT * FROM local_tbl t1 LEFT JOIN (SELECT *, (SELECT count(*) FROM async_pt WHERE a < 3000) FROM async_pt WHERE a < 3000) t2 ON t1.a = t2.a; + +EXPLAIN (VERBOSE, COSTS OFF) +SELECT * FROM async_pt t1 WHERE t1.b === 505 LIMIT 1; +EXPLAIN (ANALYZE, COSTS OFF, SUMMARY OFF, TIMING OFF) +SELECT * FROM async_pt t1 WHERE t1.b === 505 LIMIT 1; +SELECT * FROM async_pt t1 WHERE t1.b === 505 LIMIT 1; + +-- Check with foreign modify +CREATE TABLE base_tbl3 (a int, b int, c text); +CREATE FOREIGN TABLE remote_tbl (a int, b int, c text) + SERVER loopback OPTIONS (table_name 'base_tbl3'); +INSERT INTO remote_tbl VALUES (2505, 505, 'bar'); + +CREATE TABLE base_tbl4 (a int, b int, c text); +CREATE FOREIGN TABLE insert_tbl (a int, b int, c text) + SERVER loopback OPTIONS (table_name 'base_tbl4'); + +EXPLAIN (VERBOSE, COSTS OFF) +INSERT INTO insert_tbl (SELECT * FROM local_tbl UNION ALL SELECT * FROM remote_tbl); +INSERT INTO insert_tbl (SELECT * FROM local_tbl UNION ALL SELECT * FROM remote_tbl); + +SELECT * FROM insert_tbl ORDER BY a; + +-- Check with direct modify +EXPLAIN (VERBOSE, COSTS OFF) +WITH t AS (UPDATE remote_tbl SET c = c || c RETURNING *) +INSERT INTO join_tbl SELECT * FROM async_pt LEFT JOIN t ON (async_pt.a = t.a AND async_pt.b = t.b) WHERE async_pt.b === 505; +WITH t AS (UPDATE remote_tbl SET c = c || c RETURNING *) +INSERT INTO join_tbl SELECT * FROM async_pt LEFT JOIN t ON (async_pt.a = t.a AND async_pt.b = t.b) WHERE async_pt.b === 505; + +SELECT * FROM join_tbl ORDER BY a1; +DELETE FROM join_tbl; + +DROP TABLE local_tbl; +DROP FOREIGN TABLE remote_tbl; +DROP FOREIGN TABLE insert_tbl; +DROP TABLE base_tbl3; +DROP TABLE base_tbl4; + +RESET enable_mergejoin; +RESET enable_hashjoin; + +-- Test that UPDATE/DELETE with inherited target works with async_capable enabled +EXPLAIN (VERBOSE, COSTS OFF) +UPDATE async_pt SET c = c || c WHERE b = 0 RETURNING *; +UPDATE async_pt SET c = c || c WHERE b = 0 RETURNING *; +EXPLAIN (VERBOSE, COSTS OFF) +DELETE FROM async_pt WHERE b = 0 RETURNING *; +DELETE FROM async_pt WHERE b = 0 RETURNING *; + +-- Check EXPLAIN ANALYZE for a query that scans empty partitions asynchronously +DELETE FROM async_p1; +DELETE FROM async_p2; +DELETE FROM async_p3; + +EXPLAIN (ANALYZE, COSTS OFF, SUMMARY OFF, TIMING OFF) +SELECT * FROM async_pt; + +-- Clean up +DROP TABLE async_pt; +DROP TABLE base_tbl1; +DROP TABLE base_tbl2; +DROP TABLE result_tbl; +DROP TABLE join_tbl; + +-- Test that an asynchronous fetch is processed before restarting the scan in +-- ReScanForeignScan +CREATE TABLE base_tbl (a int, b int); +INSERT INTO base_tbl VALUES (1, 11), (2, 22), (3, 33); +CREATE FOREIGN TABLE foreign_tbl (b int) + SERVER loopback OPTIONS (table_name 'base_tbl'); +CREATE FOREIGN TABLE foreign_tbl2 () INHERITS (foreign_tbl) + SERVER loopback OPTIONS (table_name 'base_tbl'); + +EXPLAIN (VERBOSE, COSTS OFF) +SELECT a FROM base_tbl WHERE a IN (SELECT a FROM foreign_tbl); +SELECT a FROM base_tbl WHERE a IN (SELECT a FROM foreign_tbl); + +-- Clean up +DROP FOREIGN TABLE foreign_tbl CASCADE; +DROP TABLE base_tbl; + +ALTER SERVER loopback OPTIONS (DROP async_capable); +ALTER SERVER loopback2 OPTIONS (DROP async_capable); +*/ +-- =================================================================== +-- test invalid server, foreign table and foreign data wrapper options +-- =================================================================== +/* +-- InfluxDB FDW does not have these options +-- Invalid fdw_startup_cost option +CREATE SERVER inv_scst FOREIGN DATA WRAPPER postgres_fdw + OPTIONS(fdw_startup_cost '100$%$#$#'); +-- Invalid fdw_tuple_cost option +CREATE SERVER inv_scst FOREIGN DATA WRAPPER postgres_fdw + OPTIONS(fdw_tuple_cost '100$%$#$#'); +-- Invalid fetch_size option +CREATE FOREIGN TABLE inv_fsz (c1 int ) + SERVER loopback OPTIONS (fetch_size '100$%$#$#'); +*/ +-- Invalid batch_size option +--Testcase 776: +CREATE FOREIGN TABLE inv_bsz (c1 int ) + SERVER influxdb_svr OPTIONS (batch_size '100$%$#$#'); +ERROR: invalid value for integer option "batch_size": 100$%$#$# +-- No option is allowed to be specified at foreign data wrapper level +--Testcase 782: +ALTER FOREIGN DATA WRAPPER influxdb_fdw OPTIONS (nonexistent 'fdw'); +ERROR: invalid option "nonexistent" +HINT: There are no valid options in this context. +/* +-- =================================================================== +-- application_name is an option in libpq of postgres +-- so Influxdb_fdw not support application_name. +-- test postgres_fdw.application_name GUC +-- =================================================================== +-- To avoid race conditions in checking the remote session's application_name, +-- use this view to make the remote session itself read its application_name. +CREATE VIEW my_application_name AS + SELECT application_name FROM pg_stat_activity WHERE pid = pg_backend_pid(); + +CREATE FOREIGN TABLE remote_application_name (application_name text) + SERVER loopback2 + OPTIONS (schema_name 'public', table_name 'my_application_name'); + +SELECT count(*) FROM remote_application_name; + +-- Specify escape sequences in application_name option of a server +-- object so as to test that they are replaced with status information +-- expectedly. Note that we are also relying on ALTER SERVER to force +-- the remote session to be restarted with its new application name. +-- +-- Since pg_stat_activity.application_name may be truncated to less than +-- NAMEDATALEN characters, note that substring() needs to be used +-- at the condition of test query to make sure that the string consisting +-- of database name and process ID is also less than that. +ALTER SERVER loopback2 OPTIONS (application_name 'fdw_%d%p'); +SELECT count(*) FROM remote_application_name + WHERE application_name = + substring('fdw_' || current_database() || pg_backend_pid() for + current_setting('max_identifier_length')::int); + +-- postgres_fdw.application_name overrides application_name option +-- of a server object if both settings are present. +ALTER SERVER loopback2 OPTIONS (SET application_name 'fdw_wrong'); +SET postgres_fdw.application_name TO 'fdw_%a%u%%'; +SELECT count(*) FROM remote_application_name + WHERE application_name = + substring('fdw_' || current_setting('application_name') || + CURRENT_USER || '%' for current_setting('max_identifier_length')::int); +RESET postgres_fdw.application_name; + +-- Test %c (session ID) and %C (cluster name) escape sequences. +ALTER SERVER loopback2 OPTIONS (SET application_name 'fdw_%C%c'); +SELECT count(*) FROM remote_application_name + WHERE application_name = + substring('fdw_' || current_setting('cluster_name') || + to_hex(trunc(EXTRACT(EPOCH FROM (SELECT backend_start FROM + pg_stat_get_activity(pg_backend_pid()))))::integer) || '.' || + to_hex(pg_backend_pid()) + for current_setting('max_identifier_length')::int); + +-- Clean up. +DROP FOREIGN TABLE remote_application_name; +DROP VIEW my_application_name; + +-- =================================================================== +-- test parallel commit and parallel abort +-- =================================================================== +ALTER SERVER loopback OPTIONS (ADD parallel_commit 'true'); +ALTER SERVER loopback OPTIONS (ADD parallel_abort 'true'); +ALTER SERVER loopback2 OPTIONS (ADD parallel_commit 'true'); +ALTER SERVER loopback2 OPTIONS (ADD parallel_abort 'true'); + +CREATE TABLE ploc1 (f1 int, f2 text); +CREATE FOREIGN TABLE prem1 (f1 int, f2 text) + SERVER loopback OPTIONS (table_name 'ploc1'); +CREATE TABLE ploc2 (f1 int, f2 text); +CREATE FOREIGN TABLE prem2 (f1 int, f2 text) + SERVER loopback2 OPTIONS (table_name 'ploc2'); + +BEGIN; +INSERT INTO prem1 VALUES (101, 'foo'); +INSERT INTO prem2 VALUES (201, 'bar'); +COMMIT; +SELECT * FROM prem1; +SELECT * FROM prem2; + +BEGIN; +SAVEPOINT s; +INSERT INTO prem1 VALUES (102, 'foofoo'); +INSERT INTO prem2 VALUES (202, 'barbar'); +RELEASE SAVEPOINT s; +COMMIT; +SELECT * FROM prem1; +SELECT * FROM prem2; + +-- This tests executing DEALLOCATE ALL against foreign servers in parallel +-- during pre-commit +BEGIN; +SAVEPOINT s; +INSERT INTO prem1 VALUES (103, 'baz'); +INSERT INTO prem2 VALUES (203, 'qux'); +ROLLBACK TO SAVEPOINT s; +RELEASE SAVEPOINT s; +INSERT INTO prem1 VALUES (104, 'bazbaz'); +INSERT INTO prem2 VALUES (204, 'quxqux'); +COMMIT; +SELECT * FROM prem1; +SELECT * FROM prem2; + +BEGIN; +INSERT INTO prem1 VALUES (105, 'test1'); +INSERT INTO prem2 VALUES (205, 'test2'); +ABORT; +SELECT * FROM prem1; +SELECT * FROM prem2; + +-- This tests executing DEALLOCATE ALL against foreign servers in parallel +-- during post-abort +BEGIN; +SAVEPOINT s; +INSERT INTO prem1 VALUES (105, 'test1'); +INSERT INTO prem2 VALUES (205, 'test2'); +ROLLBACK TO SAVEPOINT s; +RELEASE SAVEPOINT s; +INSERT INTO prem1 VALUES (105, 'test1'); +INSERT INTO prem2 VALUES (205, 'test2'); +ABORT; +SELECT * FROM prem1; +SELECT * FROM prem2; + +ALTER SERVER loopback OPTIONS (DROP parallel_commit); +ALTER SERVER loopback OPTIONS (DROP parallel_abort); +ALTER SERVER loopback2 OPTIONS (DROP parallel_commit); +ALTER SERVER loopback2 OPTIONS (DROP parallel_abort); + +-- =================================================================== +-- test for ANALYZE sampling +-- =================================================================== + +CREATE TABLE analyze_table (id int, a text, b bigint); + +CREATE FOREIGN TABLE analyze_ftable (id int, a text, b bigint) + SERVER loopback OPTIONS (table_name 'analyze_rtable1'); + +INSERT INTO analyze_table (SELECT x FROM generate_series(1,1000) x); +ANALYZE analyze_table; + +SET default_statistics_target = 10; +ANALYZE analyze_table; + +ALTER SERVER loopback OPTIONS (analyze_sampling 'invalid'); + +ALTER SERVER loopback OPTIONS (analyze_sampling 'auto'); +ANALYZE analyze_table; + +ALTER SERVER loopback OPTIONS (SET analyze_sampling 'system'); +ANALYZE analyze_table; + +ALTER SERVER loopback OPTIONS (SET analyze_sampling 'bernoulli'); +ANALYZE analyze_table; + +ALTER SERVER loopback OPTIONS (SET analyze_sampling 'random'); +ANALYZE analyze_table; + +ALTER SERVER loopback OPTIONS (SET analyze_sampling 'off'); +ANALYZE analyze_table; + +-- cleanup +DROP FOREIGN TABLE analyze_ftable; +DROP TABLE analyze_table; +*/ +-- Clean-up +--Testcase 786: +delete from ft1; +--Testcase 787: +delete from ft2; +--Testcase 788: +delete from ft4; +--Testcase 789: +delete from ft5; +--Testcase 790: +delete from foo; +--Testcase 791: +delete from bar; +--Testcase 792: +delete from loct1; +--Testcase 793: +delete from loct2; +--Testcase 794: +delete from rem1; +--Testcase 795: +drop foreign table foo cascade; +NOTICE: drop cascades to foreign table foo2 +--Testcase 796: +drop foreign table bar cascade; +NOTICE: drop cascades to foreign table bar2 +--Testcase 797: +drop foreign table loct1; +--Testcase 798: +drop foreign table loct2; +--Testcase 799: +drop foreign table ft1; +--Testcase 800: +drop foreign table ft2; +--Testcase 801: +drop foreign table ft4; +--Testcase 802: +drop foreign table ft5; +--Testcase 803: +DROP TYPE IF EXISTS user_enum; +--Testcase 804: +DROP SCHEMA IF EXISTS "S 1" CASCADE; +NOTICE: drop cascades to 6 other objects +DETAIL: drop cascades to foreign table "S 1"."T 0" +drop cascades to foreign table "S 1"."T 1" +drop cascades to foreign table "S 1"."T 2" +drop cascades to foreign table "S 1"."T 3" +drop cascades to foreign table "S 1"."T 4" +drop cascades to function "S 1".f_brtrig() +--Testcase 805: +DROP FUNCTION IF EXISTS trigger_func(); +--Testcase 806: +DROP FUNCTION IF EXISTS trig_row_before_insupdate(); +--Testcase 807: +DROP FUNCTION IF EXISTS trig_null(); +--Testcase 808: +DROP SCHEMA IF EXISTS import_influx1 CASCADE; +NOTICE: drop cascades to 9 other objects +DETAIL: drop cascades to foreign table import_influx1."T1" +drop cascades to foreign table import_influx1."T2" +drop cascades to foreign table import_influx1."T3" +drop cascades to foreign table import_influx1."T4" +drop cascades to foreign table import_influx1.bar +drop cascades to foreign table import_influx1.foo +drop cascades to foreign table import_influx1.loc1 +drop cascades to foreign table import_influx1.loct1 +drop cascades to foreign table import_influx1.loct2 +--Testcase 809: +DROP SCHEMA IF EXISTS import_influx2 CASCADE; +--Testcase 810: +DROP SCHEMA IF EXISTS import_influx3 CASCADE; +--Testcase 811: +DROP SCHEMA IF EXISTS import_influx4 CASCADE; +NOTICE: drop cascades to 9 other objects +DETAIL: drop cascades to foreign table import_influx4."T1" +drop cascades to foreign table import_influx4."T2" +drop cascades to foreign table import_influx4."T3" +drop cascades to foreign table import_influx4."T4" +drop cascades to foreign table import_influx4.bar +drop cascades to foreign table import_influx4.foo +drop cascades to foreign table import_influx4.loc1 +drop cascades to foreign table import_influx4.loct1 +drop cascades to foreign table import_influx4.loct2 +--Testcase 758: +DROP USER MAPPING FOR public SERVER testserver1; +--Testcase 759: +DROP USER MAPPING FOR CURRENT_USER SERVER influxdb_svr; +--Testcase 760: +DROP USER MAPPING FOR CURRENT_USER SERVER influxdb_svr2; +--Testcase 761: +DROP SERVER testserver1 CASCADE; +--Testcase 762: +DROP SERVER influxdb_svr CASCADE; +NOTICE: drop cascades to 8 other objects +DETAIL: drop cascades to foreign table loct_empty +drop cascades to foreign table ft_empty +drop cascades to foreign table loct3 +drop cascades to foreign table ft3 +drop cascades to foreign table loc1 +drop cascades to foreign table rem1 +drop cascades to foreign table gloc1 +drop cascades to foreign table grem1 +--Testcase 763: +DROP SERVER influxdb_svr2 CASCADE; +NOTICE: drop cascades to foreign table ft6 +--Testcase 764: +DROP EXTENSION influxdb_fdw CASCADE; diff --git a/expected/14.5/extra/insert.out b/expected/16.0/extra/insert.out similarity index 97% rename from expected/14.5/extra/insert.out rename to expected/16.0/extra/insert.out index 72490a2..2c77781 100644 --- a/expected/14.5/extra/insert.out +++ b/expected/16.0/extra/insert.out @@ -105,7 +105,9 @@ select col1, col2, char_length(col3) from inserttest; --Testcase 20: -- Clean up: +--Testcase 24: delete from inserttest; +--Testcase 25: drop foreign table inserttest; /* -- skip, influxdb does not support create table with WITH option @@ -326,33 +328,6 @@ select tableoid::regclass::text, a, min(b) as min_b, max(b) as max_b from list_p -- direct partition inserts should check hash partition bound constraint --- 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 or replace function part_hashint4_noop(value int4, seed int8) -returns int8 as $$ -select value + seed; -$$ language sql immutable; - -create operator class part_test_int4_ops -for type int4 -using hash as -operator 1 =, -function 2 part_hashint4_noop(int4, int8); - -create or replace function part_hashtext_length(value text, seed int8) -RETURNS int8 AS $$ -select length(coalesce(value, ''))::int8 -$$ language sql immutable; - -create operator class part_test_text_ops -for type text -using hash as -operator 1 =, -function 2 part_hashtext_length(text, int8); - create table hash_parted ( a int ) partition by hash (a part_test_int4_ops); diff --git a/expected/11.17/extra/join.out b/expected/16.0/extra/join.out similarity index 80% rename from expected/11.17/extra/join.out rename to expected/16.0/extra/join.out index c7e1b2e..996e893 100644 --- a/expected/11.17/extra/join.out +++ b/expected/16.0/extra/join.out @@ -63,6 +63,24 @@ INSERT INTO J2_TBL VALUES (0, NULL); --INSERT INTO J2_TBL VALUES (NULL, NULL); --Testcase 24: INSERT INTO J2_TBL VALUES (NULL, 0); +CREATE FOREIGN 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 +) SERVER influxdb_svr; --Testcase 25: CREATE FOREIGN TABLE tenk1 ( unique1 int4, @@ -1440,11 +1458,73 @@ SELECT * 4 | 1 | one | 2 (4 rows) +-- test join using aliases +--Testcase 49: +SELECT * FROM J1_TBL JOIN J2_TBL USING (i) WHERE J1_TBL.t = 'one'; -- ok + i | j | t | k +---+---+-----+---- + 1 | 4 | one | -1 +(1 row) + +--Testcase 50: +SELECT * FROM J1_TBL JOIN J2_TBL USING (i) AS x WHERE J1_TBL.t = 'one'; -- ok + i | j | t | k +---+---+-----+---- + 1 | 4 | one | -1 +(1 row) + +--Testcase 51: +SELECT * FROM (J1_TBL JOIN J2_TBL USING (i)) AS x WHERE J1_TBL.t = 'one'; -- error +ERROR: invalid reference to FROM-clause entry for table "j1_tbl" +LINE 1: ... * FROM (J1_TBL JOIN J2_TBL USING (i)) AS x WHERE J1_TBL.t =... + ^ +DETAIL: There is an entry for table "j1_tbl", but it cannot be referenced from this part of the query. +--Testcase 52: +SELECT * FROM J1_TBL JOIN J2_TBL USING (i) AS x WHERE x.i = 1; -- ok + i | j | t | k +---+---+-----+---- + 1 | 4 | one | -1 +(1 row) + +--Testcase 53: +SELECT * FROM J1_TBL JOIN J2_TBL USING (i) AS x WHERE x.t = 'one'; -- error +ERROR: column x.t does not exist +LINE 1: ...CT * FROM J1_TBL JOIN J2_TBL USING (i) AS x WHERE x.t = 'one... + ^ +--Testcase 54: +SELECT * FROM (J1_TBL JOIN J2_TBL USING (i) AS x) AS xx WHERE x.i = 1; -- error (XXX could use better hint) +ERROR: missing FROM-clause entry for table "x" +LINE 1: ...ROM (J1_TBL JOIN J2_TBL USING (i) AS x) AS xx WHERE x.i = 1; + ^ +--Testcase 55: +SELECT * FROM J1_TBL a1 JOIN J2_TBL a2 USING (i) AS a1; -- error +ERROR: table name "a1" specified more than once +--Testcase 56: +SELECT x.* FROM J1_TBL JOIN J2_TBL USING (i) AS x WHERE J1_TBL.t = 'one'; + i +--- + 1 +(1 row) + +--Testcase 57: +SELECT ROW(x.*) FROM J1_TBL JOIN J2_TBL USING (i) AS x WHERE J1_TBL.t = 'one'; + row +----- + (1) +(1 row) + +--Testcase 58: +SELECT row_to_json(x.*) FROM J1_TBL JOIN J2_TBL USING (i) AS x WHERE J1_TBL.t = 'one'; + row_to_json +------------- + {"i":1} +(1 row) + -- -- NATURAL JOIN -- Inner equi-join on all columns with the same name -- ---Testcase 49: +--Testcase 59: SELECT * FROM J1_TBL NATURAL JOIN J2_TBL; i | j | t | k @@ -1458,7 +1538,7 @@ SELECT * 5 | 0 | five | -5 (7 rows) ---Testcase 50: +--Testcase 60: SELECT * FROM J1_TBL t1 (a, b, c) NATURAL JOIN J2_TBL t2 (a, d); a | b | c | d @@ -1472,7 +1552,7 @@ SELECT * 5 | 0 | five | -5 (7 rows) ---Testcase 51: +--Testcase 61: SELECT * FROM J1_TBL t1 (a, b, c) NATURAL JOIN J2_TBL t2 (d, a); a | b | c | d @@ -1484,7 +1564,7 @@ SELECT * -- mismatch number of columns -- currently, Postgres will fill in with underlying names ---Testcase 52: +--Testcase 62: SELECT * FROM J1_TBL t1 (a, b) NATURAL JOIN J2_TBL t2 (a); a | b | t | k @@ -1501,7 +1581,7 @@ SELECT * -- -- Inner joins (equi-joins) -- ---Testcase 53: +--Testcase 63: SELECT * FROM J1_TBL JOIN J2_TBL ON (J1_TBL.i = J2_TBL.i); i | j | t | i | k @@ -1515,7 +1595,7 @@ SELECT * 5 | 0 | five | 5 | -5 (7 rows) ---Testcase 54: +--Testcase 64: SELECT * FROM J1_TBL JOIN J2_TBL ON (J1_TBL.i = J2_TBL.k); i | j | t | i | k @@ -1528,7 +1608,7 @@ SELECT * -- -- Non-equi-joins -- ---Testcase 55: +--Testcase 65: SELECT * FROM J1_TBL JOIN J2_TBL ON (J1_TBL.i <= J2_TBL.k); i | j | t | i | k @@ -1548,7 +1628,7 @@ SELECT * -- Outer joins -- Note that OUTER is a noise word -- ---Testcase 56: +--Testcase 66: SELECT * FROM J1_TBL LEFT OUTER JOIN J2_TBL USING (i) ORDER BY i, k, t; @@ -1569,7 +1649,7 @@ SELECT * | 0 | zero | (13 rows) ---Testcase 57: +--Testcase 67: SELECT * FROM J1_TBL LEFT JOIN J2_TBL USING (i) ORDER BY i, k, t; @@ -1590,7 +1670,7 @@ SELECT * | 0 | zero | (13 rows) ---Testcase 58: +--Testcase 68: SELECT * FROM J1_TBL RIGHT OUTER JOIN J2_TBL USING (i); i | j | t | k @@ -1605,7 +1685,7 @@ SELECT * | | | 0 (8 rows) ---Testcase 59: +--Testcase 69: SELECT * FROM J1_TBL RIGHT JOIN J2_TBL USING (i); i | j | t | k @@ -1620,7 +1700,7 @@ SELECT * | | | 0 (8 rows) ---Testcase 60: +--Testcase 70: SELECT * FROM J1_TBL FULL OUTER JOIN J2_TBL USING (i) ORDER BY i, k, t; @@ -1642,7 +1722,7 @@ SELECT * | 0 | zero | (14 rows) ---Testcase 61: +--Testcase 71: SELECT * FROM J1_TBL FULL JOIN J2_TBL USING (i) ORDER BY i, k, t; @@ -1664,14 +1744,14 @@ SELECT * | 0 | zero | (14 rows) ---Testcase 62: +--Testcase 72: SELECT * FROM J1_TBL LEFT JOIN J2_TBL USING (i) WHERE (k = 1); i | j | t | k ---+---+---+--- (0 rows) ---Testcase 63: +--Testcase 73: SELECT * FROM J1_TBL LEFT JOIN J2_TBL USING (i) WHERE (i = 1); i | j | t | k @@ -1682,7 +1762,7 @@ SELECT * -- -- semijoin selectivity for <> -- ---Testcase 64: +--Testcase 74: explain (costs off) select * from int4_tbl i4, tenk1 a where exists(select * from tenk1 b @@ -1708,27 +1788,27 @@ where exists(select * from tenk1 b -- -- Multiway full join -- ---Testcase 65: +--Testcase 75: CREATE FOREIGN TABLE t1 (name TEXT, n INTEGER) SERVER influxdb_svr; ---Testcase 66: +--Testcase 76: CREATE FOREIGN TABLE t2 (name TEXT, n INTEGER) SERVER influxdb_svr; ---Testcase 67: +--Testcase 77: CREATE FOREIGN TABLE t3 (name TEXT, n INTEGER) SERVER influxdb_svr; ---Testcase 68: +--Testcase 78: INSERT INTO t1 VALUES ( 'bb', 11 ); ---Testcase 69: +--Testcase 79: INSERT INTO t2 VALUES ( 'bb', 12 ); ---Testcase 70: +--Testcase 80: INSERT INTO t2 VALUES ( 'cc', 22 ); ---Testcase 71: +--Testcase 81: INSERT INTO t2 VALUES ( 'ee', 42 ); ---Testcase 72: +--Testcase 82: INSERT INTO t3 VALUES ( 'bb', 13 ); ---Testcase 73: +--Testcase 83: INSERT INTO t3 VALUES ( 'cc', 23 ); ---Testcase 74: +--Testcase 84: INSERT INTO t3 VALUES ( 'dd', 33 ); ---Testcase 75: +--Testcase 85: SELECT * FROM t1 FULL JOIN t2 USING (name) FULL JOIN t3 USING (name); name | n | n | n ------+----+----+---- @@ -1742,7 +1822,7 @@ SELECT * FROM t1 FULL JOIN t2 USING (name) FULL JOIN t3 USING (name); -- Test interactions of join syntax and subqueries -- -- Basic cases (we expect planner to pull up the subquery here) ---Testcase 76: +--Testcase 86: SELECT * FROM (SELECT * FROM t2) as s2 INNER JOIN @@ -1754,7 +1834,7 @@ USING (name); cc | 22 | 23 (2 rows) ---Testcase 77: +--Testcase 87: SELECT * FROM (SELECT * FROM t2) as s2 LEFT JOIN @@ -1767,7 +1847,7 @@ USING (name); ee | 42 | (3 rows) ---Testcase 78: +--Testcase 88: SELECT * FROM (SELECT * FROM t2) as s2 FULL JOIN @@ -1783,7 +1863,7 @@ USING (name); -- Cases with non-nullable expressions in subquery results; -- make sure these go to null as expected ---Testcase 79: +--Testcase 89: SELECT * FROM (SELECT name, n as s2_n, 2 as s2_2 FROM t2) as s2 NATURAL INNER JOIN @@ -1794,7 +1874,7 @@ NATURAL INNER JOIN cc | 22 | 2 | 23 | 3 (2 rows) ---Testcase 80: +--Testcase 90: SELECT * FROM (SELECT name, n as s2_n, 2 as s2_2 FROM t2) as s2 NATURAL LEFT JOIN @@ -1806,7 +1886,7 @@ NATURAL LEFT JOIN ee | 42 | 2 | | (3 rows) ---Testcase 81: +--Testcase 91: SELECT * FROM (SELECT name, n as s2_n, 2 as s2_2 FROM t2) as s2 NATURAL FULL JOIN @@ -1819,7 +1899,7 @@ NATURAL FULL JOIN ee | 42 | 2 | | (4 rows) ---Testcase 82: +--Testcase 92: SELECT * FROM (SELECT name, n as s1_n, 1 as s1_1 FROM t1) as s1 NATURAL INNER JOIN @@ -1831,7 +1911,7 @@ NATURAL INNER JOIN bb | 11 | 1 | 12 | 2 | 13 | 3 (1 row) ---Testcase 83: +--Testcase 93: SELECT * FROM (SELECT name, n as s1_n, 1 as s1_1 FROM t1) as s1 NATURAL FULL JOIN @@ -1846,7 +1926,7 @@ NATURAL FULL JOIN ee | | | 42 | 2 | | (4 rows) ---Testcase 84: +--Testcase 94: SELECT * FROM (SELECT name, n as s1_n FROM t1) as s1 NATURAL FULL JOIN @@ -1863,7 +1943,7 @@ NATURAL FULL JOIN ee | | 42 | (4 rows) ---Testcase 85: +--Testcase 95: SELECT * FROM (SELECT name, n as s1_n FROM t1) as s1 NATURAL FULL JOIN @@ -1881,37 +1961,44 @@ NATURAL FULL JOIN (4 rows) -- Constants as join keys can also be problematic ---Testcase 86: +--Testcase 96: 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); -ERROR: FULL JOIN is only supported with merge-joinable or hash-joinable join conditions + name | s1_n | name | s2_n +------+------+------+------ + | | bb | 2 + | | cc | 2 + | | ee | 2 + bb | 11 | | +(4 rows) + -- Test for propagation of nullability constraints into sub-joins ---Testcase 87: +--Testcase 97: create foreign table x (x1 int, x2 int) server influxdb_svr; ---Testcase 88: +--Testcase 98: insert into x values (1,11); ---Testcase 89: +--Testcase 99: insert into x values (2,22); ---Testcase 90: +--Testcase 100: insert into x values (3,null); ---Testcase 91: +--Testcase 101: insert into x values (4,44); ---Testcase 92: +--Testcase 102: insert into x values (5,null); ---Testcase 93: +--Testcase 103: create foreign table y (y1 int, y2 int) server influxdb_svr; ---Testcase 94: +--Testcase 104: insert into y values (1,111); ---Testcase 95: +--Testcase 105: insert into y values (2,222); ---Testcase 96: +--Testcase 106: insert into y values (3,333); ---Testcase 97: +--Testcase 107: insert into y values (4,null); ---Testcase 98: +--Testcase 108: select * from x; x1 | x2 ----+---- @@ -1922,7 +2009,7 @@ select * from x; 5 | (5 rows) ---Testcase 99: +--Testcase 109: select * from y; y1 | y2 ----+----- @@ -1932,7 +2019,7 @@ select * from y; 4 | (4 rows) ---Testcase 100: +--Testcase 110: select * from x left join y on (x1 = y1 and x2 is not null); x1 | x2 | y1 | y2 ----+----+----+----- @@ -1943,7 +2030,7 @@ select * from x left join y on (x1 = y1 and x2 is not null); 5 | | | (5 rows) ---Testcase 101: +--Testcase 111: select * from x left join y on (x1 = y1 and y2 is not null); x1 | x2 | y1 | y2 ----+----+----+----- @@ -1954,7 +2041,7 @@ select * from x left join y on (x1 = y1 and y2 is not null); 5 | | | (5 rows) ---Testcase 102: +--Testcase 112: select * from (x left join y on (x1 = y1)) left join x xx(xx1,xx2) on (x1 = xx1); x1 | x2 | y1 | y2 | xx1 | xx2 @@ -1966,7 +2053,7 @@ on (x1 = xx1); 5 | | | | 5 | (5 rows) ---Testcase 103: +--Testcase 113: select * from (x left join y on (x1 = y1)) left join x xx(xx1,xx2) on (x1 = xx1 and x2 is not null); x1 | x2 | y1 | y2 | xx1 | xx2 @@ -1978,7 +2065,7 @@ on (x1 = xx1 and x2 is not null); 5 | | | | | (5 rows) ---Testcase 104: +--Testcase 114: select * from (x left join y on (x1 = y1)) left join x xx(xx1,xx2) on (x1 = xx1 and y2 is not null); x1 | x2 | y1 | y2 | xx1 | xx2 @@ -1990,7 +2077,7 @@ on (x1 = xx1 and y2 is not null); 5 | | | | | (5 rows) ---Testcase 105: +--Testcase 115: select * from (x left join y on (x1 = y1)) left join x xx(xx1,xx2) on (x1 = xx1 and xx2 is not null); x1 | x2 | y1 | y2 | xx1 | xx2 @@ -2003,7 +2090,7 @@ on (x1 = xx1 and xx2 is not null); (5 rows) -- these should NOT give the same answers as above ---Testcase 106: +--Testcase 116: select * from (x left join y on (x1 = y1)) left join x xx(xx1,xx2) on (x1 = xx1) where (x2 is not null); x1 | x2 | y1 | y2 | xx1 | xx2 @@ -2013,7 +2100,7 @@ on (x1 = xx1) where (x2 is not null); 4 | 44 | 4 | | 4 | 44 (3 rows) ---Testcase 107: +--Testcase 117: select * from (x left join y on (x1 = y1)) left join x xx(xx1,xx2) on (x1 = xx1) where (y2 is not null); x1 | x2 | y1 | y2 | xx1 | xx2 @@ -2023,7 +2110,7 @@ on (x1 = xx1) where (y2 is not null); 3 | | 3 | 333 | 3 | (3 rows) ---Testcase 108: +--Testcase 118: select * from (x left join y on (x1 = y1)) left join x xx(xx1,xx2) on (x1 = xx1) where (xx2 is not null); x1 | x2 | y1 | y2 | xx1 | xx2 @@ -2037,7 +2124,7 @@ on (x1 = xx1) where (xx2 is not null); -- regression test: check for bug with propagation of implied equality -- to outside an IN -- ---Testcase 109: +--Testcase 119: select count(*) from tenk1 a where unique1 in (select unique1 from tenk1 b join tenk1 c using (unique1) where b.unique2 = 42); @@ -2050,7 +2137,7 @@ select count(*) from tenk1 a where unique1 in -- regression test: check for failure to generate a plan with multiple -- degenerate IN clauses -- ---Testcase 110: +--Testcase 120: 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 @@ -2062,11 +2149,11 @@ select count(*) from tenk1 x where -- try that with GEQO too begin; ---Testcase 111: +--Testcase 121: set geqo = on; ---Testcase 112: +--Testcase 122: set geqo_threshold = 2; ---Testcase 113: +--Testcase 123: 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 @@ -2080,57 +2167,53 @@ rollback; -- -- regression test: be sure we cope with proven-dummy append rels -- ---Testcase 114: -create table b (aa int, bb int); ---Testcase 115: +--Testcase 124: +CREATE FOREIGN TABLE b_star(class char, aa int4, bb text, a int4) SERVER influxdb_svr; +--Testcase 125: explain (costs off) select aa, bb, unique1, unique1 - from tenk1 right join b on aa = unique1 + from tenk1 right join b_star on aa = unique1 where bb < bb and bb is null; QUERY PLAN ---------------------------------------------------- Hash Right Join - Hash Cond: (tenk1.unique1 = b.aa) + Hash Cond: (tenk1.unique1 = b_star.aa) -> Foreign Scan on tenk1 -> Hash - -> Seq Scan on b + -> Foreign Scan on b_star Filter: ((bb IS NULL) AND (bb < bb)) (6 rows) ---Testcase 116: +--Testcase 126: select aa, bb, unique1, unique1 - from tenk1 right join b on aa = unique1 + from tenk1 right join b_star on aa = unique1 where bb < bb and bb is null; aa | bb | unique1 | unique1 ----+----+---------+--------- (0 rows) ---Testcase 117: -drop table b; +--Testcase 127: +drop foreign table b_star; -- -- regression test: check handling of empty-FROM subquery underneath outer join -- ---Testcase 118: +--Testcase 128: explain (costs off) select * from int8_tbl i1 left join (int8_tbl i2 join (select 123 as x) ss on i2.q1 = x) on i1.q2 = i2.q2 order by 1, 2; - QUERY PLAN ------------------------------------------------------ + QUERY PLAN +----------------------------------------------- Sort Sort Key: i1.q1, i1.q2 -> Hash Left Join Hash Cond: (i1.q2 = i2.q2) -> Foreign Scan on int8_tbl i1 -> Hash - -> Hash Join - Hash Cond: (i2.q1 = (123)) - -> Foreign Scan on int8_tbl i2 - -> Hash - -> Result -(11 rows) + -> Foreign Scan on int8_tbl i2 +(7 rows) ---Testcase 119: +--Testcase 129: 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; @@ -2144,10 +2227,10 @@ order by 1, 2; (5 rows) -- --- regression test: check a case where join_clause_is_movable_into() gives --- an imprecise result, causing an assertion failure +-- regression test: check a case where join_clause_is_movable_into() +-- used to give an imprecise result, causing an assertion failure -- ---Testcase 120: +--Testcase 130: select count(*) from (select t3.tenthous as x1, coalesce(t1.stringu1, t2.stringu1) as x2 @@ -2166,7 +2249,7 @@ where t4.thousand = t5.unique1 and ss.x1 = t4.tenthous and ss.x2 = t5.stringu1; -- regression test: check a case where we formerly missed including an EC -- enforcement clause because it was expected to be handled at scan level -- ---Testcase 121: +--Testcase 131: explain (costs off) select a.f1, b.f1, t.thousand, t.tenthous from tenk1 t, @@ -2187,7 +2270,7 @@ where b.f1 = t.thousand and a.f1 = b.f1 and (a.f1+b.f1+999) = t.tenthous; -> Foreign Scan (10 rows) ---Testcase 122: +--Testcase 132: select a.f1, b.f1, t.thousand, t.tenthous from tenk1 t, (select sum(f1)+1 as f1 from int4_tbl i4a) a, @@ -2198,46 +2281,380 @@ where b.f1 = t.thousand and a.f1 = b.f1 and (a.f1+b.f1+999) = t.tenthous; (0 rows) -- --- check a case where we formerly got confused by conflicting sort orders --- in redundant merge join path keys +-- checks for correct handling of quals in multiway outer joins -- ---Testcase 123: explain (costs off) -select * from - j1_tbl full join - (select * from j2_tbl order by j2_tbl.i desc, j2_tbl.k asc) j2_tbl - on j1_tbl.i = j2_tbl.i and j1_tbl.i = j2_tbl.k; - QUERY PLAN ------------------------------------------------------------------ - Merge Full Join - Merge Cond: ((j2_tbl.i = j1_tbl.i) AND (j2_tbl.k = j1_tbl.i)) - -> Sort - Sort Key: j2_tbl.i DESC, j2_tbl.k - -> Foreign Scan on j2_tbl - -> Sort - Sort Key: j1_tbl.i DESC - -> Foreign Scan on j1_tbl -(8 rows) +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; + QUERY PLAN +----------------------------------------------------------- + Nested Loop + -> Nested Loop Left Join + Filter: (t4.f1 IS NULL) + -> Foreign Scan on int4_tbl t2 + -> Materialize + -> Nested Loop Left Join + Join Filter: (t3.f1 > 1) + -> Foreign Scan on int4_tbl t3 + -> Materialize + -> Foreign Scan on int4_tbl t4 + -> Materialize + -> Foreign Scan on int4_tbl t1 +(12 rows) ---Testcase 124: -select * from - j1_tbl full join - (select * from j2_tbl order by j2_tbl.i desc, j2_tbl.k asc) j2_tbl - on j1_tbl.i = j2_tbl.i and j1_tbl.i = j2_tbl.k; - i | j | t | i | k ----+---+-------+---+---- - | | | | 0 - | 0 | zero | | - | | null | | - 8 | 8 | eight | | - 7 | 7 | seven | | - 6 | 6 | six | | - | | | 5 | -5 - | | | 5 | -5 - 5 | 0 | five | | - 4 | 1 | four | | - | | | 3 | -3 - 3 | 2 | three | | +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; + f1 +---- +(0 rows) + +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; + QUERY PLAN +----------------------------------------------------------- + Nested Loop Left Join + -> Foreign Scan on int4_tbl t1 + -> Materialize + -> Nested Loop Left Join + Join Filter: (t3.f1 > 0) + -> Nested Loop Left Join + Join Filter: (t2.f1 > 0) + -> Foreign Scan on int4_tbl t2 + -> Materialize + -> Foreign Scan on int4_tbl t3 + -> Materialize + -> Foreign Scan on int4_tbl t4 +(12 rows) + +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; + QUERY PLAN +---------------------------------------------------- + Nested Loop Left Join + Join Filter: (t2.unique1 <> t3.unique1) + -> Hash Left Join + Hash Cond: (t1.unique1 = t2.unique1) + -> Foreign Scan on onek t1 + -> Hash + -> Foreign Scan on onek t2 + -> Materialize + -> Hash Left Join + Hash Cond: (t3.unique1 = t4.unique1) + -> Foreign Scan on onek t3 + -> Hash + -> Foreign Scan on onek t4 +(13 rows) + +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; + QUERY PLAN +----------------------------------------------------------------------- + Nested Loop + -> Nested Loop Left Join + -> Foreign Scan on int4_tbl t1 + -> Materialize + -> Merge Left Join + Merge Cond: (t2.f1 = t3.f1) + -> Sort + Sort Key: t2.f1 + -> Foreign Scan on int4_tbl t2 + -> Materialize + -> Merge Left Join + Merge Cond: (t3.f1 = t4.f1) + -> Sort + Sort Key: t3.f1 + -> Foreign Scan on int4_tbl t3 + -> Sort + Sort Key: t4.f1 + -> Foreign Scan on int4_tbl t4 + -> Materialize + -> Foreign Scan on int4_tbl t5 +(20 rows) + +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; + QUERY PLAN +----------------------------------------------------- + Nested Loop Left Join + Join Filter: (t2.f1 = t3.f1) + -> Nested Loop Left Join + -> Nested Loop Left Join + -> Foreign Scan on int4_tbl t1 + -> Materialize + -> Foreign Scan on int4_tbl t2 + -> Materialize + -> Foreign Scan on int4_tbl t3 + -> Materialize + -> Foreign Scan on int4_tbl t4 +(11 rows) + +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; + QUERY PLAN +----------------------------------------------------------- + Nested Loop Left Join + -> Foreign Scan on int4_tbl t1 + -> Materialize + -> Nested Loop Left Join + Join Filter: (t3.f1 <> t4.f1) + -> Merge Left Join + Merge Cond: (t2.f1 = t3.f1) + -> Sort + Sort Key: t2.f1 + -> Foreign Scan on int4_tbl t2 + -> Sort + Sort Key: t3.f1 + -> Foreign Scan on int4_tbl t3 + -> Materialize + -> Foreign Scan on int4_tbl t4 +(15 rows) + +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); + QUERY PLAN +----------------------------------------------------- + Nested Loop Left Join + Join Filter: ((t2.f1 > 2) AND (t3.f1 > 3)) + -> Nested Loop Left Join + Join Filter: (t2.f1 > 0) + -> Nested Loop Left Join + Filter: (t1.f1 = COALESCE(t2.f1, 1)) + -> Foreign Scan on int4_tbl t1 + -> Materialize + -> Foreign Scan on int4_tbl t2 + -> Materialize + -> Foreign Scan on int4_tbl t3 + -> Materialize + -> Foreign Scan on int4_tbl t4 +(13 rows) + +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; + QUERY PLAN +----------------------------------------------------- + Hash Right Join + Hash Cond: (t2.f1 = t1.f1) + -> Nested Loop Left Join + Join Filter: (t2.f1 > 1) + -> Nested Loop Left Join + Join Filter: (t2.f1 > 0) + Filter: (t3.f1 IS NULL) + -> Foreign Scan on int4_tbl t2 + -> Materialize + -> Foreign Scan on int4_tbl t3 + -> Materialize + -> Foreign Scan on tenk1 t4 + -> Hash + -> Foreign Scan on int4_tbl t1 +(14 rows) + +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; + QUERY PLAN +----------------------------------------------------------------- + Hash Right Join + Hash Cond: (t2.f1 = t1.f1) + -> Nested Loop Left Join + Join Filter: (t2.f1 > 1) + -> Nested Loop Left Join + Join Filter: (t2.f1 > 0) + Filter: (t2.f1 <> COALESCE(t3.f1, '-1'::integer)) + -> Foreign Scan on int4_tbl t2 + -> Materialize + -> Foreign Scan on int4_tbl t3 + -> Materialize + -> Foreign Scan on tenk1 t4 + -> Hash + -> Foreign Scan on int4_tbl t1 +(14 rows) + +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; + QUERY PLAN +------------------------------------------------------------------------ + Hash Left Join + Hash Cond: ((t3.unique1 = t4.unique1) AND (t2.unique2 = t4.unique2)) + -> Hash Left Join + Hash Cond: (t2.unique1 = t3.unique1) + -> Hash Left Join + Hash Cond: (t1.unique1 = t2.unique1) + -> Foreign Scan on onek t1 + -> Hash + -> Foreign Scan on onek t2 + -> Hash + -> Foreign Scan on onek t3 + -> Hash + -> Foreign Scan on onek t4 +(13 rows) + +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; + QUERY PLAN +----------------------------------------------------------- + Nested Loop Left Join + -> Foreign Scan on int8_tbl t1 + -> Materialize + -> Hash Right Join + Hash Cond: (t5.q1 = t2.q1) + -> Foreign Scan on int8_tbl t5 + -> Hash + -> Nested Loop Left Join + Join Filter: false + -> Foreign Scan on int8_tbl t2 + -> Result + One-Time Filter: false +(12 rows) + +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; + QUERY PLAN +----------------------------------------------- + Nested Loop Left Join + -> Foreign Scan on int8_tbl t1 + -> Materialize + -> Nested Loop Left Join + Join Filter: (t2.q1 = 1) + -> Foreign Scan on int8_tbl t2 + -> Foreign Scan on int8_tbl t3 +(7 rows) + +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; + QUERY PLAN +---------------------------------------------------- + Nested Loop Left Join + -> Foreign Scan on int8_tbl t1 + -> Materialize + -> Nested Loop Left Join + Join Filter: (t2.q1 = 1) + -> Foreign Scan on int8_tbl t2 + -> Function Scan on generate_series +(7 rows) + +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; + QUERY PLAN +----------------------------------------------- + Nested Loop Left Join + -> Foreign Scan on int8_tbl t1 + -> Materialize + -> Nested Loop Left Join + Join Filter: (t2.q1 = 1) + -> Foreign Scan on int8_tbl t2 + -> Foreign Scan on int8_tbl t3 +(7 rows) + +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; + QUERY PLAN +--------------------------------------------- + Nested Loop Left Join + -> Foreign Scan on onek t1 + -> Materialize + -> Nested Loop Left Join + Join Filter: (t2.unique1 = 1) + -> Foreign Scan on onek t2 + -> Foreign Scan on onek t3 +(7 rows) + +-- +-- check a case where we formerly got confused by conflicting sort orders +-- in redundant merge join path keys +-- +--Testcase 133: +explain (costs off) +select * from + j1_tbl full join + (select * from j2_tbl order by j2_tbl.i desc, j2_tbl.k asc) j2_tbl + on j1_tbl.i = j2_tbl.i and j1_tbl.i = j2_tbl.k; + QUERY PLAN +----------------------------------------------------------------- + Merge Full Join + Merge Cond: ((j2_tbl.i = j1_tbl.i) AND (j2_tbl.k = j1_tbl.i)) + -> Sort + Sort Key: j2_tbl.i DESC, j2_tbl.k + -> Foreign Scan on j2_tbl + -> Sort + Sort Key: j1_tbl.i DESC + -> Foreign Scan on j1_tbl +(8 rows) + +--Testcase 134: +select * from + j1_tbl full join + (select * from j2_tbl order by j2_tbl.i desc, j2_tbl.k asc) j2_tbl + on j1_tbl.i = j2_tbl.i and j1_tbl.i = j2_tbl.k; + i | j | t | i | k +---+---+-------+---+---- + | | | | 0 + | 0 | zero | | + | | null | | + 8 | 8 | eight | | + 7 | 7 | seven | | + 6 | 6 | six | | + | | | 5 | -5 + | | | 5 | -5 + 5 | 0 | five | | + 4 | 1 | four | | + | | | 3 | -3 + 3 | 2 | three | | 2 | 3 | two | 2 | 2 | | | 2 | 4 | | | 1 | -1 @@ -2249,7 +2666,7 @@ select * from -- -- a different check for handling of redundant sort keys in merge joins -- ---Testcase 125: +--Testcase 135: explain (costs off) select count(*) from (select * from tenk1 x order by x.thousand, x.twothousand, x.fivethous) x @@ -2272,7 +2689,7 @@ select count(*) from -> Foreign Scan on tenk1 y_1 (12 rows) ---Testcase 126: +--Testcase 136: select count(*) from (select * from tenk1 x order by x.thousand, x.twothousand, x.fivethous) x left join @@ -2283,60 +2700,99 @@ select count(*) from 10000 (1 row) +set enable_hashjoin = 0; +set enable_nestloop = 0; +set enable_hashagg = 0; +-- +-- 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; + QUERY PLAN +----------------------------------------------------- + GroupAggregate + Group Key: x.thousand, x.twothousand + -> Incremental Sort + Sort Key: x.thousand DESC, x.twothousand + Presorted Key: x.thousand + -> Merge Join + Merge Cond: (x.thousand = y.thousand) + -> Sort + Sort Key: x.thousand DESC + -> Foreign Scan on tenk1 x + -> Sort + Sort Key: y.thousand DESC + -> Foreign Scan on tenk1 y +(13 rows) + +reset enable_hashagg; +reset enable_nestloop; +reset enable_hashjoin; -- -- Clean up -- ---Testcase 127: +--Testcase 137: DELETE FROM t1; ---Testcase 128: +--Testcase 138: DELETE FROM t2; ---Testcase 129: +--Testcase 139: DELETE FROM t3; ---Testcase 130: +--Testcase 140: DROP FOREIGN TABLE t1; ---Testcase 131: +--Testcase 141: DROP FOREIGN TABLE t2; ---Testcase 132: +--Testcase 142: DROP FOREIGN TABLE t3; ---Testcase 133: +--Testcase 143: DELETE FROM J1_TBL; +--Testcase 575: DROP FOREIGN TABLE J1_TBL; ---Testcase 134: +--Testcase 144: DELETE FROM J2_TBL; +--Testcase 576: DROP FOREIGN TABLE J2_TBL; +--Testcase 577: DELETE FROM x; +--Testcase 578: DELETE FROM y; +--Testcase 579: DROP FOREIGN TABLE x; +--Testcase 580: DROP FOREIGN TABLE y; -- Both DELETE and UPDATE allow the specification of additional tables -- to "join" against to determine which rows should be modified. ---Testcase 135: +--Testcase 145: CREATE FOREIGN TABLE t1 (a int, b int) SERVER influxdb_svr; ---Testcase 136: +--Testcase 146: CREATE FOREIGN TABLE t2 (a int, b int) SERVER influxdb_svr; ---Testcase 137: +--Testcase 147: CREATE FOREIGN TABLE t3 (x int, y int) SERVER influxdb_svr; ---Testcase 138: +--Testcase 148: INSERT INTO t1 VALUES (5, 10); ---Testcase 139: +--Testcase 149: INSERT INTO t1 VALUES (15, 20); ---Testcase 140: +--Testcase 150: INSERT INTO t1 VALUES (100, 100); ---Testcase 141: +--Testcase 151: INSERT INTO t1 VALUES (200, 1000); ---Testcase 142: +--Testcase 152: INSERT INTO t2 VALUES (200, 2000); ---Testcase 143: +--Testcase 153: INSERT INTO t3 VALUES (5, 20); ---Testcase 144: +--Testcase 154: INSERT INTO t3 VALUES (6, 7); ---Testcase 145: +--Testcase 155: INSERT INTO t3 VALUES (7, 8); ---Testcase 146: +--Testcase 156: INSERT INTO t3 VALUES (500, 100); ---Testcase 147: +--Testcase 157: ALTER TABLE t3 ADD time timestamp; ---Testcase 148: +--Testcase 158: SELECT x, y FROM t3; x | y -----+----- @@ -2346,9 +2802,9 @@ SELECT x, y FROM t3; 500 | 100 (4 rows) ---Testcase 149: +--Testcase 159: DELETE FROM t3 USING t1 table1 WHERE t3.x = table1.a; ---Testcase 150: +--Testcase 160: SELECT x, y FROM t3; x | y -----+----- @@ -2357,9 +2813,9 @@ SELECT x, y FROM t3; 500 | 100 (3 rows) ---Testcase 151: +--Testcase 161: DELETE FROM t3 USING t1 JOIN t2 USING (a) WHERE t3.x > t1.a; ---Testcase 152: +--Testcase 162: SELECT x, y FROM t3; x | y ---+--- @@ -2367,20 +2823,20 @@ SELECT x, y FROM t3; 7 | 8 (2 rows) ---Testcase 153: +--Testcase 163: DELETE FROM t3 USING t3 t3_other WHERE t3.x = t3_other.x AND t3.y = t3_other.y; ---Testcase 154: +--Testcase 164: SELECT x, y FROM t3; x | y ---+--- (0 rows) -- Test join against inheritance tree ---Testcase 155: +--Testcase 165: create temp table t2a () inherits (t2); ---Testcase 156: +--Testcase 166: insert into t2a values (200, 2001); ---Testcase 157: +--Testcase 167: select * from t1 left join t2 on (t1.a = t2.a); a | b | a | b -----+------+-----+------ @@ -2392,33 +2848,71 @@ select * from t1 left join t2 on (t1.a = t2.a); (5 rows) -- Test matching of column name with wrong alias ---Testcase 158: +--Testcase 168: select t1.x from t1 join t3 on (t1.a = t3.x); ERROR: column t1.x does not exist LINE 1: select t1.x from t1 join t3 on (t1.a = t3.x); ^ HINT: Perhaps you meant to reference the column "t3.x". +-- Test matching of locking clause with wrong alias +--Testcase 602: +select t1.*, t2.*, unnamed_join.* from + t1 join t2 on (t1.a = t2.a), t3 as unnamed_join + for update of unnamed_join; + a | b | a | b | x | y | time +---+---+---+---+---+---+------ +(0 rows) + +--Testcase 603: +select foo.*, unnamed_join.* from + t1 join t2 using (a) as foo, t3 as unnamed_join + for update of unnamed_join; + a | x | y | time +---+---+---+------ +(0 rows) + +--Testcase 604: +select foo.*, unnamed_join.* from + t1 join t2 using (a) as foo, t3 as unnamed_join + for update of foo; +ERROR: FOR UPDATE cannot be applied to a join +LINE 3: for update of foo; + ^ +--Testcase 605: +select bar.*, unnamed_join.* from + (t1 join t2 using (a) as foo) as bar, t3 as unnamed_join + for update of foo; +ERROR: relation "foo" in FOR UPDATE clause not found in FROM clause +LINE 3: for update of foo; + ^ +--Testcase 606: +select bar.*, unnamed_join.* from + (t1 join t2 using (a) as foo) as bar, t3 as unnamed_join + for update of bar; +ERROR: FOR UPDATE cannot be applied to a join +LINE 3: for update of bar; + ^ -- -- regression test for 8.1 merge right join bug -- ---Testcase 159: +--Testcase 169: CREATE FOREIGN TABLE tt1 ( tt1_id int4, joincol int4 ) SERVER influxdb_svr; ---Testcase 160: +--Testcase 170: INSERT INTO tt1 VALUES (1, 11); ---Testcase 161: +--Testcase 171: INSERT INTO tt1 VALUES (2, NULL); ---Testcase 162: +--Testcase 172: CREATE FOREIGN TABLE tt2 ( tt2_id int4, joincol int4 ) SERVER influxdb_svr; ---Testcase 163: +--Testcase 173: INSERT INTO tt2 VALUES (21, 11); ---Testcase 164: +--Testcase 174: INSERT INTO tt2 VALUES (22, 11); ---Testcase 165: +--Testcase 175: set enable_hashjoin to off; ---Testcase 166: +--Testcase 176: set enable_nestloop to off; -- these should give the same results ---Testcase 167: +--Testcase 177: select tt1.*, tt2.* from tt1 left join tt2 on tt1.joincol = tt2.joincol; tt1_id | joincol | tt2_id | joincol --------+---------+--------+--------- @@ -2427,7 +2921,7 @@ select tt1.*, tt2.* from tt1 left join tt2 on tt1.joincol = tt2.joincol; 2 | | | (3 rows) ---Testcase 168: +--Testcase 178: select tt1.*, tt2.* from tt2 right join tt1 on tt1.joincol = tt2.joincol; tt1_id | joincol | tt2_id | joincol --------+---------+--------+--------- @@ -2436,18 +2930,20 @@ select tt1.*, tt2.* from tt2 right join tt1 on tt1.joincol = tt2.joincol; 2 | | | (3 rows) ---Testcase 169: +--Testcase 179: reset enable_hashjoin; ---Testcase 170: +--Testcase 180: reset enable_nestloop; -- -- regression test for bug #13908 (hash join with skew tuples & nbatch increase) -- ---Testcase 171: +--Testcase 181: set work_mem to '64kB'; ---Testcase 172: +--Testcase 182: set enable_mergejoin to off; ---Testcase 173: +--Testcase 183: +set enable_memoize to off; +--Testcase 184: explain (costs off) select count(*) from tenk1 a, tenk1 b where a.hundred = b.thousand and (b.fivethous % 10) < 10; @@ -2461,7 +2957,7 @@ select count(*) from tenk1 a, tenk1 b -> Foreign Scan on tenk1 b (6 rows) ---Testcase 174: +--Testcase 185: select count(*) from tenk1 a, tenk1 b where a.hundred = b.thousand and (b.fivethous % 10) < 10; count @@ -2469,30 +2965,63 @@ select count(*) from tenk1 a, tenk1 b 100000 (1 row) ---Testcase 175: +--Testcase 186: reset work_mem; ---Testcase 176: +--Testcase 187: reset enable_mergejoin; +--Testcase 188: +reset enable_memoize; -- -- regression test for 8.2 bug with improper re-ordering of left joins -- ---Testcase 177: +--Testcase 189: create foreign table tt3(f1 int, f2 text) server influxdb_svr; ---Testcase 178: +--Testcase 190: insert into tt3 select x, repeat('xyzzy', 100) from generate_series(1,10000) x; ---Testcase 179: +--Testcase 191: create foreign table tt4(f1 int) server influxdb_svr; ---Testcase 180: +--Testcase 192: insert into tt4 values (0),(1),(9999); ---Testcase 181: +set enable_nestloop to off; +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 c.f1 IS NULL + WHERE COALESCE(c.f1, 0) = 0 ) AS d ON (a.f1 = d.f1) -WHERE d.f1 IS NULL; +WHERE COALESCE(d.f1, 0) = 0 +ORDER BY 1; + QUERY PLAN +----------------------------------------------------- + Sort + Sort Key: a.f1 + -> Hash Left Join + Hash Cond: (a.f1 = b.f1) + Filter: (COALESCE(b.f1, 0) = 0) + -> Foreign Scan on tt4 a + -> Hash + -> Merge Left Join + Merge Cond: (b.f1 = c.f1) + Filter: (COALESCE(c.f1, 0) = 0) + -> Sort + Sort Key: b.f1 + -> Foreign Scan on tt3 b + -> Sort + Sort Key: c.f1 + -> Foreign Scan on tt3 c +(16 rows) + +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; f1 ------ 0 @@ -2500,12 +3029,80 @@ WHERE d.f1 IS NULL; 9999 (3 rows) +reset enable_nestloop; +-- +-- basic semijoin and antijoin recognition tests +-- +explain (costs off) +select a.* from tenk1 a +where unique1 in (select unique2 from tenk1 b); + QUERY PLAN +------------------------------------------- + Hash Join + Hash Cond: (a.unique1 = b.unique2) + -> Foreign Scan on tenk1 a + -> Hash + -> HashAggregate + Group Key: b.unique2 + -> Foreign Scan on tenk1 b +(7 rows) + +-- sadly, this is not an antijoin +explain (costs off) +select a.* from tenk1 a +where unique1 not in (select unique2 from tenk1 b); + QUERY PLAN +------------------------------------ + Foreign Scan on tenk1 a + Filter: (NOT (hashed SubPlan 1)) + SubPlan 1 + -> Foreign Scan on tenk1 b +(4 rows) + +explain (costs off) +select a.* from tenk1 a +where exists (select 1 from tenk1 b where a.unique1 = b.unique2); + QUERY PLAN +------------------------------------------- + Hash Join + Hash Cond: (a.unique1 = b.unique2) + -> Foreign Scan on tenk1 a + -> Hash + -> HashAggregate + Group Key: b.unique2 + -> Foreign Scan on tenk1 b +(7 rows) + +explain (costs off) +select a.* from tenk1 a +where not exists (select 1 from tenk1 b where a.unique1 = b.unique2); + QUERY PLAN +-------------------------------------- + Hash Anti Join + Hash Cond: (a.unique1 = b.unique2) + -> Foreign Scan on tenk1 a + -> Hash + -> Foreign Scan on tenk1 b +(5 rows) + +explain (costs off) +select a.* from tenk1 a left join tenk1 b on a.unique1 = b.unique2 +where b.unique2 is null; + QUERY PLAN +-------------------------------------- + Hash Anti Join + Hash Cond: (a.unique1 = b.unique2) + -> Foreign Scan on tenk1 a + -> Hash + -> Foreign Scan on tenk1 b +(5 rows) + -- -- regression test for proper handling of outer joins within antijoins -- ---Testcase 182: +--Testcase 194: create foreign table tt4x(c1 int, c2 int, c3 int) server influxdb_svr; ---Testcase 183: +--Testcase 195: explain (costs off) select * from tt4x t1 where not exists ( @@ -2547,21 +3144,21 @@ where not exists ( -- -- regression test for problems of the sort depicted in bug #3494 -- ---Testcase 184: +--Testcase 196: create foreign table tt5(f1 int, f2 int) server influxdb_svr; ---Testcase 185: +--Testcase 197: create foreign table tt6(f1 int, f2 int) server influxdb_svr; ---Testcase 186: +--Testcase 198: insert into tt5 values(1, 10); ---Testcase 187: +--Testcase 199: insert into tt5 values(1, 11); ---Testcase 188: +--Testcase 200: insert into tt6 values(1, 9); ---Testcase 189: +--Testcase 201: insert into tt6 values(1, 2); ---Testcase 190: +--Testcase 202: insert into tt6 values(2, 9); ---Testcase 191: +--Testcase 203: select * from tt5,tt6 where tt5.f1 = tt6.f1 and tt5.f1 = tt5.f2 - tt6.f2; f1 | f2 | f1 | f2 ----+----+----+---- @@ -2571,23 +3168,23 @@ select * from tt5,tt6 where tt5.f1 = tt6.f1 and tt5.f1 = tt5.f2 - tt6.f2; -- -- regression test for problems of the sort depicted in bug #3588 -- ---Testcase 192: +--Testcase 204: create foreign table xx (pkxx int) server influxdb_svr; ---Testcase 193: +--Testcase 205: create foreign table yy (pkyy int, pkxx int) server influxdb_svr; ---Testcase 194: +--Testcase 206: insert into xx values (1); ---Testcase 195: +--Testcase 207: insert into xx values (2); ---Testcase 196: +--Testcase 208: insert into xx values (3); ---Testcase 197: +--Testcase 209: insert into yy values (101, 1); ---Testcase 198: +--Testcase 210: insert into yy values (201, 2); ---Testcase 199: +--Testcase 211: insert into yy values (301, NULL); ---Testcase 200: +--Testcase 212: 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 @@ -2605,17 +3202,17 @@ from yy -- regression test for improper pushing of constants across outer-join clauses -- (as seen in early 8.2.x releases) -- ---Testcase 201: +--Testcase 213: create foreign table zt1 (f1 int) server influxdb_svr; ---Testcase 202: +--Testcase 214: create foreign table zt2 (f2 int) server influxdb_svr; ---Testcase 203: +--Testcase 215: create foreign table zt3 (f3 int) server influxdb_svr; ---Testcase 204: +--Testcase 216: insert into zt1 values(53); ---Testcase 205: +--Testcase 217: insert into zt2 values(53); ---Testcase 206: +--Testcase 218: select * from zt2 left join zt3 on (f2 = f3) left join zt1 on (f3 = f1) @@ -2625,9 +3222,9 @@ where f2 = 53; 53 | | (1 row) ---Testcase 207: +--Testcase 219: create temp view zv1 as select *,'dummy'::text AS junk from zt1; ---Testcase 208: +--Testcase 220: select * from zt2 left join zt3 on (f2 = f3) left join zv1 on (f3 = f1) @@ -2641,7 +3238,7 @@ where f2 = 53; -- regression test for improper extraction of OR indexqual conditions -- (as seen in early 8.3.x releases) -- ---Testcase 209: +--Testcase 221: 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 @@ -2653,19 +3250,19 @@ where a.unique1 = 42 and -- -- test proper positioning of one-time quals in EXISTS (8.4devel bug) -- ---Testcase 210: +--Testcase 222: 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)); ---Testcase 211: +--Testcase 223: execute foo(true); count ------- 10000 (1 row) ---Testcase 212: +--Testcase 224: execute foo(false); count ------- @@ -2676,38 +3273,38 @@ execute foo(false); -- test for sane behavior with noncanonical merge clauses, per bug #4926 -- begin; ---Testcase 213: +--Testcase 225: set enable_mergejoin = 1; ---Testcase 214: +--Testcase 226: set enable_hashjoin = 0; ---Testcase 215: +--Testcase 227: set enable_nestloop = 0; ---Testcase 216: +--Testcase 228: create foreign table a (i integer) server influxdb_svr; ---Testcase 217: +--Testcase 229: create foreign table b (x integer, y integer) server influxdb_svr; ---Testcase 218: +--Testcase 230: select * from a left join b on i = x and i = y and x = i; i | x | y ---+---+--- (0 rows) ---Testcase 219: +--Testcase 231: DROP FOREIGN TABLE a; ---Testcase 220: +--Testcase 232: DROP FOREIGN TABLE b; rollback; -- -- test handling of merge clauses using record_ops -- begin; ---Testcase 221: +--Testcase 233: create type mycomptype as (id int, v bigint); ---Testcase 222: +--Testcase 234: create temp table tidv (idv mycomptype); ---Testcase 223: +--Testcase 235: create index on tidv (idv); ---Testcase 224: +--Testcase 236: explain (costs off) select a.idv, b.idv from tidv a, tidv b where a.idv = b.idv; QUERY PLAN @@ -2719,11 +3316,11 @@ select a.idv, b.idv from tidv a, tidv b where a.idv = b.idv; -> Index Only Scan using tidv_idv_idx on tidv b (5 rows) ---Testcase 225: +--Testcase 237: set enable_mergejoin = 0; ---Testcase 226: +--Testcase 238: set enable_hashjoin = 0; ---Testcase 227: +--Testcase 239: explain (costs off) select a.idv, b.idv from tidv a, tidv b where a.idv = b.idv; QUERY PLAN @@ -2738,7 +3335,7 @@ rollback; -- -- test NULL behavior of whole-row Vars, per bug #5025 -- ---Testcase 228: +--Testcase 240: 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; @@ -2750,7 +3347,7 @@ group by t1.q2 order by 1; 4567890123456789 | 6 (4 rows) ---Testcase 229: +--Testcase 241: 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; @@ -2762,7 +3359,7 @@ group by t1.q2 order by 1; 4567890123456789 | 6 (4 rows) ---Testcase 230: +--Testcase 242: 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; @@ -2774,7 +3371,7 @@ group by t1.q2 order by 1; 4567890123456789 | 6 (4 rows) ---Testcase 231: +--Testcase 243: 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 @@ -2792,35 +3389,35 @@ group by t1.q2 order by 1; -- test incorrect failure to NULL pulled-up subexpressions -- begin; ---Testcase 232: +--Testcase 244: create foreign table a ( code char ) server influxdb_svr; ---Testcase 233: +--Testcase 245: create foreign table b ( a char, num integer ) server influxdb_svr; ---Testcase 234: +--Testcase 246: create foreign table c ( name char, a char ) server influxdb_svr; ---Testcase 235: +--Testcase 247: insert into a (code) values ('p'); ---Testcase 236: +--Testcase 248: insert into a (code) values ('q'); ---Testcase 237: +--Testcase 249: insert into b (a, num) values ('p', 1); ---Testcase 238: +--Testcase 250: insert into b (a, num) values ('p', 2); ---Testcase 239: +--Testcase 251: insert into c (name, a) values ('A', 'p'); ---Testcase 240: +--Testcase 252: insert into c (name, a) values ('B', 'q'); ---Testcase 241: +--Testcase 253: insert into c (name, a) values ('C', null); ---Testcase 242: +--Testcase 254: 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 @@ -2837,24 +3434,24 @@ order by c.name; C | | | (3 rows) ---Testcase 243: +--Testcase 255: DELETE FROM a; ---Testcase 244: +--Testcase 256: DELETE FROM b; ---Testcase 245: +--Testcase 257: DELETE FROM c; ---Testcase 246: +--Testcase 258: DROP FOREIGN TABLE a; ---Testcase 247: +--Testcase 259: DROP FOREIGN TABLE b; ---Testcase 248: +--Testcase 260: DROP FOREIGN TABLE c; rollback; -- -- test incorrect handling of placeholders that only appear in targetlists, -- per bug #6154 -- ---Testcase 249: +--Testcase 261: SELECT * FROM ( SELECT 1 as key1 ) sub1 LEFT JOIN @@ -2876,7 +3473,7 @@ ON sub1.key1 = sub2.key3; (1 row) -- test the path using join aliases, too ---Testcase 250: +--Testcase 262: SELECT * FROM ( SELECT 1 as key1 ) sub1 LEFT JOIN @@ -2900,7 +3497,7 @@ ON sub1.key1 = sub2.key3; -- -- test case where a PlaceHolderVar is used as a nestloop parameter -- ---Testcase 251: +--Testcase 263: EXPLAIN (COSTS OFF) SELECT qq, unique1 FROM @@ -2928,7 +3525,7 @@ SELECT qq, unique1 -> Foreign Scan on int8_tbl b (15 rows) ---Testcase 252: +--Testcase 264: SELECT qq, unique1 FROM ( SELECT COALESCE(q1, 0) AS qq FROM int8_tbl a ) AS ss1 @@ -2946,44 +3543,44 @@ SELECT qq, unique1 -- -- nested nestloops can require nested PlaceHolderVars -- ---Testcase 253: +--Testcase 265: create foreign table nt1 ( id int, a1 boolean, a2 boolean ) server influxdb_svr; ---Testcase 254: +--Testcase 266: create foreign table nt2 ( id int, nt1_id int, b1 boolean, b2 boolean ) server influxdb_svr; ---Testcase 255: +--Testcase 267: create foreign table nt3 ( id int, nt2_id int, c1 boolean ) server influxdb_svr; ---Testcase 256: +--Testcase 268: insert into nt1 values (1,true,true); ---Testcase 257: +--Testcase 269: insert into nt1 values (2,true,false); ---Testcase 258: +--Testcase 270: insert into nt1 values (3,false,false); ---Testcase 259: +--Testcase 271: insert into nt2 values (1,1,true,true); ---Testcase 260: +--Testcase 272: insert into nt2 values (2,2,true,false); ---Testcase 261: +--Testcase 273: insert into nt2 values (3,3,false,false); ---Testcase 262: +--Testcase 274: insert into nt3 values (1,1,true); ---Testcase 263: +--Testcase 275: insert into nt3 values (2,2,false); ---Testcase 264: +--Testcase 276: insert into nt3 values (3,3,true); ---Testcase 265: +--Testcase 277: explain (costs off) select nt3.id from nt3 as nt3 @@ -3010,7 +3607,7 @@ where nt3.id = 1 and ss2.b3; -> Foreign Scan on nt3 (10 rows) ---Testcase 266: +--Testcase 278: select nt3.id from nt3 as nt3 left join @@ -3030,7 +3627,7 @@ where nt3.id = 1 and ss2.b3; -- -- test case where a PlaceHolderVar is propagated into a subquery -- ---Testcase 267: +--Testcase 279: explain (costs off) select * from int8_tbl t1 left join @@ -3056,7 +3653,7 @@ order by 1,2; -> Foreign Scan on int8_tbl t3 (13 rows) ---Testcase 268: +--Testcase 280: select * from int8_tbl t1 left join (select q1 as x, 42 as y from int8_tbl t2) ss @@ -3079,7 +3676,7 @@ order by 1,2; -- -- variant where a PlaceHolderVar is needed at a join, but not above the join -- ---Testcase 269: +--Testcase 281: explain (costs off) select * from int4_tbl as i41, @@ -3097,7 +3694,7 @@ where i41.f1 > 0; -> Nested Loop -> Foreign Scan on int4_tbl i41 -> Nested Loop - Join Filter: (i41.f1 = i42.f1) + Join Filter: (i42.f1 = i41.f1) -> Foreign Scan on int8_tbl i81 -> Materialize -> Foreign Scan on int4_tbl i42 @@ -3105,7 +3702,7 @@ where i41.f1 > 0; -> Foreign Scan on int4_tbl i43 (10 rows) ---Testcase 270: +--Testcase 282: select * from int4_tbl as i41, lateral @@ -3143,7 +3740,7 @@ where i41.f1 > 0; -- -- test the corner cases FULL JOIN ON TRUE and FULL JOIN ON FALSE -- ---Testcase 271: +--Testcase 283: select * from int4_tbl a full join int4_tbl b on true; f1 | f1 -------------+------------- @@ -3174,7 +3771,7 @@ select * from int4_tbl a full join int4_tbl b on true; -2147483647 | -2147483647 (25 rows) ---Testcase 272: +--Testcase 284: select * from int4_tbl a full join int4_tbl b on false; f1 | f1 -------------+------------- @@ -3193,11 +3790,11 @@ select * from int4_tbl a full join int4_tbl b on false; -- -- test for ability to use a cartesian join when necessary -- ---Testcase 273: +--Testcase 285: create foreign table q1 (q1 int) server influxdb_svr; ---Testcase 274: +--Testcase 286: create foreign table q2 (q2 int) server influxdb_svr; ---Testcase 275: +--Testcase 287: explain (costs off) select * from tenk1 join int4_tbl on f1 = twothousand, @@ -3219,7 +3816,7 @@ where q1 = thousand or q2 = thousand; -> Foreign Scan on int4_tbl (12 rows) ---Testcase 276: +--Testcase 288: explain (costs off) select * from tenk1 join int4_tbl on f1 = twothousand, @@ -3248,7 +3845,7 @@ where thousand = (q1 + q2); -- -- test ability to generate a suitable plan for a star-schema query -- ---Testcase 277: +--Testcase 289: explain (costs off) select * from tenk1, int8_tbl a, int8_tbl b @@ -3269,7 +3866,7 @@ where thousand = a.q1 and tenthous = b.q1 and a.q2 = 1 and b.q2 = 2; -- -- test a corner case in which we shouldn't apply the star-schema optimization -- ---Testcase 278: +--Testcase 290: explain (costs off) select t1.unique2, t1.stringu1, t2.unique1, t2.stringu2 from tenk1 t1 @@ -3283,30 +3880,22 @@ select t1.unique2, t1.stringu1, t2.unique1, t2.stringu2 from left join tenk1 t2 on (subq1.y1 = t2.unique1) where t1.unique2 < 42 and t1.stringu1 > t2.stringu2; - QUERY PLAN ------------------------------------------------------------------ - Merge Join - Merge Cond: (t2.unique1 = (3)) - Join Filter: (t1.stringu1 > t2.stringu2) - -> Sort - Sort Key: t2.unique1 + QUERY PLAN +--------------------------------------------------------------------------- + Nested Loop + -> Nested Loop + Join Filter: ((t1.stringu1 > t2.stringu2) AND ((3) = t2.unique1)) + -> Nested Loop + Join Filter: ((11) = t1.unique2) + -> Nested Loop + -> Seq Scan on onerow + -> Seq Scan on onerow onerow_1 + -> Foreign Scan on tenk1 t1 -> Foreign Scan on tenk1 t2 - -> Sort - Sort Key: (3) - -> Hash Join - Hash Cond: ((11) = t1.unique2) - -> Nested Loop Left Join - Join Filter: (i1.f1 = 0) - -> Foreign Scan on int4_tbl i1 - -> Materialize - -> Nested Loop Left Join - -> Seq Scan on onerow - -> Seq Scan on onerow onerow_1 - -> Hash - -> Foreign Scan on tenk1 t1 -(19 rows) + -> Foreign Scan on int4_tbl i1 +(11 rows) ---Testcase 279: +--Testcase 291: select t1.unique2, t1.stringu1, t2.unique1, t2.stringu2 from tenk1 t1 inner join int4_tbl i1 @@ -3325,7 +3914,7 @@ where t1.unique2 < 42 and t1.stringu1 > t2.stringu2; (1 row) -- variant that isn't quite a star-schema case ---Testcase 280: +--Testcase 292: select ss1.d1 from tenk1 as t1 inner join tenk1 as t2 @@ -3346,7 +3935,7 @@ where t1.unique1 < i4.f1; (0 rows) -- this variant is foldable by the remove-useless-RESULT-RTEs code ---Testcase 281: +--Testcase 293: explain (costs off) select t1.unique2, t1.stringu1, t2.unique1, t2.stringu2 from tenk1 t1 @@ -3360,25 +3949,21 @@ select t1.unique2, t1.stringu1, t2.unique1, t2.stringu2 from left join tenk1 t2 on (subq1.y1 = t2.unique1) where t1.unique2 < 42 and t1.stringu1 > t2.stringu2; - QUERY PLAN ---------------------------------------------------------------------------- - Nested Loop - Join Filter: ((0) = i1.f1) - -> Nested Loop - Join Filter: ((t1.stringu1 > t2.stringu2) AND ((3) = t2.unique1)) + QUERY PLAN +----------------------------------------------------- + Hash Join + Hash Cond: (t2.unique1 = (3)) + Join Filter: (t1.stringu1 > t2.stringu2) + -> Foreign Scan on tenk1 t2 + -> Hash -> Hash Join Hash Cond: (t1.unique2 = (11)) -> Foreign Scan on tenk1 t1 -> Hash - -> Nested Loop - Join Filter: ((1) = (1)) - -> Result - -> Result - -> Foreign Scan on tenk1 t2 - -> Foreign Scan on int4_tbl i1 -(14 rows) + -> Foreign Scan on int4_tbl i1 +(10 rows) ---Testcase 282: +--Testcase 294: select t1.unique2, t1.stringu1, t2.unique1, t2.stringu2 from tenk1 t1 inner join int4_tbl i1 @@ -3398,28 +3983,24 @@ where t1.unique2 < 42 and t1.stringu1 > t2.stringu2; -- Here's a variant that we can't fold too aggressively, though, -- or we end up with noplace to evaluate the lateral PHV ---Testcase 283: +--Testcase 295: explain (verbose, costs off) select * from (select 1 as x) ss1 left join (select 2 as y) ss2 on (true), lateral (select ss2.y as z limit 1) ss3; - QUERY PLAN ------------------------------ + QUERY PLAN +--------------------------- Nested Loop - Output: (1), (2), ((2)) - -> Nested Loop Left Join - Output: (1), (2) - -> Result - Output: 1 - -> Result - Output: 2 + Output: 1, (2), ((2)) + -> Result + Output: 2 -> Limit Output: ((2)) -> Result Output: (2) -(12 rows) +(8 rows) ---Testcase 284: +--Testcase 296: 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; @@ -3429,7 +4010,7 @@ select * from (1 row) -- Test proper handling of appendrel PHVs during useless-RTE removal ---Testcase 285: +--Testcase 297: explain (costs off) select * from (select 0 as z) as t1 @@ -3443,16 +4024,14 @@ where b; QUERY PLAN --------------------------------------- Nested Loop - -> Nested Loop Left Join - -> Result - -> Result + -> Result -> Append -> Result -> Result One-Time Filter: (true) -(8 rows) +(6 rows) ---Testcase 286: +--Testcase 298: select * from (select 0 as z) as t1 left join @@ -3468,27 +4047,80 @@ where b; 0 | t | t (2 rows) +-- 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 ); + QUERY PLAN +---------------------------- + Result + Output: 1 + One-Time Filter: (1 = 1) +(3 rows) + +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 ); + f1 +---- + 1 +(1 row) + +-- 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; + QUERY PLAN +------------------------------------------------------------------------------------------------------------------- + Result + Output: (current_database())::information_schema.sql_identifier, (c.relname)::information_schema.sql_identifier + One-Time Filter: false +(3 rows) + +-- 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; + QUERY PLAN +----------------------------------------------------- + Nested Loop Left Join + Output: int4_tbl.f1, ('foo'::text) + Filter: (('foo'::text) IS NULL) + -> Foreign Scan on public.int4_tbl + Output: int4_tbl.f1 + InfluxDB query: SELECT "f1" FROM "int4_tbl" + -> Materialize + Output: ('foo'::text) + -> Append + -> Result + Output: 'foo'::text + -> Result + Output: 'bar'::text +(13 rows) + -- -- test inlining of immutable functions -- ---Testcase 287: +--Testcase 299: create function f_immutable_int4(i integer) returns integer as $$ begin return i; end; $$ language plpgsql immutable; -- check optimization of function scan with join ---Testcase 288: +--Testcase 300: explain (costs off) select unique1 from tenk1, (select * from f_immutable_int4(1) x) x where x = unique1; - QUERY PLAN ------------------------------------- - Hash Join - Hash Cond: (tenk1.unique1 = x.x) - -> Foreign Scan on tenk1 - -> Hash - -> Function Scan on x -(5 rows) + QUERY PLAN +----------------------- + Foreign Scan on tenk1 +(1 row) ---Testcase 289: +--Testcase 301: explain (verbose, costs off) select unique1, x.* from tenk1, (select *, random() from f_immutable_int4(1) x) x @@ -3496,104 +4128,96 @@ where x = unique1; QUERY PLAN ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- Hash Join - Output: tenk1.unique1, x.x, (random()) - Hash Cond: (tenk1.unique1 = x.x) + Output: tenk1.unique1, (1), (random()) + Hash Cond: (tenk1.unique1 = (1)) -> Foreign Scan on public.tenk1 Output: tenk1.unique1, tenk1.unique2, tenk1.two, tenk1.four, tenk1.ten, tenk1.twenty, tenk1.hundred, tenk1.thousand, tenk1.twothousand, tenk1.fivethous, tenk1.tenthous, tenk1.odd, tenk1.even, tenk1.stringu1, tenk1.stringu2, tenk1.string4 InfluxDB query: SELECT "unique1" FROM "tenk" -> Hash - Output: x.x, (random()) - -> Function Scan on x - Output: x.x, random() - Function Call: 1 -(11 rows) + Output: (1), (random()) + -> Result + Output: 1, random() +(10 rows) ---Testcase 290: +--Testcase 302: explain (costs off) select unique1 from tenk1, f_immutable_int4(1) x where x = unique1; - QUERY PLAN ------------------------------------- - Hash Join - Hash Cond: (tenk1.unique1 = x.x) - -> Foreign Scan on tenk1 - -> Hash - -> Function Scan on x -(5 rows) + QUERY PLAN +----------------------- + Foreign Scan on tenk1 +(1 row) ---Testcase 291: +--Testcase 303: explain (costs off) select unique1 from tenk1, lateral f_immutable_int4(1) x where x = unique1; - QUERY PLAN ------------------------------------- - Hash Join - Hash Cond: (tenk1.unique1 = x.x) - -> Foreign Scan on tenk1 - -> Hash - -> Function Scan on x -(5 rows) + QUERY PLAN +----------------------- + Foreign Scan on tenk1 +(1 row) ---Testcase 292: +--Testcase 569: +explain (costs off) +select unique1 from tenk1, lateral f_immutable_int4(1) x where x in (select 17); + QUERY PLAN +-------------------------- + Result + One-Time Filter: false +(2 rows) + +--Testcase 304: explain (costs off) select unique1, x from tenk1 join f_immutable_int4(1) x on unique1 = x; - QUERY PLAN ------------------------------------- - Hash Join - Hash Cond: (tenk1.unique1 = x.x) - -> Foreign Scan on tenk1 - -> Hash - -> Function Scan on x -(5 rows) + QUERY PLAN +----------------------- + Foreign Scan on tenk1 +(1 row) ---Testcase 293: +--Testcase 305: explain (costs off) select unique1, x from tenk1 left join f_immutable_int4(1) x on unique1 = x; QUERY PLAN ------------------------------------ - Hash Left Join - Hash Cond: (tenk1.unique1 = x.x) + Nested Loop Left Join + Join Filter: (tenk1.unique1 = 1) -> Foreign Scan on tenk1 - -> Hash - -> Function Scan on x + -> Materialize + -> Result (5 rows) ---Testcase 294: +--Testcase 306: explain (costs off) select unique1, x from tenk1 right join f_immutable_int4(1) x on unique1 = x; - QUERY PLAN ------------------------------------- - Hash Right Join - Hash Cond: (tenk1.unique1 = x.x) + QUERY PLAN +----------------------------- + Nested Loop Left Join + -> Result -> Foreign Scan on tenk1 - -> Hash - -> Function Scan on x -(5 rows) +(3 rows) ---Testcase 295: +--Testcase 307: explain (costs off) select unique1, x from tenk1 full join f_immutable_int4(1) x on unique1 = x; QUERY PLAN ------------------------------------ Hash Full Join - Hash Cond: (tenk1.unique1 = x.x) + Hash Cond: (tenk1.unique1 = (1)) -> Foreign Scan on tenk1 -> Hash - -> Function Scan on x + -> Result (5 rows) -- check that pullup of a const function allows further const-folding ---Testcase 296: +--Testcase 308: explain (costs off) select unique1 from tenk1, f_immutable_int4(1) x where x = 42; - QUERY PLAN ------------------------------ - Nested Loop - -> Function Scan on x - Filter: (x = 42) - -> Foreign Scan on tenk1 -(4 rows) + QUERY PLAN +-------------------------- + Result + One-Time Filter: false +(2 rows) -- test inlining of immutable functions with PlaceHolderVars ---Testcase 297: +--Testcase 309: explain (costs off) select nt3.id from nt3 as nt3 @@ -3606,30 +4230,30 @@ from nt3 as nt3 ) as ss2 on ss2.id = nt3.nt2_id where nt3.id = 1 and ss2.b3; - QUERY PLAN ------------------------------------------ + QUERY PLAN +--------------------------------------- Hash Right Join Hash Cond: (nt2.id = nt3.nt2_id) - Filter: ((nt2.b1 OR (i4.i4 = 42))) - -> Hash Left Join - Hash Cond: (nt2.nt1_id = i4.i4) + Filter: ((nt2.b1 OR ((0) = 42))) + -> Nested Loop Left Join + Join Filter: (0 = nt2.nt1_id) -> Foreign Scan on nt2 - -> Hash - -> Function Scan on i4 + -> Materialize + -> Result -> Hash -> Foreign Scan on nt3 (10 rows) ---Testcase 298: +--Testcase 310: drop function f_immutable_int4(int); -- test inlining when function returns composite ---Testcase 299: +--Testcase 311: create function mki8(bigint, bigint) returns int8_tbl as $$select row($1,$2)::int8_tbl$$ language sql; ---Testcase 300: +--Testcase 312: create function mki4(int) returns int4_tbl as $$select row($1)::int4_tbl$$ language sql; ---Testcase 301: +--Testcase 313: explain (verbose, costs off) select * from mki8(1,2); QUERY PLAN @@ -3639,14 +4263,14 @@ select * from mki8(1,2); Function Call: '(1,2)'::int8_tbl (3 rows) ---Testcase 302: +--Testcase 314: select * from mki8(1,2); q1 | q2 ----+---- 1 | 2 (1 row) ---Testcase 303: +--Testcase 315: explain (verbose, costs off) select * from mki4(42); QUERY PLAN @@ -3656,22 +4280,22 @@ select * from mki4(42); Function Call: '(42)'::int4_tbl (3 rows) ---Testcase 304: +--Testcase 316: select * from mki4(42); f1 ---- 42 (1 row) ---Testcase 305: +--Testcase 317: drop function mki8(bigint, bigint); ---Testcase 306: +--Testcase 318: drop function mki4(int); -- -- test extraction of restriction OR clauses from join OR clause -- (we used to only do this for indexable clauses) -- ---Testcase 307: +--Testcase 319: 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); @@ -3684,7 +4308,7 @@ select * from tenk1 a join tenk1 b on -> Foreign Scan on tenk1 b (5 rows) ---Testcase 308: +--Testcase 320: 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); @@ -3697,7 +4321,7 @@ select * from tenk1 a join tenk1 b on -> Foreign Scan on tenk1 b (5 rows) ---Testcase 309: +--Testcase 321: explain (costs off) select * from tenk1 a join tenk1 b on (a.unique1 = 1 and b.unique1 = 2) or @@ -3714,7 +4338,7 @@ select * from tenk1 a join tenk1 b on -- -- test placement of movable quals in a parameterized join tree -- ---Testcase 310: +--Testcase 322: explain (costs off) select * from tenk1 t1 left join (tenk1 t2 join tenk1 t3 on t2.thousand = t3.unique2) @@ -3733,7 +4357,7 @@ where t1.unique1 = 1; -> Foreign Scan on tenk1 t1 (9 rows) ---Testcase 311: +--Testcase 323: explain (costs off) select * from tenk1 t1 left join (tenk1 t2 join tenk1 t3 on t2.thousand = t3.unique2) @@ -3753,7 +4377,7 @@ where t1.unique1 = 1; -> Foreign Scan on tenk1 t1 (10 rows) ---Testcase 312: +--Testcase 324: explain (costs off) select count(*) from tenk1 a join tenk1 b on a.unique1 = b.unique2 @@ -3787,7 +4411,7 @@ select count(*) from -> Foreign Scan on tenk1 c (24 rows) ---Testcase 313: +--Testcase 325: 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 @@ -3797,7 +4421,7 @@ select count(*) from 10 (1 row) ---Testcase 314: +--Testcase 326: explain (costs off) select b.unique1 from tenk1 a join tenk1 b on a.unique1 = b.unique2 @@ -3842,7 +4466,7 @@ select b.unique1 from -> Foreign Scan on tenk1 c (33 rows) ---Testcase 315: +--Testcase 327: 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 @@ -3858,7 +4482,7 @@ select b.unique1 from (5 rows) ---Testcase 316: +--Testcase 328: explain (costs off) select * from ( @@ -3880,7 +4504,7 @@ order by fault; -> Foreign Scan on tenk1 (9 rows) ---Testcase 317: +--Testcase 329: select * from ( select unique1, q1, coalesce(unique1, -1) + q1 as fault @@ -3893,7 +4517,7 @@ order by fault; | 123 | 122 (1 row) ---Testcase 318: +--Testcase 330: explain (costs off) select * from (values (1, array[10,20]), (2, array[20,30])) as v1(v1x,v1ys) @@ -3911,7 +4535,7 @@ left join unnest(v1ys) as u1(u1y) on u1y = v2y; -> Values Scan on "*VALUES*_1" (8 rows) ---Testcase 319: +--Testcase 331: 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 @@ -3925,16 +4549,16 @@ left join unnest(v1ys) as u1(u1y) on u1y = v2y; -- -- test handling of potential equivalence clauses above outer joins -- ---Testcase 320: +--Testcase 332: explain (costs off) select q1, unique2, thousand, hundred from int8_tbl a left join tenk1 b on q1 = unique2 where coalesce(thousand,123) = q1 and q1 = coalesce(hundred,123); - QUERY PLAN --------------------------------------------------------------------------------------- + QUERY PLAN +---------------------------------------------------------------------------------------------------------- Merge Right Join Merge Cond: (b.unique2 = a.q1) - Filter: ((COALESCE(b.thousand, 123) = a.q1) AND (a.q1 = COALESCE(b.hundred, 123))) + Filter: ((COALESCE(b.thousand, 123) = COALESCE(b.hundred, 123)) AND (a.q1 = COALESCE(b.hundred, 123))) -> Sort Sort Key: b.unique2 -> Foreign Scan on tenk1 b @@ -3943,7 +4567,7 @@ select q1, unique2, thousand, hundred -> Foreign Scan on int8_tbl a (9 rows) ---Testcase 321: +--Testcase 333: 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); @@ -3951,7 +4575,7 @@ select q1, unique2, thousand, hundred ----+---------+----------+--------- (0 rows) ---Testcase 322: +--Testcase 334: 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 @@ -3969,7 +4593,7 @@ select f1, unique2, case when unique2 is null then f1 else 0 end -> Foreign Scan on tenk1 b (9 rows) ---Testcase 323: +--Testcase 335: 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; @@ -3981,15 +4605,14 @@ select f1, unique2, case when unique2 is null then f1 else 0 end -- -- another case with equivalence clauses above outer joins (bug #8591) -- ---Testcase 324: +--Testcase 336: explain (costs off) select a.unique1, b.unique1, c.unique1, coalesce(b.twothousand, a.twothousand) from tenk1 a left join tenk1 b on b.thousand = a.unique1 left join tenk1 c on c.unique2 = coalesce(b.twothousand, a.twothousand) where a.unique2 < 10 and coalesce(b.twothousand, a.twothousand) = 44; - QUERY PLAN -------------------------------------------------------------------- - Hash Left Join - Hash Cond: (COALESCE(b.twothousand, a.twothousand) = c.unique2) + QUERY PLAN +--------------------------------------------------------------- + Nested Loop Left Join -> Merge Left Join Merge Cond: (a.unique1 = b.thousand) Filter: (COALESCE(b.twothousand, a.twothousand) = 44) @@ -3999,11 +4622,11 @@ select a.unique1, b.unique1, c.unique1, coalesce(b.twothousand, a.twothousand) -> Sort Sort Key: b.thousand -> Foreign Scan on tenk1 b - -> Hash + -> Materialize -> Foreign Scan on tenk1 c -(13 rows) +(12 rows) ---Testcase 325: +--Testcase 337: 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; @@ -4011,10 +4634,46 @@ select a.unique1, b.unique1, c.unique1, coalesce(b.twothousand, a.twothousand) ---------+---------+---------+---------- (0 rows) +-- 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; + QUERY PLAN +----------------------------------------------------- + Nested Loop + -> Foreign Scan on int8_tbl t3 + -> Materialize + -> Merge Left Join + Merge Cond: (t1.q2 = t2.q1) + Filter: (t2.q1 = t2.q2) + -> Sort + Sort Key: t1.q2 + -> Foreign Scan on int8_tbl t1 + -> Sort + Sort Key: t2.q1 + -> Foreign Scan on int8_tbl t2 +(12 rows) + +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; + q1 | q2 | q1 | q2 | q1 | q2 +------------------+------------------+------------------+------------------+------------------+------------------- + 123 | 4567890123456789 | 4567890123456789 | 4567890123456789 | 123 | 456 + 4567890123456789 | 4567890123456789 | 4567890123456789 | 4567890123456789 | 123 | 456 + 123 | 4567890123456789 | 4567890123456789 | 4567890123456789 | 123 | 4567890123456789 + 4567890123456789 | 4567890123456789 | 4567890123456789 | 4567890123456789 | 123 | 4567890123456789 + 123 | 4567890123456789 | 4567890123456789 | 4567890123456789 | 4567890123456789 | 123 + 4567890123456789 | 4567890123456789 | 4567890123456789 | 4567890123456789 | 4567890123456789 | 123 + 123 | 4567890123456789 | 4567890123456789 | 4567890123456789 | 4567890123456789 | 4567890123456789 + 4567890123456789 | 4567890123456789 | 4567890123456789 | 4567890123456789 | 4567890123456789 | 4567890123456789 + 123 | 4567890123456789 | 4567890123456789 | 4567890123456789 | 4567890123456789 | -4567890123456789 + 4567890123456789 | 4567890123456789 | 4567890123456789 | 4567890123456789 | 4567890123456789 | -4567890123456789 +(10 rows) + -- -- check handling of join aliases when flattening multiple levels of subquery -- ---Testcase 326: +--Testcase 338: 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) @@ -4055,7 +4714,7 @@ using (join_key); Output: "*VALUES*".column1 (23 rows) ---Testcase 327: +--Testcase 339: select foo1.join_key as foo1_id, foo3.join_key AS foo3_id, bug_field from (values (0),(1)) foo1(join_key) left join @@ -4074,12 +4733,73 @@ using (join_key); 1 | | (2 rows) +-- +-- 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; + QUERY PLAN +-------------------------------------------------------------------------------------------------------- + Incremental Sort + Output: i0.f1, ('123'::bigint), i1.f1, i2.q1, i2.q2 + Sort Key: i0.f1, ('123'::bigint) + Presorted Key: i0.f1 + -> Merge Left Join + Output: i0.f1, ('123'::bigint), i1.f1, i2.q1, i2.q2 + Merge Cond: (i0.f1 = i1.f1) + -> Sort + Output: i0.f1 + Sort Key: i0.f1 + -> Foreign Scan on public.int4_tbl i0 + Output: i0.f1 + InfluxDB query: SELECT "f1" FROM "int4_tbl" + -> Sort + Output: i1.f1, i2.q1, i2.q2, ('123'::bigint) + Sort Key: i1.f1 + -> Nested Loop Left Join + Output: i1.f1, i2.q1, i2.q2, '123'::bigint + -> Foreign Scan on public.int4_tbl i1 + Output: i1.f1 + InfluxDB query: SELECT "f1" FROM "int4_tbl" + -> Materialize + Output: i2.q1, i2.q2 + -> Foreign Scan on public.int8_tbl i2 + Output: i2.q1, i2.q2 + InfluxDB query: SELECT "q1", "q2" FROM "int8_tbl" WHERE ((123 = "q2")) +(26 rows) + +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; + f1 | x | f1 | q1 | q2 +-------------+-----+-------------+------------------+----- + -2147483647 | 123 | -2147483647 | 4567890123456789 | 123 + -123456 | 123 | -123456 | 4567890123456789 | 123 + 0 | 123 | 0 | 4567890123456789 | 123 + 123456 | 123 | 123456 | 4567890123456789 | 123 + 2147483647 | 123 | 2147483647 | 4567890123456789 | 123 +(5 rows) + -- -- test successful handling of nested outer joins with degenerate join quals -- ---Testcase 328: +--Testcase 340: create foreign table text_tbl(f1 text) server influxdb_svr; ---Testcase 329: +--Testcase 341: explain (verbose, costs off) select t1.* from text_tbl t1 @@ -4127,7 +4847,7 @@ select t1.* from -> Sort Output: i8.q2, (NULL::integer) Sort Key: (NULL::integer) - -> Merge Left Join + -> Merge Join Output: i8.q2, (NULL::integer) Merge Cond: (i8.q1 = i8b2.q1) -> Sort @@ -4144,7 +4864,7 @@ select t1.* from InfluxDB query: SELECT "q1" FROM "int8_tbl" (49 rows) ---Testcase 330: +--Testcase 342: select t1.* from text_tbl t1 left join (select *, '***'::text as d1 from int8_tbl i8b1) b1 @@ -4161,7 +4881,7 @@ select t1.* from hi de ho neighbor (2 rows) ---Testcase 331: +--Testcase 343: explain (verbose, costs off) select t1.* from text_tbl t1 @@ -4231,7 +4951,7 @@ select t1.* from InfluxDB query: SELECT "f1" FROM "int4_tbl" (54 rows) ---Testcase 332: +--Testcase 344: select t1.* from text_tbl t1 left join (select *, '***'::text as d1 from int8_tbl i8b1) b1 @@ -4248,7 +4968,7 @@ select t1.* from hi de ho neighbor (2 rows) ---Testcase 333: +--Testcase 345: explain (verbose, costs off) select t1.* from text_tbl t1 @@ -4327,7 +5047,7 @@ select t1.* from InfluxDB query: SELECT "f1" FROM "int4_tbl" (62 rows) ---Testcase 334: +--Testcase 346: select t1.* from text_tbl t1 left join (select *, '***'::text as d1 from int8_tbl i8b1) b1 @@ -4345,7 +5065,7 @@ select t1.* from hi de ho neighbor (2 rows) ---Testcase 335: +--Testcase 347: explain (verbose, costs off) select * from text_tbl t1 @@ -4384,7 +5104,7 @@ select * from InfluxDB query: SELECT "f1" FROM "text_tbl" WHERE (("f1" = 'doh!')) (25 rows) ---Testcase 336: +--Testcase 348: select * from text_tbl t1 inner join int8_tbl i8 @@ -4399,10 +5119,57 @@ select * from doh! | 123 | 456 | hi de ho neighbor | (2 rows) +-- 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; + QUERY PLAN +-------------------------------- + Nested Loop Left Join + Join Filter: false + -> Result + -> Result + One-Time Filter: false +(5 rows) + +-- 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; + QUERY PLAN +----------------------------------------------------------- + Nested Loop Left Join + -> Result + -> Nested Loop + -> Nested Loop Left Join + Join Filter: NULL::boolean + Filter: (((1) IS NULL) OR (i8.q1 <> i8.q2)) + -> Nested Loop Left Join + Join Filter: (i4.f1 IS NOT NULL) + -> Foreign Scan on int4_tbl i4 + -> Materialize + -> Foreign Scan on int8_tbl i8 + -> Result + One-Time Filter: false + -> Materialize + -> Foreign Scan on int4_tbl i42 +(15 rows) + -- -- test for appropriate join order in the presence of lateral references -- ---Testcase 337: +--Testcase 349: explain (verbose, costs off) select * from text_tbl t1 @@ -4425,14 +5192,12 @@ where t1.f1 = ss.f1; -> Foreign Scan on public.int8_tbl i8 Output: i8.q1, i8.q2 InfluxDB query: SELECT "q1", "q2" FROM "int8_tbl" WHERE (("q2" = 123)) - -> Limit - Output: (i8.q1), t2.f1 - -> Foreign Scan on public.text_tbl t2 - Output: i8.q1, t2.f1 - InfluxDB query: SELECT "f1" FROM "text_tbl" -(18 rows) + -> Foreign Scan on public.text_tbl t2 + Output: i8.q1, t2.f1 + InfluxDB query: SELECT "f1" FROM "text_tbl" LIMIT 1 +(16 rows) ---Testcase 338: +--Testcase 350: select * from text_tbl t1 left join int8_tbl i8 @@ -4444,7 +5209,7 @@ where t1.f1 = ss.f1; doh! | 4567890123456789 | 123 | 4567890123456789 | doh! (1 row) ---Testcase 339: +--Testcase 351: explain (verbose, costs off) select * from text_tbl t1 @@ -4470,19 +5235,15 @@ where t1.f1 = ss2.f1; -> Foreign Scan on public.int8_tbl i8 Output: i8.q1, i8.q2 InfluxDB query: SELECT "q1", "q2" FROM "int8_tbl" WHERE (("q2" = 123)) - -> Limit - Output: (i8.q1), t2.f1 - -> Foreign Scan on public.text_tbl t2 - Output: i8.q1, t2.f1 - InfluxDB query: SELECT "f1" FROM "text_tbl" - -> Limit - Output: ((i8.q1)), (t2.f1) - -> Foreign Scan on public.text_tbl t3 - Output: (i8.q1), t2.f1 - InfluxDB query: SELECT * FROM "text_tbl" -(25 rows) + -> Foreign Scan on public.text_tbl t2 + Output: i8.q1, t2.f1 + InfluxDB query: SELECT "f1" FROM "text_tbl" LIMIT 1 + -> Foreign Scan on public.text_tbl t3 + Output: (i8.q1), t2.f1 + InfluxDB query: SELECT * FROM "text_tbl" LIMIT 1 +(21 rows) ---Testcase 340: +--Testcase 352: select * from text_tbl t1 left join int8_tbl i8 @@ -4495,7 +5256,7 @@ where t1.f1 = ss2.f1; doh! | 4567890123456789 | 123 | 4567890123456789 | doh! | 4567890123456789 | doh! (1 row) ---Testcase 341: +--Testcase 353: explain (verbose, costs off) select 1 from text_tbl as tt1 @@ -4504,44 +5265,44 @@ select 1 from left join text_tbl as tt4 on (tt3.f1 = tt4.f1), lateral (select tt4.f1 as c0 from text_tbl as tt5 limit 1) as ss1 where tt1.f1 = ss1.c0; - QUERY PLAN ----------------------------------------------------------------------------------------------- + QUERY PLAN +---------------------------------------------------------------------------------------------------- Nested Loop Output: 1 - -> Nested Loop Left Join + -> Hash Left Join Output: tt1.f1, tt4.f1 - -> Nested Loop - Output: tt1.f1 - -> Foreign Scan on public.text_tbl tt2 - Output: tt2.f1 - InfluxDB query: SELECT * FROM "text_tbl" - -> Materialize + Hash Cond: (tt3.f1 = tt4.f1) + -> Nested Loop Left Join + Output: tt1.f1, tt3.f1 + -> Nested Loop Output: tt1.f1 - -> Foreign Scan on public.text_tbl tt1 + -> Foreign Scan on public.text_tbl tt2 + Output: tt2.f1 + InfluxDB query: SELECT * FROM "text_tbl" + -> Materialize Output: tt1.f1 + -> Foreign Scan on public.text_tbl tt1 + Output: tt1.f1 + InfluxDB query: SELECT "f1" FROM "text_tbl" WHERE (("f1" = 'foo')) + -> Materialize + Output: tt3.f1 + -> Foreign Scan on public.text_tbl tt3 + Output: tt3.f1 InfluxDB query: SELECT "f1" FROM "text_tbl" WHERE (("f1" = 'foo')) - -> Hash Left Join + -> Hash Output: tt4.f1 - Hash Cond: (tt3.f1 = tt4.f1) - -> Foreign Scan on public.text_tbl tt3 - Output: tt3.f1 - InfluxDB query: SELECT "f1" FROM "text_tbl" WHERE (("f1" = 'foo')) - -> Hash + -> Foreign Scan on public.text_tbl tt4 Output: tt4.f1 - -> Foreign Scan on public.text_tbl tt4 - Output: tt4.f1 - InfluxDB query: SELECT "f1" FROM "text_tbl" WHERE (("f1" = 'foo')) + InfluxDB query: SELECT "f1" FROM "text_tbl" WHERE (("f1" = 'foo')) -> Subquery Scan on ss1 Output: ss1.c0 Filter: (ss1.c0 = 'foo'::text) - -> Limit - Output: (tt4.f1) - -> Foreign Scan on public.text_tbl tt5 - Output: tt4.f1 - InfluxDB query: SELECT * FROM "text_tbl" + -> Foreign Scan on public.text_tbl tt5 + Output: tt4.f1 + InfluxDB query: SELECT * FROM "text_tbl" LIMIT 1 (33 rows) ---Testcase 342: +--Testcase 354: select 1 from text_tbl as tt1 inner join text_tbl as tt2 on (tt1.f1 = 'foo') @@ -4553,10 +5314,59 @@ where tt1.f1 = ss1.c0; ---------- (0 rows) +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; + QUERY PLAN +-------------------------- + Result + Output: 1 + One-Time Filter: false +(3 rows) + +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; + ?column? +---------- +(0 rows) + +-- +-- check a case where we formerly generated invalid parameterized paths +-- +begin; +CREATE FOREIGN TABLE temp_t (a int) SERVER influxdb_svr; +explain (costs off) +select 1 from temp_t t1 + join lateral (select t1.a from (select 1) foo offset 0) as s1 on true + join + (select 1 from temp_t t2 + inner join (temp_t t3 + left join (temp_t t4 left join temp_t t5 on t4.a = 1) + on t3.a = t4.a) + on false + where t3.a = coalesce(t5.a,1)) as s2 + on true; + QUERY PLAN +-------------------------- + Result + One-Time Filter: false +(2 rows) + +rollback; -- -- check a case in which a PlaceHolderVar forces join order -- ---Testcase 343: +--Testcase 355: explain (verbose, costs off) select ss2.* from int4_tbl i41 @@ -4600,14 +5410,12 @@ where ss1.c2 = 0; -> Foreign Scan on public.int4_tbl i43 Output: i43.f1 InfluxDB query: SELECT "f1" FROM "int4_tbl" WHERE (("f1" = 0)) - -> Limit - Output: (i41.f1), (i8.q1), (i8.q2), (i42.f1), (i43.f1), ((42)) - -> Foreign Scan on public.text_tbl - Output: i41.f1, i8.q1, i8.q2, i42.f1, i43.f1, (42) - InfluxDB query: SELECT * FROM "text_tbl" -(36 rows) + -> Foreign Scan on public.text_tbl + Output: i41.f1, i8.q1, i8.q2, i42.f1, i43.f1, (42) + InfluxDB query: SELECT * FROM "text_tbl" LIMIT 1 +(34 rows) ---Testcase 344: +--Testcase 356: select ss2.* from int4_tbl i41 left join int8_tbl i8 @@ -4624,7 +5432,7 @@ where ss1.c2 = 0; -- -- test successful handling of full join underneath left join (bug #14105) -- ---Testcase 345: +--Testcase 357: explain (costs off) select * from (select 1 as id) as xx @@ -4634,16 +5442,16 @@ select * from QUERY PLAN --------------------------------------- Nested Loop Left Join - Join Filter: ((1) = COALESCE((1))) -> Result -> Hash Full Join Hash Cond: (a1.unique1 = (1)) + Filter: (1 = COALESCE((1))) -> Foreign Scan on tenk1 a1 -> Hash -> Result (8 rows) ---Testcase 346: +--Testcase 358: select * from (select 1 as id) as xx left join @@ -4657,43 +5465,38 @@ select * from -- -- test ability to push constants through outer join clauses -- ---Testcase 347: +--Testcase 359: explain (costs off) select * from int4_tbl a left join tenk1 b on f1 = unique2 where f1 = 0; QUERY PLAN ------------------------------------- - Hash Left Join - Hash Cond: (a.f1 = b.unique2) + Nested Loop Left Join -> Foreign Scan on int4_tbl a - -> Hash + -> Materialize -> Foreign Scan on tenk1 b -(5 rows) +(4 rows) ---Testcase 348: +--Testcase 360: explain (costs off) select * from tenk1 a full join tenk1 b using(unique2) where unique2 = 42; - QUERY PLAN ---------------------------------------- + QUERY PLAN +------------------------------------- Merge Full Join - Merge Cond: (a.unique2 = b.unique2) - -> Sort - Sort Key: a.unique2 - -> Foreign Scan on tenk1 a - -> Sort - Sort Key: b.unique2 + -> Foreign Scan on tenk1 a + -> Materialize -> Foreign Scan on tenk1 b -(8 rows) +(4 rows) -- -- test that quals attached to an outer join have correct semantics, -- specifically that they don't re-use expressions computed below the join; -- we force a mergejoin so that coalesce(b.q1, 1) appears as a join input -- ---Testcase 349: +--Testcase 361: set enable_hashjoin to off; ---Testcase 350: +--Testcase 362: set enable_nestloop to off; ---Testcase 351: +--Testcase 363: 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) @@ -4718,7 +5521,7 @@ explain (verbose, costs off) InfluxDB query: SELECT "q1" FROM "int8_tbl" (16 rows) ---Testcase 352: +--Testcase 364: 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; @@ -4736,32 +5539,152 @@ select a.q2, b.q1 4567890123456789 | 4567890123456789 (10 rows) ---Testcase 353: +--Testcase 365: reset enable_hashjoin; ---Testcase 354: +--Testcase 366: reset enable_nestloop; +-- +-- 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 = any (select q1 from int8_tbl c where c.q1 < b.unique1); + QUERY PLAN +------------------------------------------------ + Merge Join + Merge Cond: (b.unique2 = a.unique1) + -> Sort + Sort Key: b.unique2 + -> Foreign Scan on onek b + Filter: (SubPlan 1) + SubPlan 1 + -> Foreign Scan on int8_tbl c + -> Sort + Sort Key: a.unique1 + -> Foreign Scan on onek a +(11 rows) + +select a.unique1, b.unique2 + from onek a left join onek b on a.unique1 = b.unique2 + where b.unique2 = any (select q1 from int8_tbl c where c.q1 < b.unique1); + unique1 | unique2 +---------+--------- + 123 | 123 +(1 row) + +-- +-- 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; + QUERY PLAN +------------------------------------ + Nested Loop Left Join + -> Foreign Scan on onek a + -> Materialize + -> Foreign Scan on onek b +(4 rows) + +select a.unique1, b.unique2 + from onek a full join onek b on a.unique1 = b.unique2 + where a.unique1 = 42; + unique1 | unique2 +---------+--------- + 42 | 42 +(1 row) + +explain (costs off) +select a.unique1, b.unique2 + from onek a full join onek b on a.unique1 = b.unique2 + where b.unique2 = 43; + QUERY PLAN +------------------------------------ + Nested Loop Left Join + -> Foreign Scan on onek b + -> Materialize + -> Foreign Scan on onek a +(4 rows) + +select a.unique1, b.unique2 + from onek a full join onek b on a.unique1 = b.unique2 + where b.unique2 = 43; + unique1 | unique2 +---------+--------- + 43 | 43 +(1 row) + +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; + QUERY PLAN +------------------------------------ + Nested Loop + -> Foreign Scan on onek a + -> Materialize + -> Foreign Scan on onek b +(4 rows) + +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; + unique1 | unique2 +---------+--------- + 42 | 42 +(1 row) + +-- +-- 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; + QUERY PLAN +------------------------------------------ + Merge Full Join + -> Foreign Scan on int8_tbl i81 + -> Materialize + -> Foreign Scan on int8_tbl i82 +(4 rows) + +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; + q1 | q2 | v1 | v2 | v1 | v2 | q1 | q2 +------------------+-----+-----+----+-----+----+-----+----- + 4567890123456789 | 123 | 123 | 2 | 456 | 2 | 123 | 456 +(1 row) + -- -- test join removal -- begin; ---Testcase 355: +--Testcase 367: CREATE FOREIGN TABLE a (id int, b_id int) SERVER influxdb_svr; ---Testcase 356: +--Testcase 368: CREATE FOREIGN TABLE b (id int, c_id int) SERVER influxdb_svr; ---Testcase 357: +--Testcase 369: CREATE FOREIGN TABLE c (id int) SERVER influxdb_svr; ---Testcase 358: +--Testcase 370: CREATE FOREIGN TABLE d (a int, b int) SERVER influxdb_svr; ---Testcase 359: +--Testcase 371: INSERT INTO a VALUES (0, 0), (1, NULL); ---Testcase 360: +--Testcase 372: INSERT INTO b VALUES (0, 0), (1, NULL); ---Testcase 361: +--Testcase 373: INSERT INTO c VALUES (0), (1); ---Testcase 362: +--Testcase 374: INSERT INTO d VALUES (1,3), (2,2), (3,1); -- all three cases should be optimizable into a simple seqscan ---Testcase 363: +--Testcase 375: explain (costs off) SELECT a.* FROM a LEFT JOIN b ON a.b_id = b.id; QUERY PLAN ------------------------------- @@ -4775,7 +5698,7 @@ explain (costs off) SELECT a.* FROM a LEFT JOIN b ON a.b_id = b.id; -> Foreign Scan on b (8 rows) ---Testcase 364: +--Testcase 376: explain (costs off) SELECT b.* FROM b LEFT JOIN c ON b.c_id = c.id; QUERY PLAN ------------------------------- @@ -4789,7 +5712,7 @@ explain (costs off) SELECT b.* FROM b LEFT JOIN c ON b.c_id = c.id; -> Foreign Scan on c (8 rows) ---Testcase 365: +--Testcase 377: 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); @@ -4813,7 +5736,7 @@ explain (costs off) (15 rows) -- check optimization of outer join within another special join ---Testcase 366: +--Testcase 378: explain (costs off) select id from a where id in ( select b.id from b left join c on b.id = c.id @@ -4836,9 +5759,244 @@ select id from a where id in ( -> Foreign Scan on c (14 rows) +-- 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; + QUERY PLAN +---------------------------------------------------------- + Nested Loop Left Join + -> Foreign Scan on a a1 + -> Materialize + -> Merge Left Join + Merge Cond: (a2.id = a3.id) + -> Sort + Sort Key: a2.id + -> Foreign Scan on a a2 + -> Materialize + -> Merge Left Join + Merge Cond: (a3.id = a4.id) + -> Sort + Sort Key: a3.id + -> Foreign Scan on a a3 + -> Sort + Sort Key: a4.id + -> Foreign Scan on a a4 +(17 rows) + +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; + QUERY PLAN +---------------------------------------------- + Merge Right Join + Merge Cond: (a3.id = a2.id) + -> Merge Left Join + Merge Cond: (a3.id = a4.id) + -> Sort + Sort Key: a3.id + -> Foreign Scan on a a3 + -> Sort + Sort Key: a4.id + -> Foreign Scan on a a4 + -> Sort + Sort Key: a2.id + -> Merge Left Join + Merge Cond: (a1.id = a2.id) + -> Sort + Sort Key: a1.id + -> Foreign Scan on a a1 + -> Sort + Sort Key: a2.id + -> Foreign Scan on a a2 +(20 rows) + +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; + QUERY PLAN +---------------------------------------------------- + Merge Left Join + Merge Cond: (t2.id = t4.id) + Join Filter: (t2.id = t3.id) + -> Sort + Sort Key: t2.id + -> Nested Loop + -> Nested Loop Left Join + -> Foreign Scan on a t1 + -> Materialize + -> Foreign Scan on a t2 + -> Materialize + -> Foreign Scan on a t3 + -> Sort + Sort Key: t4.id + -> Foreign Scan on a t4 +(15 rows) + +-- 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; + QUERY PLAN +----------------------------------- + Nested Loop Left Join + Join Filter: false + -> Foreign Scan on int4_tbl t1 + -> Result + One-Time Filter: false +(5 rows) + +-- 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; + QUERY PLAN +----------------------------------- + Nested Loop Left Join + Join Filter: false + -> Foreign Scan on int4_tbl t1 + -> Result + One-Time Filter: false +(5 rows) + +-- 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; -- this is to add a Result node + QUERY PLAN +----------------------------------------------------------- + Result + One-Time Filter: (CURRENT_USER IS NOT NULL) + -> Nested Loop Left Join + -> Foreign Scan on int8_tbl i8 + -> Materialize + -> Merge Left Join + Merge Cond: (i4.f1 = a.id) + -> Sort + Sort Key: i4.f1 + -> Foreign Scan on int4_tbl i4 + -> Sort + Sort Key: a.id + -> Foreign Scan on a +(13 rows) + +-- 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; + QUERY PLAN +------------------------------------------------- + Hash Right Join + Hash Cond: (t2.q2 = t1.q2) + -> Nested Loop Left Join + Join Filter: (t2.q2 < t3.unique2) + -> Nested Loop Left Join + Join Filter: (t2.q1 > t3.unique1) + -> Foreign Scan on int8_tbl t2 + -> Materialize + -> Foreign Scan on onek t3 + -> Materialize + -> Foreign Scan on onek t4 + -> Hash + -> Foreign Scan on int8_tbl t1 +(13 rows) + +-- 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; + QUERY PLAN +-------------------------------------- + Hash Left Join + Hash Cond: (t1.q1 = q1) + -> Foreign Scan on int8_tbl t1 + -> Hash + -> Result + One-Time Filter: false +(6 rows) + +-- 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; + QUERY PLAN +-------------------------------------- + Hash Left Join + Hash Cond: (t1.q1 = q1) + -> Foreign Scan on int8_tbl t1 + -> Hash + -> Result + One-Time Filter: false +(6 rows) + +-- 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; + QUERY PLAN +------------------------------------------------------------------------- + Foreign Scan on int4_tbl x0 + SubPlan 1 + -> Nested Loop Left Join + Join Filter: (t2.q2 = t4.q2) + -> Nested Loop Left Join + Join Filter: (t1.q1 = t2.q1) + -> Foreign Scan on int8_tbl t1 + -> Materialize + -> Result + One-Time Filter: (x0.f1 = 1) + -> Nested Loop + -> Foreign Scan on int8_tbl t3 + -> Materialize + -> Foreign Scan on int8_tbl t2 + -> Materialize + -> Foreign Scan on int8_tbl t4 +(16 rows) + -- check that join removal works for a left join when joining a subquery -- that is guaranteed to be unique by its GROUP BY clause ---Testcase 367: +--Testcase 379: 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; @@ -4848,7 +6006,7 @@ select d.* from d left join (select * from b group by b.id, b.c_id) s (1 row) -- similarly, but keying off a DISTINCT clause ---Testcase 368: +--Testcase 380: 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; @@ -4861,7 +6019,7 @@ select d.* from d left join (select distinct * from b) s -- 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.) ---Testcase 369: +--Testcase 381: 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; @@ -4878,7 +6036,7 @@ select d.* from d left join (select * from b group by b.id, b.c_id) s (8 rows) -- similarly, but keying off a DISTINCT clause ---Testcase 370: +--Testcase 382: explain (costs off) select d.* from d left join (select distinct * from b) s on d.a = s.id; @@ -4894,9 +6052,25 @@ select d.* from d left join (select distinct * from b) s -> Foreign Scan on b (8 rows) +-- 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; + QUERY PLAN +---------------------------------------------- + Nested Loop Left Join + -> Foreign Scan on a t1 + -> Materialize + -> Nested Loop Left Join + Join Filter: (t2.id = 1) + -> Foreign Scan on a t2 + -> Materialize + -> Foreign Scan on a t3 +(8 rows) + -- check join removal works when uniqueness of the join condition is enforced -- by a UNION ---Testcase 371: +--Testcase 383: explain (costs off) select d.* from d left join (select id from a union select id from b) s on d.a = s.id; @@ -4906,7 +6080,7 @@ select d.* from d left join (select id from a union select id from b) s (1 row) -- check join removal with a cross-type comparison operator ---Testcase 372: +--Testcase 384: 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; @@ -4916,7 +6090,7 @@ select i8.* from int8_tbl i8 left join (select f1 from int4_tbl group by f1) i4 (1 row) -- check join removal with lateral references ---Testcase 373: +--Testcase 385: 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; @@ -4935,33 +6109,68 @@ select 1 from (select a.id FROM a left join b on a.b_id = b.id) q, Filter: (a.id = i) (11 rows) ---Testcase 374: +-- 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; + QUERY PLAN +-------------------------------------------------- + Merge Left Join + Merge Cond: (c.id = d.a) + -> Sort + Sort Key: c.id + -> Foreign Scan on c + -> Materialize + -> Merge Left Join + Merge Cond: (d.a = b.id) + -> Sort + Sort Key: d.a + -> Nested Loop + -> Seq Scan on onerow + -> Foreign Scan on d + -> Sort + Sort Key: b.id + -> Foreign Scan on b +(16 rows) + +CREATE TEMP TABLE parted_b (id int PRIMARY KEY) partition by range(id); +CREATE TEMP TABLE parted_b1 partition of parted_b for values from (0) to (10); +-- 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; + QUERY PLAN +------------------- + Foreign Scan on a +(1 row) + +--Testcase 386: DELETE FROM a; ---Testcase 375: +--Testcase 387: DELETE FROM b; ---Testcase 376: +--Testcase 388: DELETE FROM c; ---Testcase 377: +--Testcase 389: DELETE FROM d; ---Testcase 378: +--Testcase 390: DROP FOREIGN TABLE a; ---Testcase 379: +--Testcase 391: DROP FOREIGN TABLE b; ---Testcase 380: +--Testcase 392: DROP FOREIGN TABLE c; ---Testcase 381: +--Testcase 393: DROP FOREIGN TABLE d; rollback; ---Testcase 382: +--Testcase 394: create foreign table parent (k int, pd int) server influxdb_svr; ---Testcase 383: +--Testcase 395: create foreign table child (k int, cd int) server influxdb_svr; ---Testcase 384: +--Testcase 396: insert into parent values (1, 10), (2, 20), (3, 30); ---Testcase 385: +--Testcase 397: insert into child values (1, 100), (4, 400); -- this case is optimizable ---Testcase 386: +--Testcase 398: select p.* from parent p left join child c on (p.k = c.k); k | pd ---+---- @@ -4970,7 +6179,7 @@ select p.* from parent p left join child c on (p.k = c.k); 3 | 30 (3 rows) ---Testcase 387: +--Testcase 399: explain (costs off) select p.* from parent p left join child c on (p.k = c.k); QUERY PLAN @@ -4986,7 +6195,7 @@ explain (costs off) (8 rows) -- this case is not ---Testcase 388: +--Testcase 400: select p.*, linked from parent p left join (select c.*, true as linked from child c) as ss on (p.k = ss.k); @@ -4997,7 +6206,7 @@ select p.*, linked from parent p 3 | 30 | (3 rows) ---Testcase 389: +--Testcase 401: explain (costs off) select p.*, linked from parent p left join (select c.*, true as linked from child c) as ss @@ -5015,7 +6224,7 @@ explain (costs off) (8 rows) -- check for a 9.0rc1 bug: join removal breaks pseudoconstant qual handling ---Testcase 390: +--Testcase 402: select p.* from parent p left join child c on (p.k = c.k) where p.k = 1 and p.k = 2; @@ -5023,7 +6232,7 @@ select p.* from ---+---- (0 rows) ---Testcase 391: +--Testcase 403: explain (costs off) select p.* from parent p left join child c on (p.k = c.k) @@ -5034,7 +6243,7 @@ select p.* from One-Time Filter: false (2 rows) ---Testcase 392: +--Testcase 404: 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; @@ -5042,7 +6251,7 @@ select p.* from ---+---- (0 rows) ---Testcase 393: +--Testcase 405: 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 @@ -5055,44 +6264,44 @@ select p.* from -- bug 5255: this is not optimizable by join removal begin; ---Testcase 394: +--Testcase 406: CREATE FOREIGN TABLE a (id int) SERVER influxdb_svr; ---Testcase 395: +--Testcase 407: CREATE FOREIGN TABLE b (id int, a_id int) SERVER influxdb_svr; ---Testcase 396: +--Testcase 408: INSERT INTO a VALUES (0), (1); ---Testcase 397: +--Testcase 409: INSERT INTO b VALUES (0, 0), (1, NULL); ---Testcase 398: +--Testcase 410: SELECT * FROM b LEFT JOIN a ON (b.a_id = a.id) WHERE (a.id IS NULL OR a.id > 0); id | a_id | id ----+------+---- 1 | | (1 row) ---Testcase 399: +--Testcase 411: SELECT b.* FROM b LEFT JOIN a ON (b.a_id = a.id) WHERE (a.id IS NULL OR a.id > 0); id | a_id ----+------ 1 | (1 row) ---Testcase 400: +--Testcase 412: DELETE FROM a; ---Testcase 401: +--Testcase 413: DELETE FROM b; ---Testcase 402: +--Testcase 414: DROP FOREIGN TABLE a; ---Testcase 403: +--Testcase 415: DROP FOREIGN TABLE b; rollback; -- another join removal bug: this is not optimizable, either begin; ---Testcase 404: +--Testcase 416: create foreign table innertab (id int8, dat1 int8) server influxdb_svr; ---Testcase 405: +--Testcase 417: insert into innertab values(123, 42); ---Testcase 406: +--Testcase 418: SELECT * FROM (SELECT 1 AS x) ss1 LEFT JOIN @@ -5108,15 +6317,77 @@ SELECT * FROM 1 | 4567890123456789 | 4567890123456789 | 4567890123456789 (5 rows) +-- 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; + QUERY PLAN +---------------------------------------------------------------- + Merge Left Join + Merge Cond: (int8_tbl.q2 = innertab.id) + Filter: (COALESCE(innertab.dat1, '0'::bigint) = int8_tbl.q1) + -> Sort + Sort Key: int8_tbl.q2 + -> Foreign Scan on int8_tbl + -> Sort + Sort Key: innertab.id + -> Foreign Scan on innertab +(9 rows) + +-- 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; + QUERY PLAN +------------------------------------------------------ + Nested Loop Left Join + Output: q2 + Join Filter: NULL::boolean + Filter: (('constant'::text) >= ('constant'::text)) + -> Foreign Scan on public.int4_tbl + Output: int4_tbl.f1 + InfluxDB query: SELECT * FROM "int4_tbl" + -> Result + Output: q2, 'constant'::text + One-Time Filter: false +(10 rows) + +-- 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; + QUERY PLAN +-------------------------------------------------------------------------- + Nested Loop + -> Foreign Scan on int4_tbl + -> Materialize + -> Nested Loop Left Join + Join Filter: NULL::boolean + Filter: ((tenk1.unique1 = (42)) OR (tenk1.unique2 = (42))) + -> Foreign Scan on tenk1 + -> Result + One-Time Filter: false +(9 rows) + -- Clean up +--Testcase 581: DELETE FROM innertab; +--Testcase 582: DROP FOREIGN TABLE innertab; rollback; -- another join removal bug: we must clean up correctly when removing a PHV begin; ---Testcase 407: +--Testcase 419: create foreign table uniquetbl (f1 text) server influxdb_svr; ---Testcase 408: +--Testcase 420: explain (costs off) select t1.* from uniquetbl as t1 @@ -5140,7 +6411,7 @@ select t1.* from -> Foreign Scan on uniquetbl (12 rows) ---Testcase 409: +--Testcase 421: explain (costs off) select t0.* from @@ -5163,12 +6434,12 @@ where ss.stringu2 !~* ss.case1; -> Sort Sort Key: t1.unique2 -> Merge Right Join - Merge Cond: (u1.f1 = ((t1.string4)::text)) + Merge Cond: (u1.f1 = t1.string4) -> Sort - Sort Key: u1.f1 + Sort Key: u1.f1 COLLATE "C" -> Foreign Scan on uniquetbl u1 -> Sort - Sort Key: ((t1.string4)::text) + Sort Key: t1.string4 -> Merge Join Merge Cond: ((CASE t1.ten WHEN 0 THEN 'doh!'::text ELSE NULL::text END) = t0.f1) -> Sort @@ -5180,7 +6451,7 @@ where ss.stringu2 !~* ss.case1; -> Foreign Scan on text_tbl t0 (23 rows) ---Testcase 410: +--Testcase 422: select t0.* from text_tbl t0 @@ -5197,9 +6468,120 @@ where ss.stringu2 !~* ss.case1; doh! (1 row) +rollback; +-- another join removal bug: we must clean up EquivalenceClasses too +begin; +create foreign table t (a int) server influxdb_svr OPTIONS (table 't1_eq_class'); +insert into t values (1); +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; + QUERY PLAN +---------------------------------------------- + Nested Loop Left Join + Filter: (t1.a = (2)) + -> Foreign Scan on t t1 + -> Materialize + -> Merge Left Join + Merge Cond: (t2.a = t3.a) + -> Sort + Sort Key: t2.a + -> Foreign Scan on t t2 + -> Sort + Sort Key: t3.a + -> Foreign Scan on t t3 +(12 rows) + +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; + ?column? +---------- +(0 rows) + +delete from t; +rollback; +-- test cases where we can remove a join, but not a PHV computed at it +begin; +create foreign table t (a int, b int) server influxdb_svr OPTIONS (table 't2_eq_class'); +insert into t values (1,1), (2,2); +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; + QUERY PLAN +---------------------------------------------- + Nested Loop Left Join + -> Nested Loop + -> Merge Left Join + Merge Cond: (t2.a = t3.a) + Filter: (t2.a < 1) + -> Sort + Sort Key: t2.a + -> Foreign Scan on t t2 + -> Sort + Sort Key: t3.a + -> Foreign Scan on t t3 + -> Materialize + -> Foreign Scan on t t1 + -> Materialize + -> Foreign Scan on t t4 +(15 rows) + +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; + QUERY PLAN +-------------------------------------------------- + Nested Loop Left Join + -> Nested Loop + -> Foreign Scan on t t1 + -> Merge Left Join + Merge Cond: (t2.a = t3.a) + Filter: (t2.a < COALESCE(t1.a, 1)) + -> Sort + Sort Key: t2.a + -> Foreign Scan on t t2 + -> Sort + Sort Key: t3.a + -> Foreign Scan on t t3 + -> Materialize + -> Foreign Scan on t t4 +(14 rows) + +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; + a | a | c +---+---+--- + 2 | 1 | 2 + 2 | 1 | 2 +(2 rows) + +delete from t; rollback; -- test case to expose miscomputation of required relid set for a PHV ---Testcase 411: +--Testcase 423: explain (verbose, costs off) select i8.*, ss.v, t.unique2 from int8_tbl i8 @@ -5207,15 +6589,18 @@ select i8.*, ss.v, t.unique2 left join lateral (select i4.f1 + 1 as v) as ss on true left join tenk1 t on t.unique2 = ss.v where q2 = 456; - QUERY PLAN --------------------------------------------------------------------------------------------- - Hash Left Join + QUERY PLAN +--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- + Hash Right Join Output: i8.q1, i8.q2, ((i4.f1 + 1)), t.unique2 - Hash Cond: (((i4.f1 + 1)) = t.unique2) - -> Nested Loop Left Join + Hash Cond: (t.unique2 = ((i4.f1 + 1))) + -> Foreign Scan on public.tenk1 t + Output: t.unique1, t.unique2, t.two, t.four, t.ten, t.twenty, t.hundred, t.thousand, t.twothousand, t.fivethous, t.tenthous, t.odd, t.even, t.stringu1, t.stringu2, t.string4 + InfluxDB query: SELECT "unique2" FROM "tenk" + -> Hash Output: i8.q1, i8.q2, ((i4.f1 + 1)) -> Nested Loop Left Join - Output: i8.q1, i8.q2, i4.f1 + Output: i8.q1, i8.q2, (i4.f1 + 1) -> Foreign Scan on public.int8_tbl i8 Output: i8.q1, i8.q2 InfluxDB query: SELECT "q1", "q2" FROM "int8_tbl" WHERE (("q2" = 456)) @@ -5224,16 +6609,9 @@ where q2 = 456; -> Foreign Scan on public.int4_tbl i4 Output: i4.f1 InfluxDB query: SELECT "f1" FROM "int4_tbl" WHERE (("f1" = 1)) - -> Result - Output: (i4.f1 + 1) - -> Hash - Output: t.unique2 - -> Foreign Scan on public.tenk1 t - Output: t.unique2 - InfluxDB query: SELECT "unique2" FROM "tenk" -(22 rows) +(18 rows) ---Testcase 412: +--Testcase 424: select i8.*, ss.v, t.unique2 from int8_tbl i8 left join int4_tbl i4 on i4.f1 = 1 @@ -5245,21 +6623,55 @@ where q2 = 456; 123 | 456 | | (1 row) +-- InfluxDB does not support partition table, create local table for test +-- and check a related issue where we miscompute required relids for +-- a PHV that's been translated to a child rel +--Testcase 570: +create temp table parttbl (a integer primary key) partition by range (a); +--Testcase 571: +create temp table parttbl1 partition of parttbl for values from (1) to (100); +--Testcase 572: +insert into parttbl values (11), (12); +--Testcase 573: +explain (costs off) +select * from + (select *, 12 as phv from parttbl) as ss + right join int4_tbl on true +where ss.a = ss.phv and f1 = 0; + QUERY PLAN +------------------------------------------ + Nested Loop + -> Foreign Scan on int4_tbl + -> Materialize + -> Seq Scan on parttbl1 parttbl + Filter: (a = 12) +(5 rows) + +--Testcase 574: +select * from + (select *, 12 as phv from parttbl) as ss + right join int4_tbl on true +where ss.a = ss.phv and f1 = 0; + a | phv | f1 +----+-----+---- + 12 | 12 | 0 +(1 row) + -- bug #8444: we've historically allowed duplicate aliases within aliased JOINs ---Testcase 413: +--Testcase 425: select * from int8_tbl x join (int4_tbl x cross join int4_tbl y) j on q1 = f1; -- error ERROR: column reference "f1" is ambiguous LINE 2: ..._tbl x join (int4_tbl x cross join int4_tbl y) j on q1 = f1; ^ ---Testcase 414: +--Testcase 426: select * from int8_tbl x join (int4_tbl x cross join int4_tbl y) j on q1 = y.f1; -- error ERROR: invalid reference to FROM-clause entry for table "y" LINE 2: ...bl x join (int4_tbl x cross join int4_tbl y) j on q1 = y.f1; ^ -HINT: There is an entry for table "y", but it cannot be referenced from this part of the query. ---Testcase 415: +DETAIL: There is an entry for table "y", but it cannot be referenced from this part of the query. +--Testcase 427: select * from int8_tbl x join (int4_tbl x cross join int4_tbl y(ff)) j on q1 = f1; -- ok q1 | q2 | f1 | ff @@ -5269,31 +6681,38 @@ select * from -- -- Test hints given on incorrect column references are useful -- ---Testcase 416: +--Testcase 428: select t1.uunique1 from tenk1 t1 join tenk2 t2 on t1.two = t2.two; -- error, prefer "t1" suggestion ERROR: column t1.uunique1 does not exist LINE 1: select t1.uunique1 from ^ HINT: Perhaps you meant to reference the column "t1.unique1". ---Testcase 417: +--Testcase 429: select t2.uunique1 from tenk1 t1 join tenk2 t2 on t1.two = t2.two; -- error, prefer "t2" suggestion ERROR: column t2.uunique1 does not exist LINE 1: select t2.uunique1 from ^ HINT: Perhaps you meant to reference the column "t2.unique1". ---Testcase 418: +--Testcase 430: select uunique1 from tenk1 t1 join tenk2 t2 on t1.two = t2.two; -- error, suggest both at once ERROR: column "uunique1" does not exist LINE 1: select uunique1 from ^ HINT: Perhaps you meant to reference the column "t1.unique1" or the column "t2.unique1". +select ctid from + tenk1 t1 join tenk2 t2 on t1.two = t2.two; -- error, need qualification +ERROR: column "ctid" does not exist +LINE 1: select ctid from + ^ +DETAIL: There are columns named "ctid", but they are in tables that cannot be referenced from this part of the query. +HINT: Try using a table-qualified name. -- -- Take care to reference the correct RTE -- ---Testcase 556: +--Testcase 431: 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, @@ -5302,10 +6721,22 @@ select atts.relid::regclass, s.* from pg_stats s join ERROR: column atts.relid does not exist LINE 1: select atts.relid::regclass, s.* from pg_stats s join ^ +-- 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; + QUERY PLAN +-------------------------- + Result + Output: 1 + One-Time Filter: false +(3 rows) + -- -- Test LATERAL -- ---Testcase 419: +--Testcase 432: select unique2, x.* from tenk1 a, lateral (select * from int4_tbl b where f1 = a.unique1) x; unique2 | f1 @@ -5313,7 +6744,7 @@ from tenk1 a, lateral (select * from int4_tbl b where f1 = a.unique1) x; 9998 | 0 (1 row) ---Testcase 420: +--Testcase 433: explain (costs off) select unique2, x.* from tenk1 a, lateral (select * from int4_tbl b where f1 = a.unique1) x; @@ -5329,7 +6760,7 @@ explain (costs off) -> Foreign Scan on int4_tbl b (8 rows) ---Testcase 421: +--Testcase 434: select unique2, x.* from int4_tbl x, lateral (select unique2 from tenk1 where f1 = unique1) ss; unique2 | f1 @@ -5337,7 +6768,7 @@ from int4_tbl x, lateral (select unique2 from tenk1 where f1 = unique1) ss; 9998 | 0 (1 row) ---Testcase 422: +--Testcase 435: explain (costs off) select unique2, x.* from int4_tbl x, lateral (select unique2 from tenk1 where f1 = unique1) ss; @@ -5353,7 +6784,7 @@ explain (costs off) -> Foreign Scan on int4_tbl x (8 rows) ---Testcase 423: +--Testcase 436: explain (costs off) select unique2, x.* from int4_tbl x cross join lateral (select unique2 from tenk1 where f1 = unique1) ss; @@ -5369,7 +6800,7 @@ explain (costs off) -> Foreign Scan on int4_tbl x (8 rows) ---Testcase 424: +--Testcase 437: select unique2, x.* from int4_tbl x left join lateral (select unique1, unique2 from tenk1 where f1 = unique1) ss on true; unique2 | f1 @@ -5381,7 +6812,7 @@ from int4_tbl x left join lateral (select unique1, unique2 from tenk1 where f1 = | 2147483647 (5 rows) ---Testcase 425: +--Testcase 438: explain (costs off) select unique2, x.* from int4_tbl x left join lateral (select unique1, unique2 from tenk1 where f1 = unique1) ss on true; @@ -5399,7 +6830,7 @@ explain (costs off) -- check scoping of lateral versus parent references -- the first of these should return int8_tbl.q2, the second int8_tbl.q1 ---Testcase 426: +--Testcase 439: select *, (select r from (select q1 as q2) x, (select q2 as r) y) from int8_tbl; q1 | q2 | r ------------------+-------------------+------------------- @@ -5410,7 +6841,7 @@ select *, (select r from (select q1 as q2) x, (select q2 as r) y) from int8_tbl; 4567890123456789 | -4567890123456789 | -4567890123456789 (5 rows) ---Testcase 427: +--Testcase 440: select *, (select r from (select q1 as q2) x, lateral (select q2 as r) y) from int8_tbl; q1 | q2 | r ------------------+-------------------+------------------ @@ -5422,14 +6853,14 @@ select *, (select r from (select q1 as q2) x, lateral (select q2 as r) y) from i (5 rows) -- lateral with function in FROM ---Testcase 428: +--Testcase 441: select count(*) from tenk1 a, lateral generate_series(1,two) g; count ------- 5000 (1 row) ---Testcase 429: +--Testcase 442: explain (costs off) select count(*) from tenk1 a, lateral generate_series(1,two) g; QUERY PLAN @@ -5440,7 +6871,7 @@ explain (costs off) -> Function Scan on generate_series g (4 rows) ---Testcase 430: +--Testcase 443: explain (costs off) select count(*) from tenk1 a cross join lateral generate_series(1,two) g; QUERY PLAN @@ -5452,7 +6883,7 @@ explain (costs off) (4 rows) -- don't need the explicit LATERAL keyword for functions ---Testcase 431: +--Testcase 444: explain (costs off) select count(*) from tenk1 a, generate_series(1,two) g; QUERY PLAN @@ -5464,7 +6895,7 @@ explain (costs off) (4 rows) -- lateral with UNION ALL subselect ---Testcase 432: +--Testcase 445: explain (costs off) select * from generate_series(100,200) g, lateral (select * from int8_tbl a where g = q1 union all @@ -5478,7 +6909,7 @@ explain (costs off) -> Foreign Scan on int8_tbl b (5 rows) ---Testcase 433: +--Testcase 446: 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; @@ -5490,7 +6921,7 @@ select * from generate_series(100,200) g, (3 rows) -- lateral with VALUES ---Testcase 434: +--Testcase 447: explain (costs off) select count(*) from tenk1 a, tenk1 b join lateral (values(a.unique1)) ss(x) on b.unique2 = ss.x; @@ -5507,7 +6938,7 @@ explain (costs off) -> Foreign Scan on tenk1 b (9 rows) ---Testcase 435: +--Testcase 448: select count(*) from tenk1 a, tenk1 b join lateral (values(a.unique1)) ss(x) on b.unique2 = ss.x; count @@ -5516,7 +6947,7 @@ select count(*) from tenk1 a, (1 row) -- lateral with VALUES, no flattening possible ---Testcase 436: +--Testcase 449: explain (costs off) select count(*) from tenk1 a, tenk1 b join lateral (values(a.unique1),(-1)) ss(x) on b.unique2 = ss.x; @@ -5535,7 +6966,7 @@ explain (costs off) -> Values Scan on "*VALUES*" (11 rows) ---Testcase 437: +--Testcase 450: select count(*) from tenk1 a, tenk1 b join lateral (values(a.unique1),(-1)) ss(x) on b.unique2 = ss.x; count @@ -5544,7 +6975,7 @@ select count(*) from tenk1 a, (1 row) -- lateral injecting a strange outer join condition ---Testcase 438: +--Testcase 451: explain (costs off) select * from int8_tbl a, int8_tbl x left join lateral (select a.q1 from int4_tbl y) ss(z) @@ -5566,7 +6997,7 @@ explain (costs off) -> Foreign Scan on int4_tbl y (12 rows) ---Testcase 439: +--Testcase 452: 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 @@ -5633,7 +7064,7 @@ select * from int8_tbl a, (57 rows) -- lateral reference to a join alias variable ---Testcase 440: +--Testcase 453: select * from (select f1/2 as x from int4_tbl) ss1 join int4_tbl i4 on x = f1, lateral (select x) ss2(y); x | f1 | y @@ -5641,7 +7072,7 @@ select * from (select f1/2 as x from int4_tbl) ss1 join int4_tbl i4 on x = f1, 0 | 0 | 0 (1 row) ---Testcase 441: +--Testcase 454: select * from (select f1 as x from int4_tbl) ss1 join int4_tbl i4 on x = f1, lateral (values(x)) ss2(y); x | f1 | y @@ -5653,7 +7084,7 @@ select * from (select f1 as x from int4_tbl) ss1 join int4_tbl i4 on x = f1, 2147483647 | 2147483647 | 2147483647 (5 rows) ---Testcase 442: +--Testcase 455: select * from ((select f1/2 as x from int4_tbl) ss1 join int4_tbl i4 on x = f1) j, lateral (select x) ss2(y); x | f1 | y @@ -5662,7 +7093,7 @@ select * from ((select f1/2 as x from int4_tbl) ss1 join int4_tbl i4 on x = f1) (1 row) -- lateral references requiring pullup ---Testcase 443: +--Testcase 456: select * from (values(1)) x(lb), lateral generate_series(lb,4) x4; lb | x4 @@ -5673,7 +7104,7 @@ select * from (values(1)) x(lb), 1 | 4 (4 rows) ---Testcase 444: +--Testcase 457: select * from (select f1/1000000000 from int4_tbl) x(lb), lateral generate_series(lb,4) x4; lb | x4 @@ -5705,7 +7136,7 @@ select * from (select f1/1000000000 from int4_tbl) x(lb), -2 | 4 (25 rows) ---Testcase 445: +--Testcase 458: select * from (values(1)) x(lb), lateral (values(lb)) y(lbcopy); lb | lbcopy @@ -5713,7 +7144,7 @@ select * from (values(1)) x(lb), 1 | 1 (1 row) ---Testcase 446: +--Testcase 459: select * from (values(1)) x(lb), lateral (select lb from int4_tbl) y(lbcopy); lb | lbcopy @@ -5725,7 +7156,7 @@ select * from (values(1)) x(lb), 1 | 1 (5 rows) ---Testcase 447: +--Testcase 460: 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); @@ -5743,7 +7174,7 @@ select * from 4567890123456789 | 4567890123456789 | 4567890123456789 | -4567890123456789 | 4567890123456789 | 4567890123456789 | -4567890123456789 (10 rows) ---Testcase 448: +--Testcase 461: 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); @@ -5761,7 +7192,7 @@ select * from 4567890123456789 | 4567890123456789 | 4567890123456789 | -4567890123456789 | 4567890123456789 | 4567890123456789 | -4567890123456789 (10 rows) ---Testcase 449: +--Testcase 462: 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); @@ -5779,7 +7210,7 @@ select x.* from 4567890123456789 | 4567890123456789 (10 rows) ---Testcase 450: +--Testcase 463: 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, @@ -5808,7 +7239,7 @@ select v.* from 4567890123456789 | -4567890123456789 (20 rows) ---Testcase 451: +--Testcase 464: 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, @@ -5837,7 +7268,7 @@ select v.* from 4567890123456789 | -4567890123456789 (20 rows) ---Testcase 452: +--Testcase 465: 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, @@ -5866,7 +7297,7 @@ select v.* from 4567890123456789 | -4567890123456789 (20 rows) ---Testcase 453: +--Testcase 466: explain (verbose, costs off) select * from int8_tbl a left join @@ -5883,7 +7314,7 @@ select * from InfluxDB query: SELECT "q1", "q2" FROM "int8_tbl" WHERE (($1 = "q1")) (8 rows) ---Testcase 454: +--Testcase 467: select * from int8_tbl a left join lateral (select *, a.q2 as x from int8_tbl b) ss on a.q2 = ss.q1; @@ -5901,7 +7332,7 @@ select * from 4567890123456789 | -4567890123456789 | | | (10 rows) ---Testcase 455: +--Testcase 468: explain (verbose, costs off) select * from int8_tbl a left join @@ -5918,7 +7349,7 @@ select * from InfluxDB query: SELECT "q1", "q2" FROM "int8_tbl" WHERE (($1 = "q1")) (8 rows) ---Testcase 456: +--Testcase 469: 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; @@ -5938,7 +7369,7 @@ select * from -- lateral can result in join conditions appearing below their -- real semantic level ---Testcase 457: +--Testcase 470: 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; @@ -5961,7 +7392,7 @@ select * from int4_tbl i left join InfluxDB query: SELECT "f1" FROM "int2_tbl" (15 rows) ---Testcase 458: +--Testcase 471: select * from int4_tbl i left join lateral (select * from int2_tbl j where i.f1 = j.f1) k on true; f1 | f1 @@ -5973,7 +7404,7 @@ select * from int4_tbl i left join 2147483647 | (5 rows) ---Testcase 459: +--Testcase 472: 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; @@ -5989,7 +7420,7 @@ select * from int4_tbl i left join InfluxDB query: SELECT "f1" FROM "int2_tbl" WHERE (($1 = "f1")) (8 rows) ---Testcase 460: +--Testcase 473: select * from int4_tbl i left join lateral (select coalesce(i) from int2_tbl j where i.f1 = j.f1) k on true; f1 | coalesce @@ -6001,7 +7432,7 @@ select * from int4_tbl i left join -2147483647 | (5 rows) ---Testcase 461: +--Testcase 474: explain (verbose, costs off) select * from int4_tbl a, lateral ( @@ -6027,7 +7458,7 @@ select * from int4_tbl a, InfluxDB query: SELECT "q1", "q2" FROM "int8_tbl" WHERE (($1 = "q2")) (16 rows) ---Testcase 462: +--Testcase 475: select * from int4_tbl a, lateral ( select * from int4_tbl b left join int8_tbl c on (b.f1 = q1 and a.f1 = q2) @@ -6062,7 +7493,7 @@ select * from int4_tbl a, (25 rows) -- lateral reference in a PlaceHolderVar evaluated at join level ---Testcase 463: +--Testcase 476: explain (verbose, costs off) select * from int8_tbl a left join lateral @@ -6088,7 +7519,7 @@ select * from InfluxDB query: SELECT "q1" FROM "int8_tbl" (15 rows) ---Testcase 464: +--Testcase 477: 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 @@ -6141,7 +7572,7 @@ select * from (42 rows) -- case requiring nested PlaceHolderVars ---Testcase 465: +--Testcase 478: explain (verbose, costs off) select * from int8_tbl c left join ( @@ -6156,10 +7587,10 @@ select * from Nested Loop Output: c.q1, c.q2, a.q1, a.q2, b.q1, (COALESCE(b.q2, '42'::bigint)), d.q1, (COALESCE((COALESCE(b.q2, '42'::bigint)), d.q2)), ((COALESCE((COALESCE(b.q2, '42'::bigint)), d.q2))) -> Hash Right Join - Output: c.q1, c.q2, a.q1, a.q2, b.q1, d.q1, (COALESCE(b.q2, '42'::bigint)), (COALESCE((COALESCE(b.q2, '42'::bigint)), d.q2)) + Output: c.q1, c.q2, a.q1, a.q2, b.q1, (COALESCE(b.q2, '42'::bigint)), d.q1, (COALESCE((COALESCE(b.q2, '42'::bigint)), d.q2)) Hash Cond: (d.q1 = c.q2) -> Nested Loop - Output: a.q1, a.q2, b.q1, d.q1, (COALESCE(b.q2, '42'::bigint)), (COALESCE((COALESCE(b.q2, '42'::bigint)), d.q2)) + Output: a.q1, a.q2, b.q1, (COALESCE(b.q2, '42'::bigint)), d.q1, (COALESCE((COALESCE(b.q2, '42'::bigint)), d.q2)) -> Merge Left Join Output: a.q1, a.q2, b.q1, (COALESCE(b.q2, '42'::bigint)) Merge Cond: (a.q2 = b.q1) @@ -6188,7 +7619,7 @@ select * from (32 rows) -- case that breaks the old ph_may_need optimization ---Testcase 466: +--Testcase 479: explain (verbose, costs off) select c.*,a.*,ss1.q1,ss2.q1,ss3.* from int8_tbl c left join ( @@ -6251,7 +7682,7 @@ select c.*,a.*,ss1.q1,ss2.q1,ss3.* from (46 rows) -- check processing of postponed quals (bug #9041) ---Testcase 467: +--Testcase 480: explain (verbose, costs off) select * from (select 1 as x offset 0) x cross join (select 2 as y offset 0) y @@ -6273,8 +7704,30 @@ select * from Output: 3 (11 rows) +-- 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; + QUERY PLAN +----------------------------------------------------------- + Nested Loop Left Join + -> Nested Loop + -> Nested Loop + -> Nested Loop + -> Foreign Scan on int4_tbl t2 + -> Materialize + -> Foreign Scan on int4_tbl t1 + -> Materialize + -> Foreign Scan on int4_tbl t3 + -> Materialize + -> Foreign Scan on int4_tbl t4 + -> Materialize + -> Foreign Scan on int4_tbl t5 +(13 rows) + -- check dummy rels with lateral references (bug #15694) ---Testcase 468: +--Testcase 481: explain (verbose, costs off) select * from int8_tbl i8 left join lateral (select *, i8.q2 from int4_tbl where false) ss on true; @@ -6282,15 +7735,16 @@ select * from int8_tbl i8 left join lateral ----------------------------------------------------------- Nested Loop Left Join Output: i8.q1, i8.q2, f1, (i8.q2) + Join Filter: false -> Foreign Scan on public.int8_tbl i8 Output: i8.q1, i8.q2 InfluxDB query: SELECT "q1", "q2" FROM "int8_tbl" -> Result Output: f1, i8.q2 One-Time Filter: false -(8 rows) +(9 rows) ---Testcase 469: +--Testcase 482: 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; @@ -6307,7 +7761,7 @@ select * from int8_tbl i8 left join lateral (8 rows) -- check handling of nested appendrels inside LATERAL ---Testcase 470: +--Testcase 483: select * from ((select 2 as v) union all (select 3 as v)) as q1 cross join lateral @@ -6327,10 +7781,11 @@ select * from (6 rows) -- check the number of columns specified +--Testcase 601: SELECT * FROM (int8_tbl i cross join int4_tbl j) ss(a,b,c,d); ERROR: join expression "ss" has 3 columns available but 4 columns specified -- check we don't try to do a unique-ified semijoin with LATERAL ---Testcase 471: +--Testcase 484: explain (verbose, costs off) select * from (values (0,9998), (1,1000)) v(id,x), @@ -6356,7 +7811,7 @@ select * from InfluxDB query: SELECT "unique1" FROM "tenk" WHERE (("unique2" = $1)) (15 rows) ---Testcase 472: +--Testcase 485: select * from (values (0,9998), (1,1000)) v(id,x), lateral (select f1 from int4_tbl @@ -6369,7 +7824,7 @@ select * from -- check proper extParam/allParam handling (this isn't exactly a LATERAL issue, -- but we can make the test case much more compact with LATERAL) ---Testcase 473: +--Testcase 486: explain (verbose, costs off) select * from (values (0), (1)) v(id), lateral (select * from int8_tbl t1, @@ -6403,16 +7858,16 @@ lateral (select * from int8_tbl t1, One-Time Filter: $4 InitPlan 1 (returns $2) -> Result - Output: GREATEST($0, t2.q2) + Output: GREATEST(t1.q1, t2.q2) InitPlan 2 (returns $4) -> Result - Output: ($3 = 0) + Output: ("*VALUES*".column1 = 0) -> Foreign Scan on public.int8_tbl t3 Output: t3.q1, t3.q2 InfluxDB query: SELECT "q2" FROM "int8_tbl" WHERE (("q2" = $1)) (29 rows) ---Testcase 474: +--Testcase 487: select * from (values (0), (1)) v(id), lateral (select * from int8_tbl t1, lateral (select * from @@ -6429,97 +7884,101 @@ lateral (select * from int8_tbl t1, (3 rows) -- test some error cases where LATERAL should have been used but wasn't ---Testcase 475: +--Testcase 488: select f1,g from int4_tbl a, (select f1 as g) ss; ERROR: column "f1" does not exist LINE 1: select f1,g from int4_tbl a, (select f1 as g) ss; ^ -HINT: There is a column named "f1" in table "a", but it cannot be referenced from this part of the query. ---Testcase 476: +DETAIL: There is a column named "f1" in table "a", but it cannot be referenced from this part of the query. +HINT: To reference that column, you must mark this subquery with LATERAL. +--Testcase 489: select f1,g from int4_tbl a, (select a.f1 as g) ss; ERROR: invalid reference to FROM-clause entry for table "a" LINE 1: select f1,g from int4_tbl a, (select a.f1 as g) ss; ^ -HINT: There is an entry for table "a", but it cannot be referenced from this part of the query. ---Testcase 477: +DETAIL: There is an entry for table "a", but it cannot be referenced from this part of the query. +HINT: To reference that table, you must mark this subquery with LATERAL. +--Testcase 490: select f1,g from int4_tbl a cross join (select f1 as g) ss; ERROR: column "f1" does not exist LINE 1: select f1,g from int4_tbl a cross join (select f1 as g) ss; ^ -HINT: There is a column named "f1" in table "a", but it cannot be referenced from this part of the query. ---Testcase 478: +DETAIL: There is a column named "f1" in table "a", but it cannot be referenced from this part of the query. +HINT: To reference that column, you must mark this subquery with LATERAL. +--Testcase 491: select f1,g from int4_tbl a cross join (select a.f1 as g) ss; ERROR: invalid reference to FROM-clause entry for table "a" LINE 1: select f1,g from int4_tbl a cross join (select a.f1 as g) ss... ^ -HINT: There is an entry for table "a", but it cannot be referenced from this part of the query. +DETAIL: There is an entry for table "a", but it cannot be referenced from this part of the query. +HINT: To reference that table, you must mark this subquery with LATERAL. -- SQL:2008 says the left table is in scope but illegal to access here ---Testcase 479: +--Testcase 492: select f1,g from int4_tbl a right join lateral generate_series(0, a.f1) g on true; ERROR: invalid reference to FROM-clause entry for table "a" LINE 1: ... int4_tbl a right join lateral generate_series(0, a.f1) g on... ^ DETAIL: The combining JOIN type must be INNER or LEFT for a LATERAL reference. ---Testcase 480: +--Testcase 493: select f1,g from int4_tbl a full join lateral generate_series(0, a.f1) g on true; ERROR: invalid reference to FROM-clause entry for table "a" LINE 1: ...m int4_tbl a full join lateral generate_series(0, a.f1) g on... ^ DETAIL: The combining JOIN type must be INNER or LEFT for a LATERAL reference. -- check we complain about ambiguous table references ---Testcase 481: +--Testcase 494: select * from int8_tbl x cross join (int4_tbl x cross join lateral (select x.f1) ss); ERROR: table reference "x" is ambiguous LINE 2: ...cross join (int4_tbl x cross join lateral (select x.f1) ss); ^ -- LATERAL can be used to put an aggregate into the FROM clause of its query ---Testcase 482: +--Testcase 495: select 1 from tenk1 a, lateral (select max(a.unique1) from int4_tbl b) ss; ERROR: aggregate functions are not allowed in FROM clause of their own query level LINE 1: select 1 from tenk1 a, lateral (select max(a.unique1) from i... ^ -- check behavior of LATERAL in UPDATE/DELETE ---Testcase 483: +--Testcase 496: create temp table xx1 as select f1 as x1, -f1 as x2 from int4_tbl; -- error, can't do this: ---Testcase 484: +--Testcase 497: update xx1 set x2 = f1 from (select * from int4_tbl where f1 = x1) ss; ERROR: column "x1" does not exist LINE 1: ... set x2 = f1 from (select * from int4_tbl where f1 = x1) ss; ^ -HINT: There is a column named "x1" in table "xx1", but it cannot be referenced from this part of the query. ---Testcase 485: +DETAIL: There is a column named "x1" in table "xx1", but it cannot be referenced from this part of the query. +--Testcase 498: update xx1 set x2 = f1 from (select * from int4_tbl where f1 = xx1.x1) ss; ERROR: invalid reference to FROM-clause entry for table "xx1" LINE 1: ...t x2 = f1 from (select * from int4_tbl where f1 = xx1.x1) ss... ^ -HINT: There is an entry for table "xx1", but it cannot be referenced from this part of the query. +DETAIL: There is an entry for table "xx1", but it cannot be referenced from this part of the query. -- can't do it even with LATERAL: ---Testcase 486: +--Testcase 499: update xx1 set x2 = f1 from lateral (select * from int4_tbl where f1 = x1) ss; ERROR: invalid reference to FROM-clause entry for table "xx1" LINE 1: ...= f1 from lateral (select * from int4_tbl where f1 = x1) ss; ^ HINT: There is an entry for table "xx1", but it cannot be referenced from this part of the query. -- we might in future allow something like this, but for now it's an error: ---Testcase 487: +--Testcase 500: update xx1 set x2 = f1 from xx1, lateral (select * from int4_tbl where f1 = x1) ss; ERROR: table name "xx1" specified more than once -- also errors: ---Testcase 488: +--Testcase 501: delete from xx1 using (select * from int4_tbl where f1 = x1) ss; ERROR: column "x1" does not exist LINE 1: ...te from xx1 using (select * from int4_tbl where f1 = x1) ss; ^ -HINT: There is a column named "x1" in table "xx1", but it cannot be referenced from this part of the query. ---Testcase 489: +DETAIL: There is a column named "x1" in table "xx1", but it cannot be referenced from this part of the query. +--Testcase 502: delete from xx1 using (select * from int4_tbl where f1 = xx1.x1) ss; ERROR: invalid reference to FROM-clause entry for table "xx1" LINE 1: ...from xx1 using (select * from int4_tbl where f1 = xx1.x1) ss... ^ -HINT: There is an entry for table "xx1", but it cannot be referenced from this part of the query. ---Testcase 490: +DETAIL: There is an entry for table "xx1", but it cannot be referenced from this part of the query. +--Testcase 503: delete from xx1 using lateral (select * from int4_tbl where f1 = x1) ss; ERROR: invalid reference to FROM-clause entry for table "xx1" LINE 1: ...xx1 using lateral (select * from int4_tbl where f1 = x1) ss; @@ -6583,15 +8042,15 @@ rollback; -- test that foreign key join estimation performs sanely for outer joins -- begin; ---Testcase 491: +--Testcase 504: create foreign table fkest (a int, b int, c int) server influxdb_svr; ---Testcase 492: +--Testcase 505: create foreign table fkest1 (a int, b int) server influxdb_svr; ---Testcase 493: +--Testcase 506: insert into fkest select x/10, x%10, x from generate_series(1,1000) x; ---Testcase 494: +--Testcase 507: insert into fkest1 select x/10, x%10 from generate_series(1,1000) x; ---Testcase 495: +--Testcase 508: explain (costs off) select * from fkest f @@ -6620,20 +8079,20 @@ rollback; -- -- test planner's ability to mark joins as unique -- ---Testcase 496: +--Testcase 509: create foreign table j1 (id int) server influxdb_svr; ---Testcase 497: +--Testcase 510: create foreign table j2 (id int) server influxdb_svr; ---Testcase 498: +--Testcase 511: create foreign table j3 (id int) server influxdb_svr; ---Testcase 499: +--Testcase 512: insert into j1 values(1),(2),(3); ---Testcase 500: +--Testcase 513: insert into j2 values(1),(2),(3); ---Testcase 501: +--Testcase 514: insert into j3 values(1),(1); -- ensure join is properly marked as unique ---Testcase 502: +--Testcase 515: explain (verbose, costs off) select * from j1 inner join j2 on j1.id = j2.id; QUERY PLAN @@ -6656,7 +8115,7 @@ select * from j1 inner join j2 on j1.id = j2.id; (15 rows) -- ensure join is not unique when not an equi-join ---Testcase 503: +--Testcase 516: explain (verbose, costs off) select * from j1 inner join j2 on j1.id > j2.id; QUERY PLAN @@ -6675,7 +8134,7 @@ select * from j1 inner join j2 on j1.id > j2.id; (11 rows) -- ensure non-unique rel is not chosen as inner ---Testcase 504: +--Testcase 517: explain (verbose, costs off) select * from j1 inner join j3 on j1.id = j3.id; QUERY PLAN @@ -6698,7 +8157,7 @@ select * from j1 inner join j3 on j1.id = j3.id; (15 rows) -- ensure left join is marked as unique ---Testcase 505: +--Testcase 518: explain (verbose, costs off) select * from j1 left join j2 on j1.id = j2.id; QUERY PLAN @@ -6721,7 +8180,7 @@ select * from j1 left join j2 on j1.id = j2.id; (15 rows) -- ensure right join is marked as unique ---Testcase 506: +--Testcase 519: explain (verbose, costs off) select * from j1 right join j2 on j1.id = j2.id; QUERY PLAN @@ -6744,7 +8203,7 @@ select * from j1 right join j2 on j1.id = j2.id; (15 rows) -- ensure full join is marked as unique ---Testcase 507: +--Testcase 520: explain (verbose, costs off) select * from j1 full join j2 on j1.id = j2.id; QUERY PLAN @@ -6767,7 +8226,7 @@ select * from j1 full join j2 on j1.id = j2.id; (15 rows) -- a clauseless (cross) join can't be unique ---Testcase 508: +--Testcase 521: explain (verbose, costs off) select * from j1 cross join j2; QUERY PLAN @@ -6785,7 +8244,7 @@ select * from j1 cross join j2; (10 rows) -- ensure a natural join is marked as unique ---Testcase 509: +--Testcase 522: explain (verbose, costs off) select * from j1 natural join j2; QUERY PLAN @@ -6808,7 +8267,7 @@ select * from j1 natural join j2; (15 rows) -- ensure a distinct clause allows the inner to become unique ---Testcase 510: +--Testcase 523: explain (verbose, costs off) select * from j1 inner join (select distinct id from j3) j3 on j1.id = j3.id; @@ -6832,7 +8291,7 @@ inner join (select distinct id from j3) j3 on j1.id = j3.id; (15 rows) -- ensure group by clause allows the inner to become unique ---Testcase 511: +--Testcase 524: explain (verbose, costs off) select * from j1 inner join (select id from j3 group by id) j3 on j1.id = j3.id; @@ -6855,34 +8314,34 @@ inner join (select id from j3 group by id) j3 on j1.id = j3.id; InfluxDB query: SELECT "id" FROM "j3" (15 rows) ---Testcase 512: +--Testcase 525: delete from j1; ---Testcase 513: +--Testcase 526: delete from j2; ---Testcase 514: +--Testcase 527: delete from j3; ---Testcase 515: +--Testcase 528: drop foreign table j1; ---Testcase 516: +--Testcase 529: drop foreign table j2; ---Testcase 517: +--Testcase 530: drop foreign table j3; -- test more complex permutations of unique joins ---Testcase 518: +--Testcase 531: create foreign table j1 (id1 int, id2 int) server influxdb_svr; ---Testcase 519: +--Testcase 532: create foreign table j2 (id1 int, id2 int) server influxdb_svr; ---Testcase 520: +--Testcase 533: create foreign table j3 (id1 int, id2 int) server influxdb_svr; ---Testcase 521: +--Testcase 534: insert into j1 values(1,1),(1,2); ---Testcase 522: +--Testcase 535: insert into j2 values(1,1); ---Testcase 523: +--Testcase 536: insert into j3 values(1,1); -- ensure there's no unique join when not all columns which are part of the -- unique index are seen in the join clause ---Testcase 524: +--Testcase 537: explain (verbose, costs off) select * from j1 inner join j2 on j1.id1 = j2.id1; @@ -6906,7 +8365,7 @@ inner join j2 on j1.id1 = j2.id1; (15 rows) -- ensure proper unique detection with multiple join quals ---Testcase 525: +--Testcase 538: explain (verbose, costs off) select * from j1 inner join j2 on j1.id1 = j2.id1 and j1.id2 = j2.id2; @@ -6931,7 +8390,7 @@ inner join j2 on j1.id1 = j2.id1 and j1.id2 = j2.id2; -- ensure we don't detect the join to be unique when quals are not part of the -- join condition ---Testcase 526: +--Testcase 539: explain (verbose, costs off) select * from j1 inner join j2 on j1.id1 = j2.id1 where j1.id2 = 1; @@ -6951,7 +8410,7 @@ inner join j2 on j1.id1 = j2.id1 where j1.id2 = 1; (11 rows) -- as above, but for left joins. ---Testcase 527: +--Testcase 540: explain (verbose, costs off) select * from j1 left join j2 on j1.id1 = j2.id1 where j1.id2 = 1; @@ -6970,23 +8429,48 @@ left join j2 on j1.id1 = j2.id1 where j1.id2 = 1; InfluxDB query: SELECT "id1", "id2" FROM "j1" WHERE (("id2" = 1)) (11 rows) +-- create unique index j1_id2_idx on j1(id2) where id2 is not null; +-- 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; + QUERY PLAN +------------------------------------------------------------- + Merge Join + Output: j1.id1, j1.id2, j2.id1, j2.id2 + Merge Cond: (j1.id2 = j2.id2) + -> Sort + Output: j1.id1, j1.id2 + Sort Key: j1.id2 + -> Foreign Scan on public.j1 + Output: j1.id1, j1.id2 + InfluxDB query: SELECT "id1", "id2" FROM "j1" + -> Sort + Output: j2.id1, j2.id2 + Sort Key: j2.id2 + -> Foreign Scan on public.j2 + Output: j2.id1, j2.id2 + InfluxDB query: SELECT "id1", "id2" FROM "j2" +(15 rows) + +-- drop index j1_id2_idx; -- 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. ---Testcase 528: +--Testcase 541: set enable_nestloop to 0; ---Testcase 529: +--Testcase 542: set enable_hashjoin to 0; ---Testcase 530: +--Testcase 543: set enable_sort to 0; -- create indexes that will be preferred over the PKs to perform the join --create index j1_id1_idx on j1 (id1) where id1 % 1000 = 1; --create index j2_id1_idx on j2 (id1) where id1 % 1000 = 1; -- need an additional row in j2, if we want j2_id1_idx to be preferred ---Testcase 531: +--Testcase 544: insert into j2 values(1,2); --analyze j2; ---Testcase 532: +--Testcase 545: 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; @@ -6999,7 +8483,7 @@ where j1.id1 % 1000 = 1 and j2.id1 % 1000 = 1; -> Foreign Scan on j2 (5 rows) ---Testcase 533: +--Testcase 546: 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; @@ -7010,7 +8494,7 @@ where j1.id1 % 1000 = 1 and j2.id1 % 1000 = 1; (2 rows) -- Exercise array keys mark/restore B-Tree code ---Testcase 534: +--Testcase 547: 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]); @@ -7023,7 +8507,7 @@ where j1.id1 % 1000 = 1 and j2.id1 % 1000 = 1 and j2.id1 = any (array[1]); -> Foreign Scan on j2 (5 rows) ---Testcase 535: +--Testcase 548: 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]); @@ -7034,7 +8518,7 @@ where j1.id1 % 1000 = 1 and j2.id1 % 1000 = 1 and j2.id1 = any (array[1]); (2 rows) -- Exercise array keys "find extreme element" B-Tree code ---Testcase 536: +--Testcase 549: 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]); @@ -7047,7 +8531,7 @@ where j1.id1 % 1000 = 1 and j2.id1 % 1000 = 1 and j2.id1 >= any (array[1,5]); -> Foreign Scan on j2 (5 rows) ---Testcase 537: +--Testcase 550: 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]); @@ -7057,46 +8541,26 @@ where j1.id1 % 1000 = 1 and j2.id1 % 1000 = 1 and j2.id1 >= any (array[1,5]); 1 | 2 | 1 | 2 (2 rows) ---Testcase 538: +--Testcase 551: reset enable_nestloop; ---Testcase 539: +--Testcase 552: reset enable_hashjoin; ---Testcase 540: +--Testcase 553: reset enable_sort; ---Testcase 541: +--Testcase 554: delete from j1; ---Testcase 542: +--Testcase 555: delete from j2; ---Testcase 543: +--Testcase 556: delete from j3; ---Testcase 544: +--Testcase 557: drop foreign table j1; ---Testcase 545: +--Testcase 558: drop foreign table j2; ---Testcase 546: +--Testcase 559: drop foreign table j3; -- check that semijoin inner is not seen as unique for a portion of the outerrel ---Testcase 547: -CREATE FOREIGN 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 -) SERVER influxdb_svr; --- check that semijoin inner is not seen as unique for a portion of the outerrel ---Testcase 548: +--Testcase 561: explain (verbose, costs off) select t1.unique1, t2.hundred from onek t1, tenk1 t2 @@ -7130,12 +8594,12 @@ where exists (select 1 from tenk1 t3 (22 rows) -- ... unless it actually is unique ---Testcase 549: +--Testcase 562: create table j3 as select unique1, tenthous from onek; vacuum analyze j3; ---Testcase 550: +--Testcase 563: create unique index on j3(unique1, tenthous); ---Testcase 551: +--Testcase 564: explain (verbose, costs off) select t1.unique1, t2.hundred from onek t1, tenk1 t2 @@ -7164,26 +8628,44 @@ where exists (select 1 from j3 Output: j3.unique1, j3.tenthous (18 rows) ---Testcase 552: +--Testcase 565: drop table j3; -- Clean up +--Testcase 583: DELETE FROM t1; +--Testcase 584: DELETE FROM t2; +--Testcase 585: DELETE FROM t3; +--Testcase 586: DELETE FROM tt1; +--Testcase 587: DELETE FROM tt2; +--Testcase 588: DELETE FROM tt3; +--Testcase 589: DELETE FROM tt4; +--Testcase 590: DELETE FROM tt5; +--Testcase 591: DELETE FROM tt6; +--Testcase 592: DELETE FROM xx; +--Testcase 593: DELETE FROM yy; +--Testcase 594: DELETE FROM zt1; +--Testcase 595: DELETE FROM zt2; +--Testcase 596: DELETE FROM nt1; +--Testcase 597: DELETE FROM nt2; +--Testcase 598: DELETE FROM nt3; +--Testcase 599: DELETE FROM parent; +--Testcase 600: DELETE FROM child; DO $d$ declare @@ -7197,9 +8679,9 @@ end; $d$; NOTICE: drop cascades to table t2a NOTICE: drop cascades to view zv1 ---Testcase 553: +--Testcase 566: DROP USER MAPPING FOR CURRENT_USER SERVER influxdb_svr; ---Testcase 554: +--Testcase 567: DROP SERVER influxdb_svr CASCADE; ---Testcase 555: +--Testcase 568: DROP EXTENSION influxdb_fdw CASCADE; diff --git a/expected/12.12/extra/limit.out b/expected/16.0/extra/limit.out similarity index 89% rename from expected/12.12/extra/limit.out rename to expected/16.0/extra/limit.out index 86353e2..c23ffba 100644 --- a/expected/12.12/extra/limit.out +++ b/expected/16.0/extra/limit.out @@ -1,18 +1,16 @@ \set ECHO none ---Testcase 51: +--Testcase 1: CREATE EXTENSION influxdb_fdw; ---Testcase 52: +--Testcase 2: CREATE SERVER influxdb_svr FOREIGN DATA WRAPPER influxdb_fdw OPTIONS (dbname 'coredb', :SERVER); ---Testcase 53: +--Testcase 3: CREATE USER MAPPING FOR CURRENT_USER SERVER influxdb_svr OPTIONS (:AUTHENTICATION); --- import time column as timestamp and text type --- IMPORT FOREIGN SCHEMA influxdb_schema FROM SERVER influxdb_svr INTO public; -- -- LIMIT -- Check the LIMIT/OFFSET feature of SELECT -- ---Testcase 54: +--Testcase 4: CREATE FOREIGN TABLE onek ( unique1 int4, unique2 int4, @@ -31,9 +29,9 @@ CREATE FOREIGN TABLE onek ( stringu2 name, string4 name ) SERVER influxdb_svr; ---Testcase 55: +--Testcase 5: CREATE FOREIGN TABLE int8_tbl(q1 int8, q2 int8) SERVER influxdb_svr; ---Testcase 56: +--Testcase 6: CREATE FOREIGN TABLE tenk1 ( unique1 int4, unique2 int4, @@ -52,7 +50,7 @@ CREATE FOREIGN TABLE tenk1 ( stringu2 name, string4 name ) SERVER influxdb_svr OPTIONS (table 'tenk'); ---Testcase 1: +--Testcase 7: SELECT ''::text AS two, unique1, unique2, stringu1 FROM onek WHERE unique1 > 50 ORDER BY unique1 LIMIT 2; @@ -62,7 +60,7 @@ SELECT ''::text AS two, unique1, unique2, stringu1 | 52 | 985 | ACAAAA (2 rows) ---Testcase 2: +--Testcase 8: SELECT ''::text AS five, unique1, unique2, stringu1 FROM onek WHERE unique1 > 60 ORDER BY unique1 LIMIT 5; @@ -75,7 +73,7 @@ SELECT ''::text AS five, unique1, unique2, stringu1 | 65 | 64 | NCAAAA (5 rows) ---Testcase 3: +--Testcase 9: SELECT ''::text AS two, unique1, unique2, stringu1 FROM onek WHERE unique1 > 60 AND unique1 < 63 ORDER BY unique1 LIMIT 5; @@ -85,7 +83,7 @@ SELECT ''::text AS two, unique1, unique2, stringu1 | 62 | 633 | KCAAAA (2 rows) ---Testcase 4: +--Testcase 10: SELECT ''::text AS three, unique1, unique2, stringu1 FROM onek WHERE unique1 > 100 ORDER BY unique1 LIMIT 3 OFFSET 20; @@ -96,7 +94,7 @@ SELECT ''::text AS three, unique1, unique2, stringu1 | 123 | 777 | TEAAAA (3 rows) ---Testcase 5: +--Testcase 11: SELECT ''::text AS zero, unique1, unique2, stringu1 FROM onek WHERE unique1 < 50 ORDER BY unique1 DESC LIMIT 8 OFFSET 99; @@ -104,7 +102,7 @@ SELECT ''::text AS zero, unique1, unique2, stringu1 ------+---------+---------+---------- (0 rows) ---Testcase 6: +--Testcase 12: SELECT ''::text AS eleven, unique1, unique2, stringu1 FROM onek WHERE unique1 < 50 ORDER BY unique1 DESC LIMIT 20 OFFSET 39; @@ -123,7 +121,7 @@ SELECT ''::text AS eleven, unique1, unique2, stringu1 | 0 | 998 | AAAAAA (11 rows) ---Testcase 7: +--Testcase 13: SELECT ''::text AS ten, unique1, unique2, stringu1 FROM onek ORDER BY unique1 OFFSET 990; @@ -141,7 +139,7 @@ SELECT ''::text AS ten, unique1, unique2, stringu1 | 999 | 152 | LMAAAA (10 rows) ---Testcase 8: +--Testcase 14: SELECT ''::text AS five, unique1, unique2, stringu1 FROM onek ORDER BY unique1 OFFSET 990 LIMIT 5; @@ -154,7 +152,7 @@ SELECT ''::text AS five, unique1, unique2, stringu1 | 994 | 695 | GMAAAA (5 rows) ---Testcase 9: +--Testcase 15: SELECT ''::text AS five, unique1, unique2, stringu1 FROM onek ORDER BY unique1 LIMIT 5 OFFSET 900; @@ -169,7 +167,7 @@ SELECT ''::text AS five, unique1, unique2, stringu1 -- Test null limit and offset. The planner would discard a simple null -- constant, so to ensure executor is exercised, do this: ---Testcase 10: +--Testcase 16: select * from int8_tbl limit (case when random() < 0.5 then null::bigint end); q1 | q2 ------------------+------------------- @@ -180,7 +178,7 @@ select * from int8_tbl limit (case when random() < 0.5 then null::bigint end); 4567890123456789 | -4567890123456789 (5 rows) ---Testcase 11: +--Testcase 17: select * from int8_tbl offset (case when random() < 0.5 then null::bigint end); q1 | q2 ------------------+------------------- @@ -194,7 +192,7 @@ select * from int8_tbl offset (case when random() < 0.5 then null::bigint end); -- Test assorted cases involving backwards fetch from a LIMIT plan node begin; declare c1 scroll cursor for select * from int8_tbl limit 10; ---Testcase 12: +--Testcase 18: fetch all in c1; q1 | q2 ------------------+------------------- @@ -205,20 +203,20 @@ fetch all in c1; 4567890123456789 | -4567890123456789 (5 rows) ---Testcase 13: +--Testcase 19: fetch 1 in c1; q1 | q2 ----+---- (0 rows) ---Testcase 14: +--Testcase 20: fetch backward 1 in c1; q1 | q2 ------------------+------------------- 4567890123456789 | -4567890123456789 (1 row) ---Testcase 15: +--Testcase 21: fetch backward all in c1; q1 | q2 ------------------+------------------ @@ -228,13 +226,13 @@ fetch backward all in c1; 123 | 456 (4 rows) ---Testcase 16: +--Testcase 22: fetch backward 1 in c1; q1 | q2 ----+---- (0 rows) ---Testcase 17: +--Testcase 23: fetch all in c1; q1 | q2 ------------------+------------------- @@ -246,7 +244,7 @@ fetch all in c1; (5 rows) declare c2 scroll cursor for select * from int8_tbl limit 3; ---Testcase 18: +--Testcase 24: fetch all in c2; q1 | q2 ------------------+------------------ @@ -255,20 +253,20 @@ fetch all in c2; 4567890123456789 | 123 (3 rows) ---Testcase 19: +--Testcase 25: fetch 1 in c2; q1 | q2 ----+---- (0 rows) ---Testcase 20: +--Testcase 26: fetch backward 1 in c2; q1 | q2 ------------------+----- 4567890123456789 | 123 (1 row) ---Testcase 21: +--Testcase 27: fetch backward all in c2; q1 | q2 -----+------------------ @@ -276,13 +274,13 @@ fetch backward all in c2; 123 | 456 (2 rows) ---Testcase 22: +--Testcase 28: fetch backward 1 in c2; q1 | q2 ----+---- (0 rows) ---Testcase 23: +--Testcase 29: fetch all in c2; q1 | q2 ------------------+------------------ @@ -292,7 +290,7 @@ fetch all in c2; (3 rows) declare c3 scroll cursor for select * from int8_tbl offset 3; ---Testcase 24: +--Testcase 30: fetch all in c3; q1 | q2 ------------------+------------------- @@ -300,33 +298,33 @@ fetch all in c3; 4567890123456789 | -4567890123456789 (2 rows) ---Testcase 25: +--Testcase 31: fetch 1 in c3; q1 | q2 ----+---- (0 rows) ---Testcase 26: +--Testcase 32: fetch backward 1 in c3; q1 | q2 ------------------+------------------- 4567890123456789 | -4567890123456789 (1 row) ---Testcase 27: +--Testcase 33: fetch backward all in c3; q1 | q2 ------------------+------------------ 4567890123456789 | 4567890123456789 (1 row) ---Testcase 28: +--Testcase 34: fetch backward 1 in c3; q1 | q2 ----+---- (0 rows) ---Testcase 29: +--Testcase 35: fetch all in c3; q1 | q2 ------------------+------------------- @@ -335,75 +333,107 @@ fetch all in c3; (2 rows) declare c4 scroll cursor for select * from int8_tbl offset 10; ---Testcase 30: +--Testcase 36: fetch all in c4; q1 | q2 ----+---- (0 rows) ---Testcase 31: +--Testcase 37: fetch 1 in c4; q1 | q2 ----+---- (0 rows) ---Testcase 32: +--Testcase 38: fetch backward 1 in c4; q1 | q2 ----+---- (0 rows) ---Testcase 33: +--Testcase 39: fetch backward all in c4; q1 | q2 ----+---- (0 rows) ---Testcase 34: +--Testcase 40: fetch backward 1 in c4; q1 | q2 ----+---- (0 rows) ---Testcase 35: +--Testcase 41: fetch all in c4; q1 | q2 ----+---- (0 rows) declare c5 scroll cursor for select * from int8_tbl order by q1 fetch first 2 rows with ties; -ERROR: syntax error at or near "with" -LINE 1: ...ct * from int8_tbl order by q1 fetch first 2 rows with ties; - ^ ---Testcase 57: +--Testcase 42: fetch all in c5; -ERROR: current transaction is aborted, commands ignored until end of transaction block ---Testcase 58: + q1 | q2 +-----+------------------ + 123 | 456 + 123 | 4567890123456789 +(2 rows) + +--Testcase 43: fetch 1 in c5; -ERROR: current transaction is aborted, commands ignored until end of transaction block ---Testcase 59: + q1 | q2 +----+---- +(0 rows) + +--Testcase 44: fetch backward 1 in c5; -ERROR: current transaction is aborted, commands ignored until end of transaction block ---Testcase 60: + q1 | q2 +-----+------------------ + 123 | 4567890123456789 +(1 row) + +--Testcase 45: fetch backward 1 in c5; -ERROR: current transaction is aborted, commands ignored until end of transaction block ---Testcase 61: + q1 | q2 +-----+----- + 123 | 456 +(1 row) + +--Testcase 46: fetch all in c5; -ERROR: current transaction is aborted, commands ignored until end of transaction block ---Testcase 62: + q1 | q2 +-----+------------------ + 123 | 4567890123456789 +(1 row) + +--Testcase 47: fetch backward all in c5; -ERROR: current transaction is aborted, commands ignored until end of transaction block ---Testcase 63: + q1 | q2 +-----+------------------ + 123 | 4567890123456789 + 123 | 456 +(2 rows) + +--Testcase 48: fetch all in c5; -ERROR: current transaction is aborted, commands ignored until end of transaction block ---Testcase 64: + q1 | q2 +-----+------------------ + 123 | 456 + 123 | 4567890123456789 +(2 rows) + +--Testcase 49: fetch backward all in c5; -ERROR: current transaction is aborted, commands ignored until end of transaction block + q1 | q2 +-----+------------------ + 123 | 4567890123456789 + 123 | 456 +(2 rows) + rollback; -- Stress test for variable LIMIT in conjunction with bounded-heap sorting ---Testcase 65: +--Testcase 50: CREATE FOREIGN TABLE generate_series4(a int) SERVER influxdb_svr; ---Testcase 36: +--Testcase 51: SELECT (SELECT a FROM (VALUES (1)) AS x, @@ -428,9 +458,9 @@ SELECT -- Test behavior of volatile and set-returning functions in conjunction -- with ORDER BY and LIMIT. -- ---Testcase 66: +--Testcase 52: create temp sequence testseq; ---Testcase 37: +--Testcase 53: explain (verbose, costs off) select unique1, unique2, nextval('testseq') from tenk1 order by unique2 limit 10; @@ -448,7 +478,7 @@ select unique1, unique2, nextval('testseq') InfluxDB query: SELECT "unique1", "unique2" FROM "tenk" (10 rows) ---Testcase 38: +--Testcase 54: select unique1, unique2, nextval('testseq') from tenk1 order by unique2 limit 10; unique1 | unique2 | nextval @@ -465,14 +495,14 @@ select unique1, unique2, nextval('testseq') 3043 | 9 | 10 (10 rows) ---Testcase 39: +--Testcase 55: select currval('testseq'); currval --------- 10 (1 row) ---Testcase 40: +--Testcase 56: explain (verbose, costs off) select unique1, unique2, nextval('testseq') from tenk1 order by tenthous limit 10; @@ -490,7 +520,7 @@ select unique1, unique2, nextval('testseq') InfluxDB query: SELECT "unique1", "unique2", "tenthous" FROM "tenk" (10 rows) ---Testcase 41: +--Testcase 57: select unique1, unique2, nextval('testseq') from tenk1 order by tenthous limit 10; unique1 | unique2 | nextval @@ -507,14 +537,14 @@ select unique1, unique2, nextval('testseq') 9 | 4463 | 20 (10 rows) ---Testcase 42: +--Testcase 58: select currval('testseq'); currval --------- 20 (1 row) ---Testcase 43: +--Testcase 59: explain (verbose, costs off) select unique1, unique2, generate_series(1,10) from tenk1 order by unique2 limit 7; @@ -532,7 +562,7 @@ select unique1, unique2, generate_series(1,10) InfluxDB query: SELECT "unique1", "unique2" FROM "tenk" (10 rows) ---Testcase 44: +--Testcase 60: select unique1, unique2, generate_series(1,10) from tenk1 order by unique2 limit 7; unique1 | unique2 | generate_series @@ -546,7 +576,7 @@ select unique1, unique2, generate_series(1,10) 8800 | 0 | 7 (7 rows) ---Testcase 45: +--Testcase 61: explain (verbose, costs off) select unique1, unique2, generate_series(1,10) from tenk1 order by tenthous limit 7; @@ -564,7 +594,7 @@ select unique1, unique2, generate_series(1,10) InfluxDB query: SELECT "unique1", "unique2", "tenthous" FROM "tenk" (10 rows) ---Testcase 46: +--Testcase 62: select unique1, unique2, generate_series(1,10) from tenk1 order by tenthous limit 7; unique1 | unique2 | generate_series @@ -579,7 +609,7 @@ select unique1, unique2, generate_series(1,10) (7 rows) -- use of random() is to keep planner from folding the expressions together ---Testcase 47: +--Testcase 63: explain (verbose, costs off) select generate_series(0,2) as s1, generate_series((random()*.1)::int,2) as s2; QUERY PLAN @@ -589,7 +619,7 @@ select generate_series(0,2) as s1, generate_series((random()*.1)::int,2) as s2; -> Result (3 rows) ---Testcase 48: +--Testcase 64: select generate_series(0,2) as s1, generate_series((random()*.1)::int,2) as s2; s1 | s2 ----+---- @@ -598,7 +628,7 @@ select generate_series(0,2) as s1, generate_series((random()*.1)::int,2) as s2; 2 | 2 (3 rows) ---Testcase 49: +--Testcase 65: explain (verbose, costs off) select generate_series(0,2) as s1, generate_series((random()*.1)::int,2) as s2 order by s2 desc; @@ -612,7 +642,7 @@ order by s2 desc; -> Result (6 rows) ---Testcase 50: +--Testcase 66: select generate_series(0,2) as s1, generate_series((random()*.1)::int,2) as s2 order by s2 desc; s1 | s2 @@ -662,23 +692,56 @@ select sum(tenthous) as s1, sum(tenthous) + random()*0 as s2 SELECT thousand FROM onek WHERE thousand < 5 ORDER BY thousand FETCH FIRST 2 ROW WITH TIES; -ERROR: syntax error at or near "WITH" -LINE 3: ORDER BY thousand FETCH FIRST 2 ROW WITH TIES; - ^ + thousand +---------- + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 +(10 rows) + --Testcase 70: SELECT thousand FROM onek WHERE thousand < 5 ORDER BY thousand FETCH FIRST ROWS WITH TIES; -ERROR: syntax error at or near "WITH" -LINE 3: ORDER BY thousand FETCH FIRST ROWS WITH TIES; - ^ + thousand +---------- + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 +(10 rows) + --Testcase 71: SELECT thousand FROM onek WHERE thousand < 5 ORDER BY thousand FETCH FIRST 1 ROW WITH TIES; -ERROR: syntax error at or near "WITH" -LINE 3: ORDER BY thousand FETCH FIRST 1 ROW WITH TIES; - ^ + thousand +---------- + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 +(10 rows) + --Testcase 72: SELECT thousand FROM onek WHERE thousand < 5 @@ -689,23 +752,36 @@ SELECT thousand 0 (2 rows) +-- SKIP LOCKED and WITH TIES are incompatible +--Testcase 90: +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 -- should fail --Testcase 73: SELECT ''::text AS two, unique1, unique2, stringu1 FROM onek WHERE unique1 > 50 FETCH FIRST 2 ROW WITH TIES; -ERROR: syntax error at or near "WITH" -LINE 3: FETCH FIRST 2 ROW WITH TIES; - ^ +ERROR: WITH TIES cannot be specified without ORDER BY clause -- test ruleutils --Testcase 74: 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; -ERROR: syntax error at or near "WITH" -LINE 2: ORDER BY thousand FETCH FIRST 5 ROWS WITH TIES OFFSET 10; - ^ --Testcase 75: \d+ limit_thousand_v_1 + View "public.limit_thousand_v_1" + Column | Type | Collation | Nullable | Default | Storage | Description +----------+---------+-----------+----------+---------+---------+------------- + thousand | integer | | | | plain | +View definition: + SELECT thousand + FROM onek + WHERE thousand < 995 + ORDER BY thousand + OFFSET 10 + FETCH FIRST 5 ROWS WITH TIES; + --Testcase 76: CREATE VIEW limit_thousand_v_2 AS SELECT thousand FROM onek WHERE thousand < 995 ORDER BY thousand OFFSET 10 FETCH FIRST 5 ROWS ONLY; @@ -716,27 +792,33 @@ CREATE VIEW limit_thousand_v_2 AS SELECT thousand FROM onek WHERE thousand < 995 ----------+---------+-----------+----------+---------+---------+------------- thousand | integer | | | | plain | View definition: - SELECT onek.thousand + SELECT thousand FROM onek - WHERE onek.thousand < 995 - ORDER BY onek.thousand + WHERE thousand < 995 + ORDER BY thousand OFFSET 10 LIMIT 5; --Testcase 78: CREATE VIEW limit_thousand_v_3 AS SELECT thousand FROM onek WHERE thousand < 995 ORDER BY thousand FETCH FIRST NULL ROWS WITH TIES; -- fails -ERROR: syntax error at or near "WITH" -LINE 2: ORDER BY thousand FETCH FIRST NULL ROWS WITH TIES; - ^ +ERROR: row count cannot be null in FETCH FIRST ... WITH TIES clause --Testcase 79: CREATE VIEW limit_thousand_v_3 AS SELECT thousand FROM onek WHERE thousand < 995 ORDER BY thousand FETCH FIRST (NULL+1) ROWS WITH TIES; -ERROR: syntax error at or near "WITH" -LINE 2: ORDER BY thousand FETCH FIRST (NULL+1) ROWS WITH TIES; - ^ --Testcase 80: \d+ limit_thousand_v_3 + View "public.limit_thousand_v_3" + Column | Type | Collation | Nullable | Default | Storage | Description +----------+---------+-----------+----------+---------+---------+------------- + thousand | integer | | | | plain | +View definition: + SELECT thousand + FROM onek + WHERE thousand < 995 + ORDER BY thousand + FETCH FIRST (NULL::integer + 1) ROWS WITH TIES; + --Testcase 81: CREATE VIEW limit_thousand_v_4 AS SELECT thousand FROM onek WHERE thousand < 995 ORDER BY thousand FETCH FIRST NULL ROWS ONLY; @@ -747,21 +829,19 @@ CREATE VIEW limit_thousand_v_4 AS SELECT thousand FROM onek WHERE thousand < 995 ----------+---------+-----------+----------+---------+---------+------------- thousand | integer | | | | plain | View definition: - SELECT onek.thousand + SELECT thousand FROM onek - WHERE onek.thousand < 995 - ORDER BY onek.thousand + WHERE thousand < 995 + ORDER BY thousand LIMIT ALL; -- leave these views --Testcase 83: DROP VIEW limit_thousand_v_1; -ERROR: view "limit_thousand_v_1" does not exist --Testcase 84: DROP VIEW limit_thousand_v_2; --Testcase 85: DROP VIEW limit_thousand_v_3; -ERROR: view "limit_thousand_v_3" does not exist --Testcase 86: DROP VIEW limit_thousand_v_4; -- Clean up diff --git a/expected/12.12/extra/prepare.out b/expected/16.0/extra/prepare.out similarity index 80% rename from expected/12.12/extra/prepare.out rename to expected/16.0/extra/prepare.out index c16a927..7cc4a8f 100644 --- a/expected/12.12/extra/prepare.out +++ b/expected/16.0/extra/prepare.out @@ -2,14 +2,14 @@ -- of the pg_prepared_statements view as prepared statements are -- created and removed. \set ECHO none ---Testcase 27: +--Testcase 1: CREATE EXTENSION influxdb_fdw; ---Testcase 28: +--Testcase 2: CREATE SERVER influxdb_svr FOREIGN DATA WRAPPER influxdb_fdw OPTIONS (dbname 'coredb', :SERVER); ---Testcase 29: +--Testcase 3: CREATE USER MAPPING FOR CURRENT_USER SERVER influxdb_svr OPTIONS (:AUTHENTICATION); ---Testcase 30: +--Testcase 4: CREATE FOREIGN TABLE tenk1 ( unique1 int4, unique2 int4, @@ -30,95 +30,95 @@ CREATE FOREIGN TABLE tenk1 ( ) SERVER influxdb_svr OPTIONS (table 'tenk'); -- Does not support this command -- ALTER TABLE tenk1 SET WITH OIDS; ---Testcase 31: +--Testcase 5: CREATE FOREIGN TABLE road ( name text, thepath path ) SERVER influxdb_svr; ---Testcase 32: +--Testcase 6: CREATE FOREIGN TABLE road_tmp (a int, b int) SERVER influxdb_svr; ---Testcase 1: -SELECT name, statement, parameter_types FROM pg_prepared_statements; - name | statement | parameter_types -------+-----------+----------------- +--Testcase 7: +SELECT name, statement, parameter_types, result_types FROM pg_prepared_statements; + name | statement | parameter_types | result_types +------+-----------+-----------------+-------------- (0 rows) ---Testcase 2: +--Testcase 8: PREPARE q1 AS SELECT a AS a FROM road_tmp; ---Testcase 3: +--Testcase 9: EXECUTE q1; a --- 1 (1 row) ---Testcase 4: -SELECT name, statement, parameter_types FROM pg_prepared_statements; - name | statement | parameter_types -------+--------------------------------------------+----------------- - q1 | PREPARE q1 AS SELECT a AS a FROM road_tmp; | {} +--Testcase 10: +SELECT name, statement, parameter_types, result_types FROM pg_prepared_statements; + name | statement | parameter_types | result_types +------+--------------------------------------------+-----------------+-------------- + q1 | PREPARE q1 AS SELECT a AS a FROM road_tmp; | {} | {integer} (1 row) -- should fail ---Testcase 5: +--Testcase 11: PREPARE q1 AS SELECT b FROM road_tmp; ERROR: prepared statement "q1" already exists -- should succeed DEALLOCATE q1; ---Testcase 6: +--Testcase 12: PREPARE q1 AS SELECT b FROM road_tmp; ---Testcase 7: +--Testcase 13: EXECUTE q1; b --- 2 (1 row) ---Testcase 8: +--Testcase 14: PREPARE q2 AS SELECT b AS b FROM road_tmp; ---Testcase 9: -SELECT name, statement, parameter_types FROM pg_prepared_statements; - name | statement | parameter_types -------+--------------------------------------------+----------------- - q1 | PREPARE q1 AS SELECT b FROM road_tmp; | {} - q2 | PREPARE q2 AS SELECT b AS b FROM road_tmp; | {} +--Testcase 15: +SELECT name, statement, parameter_types, result_types FROM pg_prepared_statements; + name | statement | parameter_types | result_types +------+--------------------------------------------+-----------------+-------------- + q1 | PREPARE q1 AS SELECT b FROM road_tmp; | {} | {integer} + q2 | PREPARE q2 AS SELECT b AS b FROM road_tmp; | {} | {integer} (2 rows) -- sql92 syntax DEALLOCATE PREPARE q1; ---Testcase 10: -SELECT name, statement, parameter_types FROM pg_prepared_statements; - name | statement | parameter_types -------+--------------------------------------------+----------------- - q2 | PREPARE q2 AS SELECT b AS b FROM road_tmp; | {} +--Testcase 16: +SELECT name, statement, parameter_types, result_types FROM pg_prepared_statements; + name | statement | parameter_types | result_types +------+--------------------------------------------+-----------------+-------------- + q2 | PREPARE q2 AS SELECT b AS b FROM road_tmp; | {} | {integer} (1 row) DEALLOCATE PREPARE q2; -- the view should return the empty set again ---Testcase 11: -SELECT name, statement, parameter_types FROM pg_prepared_statements; - name | statement | parameter_types -------+-----------+----------------- +--Testcase 17: +SELECT name, statement, parameter_types, result_types FROM pg_prepared_statements; + name | statement | parameter_types | result_types +------+-----------+-----------------+-------------- (0 rows) -- parameterized queries ---Testcase 12: +--Testcase 18: PREPARE q2(text) AS SELECT datname, datistemplate, datallowconn FROM pg_database WHERE datname = $1; ---Testcase 13: +--Testcase 19: EXECUTE q2('postgres'); datname | datistemplate | datallowconn ----------+---------------+-------------- postgres | f | t (1 row) ---Testcase 14: +--Testcase 20: 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; ---Testcase 15: +--Testcase 21: EXECUTE q3('AAAAxx', 5::smallint, 10.5::float, false, 4::bigint); unique1 | unique2 | two | four | ten | twenty | hundred | thousand | twothousand | fivethous | tenthous | odd | even | stringu1 | stringu2 | string4 ---------+---------+-----+------+-----+--------+---------+----------+-------------+-----------+----------+-----+------+----------+----------+--------- @@ -154,34 +154,36 @@ EXECUTE q3('AAAAxx', 5::smallint, 10.5::float, false, 4::bigint); (29 rows) -- too few params ---Testcase 16: +--Testcase 22: EXECUTE q3('bool'); ERROR: wrong number of parameters for prepared statement "q3" DETAIL: Expected 5 parameters but got 1. -- too many params ---Testcase 17: +--Testcase 23: EXECUTE q3('bytea', 5::smallint, 10.5::float, false, 4::bigint, true); ERROR: wrong number of parameters for prepared statement "q3" DETAIL: Expected 5 parameters but got 6. -- wrong param types ---Testcase 18: +--Testcase 24: EXECUTE q3(5::smallint, 10.5::float, false, 4::bigint, 'bytea'); ERROR: parameter $3 of type boolean cannot be coerced to the expected type double precision +LINE 1: EXECUTE q3(5::smallint, 10.5::float, false, 4::bigint, 'byte... + ^ HINT: You will need to rewrite or cast the expression. -- invalid type ---Testcase 19: +--Testcase 25: PREPARE q4(nonexistenttype) AS SELECT $1; ERROR: type "nonexistenttype" does not exist LINE 1: PREPARE q4(nonexistenttype) AS SELECT $1; ^ -- create table as execute ---Testcase 20: +--Testcase 26: PREPARE q5(int, text) AS SELECT * FROM tenk1 WHERE unique1 = $1 OR stringu1 = $2 ORDER BY unique1; ---Testcase 33: +--Testcase 27: CREATE TEMPORARY TABLE q5_prep_results AS EXECUTE q5(200, 'DTAAAA'); ---Testcase 21: +--Testcase 28: SELECT * FROM q5_prep_results; unique1 | unique2 | two | four | ten | twenty | hundred | thousand | twothousand | fivethous | tenthous | odd | even | stringu1 | stringu2 | string4 ---------+---------+-----+------+-----+--------+---------+----------+-------------+-----------+----------+-----+------+----------+----------+--------- @@ -203,46 +205,51 @@ SELECT * FROM q5_prep_results; 9961 | 2058 | 1 | 1 | 1 | 1 | 61 | 961 | 1961 | 4961 | 9961 | 122 | 123 | DTAAAA | EBDAAA | OOOOxx (16 rows) ---Testcase 34: +--Testcase 29: CREATE TEMPORARY TABLE q5_prep_nodata AS EXECUTE q5(200, 'DTAAAA') WITH NO DATA; ---Testcase 22: +--Testcase 30: SELECT * FROM q5_prep_nodata; unique1 | unique2 | two | four | ten | twenty | hundred | thousand | twothousand | fivethous | tenthous | odd | even | stringu1 | stringu2 | string4 ---------+---------+-----+------+-----+--------+---------+----------+-------------+-----------+----------+-----+------+----------+----------+--------- (0 rows) -- unknown or unspecified parameter types: should succeed ---Testcase 23: +--Testcase 31: PREPARE q6 AS SELECT * FROM tenk1 WHERE unique1 = $1 AND stringu1 = $2; ---Testcase 24: +--Testcase 32: PREPARE q7(unknown) AS SELECT * FROM road WHERE thepath = $1; ---Testcase 25: -SELECT name, statement, parameter_types FROM pg_prepared_statements +--Testcase 33: +-- DML statements +PREPARE q8 AS + UPDATE tenk1 SET stringu1 = $2 WHERE unique1 = $1; +SELECT name, statement, parameter_types, result_types FROM pg_prepared_statements ORDER BY name; - name | statement | parameter_types -------+------------------------------------------------------------------+---------------------------------------------------- - q2 | PREPARE q2(text) AS +| {text} - | SELECT datname, datistemplate, datallowconn +| - | FROM pg_database WHERE datname = $1; | - q3 | PREPARE q3(text, int, float, boolean, smallint) AS +| {text,integer,"double precision",boolean,smallint} - | SELECT * FROM tenk1 WHERE string4 = $1 AND (four = $2 OR+| - | ten = $3::bigint OR true = $4 OR odd = $5::int) +| - | ORDER BY unique1; | - q5 | PREPARE q5(int, text) AS +| {integer,text} - | SELECT * FROM tenk1 WHERE unique1 = $1 OR stringu1 = $2 +| - | ORDER BY unique1; | - q6 | PREPARE q6 AS +| {integer,name} - | SELECT * FROM tenk1 WHERE unique1 = $1 AND stringu1 = $2; | - q7 | PREPARE q7(unknown) AS +| {path} - | SELECT * FROM road WHERE thepath = $1; | -(5 rows) + name | statement | parameter_types | result_types +------+------------------------------------------------------------------+----------------------------------------------------+-------------------------------------------------------------------------------------------------------------------------- + q2 | PREPARE q2(text) AS +| {text} | {name,boolean,boolean} + | SELECT datname, datistemplate, datallowconn +| | + | FROM pg_database WHERE datname = $1; | | + q3 | PREPARE q3(text, int, float, boolean, smallint) AS +| {text,integer,"double precision",boolean,smallint} | {integer,integer,integer,integer,integer,integer,integer,integer,integer,integer,integer,integer,integer,name,name,name} + | SELECT * FROM tenk1 WHERE string4 = $1 AND (four = $2 OR+| | + | ten = $3::bigint OR true = $4 OR odd = $5::int) +| | + | ORDER BY unique1; | | + q5 | PREPARE q5(int, text) AS +| {integer,text} | {integer,integer,integer,integer,integer,integer,integer,integer,integer,integer,integer,integer,integer,name,name,name} + | SELECT * FROM tenk1 WHERE unique1 = $1 OR stringu1 = $2 +| | + | ORDER BY unique1; | | + q6 | PREPARE q6 AS +| {integer,name} | {integer,integer,integer,integer,integer,integer,integer,integer,integer,integer,integer,integer,integer,name,name,name} + | SELECT * FROM tenk1 WHERE unique1 = $1 AND stringu1 = $2; | | + q7 | PREPARE q7(unknown) AS +| {path} | {text,path} + | SELECT * FROM road WHERE thepath = $1; | | + q8 | PREPARE q8 AS +| {integer,name} | + | UPDATE tenk1 SET stringu1 = $2 WHERE unique1 = $1; | | +(6 rows) -- test DEALLOCATE ALL; DEALLOCATE ALL; ---Testcase 26: +--Testcase 34: SELECT name, statement, parameter_types FROM pg_prepared_statements ORDER BY name; name | statement | parameter_types diff --git a/expected/11.17/extra/select.out b/expected/16.0/extra/select.out similarity index 96% rename from expected/11.17/extra/select.out rename to expected/16.0/extra/select.out index 21bd156..65ad5cc 100644 --- a/expected/11.17/extra/select.out +++ b/expected/16.0/extra/select.out @@ -2,14 +2,14 @@ -- SELECT -- \set ECHO none ---Testcase 52: +--Testcase 1: CREATE EXTENSION influxdb_fdw; ---Testcase 53: +--Testcase 2: CREATE SERVER influxdb_svr FOREIGN DATA WRAPPER influxdb_fdw OPTIONS (dbname 'coredb', :SERVER); ---Testcase 54: +--Testcase 3: CREATE USER MAPPING FOR CURRENT_USER SERVER influxdb_svr OPTIONS (:AUTHENTICATION); ---Testcase 55: +--Testcase 4: CREATE FOREIGN TABLE onek ( unique1 int4, unique2 int4, @@ -28,7 +28,7 @@ CREATE FOREIGN TABLE onek ( stringu2 name, string4 name ) SERVER influxdb_svr; ---Testcase 56: +--Testcase 5: CREATE FOREIGN TABLE onek2 ( unique1 int4, unique2 int4, @@ -47,27 +47,27 @@ CREATE FOREIGN TABLE onek2 ( stringu2 name, string4 name ) SERVER influxdb_svr OPTIONS (table 'onek'); ---Testcase 57: +--Testcase 6: CREATE FOREIGN TABLE INT8_TBL ( q1 int8, q2 int8 ) SERVER influxdb_svr; ---Testcase 58: +--Testcase 7: CREATE FOREIGN TABLE person ( name text, age int4, location point ) SERVER influxdb_svr; ---Testcase 59: +--Testcase 8: CREATE FOREIGN TABLE emp ( salary int4, manager text ) INHERITS (person) SERVER influxdb_svr; ---Testcase 60: +--Testcase 9: CREATE FOREIGN TABLE student ( gpa float8 ) INHERITS (person) SERVER influxdb_svr; ---Testcase 61: +--Testcase 10: CREATE FOREIGN TABLE stud_emp ( percent int4 ) INHERITS (emp, student) SERVER influxdb_svr; @@ -77,7 +77,7 @@ NOTICE: merging multiple inherited definitions of column "location" -- btree index -- awk '{if($1<10){print;}else{next;}}' onek.data | sort +0n -1 -- ---Testcase 1: +--Testcase 11: SELECT * FROM onek WHERE onek.unique1 < 10 ORDER BY onek.unique1; @@ -98,7 +98,7 @@ SELECT * FROM onek -- -- awk '{if($1<20){print $1,$14;}else{next;}}' onek.data | sort +0nr -1 -- ---Testcase 2: +--Testcase 12: SELECT onek.unique1, onek.stringu1 FROM onek WHERE onek.unique1 < 20 ORDER BY unique1 using >; @@ -129,7 +129,7 @@ SELECT onek.unique1, onek.stringu1 FROM onek -- -- awk '{if($1>980){print $1,$14;}else{next;}}' onek.data | sort +1d -2 -- ---Testcase 3: +--Testcase 13: SELECT onek.unique1, onek.stringu1 FROM onek WHERE onek.unique1 > 980 ORDER BY stringu1 using <; @@ -160,7 +160,7 @@ SELECT onek.unique1, onek.stringu1 FROM onek -- awk '{if($1>980){print $1,$16;}else{next;}}' onek.data | -- sort +1d -2 +0nr -1 -- ---Testcase 4: +--Testcase 14: SELECT onek.unique1, onek.string4 FROM onek WHERE onek.unique1 > 980 ORDER BY string4 using <, unique1 using >; @@ -191,7 +191,7 @@ SELECT onek.unique1, onek.string4 FROM onek -- awk '{if($1>980){print $1,$16;}else{next;}}' onek.data | -- sort +1dr -2 +0n -1 -- ---Testcase 5: +--Testcase 15: SELECT onek.unique1, onek.string4 FROM onek WHERE onek.unique1 > 980 ORDER BY string4 using >, unique1 using <; @@ -222,7 +222,7 @@ SELECT onek.unique1, onek.string4 FROM onek -- awk '{if($1<20){print $1,$16;}else{next;}}' onek.data | -- sort +0nr -1 +1d -2 -- ---Testcase 6: +--Testcase 16: SELECT onek.unique1, onek.string4 FROM onek WHERE onek.unique1 < 20 ORDER BY unique1 using >, string4 using <; @@ -254,7 +254,7 @@ SELECT onek.unique1, onek.string4 FROM onek -- awk '{if($1<20){print $1,$16;}else{next;}}' onek.data | -- sort +0n -1 +1dr -2 -- ---Testcase 7: +--Testcase 17: SELECT onek.unique1, onek.string4 FROM onek WHERE onek.unique1 < 20 ORDER BY unique1 using <, string4 using >; @@ -290,13 +290,16 @@ SELECT onek.unique1, onek.string4 FROM onek -- followed by sort, because that could hide index ordering problems. -- -- ANALYZE onek2; +--Testcase 18: SET enable_seqscan TO off; +--Testcase 19: SET enable_bitmapscan TO off; +--Testcase 20: SET enable_sort TO off; -- -- awk '{if($1<10){print $0;}else{next;}}' onek.data | sort +0n -1 -- ---Testcase 8: +--Testcase 21: SELECT onek2.* FROM onek2 WHERE onek2.unique1 < 10 order by 1; unique1 | unique2 | two | four | ten | twenty | hundred | thousand | twothousand | fivethous | tenthous | odd | even | stringu1 | stringu2 | string4 ---------+---------+-----+------+-----+--------+---------+----------+-------------+-----------+----------+-----+------+----------+----------+--------- @@ -315,7 +318,7 @@ SELECT onek2.* FROM onek2 WHERE onek2.unique1 < 10 order by 1; -- -- awk '{if($1<20){print $1,$14;}else{next;}}' onek.data | sort +0nr -1 -- ---Testcase 9: +--Testcase 22: SELECT onek2.unique1, onek2.stringu1 FROM onek2 WHERE onek2.unique1 < 20 ORDER BY unique1 using >; @@ -346,7 +349,7 @@ SELECT onek2.unique1, onek2.stringu1 FROM onek2 -- -- awk '{if($1>980){print $1,$14;}else{next;}}' onek.data | sort +1d -2 -- ---Testcase 10: +--Testcase 23: SELECT onek2.unique1, onek2.stringu1 FROM onek2 WHERE onek2.unique1 > 980 order by 1; unique1 | stringu1 @@ -372,13 +375,16 @@ SELECT onek2.unique1, onek2.stringu1 FROM onek2 999 | LMAAAA (19 rows) +--Testcase 24: RESET enable_seqscan; +--Testcase 25: RESET enable_bitmapscan; +--Testcase 26: RESET enable_sort; ---Testcase 11: -SELECT two, stringu1, ten, string4 - INTO TABLE tmp - FROM onek; +--Testcase 27: +--SELECT two, stringu1, ten, string4 +-- INTO TABLE tmp +-- FROM onek; -- -- awk '{print $1,$2;}' person.data | -- awk '{if(NF!=2){print $3,$2;}else{print;}}' - emp.data | @@ -386,7 +392,7 @@ SELECT two, stringu1, ten, string4 -- awk 'BEGIN{FS=" ";}{if(NF!=2){print $4,$5;}else{print;}}' - stud_emp.data -- -- SELECT name, age FROM person*; ??? check if different ---Testcase 12: +--Testcase 28: SELECT p.name, p.age FROM person* p; name | age ---------+----- @@ -457,7 +463,7 @@ SELECT p.name, p.age FROM person* p; -- awk 'BEGIN{FS=" ";}{if(NF!=1){print $4,$5;}else{print;}}' - stud_emp.data | -- sort +1nr -2 -- ---Testcase 13: +--Testcase 29: SELECT p.name, p.age FROM person* p ORDER BY age using >, name; name | age ---------+----- @@ -524,21 +530,21 @@ SELECT p.name, p.age FROM person* p ORDER BY age using >, name; -- -- Test some cases involving whole-row Var referencing a subquery -- ---Testcase 14: +--Testcase 30: select foo from (select 1 offset 0) as foo; foo ----- (1) (1 row) ---Testcase 15: +--Testcase 31: select foo from (select null offset 0) as foo; foo ----- () (1 row) ---Testcase 16: +--Testcase 32: select foo from (select 'xyzzy',1,null offset 0) as foo; foo ------------ @@ -548,7 +554,7 @@ select foo from (select 'xyzzy',1,null offset 0) as foo; -- -- Test VALUES lists -- ---Testcase 17: +--Testcase 33: select * from onek, (values(147, 'RFAAAA'), (931, 'VJAAAA')) as v (i, j) WHERE onek.unique1 = v.i and onek.stringu1 = v.j; unique1 | unique2 | two | four | ten | twenty | hundred | thousand | twothousand | fivethous | tenthous | odd | even | stringu1 | stringu2 | string4 | i | j @@ -559,7 +565,7 @@ select * from onek, (values(147, 'RFAAAA'), (931, 'VJAAAA')) as v (i, j) -- a more complex case -- looks like we're coding lisp :-) ---Testcase 18: +--Testcase 34: select * from onek, (values ((select i from (values(10000), (2), (389), (1000), (2000), ((select 10029))) as foo(i) @@ -571,7 +577,7 @@ select * from onek, (1 row) -- try VALUES in a subquery ---Testcase 19: +--Testcase 35: select * from onek where (unique1,ten) in (values (1,1), (20,0), (99,9), (17,99)) order by unique1; @@ -583,7 +589,7 @@ select * from onek (3 rows) -- VALUES is also legal as a standalone query or a set-operation member ---Testcase 20: +--Testcase 36: VALUES (1,2), (3,4+4), (7,77.7); column1 | column2 ---------+--------- @@ -592,7 +598,7 @@ VALUES (1,2), (3,4+4), (7,77.7); 7 | 77.7 (3 rows) ---Testcase 21: +--Testcase 37: VALUES (1,2), (3,4+4), (7,77.7) UNION ALL SELECT 2+2, 57 @@ -611,12 +617,20 @@ TABLE int8_tbl; 4567890123456789 | -4567890123456789 (9 rows) +-- -- corner case: VALUES with no columns +-- InfluxDB not support table with no columns. +-- --Testcase 79: +-- CREATE FOREIGN TABLE nocols() SERVER influxdb_svr; +-- --Testcase 80: +-- INSERT INTO nocols DEFAULT VALUES; +-- --Testcase 81: +-- SELECT * FROM nocols n, LATERAL (VALUES(n.*)) v; -- -- Test ORDER BY options -- ---Testcase 62: +--Testcase 38: CREATE FOREIGN TABLE foo (f1 int) SERVER influxdb_svr; ---Testcase 22: +--Testcase 39: SELECT * FROM foo ORDER BY f1; f1 ---- @@ -627,7 +641,7 @@ SELECT * FROM foo ORDER BY f1; 42 (5 rows) ---Testcase 23: +--Testcase 40: SELECT * FROM foo ORDER BY f1 ASC; -- same thing f1 ---- @@ -638,7 +652,7 @@ SELECT * FROM foo ORDER BY f1 ASC; -- same thing 42 (5 rows) ---Testcase 24: +--Testcase 41: SELECT * FROM foo ORDER BY f1 NULLS FIRST; f1 ---- @@ -649,7 +663,7 @@ SELECT * FROM foo ORDER BY f1 NULLS FIRST; 42 (5 rows) ---Testcase 25: +--Testcase 42: SELECT * FROM foo ORDER BY f1 DESC; f1 ---- @@ -660,7 +674,7 @@ SELECT * FROM foo ORDER BY f1 DESC; 1 (5 rows) ---Testcase 26: +--Testcase 43: SELECT * FROM foo ORDER BY f1 DESC NULLS LAST; f1 ---- @@ -694,15 +708,16 @@ SELECT * FROM foo ORDER BY f1 DESC NULLS LAST; -- Test planning of some cases with partial indexes -- -- partial index is usable ---Testcase 27: +--Testcase 44: explain (costs off) select * from onek2 where unique2 = 11 and stringu1 = 'ATAAAA'; - QUERY PLAN ------------------------ + QUERY PLAN +--------------------------------------- Foreign Scan on onek2 -(1 row) + Filter: (stringu1 = 'ATAAAA'::name) +(2 rows) ---Testcase 28: +--Testcase 45: select * from onek2 where unique2 = 11 and stringu1 = 'ATAAAA'; unique1 | unique2 | two | four | ten | twenty | hundred | thousand | twothousand | fivethous | tenthous | odd | even | stringu1 | stringu2 | string4 ---------+---------+-----+------+-----+--------+---------+----------+-------------+-----------+----------+-----+------+----------+----------+--------- @@ -710,23 +725,25 @@ select * from onek2 where unique2 = 11 and stringu1 = 'ATAAAA'; (1 row) -- actually run the query with an analyze to use the partial index ---Testcase 63: +--Testcase 46: explain (costs off, analyze on, timing off, summary off) select * from onek2 where unique2 = 11 and stringu1 = 'ATAAAA'; QUERY PLAN ----------------------------------------------- Foreign Scan on onek2 (actual rows=1 loops=1) -(1 row) + Filter: (stringu1 = 'ATAAAA'::name) +(2 rows) ---Testcase 30: +--Testcase 47: explain (costs off) select unique2 from onek2 where unique2 = 11 and stringu1 = 'ATAAAA'; - QUERY PLAN ------------------------ + QUERY PLAN +--------------------------------------- Foreign Scan on onek2 -(1 row) + Filter: (stringu1 = 'ATAAAA'::name) +(2 rows) ---Testcase 31: +--Testcase 48: select unique2 from onek2 where unique2 = 11 and stringu1 = 'ATAAAA'; unique2 --------- @@ -734,7 +751,7 @@ select unique2 from onek2 where unique2 = 11 and stringu1 = 'ATAAAA'; (1 row) -- partial index predicate implies clause, so no need for retest ---Testcase 32: +--Testcase 49: explain (costs off) select * from onek2 where unique2 = 11 and stringu1 < 'B'; QUERY PLAN @@ -743,14 +760,14 @@ select * from onek2 where unique2 = 11 and stringu1 < 'B'; Filter: (stringu1 < 'B'::name) (2 rows) ---Testcase 33: +--Testcase 50: select * from onek2 where unique2 = 11 and stringu1 < 'B'; unique1 | unique2 | two | four | ten | twenty | hundred | thousand | twothousand | fivethous | tenthous | odd | even | stringu1 | stringu2 | string4 ---------+---------+-----+------+-----+--------+---------+----------+-------------+-----------+----------+-----+------+----------+----------+--------- 494 | 11 | 0 | 2 | 4 | 14 | 4 | 94 | 94 | 494 | 494 | 8 | 9 | ATAAAA | LAAAAA | VVVVxx (1 row) ---Testcase 34: +--Testcase 51: explain (costs off) select unique2 from onek2 where unique2 = 11 and stringu1 < 'B'; QUERY PLAN @@ -759,7 +776,7 @@ select unique2 from onek2 where unique2 = 11 and stringu1 < 'B'; Filter: (stringu1 < 'B'::name) (2 rows) ---Testcase 35: +--Testcase 52: select unique2 from onek2 where unique2 = 11 and stringu1 < 'B'; unique2 --------- @@ -767,7 +784,7 @@ select unique2 from onek2 where unique2 = 11 and stringu1 < 'B'; (1 row) -- but if it's an update target, must retest anyway ---Testcase 36: +--Testcase 53: explain (costs off) select unique2 from onek2 where unique2 = 11 and stringu1 < 'B' for update; QUERY PLAN @@ -777,7 +794,7 @@ select unique2 from onek2 where unique2 = 11 and stringu1 < 'B' for update; Filter: (stringu1 < 'B'::name) (3 rows) ---Testcase 37: +--Testcase 54: select unique2 from onek2 where unique2 = 11 and stringu1 < 'B' for update; unique2 --------- @@ -785,7 +802,7 @@ select unique2 from onek2 where unique2 = 11 and stringu1 < 'B' for update; (1 row) -- partial index is not applicable ---Testcase 38: +--Testcase 55: explain (costs off) select unique2 from onek2 where unique2 = 11 and stringu1 < 'C'; QUERY PLAN @@ -794,7 +811,7 @@ select unique2 from onek2 where unique2 = 11 and stringu1 < 'C'; Filter: (stringu1 < 'C'::name) (2 rows) ---Testcase 39: +--Testcase 56: select unique2 from onek2 where unique2 = 11 and stringu1 < 'C'; unique2 --------- @@ -802,8 +819,9 @@ select unique2 from onek2 where unique2 = 11 and stringu1 < 'C'; (1 row) -- partial index implies clause, but bitmap scan must recheck predicate anyway +--Testcase 57: SET enable_indexscan TO off; ---Testcase 40: +--Testcase 58: explain (costs off) select unique2 from onek2 where unique2 = 11 and stringu1 < 'B'; QUERY PLAN @@ -812,16 +830,17 @@ select unique2 from onek2 where unique2 = 11 and stringu1 < 'B'; Filter: (stringu1 < 'B'::name) (2 rows) ---Testcase 41: +--Testcase 59: select unique2 from onek2 where unique2 = 11 and stringu1 < 'B'; unique2 --------- 11 (1 row) +--Testcase 60: RESET enable_indexscan; -- check multi-index cases too ---Testcase 42: +--Testcase 61: explain (costs off) select unique1, unique2 from onek2 where (unique2 = 11 or unique1 = 0) and stringu1 < 'B'; @@ -831,7 +850,7 @@ select unique1, unique2 from onek2 Filter: (stringu1 < 'B'::name) (2 rows) ---Testcase 43: +--Testcase 62: select unique1, unique2 from onek2 where (unique2 = 11 or unique1 = 0) and stringu1 < 'B'; unique1 | unique2 @@ -840,7 +859,7 @@ select unique1, unique2 from onek2 0 | 998 (2 rows) ---Testcase 44: +--Testcase 63: explain (costs off) select unique1, unique2 from onek2 where (unique2 = 11 and stringu1 < 'B') or unique1 = 0; @@ -850,7 +869,7 @@ select unique1, unique2 from onek2 Filter: (((unique2 = 11) AND (stringu1 < 'B'::name)) OR (unique1 = 0)) (2 rows) ---Testcase 45: +--Testcase 64: select unique1, unique2 from onek2 where (unique2 = 11 and stringu1 < 'B') or unique1 = 0; unique1 | unique2 @@ -863,7 +882,7 @@ select unique1, unique2 from onek2 -- Test some corner cases that have been known to confuse the planner -- -- ORDER BY on a constant doesn't really need any sorting ---Testcase 46: +--Testcase 65: SELECT 1 AS x ORDER BY x; x --- @@ -871,10 +890,10 @@ SELECT 1 AS x ORDER BY x; (1 row) -- But ORDER BY on a set-valued expression does ---Testcase 64: +--Testcase 66: create function sillysrf(int) returns setof int as 'values (1),(10),(2),($1)' language sql immutable; ---Testcase 47: +--Testcase 67: select sillysrf(42); sillysrf ---------- @@ -884,7 +903,7 @@ select sillysrf(42); 42 (4 rows) ---Testcase 48: +--Testcase 68: select sillysrf(-1) order by 1; sillysrf ---------- @@ -894,11 +913,11 @@ select sillysrf(-1) order by 1; 10 (4 rows) ---Testcase 65: +--Testcase 69: drop function sillysrf(int); -- X = X isn't a no-op, it's effectively X IS NOT NULL assuming = is strict -- (see bug #5084) ---Testcase 49: +--Testcase 70: select * from (values (2),(null),(1)) v(k) where k = k order by k; k --- @@ -906,7 +925,7 @@ select * from (values (2),(null),(1)) v(k) where k = k order by k; 2 (2 rows) ---Testcase 50: +--Testcase 71: select * from (values (2),(null),(1)) v(k) where k = k; k --- @@ -916,12 +935,12 @@ select * from (values (2),(null),(1)) v(k) where k = k; -- Test partitioned tables with no partitions, which should be handled the -- same as the non-inheritance case when expanding its RTE. ---Testcase 66: +--Testcase 72: create table list_parted_tbl (a int,b int) partition by list (a); ---Testcase 67: +--Testcase 73: create table list_parted_tbl1 partition of list_parted_tbl for values in (1) partition by list(b); ---Testcase 51: +--Testcase 74: explain (costs off) select * from list_parted_tbl; QUERY PLAN -------------------------- @@ -929,13 +948,13 @@ explain (costs off) select * from list_parted_tbl; One-Time Filter: false (2 rows) ---Testcase 68: +--Testcase 75: drop table list_parted_tbl; -- Clean up: -DROP TABLE IF EXISTS tmp; ---Testcase 69: +--DROP TABLE IF EXISTS tmp; +--Testcase 76: DROP USER MAPPING FOR CURRENT_USER SERVER influxdb_svr; ---Testcase 70: +--Testcase 77: DROP SERVER influxdb_svr CASCADE; NOTICE: drop cascades to 8 other objects DETAIL: drop cascades to foreign table onek @@ -946,5 +965,5 @@ drop cascades to foreign table emp drop cascades to foreign table student drop cascades to foreign table stud_emp drop cascades to foreign table foo ---Testcase 71: +--Testcase 78: DROP EXTENSION influxdb_fdw CASCADE; diff --git a/expected/14.5/extra/select_having.out b/expected/16.0/extra/select_having.out similarity index 99% rename from expected/14.5/extra/select_having.out rename to expected/16.0/extra/select_having.out index 036a7d3..bda3119 100644 --- a/expected/14.5/extra/select_having.out +++ b/expected/16.0/extra/select_having.out @@ -121,7 +121,9 @@ SELECT 1 AS one FROM test_having WHERE 1/a = 1 HAVING 1 < 2; --Testcase 26: -- Clean up: +--Testcase 30: DELETE FROM test_having; +--Testcase 31: DROP FOREIGN TABLE test_having; --Testcase 27: DROP USER MAPPING FOR CURRENT_USER SERVER influxdb_svr; diff --git a/expected/16.0/influxdb_fdw.out b/expected/16.0/influxdb_fdw.out new file mode 100644 index 0000000..7e6a546 --- /dev/null +++ b/expected/16.0/influxdb_fdw.out @@ -0,0 +1,1755 @@ +--SET log_min_messages=debug1; +--SET client_min_messages=debug1; +--Testcase 1: +SET datestyle=ISO; +-- timestamp with time zone differs based on this +--Testcase 2: +SET timezone='Japan'; +\set ECHO none +--Testcase 3: +CREATE EXTENSION influxdb_fdw; +--Testcase 4: +CREATE SERVER server1 FOREIGN DATA WRAPPER influxdb_fdw OPTIONS +(dbname 'mydb', :SERVER); +--Testcase 5: +CREATE USER MAPPING FOR CURRENT_USER SERVER server1 OPTIONS (:AUTHENTICATION); +-- import time column as timestamp and text type +IMPORT FOREIGN SCHEMA public FROM SERVER server1 INTO public OPTIONS(import_time_text 'true'); +--Testcase 6: +SELECT * FROM cpu; + time | time_text | tag1 | tag2 | value1 | value2 | value3 | value4 +------------------------+----------------------+--------+--------+--------+--------+--------+-------- + 2015-08-18 09:00:00+09 | 2015-08-18T00:00:00Z | tag1_A | tag2_A | 100 | 0.5 | str | t + 2015-08-18 09:00:00+09 | 2015-08-18T00:00:00Z | tag1_B | | 100 | 2 | | f + 2015-08-18 09:48:08+09 | 2015-08-18T00:48:08Z | | tag2_A | | 2 | | +(3 rows) + +--Testcase 7: +SELECT tag1, value1 FROM cpu; + tag1 | value1 +--------+-------- + tag1_A | 100 + tag1_B | 100 +(2 rows) + +--Testcase 8: +SELECT value1, time, value2 FROM cpu; + value1 | time | value2 +--------+------------------------+-------- + 100 | 2015-08-18 09:00:00+09 | 0.5 + 100 | 2015-08-18 09:00:00+09 | 2 + | 2015-08-18 09:48:08+09 | 2 +(3 rows) + +--Testcase 9: +SELECT value1, time_text, value2 FROM cpu; + value1 | time_text | value2 +--------+----------------------+-------- + 100 | 2015-08-18T00:00:00Z | 0.5 + 100 | 2015-08-18T00:00:00Z | 2 + | 2015-08-18T00:48:08Z | 2 +(3 rows) + +--Testcase 10: +DROP FOREIGN TABLE cpu; +--Testcase 11: +DROP FOREIGN TABLE t3; +--Testcase 12: +DROP FOREIGN TABLE t4; +--Testcase 13: +DROP FOREIGN TABLE tx; +--Testcase 14: +DROP FOREIGN TABLE numbers; +-- test EXECPT +IMPORT FOREIGN SCHEMA public EXCEPT (cpu, t3, t4, tx, numbers) FROM SERVER server1 INTO public; +--Testcase 15: +SELECT ftoptions FROM pg_foreign_table; + ftoptions +----------- +(0 rows) + +-- test LIMIT TO +IMPORT FOREIGN SCHEMA public LIMIT TO (cpu) FROM SERVER server1 INTO public; +--Testcase 16: +SELECT ftoptions FROM pg_foreign_table; + ftoptions +------------------------------ + {table=cpu,"tags=tag1,tag2"} +(1 row) + +--Testcase 17: +DROP FOREIGN TABLE cpu; +IMPORT FOREIGN SCHEMA public FROM SERVER server1 INTO public OPTIONS(import_time_text 'false'); +--Testcase 18: +SELECT * FROM cpu; + time | tag1 | tag2 | value1 | value2 | value3 | value4 +------------------------+--------+--------+--------+--------+--------+-------- + 2015-08-18 09:00:00+09 | tag1_A | tag2_A | 100 | 0.5 | str | t + 2015-08-18 09:00:00+09 | tag1_B | | 100 | 2 | | f + 2015-08-18 09:48:08+09 | | tag2_A | | 2 | | +(3 rows) + +--Testcase 19: +SELECT tag1, value1 FROM cpu; + tag1 | value1 +--------+-------- + tag1_A | 100 + tag1_B | 100 +(2 rows) + +--Testcase 20: +SELECT value1, time, value2 FROM cpu; + value1 | time | value2 +--------+------------------------+-------- + 100 | 2015-08-18 09:00:00+09 | 0.5 + 100 | 2015-08-18 09:00:00+09 | 2 + | 2015-08-18 09:48:08+09 | 2 +(3 rows) + +--Testcase 21: +SELECT tag1 FROM cpu; + tag1 +-------- + tag1_A + tag1_B +(2 rows) + +--Testcase 22: +SELECT * FROM numbers; + time | tag1 | a | b +------------------------+------+---+----- + 1970-01-01 09:00:00+09 | a | 1 | One + 1970-01-01 09:00:01+09 | a | 2 | Two +(2 rows) + +--Testcase 23: +\d cpu; + Foreign table "public.cpu" + Column | Type | Collation | Nullable | Default | FDW options +--------+--------------------------+-----------+----------+---------+------------- + time | timestamp with time zone | | | | + tag1 | text | | | | + tag2 | text | | | | + value1 | bigint | | | | + value2 | double precision | | | | + value3 | text | | | | + value4 | boolean | | | | +Server: server1 +FDW options: ("table" 'cpu', tags 'tag1,tag2') + +--Testcase 24: +SELECT * FROM cpu WHERE value1=100; + time | tag1 | tag2 | value1 | value2 | value3 | value4 +------------------------+--------+--------+--------+--------+--------+-------- + 2015-08-18 09:00:00+09 | tag1_A | tag2_A | 100 | 0.5 | str | t + 2015-08-18 09:00:00+09 | tag1_B | | 100 | 2 | | f +(2 rows) + +--Testcase 25: +SELECT * FROM cpu WHERE value2=0.5; + time | tag1 | tag2 | value1 | value2 | value3 | value4 +------------------------+--------+--------+--------+--------+--------+-------- + 2015-08-18 09:00:00+09 | tag1_A | tag2_A | 100 | 0.5 | str | t +(1 row) + +--Testcase 26: +SELECT * FROM cpu WHERE value3='str'; + time | tag1 | tag2 | value1 | value2 | value3 | value4 +------------------------+--------+--------+--------+--------+--------+-------- + 2015-08-18 09:00:00+09 | tag1_A | tag2_A | 100 | 0.5 | str | t +(1 row) + +--Testcase 27: +SELECT * FROM cpu WHERE value4=true; + time | tag1 | tag2 | value1 | value2 | value3 | value4 +------------------------+--------+--------+--------+--------+--------+-------- + 2015-08-18 09:00:00+09 | tag1_A | tag2_A | 100 | 0.5 | str | t +(1 row) + +--Testcase 28: +SELECT * FROM cpu WHERE NOT (value4 AND value1=100); + time | tag1 | tag2 | value1 | value2 | value3 | value4 +------------------------+--------+------+--------+--------+--------+-------- + 2015-08-18 09:00:00+09 | tag1_B | | 100 | 2 | | f +(1 row) + +--Testcase 29: +SELECT * FROM cpu WHERE tag1='tag1_A'; + time | tag1 | tag2 | value1 | value2 | value3 | value4 +------------------------+--------+--------+--------+--------+--------+-------- + 2015-08-18 09:00:00+09 | tag1_A | tag2_A | 100 | 0.5 | str | t +(1 row) + +--Testcase 30: +EXPLAIN (VERBOSE, COSTS OFF) +SELECT * FROM cpu WHERE value3 IS NULL; + QUERY PLAN +-------------------------------------------------------------------------------------------- + Foreign Scan on public.cpu + Output: "time", tag1, tag2, value1, value2, value3, value4 + Filter: (cpu.value3 IS NULL) + InfluxDB query: SELECT "tag1", "tag2", "value1", "value2", "value3", "value4" FROM "cpu" +(4 rows) + +--Testcase 31: +SELECT * FROM cpu WHERE value3 IS NULL; + time | tag1 | tag2 | value1 | value2 | value3 | value4 +------------------------+--------+--------+--------+--------+--------+-------- + 2015-08-18 09:00:00+09 | tag1_B | | 100 | 2 | | f + 2015-08-18 09:48:08+09 | | tag2_A | | 2 | | +(2 rows) + +--Testcase 32: +SELECT * FROM cpu WHERE tag2 IS NULL; + time | tag1 | tag2 | value1 | value2 | value3 | value4 +------------------------+--------+------+--------+--------+--------+-------- + 2015-08-18 09:00:00+09 | tag1_B | | 100 | 2 | | f +(1 row) + +--Testcase 33: +SELECT * FROM cpu WHERE value3 IS NOT NULL; + time | tag1 | tag2 | value1 | value2 | value3 | value4 +------------------------+--------+--------+--------+--------+--------+-------- + 2015-08-18 09:00:00+09 | tag1_A | tag2_A | 100 | 0.5 | str | t +(1 row) + +--Testcase 34: +SELECT * FROM cpu WHERE tag2 IS NOT NULL; + time | tag1 | tag2 | value1 | value2 | value3 | value4 +------------------------+--------+--------+--------+--------+--------+-------- + 2015-08-18 09:00:00+09 | tag1_A | tag2_A | 100 | 0.5 | str | t + 2015-08-18 09:48:08+09 | | tag2_A | | 2 | | +(2 rows) + +-- InfluxDB not support compare timestamp with OR condition +--Testcase 35: +SELECT * FROM cpu WHERE time = '2015-08-18 09:48:08+09' OR value2 = 0.5; + time | tag1 | tag2 | value1 | value2 | value3 | value4 +------------------------+--------+--------+--------+--------+--------+-------- + 2015-08-18 09:00:00+09 | tag1_A | tag2_A | 100 | 0.5 | str | t + 2015-08-18 09:48:08+09 | | tag2_A | | 2 | | +(2 rows) + +-- InfluxDB not support compare timestamp with != or <> +--Testcase 36: +SELECT * FROM cpu WHERE time != '2015-08-18 09:48:08+09'; + time | tag1 | tag2 | value1 | value2 | value3 | value4 +------------------------+--------+--------+--------+--------+--------+-------- + 2015-08-18 09:00:00+09 | tag1_A | tag2_A | 100 | 0.5 | str | t + 2015-08-18 09:00:00+09 | tag1_B | | 100 | 2 | | f +(2 rows) + +--Testcase 37: +SELECT * FROM cpu WHERE time <> '2015-08-18 09:48:08+09'; + time | tag1 | tag2 | value1 | value2 | value3 | value4 +------------------------+--------+--------+--------+--------+--------+-------- + 2015-08-18 09:00:00+09 | tag1_A | tag2_A | 100 | 0.5 | str | t + 2015-08-18 09:00:00+09 | tag1_B | | 100 | 2 | | f +(2 rows) + +--Testcase 38: +SELECT * FROM cpu WHERE time = '2015-08-18 09:48:08+09' OR value2 = 0.5; + time | tag1 | tag2 | value1 | value2 | value3 | value4 +------------------------+--------+--------+--------+--------+--------+-------- + 2015-08-18 09:00:00+09 | tag1_A | tag2_A | 100 | 0.5 | str | t + 2015-08-18 09:48:08+09 | | tag2_A | | 2 | | +(2 rows) + +-- There is inconsitency for search of missing values between tag and field +--Testcase 39: +EXPLAIN (VERBOSE, COSTS OFF) +SELECT * FROM cpu WHERE value3 = ''; + QUERY PLAN +-------------------------------------------------------------------------------------------------------------------- + Foreign Scan on public.cpu + Output: "time", tag1, tag2, value1, value2, value3, value4 + InfluxDB query: SELECT "tag1", "tag2", "value1", "value2", "value3", "value4" FROM "cpu" WHERE (("value3" = '')) +(3 rows) + +--Testcase 40: +SELECT * FROM cpu WHERE value3 = ''; + time | tag1 | tag2 | value1 | value2 | value3 | value4 +------+------+------+--------+--------+--------+-------- +(0 rows) + +--Testcase 41: +EXPLAIN (VERBOSE, COSTS OFF) +SELECT * FROM cpu WHERE tag2 = ''; + QUERY PLAN +------------------------------------------------------------------------------------------------------------------ + Foreign Scan on public.cpu + Output: "time", tag1, tag2, value1, value2, value3, value4 + InfluxDB query: SELECT "tag1", "tag2", "value1", "value2", "value3", "value4" FROM "cpu" WHERE (("tag2" = '')) +(3 rows) + +--Testcase 42: +SELECT * FROM cpu WHERE tag2 = ''; + time | tag1 | tag2 | value1 | value2 | value3 | value4 +------------------------+--------+------+--------+--------+--------+-------- + 2015-08-18 09:00:00+09 | tag1_B | | 100 | 2 | | f +(1 row) + +--Testcase 43: +SELECT * FROM cpu WHERE tag1 IN ('tag1_A', 'tag1_B'); + time | tag1 | tag2 | value1 | value2 | value3 | value4 +------------------------+--------+--------+--------+--------+--------+-------- + 2015-08-18 09:00:00+09 | tag1_A | tag2_A | 100 | 0.5 | str | t + 2015-08-18 09:00:00+09 | tag1_B | | 100 | 2 | | f +(2 rows) + +--Testcase 44: +EXPLAIN VERBOSE +SELECT * FROM cpu WHERE tag1 IN ('tag1_A', 'tag1_B'); + QUERY PLAN +------------------------------------------------------------------------------------------------------------------------------------------- + Foreign Scan on public.cpu (cost=10.00..6.00 rows=6 width=121) + Output: "time", tag1, tag2, value1, value2, value3, value4 + InfluxDB query: SELECT "tag1", "tag2", "value1", "value2", "value3", "value4" FROM "cpu" WHERE ("tag1" = 'tag1_A' OR "tag1" = 'tag1_B') +(3 rows) + +-- Rows which have no tag are considered to have empty string +--Testcase 45: +SELECT * FROM cpu WHERE tag1 NOT IN ('tag1_A', 'tag1_B'); + time | tag1 | tag2 | value1 | value2 | value3 | value4 +------------------------+------+--------+--------+--------+--------+-------- + 2015-08-18 09:48:08+09 | | tag2_A | | 2 | | +(1 row) + +--Testcase 46: +EXPLAIN VERBOSE +SELECT * FROM cpu WHERE tag1 NOT IN ('tag1_A', 'tag1_B'); + QUERY PLAN +---------------------------------------------------------------------------------------------------------------------------------------------- + Foreign Scan on public.cpu (cost=10.00..558.00 rows=558 width=121) + Output: "time", tag1, tag2, value1, value2, value3, value4 + InfluxDB query: SELECT "tag1", "tag2", "value1", "value2", "value3", "value4" FROM "cpu" WHERE ("tag1" <> 'tag1_A' AND "tag1" <> 'tag1_B') +(3 rows) + +-- test IN/NOT IN +--Testcase 47: +SELECT * FROM cpu WHERE time IN ('2015-08-18 09:48:08+09','2016-08-28 07:44:00+07'); + time | tag1 | tag2 | value1 | value2 | value3 | value4 +------------------------+------+--------+--------+--------+--------+-------- + 2015-08-18 09:48:08+09 | | tag2_A | | 2 | | +(1 row) + +--Testcase 48: +SELECT * FROM cpu WHERE time NOT IN ('2015-08-18 09:48:08+09','2016-08-28 07:44:00+07'); + time | tag1 | tag2 | value1 | value2 | value3 | value4 +------------------------+--------+--------+--------+--------+--------+-------- + 2015-08-18 09:00:00+09 | tag1_A | tag2_A | 100 | 0.5 | str | t + 2015-08-18 09:00:00+09 | tag1_B | | 100 | 2 | | f +(2 rows) + +--Testcase 49: +SELECT * FROM cpu WHERE value1 NOT IN (100, 97); + time | tag1 | tag2 | value1 | value2 | value3 | value4 +------+------+------+--------+--------+--------+-------- +(0 rows) + +--Testcase 50: +SELECT * FROM cpu WHERE value1 IN (100, 97); + time | tag1 | tag2 | value1 | value2 | value3 | value4 +------------------------+--------+--------+--------+--------+--------+-------- + 2015-08-18 09:00:00+09 | tag1_A | tag2_A | 100 | 0.5 | str | t + 2015-08-18 09:00:00+09 | tag1_B | | 100 | 2 | | f +(2 rows) + +--Testcase 51: +SELECT * FROM cpu WHERE value2 IN (0.5, 10.9); + time | tag1 | tag2 | value1 | value2 | value3 | value4 +------------------------+--------+--------+--------+--------+--------+-------- + 2015-08-18 09:00:00+09 | tag1_A | tag2_A | 100 | 0.5 | str | t +(1 row) + +--Testcase 52: +SELECT * FROM cpu WHERE value2 NOT IN (2, 9.7); + time | tag1 | tag2 | value1 | value2 | value3 | value4 +------------------------+--------+--------+--------+--------+--------+-------- + 2015-08-18 09:00:00+09 | tag1_A | tag2_A | 100 | 0.5 | str | t +(1 row) + +--Testcase 53: +SELECT * FROM cpu WHERE value4 NOT IN ('true', 'true'); + time | tag1 | tag2 | value1 | value2 | value3 | value4 +------------------------+--------+------+--------+--------+--------+-------- + 2015-08-18 09:00:00+09 | tag1_B | | 100 | 2 | | f +(1 row) + +--Testcase 54: +SELECT * FROM cpu WHERE time IN ('2015-08-18 09:48:08+09','2016-08-28 07:44:00+07'); + time | tag1 | tag2 | value1 | value2 | value3 | value4 +------------------------+------+--------+--------+--------+--------+-------- + 2015-08-18 09:48:08+09 | | tag2_A | | 2 | | +(1 row) + +--Testcase 55: +SELECT * FROM cpu WHERE time NOT IN ('2015-08-18 09:48:08+09','2016-08-28 07:44:00+07'); + time | tag1 | tag2 | value1 | value2 | value3 | value4 +------------------------+--------+--------+--------+--------+--------+-------- + 2015-08-18 09:00:00+09 | tag1_A | tag2_A | 100 | 0.5 | str | t + 2015-08-18 09:00:00+09 | tag1_B | | 100 | 2 | | f +(2 rows) + +--Testcase 56: +SELECT * FROM cpu WHERE value1 NOT IN (100, 97); + time | tag1 | tag2 | value1 | value2 | value3 | value4 +------+------+------+--------+--------+--------+-------- +(0 rows) + +--Testcase 57: +SELECT * FROM cpu WHERE value1 IN (100, 97); + time | tag1 | tag2 | value1 | value2 | value3 | value4 +------------------------+--------+--------+--------+--------+--------+-------- + 2015-08-18 09:00:00+09 | tag1_A | tag2_A | 100 | 0.5 | str | t + 2015-08-18 09:00:00+09 | tag1_B | | 100 | 2 | | f +(2 rows) + +--Testcase 58: +SELECT * FROM cpu WHERE value2 IN (0.5, 10.9); + time | tag1 | tag2 | value1 | value2 | value3 | value4 +------------------------+--------+--------+--------+--------+--------+-------- + 2015-08-18 09:00:00+09 | tag1_A | tag2_A | 100 | 0.5 | str | t +(1 row) + +--Testcase 59: +SELECT * FROM cpu WHERE value2 NOT IN (2, 9.7); + time | tag1 | tag2 | value1 | value2 | value3 | value4 +------------------------+--------+--------+--------+--------+--------+-------- + 2015-08-18 09:00:00+09 | tag1_A | tag2_A | 100 | 0.5 | str | t +(1 row) + +--Testcase 60: +SELECT * FROM cpu WHERE value4 NOT IN ('true', 'true'); + time | tag1 | tag2 | value1 | value2 | value3 | value4 +------------------------+--------+------+--------+--------+--------+-------- + 2015-08-18 09:00:00+09 | tag1_B | | 100 | 2 | | f +(1 row) + +--Testcase 61: +SELECT * FROM cpu WHERE value4 IN ('f', 't'); + time | tag1 | tag2 | value1 | value2 | value3 | value4 +------------------------+--------+--------+--------+--------+--------+-------- + 2015-08-18 09:00:00+09 | tag1_A | tag2_A | 100 | 0.5 | str | t + 2015-08-18 09:00:00+09 | tag1_B | | 100 | 2 | | f +(2 rows) + +--Testcase 62: +CREATE FOREIGN TABLE t1(time timestamp with time zone , tag1 text, value1 integer) SERVER server1 OPTIONS (table 'cpu'); +--Testcase 63: +CREATE FOREIGN TABLE t2(time timestamp , tag1 text, value1 integer) SERVER server1 OPTIONS (table 'cpu'); +--Testcase 64: +SELECT * FROM t1; + time | tag1 | value1 +------------------------+--------+-------- + 2015-08-18 09:00:00+09 | tag1_A | 100 + 2015-08-18 09:00:00+09 | tag1_B | 100 +(2 rows) + +--Testcase 65: +SELECT * FROM t2; + time | tag1 | value1 +---------------------+--------+-------- + 2015-08-18 00:00:00 | tag1_A | 100 + 2015-08-18 00:00:00 | tag1_B | 100 +(2 rows) + +-- In following four queries, timestamp condition is added to InfluxQL as "time = '2015-08-18 00:00:00'" +--Testcase 66: +SELECT * FROM t1 WHERE time = TIMESTAMP WITH TIME ZONE '2015-08-18 09:00:00+09'; + time | tag1 | value1 +------------------------+--------+-------- + 2015-08-18 09:00:00+09 | tag1_A | 100 + 2015-08-18 09:00:00+09 | tag1_B | 100 +(2 rows) + +--Testcase 67: +SELECT * FROM t1 WHERE time = TIMESTAMP '2015-08-18 00:00:00'; + time | tag1 | value1 +------------------------+--------+-------- + 2015-08-18 09:00:00+09 | tag1_A | 100 + 2015-08-18 09:00:00+09 | tag1_B | 100 +(2 rows) + +--Testcase 68: +SELECT * FROM t2 WHERE time = TIMESTAMP WITH TIME ZONE '2015-08-18 09:00:00+09'; + time | tag1 | value1 +---------------------+--------+-------- + 2015-08-18 00:00:00 | tag1_A | 100 + 2015-08-18 00:00:00 | tag1_B | 100 +(2 rows) + +--Testcase 69: +SELECT * FROM t2 WHERE time = TIMESTAMP '2015-08-18 00:00:00'; + time | tag1 | value1 +---------------------+--------+-------- + 2015-08-18 00:00:00 | tag1_A | 100 + 2015-08-18 00:00:00 | tag1_B | 100 +(2 rows) + +-- pushdown now() +--Testcase 70: +SELECT * FROM t2 WHERE now() > time; + time | tag1 | value1 +---------------------+--------+-------- + 2015-08-18 00:00:00 | tag1_A | 100 + 2015-08-18 00:00:00 | tag1_B | 100 +(2 rows) + +--Testcase 71: +EXPLAIN VERBOSE +SELECT * FROM t2 WHERE now() > time; + QUERY PLAN +----------------------------------------------------------------------------- + Foreign Scan on public.t2 (cost=10.00..401.00 rows=401 width=44) + Output: "time", tag1, value1 + InfluxDB query: SELECT "tag1", "value1" FROM "cpu" WHERE ((now() > time)) +(3 rows) + +--Testcase 72: +SELECT * FROM t2 WHERE time = TIMESTAMP WITH TIME ZONE '2015-08-26 05:43:21.1+00' - interval '1 week 1 day 5 hour 43 minute 21 second 100 millisecond'; + time | tag1 | value1 +---------------------+--------+-------- + 2015-08-18 00:00:00 | tag1_A | 100 + 2015-08-18 00:00:00 | tag1_B | 100 +(2 rows) + +--Testcase 73: +EXPLAIN VERBOSE +SELECT * FROM t2 WHERE time = TIMESTAMP WITH TIME ZONE '2015-08-26 05:43:21.1+00' - interval '1 week 1 day 5 hour 43 minute 21 second 100 millisecond'; + QUERY PLAN +--------------------------------------------------------------------------------------------------------------------- + Foreign Scan on public.t2 (cost=10.00..6.00 rows=6 width=44) + Output: "time", tag1, value1 + InfluxDB query: SELECT "tag1", "value1" FROM "cpu" WHERE ((time = ('2015-08-26 05:43:21.1' - 8d5h43m21s100000u))) +(3 rows) + +-- InfluxDB does not seem to support time column + interval, so below query returns empty result +-- SELECT * FROM t2 WHERE time + interval '1 week 1 day 5 hour 43 minute 21 second 100 millisecond' = TIMESTAMP WITH TIME ZONE '2015-08-26 05:43:21.1+00'; +-- EXPLAIN (VERBOSE, COSTS OFF) +-- SELECT * FROM t2 WHERE time + interval '1 week 1 day 5 hour 43 minute 21 second 100 millisecond' = TIMESTAMP WITH TIME ZONE '2015-08-26 05:43:21.1+00'; +-- InfluxDB does not support month or year interval, so not push down +--Testcase 74: +SELECT * FROM t2 WHERE time = TIMESTAMP '2015-09-18 00:00:00' - interval '1 months'; + time | tag1 | value1 +---------------------+--------+-------- + 2015-08-18 00:00:00 | tag1_A | 100 + 2015-08-18 00:00:00 | tag1_B | 100 +(2 rows) + +--Testcase 75: +EXPLAIN VERBOSE +SELECT * FROM t2 WHERE time = TIMESTAMP '2015-09-18 00:00:00' - interval '1 months'; + QUERY PLAN +--------------------------------------------------------------------------------------------- + Foreign Scan on public.t2 (cost=10.00..6.00 rows=6 width=44) + Output: "time", tag1, value1 + InfluxDB query: SELECT "tag1", "value1" FROM "cpu" WHERE ((time = '2015-08-18 00:00:00')) +(3 rows) + +--Testcase 76: +SELECT * FROM t2 WHERE value1 = ANY (ARRAY(SELECT value1 FROM t1 WHERE value1 < 1000)); + time | tag1 | value1 +---------------------+--------+-------- + 2015-08-18 00:00:00 | tag1_A | 100 + 2015-08-18 00:00:00 | tag1_B | 100 +(2 rows) + +-- ANY with ARRAY expression +--Testcase 77: +EXPLAIN VERBOSE +SELECT a, b FROM numbers WHERE a = ANY(ARRAY[1, a + 1]); + QUERY PLAN +----------------------------------------------------------------------------------------- + Foreign Scan on public.numbers (cost=10.00..13.00 rows=13 width=40) + Output: a, b + InfluxDB query: SELECT "a", "b" FROM "numbers" WHERE (("a" = 1) OR ("a" = ("a" + 1))) +(3 rows) + +--Testcase 78: +SELECT a, b FROM numbers WHERE a = ANY(ARRAY[1, a + 1]); + a | b +---+----- + 1 | One +(1 row) + +--Testcase 79: +EXPLAIN VERBOSE +SELECT a, b FROM numbers WHERE a <> ANY(ARRAY[1, a + 1]); + QUERY PLAN +------------------------------------------------------------------------------------------- + Foreign Scan on public.numbers (cost=10.00..1280.00 rows=1280 width=40) + Output: a, b + InfluxDB query: SELECT "a", "b" FROM "numbers" WHERE (("a" <> 1) OR ("a" <> ("a" + 1))) +(3 rows) + +--Testcase 80: +SELECT a, b FROM numbers WHERE a <> ANY(ARRAY[1, a + 1]); + a | b +---+----- + 1 | One + 2 | Two +(2 rows) + +--Testcase 81: +EXPLAIN VERBOSE +SELECT a, b FROM numbers WHERE a >= ANY(ARRAY[1, a + 1]); + QUERY PLAN +------------------------------------------------------------------------------------------- + Foreign Scan on public.numbers (cost=10.00..711.00 rows=711 width=40) + Output: a, b + InfluxDB query: SELECT "a", "b" FROM "numbers" WHERE (("a" >= 1) OR ("a" >= ("a" + 1))) +(3 rows) + +--Testcase 82: +SELECT a, b FROM numbers WHERE a >= ANY(ARRAY[1, a + 1]); + a | b +---+----- + 1 | One + 2 | Two +(2 rows) + +--Testcase 83: +EXPLAIN VERBOSE +SELECT a, b FROM numbers WHERE a <= ANY(ARRAY[1, a + 1]); + QUERY PLAN +------------------------------------------------------------------------------------------- + Foreign Scan on public.numbers (cost=10.00..711.00 rows=711 width=40) + Output: a, b + InfluxDB query: SELECT "a", "b" FROM "numbers" WHERE (("a" <= 1) OR ("a" <= ("a" + 1))) +(3 rows) + +--Testcase 84: +SELECT a, b FROM numbers WHERE a <= ANY(ARRAY[1, a + 1]); + a | b +---+----- + 1 | One + 2 | Two +(2 rows) + +--Testcase 85: +EXPLAIN VERBOSE +SELECT a, b FROM numbers WHERE a > ANY(ARRAY[1, a + 1]); + QUERY PLAN +----------------------------------------------------------------------------------------- + Foreign Scan on public.numbers (cost=10.00..711.00 rows=711 width=40) + Output: a, b + InfluxDB query: SELECT "a", "b" FROM "numbers" WHERE (("a" > 1) OR ("a" > ("a" + 1))) +(3 rows) + +--Testcase 86: +SELECT a, b FROM numbers WHERE a > ANY(ARRAY[1, a + 1]); + a | b +---+----- + 2 | Two +(1 row) + +--Testcase 87: +EXPLAIN VERBOSE +SELECT a, b FROM numbers WHERE a < ANY(ARRAY[1, a + 1]); + QUERY PLAN +----------------------------------------------------------------------------------------- + Foreign Scan on public.numbers (cost=10.00..711.00 rows=711 width=40) + Output: a, b + InfluxDB query: SELECT "a", "b" FROM "numbers" WHERE (("a" < 1) OR ("a" < ("a" + 1))) +(3 rows) + +--Testcase 88: +SELECT a, b FROM numbers WHERE a < ANY(ARRAY[1, a + 1]); + a | b +---+----- + 1 | One + 2 | Two +(2 rows) + +-- ANY with ARRAY const +--Testcase 89: +EXPLAIN VERBOSE +SELECT a, b FROM numbers WHERE a = ANY(ARRAY[1, 2]); + QUERY PLAN +----------------------------------------------------------------------------- + Foreign Scan on public.numbers (cost=10.00..13.00 rows=13 width=40) + Output: a, b + InfluxDB query: SELECT "a", "b" FROM "numbers" WHERE ("a" = 1 OR "a" = 2) +(3 rows) + +--Testcase 90: +SELECT a, b FROM numbers WHERE a = ANY(ARRAY[1, 2]); + a | b +---+----- + 1 | One + 2 | Two +(2 rows) + +--Testcase 91: +EXPLAIN VERBOSE +SELECT a, b FROM numbers WHERE a <> ANY(ARRAY[1, 2]); + QUERY PLAN +------------------------------------------------------------------------------- + Foreign Scan on public.numbers (cost=10.00..1280.00 rows=1280 width=40) + Output: a, b + InfluxDB query: SELECT "a", "b" FROM "numbers" WHERE ("a" <> 1 OR "a" <> 2) +(3 rows) + +--Testcase 92: +SELECT a, b FROM numbers WHERE a <> ANY(ARRAY[1, 2]); + a | b +---+----- + 1 | One + 2 | Two +(2 rows) + +--Testcase 93: +EXPLAIN VERBOSE +SELECT a, b FROM numbers WHERE a >= ANY(ARRAY[1, 2]); + QUERY PLAN +------------------------------------------------------------------------------- + Foreign Scan on public.numbers (cost=10.00..711.00 rows=711 width=40) + Output: a, b + InfluxDB query: SELECT "a", "b" FROM "numbers" WHERE ("a" >= 1 OR "a" >= 2) +(3 rows) + +--Testcase 94: +SELECT a, b FROM numbers WHERE a >= ANY(ARRAY[1, 2]); + a | b +---+----- + 1 | One + 2 | Two +(2 rows) + +--Testcase 95: +EXPLAIN VERBOSE +SELECT a, b FROM numbers WHERE a <= ANY(ARRAY[1, 2]); + QUERY PLAN +------------------------------------------------------------------------------- + Foreign Scan on public.numbers (cost=10.00..711.00 rows=711 width=40) + Output: a, b + InfluxDB query: SELECT "a", "b" FROM "numbers" WHERE ("a" <= 1 OR "a" <= 2) +(3 rows) + +--Testcase 96: +SELECT a, b FROM numbers WHERE a <= ANY(ARRAY[1, 2]); + a | b +---+----- + 1 | One + 2 | Two +(2 rows) + +--Testcase 97: +EXPLAIN VERBOSE +SELECT a, b FROM numbers WHERE a > ANY(ARRAY[1, 2]); + QUERY PLAN +----------------------------------------------------------------------------- + Foreign Scan on public.numbers (cost=10.00..711.00 rows=711 width=40) + Output: a, b + InfluxDB query: SELECT "a", "b" FROM "numbers" WHERE ("a" > 1 OR "a" > 2) +(3 rows) + +--Testcase 98: +SELECT a, b FROM numbers WHERE a > ANY(ARRAY[1, 2]); + a | b +---+----- + 2 | Two +(1 row) + +--Testcase 99: +EXPLAIN VERBOSE +SELECT a, b FROM numbers WHERE a < ANY(ARRAY[1, 2]); + QUERY PLAN +----------------------------------------------------------------------------- + Foreign Scan on public.numbers (cost=10.00..711.00 rows=711 width=40) + Output: a, b + InfluxDB query: SELECT "a", "b" FROM "numbers" WHERE ("a" < 1 OR "a" < 2) +(3 rows) + +--Testcase 100: +SELECT a, b FROM numbers WHERE a < ANY(ARRAY[1, 2]); + a | b +---+----- + 1 | One +(1 row) + +--Testcase 101: +EXPLAIN VERBOSE +SELECT a, b FROM numbers WHERE a = ANY('{1, 2, 3}'); + QUERY PLAN +---------------------------------------------------------------------------------------- + Foreign Scan on public.numbers (cost=10.00..19.00 rows=19 width=40) + Output: a, b + InfluxDB query: SELECT "a", "b" FROM "numbers" WHERE ("a" = 1 OR "a" = 2 OR "a" = 3) +(3 rows) + +--Testcase 102: +SELECT a, b FROM numbers WHERE a = ANY('{1, 2, 3}'); + a | b +---+----- + 1 | One + 2 | Two +(2 rows) + +--Testcase 103: +EXPLAIN VERBOSE +SELECT a, b FROM numbers WHERE a <> ANY('{1, 2, 3}'); + QUERY PLAN +------------------------------------------------------------------------------------------- + Foreign Scan on public.numbers (cost=10.00..1280.00 rows=1280 width=40) + Output: a, b + InfluxDB query: SELECT "a", "b" FROM "numbers" WHERE ("a" <> 1 OR "a" <> 2 OR "a" <> 3) +(3 rows) + +--Testcase 104: +SELECT a, b FROM numbers WHERE a <> ANY('{1, 2, 3}'); + a | b +---+----- + 1 | One + 2 | Two +(2 rows) + +-- ALL with ARRAY expression +--Testcase 105: +EXPLAIN VERBOSE +SELECT a, b FROM numbers WHERE a = ALL(ARRAY[1, a * 1]); + QUERY PLAN +------------------------------------------------------------------------------------------ + Foreign Scan on public.numbers (cost=10.00..1.00 rows=1 width=40) + Output: a, b + InfluxDB query: SELECT "a", "b" FROM "numbers" WHERE (("a" = 1) AND ("a" = ("a" * 1))) +(3 rows) + +--Testcase 106: +SELECT a, b FROM numbers WHERE a = ALL(ARRAY[1, a * 1]); + a | b +---+----- + 1 | One +(1 row) + +--Testcase 107: +EXPLAIN VERBOSE +SELECT a, b FROM numbers WHERE a <> ALL(ARRAY[1, a + 1]); + QUERY PLAN +-------------------------------------------------------------------------------------------- + Foreign Scan on public.numbers (cost=10.00..1267.00 rows=1267 width=40) + Output: a, b + InfluxDB query: SELECT "a", "b" FROM "numbers" WHERE (("a" <> 1) AND ("a" <> ("a" + 1))) +(3 rows) + +--Testcase 108: +SELECT a, b FROM numbers WHERE a <> ALL(ARRAY[1, a + 1]); + a | b +---+----- + 2 | Two +(1 row) + +--Testcase 109: +EXPLAIN VERBOSE +SELECT a, b FROM numbers WHERE a >= ALL(ARRAY[1, a / 1]); + QUERY PLAN +-------------------------------------------------------------------------------------------- + Foreign Scan on public.numbers (cost=10.00..142.00 rows=142 width=40) + Output: a, b + InfluxDB query: SELECT "a", "b" FROM "numbers" WHERE (("a" >= 1) AND ("a" >= ("a" / 1))) +(3 rows) + +--Testcase 110: +SELECT a, b FROM numbers WHERE a >= ALL(ARRAY[1, a / 1]); + a | b +---+----- + 1 | One + 2 | Two +(2 rows) + +--Testcase 111: +EXPLAIN VERBOSE +SELECT a, b FROM numbers WHERE a <= ALL(ARRAY[1, a + 1]); + QUERY PLAN +-------------------------------------------------------------------------------------------- + Foreign Scan on public.numbers (cost=10.00..142.00 rows=142 width=40) + Output: a, b + InfluxDB query: SELECT "a", "b" FROM "numbers" WHERE (("a" <= 1) AND ("a" <= ("a" + 1))) +(3 rows) + +--Testcase 112: +SELECT a, b FROM numbers WHERE a <= ALL(ARRAY[1, a + 1]); + a | b +---+----- + 1 | One +(1 row) + +--Testcase 113: +EXPLAIN VERBOSE +SELECT a, b FROM numbers WHERE a > ALL(ARRAY[1, a - 1]); + QUERY PLAN +------------------------------------------------------------------------------------------ + Foreign Scan on public.numbers (cost=10.00..142.00 rows=142 width=40) + Output: a, b + InfluxDB query: SELECT "a", "b" FROM "numbers" WHERE (("a" > 1) AND ("a" > ("a" - 1))) +(3 rows) + +--Testcase 114: +SELECT a, b FROM numbers WHERE a > ALL(ARRAY[1, a - 1]); + a | b +---+----- + 2 | Two +(1 row) + +--Testcase 115: +EXPLAIN VERBOSE +SELECT a, b FROM numbers WHERE a < ALL(ARRAY[2, a + 1]); + QUERY PLAN +------------------------------------------------------------------------------------------ + Foreign Scan on public.numbers (cost=10.00..142.00 rows=142 width=40) + Output: a, b + InfluxDB query: SELECT "a", "b" FROM "numbers" WHERE (("a" < 2) AND ("a" < ("a" + 1))) +(3 rows) + +--Testcase 116: +SELECT a, b FROM numbers WHERE a < ALL(ARRAY[2, a + 1]); + a | b +---+----- + 1 | One +(1 row) + +-- ALL with ARRAY const +--Testcase 117: +EXPLAIN VERBOSE +SELECT a, b FROM numbers WHERE a = ALL(ARRAY[1, 1]); + QUERY PLAN +------------------------------------------------------------------------------ + Foreign Scan on public.numbers (cost=10.00..1.00 rows=1 width=40) + Output: a, b + InfluxDB query: SELECT "a", "b" FROM "numbers" WHERE ("a" = 1 AND "a" = 1) +(3 rows) + +--Testcase 118: +SELECT a, b FROM numbers WHERE a = ALL(ARRAY[1, 1]); + a | b +---+----- + 1 | One +(1 row) + +--Testcase 119: +EXPLAIN VERBOSE +SELECT a, b FROM numbers WHERE a <> ALL(ARRAY[1, 3]); + QUERY PLAN +-------------------------------------------------------------------------------- + Foreign Scan on public.numbers (cost=10.00..1267.00 rows=1267 width=40) + Output: a, b + InfluxDB query: SELECT "a", "b" FROM "numbers" WHERE ("a" <> 1 AND "a" <> 3) +(3 rows) + +--Testcase 120: +SELECT a, b FROM numbers WHERE a <> ALL(ARRAY[1, 3]); + a | b +---+----- + 2 | Two +(1 row) + +--Testcase 121: +EXPLAIN VERBOSE +SELECT a, b FROM numbers WHERE a >= ALL(ARRAY[1, 2]); + QUERY PLAN +-------------------------------------------------------------------------------- + Foreign Scan on public.numbers (cost=10.00..142.00 rows=142 width=40) + Output: a, b + InfluxDB query: SELECT "a", "b" FROM "numbers" WHERE ("a" >= 1 AND "a" >= 2) +(3 rows) + +--Testcase 122: +SELECT a, b FROM numbers WHERE a >= ALL(ARRAY[1, 2]); + a | b +---+----- + 2 | Two +(1 row) + +--Testcase 123: +EXPLAIN VERBOSE +SELECT a, b FROM numbers WHERE a <= ALL(ARRAY[1, 2]); + QUERY PLAN +-------------------------------------------------------------------------------- + Foreign Scan on public.numbers (cost=10.00..142.00 rows=142 width=40) + Output: a, b + InfluxDB query: SELECT "a", "b" FROM "numbers" WHERE ("a" <= 1 AND "a" <= 2) +(3 rows) + +--Testcase 124: +SELECT a, b FROM numbers WHERE a <= ALL(ARRAY[1, 2]); + a | b +---+----- + 1 | One +(1 row) + +--Testcase 125: +EXPLAIN VERBOSE +SELECT a, b FROM numbers WHERE a > ALL(ARRAY[0, 1]); + QUERY PLAN +------------------------------------------------------------------------------ + Foreign Scan on public.numbers (cost=10.00..142.00 rows=142 width=40) + Output: a, b + InfluxDB query: SELECT "a", "b" FROM "numbers" WHERE ("a" > 0 AND "a" > 1) +(3 rows) + +--Testcase 126: +SELECT a, b FROM numbers WHERE a > ALL(ARRAY[0, 1]); + a | b +---+----- + 2 | Two +(1 row) + +--Testcase 127: +EXPLAIN VERBOSE +SELECT a, b FROM numbers WHERE a < ALL(ARRAY[2, 3]); + QUERY PLAN +------------------------------------------------------------------------------ + Foreign Scan on public.numbers (cost=10.00..142.00 rows=142 width=40) + Output: a, b + InfluxDB query: SELECT "a", "b" FROM "numbers" WHERE ("a" < 2 AND "a" < 3) +(3 rows) + +--Testcase 128: +SELECT a, b FROM numbers WHERE a < ALL(ARRAY[2, 3]); + a | b +---+----- + 1 | One +(1 row) + +-- ANY/ALL with TEXT ARRAY const +--Testcase 129: +EXPLAIN VERBOSE +SELECT a, b FROM numbers WHERE b = ANY(ARRAY['One', 'Two']); + QUERY PLAN +------------------------------------------------------------------------------------- + Foreign Scan on public.numbers (cost=10.00..13.00 rows=13 width=40) + Output: a, b + InfluxDB query: SELECT "a", "b" FROM "numbers" WHERE ("b" = 'One' OR "b" = 'Two') +(3 rows) + +--Testcase 130: +SELECT a, b FROM numbers WHERE b = ANY(ARRAY['One', 'Two']); + a | b +---+----- + 1 | One + 2 | Two +(2 rows) + +--Testcase 131: +EXPLAIN VERBOSE +SELECT a, b FROM numbers WHERE b <> ALL(ARRAY['One', 'Four']); + QUERY PLAN +----------------------------------------------------------------------------------------- + Foreign Scan on public.numbers (cost=10.00..1267.00 rows=1267 width=40) + Output: a, b + InfluxDB query: SELECT "a", "b" FROM "numbers" WHERE ("b" <> 'One' AND "b" <> 'Four') +(3 rows) + +--Testcase 132: +SELECT a, b FROM numbers WHERE b <> ALL(ARRAY['One', 'Four']); + a | b +---+----- + 2 | Two +(1 row) + +--Testcase 133: +EXPLAIN VERBOSE +SELECT a, b FROM numbers WHERE b > ANY(ARRAY['One', 'Two']); + QUERY PLAN +------------------------------------------------------------------------ + Foreign Scan on public.numbers (cost=10.00..711.00 rows=711 width=40) + Output: a, b + Filter: (numbers.b > ANY ('{One,Two}'::text[])) + InfluxDB query: SELECT "a", "b" FROM "numbers" +(4 rows) + +--Testcase 134: +SELECT a, b FROM numbers WHERE b > ANY(ARRAY['One', 'Two']); + a | b +---+----- + 2 | Two +(1 row) + +--Testcase 135: +EXPLAIN VERBOSE +SELECT * FROM numbers WHERE b > ALL(ARRAY['Four', 'Five']); + QUERY PLAN +---------------------------------------------------------------------- + Foreign Scan on public.numbers (cost=10.00..87.00 rows=87 width=80) + Output: "time", tag1, a, b + Filter: (numbers.b > ALL ('{Four,Five}'::text[])) + InfluxDB query: SELECT "tag1", "a", "b" FROM "numbers" +(4 rows) + +--Testcase 136: +SELECT a, b FROM numbers WHERE b > ALL(ARRAY['Four', 'Five']); + a | b +---+----- + 1 | One + 2 | Two +(2 rows) + +--Testcase 137: +DROP FOREIGN TABLE numbers; +--Testcase 138: +ALTER SERVER server1 OPTIONS (SET dbname 'no such database'); +--Testcase 139: +SELECT * FROM t1; +ERROR: influxdb_fdw : database not found: no such database +--Testcase 140: +ALTER SERVER server1 OPTIONS (SET dbname 'mydb'); +--Testcase 141: +SELECT * FROM t1; + time | tag1 | value1 +------------------------+--------+-------- + 2015-08-18 09:00:00+09 | tag1_A | 100 + 2015-08-18 09:00:00+09 | tag1_B | 100 +(2 rows) + +-- map time column to both timestamp and text +--Testcase 142: +CREATE FOREIGN TABLE t5(t timestamp OPTIONS (column_name 'time'), tag1 text OPTIONS (column_name 'time'), v1 integer OPTIONS (column_name 'value1')) SERVER server1 OPTIONS (table 'cpu'); +--Testcase 143: +SELECT * FROM t5; + t | tag1 | v1 +---------------------+----------------------+----- + 2015-08-18 00:00:00 | 2015-08-18T00:00:00Z | 100 + 2015-08-18 00:00:00 | 2015-08-18T00:00:00Z | 100 +(2 rows) + +--get version +--Testcase 144: +\df influxdb_fdw* + List of functions + Schema | Name | Result data type | Argument data types | Type +--------+------------------------+------------------+---------------------+------ + public | influxdb_fdw_handler | fdw_handler | | func + public | influxdb_fdw_validator | void | text[], oid | func + public | influxdb_fdw_version | integer | | func +(3 rows) + +--Testcase 145: +SELECT * FROM public.influxdb_fdw_version(); + influxdb_fdw_version +---------------------- + 20100 +(1 row) + +--Testcase 146: +SELECT influxdb_fdw_version(); + influxdb_fdw_version +---------------------- + 20100 +(1 row) + +--Test pushdown LIMIT...OFFSET +--Testcase 147: +EXPLAIN (VERBOSE, COSTS OFF) +SELECT tableoid::regclass, * FROM t1 LIMIT 1 OFFSET 0; + QUERY PLAN +----------------------------------------------------------------------- + Foreign Scan on public.t1 + Output: (tableoid)::regclass, "time", tag1, value1 + InfluxDB query: SELECT "tag1", "value1" FROM "cpu" LIMIT 1 OFFSET 0 +(3 rows) + +--Testcase 148: +SELECT tableoid::regclass, * FROM t1 LIMIT 1 OFFSET 0; + tableoid | time | tag1 | value1 +----------+------------------------+--------+-------- + t1 | 2015-08-18 09:00:00+09 | tag1_A | 100 +(1 row) + +--Testcase 149: +EXPLAIN (VERBOSE, COSTS OFF) +SELECT tableoid::regclass, * FROM t1 LIMIT 1 OFFSET 1; + QUERY PLAN +----------------------------------------------------------------------- + Foreign Scan on public.t1 + Output: (tableoid)::regclass, "time", tag1, value1 + InfluxDB query: SELECT "tag1", "value1" FROM "cpu" LIMIT 1 OFFSET 1 +(3 rows) + +--Testcase 150: +SELECT tableoid::regclass, * FROM t1 LIMIT 1 OFFSET 1; + tableoid | time | tag1 | value1 +----------+------------------------+--------+-------- + t1 | 2015-08-18 09:00:00+09 | tag1_B | 100 +(1 row) + +--Testcase 151: +EXPLAIN (VERBOSE, COSTS OFF) +SELECT ctid, * FROM t1 LIMIT 1 OFFSET 0; + QUERY PLAN +----------------------------------------------------------------------- + Foreign Scan on public.t1 + Output: ctid, "time", tag1, value1 + InfluxDB query: SELECT "tag1", "value1" FROM "cpu" LIMIT 1 OFFSET 0 +(3 rows) + +--Testcase 152: +SELECT ctid, * FROM t1 LIMIT 1 OFFSET 0; + ctid | time | tag1 | value1 +----------------+------------------------+--------+-------- + (4294967295,0) | 2015-08-18 09:00:00+09 | tag1_A | 100 +(1 row) + +--Testcase 153: +EXPLAIN (VERBOSE, COSTS OFF) +SELECT ctid, * FROM t2 LIMIT 10 OFFSET 20; + QUERY PLAN +------------------------------------------------------------------------- + Foreign Scan on public.t2 + Output: ctid, "time", tag1, value1 + InfluxDB query: SELECT "tag1", "value1" FROM "cpu" LIMIT 10 OFFSET 20 +(3 rows) + +--Testcase 154: +SELECT ctid, * FROM t2 LIMIT 10 OFFSET 20; + ctid | time | tag1 | value1 +------+------+------+-------- +(0 rows) + +--Testcase 155: +EXPLAIN (VERBOSE, COSTS OFF) +SELECT * FROM + t1 + LEFT JOIN t2 + ON t2.value1 = 123, + LATERAL (SELECT t2.value1, t1.tag1 FROM t1 LIMIT 1 OFFSET 0) AS ss +WHERE t1.value1 = ss.value1; + QUERY PLAN +------------------------------------------------------------------------------------------------- + Nested Loop + Output: t1."time", t1.tag1, t1.value1, t2."time", t2.tag1, t2.value1, (t2.value1), t1_1.tag1 + Join Filter: (t1.value1 = (t2.value1)) + -> Nested Loop Left Join + Output: t1."time", t1.tag1, t1.value1, t2."time", t2.tag1, t2.value1 + -> Foreign Scan on public.t1 + Output: t1."time", t1.tag1, t1.value1 + InfluxDB query: SELECT "tag1", "value1" FROM "cpu" + -> Materialize + Output: t2."time", t2.tag1, t2.value1 + -> Foreign Scan on public.t2 + Output: t2."time", t2.tag1, t2.value1 + InfluxDB query: SELECT "tag1", "value1" FROM "cpu" WHERE (("value1" = 123)) + -> Foreign Scan on public.t1 t1_1 + Output: t2.value1, t1_1.tag1 + InfluxDB query: SELECT "tag1" FROM "cpu" LIMIT 1 OFFSET 0 +(16 rows) + +--Testcase 156: +EXPLAIN (VERBOSE, COSTS OFF) +SELECT * FROM + t1 + LEFT JOIN t2 + ON t2.value1 = 123, + LATERAL (SELECT t2.value1, t1.tag1 FROM t1 LIMIT 1 OFFSET 0) AS ss1, + LATERAL (SELECT ss1.* from t3 LIMIT 1 OFFSET 20) AS ss2 +WHERE t1.value1 = ss2.value1; + QUERY PLAN +---------------------------------------------------------------------------------------------------------------------------- + Nested Loop + Output: t1."time", t1.tag1, t1.value1, t2."time", t2.tag1, t2.value1, (t2.value1), t1_1.tag1, ((t2.value1)), (t1_1.tag1) + Join Filter: (t1.value1 = ((t2.value1))) + -> Nested Loop + Output: t1."time", t1.tag1, t1.value1, t2."time", t2.tag1, t2.value1, (t2.value1), t1_1.tag1 + -> Nested Loop Left Join + Output: t1."time", t1.tag1, t1.value1, t2."time", t2.tag1, t2.value1 + -> Foreign Scan on public.t1 + Output: t1."time", t1.tag1, t1.value1 + InfluxDB query: SELECT "tag1", "value1" FROM "cpu" + -> Materialize + Output: t2."time", t2.tag1, t2.value1 + -> Foreign Scan on public.t2 + Output: t2."time", t2.tag1, t2.value1 + InfluxDB query: SELECT "tag1", "value1" FROM "cpu" WHERE (("value1" = 123)) + -> Foreign Scan on public.t1 t1_1 + Output: t2.value1, t1_1.tag1 + InfluxDB query: SELECT "tag1" FROM "cpu" LIMIT 1 OFFSET 0 + -> Foreign Scan on public.t3 + Output: (t2.value1), t1_1.tag1 + InfluxDB query: SELECT * FROM "t3" LIMIT 1 OFFSET 20 +(21 rows) + +--Testcase 157: +DROP FOREIGN TABLE cpu; +--Testcase 158: +DROP FOREIGN TABLE t1; +--Testcase 159: +DROP FOREIGN TABLE t2; +--Testcase 160: +DROP FOREIGN TABLE t3; +--Testcase 161: +DROP FOREIGN TABLE t4; +--Testcase 162: +DROP FOREIGN TABLE t5; +--Testcase 163: +DROP FOREIGN TABLE tx; +-- test INSERT, DELETE +IMPORT FOREIGN SCHEMA public FROM SERVER server1 INTO public OPTIONS(import_time_text 'true'); +--Testcase 164: +SELECT * FROM cpu; + time | time_text | tag1 | tag2 | value1 | value2 | value3 | value4 +------------------------+----------------------+--------+--------+--------+--------+--------+-------- + 2015-08-18 09:00:00+09 | 2015-08-18T00:00:00Z | tag1_A | tag2_A | 100 | 0.5 | str | t + 2015-08-18 09:00:00+09 | 2015-08-18T00:00:00Z | tag1_B | | 100 | 2 | | f + 2015-08-18 09:48:08+09 | 2015-08-18T00:48:08Z | | tag2_A | | 2 | | +(3 rows) + +--Testcase 165: +EXPLAIN VERBOSE +INSERT INTO cpu(time, tag1, tag2, value1, value2, value3, value4) VALUES('2021-01-01 00:00:01+09', 'tag1_K', 'tag2_H', 200, 5.5, 'test1', true); + QUERY PLAN +----------------------------------------------------------------------------------------------------------------------------------------------------------------------------- + Insert on public.cpu (cost=0.00..0.01 rows=0 width=0) + Batch Size: 1 + -> Result (cost=0.00..0.01 rows=1 width=153) + Output: '2021-01-01 00:00:01+09'::timestamp with time zone, NULL::text, 'tag1_K'::text, 'tag2_H'::text, '200'::bigint, '5.5'::double precision, 'test1'::text, true +(4 rows) + +--Testcase 166: +INSERT INTO cpu(time, tag1, tag2, value1, value2, value3, value4) VALUES('2021-01-01 00:00:01+09', 'tag1_K', 'tag2_H', 200, 5.5, 'test', true); +--Testcase 167: +SELECT * FROM cpu; + time | time_text | tag1 | tag2 | value1 | value2 | value3 | value4 +------------------------+----------------------+--------+--------+--------+--------+--------+-------- + 2015-08-18 09:00:00+09 | 2015-08-18T00:00:00Z | tag1_A | tag2_A | 100 | 0.5 | str | t + 2015-08-18 09:00:00+09 | 2015-08-18T00:00:00Z | tag1_B | | 100 | 2 | | f + 2015-08-18 09:48:08+09 | 2015-08-18T00:48:08Z | | tag2_A | | 2 | | + 2021-01-01 00:00:01+09 | 2020-12-31T15:00:01Z | tag1_K | tag2_H | 200 | 5.5 | test | t +(4 rows) + +--Testcase 168: +EXPLAIN VERBOSE +INSERT INTO cpu(time, tag1, tag2, value1, value2, value3, value4) VALUES('2021-01-02 00:00:02+05', 'tag1_I', 'tag2_E', 300, 15.5, 'test2', false), + ('2029-02-02 00:02:02+04', 'tag1_U', 'tag2_DZ', (SELECT 350), (SELECT i FROM (VALUES(6.9)) AS foo (i)), 'funny', true); + QUERY PLAN +------------------------------------------------------------------------------------------------------------------------------------------------------------------------ + Insert on public.cpu (cost=0.02..0.04 rows=0 width=0) + Batch Size: 1 + InitPlan 1 (returns $0) + -> Result (cost=0.00..0.01 rows=1 width=4) + Output: 350 + InitPlan 2 (returns $1) + -> Result (cost=0.00..0.01 rows=1 width=32) + Output: 6.9 + -> Values Scan on "*VALUES*" (cost=0.00..0.03 rows=2 width=153) + Output: "*VALUES*".column1, NULL::text, "*VALUES*".column2, "*VALUES*".column3, "*VALUES*".column4, "*VALUES*".column5, "*VALUES*".column6, "*VALUES*".column7 +(10 rows) + +--Testcase 169: +INSERT INTO cpu(time, tag1, tag2, value1, value2, value3, value4) VALUES('2021-01-02 00:00:02+05', 'tag1_I', 'tag2_E', 300, 15.5, 'test2', false), + ('2029-02-02 00:02:02+04', 'tag1_U', 'tag2_DZ', (SELECT 350), (SELECT i FROM (VALUES(6.9)) AS foo (i)), 'funny', true); +--Testcase 170: +SELECT * FROM cpu; + time | time_text | tag1 | tag2 | value1 | value2 | value3 | value4 +------------------------+----------------------+--------+---------+--------+--------+--------+-------- + 2015-08-18 09:00:00+09 | 2015-08-18T00:00:00Z | tag1_A | tag2_A | 100 | 0.5 | str | t + 2015-08-18 09:00:00+09 | 2015-08-18T00:00:00Z | tag1_B | | 100 | 2 | | f + 2015-08-18 09:48:08+09 | 2015-08-18T00:48:08Z | | tag2_A | | 2 | | + 2021-01-01 00:00:01+09 | 2020-12-31T15:00:01Z | tag1_K | tag2_H | 200 | 5.5 | test | t + 2021-01-02 04:00:02+09 | 2021-01-01T19:00:02Z | tag1_I | tag2_E | 300 | 15.5 | test2 | f + 2029-02-02 05:02:02+09 | 2029-02-01T20:02:02Z | tag1_U | tag2_DZ | 350 | 6.9 | funny | t +(6 rows) + +--Testcase 171: +INSERT INTO cpu(tag2, value1) VALUES('tag2_KH', 400); +--Testcase 172: +SELECT tag1, tag2, value1, value2, value3, value4 FROM cpu; + tag1 | tag2 | value1 | value2 | value3 | value4 +--------+---------+--------+--------+--------+-------- + tag1_A | tag2_A | 100 | 0.5 | str | t + tag1_B | | 100 | 2 | | f + | tag2_A | | 2 | | + tag1_K | tag2_H | 200 | 5.5 | test | t + tag1_I | tag2_E | 300 | 15.5 | test2 | f + | tag2_KH | 400 | | | + tag1_U | tag2_DZ | 350 | 6.9 | funny | t +(7 rows) + +--Testcase 173: +EXPLAIN VERBOSE +DELETE FROM cpu WHERE tag2 = 'tag2_KH'; + QUERY PLAN +------------------------------------------------------------------------- + Delete on public.cpu (cost=10.00..3.00 rows=0 width=0) + -> Foreign Delete on public.cpu (cost=10.00..3.00 rows=3 width=104) + InfluxDB query: DELETE FROM "cpu" WHERE (("tag2" = 'tag2_KH')) +(3 rows) + +--Testcase 174: +DELETE FROM cpu WHERE tag2 = 'tag2_KH'; +--Testcase 175: +SELECT tag1, tag2, value1, value2, value3, value4 FROM cpu; + tag1 | tag2 | value1 | value2 | value3 | value4 +--------+---------+--------+--------+--------+-------- + tag1_A | tag2_A | 100 | 0.5 | str | t + tag1_B | | 100 | 2 | | f + | tag2_A | | 2 | | + tag1_K | tag2_H | 200 | 5.5 | test | t + tag1_I | tag2_E | 300 | 15.5 | test2 | f + tag1_U | tag2_DZ | 350 | 6.9 | funny | t +(6 rows) + +--Testcase 176: +EXPLAIN VERBOSE +DELETE FROM cpu WHERE time = '2021-01-02 04:00:02+09'; + QUERY PLAN +---------------------------------------------------------------------------------- + Delete on public.cpu (cost=10.00..3.00 rows=0 width=0) + -> Foreign Delete on public.cpu (cost=10.00..3.00 rows=3 width=104) + InfluxDB query: DELETE FROM "cpu" WHERE ((time = '2021-01-01 19:00:02')) +(3 rows) + +--Testcase 177: +DELETE FROM cpu WHERE time = '2021-01-02 04:00:02+09'; +--Testcase 178: +SELECT * FROM cpu; + time | time_text | tag1 | tag2 | value1 | value2 | value3 | value4 +------------------------+----------------------+--------+---------+--------+--------+--------+-------- + 2015-08-18 09:00:00+09 | 2015-08-18T00:00:00Z | tag1_A | tag2_A | 100 | 0.5 | str | t + 2015-08-18 09:00:00+09 | 2015-08-18T00:00:00Z | tag1_B | | 100 | 2 | | f + 2015-08-18 09:48:08+09 | 2015-08-18T00:48:08Z | | tag2_A | | 2 | | + 2021-01-01 00:00:01+09 | 2020-12-31T15:00:01Z | tag1_K | tag2_H | 200 | 5.5 | test | t + 2029-02-02 05:02:02+09 | 2029-02-01T20:02:02Z | tag1_U | tag2_DZ | 350 | 6.9 | funny | t +(5 rows) + +--Testcase 179: +EXPLAIN VERBOSE +DELETE FROM cpu WHERE time < '2018-07-07' AND tag1 != 'tag1_B'; + QUERY PLAN +------------------------------------------------------------------------------------------------------------- + Delete on public.cpu (cost=10.00..212.00 rows=0 width=0) + -> Foreign Delete on public.cpu (cost=10.00..212.00 rows=212 width=104) + InfluxDB query: DELETE FROM "cpu" WHERE ((time < '2018-07-06 15:00:00')) AND (("tag1" <> 'tag1_B')) +(3 rows) + +--Testcase 180: +DELETE FROM cpu WHERE time < '2018-07-07' AND tag1 != 'tag1_B'; +--Testcase 181: +SELECT * FROM cpu; + time | time_text | tag1 | tag2 | value1 | value2 | value3 | value4 +------------------------+----------------------+--------+---------+--------+--------+--------+-------- + 2015-08-18 09:00:00+09 | 2015-08-18T00:00:00Z | tag1_B | | 100 | 2 | | f + 2021-01-01 00:00:01+09 | 2020-12-31T15:00:01Z | tag1_K | tag2_H | 200 | 5.5 | test | t + 2029-02-02 05:02:02+09 | 2029-02-01T20:02:02Z | tag1_U | tag2_DZ | 350 | 6.9 | funny | t +(3 rows) + +-- Test INSERT, DELETE with time_text column +--Testcase 182: +INSERT INTO cpu(time_text, tag1, tag2, value1, value2, value3, value4) VALUES('2021-02-02T00:00:00Z', 'tag1_D', 'tag2_E', 600, 20.2, 'test3', true); +--Testcase 183: +SELECT * FROM cpu; + time | time_text | tag1 | tag2 | value1 | value2 | value3 | value4 +------------------------+----------------------+--------+---------+--------+--------+--------+-------- + 2015-08-18 09:00:00+09 | 2015-08-18T00:00:00Z | tag1_B | | 100 | 2 | | f + 2021-01-01 00:00:01+09 | 2020-12-31T15:00:01Z | tag1_K | tag2_H | 200 | 5.5 | test | t + 2021-02-02 09:00:00+09 | 2021-02-02T00:00:00Z | tag1_D | tag2_E | 600 | 20.2 | test3 | t + 2029-02-02 05:02:02+09 | 2029-02-01T20:02:02Z | tag1_U | tag2_DZ | 350 | 6.9 | funny | t +(4 rows) + +--Testcase 184: +INSERT INTO cpu(time_text, tag1, value2) VALUES('2021-02-02T00:00:00.123456789Z', 'tag1_P', 25.8); +--Testcase 185: +SELECT * FROM cpu; + time | time_text | tag1 | tag2 | value1 | value2 | value3 | value4 +-------------------------------+--------------------------------+--------+---------+--------+--------+--------+-------- + 2015-08-18 09:00:00+09 | 2015-08-18T00:00:00Z | tag1_B | | 100 | 2 | | f + 2021-01-01 00:00:01+09 | 2020-12-31T15:00:01Z | tag1_K | tag2_H | 200 | 5.5 | test | t + 2021-02-02 09:00:00+09 | 2021-02-02T00:00:00Z | tag1_D | tag2_E | 600 | 20.2 | test3 | t + 2021-02-02 09:00:00.123457+09 | 2021-02-02T00:00:00.123456789Z | tag1_P | | | 25.8 | | + 2029-02-02 05:02:02+09 | 2029-02-01T20:02:02Z | tag1_U | tag2_DZ | 350 | 6.9 | funny | t +(5 rows) + +--Testcase 186: +INSERT INTO cpu(time_text, tag1, value2) VALUES('2021-02-02 00:00:01', 'tag1_J', 37.1); +--Testcase 187: +SELECT * FROM cpu; + time | time_text | tag1 | tag2 | value1 | value2 | value3 | value4 +-------------------------------+--------------------------------+--------+---------+--------+--------+--------+-------- + 2015-08-18 09:00:00+09 | 2015-08-18T00:00:00Z | tag1_B | | 100 | 2 | | f + 2021-01-01 00:00:01+09 | 2020-12-31T15:00:01Z | tag1_K | tag2_H | 200 | 5.5 | test | t + 2021-02-02 09:00:00+09 | 2021-02-02T00:00:00Z | tag1_D | tag2_E | 600 | 20.2 | test3 | t + 2021-02-02 09:00:00.123457+09 | 2021-02-02T00:00:00.123456789Z | tag1_P | | | 25.8 | | + 2021-02-02 09:00:01+09 | 2021-02-02T00:00:01Z | tag1_J | | | 37.1 | | + 2029-02-02 05:02:02+09 | 2029-02-01T20:02:02Z | tag1_U | tag2_DZ | 350 | 6.9 | funny | t +(6 rows) + +--Testcase 188: +INSERT INTO cpu(time, time_text, tag1, tag2, value1, value2, value3, value4) VALUES('2021-02-02 00:00:01+05', '2021-02-02T00:00:02.123456789Z', 'tag1_A', 'tag2_B', 200, 5.5, 'test', true); +WARNING: Inserting value has both 'time_text' and 'time' columns specified. The 'time' will be ignored. +--Testcase 189: +SELECT * FROM cpu; + time | time_text | tag1 | tag2 | value1 | value2 | value3 | value4 +-------------------------------+--------------------------------+--------+---------+--------+--------+--------+-------- + 2015-08-18 09:00:00+09 | 2015-08-18T00:00:00Z | tag1_B | | 100 | 2 | | f + 2021-01-01 00:00:01+09 | 2020-12-31T15:00:01Z | tag1_K | tag2_H | 200 | 5.5 | test | t + 2021-02-02 09:00:00+09 | 2021-02-02T00:00:00Z | tag1_D | tag2_E | 600 | 20.2 | test3 | t + 2021-02-02 09:00:00.123457+09 | 2021-02-02T00:00:00.123456789Z | tag1_P | | | 25.8 | | + 2021-02-02 09:00:01+09 | 2021-02-02T00:00:01Z | tag1_J | | | 37.1 | | + 2021-02-02 09:00:02.123457+09 | 2021-02-02T00:00:02.123456789Z | tag1_A | tag2_B | 200 | 5.5 | test | t + 2029-02-02 05:02:02+09 | 2029-02-01T20:02:02Z | tag1_U | tag2_DZ | 350 | 6.9 | funny | t +(7 rows) + +--Testcase 190: +INSERT INTO cpu(time_text, time, tag1, tag2, value1, value2, value3, value4) VALUES('2021-02-03T00:00:03.123456789Z', '2021-03-03 00:00:01+07', 'tag1_C', 'tag2_D', 200, 5.5, 'test', true); +WARNING: Inserting value has both 'time_text' and 'time' columns specified. The 'time' will be ignored. +--Testcase 191: +SELECT * FROM cpu; + time | time_text | tag1 | tag2 | value1 | value2 | value3 | value4 +-------------------------------+--------------------------------+--------+---------+--------+--------+--------+-------- + 2015-08-18 09:00:00+09 | 2015-08-18T00:00:00Z | tag1_B | | 100 | 2 | | f + 2021-01-01 00:00:01+09 | 2020-12-31T15:00:01Z | tag1_K | tag2_H | 200 | 5.5 | test | t + 2021-02-02 09:00:00+09 | 2021-02-02T00:00:00Z | tag1_D | tag2_E | 600 | 20.2 | test3 | t + 2021-02-02 09:00:00.123457+09 | 2021-02-02T00:00:00.123456789Z | tag1_P | | | 25.8 | | + 2021-02-02 09:00:01+09 | 2021-02-02T00:00:01Z | tag1_J | | | 37.1 | | + 2021-02-02 09:00:02.123457+09 | 2021-02-02T00:00:02.123456789Z | tag1_A | tag2_B | 200 | 5.5 | test | t + 2021-02-03 09:00:03.123457+09 | 2021-02-03T00:00:03.123456789Z | tag1_C | tag2_D | 200 | 5.5 | test | t + 2029-02-02 05:02:02+09 | 2029-02-01T20:02:02Z | tag1_U | tag2_DZ | 350 | 6.9 | funny | t +(8 rows) + +--Testcase 192: +EXPLAIN VERBOSE +DELETE FROM cpu WHERE time_text = '2021-02-02T00:00:00.123456789Z'; + QUERY PLAN +--------------------------------------------------------------------------------------------- + Delete on public.cpu (cost=10.00..3.00 rows=0 width=0) + -> Foreign Delete on public.cpu (cost=10.00..3.00 rows=3 width=104) + InfluxDB query: DELETE FROM "cpu" WHERE ((time = '2021-02-02T00:00:00.123456789Z')) +(3 rows) + +--Testcase 193: +DELETE FROM cpu WHERE time_text = '2021-02-02T00:00:00.123456789Z'; +--Testcase 194: +SELECT * FROM cpu; + time | time_text | tag1 | tag2 | value1 | value2 | value3 | value4 +-------------------------------+--------------------------------+--------+---------+--------+--------+--------+-------- + 2015-08-18 09:00:00+09 | 2015-08-18T00:00:00Z | tag1_B | | 100 | 2 | | f + 2021-01-01 00:00:01+09 | 2020-12-31T15:00:01Z | tag1_K | tag2_H | 200 | 5.5 | test | t + 2021-02-02 09:00:00+09 | 2021-02-02T00:00:00Z | tag1_D | tag2_E | 600 | 20.2 | test3 | t + 2021-02-02 09:00:01+09 | 2021-02-02T00:00:01Z | tag1_J | | | 37.1 | | + 2021-02-02 09:00:02.123457+09 | 2021-02-02T00:00:02.123456789Z | tag1_A | tag2_B | 200 | 5.5 | test | t + 2021-02-03 09:00:03.123457+09 | 2021-02-03T00:00:03.123456789Z | tag1_C | tag2_D | 200 | 5.5 | test | t + 2029-02-02 05:02:02+09 | 2029-02-01T20:02:02Z | tag1_U | tag2_DZ | 350 | 6.9 | funny | t +(7 rows) + +--Testcase 195: +EXPLAIN VERBOSE +DELETE FROM cpu WHERE time_text = '2021-02-02T00:00:01Z' AND tag1 = 'tag1_J'; + QUERY PLAN +------------------------------------------------------------------------------------------------------------- + Delete on public.cpu (cost=10.00..1.00 rows=0 width=0) + -> Foreign Delete on public.cpu (cost=10.00..1.00 rows=1 width=104) + InfluxDB query: DELETE FROM "cpu" WHERE ((time = '2021-02-02T00:00:01Z')) AND (("tag1" = 'tag1_J')) +(3 rows) + +--Testcase 196: +DELETE FROM cpu WHERE time_text = '2021-02-02T00:00:01Z' AND tag1 = 'tag1_J'; +--Testcase 197: +SELECT * FROM cpu; + time | time_text | tag1 | tag2 | value1 | value2 | value3 | value4 +-------------------------------+--------------------------------+--------+---------+--------+--------+--------+-------- + 2015-08-18 09:00:00+09 | 2015-08-18T00:00:00Z | tag1_B | | 100 | 2 | | f + 2021-01-01 00:00:01+09 | 2020-12-31T15:00:01Z | tag1_K | tag2_H | 200 | 5.5 | test | t + 2021-02-02 09:00:00+09 | 2021-02-02T00:00:00Z | tag1_D | tag2_E | 600 | 20.2 | test3 | t + 2021-02-02 09:00:02.123457+09 | 2021-02-02T00:00:02.123456789Z | tag1_A | tag2_B | 200 | 5.5 | test | t + 2021-02-03 09:00:03.123457+09 | 2021-02-03T00:00:03.123456789Z | tag1_C | tag2_D | 200 | 5.5 | test | t + 2029-02-02 05:02:02+09 | 2029-02-01T20:02:02Z | tag1_U | tag2_DZ | 350 | 6.9 | funny | t +(6 rows) + +--Testcase 198: +EXPLAIN VERBOSE +DELETE FROM cpu WHERE time_text = '2021-02-02 00:00:00' OR time ='2029-02-02 05:02:02+09'; + QUERY PLAN +-------------------------------------------------------------------------------------------------------------------------------------- + Delete on public.cpu (cost=10.00..6.00 rows=0 width=0) + -> Foreign Scan on public.cpu (cost=10.00..6.00 rows=6 width=104) + Output: "time", time_text, tag1, tag2 + Filter: ((cpu.time_text = '2021-02-02 00:00:00'::text) OR (cpu."time" = '2029-02-02 05:02:02+09'::timestamp with time zone)) + InfluxDB query: SELECT "tag1", "tag2", "value1" FROM "cpu" +(5 rows) + +--Testcase 199: +DELETE FROM cpu WHERE time_text = '2021-02-02 00:00:00' OR time ='2029-02-02 05:02:02+09'; +--Testcase 200: +SELECT * FROM cpu; + time | time_text | tag1 | tag2 | value1 | value2 | value3 | value4 +-------------------------------+--------------------------------+--------+--------+--------+--------+--------+-------- + 2015-08-18 09:00:00+09 | 2015-08-18T00:00:00Z | tag1_B | | 100 | 2 | | f + 2021-01-01 00:00:01+09 | 2020-12-31T15:00:01Z | tag1_K | tag2_H | 200 | 5.5 | test | t + 2021-02-02 09:00:00+09 | 2021-02-02T00:00:00Z | tag1_D | tag2_E | 600 | 20.2 | test3 | t + 2021-02-02 09:00:02.123457+09 | 2021-02-02T00:00:02.123456789Z | tag1_A | tag2_B | 200 | 5.5 | test | t + 2021-02-03 09:00:03.123457+09 | 2021-02-03T00:00:03.123456789Z | tag1_C | tag2_D | 200 | 5.5 | test | t +(5 rows) + +-- InfluxDB_FDW will store time data for Field values as a strings +--Testcase 204: +CREATE FOREIGN TABLE tmp_time ( +time timestamp, +c1 time, +c2 timestamp, +c3 timestamp with time zone +) SERVER server1 OPTIONS (table 'tmp_time'); +--Testcase 205: +SELECT * FROM tmp_time; + time | c1 | c2 | c3 +------+----+----+---- +(0 rows) + +--Testcase 206: +INSERT INTO tmp_time (time, c1) VALUES ('1900-01-01 01:01:01', '01:02:03'); +--Testcase 207: +INSERT INTO tmp_time (time, c1) VALUES ('2100-01-01 01:01:01', '04:05:06'); +--Testcase 208: +INSERT INTO tmp_time (time, c1) VALUES ('1990-01-01 01:01:01', '07:08:09'); +--Testcase 209: +INSERT INTO tmp_time (time, c2) VALUES ('2020-12-27 03:02:56.634467', '1950-02-02 02:02:02'); +--Testcase 210: +INSERT INTO tmp_time (time, c3) VALUES ('2021-12-27 03:02:56.668301', '1800-02-02 02:02:02+9'); +--Testcase 210: +INSERT INTO tmp_time (time, c1, c2, c3) VALUES ('2022-05-06 07:08:09', '07:08:09', '2022-05-06 07:08:09', '2022-05-06 07:08:09+9'); +--Testcase 211: +-- 1800-02-02 02:02:02+9 is Daylight Saving Time (DST) changes in Japan. +-- Timezone setting Japan so it will plus 18s:59 +-- https://www.timeanddate.com/time/zone/japan/tokyo?syear=1850 +SELECT * FROM tmp_time; + time | c1 | c2 | c3 +----------------------------+----------+---------------------+------------------------------ + 1900-01-01 01:01:01 | 01:02:03 | | + 1990-01-01 01:01:01 | 07:08:09 | | + 2020-12-27 03:02:56.634467 | | 1950-02-02 02:02:02 | + 2021-12-27 03:02:56.668301 | | | 1800-02-02 02:21:01+09:18:59 + 2022-05-06 07:08:09 | 07:08:09 | 2022-05-06 07:08:09 | 2022-05-06 07:08:09+09 + 2100-01-01 01:01:01 | 04:05:06 | | +(6 rows) + +-- Type mis-match +--Testcase 212: +CREATE FOREIGN TABLE datatype_test ( + time timestamp with time zone, + tag1 text, + tag2 text, + value1 int, + value2 text +) SERVER server1 OPTIONS (table 'datatype_test', tags 'tag1,tag2'); +--Testcase 213: +INSERT INTO datatype_test (tag1, tag2, value1, value2) VALUES ('time', '2021-02-02T00:00:01Z', '1', '2021-02-05T00:00:00Z'); +--Testcase 214: +INSERT INTO datatype_test (tag1, tag2, value1, value2) VALUES ('time', '2022-02-02T00:00:01Z', '2', '2022-02-05T00:00:00Z'); +--Testcase 215: +SELECT tag1, tag2, value1, value2 FROM datatype_test; + tag1 | tag2 | value1 | value2 +------+----------------------+--------+---------------------- + time | 2021-02-02T00:00:01Z | 1 | 2021-02-05T00:00:00Z + time | 2022-02-02T00:00:01Z | 2 | 2022-02-05T00:00:00Z +(2 rows) + +-- Using text as timestamp +--Testcase 216: +ALTER FOREIGN TABLE datatype_test ALTER COLUMN tag2 TYPE timestamptz; +--Testcase 217: +ALTER FOREIGN TABLE datatype_test ALTER COLUMN value2 TYPE timestamptz; +-- SELECT OK without filter +--Testcase 218: +SELECT tag1, tag2, value1, value2 FROM datatype_test; + tag1 | tag2 | value1 | value2 +------+------------------------+--------+------------------------ + time | 2021-02-02 09:00:01+09 | 1 | 2021-02-05 09:00:00+09 + time | 2022-02-02 09:00:01+09 | 2 | 2022-02-05 09:00:00+09 +(2 rows) + +-- SELECT with timestamp filter, WHERE clause is pushed down +-- InfluxDB cannot compare correctly, 0 row returned +--Testcase 219: +EXPLAIN (VERBOSE, COSTS OFF) +SELECT tag1, tag2, value1, value2 FROM datatype_test WHERE tag2 > '2021-02-02 00:00:01+00'; + QUERY PLAN +--------------------------------------------------------------------------------------------------------------------------- + Foreign Scan on public.datatype_test + Output: tag1, tag2, value1, value2 + InfluxDB query: SELECT "tag1", "tag2", "value1", "value2" FROM "datatype_test" WHERE (("tag2" > '2021-02-02 00:00:01')) +(3 rows) + +--Testcase 220: +SELECT tag1, tag2, value1, value2 FROM datatype_test WHERE tag2 > '2021-02-02 00:00:01+00'; + tag1 | tag2 | value1 | value2 +------+------+--------+-------- +(0 rows) + +--Testcase 221: +EXPLAIN (VERBOSE, COSTS OFF) +SELECT tag1, tag2, value1, value2 FROM datatype_test WHERE value2 > '2021-02-05 00:00:00+00'; + QUERY PLAN +----------------------------------------------------------------------------------------------------------------------------- + Foreign Scan on public.datatype_test + Output: tag1, tag2, value1, value2 + InfluxDB query: SELECT "tag1", "tag2", "value1", "value2" FROM "datatype_test" WHERE (("value2" > '2021-02-05 00:00:00')) +(3 rows) + +--Testcase 222: +SELECT tag1, tag2, value1, value2 FROM datatype_test WHERE value2 > '2021-02-05 00:00:00+00'; + tag1 | tag2 | value1 | value2 +------+------+--------+-------- +(0 rows) + +--Testcase 223: +ALTER FOREIGN TABLE datatype_test ALTER COLUMN tag2 TYPE text; +--Testcase 224: +ALTER FOREIGN TABLE datatype_test ALTER COLUMN value2 TYPE text; +-- uses explicit cast, WHERE clause is not pushed down +-- compared correctly by postgres, 1 row returned +--Testcase 225: +EXPLAIN (VERBOSE, COSTS OFF) +SELECT tag1, tag2, value1, value2 FROM datatype_test WHERE tag2::timestamptz > '2021-02-02 00:00:01+00'; + QUERY PLAN +----------------------------------------------------------------------------------------------------------------- + Foreign Scan on public.datatype_test + Output: tag1, tag2, value1, value2 + Filter: ((datatype_test.tag2)::timestamp with time zone > '2021-02-02 09:00:01+09'::timestamp with time zone) + InfluxDB query: SELECT "tag1", "tag2", "value1", "value2" FROM "datatype_test" +(4 rows) + +--Testcase 226: +SELECT tag1, tag2, value1, value2 FROM datatype_test WHERE tag2::timestamptz > '2021-02-02 00:00:01+00'; + tag1 | tag2 | value1 | value2 +------+----------------------+--------+---------------------- + time | 2022-02-02T00:00:01Z | 2 | 2022-02-05T00:00:00Z +(1 row) + +--Testcase 227: +EXPLAIN (VERBOSE, COSTS OFF) +SELECT tag1, tag2, value1, value2 FROM datatype_test WHERE value2::timestamptz > '2021-02-05 00:00:00+00'; + QUERY PLAN +------------------------------------------------------------------------------------------------------------------- + Foreign Scan on public.datatype_test + Output: tag1, tag2, value1, value2 + Filter: ((datatype_test.value2)::timestamp with time zone > '2021-02-05 09:00:00+09'::timestamp with time zone) + InfluxDB query: SELECT "tag1", "tag2", "value1", "value2" FROM "datatype_test" +(4 rows) + +--Testcase 228: +SELECT tag1, tag2, value1, value2 FROM datatype_test WHERE value2::timestamptz > '2021-02-05 00:00:00+00'; + tag1 | tag2 | value1 | value2 +------+----------------------+--------+---------------------- + time | 2022-02-02T00:00:01Z | 2 | 2022-02-05T00:00:00Z +(1 row) + +-- clean-up +--Testcase 229: +DELETE FROM datatype_test; +--Testcase 230: +DROP FOREIGN TABLE datatype_test; +-- Recover data +:RECOVER_INIT_TXT_DROP_BUCKET; +:RECOVER_INIT_TXT_CREATE_BUCKET; +:RECOVER_INIT_TXT; +--Testcase 201: +DROP USER MAPPING FOR CURRENT_USER SERVER server1; +--Testcase 202: +DROP SERVER server1 CASCADE; +NOTICE: drop cascades to 6 other objects +DETAIL: drop cascades to foreign table cpu +drop cascades to foreign table numbers +drop cascades to foreign table t3 +drop cascades to foreign table t4 +drop cascades to foreign table tx +drop cascades to foreign table tmp_time +--Testcase 203: +DROP EXTENSION influxdb_fdw CASCADE; diff --git a/expected/15.0/option.out b/expected/16.0/option.out similarity index 100% rename from expected/15.0/option.out rename to expected/16.0/option.out diff --git a/expected/11.17/schemaless/add_fields.out b/expected/16.0/schemaless/add_fields.out similarity index 91% rename from expected/11.17/schemaless/add_fields.out rename to expected/16.0/schemaless/add_fields.out index e0edb34..1716680 100644 --- a/expected/11.17/schemaless/add_fields.out +++ b/expected/16.0/schemaless/add_fields.out @@ -47,7 +47,7 @@ SELECT max(time), max((fields->>'sig1')::bigint), max((fields->>'sig1')::bigint) (9 rows) --Testcase 8: -SELECT tags->>'device_id' device_id,(fields->>'sig1')::bigint sig1,fields->>'sig2' sig2, (fields->>'sig3')::float8 sig3, (fields->>'sig4')::boolean sig4 from sctbl1 ORDER BY tags->>'device_id'; +SELECT (tags->>'device_id' COLLATE "en_US") device_id,(fields->>'sig1')::bigint sig1,fields->>'sig2' sig2, (fields->>'sig3')::float8 sig3, (fields->>'sig4')::boolean sig4 from sctbl1 ORDER BY (tags->>'device_id' COLLATE "en_US"); device_id | sig1 | sig2 | sig3 | sig4 -----------+-------+----------------------------------------+----------------+------ dev1 | -664 | | 0.78 | t @@ -78,16 +78,16 @@ SELECT bool_or((fields->>'sig1')::bigint <> 10) AND true, bool_and(fields->>'sig --Testcase 10: SELECT sqrt(abs((fields->>'sig1')::float8)), sqrt(abs((fields->>'sig3')::float8)) FROM ( SELECT * FROM sctbl1 WHERE (fields->>'sig1')::bigint > -1000 AND (fields->>'sig3')::float8 < 1000 ) AS sctbl1 ORDER BY 1 ASC,2 DESC; - sqrt | sqrt -------------------+------------------- - 3.3166247903554 | 0.893136683190205 - 17.8605710994918 | 0.565685424949238 - 25.7681974534503 | 0.883176086632785 - 47.1380949975707 | 1 - 185.531668455819 | 0.565685424949238 - 188.825316099299 | 0.5 - 255.998046867549 | 0.953939201416946 - 264.990565869806 | 0.608276253029822 + sqrt | sqrt +--------------------+-------------------- + 3.3166247903554 | 0.8931366831902047 + 17.86057109949175 | 0.565685424949238 + 25.768197453450252 | 0.8831760866327847 + 47.138094997570704 | 1 + 185.53166845581916 | 0.565685424949238 + 188.8253160992985 | 0.5 + 255.99804686754936 | 0.9539392014169457 + 264.990565869806 | 0.6082762530298219 (8 rows) --Testcase 11: @@ -97,7 +97,7 @@ LINE 1: SELECT fields->>'sig2' sig2, mode((fields->>'sig3')::float8)... ^ HINT: No function matches the given name and argument types. You might need to add explicit type casts. --Testcase 12: -SELECT upper(fields->>'sig2'), upper(fields->>'sig2'), lower(fields->>'sig2'), lower(fields->>'sig2') FROM sctbl1 ORDER BY 1 ASC,2 DESC,3 ASC,4; +SELECT upper(fields->>'sig2' COLLATE "en_US"), upper(fields->>'sig2'), lower(fields->>'sig2'), lower(fields->>'sig2') FROM sctbl1 ORDER BY 1 ASC,2 DESC,3 ASC,4; upper | upper | lower | lower ----------------------------------------+----------------------------------------+----------------------------------------+---------------------------------------- `~!@#$%^&*()_+= | `~!@#$%^&*()_+= | `~!@#$%^&*()_+= | `~!@#$%^&*()_+= @@ -134,7 +134,7 @@ SELECT * FROM sctbl1; --Select fields,tags --Testcase 16: -SELECT tags->>'device_id' device_id,(fields->>'sig1')::bigint sig1,(fields->>'sig3')::float8 sig3 FROM sctbl1 WHERE NOT (fields->>'sig1')::bigint < (fields->>'sig3')::float8 ORDER BY 1 DESC,2 ASC,3 DESC LIMIT 5 OFFSET 0; +SELECT (tags->>'device_id' COLLATE "en_US") device_id,(fields->>'sig1')::bigint sig1,(fields->>'sig3')::float8 sig3 FROM sctbl1 WHERE NOT (fields->>'sig1')::bigint < (fields->>'sig3')::float8 ORDER BY 1 DESC,2 ASC,3 DESC LIMIT 5 OFFSET 0; device_id | sig1 | sig3 -----------+-------+------- 'dev3' | 34422 | 0.32 @@ -145,7 +145,7 @@ SELECT tags->>'device_id' device_id,(fields->>'sig1')::bigint sig1,(fields->>'si (5 rows) --Testcase 17: -SELECT tags->>'device_id' device_id,(fields->>'sig1')::bigint sig1,(fields->>'sig3')::float8 sig3 FROM sctbl1 WHERE (fields->>'sig3')::float8 < 0 ORDER BY 1 DESC,2 ASC,3 DESC LIMIT 5 OFFSET 0; +SELECT (tags->>'device_id' COLLATE "en_US") device_id,(fields->>'sig1')::bigint sig1,(fields->>'sig3')::float8 sig3 FROM sctbl1 WHERE (fields->>'sig3')::float8 < 0 ORDER BY 1 DESC,2 ASC,3 DESC LIMIT 5 OFFSET 0; device_id | sig1 | sig3 -----------+-------+---------------- dev3 | 65535 | -0.91 @@ -154,7 +154,7 @@ SELECT tags->>'device_id' device_id,(fields->>'sig1')::bigint sig1,(fields->>'si (3 rows) --Testcase 18: -SELECT tags->>'device_id' device_id,(fields->>'sig1')::bigint sig1,(fields->>'sig3')::float8 sig3 FROM sctbl1 WHERE NOT time >'2020-1-3 20:30:50' ORDER BY 1 DESC,2 ASC,3 DESC LIMIT 5 OFFSET 2; +SELECT (tags->>'device_id' COLLATE "en_US") device_id,(fields->>'sig1')::bigint sig1,(fields->>'sig3')::float8 sig3 FROM sctbl1 WHERE NOT time >'2020-1-3 20:30:50' ORDER BY 1 DESC,2 ASC,3 DESC LIMIT 5 OFFSET 2; device_id | sig1 | sig3 -----------+-------+------ d ,=ev2 | 2222 | -1 @@ -165,7 +165,7 @@ SELECT tags->>'device_id' device_id,(fields->>'sig1')::bigint sig1,(fields->>'si (5 rows) --Testcase 19: -SELECT time, tags->>'device_id' device_id,(fields->>'sig1')::bigint sig1,fields->>'sig2' sig2,(fields->>'sig3')::float8 sig3,(fields->>'sig4')::boolean sig4,(fields->>'sig5')::boolean sig5 FROM sctbl1 WHERE true ORDER BY 1 DESC,2 ASC,3 DESC,4,5 LIMIT 5 OFFSET 0; +SELECT time, (tags->>'device_id' COLLATE "en_US") device_id,(fields->>'sig1')::bigint sig1,fields->>'sig2' sig2,(fields->>'sig3')::float8 sig3,(fields->>'sig4')::boolean sig4,(fields->>'sig5')::boolean sig5 FROM sctbl1 WHERE true ORDER BY 1 DESC,2 ASC,3 DESC,4,5 LIMIT 5 OFFSET 0; time | device_id | sig1 | sig2 | sig3 | sig4 | sig5 -------------------------------+-----------+-------+----------------------------------------+----------------+------+------ 2262-04-11 23:47:16.854776+00 | 'dev3' | 34422 | 散りぬるを我が世誰 | 0.32 | f | t @@ -191,7 +191,7 @@ SELECT (fields->>'sig1')::bigint sig1,(fields->>'sig3')::float8 sig3, (fields->> (3 rows) --Testcase 22: -SELECT time, tags->>'device_id' device_id,(fields->>'sig1')::bigint sig1,fields->>'sig2' sig2,(fields->>'sig3')::float8 sig3,(fields->>'sig4')::boolean sig4,(fields->>'sig5')::boolean sig5 FROM sctbl1 WHERE fields->>'sig2' LIKE 'x%' ORDER BY 1 DESC,2 ASC,3 DESC,4,5 LIMIT 5 OFFSET 0; +SELECT time, (tags->>'device_id' COLLATE "en_US") device_id,(fields->>'sig1')::bigint sig1,fields->>'sig2' sig2,(fields->>'sig3')::float8 sig3,(fields->>'sig4')::boolean sig4,(fields->>'sig5')::boolean sig5 FROM sctbl1 WHERE fields->>'sig2' LIKE 'x%' ORDER BY 1 DESC,2 ASC,3 DESC,4,5 LIMIT 5 OFFSET 0; time | device_id | sig1 | sig2 | sig3 | sig4 | sig5 -----------------------------+-----------+-------+----------------------------+------+------+------ 2016-06-13 17:43:50.1004+00 | dev2 | 35655 | abcdefghijklmnopqrstuvwxyz | 0.25 | f | t @@ -199,7 +199,7 @@ SELECT time, tags->>'device_id' device_id,(fields->>'sig1')::bigint sig1,fields- (2 rows) --Testcase 23: -SELECT tags->>'device_id' device_id,(fields->>'sig1')::bigint sig1,fields->>'sig2' sig2,(fields->>'sig3')::float8 sig3,(fields->>'sig4')::boolean sig4 FROM sctbl1 WHERE NOT EXISTS (SELECT fields->>'sig2' FROM sctbl1 WHERE fields->>'sig2'='AHW') ORDER BY 1 DESC,2 ASC LIMIT 5 OFFSET 0; +SELECT (tags->>'device_id' COLLATE "en_US") device_id,(fields->>'sig1')::bigint sig1,fields->>'sig2' sig2,(fields->>'sig3')::float8 sig3,(fields->>'sig4')::boolean sig4 FROM sctbl1 WHERE NOT EXISTS (SELECT fields->>'sig2' FROM sctbl1 WHERE fields->>'sig2'='AHW') ORDER BY 1 DESC,2 ASC LIMIT 5 OFFSET 0; device_id | sig1 | sig2 | sig3 | sig4 -----------+-------+---------------------+-------+------ 'dev3' | 34422 | 散りぬるを我が世誰 | 0.32 | f @@ -270,25 +270,25 @@ SELECT (fields->>'sig1')::bigint sig1,(fields->>'sig3')::float8 sig3,(fields->>' (1 row) --Testcase 30: -SELECT (fields->>'sig1')::bigint sig1,(fields->>'sig3')::float8 sig3,(fields->>'sig5')::boolean sig5,(fields->>'sig1')::bigint/(fields->>'sig3')::float8 as dd FROM sctbl1 WHERE fields->>'sig2' IS NOT NULL ORDER BY fields->>'sig2' DESC,(fields->>'sig1')::bigint ASC LIMIT 5 OFFSET 0; - sig1 | sig3 | sig5 | dd --------+------+------+------------------- - 34422 | 0.32 | t | 107568.75 - 2222 | -1 | f | -2222 - 319 | 0.32 | t | 996.875 - -8555 | 0.34 | f | -25161.7647058823 - 35655 | 0.25 | t | 142620 +SELECT (fields->>'sig1')::bigint sig1,(fields->>'sig3')::float8 sig3,(fields->>'sig5')::boolean sig5,(fields->>'sig1')::bigint/(fields->>'sig3')::float8 as dd FROM sctbl1 WHERE (fields->>'sig2' COLLATE "en_US") IS NOT NULL ORDER BY (fields->>'sig2' COLLATE "en_US") DESC,(fields->>'sig1')::bigint ASC LIMIT 5 OFFSET 0; + sig1 | sig3 | sig5 | dd +-------+------+------+-------------------- + 34422 | 0.32 | t | 107568.75 + 2222 | -1 | f | -2222 + 319 | 0.32 | t | 996.875 + -8555 | 0.34 | f | -25161.76470588235 + 35655 | 0.25 | t | 142620 (5 rows) --Testcase 31: -SELECT (fields->>'sig1')::bigint sig1,(fields->>'sig3')::float8 sig3,(fields->>'sig5')::boolean sig5,(fields->>'sig1')::bigint*(fields->>'sig3')::float8 as mm FROM sctbl1 WHERE NOT (fields->>'sig1')::bigint=5 ORDER BY fields->>'sig2' DESC LIMIT 5 OFFSET 0; - sig1 | sig3 | sig5 | mm --------+------+------+---------- - -664 | 0.78 | f | -517.92 - 34422 | 0.32 | t | 11015.04 - 2222 | -1 | f | -2222 - 319 | 0.32 | t | 102.08 - -8555 | 0.34 | f | -2908.7 +SELECT (fields->>'sig1')::bigint sig1,(fields->>'sig3')::float8 sig3,(fields->>'sig5')::boolean sig5,(fields->>'sig1')::bigint*(fields->>'sig3')::float8 as mm FROM sctbl1 WHERE NOT (fields->>'sig1')::bigint=5 ORDER BY (fields->>'sig2' COLLATE "en_US") DESC LIMIT 5 OFFSET 0; + sig1 | sig3 | sig5 | mm +-------+------+------+--------------------- + -664 | 0.78 | f | -517.9200000000001 + 34422 | 0.32 | t | 11015.04 + 2222 | -1 | f | -2222 + 319 | 0.32 | t | 102.08 + -8555 | 0.34 | f | -2908.7000000000003 (5 rows) --Testcase 32: @@ -311,7 +311,7 @@ SELECT (fields->>'sig1')::bigint sig1, fields->>'sig2' sig2, (fields->>'sig3'):: (5 rows) --Testcase 34: -SELECT (fields->>'sig1')::bigint sig1,fields->>'sig2' sig2,(fields->>'sig3')::float8 sig3,(fields->>'sig4')::boolean sig4,(fields->>'sig5')::boolean sig5 FROM ( SELECT * FROM sctbl1 WHERE (fields->>'sig1')::bigint>-1000 AND (fields->>'sig3')::float8 < 1 ) AS tb1 WHERE (fields->>'sig3')::float8 < -0.1 AND fields->>'sig2' > 'Mee' ORDER BY 1 DESC,2 ASC,3 DESC,4,5 LIMIT 5 OFFSET 0; +SELECT (fields->>'sig1')::bigint sig1,fields->>'sig2' sig2,(fields->>'sig3')::float8 sig3,(fields->>'sig4')::boolean sig4,(fields->>'sig5')::boolean sig5 FROM ( SELECT * FROM sctbl1 WHERE (fields->>'sig1')::bigint>-1000 AND (fields->>'sig3')::float8 < 1 ) AS tb1 WHERE (fields->>'sig3')::float8 < -0.1 AND (fields->>'sig2' COLLATE "en_US") > 'Mee' ORDER BY 1 DESC,2 ASC,3 DESC,4,5 LIMIT 5 OFFSET 0; sig1 | sig2 | sig3 | sig4 | sig5 ------+---------------------+------+------+------ 2222 | x'a8a9aaabacadaeaf' | -1 | f | f @@ -364,7 +364,7 @@ SELECT (fields->>'sig1')::bigint sig1,fields->>'sig2' sig2,(fields->>'sig3')::fl (4 rows) --Testcase 40: -SELECT time, fields->>'sig2' sig2 FROM sctbl1 WHERE fields->>'sig2' <= 'A' AND (fields->>'sig3')::float8 <>-5 AND (fields->>'sig1')::bigint <> 100 ORDER BY 1 ASC,2 DESC LIMIT 5 OFFSET 1; +SELECT time, (fields->>'sig2' COLLATE "en_US") sig2 FROM sctbl1 WHERE (fields->>'sig2' COLLATE "en_US") <= 'A' AND (fields->>'sig3')::float8 <>-5 AND (fields->>'sig1')::bigint <> 100 ORDER BY 1 ASC,2 DESC LIMIT 5 OFFSET 1; time | sig2 ----------------------------+---------------------------------------- 2019-05-02 16:12:41.098+00 | 2e2eawekfrjq2o @@ -393,9 +393,9 @@ SELECT tags->>'device_id' device_id,abs((fields->>'sig1')::bigint), ceil((fields --Testcase 43: SELECT count(tags->>'device_id'),sum((fields->>'sig1')::bigint),sum((fields->>'sig1')::bigint+(fields->>'sig3')::float8),stddev((fields->>'sig3')::float8 order by (fields->>'sig3')::float8) from sctbl1 ORDER BY 1 DESC,2 ASC,3 DESC LIMIT 5 OFFSET 0; - count | sum | sum | stddev --------+--------+------------------+------------------- - 9 | 199165 | 199164.672306865 | 0.669018209414099 + count | sum | sum | stddev +-------+--------+--------------------+-------------------- + 9 | 199165 | 199164.67230686513 | 0.6690182094140991 (1 row) --Testcase 44: @@ -411,22 +411,25 @@ LINE 1: ...ds->>'sig5')::boolean != true ORDER BY 1 DESC, 2, 3 LIMIT 5 ... ^ --Testcase 46: SELECT (fields->>'sig3')::float8 sig3, acos((fields->>'sig3')::float8), atan((fields->>'sig3')::float8) FROM sctbl1 WHERE fields->>'sig2' IS NULL GROUP BY fields->>'sig3' HAVING min((fields->>'sig1')::bigint) < min((fields->>'sig3')::float8) ORDER BY 1 DESC, 2, 3 LIMIT 5 OFFSET 0; - sig3 | acos | atan -------+-------------------+------------------- - 0.78 | 0.676130509560661 | 0.662426293833151 + sig3 | acos | atan +------+--------------------+-------------------- + 0.78 | 0.6761305095606613 | 0.6624262938331512 (1 row) --Testcase 47: SELECT (fields->>'sig3')::float8 sig3, log((fields->>'sig3')::float8),cos((fields->>'sig3')::float8) FROM sctbl1 WHERE fields->>'sig2' IS NOT NULL AND (fields->>'sig3')::float8 > 0 GROUP BY fields->>'sig3' HAVING min((fields->>'sig3')::float8) < 100 AND max((fields->>'sig1')::bigint) < 1000 AND sum((fields->>'sig3')::float8) > -1000 AND avg((fields->>'sig3')::float8) > -1000 ORDER BY 1 DESC, 2, 3 LIMIT 5 OFFSET 0; - sig3 | log | cos -------+--------------------+------------------- - 0.34 | -0.468521082957745 | 0.942754665528346 + sig3 | log | cos +------+----------------------+-------------------- + 0.34 | -0.46852108295774486 | 0.9427546655283462 (1 row) --Testcase 48: SELECT (fields->>'sig1')::bigint sig1,(fields->>'sig3')::float8 sig3,ln((fields->>'sig1')::bigint), log10((fields->>'sig3')::float8) FROM sctbl1 WHERE NOT (fields->>'sig1')::bigint=5 GROUP BY fields->>'sig1', fields->>'sig3' HAVING min((fields->>'sig3')::float8) < 100 AND max((fields->>'sig1')::bigint) < 1000 AND (fields->>'sig1')::bigint > 0 AND (fields->>'sig3')::float8 > 0 ORDER BY 1 DESC, 2, 3 LIMIT 5 OFFSET 0; -ERROR: stub log10(float8) is called -CONTEXT: PL/pgSQL function log10(double precision) line 3 at RAISE + sig1 | sig3 | ln | log10 +------+------+-------------------+-------------------- + 319 | 0.32 | 5.765191102784844 | -0.494850021680094 +(1 row) + --Testcase 49: SELECT max(time), max((fields->>'sig1')::bigint + (fields->>'sig3')::float8), min((fields->>'sig1')::bigint + (fields->>'sig3')::float8) FROM ( SELECT * FROM sctbl1 WHERE (fields->>'sig3')::float8 > -1000 AND (fields->>'sig4')::boolean != true ) AS tb1 WHERE (fields->>'sig3')::float8 != -1 AND (fields->>'sig5')::boolean != true GROUP BY fields->>'sig1' ORDER BY 1 DESC, 2, 3 LIMIT 5 OFFSET 0; max | max | min @@ -444,12 +447,12 @@ SELECT every((fields->>'sig1')::bigint > 5),every((fields->>'sig3')::float8 != 5 --Testcase 51: SELECT (fields->>'sig3')::float8 sig3,exp((fields->>'sig3')::float8),exp((fields->>'sig3')::float8*2) FROM ( SELECT * FROM sctbl1 WHERE (fields->>'sig3')::float8 > -1000 AND (fields->>'sig5')::boolean = true ) AS tb1 WHERE true GROUP BY fields->>'sig3' ORDER BY 1 DESC, 2, 3 LIMIT 5 OFFSET 0; - sig3 | exp | exp -----------------+-------------------+------------------- - 0.32 | 1.37712776433596 | 1.89648087930495 - 0.25 | 1.28402541668774 | 1.64872127070013 - -0.79769313486 | 0.450366701941337 | 0.202830166217517 - -0.91 | 0.402524224033636 | 0.162025750933881 + sig3 | exp | exp +----------------+---------------------+--------------------- + 0.32 | 1.3771277643359572 | 1.8964808793049515 + 0.25 | 1.2840254166877414 | 1.6487212707001282 + -0.79769313486 | 0.45036670194133693 | 0.20283016621751704 + -0.91 | 0.40252422403363597 | 0.16202575093388075 (4 rows) --Testcase 52: @@ -475,14 +478,14 @@ SELECT floor((fields->>'sig1')::bigint*(fields->>'sig3')::float8), floor((fields (5 rows) --Testcase 54: -SELECT time, tags->>'device_id' device_id, pow((fields->>'sig1')::bigint,-2) FROM sctbl1 WHERE ((fields->>'sig3')::float8 - 1)/3 != 1 GROUP BY time, tags->>'device_id', fields->>'sig1' ORDER BY 1 ASC,2 DESC LIMIT 5 OFFSET 0; - time | device_id | pow --------------------------------+-----------+---------------------- - 1677-09-21 00:12:43.145224+00 | dev1 | 2.26810857889389e-06 - 2016-06-13 17:43:50.1004+00 | dev3 | 2.32837749243861e-10 - 2016-06-13 17:43:50.1004+00 | d ,=ev2 | 2.0254050607581e-07 - 2016-06-13 17:43:50.1004+00 | dev2 | 7.86609375546018e-10 - 2019-05-02 16:12:41.098+00 | dev3 | 9.82694745531196e-06 +SELECT time, (tags->>'device_id' COLLATE "en_US") device_id, pow((fields->>'sig1')::bigint,-2) FROM sctbl1 WHERE ((fields->>'sig3')::float8 - 1)/3 != 1 GROUP BY time, (tags->>'device_id' COLLATE "en_US"), fields->>'sig1' ORDER BY 1 ASC,2 DESC LIMIT 5 OFFSET 0; + time | device_id | pow +-------------------------------+-----------+------------------------ + 1677-09-21 00:12:43.145224+00 | dev1 | 2.2681085788938886e-06 + 2016-06-13 17:43:50.1004+00 | dev3 | 2.3283774924386086e-10 + 2016-06-13 17:43:50.1004+00 | d ,=ev2 | 2.025405060758101e-07 + 2016-06-13 17:43:50.1004+00 | dev2 | 7.866093755460175e-10 + 2019-05-02 16:12:41.098+00 | dev3 | 9.826947455311957e-06 (5 rows) --Testcase 55: @@ -510,7 +513,7 @@ SELECT max((fields->>'sig3')::float8), count(*), exists(SELECT * FROM sctbl1 WHE --Join table, each table has 5 fields --Testcase 58: -SELECT * FROM sctbl1 s1 FULL JOIN sctbl2 s2 ON s1.tags->>'device_id'=s2.tags->>'device_id'; +SELECT * FROM sctbl1 s1 FULL JOIN sctbl2 s2 ON (s1.tags->>'device_id' COLLATE "en_US")=(s2.tags->>'device_id' COLLATE "en_US"); time | tags | fields | time | tags | fields -------------------------------+----------------------------+----------------------------------------------------------------------------------------------------------------------+-------------------------------+-----------------------+------------------------------------------------------------------------------------------------------------------------------------------------------------------- 1677-09-21 00:12:43.145224+00 | {"device_id": "dev1"} | {"sig1": "-664", "sig2": null, "sig3": "0.78", "sig4": "true", "sig5": "false"} | 2016-06-13 17:43:50.1004+00 | {"device_id": "dev1"} | {"sig1": "640", "sig2": "敷ヘカウ告政ヨハツヤ", "sig3": "20.4222211221", "sig4": "true", "sig5": "[(-122.107,37.664),(-122.107101,37.66425),(-122.1074,37.665)]"} @@ -593,7 +596,8 @@ SELECT * FROM (SELECT time, tags->>'device_id' device_id, (fields->>'sig1')::big --Testcase 62: SELECT s1.device_id,s1.sig1,s1.sig2,s1.sig3,s1.sig4,s1.sig5 FROM (SELECT time, tags->>'device_id' device_id, (fields->>'sig1')::bigint sig1, fields->>'sig2' sig2, (fields->>'sig3')::float8 sig3, (fields->>'sig4')::boolean sig4,(fields->>'sig5')::boolean sig5 FROM sctbl1) s1 NATURAL JOIN (SELECT time, tags->>'device_id' device_id, (fields->>'sig1')::bigint sig1, fields->>'sig2' sig2, (fields->>'sig3')::float8 sig3, (fields->>'sig4')::boolean sig4,fields->>'sig5' sig5 FROM sctbl2) s2; -ERROR: JOIN/USING types boolean and text cannot be matched +ERROR: operator does not exist: boolean = text +HINT: No operator matches the given name and argument types. You might need to add explicit type casts. --Testcase 63: SELECT s1.tags->>'device_id' device_id,(s1.fields->>'sig1')::bigint sig1,s1.fields->>'sig2' sig2,(s1.fields->>'sig3')::float8 sig3,(s1.fields->>'sig4')::boolean sig4,(s1.fields->>'sig5')::boolean sig5 FROM sctbl1 s1 JOIN sctbl2 s2 on true; device_id | sig1 | sig2 | sig3 | sig4 | sig5 @@ -707,7 +711,7 @@ SELECT sum('NaN'::numeric) FROM sctbl1; --Select fields,tags --Testcase 70: -SELECT tags->>'device_id' device_id,(fields->>'sig1')::bigint sig1,(fields->>'sig3')::float8 sig3,(fields->>'sig6')::bigint sig6 FROM sctbl1 WHERE NOT (fields->>'sig6')::bigint < (fields->>'sig1')::bigint ORDER BY 1 DESC,2 ASC,3 DESC LIMIT 15 OFFSET 0; +SELECT (tags->>'device_id' COLLATE "en_US") device_id,(fields->>'sig1')::bigint sig1,(fields->>'sig3')::float8 sig3,(fields->>'sig6')::bigint sig6 FROM sctbl1 WHERE NOT (fields->>'sig6')::bigint < (fields->>'sig1')::bigint ORDER BY 1 DESC,2 ASC,3 DESC LIMIT 15 OFFSET 0; device_id | sig1 | sig3 | sig6 -----------+-------+-----------------+-------- dev3 | 319 | 0.32 | 111545 @@ -718,7 +722,7 @@ SELECT tags->>'device_id' device_id,(fields->>'sig1')::bigint sig1,(fields->>'si (5 rows) --Testcase 71: -SELECT tags->>'device_id' device_id,(fields->>'sig1')::bigint sig1,(fields->>'sig3')::float8 sig3,(fields->>'sig7')::float8 sig7 FROM sctbl1 WHERE (fields->>'sig7')::float8 < 0 ORDER BY 1 DESC,2 ASC,3 DESC LIMIT 15 OFFSET 0; +SELECT (tags->>'device_id' COLLATE "en_US") device_id,(fields->>'sig1')::bigint sig1,(fields->>'sig3')::float8 sig3,(fields->>'sig7')::float8 sig7 FROM sctbl1 WHERE (fields->>'sig7')::float8 < 0 ORDER BY 1 DESC,2 ASC,3 DESC LIMIT 15 OFFSET 0; device_id | sig1 | sig3 | sig7 -----------+-------+-----------------+--------------- dev3 | 319 | 0.32 | -223445600 @@ -730,7 +734,7 @@ SELECT tags->>'device_id' device_id,(fields->>'sig1')::bigint sig1,(fields->>'si (6 rows) --Testcase 72: -SELECT tags->>'device_id' device_id,(fields->>'sig1')::bigint sig1,(fields->>'sig3')::float8 sig3,(fields->>'sig8')::float8 sig8 FROM sctbl1 WHERE NOT time >'2020-1-3 20:30:50' ORDER BY 1 DESC,2 ASC,3 DESC LIMIT 15 OFFSET 2; +SELECT (tags->>'device_id' COLLATE "en_US") device_id,(fields->>'sig1')::bigint sig1,(fields->>'sig3')::float8 sig3,(fields->>'sig8')::float8 sig8 FROM sctbl1 WHERE NOT time >'2020-1-3 20:30:50' ORDER BY 1 DESC,2 ASC,3 DESC LIMIT 15 OFFSET 2; device_id | sig1 | sig3 | sig8 -----------+-------+-----------------+------- d ,=ev2 | 2222 | -1 | 2.024 @@ -742,7 +746,7 @@ SELECT tags->>'device_id' device_id,(fields->>'sig1')::bigint sig1,(fields->>'si (6 rows) --Testcase 73: -SELECT time, tags->>'device_id' device_id,(fields->>'sig1')::bigint sig1,fields->>'sig2' sig2,(fields->>'sig3')::float8 sig3,(fields->>'sig4')::boolean sig4,(fields->>'sig5')::boolean sig5,(fields->>'sig6')::bigint sig6,(fields->>'sig7')::float8 sig7,(fields->>'sig8')::float8 sig8,(fields->>'sig9')::float8 sig9,(fields->>'sig10')::int sig10,fields->>'sig11' sig11,fields->>'sig12' sig12,(fields->>'sig13')::boolean sig13,fields->>'sig14' sig14,(fields->>'sig15')::bigint sig15,(fields->>'sig16')::bigint sig16,(fields->>'sig17')::bigint sig17,fields->>'sig18' sig18,fields->>'sig19' sig19,fields->>'sig20' sig20,(fields->>'sig21')::boolean sig21,fields->>'sig22' sig22,(fields->>'sig23')::bigint sig23,(fields->>'sig24')::int sig24,(fields->>'sig25')::float8 sig25 FROM sctbl1 WHERE true ORDER BY 1 DESC,2 ASC,3 DESC,4,5 LIMIT 15 OFFSET 0; +SELECT time, (tags->>'device_id' COLLATE "en_US") device_id,(fields->>'sig1')::bigint sig1,fields->>'sig2' sig2,(fields->>'sig3')::float8 sig3,(fields->>'sig4')::boolean sig4,(fields->>'sig5')::boolean sig5,(fields->>'sig6')::bigint sig6,(fields->>'sig7')::float8 sig7,(fields->>'sig8')::float8 sig8,(fields->>'sig9')::float8 sig9,(fields->>'sig10')::int sig10,fields->>'sig11' sig11,fields->>'sig12' sig12,(fields->>'sig13')::boolean sig13,fields->>'sig14' sig14,(fields->>'sig15')::bigint sig15,(fields->>'sig16')::bigint sig16,(fields->>'sig17')::bigint sig17,fields->>'sig18' sig18,fields->>'sig19' sig19,fields->>'sig20' sig20,(fields->>'sig21')::boolean sig21,fields->>'sig22' sig22,(fields->>'sig23')::bigint sig23,(fields->>'sig24')::int sig24,(fields->>'sig25')::float8 sig25 FROM sctbl1 WHERE true ORDER BY 1 DESC,2 ASC,3 DESC,4,5 LIMIT 15 OFFSET 0; time | device_id | sig1 | sig2 | sig3 | sig4 | sig5 | sig6 | sig7 | sig8 | sig9 | sig10 | sig11 | sig12 | sig13 | sig14 | sig15 | sig16 | sig17 | sig18 | sig19 | sig20 | sig21 | sig22 | sig23 | sig24 | sig25 -------------------------------+-----------+-------+----------------------------------------+-----------------+------+------+--------+---------------+-------+--------+-------+--------------+------------------+-------+----------------+---------------------+----------------------+---------------------+-------+-------+-------+-------+-------+-------+-------+------- 2262-04-11 23:47:16.854776+00 | 'dev3' | 34422 | 散りぬるを我が世誰 | 0.32 | f | t | 232 | 123445600 | 3.025 | -0.423 | 22 | Zep | | f | | 9223372036854775807 | -9223372036854775808 | 9223372036854775807 | west | east | | t | wef | 1112 | 122 | 0.2 @@ -785,7 +789,7 @@ SELECT * FROM sctbl1 WHERE fields->>'sig11' LIKE 'w%' ORDER BY fields->>'sig11' (3 rows) --Testcase 77: -SELECT tags->>'device_id' device_id,(fields->>'sig1')::bigint sig1,fields->>'sig2' sig2,fields->>'sig12' sig12,(fields->>'sig13')::boolean sig13 FROM sctbl1 WHERE NOT EXISTS (SELECT fields->>'sig12' FROM sctbl1 WHERE fields->>'sig11'='33') ORDER BY tags->>'device_id' DESC,(fields->>'sig1')::bigint ASC LIMIT 15 OFFSET 0; +SELECT tags->>'device_id' device_id,(fields->>'sig1')::bigint sig1,fields->>'sig2' sig2,fields->>'sig12' sig12,(fields->>'sig13')::boolean sig13 FROM sctbl1 WHERE NOT EXISTS (SELECT fields->>'sig12' FROM sctbl1 WHERE fields->>'sig11'='33') ORDER BY (tags->>'device_id' COLLATE "en_US") DESC,(fields->>'sig1')::bigint ASC LIMIT 15 OFFSET 0; device_id | sig1 | sig2 | sig12 | sig13 -----------+-------+----------------------------------------+------------------+------- 'dev3' | 34422 | 散りぬるを我が世誰 | | f @@ -880,22 +884,22 @@ SELECT (fields->>'sig16')::bigint sig16,(fields->>'sig17')::bigint sig17,(fields --Testcase 85: SELECT (fields->>'sig1')::bigint sig1,(fields->>'sig17')::bigint sig17,(fields->>'sig24')::int sig24,(fields->>'sig25')::float8 sig25,(fields->>'sig17')::bigint*(fields->>'sig25')::float8 as mm FROM sctbl1 WHERE NOT (fields->>'sig10')::bigint=15 ORDER BY fields->>'sig20' DESC LIMIT 15 OFFSET 0; - sig1 | sig17 | sig24 | sig25 | mm --------+---------------------+-------+-------+---------------------- - 34422 | 9223372036854775807 | 122 | 0.2 | 1.84467440737096e+18 - 2222 | 9223372036854775807 | 122 | 0.1 | 9.22337203685478e+17 - 65535 | 9223372036854775807 | 122 | 0.5 | 4.61168601842739e+18 - 35655 | 9223372036854775807 | 122 | 0 | 0 - -664 | 9223372036854775807 | 122 | 0 | 0 - 319 | 9223372036854775807 | 122 | 0 | 0 - -8555 | 9223372036854775807 | 122 | 0.7 | 6.45636042579834e+18 - 11 | 9223372036854775807 | 122 | 0 | 0 - 70220 | 9223372036854775807 | 122 | 0 | 0 + sig1 | sig17 | sig24 | sig25 | mm +-------+---------------------+-------+-------+------------------------ + 34422 | 9223372036854775807 | 122 | 0.2 | 1.8446744073709553e+18 + 2222 | 9223372036854775807 | 122 | 0.1 | 9.223372036854776e+17 + 65535 | 9223372036854775807 | 122 | 0.5 | 4.611686018427388e+18 + 35655 | 9223372036854775807 | 122 | 0 | 0 + -664 | 9223372036854775807 | 122 | 0 | 0 + 319 | 9223372036854775807 | 122 | 0 | 0 + -8555 | 9223372036854775807 | 122 | 0.7 | 6.456360425798343e+18 + 11 | 9223372036854775807 | 122 | 0 | 0 + 70220 | 9223372036854775807 | 122 | 0 | 0 (9 rows) --Testcase 86: SELECT (fields->>'sig21')::boolean sig21,fields->>'sig22' sig22,(fields->>'sig23')::bigint sig23,(fields->>'sig24')::int sig24,(fields->>'sig25')::float8 sig25 FROM ( SELECT * FROM sctbl1 WHERE (fields->>'sig6')::bigint>-1000 AND (fields->>'sig9')::float8 < 1 ) AS tb1 WHERE (fields->>'sig10')::bigint != 0 AND (fields->>'sig7')::float8=-1.234456e+78 ORDER BY 1 DESC,2 ASC LIMIT 15 OFFSET 0; -ERROR: influxdb_fdw : error parsing query: found e, expected ) at line 1, char 169 +ERROR: influxdb_fdw : error parsing query: found e, expected ) at line 1, char 158 --Testcase 87: SELECT (fields->>'sig21')::boolean sig21,fields->>'sig22' sig22,(fields->>'sig23')::bigint sig23,(fields->>'sig24')::int sig24,(fields->>'sig25')::float8 sig25 FROM ( SELECT * FROM sctbl1 WHERE (fields->>'sig6')::bigint>-1000 AND (fields->>'sig9')::float8 < 1 ) AS tb1 WHERE (fields->>'sig7')::float8 > -1.0 OR fields->>'sig12' != 'Hello' ORDER BY 1 DESC,2 ASC,3 DESC,4,5 LIMIT 15 OFFSET 0; sig21 | sig22 | sig23 | sig24 | sig25 @@ -999,9 +1003,9 @@ SELECT tags->>'device_id' device_id,abs((fields->>'sig16')::bigint), ceil((field ERROR: bigint out of range --Testcase 97: SELECT count(tags->>'device_id'),sum((fields->>'sig10')::bigint),sum((fields->>'sig7')::float8+(fields->>'sig10')::bigint),stddev((fields->>'sig8')::float8 order by (fields->>'sig8')::float8) from sctbl1 ORDER BY 1 DESC,2 ASC,3 DESC LIMIT 15 OFFSET 0; - count | sum | sum | stddev --------+------+---------------+------------------ - 9 | 8777 | -1.234456e+78 | 2.74135140031336 + count | sum | sum | stddev +-------+------+---------------+------------------- + 9 | 8777 | -1.234456e+78 | 2.741351400313357 (1 row) --Testcase 98: @@ -1017,24 +1021,30 @@ LINE 1: ...s->>'sig21')::boolean != true ORDER BY 1 DESC, 2, 3 LIMIT 15... ^ --Testcase 100: SELECT (fields->>'sig9')::float8 sig9, acos((fields->>'sig9')::float8), atan((fields->>'sig9')::float8) FROM sctbl1 WHERE fields->>'sig12' IS NULL GROUP BY fields->>'sig9' HAVING min((fields->>'sig10')::bigint) < min((fields->>'sig6')::bigint) ORDER BY 1 DESC, 2, 3 LIMIT 15 OFFSET 0; - sig9 | acos | atan ---------+------------------+-------------------- - 0.26 | 1.30777412388643 | 0.254368058553266 - -0.423 | 2.0075498827442 | -0.400175410565532 - -0.9 | 2.69056584179353 | -0.732815101786507 + sig9 | acos | atan +--------+--------------------+--------------------- + 0.26 | 1.3077741238864278 | 0.25436805855326594 + -0.423 | 2.007549882744198 | -0.4001754105655318 + -0.9 | 2.6905658417935308 | -0.7328151017865066 (3 rows) --Testcase 101: SELECT (fields->>'sig9')::float8 sig9, log((fields->>'sig9')::float8),cos((fields->>'sig9')::float8) FROM sctbl1 WHERE fields->>'sig12' IS NOT NULL AND (fields->>'sig9')::float8 > 0 GROUP BY fields->>'sig9' HAVING min((fields->>'sig9')::float8) < 100 AND max((fields->>'sig1')::bigint) < 1000 AND sum((fields->>'sig3')::float8) > -1000 AND avg((fields->>'sig3')::float8) > -1000 ORDER BY 1 DESC, 2, 3 LIMIT 15 OFFSET 0; - sig9 | log | cos -------+--------------------+------------------ - 0.24 | -0.619788758288394 | 0.97133797485203 + sig9 | log | cos +------+--------------------+-------------------- + 0.24 | -0.619788758288394 | 0.9713379748520297 (1 row) --Testcase 102: SELECT (fields->>'sig10')::bigint sig10,(fields->>'sig8')::float8 sig8,ln((fields->>'sig10')::bigint), log10((fields->>'sig8')::float8) FROM sctbl1 WHERE NOT (fields->>'sig10')::bigint=5 GROUP BY fields->>'sig10', fields->>'sig8' HAVING min((fields->>'sig7')::float8) < 100 AND max((fields->>'sig6')::bigint) < 1000 AND (fields->>'sig10')::bigint > 0 AND (fields->>'sig8')::float8 > 0 ORDER BY 1 DESC, 2, 3 LIMIT 15 OFFSET 0; -ERROR: stub log10(float8) is called -CONTEXT: PL/pgSQL function log10(double precision) line 3 at RAISE + sig10 | sig8 | ln | log10 +-------+-------+--------------------+---------------------- + 226 | 1.023 | 5.420534999272286 | 0.009875633712160119 + 77 | 8.03 | 4.343805421853684 | 0.9047155452786809 + 55 | 6.028 | 4.007333185232471 | 0.7801732436425941 + 33 | 4.026 | 3.4965075614664802 | 0.6048737705526357 +(4 rows) + --Testcase 103: SELECT max(time), max((fields->>'sig6')::bigint + (fields->>'sig7')::float8), min((fields->>'sig6')::bigint + (fields->>'sig7')::float8) FROM ( SELECT * FROM sctbl1 WHERE (fields->>'sig8')::float8 > -1000 AND (fields->>'sig13')::boolean != true ) AS tb1 WHERE (fields->>'sig7')::float8 != -1 AND (fields->>'sig21')::boolean != true GROUP BY fields->>'sig6' ORDER BY 1 DESC, 2, 3 LIMIT 15 OFFSET 0; max | max | min @@ -1052,13 +1062,13 @@ SELECT avg((fields->>'sig23')::bigint order by (fields->>'sig23')::bigint),avg(( --Testcase 105: SELECT (fields->>'sig8')::float8 sig8,exp((fields->>'sig8')::float8),exp((fields->>'sig8')::float8*2) FROM ( SELECT * FROM sctbl1 WHERE (fields->>'sig9')::float8 > -1000 AND (fields->>'sig21')::boolean = true ) AS tb1 WHERE true GROUP BY fields->>'sig8' ORDER BY 1 DESC, 2, 3 LIMIT 15 OFFSET 0; - sig8 | exp | exp --------+------------------+------------------ - 9.031 | 8358.21360806988 | 69859734.7181246 - 7.029 | 1128.9011444032 | 1274417.79383485 - 5.027 | 152.474901168402 | 23248.5954863141 - 3.025 | 20.594004711196 | 424.113030044764 - 1.023 | 2.78152684012137 | 7.73689156231557 + sig8 | exp | exp +-------+--------------------+-------------------- + 9.031 | 8358.213608069884 | 69859734.71812458 + 7.029 | 1128.9011444031978 | 1274417.7938348497 + 5.027 | 152.4749011684023 | 23248.595486314054 + 3.025 | 20.59400471119603 | 424.1130300447642 + 1.023 | 2.78152684012137 | 7.736891562315574 (5 rows) --Testcase 106: @@ -1079,18 +1089,18 @@ SELECT min(time)+'10 days'::interval, min((fields->>'sig10')::bigint + (fields-> SELECT floor((fields->>'sig23')::bigint*(fields->>'sig25')::float8), floor((fields->>'sig24')::bigint/(fields->>'sig25')::float8) FROM sctbl1 WHERE ((fields->>'sig25')::float8 - 1)/3 != 1 GROUP BY (fields->>'sig23')::bigint, (fields->>'sig24')::bigint,(fields->>'sig25')::float8 HAVING sum((fields->>'sig23')::bigint) > avg((fields->>'sig24')::bigint) ORDER BY 1 ASC,2 DESC LIMIT 15 OFFSET 0; ERROR: division by zero --Testcase 108: -SELECT time, tags->>'device_id' device_id, pow((fields->>'sig25')::float8,2) FROM sctbl1 WHERE ((fields->>'sig25')::float8 - 1)/3 != 1 GROUP BY time,tags->>'device_id',fields->>'sig25' ORDER BY 1 ASC,2 DESC LIMIT 15 OFFSET 0; - time | device_id | pow --------------------------------+-----------+------ - 1677-09-21 00:12:43.145224+00 | dev1 | 0 - 2016-06-13 17:43:50.1004+00 | dev3 | 0.25 - 2016-06-13 17:43:50.1004+00 | d ,=ev2 | 0.01 - 2016-06-13 17:43:50.1004+00 | dev2 | 0 - 2019-05-02 16:12:41.098+00 | dev3 | 0 - 2019-05-02 16:12:41.098+00 | dev2 | 0.49 - 2019-05-02 16:12:41.098+00 | "dev 1" | 0 - 2019-05-02 16:12:41.098+00 | dev1 | 0 - 2262-04-11 23:47:16.854776+00 | 'dev3' | 0.04 +SELECT time, (tags->>'device_id' COLLATE "en_US") device_id, pow((fields->>'sig25')::float8,2) FROM sctbl1 WHERE ((fields->>'sig25')::float8 - 1)/3 != 1 GROUP BY time,(tags->>'device_id' COLLATE "en_US"),fields->>'sig25' ORDER BY 1 ASC,2 DESC LIMIT 15 OFFSET 0; + time | device_id | pow +-------------------------------+-----------+---------------------- + 1677-09-21 00:12:43.145224+00 | dev1 | 0 + 2016-06-13 17:43:50.1004+00 | dev3 | 0.25 + 2016-06-13 17:43:50.1004+00 | d ,=ev2 | 0.010000000000000002 + 2016-06-13 17:43:50.1004+00 | dev2 | 0 + 2019-05-02 16:12:41.098+00 | dev3 | 0 + 2019-05-02 16:12:41.098+00 | dev2 | 0.48999999999999994 + 2019-05-02 16:12:41.098+00 | "dev 1" | 0 + 2019-05-02 16:12:41.098+00 | dev1 | 0 + 2262-04-11 23:47:16.854776+00 | 'dev3' | 0.04000000000000001 (9 rows) --Testcase 109: @@ -1125,7 +1135,7 @@ SELECT (fields->>'sig9')::float8 sig9, abs(avg((fields->>'sig16')::bigint)),stri --Join table --Testcase 113: -SELECT s1.tags->>'device_id' device_id,(s1.fields->>'sig21')::boolean sig21,s1.fields->>'sig22' sig22,(s1.fields->>'sig23')::bigint sig23,(s1.fields->>'sig24')::int sig24,(s1.fields->>'sig25')::float8 sig25 FROM sctbl1 s1 FULL JOIN sctbl2 s2 ON s1.tags->>'device_id'=s2.tags->>'device_id' ORDER BY device_id,sig21,sig22,sig23,sig24,sig25; +SELECT (s1.tags->>'device_id' COLLATE "en_US") device_id,(s1.fields->>'sig21')::boolean sig21,s1.fields->>'sig22' sig22,(s1.fields->>'sig23')::bigint sig23,(s1.fields->>'sig24')::int sig24,(s1.fields->>'sig25')::float8 sig25 FROM sctbl1 s1 FULL JOIN sctbl2 s2 ON s1.tags->>'device_id'=s2.tags->>'device_id' ORDER BY device_id,sig21,sig22,sig23,sig24,sig25; device_id | sig21 | sig22 | sig23 | sig24 | sig25 -----------+-------+-------+-------+-------+------- dev1 | f | wef | 1112 | 122 | 0 @@ -1190,7 +1200,7 @@ SELECT s1.device_id,s1.sig21,s1.sig22,s1.sig23,s1.sig24,s1.sig25 FROM (SELECT ti (6 rows) --Testcase 116: -SELECT * FROM (SELECT time, tags->>'device_id' device_id, (fields->>'sig1')::bigint sig1, fields->>'sig2' sig2, (fields->>'sig3')::float8 sig3, (fields->>'sig4')::boolean sig4,(fields->>'sig5')::boolean sig5,(fields->>'sig6')::bigint sig6, (fields->>'sig7')::float8 sig7,(fields->>'sig8')::float8 sig8,(fields->>'sig9')::float8 sig9,(fields->>'sig10')::bigint sig10,fields->>'sig11' sig11,fields->>'sig12' sig12, (fields->>'sig13')::boolean sig13, fields->>'sig14' sig14, (fields->>'sig15')::bigint sig15,(fields->>'sig16')::bigint sig16, (fields->>'sig17')::bigint sig17, fields->>'sig18' sig18,fields->>'sig19' sig19, fields->>'sig20' sig20, (fields->>'sig21')::boolean sig21, fields->>'sig22' sig22, (fields->>'sig23')::bigint sig23, (fields->>'sig24')::bigint sig24, (fields->>'sig25')::float8 sig25 FROM sctbl1) s1 FULL OUTER JOIN (SELECT time, tags->>'device_id' device_id, (fields->>'sig1')::bigint sig1, fields->>'sig2' sig2, (fields->>'sig3')::float8 sig3, (fields->>'sig4')::boolean sig4,fields->>'sig5' sig5 FROM sctbl2) s2 USING(sig2) ORDER BY s1.sig2, s1.time, s1.device_id, s2.time, s2.device_id; +SELECT * FROM (SELECT time, tags->>'device_id' device_id, (fields->>'sig1')::bigint sig1, fields->>'sig2' sig2, (fields->>'sig3')::float8 sig3, (fields->>'sig4')::boolean sig4,(fields->>'sig5')::boolean sig5,(fields->>'sig6')::bigint sig6, (fields->>'sig7')::float8 sig7,(fields->>'sig8')::float8 sig8,(fields->>'sig9')::float8 sig9,(fields->>'sig10')::bigint sig10,fields->>'sig11' sig11,fields->>'sig12' sig12, (fields->>'sig13')::boolean sig13, fields->>'sig14' sig14, (fields->>'sig15')::bigint sig15,(fields->>'sig16')::bigint sig16, (fields->>'sig17')::bigint sig17, fields->>'sig18' sig18,fields->>'sig19' sig19, fields->>'sig20' sig20, (fields->>'sig21')::boolean sig21, fields->>'sig22' sig22, (fields->>'sig23')::bigint sig23, (fields->>'sig24')::bigint sig24, (fields->>'sig25')::float8 sig25 FROM sctbl1) s1 FULL OUTER JOIN (SELECT time, tags->>'device_id' device_id, (fields->>'sig1')::bigint sig1, fields->>'sig2' sig2, (fields->>'sig3')::float8 sig3, (fields->>'sig4')::boolean sig4,fields->>'sig5' sig5 FROM sctbl2) s2 USING(sig2) ORDER BY s1.sig2 COLLATE "en_US", s1.time, s1.device_id, s2.time, s2.device_id; sig2 | time | device_id | sig1 | sig3 | sig4 | sig5 | sig6 | sig7 | sig8 | sig9 | sig10 | sig11 | sig12 | sig13 | sig14 | sig15 | sig16 | sig17 | sig18 | sig19 | sig20 | sig21 | sig22 | sig23 | sig24 | sig25 | time | device_id | sig1 | sig3 | sig4 | sig5 ----------------------------------------+-------------------------------+-----------+-------+-----------------+------+------+--------+---------------+-------+--------+-------+--------------+------------------+-------+----------------+---------------------+----------------------+---------------------+-------+-------+-------+-------+-------+-------+-------+-------+-------------------------------+-----------+-------+----------------+------+--------------------------------------------------------------- `~!@#$%^&*()_+= | 2016-06-13 17:43:50.1004+00 | dev3 | 65535 | -0.91 | f | t | 311 | -123445600 | 6.028 | 0.26 | 55 | wwefs | | f | example string | 9223372036854775807 | -9223372036854775808 | 9223372036854775807 | | | OFF | f | wef | 1112 | 122 | 0.5 | | | | | | @@ -1212,7 +1222,8 @@ SELECT * FROM (SELECT time, tags->>'device_id' device_id, (fields->>'sig1')::big --Testcase 117: SELECT s2.device_id,s2.sig1,s2.sig2,s2.sig3,s2.sig4,s2.sig5 FROM (SELECT time, tags->>'device_id' device_id, (fields->>'sig1')::bigint sig1, fields->>'sig2' sig2, (fields->>'sig3')::float8 sig3, (fields->>'sig4')::boolean sig4,(fields->>'sig5')::boolean sig5,(fields->>'sig6')::bigint sig6, (fields->>'sig7')::float8 sig7,(fields->>'sig8')::float8 sig8,(fields->>'sig9')::float8 sig9,(fields->>'sig10')::bigint sig10,fields->>'sig11' sig11,fields->>'sig12' sig12, (fields->>'sig13')::boolean sig13, fields->>'sig14' sig14, (fields->>'sig15')::bigint sig15,(fields->>'sig16')::bigint sig16, (fields->>'sig17')::bigint sig17, fields->>'sig18' sig18,fields->>'sig19' sig19, fields->>'sig20' sig20, (fields->>'sig21')::boolean sig21, fields->>'sig22' sig22, (fields->>'sig23')::bigint sig23, (fields->>'sig24')::bigint sig24, (fields->>'sig25')::float8 sig25 FROM sctbl1) s1 NATURAL JOIN (SELECT time, tags->>'device_id' device_id, (fields->>'sig1')::bigint sig1, fields->>'sig2' sig2, (fields->>'sig3')::float8 sig3, (fields->>'sig4')::boolean sig4,fields->>'sig5' sig5 FROM sctbl2) s2; -ERROR: JOIN/USING types boolean and text cannot be matched +ERROR: operator does not exist: boolean = text +HINT: No operator matches the given name and argument types. You might need to add explicit type casts. --Testcase 118: SELECT s1.device_id,s1.sig11,s1.sig12,s1.sig13,s1.sig14,s1.sig15 FROM (SELECT time, tags->>'device_id' device_id, (fields->>'sig1')::bigint sig1, fields->>'sig2' sig2, (fields->>'sig3')::float8 sig3, (fields->>'sig4')::boolean sig4,(fields->>'sig5')::boolean sig5,(fields->>'sig6')::bigint sig6, (fields->>'sig7')::float8 sig7,(fields->>'sig8')::float8 sig8,(fields->>'sig9')::float8 sig9,(fields->>'sig10')::bigint sig10,fields->>'sig11' sig11,fields->>'sig12' sig12, (fields->>'sig13')::boolean sig13, fields->>'sig14' sig14, (fields->>'sig15')::bigint sig15,(fields->>'sig16')::bigint sig16, (fields->>'sig17')::bigint sig17, fields->>'sig18' sig18,fields->>'sig19' sig19, fields->>'sig20' sig20, (fields->>'sig21')::boolean sig21, fields->>'sig22' sig22, (fields->>'sig23')::bigint sig23, (fields->>'sig24')::bigint sig24, (fields->>'sig25')::float8 sig25 FROM sctbl1) s1 JOIN (SELECT time, tags->>'device_id' device_id, (fields->>'sig1')::bigint sig1, fields->>'sig2' sig2, (fields->>'sig3')::float8 sig3, (fields->>'sig4')::boolean sig4,fields->>'sig5' sig5 FROM sctbl2) s2 on true; device_id | sig11 | sig12 | sig13 | sig14 | sig15 @@ -1276,7 +1287,11 @@ SELECT s1.device_id,s1.sig11,s1.sig12,s1.sig13,s1.sig14,s1.sig15 FROM (SELECT ti --Clean --Testcase 119: DROP FOREIGN TABLE sctbl1; +--Testcase 120: DROP FOREIGN TABLE sctbl2; +--Testcase 121: DROP USER MAPPING FOR CURRENT_USER SERVER influxdb_svr; +--Testcase 122: DROP SERVER influxdb_svr CASCADE; +--Testcase 123: DROP EXTENSION influxdb_fdw; diff --git a/expected/11.17/schemaless/add_multi_key.out b/expected/16.0/schemaless/add_multi_key.out similarity index 95% rename from expected/11.17/schemaless/add_multi_key.out rename to expected/16.0/schemaless/add_multi_key.out index e93572b..4c2ae01 100644 --- a/expected/11.17/schemaless/add_multi_key.out +++ b/expected/16.0/schemaless/add_multi_key.out @@ -160,7 +160,7 @@ ERROR: column "sctbl3.fields" must appear in the GROUP BY clause or be used in LINE 1: SELECT count(fields->>'c2'), (fields->>'c3')::bigint c3, fie... ^ --Testcase 18: -SELECT 32 + (fields->>'c3')::bigint, (fields->>'c3')::bigint + (fields->>'c3')::bigint from sctbl3 GROUP BY fields->>'c3', fields->>'c5', fields->>'c2' ORDER BY fields->>'c2'; +SELECT 32 + (fields->>'c3')::bigint, (fields->>'c3')::bigint + (fields->>'c3')::bigint from sctbl3 GROUP BY fields->>'c3', fields->>'c5', (fields->>'c2' COLLATE "en_US") ORDER BY (fields->>'c2' COLLATE "en_US"); ?column? | ?column? --------------+-------------- 30 | -4 @@ -246,7 +246,7 @@ SELECT stddev((fields->>'c3')::bigint), stddev((fields->>'c3')::bigint ORDER BY (13 rows) --Testcase 23: -SELECT string_agg(fields->>'c2', ';' ORDER BY fields->>'c2') FROM sctbl3 GROUP BY fields->>'c2' ORDER BY 1; +SELECT string_agg(fields->>'c2' COLLATE "en_US", ';' ORDER BY fields->>'c2') FROM sctbl3 GROUP BY fields->>'c2' ORDER BY 1; string_agg ---------------------------------------------------------------------------------- `~!@#$%^&*()_+=-{}[]|:;<>?/. @@ -541,19 +541,19 @@ SELECT stddev((fields->>'c3')::bigint), stddev((fields->>'c3')::bigint ORDER BY --Testcase 44: SELECT sqrt(abs((fields->>'c3')::bigint)), sqrt(abs((fields->>'c3')::bigint)) FROM ( SELECT * FROM sctbl3 WHERE (fields->>'c3')::bigint>-1000 AND (fields->>'c3')::bigint<1000 ) AS sctbl3 ORDER BY 1 ASC,2 DESC; - sqrt | sqrt -------------------+------------------ - 0 | 0 - 1 | 1 - 1 | 1 - 1.4142135623731 | 1.4142135623731 - 1.4142135623731 | 1.4142135623731 - 1.73205080756888 | 1.73205080756888 - 1.73205080756888 | 1.73205080756888 - 2 | 2 - 2 | 2 - 2.23606797749979 | 2.23606797749979 - 2.23606797749979 | 2.23606797749979 + sqrt | sqrt +--------------------+-------------------- + 0 | 0 + 1 | 1 + 1 | 1 + 1.4142135623730951 | 1.4142135623730951 + 1.4142135623730951 | 1.4142135623730951 + 1.7320508075688772 | 1.7320508075688772 + 1.7320508075688772 | 1.7320508075688772 + 2 | 2 + 2 | 2 + 2.23606797749979 | 2.23606797749979 + 2.23606797749979 | 2.23606797749979 (11 rows) --Testcase 45: @@ -756,7 +756,7 @@ SELECT time,fields->>'c2' c2,(fields->>'c3')::bigint c3,(fields->>'c4')::double -- Select many target aggregate in one query and combine with condition --Testcase 62: -SELECT upper(fields->>'c2'), upper(fields->>'c2'), lower(fields->>'c2'), lower(fields->>'c2') FROM sctbl3 ORDER BY 1 ASC,2 DESC,3 ASC,4; +SELECT upper(fields->>'c2' COLLATE "en_US"), upper(fields->>'c2' COLLATE "en_US"), lower(fields->>'c2' COLLATE "en_US"), lower(fields->>'c2' COLLATE "en_US") FROM sctbl3 ORDER BY 1 ASC,2 DESC,3 ASC,4; upper | upper | lower | lower ----------------------------------------------------------------------------------+----------------------------------------------------------------------------------+----------------------------------------------------------------------------------+---------------------------------------------------------------------------------- `~!@#$%^&*()_+=-{}[]|:;<>?/. | `~!@#$%^&*()_+=-{}[]|:;<>?/. | `~!@#$%^&*()_+=-{}[]|:;<>?/. | `~!@#$%^&*()_+=-{}[]|:;<>?/. @@ -906,7 +906,7 @@ SELECT count(fields->>'c2'), bit_and((fields->>'c3')::bigint), bit_or((fields->> SELECT array_agg((fields->>'c3')::bigint-(fields->>'c3')::bigint-(fields->>'c3')::bigint), array_agg((fields->>'c3')::bigint/(fields->>'c3')::bigint*(fields->>'c3')::bigint), array_agg(((fields->>'c3')::bigint+(fields->>'c3')::bigint/(fields->>'c3')::bigint)*-1000), array_agg((fields->>'c3')::bigint*(fields->>'c3')::bigint-(fields->>'c3')::bigint), array_agg(((fields->>'c3')::bigint-(fields->>'c3')::bigint+(fields->>'c3')::bigint)+9999999999999.998) from sctbl3 GROUP BY (fields->>'c3')::bigint, (fields->>'c3')::bigint ORDER BY 1, 2, 3, 4, 5; ERROR: bigint out of range --Testcase 74: -SELECT avg((fields->>'c3')::bigint-(fields->>'c3')::bigint-(fields->>'c3')::bigint)-0.567-avg((fields->>'c3')::bigint/3+(fields->>'c3')::bigint)+17.55435, avg((fields->>'c3')::bigint+(fields->>'c3')::bigint/((fields->>'c3')::bigint+45))- -9.5+2*avg((fields->>'c3')::bigint), avg((fields->>'c3')::bigint/((fields->>'c3')::bigint-10.2)*(fields->>'c3')::bigint)+0.567+avg((fields->>'c3')::bigint)*4.5+(fields->>'c3')::bigint, avg((fields->>'c3')::bigint+(fields->>'c3')::bigint/((fields->>'c3')::bigint+5.6))+100-(fields->>'c3')::bigint from sctbl3 WHERE fields->>'c2'<='$' AND (fields->>'c3')::bigint<>-5 AND (fields->>'c3')::bigint<>10.746 GROUP BY fields->>'c3', fields->>'c3' ORDER BY 1,2,3,4 limit 5; +SELECT avg((fields->>'c3')::bigint-(fields->>'c3')::bigint-(fields->>'c3')::bigint)-0.567-avg((fields->>'c3')::bigint/3+(fields->>'c3')::bigint)+17.55435, avg((fields->>'c3')::bigint+(fields->>'c3')::bigint/((fields->>'c3')::bigint+45))- -9.5+2*avg((fields->>'c3')::bigint), avg((fields->>'c3')::bigint/((fields->>'c3')::bigint-10.2)*(fields->>'c3')::bigint)+0.567+avg((fields->>'c3')::bigint)*4.5+(fields->>'c3')::bigint, avg((fields->>'c3')::bigint+(fields->>'c3')::bigint/((fields->>'c3')::bigint+5.6))+100-(fields->>'c3')::bigint from sctbl3 WHERE fields->>'c2'<='$' COLLATE "en_US" AND (fields->>'c3')::bigint<>-5 AND (fields->>'c3')::bigint<>10.746 GROUP BY fields->>'c3', fields->>'c3' ORDER BY 1,2,3,4 limit 5; ?column? | ?column? | ?column? | ?column? ----------------------+------------------------+------------------------------------+-------------------------- 5.9873500000000000 | 24.5000000000000000 | 23.25930769230769230770 | 100.47169811320754716981 @@ -915,13 +915,13 @@ SELECT avg((fields->>'c3')::bigint-(fields->>'c3')::bigint-(fields->>'c3')::bigi (3 rows) --Testcase 75: -SELECT bit_and((fields->>'c3')::bigint/3*(fields->>'c3')::bigint)-1 + bit_and((fields->>'c3')::bigint/4/((fields->>'c3')::bigint+6)),2* bit_and((fields->>'c3')::bigint-(fields->>'c3')::bigint+(fields->>'c3')::bigint)*1, 5-bit_and((fields->>'c3')::bigint+(fields->>'c3')::bigint-(fields->>'c3')::bigint)-1000000+(fields->>'c3')::bigint from sctbl3 WHERE fields->>'c2'<='$' AND (fields->>'c3')::bigint<>-5 AND (fields->>'c3')::bigint<>10.746 GROUP BY fields->>'c3' ORDER BY 1,2,3; +SELECT bit_and((fields->>'c3')::bigint/3*(fields->>'c3')::bigint)-1 + bit_and((fields->>'c3')::bigint/4/((fields->>'c3')::bigint+6)),2* bit_and((fields->>'c3')::bigint-(fields->>'c3')::bigint+(fields->>'c3')::bigint)*1, 5-bit_and((fields->>'c3')::bigint+(fields->>'c3')::bigint-(fields->>'c3')::bigint)-1000000+(fields->>'c3')::bigint from sctbl3 WHERE fields->>'c2'<='$' COLLATE "en_US" AND (fields->>'c3')::bigint<>-5 AND (fields->>'c3')::bigint<>10.746 GROUP BY fields->>'c3' ORDER BY 1,2,3; ERROR: bigint out of range --Testcase 76: -SELECT bit_or((fields->>'c3')::bigint/3*(fields->>'c3')::bigint)-1 + bit_or((fields->>'c3')::bigint/4/((fields->>'c3')::bigint+6)),2* bit_or((fields->>'c3')::bigint-(fields->>'c3')::bigint+(fields->>'c3')::bigint)*1, 5-bit_or((fields->>'c3')::bigint+(fields->>'c3')::bigint-(fields->>'c3')::bigint)-1000000+(fields->>'c3')::bigint from sctbl3 WHERE fields->>'c2'<='$' AND (fields->>'c3')::bigint<>-5 AND (fields->>'c3')::bigint<>10.746 GROUP BY fields->>'c3' ORDER BY 1,2,3; +SELECT bit_or((fields->>'c3')::bigint/3*(fields->>'c3')::bigint)-1 + bit_or((fields->>'c3')::bigint/4/((fields->>'c3')::bigint+6)),2* bit_or((fields->>'c3')::bigint-(fields->>'c3')::bigint+(fields->>'c3')::bigint)*1, 5-bit_or((fields->>'c3')::bigint+(fields->>'c3')::bigint-(fields->>'c3')::bigint)-1000000+(fields->>'c3')::bigint from sctbl3 WHERE fields->>'c2'<='$' COLLATE "en_US" AND (fields->>'c3')::bigint<>-5 AND (fields->>'c3')::bigint<>10.746 GROUP BY fields->>'c3' ORDER BY 1,2,3; ERROR: bigint out of range --Testcase 77: -SELECT count(*)-5.6, 2*count(*), 10.2/count(*)+count(*)-(fields->>'c3')::bigint from sctbl3 WHERE (fields->>'c3')::bigint>0.774 OR fields->>'c2' = 'Which started out as a kind' GROUP BY fields->>'c3' ORDER BY 1, 2, 3; +SELECT count(*)-5.6, 2*count(*), 10.2/count(*)+count(*)-(fields->>'c3')::bigint from sctbl3 WHERE (fields->>'c3')::bigint>0.774 OR fields->>'c2' = 'Which started out as a kind' COLLATE "en_US" GROUP BY fields->>'c3' ORDER BY 1, 2, 3; ?column? | ?column? | ?column? ----------+----------+------------------------------- -4.6 | 2 | -36854775795.8000000000000000 @@ -1004,7 +1004,7 @@ SELECT max((fields->>'c4')::double precision), max((fields->>'c3')::bigint)+(fie (8 rows) --Testcase 84: -SELECT min(fields->>'c2'), min((fields->>'c3')::bigint)+(fields->>'c3')::bigint-1, min((fields->>'c3')::bigint+(fields->>'c3')::bigint)-(fields->>'c3')::bigint-3, min((fields->>'c3')::bigint)+min((fields->>'c3')::bigint) from sctbl3 WHERE (fields->>'c4')::double precision<0 GROUP BY fields->>'c3', fields->>'c3' ORDER BY 1,2,3,4; +SELECT min(fields->>'c2' COLLATE "en_US"), min((fields->>'c3')::bigint)+(fields->>'c3')::bigint-1, min((fields->>'c3')::bigint+(fields->>'c3')::bigint)-(fields->>'c3')::bigint-3, min((fields->>'c3')::bigint)+min((fields->>'c3')::bigint) from sctbl3 WHERE (fields->>'c4')::double precision<0 GROUP BY fields->>'c3', fields->>'c3' ORDER BY 1,2,3,4; min | ?column? | ?column? | ?column? ----------------------------------------------------------------------------------+-------------+-------------+------------- `~!@#$%^&*()_+=-{}[]|:;<>?/. | -5 | -5 | -4 @@ -1039,16 +1039,16 @@ SELECT variance((fields->>'c3')::bigint+(fields->>'c3')::bigint)+(fields->>'c3') --Testcase 86: SELECT sqrt(abs((fields->>'c3')::bigint*5)) + sqrt(abs((fields->>'c3')::bigint+6)), sqrt(abs((fields->>'c3')::bigint)+5)+(fields->>'c3')::bigint, 4*sqrt(abs((fields->>'c3')::bigint-100))-(fields->>'c3')::bigint from sctbl3 WHERE (fields->>'c3')::bigint>'c3')::bigint FROM sctbl3 WHERE (fields->>'c3')::bigint>0) ORDER BY 1, 2, 3; - ?column? | ?column? | ?column? -------------------+-------------------+------------------ - 2.44948974278318 | 2.23606797749979 | 40 - 4.47213595499958 | 1.44948974278318 | 41.1995024844836 - 5.16227766016838 | 0.645751311064591 | 42.3980197534483 - 5.60503415377629 | -0.17157287525381 | 43.5955662603689 - 5.88634951737267 | -1 | 44.7921561087423 - 6 | -1.83772233983162 | 45.9878030638384 - 621247.312124984 | -36854583831.0228 | 36855543710.9097 - 621247.312133412 | -36854583832.0228 | 36855543711.9097 + ?column? | ?column? | ?column? +--------------------+---------------------+-------------------- + 2.449489742783178 | 2.23606797749979 | 40 + 4.47213595499958 | 1.4494897427831779 | 41.19950248448356 + 5.16227766016838 | 0.6457513110645907 | 42.39801975344831 + 5.605034153776295 | -0.1715728752538097 | 43.59556626036888 + 5.8863495173726745 | -1 | 44.792156108742276 + 6 | -1.8377223398316205 | 45.98780306383839 + 621247.3121249836 | -36854583831.02283 | 36855543710.90968 + 621247.312133412 | -36854583832.02282 | 36855543711.9097 (8 rows) --Testcase 87: @@ -1103,8 +1103,11 @@ SELECT (fields->>'c3')::bigint-30, (fields->>'c3')::bigint-10, sum((fields->>'c3 ---------------------------------------------------------- Update data: add 1 tag and 1 fields------------------------------------------------------------------------------------------------- -- Update data :RECOVER_INIT_MULTILEY_ADD_1TAG_1FIELDS; +--Testcase 202: drop view if exists view_sctbl3 ; +--Testcase 203: drop foreign table if exists sctbl3; +--Testcase 204: CREATE FOREIGN TABLE sctbl3 (time timestamp with time zone, tags jsonb OPTIONS(tags 'true'), fields jsonb OPTIONS(fields 'true')) SERVER influxdb_svr OPTIONS (schemaless 'true', tags 't1'); -- Select all data with condition and combine clause --Testcase 90: @@ -1118,7 +1121,7 @@ SELECT time,tags->>'t1' t1,(fields->>'c1')::bool c1,fields->>'c2' c2,(fields->>' (4 rows) --Testcase 91: -SELECT * FROM sctbl3 WHERE EXISTS (SELECT (fields->>'c3')::bigint FROM sctbl3 WHERE (fields->>'c3')::bigint != 40.772) ORDER BY tags->>'t1'; +SELECT * FROM sctbl3 WHERE EXISTS (SELECT (fields->>'c3')::bigint FROM sctbl3 WHERE (fields->>'c3')::bigint != 40.772) ORDER BY tags->>'t1' COLLATE "en_US"; time | tags | fields -------------------------------+-----------------------+--------------------------------------------------------------------------------------------------------------------------------------------------- 1970-01-01 00:00:00+00 | {"t1": "-2323.54454"} | {"c1": "true", "c2": "Tôi không biết", "c3": "32", "c4": "78.14", "c5": "false"} @@ -1213,7 +1216,7 @@ SELECT time,tags->>'t1' t1,(fields->>'c1')::bool c1,fields->>'c2' c2,(fields->>' -- Select aggregate function and specific column from original table --Testcase 97: -SELECT tags->>'t1' t1, (fields->>'c1')::bool c1, max(tags->>'t1'), sum((fields->>'c3')::bigint), sum((fields->>'c3')::bigint ORDER BY (fields->>'c3')::bigint) FROM sctbl3 GROUP BY tags->>'t1', (fields->>'c1')::bool, (fields->>'c3')::bigint, fields->>'c2' ORDER BY 1; +SELECT (tags->>'t1' COLLATE "en_US") t1, (fields->>'c1')::bool c1, max(tags->>'t1'), sum((fields->>'c3')::bigint), sum((fields->>'c3')::bigint ORDER BY (fields->>'c3')::bigint) FROM sctbl3 GROUP BY (tags->>'t1' COLLATE "en_US"), (fields->>'c1')::bool, (fields->>'c3')::bigint, fields->>'c2' ORDER BY 1; t1 | c1 | max | sum | sum -------------+----+-------------+--------------+-------------- -2323.54454 | t | -2323.54454 | 32 | 32 @@ -1244,7 +1247,7 @@ SELECT sum((fields->>'c3')::bigint), tags->>'t1' t1, sum((fields->>'c3')::bigint (0 rows) --Testcase 99: -SELECT stddev((fields->>'c3')::bigint), (fields->>'c1')::bool c1, stddev((fields->>'c3')::bigint ORDER BY (fields->>'c3')::bigint), tags->>'t1' t1 FROM sctbl3 GROUP BY time, fields->>'c3', tags->>'t1', fields->>'c1' ORDER BY tags->>'t1' ASC,fields->>'c1' DESC; +SELECT stddev((fields->>'c3')::bigint), (fields->>'c1')::bool c1, stddev((fields->>'c3')::bigint ORDER BY (fields->>'c3')::bigint), (tags->>'t1' COLLATE "en_US") t1 FROM sctbl3 GROUP BY time, fields->>'c3', (tags->>'t1' COLLATE "en_US"), fields->>'c1' ORDER BY (tags->>'t1' COLLATE "en_US") ASC,fields->>'c1' DESC; stddev | c1 | stddev | t1 --------+----+--------+------------- | t | | -2323.54454 @@ -1352,10 +1355,10 @@ SELECT max(time), max((fields->>'c3')::bigint), max((fields->>'c3')::bigint)+10, (19 rows) --Testcase 104: -SELECT array_agg((fields->>'c3')::bigint/2 ORDER BY (fields->>'c3')::bigint), array_agg((fields->>'c1')::bool), array_agg(tags->>'t1'), array_agg(fields->>'c2' ORDER BY fields->>'c2'), array_agg(time ORDER BY time) FROM ( SELECT * FROM sctbl3 WHERE (fields->>'c3')::bigint>-1000 AND (fields->>'c3')::bigint<1000 ) AS sctbl3 GROUP BY fields->>'c5' HAVING (fields->>'c5')::boolean != true ORDER BY 1 DESC, 2, 3; +SELECT array_agg((fields->>'c3')::bigint/2 ORDER BY (fields->>'c3')::bigint), array_agg((fields->>'c1' COLLATE "en_US")::bool ORDER BY (fields->>'c1' COLLATE "en_US")::bool), array_agg((tags->>'t1' COLLATE "en_US") ORDER BY (tags->>'t1' COLLATE "en_US")), array_agg((fields->>'c2' COLLATE "en_US") ORDER BY (fields->>'c2' COLLATE "en_US")), array_agg(time ORDER BY time) FROM ( SELECT * FROM sctbl3 WHERE (fields->>'c3')::bigint>-1000 AND (fields->>'c3')::bigint<1000 ) AS sctbl3 GROUP BY fields->>'c5' HAVING (fields->>'c5')::boolean != true ORDER BY 1 DESC, 2, 3; array_agg | array_agg | array_agg | array_agg | array_agg ----------------------+-------------------------------------+----------------------------------------------------+-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- - {-1,0,0,1,2,2,16,17} | {t,t,NULL,NULL,NULL,NULL,NULL,NULL} | {faefek,-2323.54454,NULL,NULL,NULL,NULL,NULL,NULL} | {"`~!@#$%^&*()_+=-{}[]|:;<>?/.",$,0123456789,"change for new change","Change our locale from $ to ¥ in","Chúc mừng năm mới 2021","In Bulgarian it is desirable","Tôi không biết"} | {"1969-12-22 20:42:30+00","1970-01-01 00:00:00+00","2020-01-06 01:00:00+00","2020-01-07 01:00:00+00","2020-01-08 01:00:00+00","2020-01-11 01:00:00+00","2020-01-12 01:00:00+00","2020-01-13 01:00:00+00"} + {-1,0,0,1,2,2,16,17} | {t,t,NULL,NULL,NULL,NULL,NULL,NULL} | {-2323.54454,faefek,NULL,NULL,NULL,NULL,NULL,NULL} | {"`~!@#$%^&*()_+=-{}[]|:;<>?/.",$,0123456789,"change for new change","Change our locale from $ to ¥ in","Chúc mừng năm mới 2021","In Bulgarian it is desirable","Tôi không biết"} | {"1969-12-22 20:42:30+00","1970-01-01 00:00:00+00","2020-01-06 01:00:00+00","2020-01-07 01:00:00+00","2020-01-08 01:00:00+00","2020-01-11 01:00:00+00","2020-01-12 01:00:00+00","2020-01-13 01:00:00+00"} (1 row) --Testcase 105: @@ -1498,23 +1501,23 @@ SELECT stddev((fields->>'c3')::bigint), stddev((fields->>'c3')::bigint ORDER BY --Testcase 116: SELECT sqrt(abs((fields->>'c3')::bigint)), sqrt(abs((fields->>'c3')::bigint)) FROM ( SELECT * FROM sctbl3 WHERE (fields->>'c3')::bigint>-1000 AND (fields->>'c3')::bigint<1000 ) AS sctbl3 ORDER BY 1 ASC,tags->>'t1' DESC; - sqrt | sqrt -------------------+------------------ - 0 | 0 - 0 | 0 - 1 | 1 - 1 | 1 - 1 | 1 - 1.4142135623731 | 1.4142135623731 - 1.4142135623731 | 1.4142135623731 - 1.73205080756888 | 1.73205080756888 - 1.73205080756888 | 1.73205080756888 - 2 | 2 - 2 | 2 - 2.23606797749979 | 2.23606797749979 - 2.23606797749979 | 2.23606797749979 - 5.65685424949238 | 5.65685424949238 - 5.8309518948453 | 5.8309518948453 + sqrt | sqrt +--------------------+-------------------- + 0 | 0 + 0 | 0 + 1 | 1 + 1 | 1 + 1 | 1 + 1.4142135623730951 | 1.4142135623730951 + 1.4142135623730951 | 1.4142135623730951 + 1.7320508075688772 | 1.7320508075688772 + 1.7320508075688772 | 1.7320508075688772 + 2 | 2 + 2 | 2 + 2.23606797749979 | 2.23606797749979 + 2.23606797749979 | 2.23606797749979 + 5.656854249492381 | 5.656854249492381 + 5.830951894845301 | 5.830951894845301 (15 rows) --Testcase 117: @@ -1558,7 +1561,7 @@ SELECT tags->>'t1' t1, (fields->>'c1')::bool c1, fields->>'c2' c2 FROM ( SELECT (2 rows) --Testcase 120: -SELECT (fields->>'c1')::bool c1, fields->>'c2' c2, (fields->>'c4')::double precision c4 FROM ( SELECT * FROM sctbl3 WHERE (fields->>'c3')::bigint>-1000 AND (fields->>'c3')::bigint<1000 ) AS tb3 WHERE fields->>'c2'=ANY (ARRAY(SELECT fields->>'c2' FROM sctbl3 WHERE (fields->>'c3')::bigint%2=0)) ORDER BY tags->>'t1'; +SELECT (fields->>'c1')::bool c1, fields->>'c2' c2, (fields->>'c4')::double precision c4 FROM ( SELECT * FROM sctbl3 WHERE (fields->>'c3')::bigint>-1000 AND (fields->>'c3')::bigint<1000 ) AS tb3 WHERE fields->>'c2'=ANY (ARRAY(SELECT fields->>'c2' FROM sctbl3 WHERE (fields->>'c3')::bigint%2=0)) ORDER BY (tags->>'t1' COLLATE "en_US"); c1 | c2 | c4 ----+-----------------------------------------------------------------------+--------------- t | Tôi không biết | 78.14 @@ -1690,7 +1693,7 @@ SELECT * FROM view_sctbl3 WHERE (fields->>'c3')::bigint NOT IN (-1,1,0,2,-2) ORD -- Select many target aggregate in one query and combine with (fields->>'c1')::bool --Testcase 136: -SELECT upper(fields->>'c2'), lower(fields->>'c2'), lower(tags->>'t1') FROM sctbl3 ORDER BY 1 ASC,2 DESC,3; +SELECT upper(fields->>'c2' COLLATE "en_US"), lower(fields->>'c2' COLLATE "en_US"), lower(tags->>'t1') FROM sctbl3 ORDER BY 1 ASC,2 DESC,3; upper | lower | lower ----------------------------------------------------------------------------------+----------------------------------------------------------------------------------+------------- `~!@#$%^&*()_+=-{}[]|:;<>?/. | `~!@#$%^&*()_+=-{}[]|:;<>?/. | @@ -1723,7 +1726,7 @@ SELECT max(time), min((fields->>'c3')::bigint), sum((fields->>'c3')::bigint ORDE (2 rows) --Testcase 138: -SELECT (fields->>'c3')::bigint*(random()<=1)::int, (random()<=1)::int*(25-10)+10 FROM sctbl3 ORDER BY tags->>'t1' ASC,fields->>'c1' DESC; +SELECT (fields->>'c3')::bigint*(random()<=1)::int, (random()<=1)::int*(25-10)+10 FROM sctbl3 ORDER BY (tags->>'t1' COLLATE "en_US") ASC,fields->>'c1' DESC; ?column? | ?column? --------------+---------- 32 | 25 @@ -1819,7 +1822,7 @@ SELECT count((fields->>'c3')::bigint), max((fields->>'c3')::bigint), sum((fields SELECT array_agg((fields->>'c3')::bigint-(fields->>'c3')::bigint-(fields->>'c3')::bigint), array_agg((fields->>'c3')::bigint/(fields->>'c3')::bigint*(fields->>'c3')::bigint), array_agg(((fields->>'c3')::bigint+(fields->>'c3')::bigint/(fields->>'c3')::bigint)*-1000), array_agg((fields->>'c3')::bigint*(fields->>'c3')::bigint-(fields->>'c3')::bigint), array_agg(((fields->>'c3')::bigint-(fields->>'c3')::bigint+(fields->>'c3')::bigint)+9999999999999.998) from sctbl3 GROUP BY (fields->>'c3')::bigint, (fields->>'c3')::bigint ORDER BY 1, 2, 3, 4, 5; ERROR: bigint out of range --Testcase 146: -SELECT avg((fields->>'c3')::bigint-(fields->>'c3')::bigint-(fields->>'c3')::bigint)-0.567-avg((fields->>'c3')::bigint/3+(fields->>'c3')::bigint)+17.55435, avg((fields->>'c3')::bigint+(fields->>'c3')::bigint/((fields->>'c3')::bigint+45))- -9.5+2*avg((fields->>'c3')::bigint), avg((fields->>'c3')::bigint/((fields->>'c3')::bigint-10.2)*(fields->>'c3')::bigint)+0.567+avg((fields->>'c3')::bigint)*4.5+(fields->>'c3')::bigint, avg((fields->>'c3')::bigint+(fields->>'c3')::bigint/((fields->>'c3')::bigint+5.6))+100-(fields->>'c3')::bigint from sctbl3 WHERE fields->>'c2'<='$' AND (fields->>'c3')::bigint<>-5 AND (fields->>'c3')::bigint<>10.746 GROUP BY fields->>'c3', fields->>'c3' ORDER BY 1,2,3,4 limit 5; +SELECT avg((fields->>'c3')::bigint-(fields->>'c3')::bigint-(fields->>'c3')::bigint)-0.567-avg((fields->>'c3')::bigint/3+(fields->>'c3')::bigint)+17.55435, avg((fields->>'c3')::bigint+(fields->>'c3')::bigint/((fields->>'c3')::bigint+45))- -9.5+2*avg((fields->>'c3')::bigint), avg((fields->>'c3')::bigint/((fields->>'c3')::bigint-10.2)*(fields->>'c3')::bigint)+0.567+avg((fields->>'c3')::bigint)*4.5+(fields->>'c3')::bigint, avg((fields->>'c3')::bigint+(fields->>'c3')::bigint/((fields->>'c3')::bigint+5.6))+100-(fields->>'c3')::bigint from sctbl3 WHERE fields->>'c2'<='$' COLLATE "en_US" AND (fields->>'c3')::bigint<>-5 AND (fields->>'c3')::bigint<>10.746 GROUP BY fields->>'c3', fields->>'c3' ORDER BY 1,2,3,4 limit 5; ?column? | ?column? | ?column? | ?column? ----------------------+------------------------+------------------------------------+-------------------------- 5.9873500000000000 | 24.5000000000000000 | 23.25930769230769230770 | 100.47169811320754716981 @@ -1845,9 +1848,13 @@ SELECT count(*)-5.6, 2*count(*), 10.2/count(*)+count(*)-(fields->>'c3')::bigint -- ------------------------------Update data: add 5 tags and 20 fields----------------------------------------- -- Update data :RECOVER_INIT_MULTILEY_ADD_5TAG_20FIELDS; +--Testcase 205: drop view if exists view_sctbl3 ; +--Testcase 206: drop foreign table if exists sctbl3; +--Testcase 207: CREATE FOREIGN TABLE sctbl3 (time timestamp with time zone, tags jsonb OPTIONS(tags 'true'), fields jsonb OPTIONS(fields 'true')) SERVER influxdb_svr OPTIONS (schemaless 'true', tags 't1, t2, t3, t4, t5'); +--Testcase 208: create view view_sctbl3 as select * from sctbl3 where ((fields->>'c20')::int != 6789 OR (fields->>'c19')::double precision != -1); -- Update data: add 5 tags and 20 fields -- Select all data with condition and combine clause @@ -1967,7 +1974,7 @@ SELECT max(tags->>'t4'), max(tags->>'t5'), max((fields->>'c3')::bigint), count(* (2 rows) --Testcase 156: -SELECT max(fields->>'c2'), min((fields->>'c3')::bigint), max((fields->>'c3')::bigint), max((fields->>'c11')::bigint), max((fields->>'c6')::double precision), max((fields->>'c7')::double precision), max((fields->>'c8')::float), max (20) from sctbl3 GROUP BY fields->>'c3' ORDER BY (fields->>'c3')::bigint; +SELECT max(fields->>'c2' COLLATE "en_US"), min((fields->>'c3')::bigint), max((fields->>'c3')::bigint), max((fields->>'c11')::bigint), max((fields->>'c6')::double precision), max((fields->>'c7')::double precision), max((fields->>'c8')::float), max (20) from sctbl3 GROUP BY fields->>'c3' ORDER BY (fields->>'c3')::bigint; max | min | max | max | max | max | max | max ----------------------------------------------------------------------------------+--------------+--------------+------+-------------+-----------------+---------------+----- ^%(@#%^(@#%&@#)%^)!^%)!)% | -36854775808 | -36854775808 | | | | | 20 @@ -2102,10 +2109,10 @@ SELECT sum((fields->>'c3')::bigint+(fields->>'c3')::bigint ORDER BY (fields->>'c --Testcase 163: SELECT array_agg((fields->>'c3')::bigint/2 ORDER BY (fields->>'c3')::bigint), array_agg(fields->>'c2' ORDER BY fields->>'c2'), array_agg(time ORDER BY time), array_agg((fields->>'c6')::double precision+2), array_agg((fields->>'c7')::double precision/10), array_agg((fields->>'c8')::float-2) FROM sctbl3 GROUP BY (fields->>'c17')::bool, (fields->>'c20')::int, (fields->>'c18')::bool, (fields->>'c19')::double precision HAVING (fields->>'c17')::bool != true ORDER BY (fields->>'c20')::int DESC, (fields->>'c19')::double precision, (fields->>'c18')::bool; - array_agg | array_agg | array_agg | array_agg | array_agg | array_agg ------------+--------------+-----------------------------------+--------------+-------------------+--------------------- + array_agg | array_agg | array_agg | array_agg | array_agg | array_agg +-----------+--------------+-----------------------------------+--------------+-------------------+---------------------- {1842904} | {何してるの} | {"1970-04-24 05:54:24.343435+00"} | {748452589} | {-24645544144.1} | {91.147895} - {-49} | {wenzani} | {"1970-04-12 17:40:00+00"} | {2147483649} | {9227203685580.7} | {-2.00000000004785} + {-49} | {wenzani} | {"1970-04-12 17:40:00+00"} | {2147483649} | {9227203685580.7} | {-2.000000000047854} (2 rows) --Testcase 164: @@ -2187,7 +2194,7 @@ SELECT time, fields->>'c2' c2, fields->>'c15' c15, tags->>'t1' t1, (tags->>'t3') (5 rows) --Testcase 172: -SELECT max(time), max(7), max((fields->>'c7')::double precision)+17, max((fields->>'c11')::bigint)+10, max((fields->>'c3')::bigint), max((fields->>'c14')::bigint)/2 FROM ( SELECT * FROM sctbl3 WHERE (fields->>'c3')::bigint>-1000 AND (fields->>'c3')::bigint<1000 ) AS sctbl3 GROUP BY fields->>'c2' ORDER BY fields->>'c2'; +SELECT max(time), max(7), max((fields->>'c7')::double precision)+17, max((fields->>'c11')::bigint)+10, max((fields->>'c3')::bigint), max((fields->>'c14')::bigint)/2 FROM ( SELECT * FROM sctbl3 WHERE (fields->>'c3')::bigint>-1000 AND (fields->>'c3')::bigint<1000 ) AS sctbl3 GROUP BY (fields->>'c2' COLLATE "en_US") ORDER BY (fields->>'c2' COLLATE "en_US"); max | max | ?column? | ?column? | max | ?column? -------------------------------+-----+-----------------+----------+-----+---------- 2020-01-06 01:00:00+00 | 7 | | | -2 | @@ -2212,16 +2219,37 @@ SELECT max(time), max(7), max((fields->>'c7')::double precision)+17, max((fields --Testcase 173: SELECT stddev((fields->>'c3')::bigint), stddev((fields->>'c3')::bigint ORDER BY (fields->>'c3')::bigint), stddev((fields->>'c11')::bigint), stddev((fields->>'c14')::bigint), stddev((fields->>'c19')::double precision) FROM ( SELECT * FROM sctbl3 WHERE (fields->>'c3')::bigint>-1000 AND (fields->>'c3')::bigint<1000 ) AS sctbl3 GROUP BY time ORDER BY 1 ASC,2 DESC; -ERROR: value out of range: overflow + stddev | stddev | stddev | stddev | stddev +--------+--------+--------+--------+-------- + | | | | + | | | | + | | | | + | | | | + | | | | + | | | | + | | | | + | | | | + | | | | + | | | | + | | | | + | | | | + | | | | + | | | | + | | | | + | | | | + | | | | + | | | | +(18 rows) + --Testcase 174: SELECT sqrt(abs((fields->>'c3')::bigint)), sqrt(abs((fields->>'c3')::bigint)), sqrt(abs((fields->>'c11')::bigint)), sqrt(abs((fields->>'c20')::int)) FROM ( SELECT * FROM sctbl3 WHERE tags->>'t5' LIKE '111111' ) AS sctbl3 ORDER BY 1 ASC,2 DESC; - sqrt | sqrt | sqrt | sqrt -------------------+------------------+------------------+------------------ - 19197.5469005808 | 19197.5469005808 | 8.83176086632785 | 8.83176086632785 + sqrt | sqrt | sqrt | sqrt +-------------------+-------------------+-------------------+------------------- + 19197.54690058081 | 19197.54690058081 | 8.831760866327848 | 8.831760866327848 (1 row) --Testcase 175: -SELECT * FROM ( SELECT tags->>'t1' t1, (tags->>'t2')::int t2, (tags->>'t3')::double precision t3, tags->>'t4' t4, tags->>'t5' t5, fields->>'c2' c2, (fields->>'c3')::bigint c3 FROM sctbl3 WHERE (fields->>'c13')::int>-1000 OR (fields->>'c14')::bigint<1000 ) AS tb3 WHERE c3 <-1 AND c2 > 'KissMe' ORDER BY 1 DESC,2 ASC,3 DESC,4,5 LIMIT 5 OFFSET 0; +SELECT * FROM ( SELECT tags->>'t1' t1, (tags->>'t2')::int t2, (tags->>'t3')::double precision t3, tags->>'t4' t4, tags->>'t5' t5, fields->>'c2' c2, (fields->>'c3')::bigint c3 FROM sctbl3 WHERE (fields->>'c13')::int>-1000 OR (fields->>'c14')::bigint<1000 ) AS tb3 WHERE c3 <-1 AND c2 > 'KissMe' ORDER BY t1 COLLATE "en_US" DESC,2 ASC,3 DESC,4,5 LIMIT 5 OFFSET 0; t1 | t2 | t3 | t4 | t5 | c2 | c3 --------+----+---------+-----+----------------+------------+------------ 'tag2' | 2 | 741.14 | 4i | 'THisiSString' | wenzani | -98 @@ -2308,7 +2336,7 @@ SELECT bit_or((fields->>'c3')::bigint), bit_or((fields->>'c3')::bigint/2), (tags (2 rows) --Testcase 185: -SELECT bool_and((fields->>'c11')::bigint>0), bool_and((fields->>'c13')::int<0), bool_and((fields->>'c3')::bigint<(fields->>'c3')::bigint), bool_and((fields->>'c7')::double precision>=(fields->>'c8')::float) FROM view_sctbl3 GROUP BY time, tags->>'t1', tags->>'t2',tags->>'t3' ORDER BY tags->>'t1' DESC,(tags->>'t2')::float, (tags->>'t3')::double precision; +SELECT bool_and((fields->>'c11')::bigint>0), bool_and((fields->>'c13')::int<0), bool_and((fields->>'c3')::bigint<(fields->>'c3')::bigint), bool_and((fields->>'c7')::double precision>=(fields->>'c8')::float) FROM view_sctbl3 GROUP BY time, (tags->>'t1' COLLATE "en_US"), tags->>'t2',tags->>'t3' ORDER BY (tags->>'t1' COLLATE "en_US") DESC,(tags->>'t2')::float, (tags->>'t3')::double precision; bool_and | bool_and | bool_and | bool_and ----------+----------+----------+---------- t | f | f | f @@ -2360,7 +2388,7 @@ SELECT time,tags->>'t1' t1,(tags->>'t2')::int t2,(tags->>'t3')::double precision -- Select many target aggregate in one query and combine with condition --Testcase 191: -SELECT count((fields->>'c1')::bool)+count(fields->>'c2')-2*count((fields->>'c3')::bigint), count((fields->>'c3')::bigint)/count((fields->>'c5')::bool)-(fields->>'c3')::bigint, count((fields->>'c11')::bigint-(fields->>'c14')::bigint), 2*count(*) from sctbl3 GROUP BY fields->>'c5', fields->>'c3', fields->>'c1', fields->>'c20', tags->>'t5' order by tags->>'t5', fields->>'c1', (fields->>'c20')::int limit 1; +SELECT count((fields->>'c1')::bool)+count(fields->>'c2')-2*count((fields->>'c3')::bigint), count((fields->>'c3')::bigint)/count((fields->>'c5')::bool)-(fields->>'c3')::bigint, count((fields->>'c11')::bigint-(fields->>'c14')::bigint), 2*count(*) from sctbl3 GROUP BY fields->>'c5', fields->>'c3', fields->>'c1', fields->>'c20', (tags->>'t5' COLLATE "en_US") order by (tags->>'t5' COLLATE "en_US"), fields->>'c1', (fields->>'c20')::int limit 1; ?column? | ?column? | count | ?column? ----------+-----------+-------+---------- 0 | 368545808 | 1 | 2 @@ -2398,30 +2426,30 @@ SELECT sum((fields->>'c3')::bigint+(fields->>'c3')::bigint-(fields->>'c3')::bigi --Testcase 195: SELECT sum((fields->>'c14')::bigint+(fields->>'c3')::bigint)-6+sum((fields->>'c11')::bigint), sum((fields->>'c3')::bigint*1.3-(fields->>'c3')::bigint)*9.998-sum((fields->>'c7')::double precision)*4, sum((fields->>'c8')::float-(fields->>'c7')::double precision/4)*-9.5-(fields->>'c3')::bigint, sum((fields->>'c20')::int-(fields->>'c3')::bigint-(fields->>'c16')::int)/17.55435+(fields->>'c3')::bigint, sum((fields->>'c3')::bigint+(fields->>'c3')::bigint+(fields->>'c3')::bigint)*6-(fields->>'c3')::bigint-(fields->>'c3')::bigint from sctbl3 GROUP BY fields->>'c13', fields->>'c14', fields->>'c16', fields->>'c11', fields->>'c3', fields->>'c3' ORDER BY 1,2,3,4,5; - ?column? | ?column? | ?column? | ?column? | ?column? -------------+-------------------+-------------------+-------------------------+--------------- - -348845790 | -22255731678509.5 | 13214052889115 | -403832915.779305414328 | -5896732912 - 252369 | -29698616 | 17633543.749335 | -6467.3428523414424345 | 0 - 19654506 | -369088147423522 | 219146087532640 | -18410.782871481997 | -1568 - 20112568 | 128147419104870 | -76087529343111.1 | -6514.8139862769057242 | 8736 - 23645228 | 985832820976.515 | -585335360115.28 | 3475241.844032960491 | 58972928 - | | | | -589676412928 - | | | | -589676412912 - | | | | -80 - | | | | -64 - | | | | -48 - | | | | -32 - | | | | -16 - | | | | 0 - | | | | 32 - | | | | 34 - | | | | 48 - | | | | 64 - | | | | 80 - | | | | 512 - | | | | 544 - | | | | 589676412896 - | | | | 589676412912 + ?column? | ?column? | ?column? | ?column? | ?column? +------------+---------------------+--------------------+-------------------------+--------------- + -348845790 | -22255731678509.516 | 13214052889115.035 | -403832915.779305414328 | -5896732912 + 252369 | -29698616 | 17633543.749335 | -6467.3428523414424345 | 0 + 19654506 | -369088147423521.94 | 219146087532639.62 | -18410.782871481997 | -1568 + 20112568 | 128147419104869.67 | -76087529343111.12 | -6514.8139862769057242 | 8736 + 23645228 | 985832820976.5153 | -585335360115.28 | 3475241.844032960491 | 58972928 + | | | | -589676412928 + | | | | -589676412912 + | | | | -80 + | | | | -64 + | | | | -48 + | | | | -32 + | | | | -16 + | | | | 0 + | | | | 32 + | | | | 34 + | | | | 48 + | | | | 64 + | | | | 80 + | | | | 512 + | | | | 544 + | | | | 589676412896 + | | | | 589676412912 (22 rows) --Testcase 196: @@ -2465,20 +2493,20 @@ SELECT variance((fields->>'c3')::bigint+(fields->>'c3')::bigint)+(fields->>'c3') --Testcase 198: SELECT sqrt(abs((fields->>'c3')::bigint*5)) + sqrt(abs((fields->>'c3')::bigint+6)), sqrt(abs((fields->>'c3')::bigint)+5)+(fields->>'c3')::bigint, 4*sqrt(abs((fields->>'c3')::bigint-100))-(fields->>'c3')::bigint from sctbl3 WHERE (fields->>'c3')::bigint>'c3')::bigint FROM sctbl3 WHERE (fields->>'c3')::bigint>0) ORDER BY 1, 2, 3; - ?column? | ?column? | ?column? -------------------+-------------------+------------------ - 2.44948974278318 | 2.23606797749979 | 40 - 2.44948974278318 | 2.23606797749979 | 40 - 2.44948974278318 | 2.23606797749979 | 40 - 4.47213595499958 | 1.44948974278318 | 41.1995024844836 - 5.16227766016838 | 0.645751311064591 | 42.3980197534483 - 5.60503415377629 | -0.17157287525381 | 43.5955662603689 - 5.88634951737267 | -1 | 44.7921561087423 - 6 | -1.83772233983162 | 45.9878030638384 - 31.7276066678041 | -87.8511084349078 | 154.284989117881 - 62124.5666152499 | -368526609.452969 | 368622597.19802 - 621247.312124984 | -36854583831.0228 | 36855543710.9097 - 621247.312133412 | -36854583832.0228 | 36855543711.9097 + ?column? | ?column? | ?column? +--------------------+---------------------+-------------------- + 2.449489742783178 | 2.23606797749979 | 40 + 2.449489742783178 | 2.23606797749979 | 40 + 2.449489742783178 | 2.23606797749979 | 40 + 4.47213595499958 | 1.4494897427831779 | 41.19950248448356 + 5.16227766016838 | 0.6457513110645907 | 42.39801975344831 + 5.605034153776295 | -0.1715728752538097 | 43.59556626036888 + 5.8863495173726745 | -1 | 44.792156108742276 + 6 | -1.8377223398316205 | 45.98780306383839 + 31.727606667804093 | -87.85110843490779 | 154.28498911788114 + 62124.56661524995 | -368526609.4529692 | 368622597.19802034 + 621247.3121249836 | -36854583831.02283 | 36855543710.90968 + 621247.312133412 | -36854583832.02282 | 36855543711.9097 (12 rows) --Testcase 199: @@ -2546,8 +2574,12 @@ SELECT (fields->>'c3')::bigint-30, (fields->>'c3')::bigint-10, sum((fields->>'c3 (23 rows) -- Clean +--Testcase 209: DROP FOREIGN TABLE sctbl3 CASCADE; NOTICE: drop cascades to view view_sctbl3 +--Testcase 210: DROP USER MAPPING FOR CURRENT_USER SERVER influxdb_svr; +--Testcase 211: DROP SERVER influxdb_svr CASCADE; +--Testcase 212: DROP EXTENSION influxdb_fdw; diff --git a/expected/11.17/schemaless/add_tags.out b/expected/16.0/schemaless/add_tags.out similarity index 91% rename from expected/11.17/schemaless/add_tags.out rename to expected/16.0/schemaless/add_tags.out index 501783e..8382225 100644 --- a/expected/11.17/schemaless/add_tags.out +++ b/expected/16.0/schemaless/add_tags.out @@ -61,17 +61,17 @@ select bool_and((fields->>'sig3')::double precision > -10), string_agg('446757sv (1 row) --Testcase 10: -select count(fields->>'sig1'), stddev((fields->>'sig3')::double precision + 333), min(fields->>'sig2') from sctbl4; - count | stddev | min --------+------------------+---------- - 9 | 145.854760330649 | システム +select count(fields->>'sig1'), stddev((fields->>'sig3')::double precision + 333), min(fields->>'sig2' COLLATE "en_US") from sctbl4; + count | stddev | min +-------+--------------------+---------- + 9 | 145.85476033064916 | システム (1 row) --Testcase 11: select bool_or((fields->>'sig1')::bigint >= 1234), stddev((fields->>'sig1')::bigint), stddev((fields->>'sig3')::double precision) from sctbl4; - bool_or | stddev | stddev ----------+-------------------+------------------ - t | 4590.734630148474 | 145.854760330649 + bool_or | stddev | stddev +---------+-------------------+-------------------- + t | 4590.734630148474 | 145.85476033064916 (1 row) --------------------------------------------------------------------------------------- Update: Add 1 tag -------------------------------------------------------------------------------------------------------------- @@ -84,35 +84,35 @@ CREATE FOREIGN TABLE sctbl4 (tags jsonb OPTIONS(tags 'true'), fields jsonb OPTIO -- Select all data with aggregate --Testcase 14: select avg((fields->>'sig3')::double precision), bool_and(fields->>'sig2' != '%a%'), count(*) from sctbl4 GROUP BY tags->>'sid' ORDER BY tags->>'sid'; - avg | bool_and | count -------------------+----------+------- - 2516968931 | t | 3 - 566298823 | t | 2 - -12 | t | 2 - 4917871303.5 | t | 2 - 159.888888888889 | t | 9 + avg | bool_and | count +--------------------+----------+------- + 2516968931 | t | 3 + 566298823 | t | 2 + -12 | t | 2 + 4917871303.5 | t | 2 + 159.88888888888889 | t | 9 (5 rows) --Testcase 15: select bool_or((fields->>'sig1')::bigint >= 1234), stddev((fields->>'sig1')::bigint), avg((fields->>'sig3')::double precision) from sctbl4 GROUP BY tags->>'sid' ORDER BY tags->>'sid'; - bool_or | stddev | avg ----------+-------------------+------------------ - t | 6603.097757870922 | 2516968931 - t | 1237.436867076458 | 566298823 - t | 6710.443353460336 | -12 - f | 579.827560572969 | 4917871303.5 - t | 4590.734630148474 | 159.888888888889 + bool_or | stddev | avg +---------+-------------------+-------------------- + t | 6603.097757870922 | 2516968931 + t | 1237.436867076458 | 566298823 + t | 6710.443353460336 | -12 + f | 579.827560572969 | 4917871303.5 + t | 4590.734630148474 | 159.88888888888889 (5 rows) --Testcase 16: select max(time), avg((fields->>'sig3')::double precision), sum((fields->>'sig1')::bigint) from sctbl4 GROUP BY tags->>'sid' ORDER BY tags->>'sid'; - max | avg | sum ----------------------+------------------+------- - 1970-01-01 02:22:58 | 2516968931 | 13560 - 1970-01-07 01:54:05 | 566298823 | 2490 - 1970-01-01 12:05:46 | -12 | 9030 - 1970-01-01 14:36:06 | 4917871303.5 | 140 - 1970-10-28 16:19:12 | 159.888888888889 | 25220 + max | avg | sum +---------------------+--------------------+------- + 1970-01-01 02:22:58 | 2516968931 | 13560 + 1970-01-07 01:54:05 | 566298823 | 2490 + 1970-01-01 12:05:46 | -12 | 9030 + 1970-01-01 14:36:06 | 4917871303.5 | 140 + 1970-10-28 16:19:12 | 159.88888888888889 | 25220 (5 rows) --Testcase 17: @@ -128,58 +128,58 @@ select string_agg(fields->>'sig2', 'ASDFG!@#$%zxc'), count(time), avg((fields->> --Testcase 18: select sum((fields->>'sig3')::double precision), stddev((fields->>'sig3')::double precision), min((fields->>'sig1')::bigint) from sctbl4 GROUP BY tags->>'sid' ORDER BY 1, 2, 3; - sum | stddev | min -------------+------------------+------ - -24 | 16.9705627484771 | -230 - 1439 | 145.854760330649 | -340 - 1132597646 | 646026566.50168 | 370 - 7550906793 | 2203533896.7414 | 190 - 9835742607 | 6941647940.73026 | -340 + sum | stddev | min +------------+--------------------+------ + -24 | 16.97056274847714 | -230 + 1439 | 145.85476033064916 | -340 + 1132597646 | 646026566.5016799 | 370 + 7550906793 | 2203533896.7414036 | 190 + 9835742607 | 6941647940.73026 | -340 (5 rows) -- Select aggregate contain expression --Testcase 19: select bool_or(((fields->>'sig1')::bigint + (fields->>'sig3')::double precision - 9999) > 0), stddev((fields->>'sig3')::double precision / (fields->>'sig1')::bigint + 3291), stddev((fields->>'sig3')::double precision * 12.3 - (fields->>'sig1')::bigint) from sctbl4 GROUP BY tags->>'sid' ORDER BY tags->>'sid'; - bool_or | stddev | stddev ----------+-------------------+------------------ - t | 10395428.6492871 | 27103463254.8422 - t | 132004.122810283 | 7946125530.5338 - f | 0.0018310546875 | 6919.1812752666 - t | 14495110.0813057 | 85382269091.1546 - t | 0.618104797597138 | 5676.87270740776 + bool_or | stddev | stddev +---------+-----------------------+------------------- + t | 10395428.649287097 | 27103463254.84223 + t | 132004.1228102828 | 7946125530.533796 + f | 0.0018326741624507942 | 6919.181275266606 + t | 14495110.081305722 | 85382269091.15465 + t | 0.6181047995469497 | 5676.87270740776 (5 rows) --Testcase 20: select avg((fields->>'sig3')::double precision * (fields->>'sig1')::bigint / 34241), bool_and(fields->>'sig2' != '%c'), bool_and((fields->>'sig4')::boolean AND true OR true) from sctbl4 GROUP BY tags->>'sid' ORDER BY tags->>'sid'; - avg | bool_and | bool_and --------------------+----------+---------- - 489923530.058702 | t | t - 32263969.5068777 | t | t - -3.24523232382232 | t | t - 68827732.4599165 | t | t - 4.71293348779403 | t | t + avg | bool_and | bool_and +---------------------+----------+---------- + 489923530.0587015 | t | t + 32263969.506877717 | t | t + -3.2452323238223184 | t | t + 68827732.45991647 | t | t + 4.712933487794035 | t | t (5 rows) --Testcase 21: select sum((fields->>'sig3')::double precision * 123.456 + (fields->>'sig1')::bigint), bool_and((fields->>'sig4')::boolean OR false), bool_or((fields->>'sig4')::boolean AND true AND true) from sctbl4 GROUP BY tags->>'sid' ORDER BY tags->>'sid'; - sum | bool_and | bool_or -------------------+----------+--------- - 932204762596.608 | f | t - 139825977474.576 | f | t - 6067.056 | f | f - 1214281439429.79 | f | t - 202873.184 | f | t + sum | bool_and | bool_or +--------------------+----------+--------- + 932204762596.608 | f | t + 139825977474.576 | f | t + 6067.0560000000005 | f | f + 1214281439429.792 | f | t + 202873.184 | f | t (5 rows) --Testcase 22: select min((fields->>'sig3')::double precision / ((fields->>'sig3')::double precision + 223344)), max((fields->>'sig1')::bigint * (fields->>'sig3')::double precision - (fields->>'sig3')::double precision), count(*) from sctbl4 GROUP BY tags->>'sid' ORDER BY tags->>'sid'; - min | max | count ------------------------+----------------+------- - -0.0468726563671816 | 49666316485165 | 3 - 0.997964277529575 | 2167967100091 | 2 - -0.000107469102632993 | -0 | 2 - 0.976755135863558 | 4706825307165 | 2 - -0.000452421800459589 | 1907354 | 9 + min | max | count +-------------------------+----------------+------- + -0.04687265636718164 | 49666316485165 | 3 + 0.9979642775295748 | 2167967100091 | 2 + -0.00010746910263299302 | -0 | 2 + 0.9767551358635582 | 4706825307165 | 2 + -0.00045242180045958885 | 1907354 | 9 (5 rows) --Testcase 23: @@ -196,46 +196,46 @@ select every((fields->>'sig4')::boolean OR (fields->>'sig4')::boolean AND true), -- Select combine-aggregate --Testcase 24: select avg((fields->>'sig3')::double precision) + sum((fields->>'sig3')::double precision) / avg((fields->>'sig1')::bigint), bool_and(fields->>'sig2' != '%a%') AND bool_and((fields->>'sig4')::boolean AND true) AND true , max((fields->>'sig1')::bigint * (fields->>'sig1')::bigint / 0.0001) + min((fields->>'sig3')::double precision / ((fields->>'sig1')::bigint + 99999)) * sum((fields->>'sig1')::bigint * (fields->>'sig1')::bigint - (fields->>'sig3')::double precision) from sctbl4 GROUP BY tags->>'sid' ORDER BY tags->>'sid'; - ?column? | ?column? | ?column? --------------------+----------+------------------- - 2518639485.60022 | f | 1469675109817.68 - 567208539.984739 | f | -1185515320619.67 - -12.0053156146179 | f | 857475981152.925 - 5058381912.17143 | f | -923903585522.532 - 160.402409903956 | f | 1468943784459.32 + ?column? | ?column? | ?column? +--------------------+----------+--------------------- + 2518639485.600221 | f | 1469675109817.6772 + 567208539.984739 | f | -1185515320619.6707 + -12.00531561461794 | f | 857475981152.9249 + 5058381912.171429 | f | -923903585522.5319 + 160.40240990395628 | f | 1468943784459.3203 (5 rows) --Testcase 25: select stddev((fields->>'sig3')::double precision * 0.0001 - (fields->>'sig1')::bigint) + min((fields->>'sig3')::double precision / ((fields->>'sig1')::bigint + 3.344)) * stddev((fields->>'sig1')::bigint * (fields->>'sig1')::bigint - (fields->>'sig3')::double precision), bool_or((fields->>'sig3')::double precision / (fields->>'sig1')::bigint < -10) OR bool_or((fields->>'sig4')::boolean OR true OR false) AND bool_and(fields->>'sig2' != '%c'), string_agg(fields->>'sig2', '恨挫') from sctbl4 GROUP BY tags->>'sid' ORDER BY tags->>'sid'; - ?column? | ?column? | string_agg --------------------+----------+------------------------------------------------------------------------------------------------------------------------------------------------------- - -17175771729.8977 | t | 012002'akewo02恨挫aoaowejf恨挫システムGUIソフトウエア - 188553934054511 | t | g029012恨挫BAEFOAWJ#AWEK - -150283.367427508 | t | インターフェース設計検討資料恨挫C)@maEFJAe=3kake - -193510317626755 | t | +!2-3-12030_!@#!)~_#@%)恨挫装置開発機能仕 - -24144718.9596548 | t | 装置開発機能仕恨挫設計 検討資料恨挫+!2-3-12030_!@#!)~_#@%)恨挫aoao wejf恨挫g029012恨挫システム恨挫012002'akewo02恨挫BAEFOAWJ#AWEK恨挫C)@maEFJAe=3kake + ?column? | ?column? | string_agg +---------------------+----------+------------------------------------------------------------------------------------------------------------------------------------------------------- + -17175771729.897675 | t | 012002'akewo02恨挫aoaowejf恨挫システムGUIソフトウエア + 188553934054511.12 | t | g029012恨挫BAEFOAWJ#AWEK + -150283.36742750753 | t | インターフェース設計検討資料恨挫C)@maEFJAe=3kake + -193510317626754.6 | t | +!2-3-12030_!@#!)~_#@%)恨挫装置開発機能仕 + -24144718.959654775 | t | 装置開発機能仕恨挫設計 検討資料恨挫+!2-3-12030_!@#!)~_#@%)恨挫aoao wejf恨挫g029012恨挫システム恨挫012002'akewo02恨挫BAEFOAWJ#AWEK恨挫C)@maEFJAe=3kake (5 rows) --Testcase 26: select max((fields->>'sig1')::bigint) * max((fields->>'sig3')::double precision) + sum((fields->>'sig1')::bigint), stddev((fields->>'sig1')::bigint) * avg((fields->>'sig3')::double precision) / avg((fields->>'sig1')::bigint), sum((fields->>'sig3')::double precision) + stddev((fields->>'sig3')::double precision) - count((fields->>'sig4')::boolean) from sctbl4 GROUP BY tags->>'sid' ORDER BY tags->>'sid'; - ?column? | ?column? | ?column? -----------------+-------------------+------------------- - 49670414717760 | 3676945111.70727 | 9754440686.7414 - 2168990211170 | 562858667.760808 | 1778624210.50168 - 9030 | -17.8350653912567 | -9.02943725152286 - 4716651664940 | 40735961730.2887 | 16777390545.7303 - 3770300 | 261.937634130993 | 1575.85476033065 + ?column? | ?column? | ?column? +----------------+---------------------+-------------------- + 49670414717760 | 3676945111.7072725 | 9754440686.741404 + 2168990211170 | 562858667.7608076 | 1778624210.50168 + 9030 | -17.835065391256705 | -9.029437251522861 + 4716651664940 | 40735961730.28875 | 16777390545.730259 + 3770300 | 261.9376341309934 | 1575.8547603306492 (5 rows) --Testcase 27: select count(fields->>'sig2') * count(fields->>'sig4') / min((fields->>'sig1')::bigint), stddev((fields->>'sig1')::bigint) - count(fields->>'sig2') * sum((fields->>'sig1')::bigint), avg((fields->>'sig3')::double precision) - avg((fields->>'sig1')::bigint) * sum((fields->>'sig1')::bigint) from sctbl4 GROUP BY tags->>'sid' ORDER BY tags->>'sid'; - ?column? | ?column? | ?column? -----------+----------------------+------------------- - 0 | -34076.902242129078 | 2455677731 - 0 | -3742.563132923542 | 563198773 - 0 | -11349.556646539664 | -40770462 - 0 | 299.827560572969 | 4917861503.5 - 0 | -222389.265369851526 | -70671884.5555556 + ?column? | ?column? | ?column? +----------+----------------------+-------------------- + 0 | -34076.902242129078 | 2455677731 + 0 | -3742.563132923542 | 563198773 + 0 | -11349.556646539664 | -40770462 + 0 | 299.827560572969 | 4917861503.5 + 0 | -222389.265369851526 | -70671884.55555555 (5 rows) -- Select with WHERE multi-condition @@ -261,12 +261,12 @@ select bool_and((fields->>'sig3')::double precision >= 1.6789), string_agg('っ --Testcase 30: select avg((fields->>'sig3')::double precision), count(*), count(fields->>'sig2') from sctbl4 WHERE (fields->>'sig4')::boolean = true OR time = '2020-01-09 01:00:00+00' AND (fields->>'sig3')::double precision != 0 GROUP BY tags->>'sid' ORDER BY tags->>'sid'; - avg | count | count -------------------+-------+------- - 4098219035 | 1 | 1 - 109489057 | 1 | 1 - 9384972 | 1 | 1 - 68.6666666666667 | 3 | 3 + avg | count | count +-------------------+-------+------- + 4098219035 | 1 | 1 + 109489057 | 1 | 1 + 9384972 | 1 | 1 + 68.66666666666667 | 3 | 3 (4 rows) --Testcase 31: @@ -300,20 +300,20 @@ select sum((fields->>'sig1')::bigint + (fields->>'sig1')::bigint * (fields->>'si --Testcase 34: select string_agg(fields->>'sig2' || (fields->>'sig2')::text, fields->>'sig2' || '!@#$%^&*'), every((fields->>'sig4')::boolean OR true AND false), stddev((fields->>'sig3')::double precision - (fields->>'sig1')::bigint / (fields->>'sig1')::bigint) from sctbl4 WHERE (fields->>'sig3')::double precision <= 999999999 GROUP BY tags->>'sid',fields->>'sig4' HAVING (fields->>'sig4')::boolean <> false ORDER BY tags->>'sid' LIMIT 5 OFFSET 1; - string_agg | every | stddev -----------------------------------------------------------------------------------------------+-------+------------------ - 装置開発機能仕装置開発機能仕 | t | - 装置開発機能仕装置開発機能仕aoao wejf!@#$%^&*aoao wejfaoao wejfg029012!@#$%^&*g029012g029012 | t | 212.490784113884 + string_agg | every | stddev +----------------------------------------------------------------------------------------------+-------+------------------- + 装置開発機能仕装置開発機能仕 | t | + 装置開発機能仕装置開発機能仕aoao wejf!@#$%^&*aoao wejfaoao wejfg029012!@#$%^&*g029012g029012 | t | 212.4907841138842 (2 rows) --Testcase 35: select stddev((fields->>'sig3')::double precision * 0.416754 + (fields->>'sig1')::bigint), min((fields->>'sig3')::double precision / ((fields->>'sig1')::bigint + 3.344)), stddev((fields->>'sig1')::bigint * (fields->>'sig1')::bigint - (fields->>'sig3')::double precision) from sctbl4 WHERE (fields->>'sig1')::bigint >= -1555.555 GROUP BY tags->>'sid',fields->>'sig4' HAVING (fields->>'sig4')::boolean <> true ORDER BY tags->>'sid' LIMIT 5 OFFSET 1; - stddev | min | stddev -------------------+----------------------+------------------ - | 481838.359210754 | - 6703.37080355266 | -0.00259085703823587 | 60595320.4523096 - | 20329946.4460095 | - 3565.33177691479 | -0.454433149795284 | 34527904.9647854 + stddev | min | stddev +--------------------+------------------------+-------------------- + | 481838.35921075434 | + 6703.370803552657 | -0.0025908570382358683 | 60595320.452309586 + | 20329946.44600947 | + 3565.3317769147857 | -0.4544331497952845 | 34527904.96478543 (4 rows) --Testcase 36: @@ -325,7 +325,7 @@ select bool_or((fields->>'sig3')::double precision / (fields->>'sig1')::bigint > (2 rows) --Testcase 37: -select max (fields->>'sig2' || 'kethattinh' || 'hanoilanhqua'), sum ((fields->>'sig3')::double precision - (fields->>'sig3')::double precision - (fields->>'sig1')::bigint), avg((fields->>'sig1')::bigint + (fields->>'sig1')::bigint + (fields->>'sig3')::double precision) from sctbl4 WHERE (fields->>'sig1')::bigint <= 10000000 GROUP BY tags->>'sid',fields->>'sig2',fields->>'sig4' HAVING fields->>'sig2' IN ('%c%', '%1%') OR fields->>'sig2' LIKE '%a%' ORDER BY tags->>'sid' LIMIT 5 OFFSET 2; +select max (fields->>'sig2' || 'kethattinh' || 'hanoilanhqua'), sum ((fields->>'sig3')::double precision - (fields->>'sig3')::double precision - (fields->>'sig1')::bigint), avg((fields->>'sig1')::bigint + (fields->>'sig1')::bigint + (fields->>'sig3')::double precision) from sctbl4 WHERE (fields->>'sig1')::bigint <= 10000000 GROUP BY tags->>'sid',(fields->>'sig2' COLLATE "en_US"),fields->>'sig4' HAVING (fields->>'sig2' COLLATE "en_US") IN ('%c%', '%1%') OR (fields->>'sig2' COLLATE "en_US") LIKE '%a%' ORDER BY tags->>'sid' LIMIT 5 OFFSET 2; max | sum | avg ----------------------------------------+--------+------- C)@maEFJAe=3kakekethattinhhanoilanhqua | 230 | -460 @@ -352,11 +352,11 @@ select time, tags->>'sname' sname, (fields->>'sig1')::bigint sig1, fields->>'sig --Testcase 39: select time, max(sig1), avg(sig3) from (select time, tags->>'sname' sname, ((fields->>'sig1')::bigint) sig1, fields->>'sig2' sig2, ((fields->>'sig3')::double precision) sig3, (fields->>'sig4')::boolean sig4 from sctbl9 GROUP BY time,tags->>'sname',fields->>'sig1',fields->>'sig2',fields->>'sig3',fields->>'sig4' ORDER BY 1,2,3,4,5,6) AS sctbl9 GROUP BY time; - time | max | avg ----------------------+-------+------ - 1970-01-01 00:00:00 | 12120 | 10.2 - 1970-01-01 00:00:01 | 9260 | 20.5 - 1970-01-01 00:00:02 | 480 | 30.8 + time | max | avg +---------------------+-------+-------------------- + 1970-01-01 00:00:00 | 12120 | 10.200000000000001 + 1970-01-01 00:00:01 | 9260 | 20.5 + 1970-01-01 00:00:02 | 480 | 30.8 (3 rows) --Testcase 40: @@ -482,7 +482,7 @@ select string_agg(tags->>'sid19', tags->>'sid17'), avg((tags->>'sid3')::bigint), (14 rows) --Testcase 47: -select sum((tags->>'sid3')::bigint), sum((tags->>'sid20')::bigint), bool_and((tags->>'sid5')::boolean != (tags->>'sid6')::boolean) from sctbl4 GROUP BY fields->>'sig2' ORDER BY fields->>'sig2'; +select sum((tags->>'sid3')::bigint), sum((tags->>'sid20')::bigint), bool_and((tags->>'sid5')::boolean != (tags->>'sid6')::boolean) from sctbl4 GROUP BY (fields->>'sig2' COLLATE "en_US") ORDER BY (fields->>'sig2' COLLATE "en_US"); sum | sum | bool_and ------+----------+---------- 7663 | 8888888 | t @@ -528,7 +528,7 @@ select stddev((tags->>'sid20')::bigint), avg((tags->>'sid2')::bigint order by (t (22 rows) --Testcase 49: -select every((tags->>'sid11')::boolean = (tags->>'sid15')::boolean), bool_or((tags->>'sid6')::boolean != (tags->>'sid11')::boolean), count(time) from sctbl4 GROUP BY fields->>'sig2' ORDER BY fields->>'sig2'; +select every((tags->>'sid11')::boolean = (tags->>'sid15')::boolean), bool_or((tags->>'sid6')::boolean != (tags->>'sid11')::boolean), count(time) from sctbl4 GROUP BY (fields->>'sig2' COLLATE "en_US") ORDER BY (fields->>'sig2' COLLATE "en_US"); every | bool_or | count -------+---------+------- f | f | 2 @@ -688,14 +688,14 @@ select stddev((tags->>'sid12')::double precision), stddev((tags->>'sid13')::doub -- Select aggregate contain expression --Testcase 59: select max((tags->>'sid2')::bigint / (tags->>'sid3')::bigint + (fields->>'sig3')::double precision), avg((tags->>'sid20')::bigint - (fields->>'sig3')::double precision * (tags->>'sid3')::bigint), sum((tags->>'sid2')::bigint + (fields->>'sig3')::double precision / (tags->>'sid3')::bigint) from sctbl4 GROUP BY tags->>'sid20' ORDER BY (tags->>'sid20')::bigint; - max | avg | sum -----------+------------+------------------ - 2658.2 | -35957.2 | 9655923.00279759 - 127140.3 | 30854.6 | 4830959.27105263 - 755.5 | 8731796.5 | 5637128.00267519 - 583.4 | 12226408.6 | 2462190.00467247 - 600.1 | 14595126.2 | 5061715.00117743 - | | + max | avg | sum +----------+------------+------------------- + 2658.2 | -35957.2 | 9655923.002797587 + 127140.3 | 30854.6 | 4830959.271052632 + 755.5 | 8731796.5 | 5637128.002675192 + 583.4 | 12226408.6 | 2462190.004672469 + 600.1 | 14595126.2 | 5061715.001177431 + | | (6 rows) --Testcase 60: @@ -743,48 +743,48 @@ select every((tags->>'sid6')::boolean = (tags->>'sid15')::boolean), bool_or(tags --Testcase 64: select every((tags->>'sid5')::boolean <> (tags->>'sid6')::boolean), sum((tags->>'sid2')::bigint / (fields->>'sig1')::bigint * (fields->>'sig3')::double precision), string_agg(tags->>'sid9' || (tags->>'sid18')::text, tags->>'sid17' || (tags->>'sid16')::text) from sctbl4 GROUP BY tags->>'sid14' ORDER BY tags->>'sid14'; - every | sum | string_agg --------+-----------+------------------------------------------------------------------------ - t | 96646.2 | 悲观失望希望美丽id1那就是他如何赢得100万美元id1辛辣仇恨挫败悲观情绪id1 - t | 46450.8 | 讨厌生活id2 - t | -216341.2 | 爱情不幸福id3 - t | -147716.4 | 生活无聊id4 - | | + every | sum | string_agg +-------+--------------------+------------------------------------------------------------------------ + t | 96646.2 | 悲观失望希望美丽id1那就是他如何赢得100万美元id1辛辣仇恨挫败悲观情绪id1 + t | 46450.799999999996 | 讨厌生活id2 + t | -216341.2 | 爱情不幸福id3 + t | -147716.4 | 生活无聊id4 + | | (5 rows) --Testcase 65: select min((fields->>'sig1')::bigint * (tags->>'sid20')::bigint - (tags->>'sid13')::double precision), bool_and(tags->>'sid4' != '%c%' AND tags->>'sid4' != '%a%'), max((tags->>'sid3')::bigint - (fields->>'sig3')::double precision + (tags->>'sid12')::double precision) from sctbl4 GROUP BY tags->>'sid13' ORDER BY (tags->>'sid13')::double precision; - min | bool_and | max -------------------+----------+---------------- - -7191568.9871 | t | 10781647646.7 - 2601956.5659 | t | 16802.8 - 177942825098.722 | t | 22220.9 - -4187440117.7 | t | 361645191845.6 - 11110452101.99 | t | 6154356.5 - | | + min | bool_and | max +-------------------+----------+---------------- + -7191568.9871 | t | 10781647646.7 + 2601956.5659 | t | 16802.8 + 177942825098.7216 | t | 22220.9 + -4187440117.7 | t | 361645191845.6 + 11110452101.99 | t | 6154356.5 + | | (6 rows) --Testcase 66: select bool_and((tags->>'sid6')::boolean != false OR (tags->>'sid11')::boolean = true), min((tags->>'sid13')::double precision / (fields->>'sig3')::double precision - (tags->>'sid12')::bigint), avg((tags->>'sid20')::bigint / (tags->>'sid12')::bigint + (tags->>'sid3')::bigint) from sctbl4 GROUP BY tags->>'sid12' ORDER BY (tags->>'sid12')::bigint; - bool_and | min | avg -----------+-------------------+----------------------- - t | -12198.035872549 | 3646.0000000000000000 - t | 1652.07707029703 | 9653.0000000000000000 - f | -6114621.41414634 | 7664.0000000000000000 - t | -10781647134.6323 | 38.0000000000000000 - t | -361645178744.23 | 4366.0000000000000000 - | | + bool_and | min | avg +----------+---------------------+----------------------- + t | -12198.035872549019 | 3646.0000000000000000 + t | 1652.0770702970294 | 9653.0000000000000000 + f | -6114621.414146341 | 7664.0000000000000000 + t | -10781647134.63232 | 38.0000000000000000 + t | -361645178744.2304 | 4366.0000000000000000 + | | (6 rows) --Testcase 67: -select stddev((tags->>'sid13')::double precision + (fields->>'sig1')::bigint * (tags->>'sid2')::bigint), sum((tags->>'sid12')::bigint + (tags->>'sid20')::bigint - (tags->>'sid3')::bigint), string_agg(tags->>'sid7' || '豚は誰も好', 'なぜ18歳で' || (tags->>'sid17')::text) from sctbl4 GROUP BY tags->>'sid8' ORDER BY tags->>'sid8'; - stddev | sum | string_agg -------------------+--------------+------------------------------------------------------------------------- - | 10753 | constraint豚は誰も好 - | 361657498609 | cooperation豚は誰も好 - 44165363438.8025 | 10796365666 | freighter豚は誰も好なぜ18歳で那就是他如何赢得100万美元attract豚は誰も好 - | 15027939 | average豚は誰も好 - | | +select stddev((tags->>'sid13')::double precision + (fields->>'sig1')::bigint * (tags->>'sid2')::bigint), sum((tags->>'sid12')::bigint + (tags->>'sid20')::bigint - (tags->>'sid3')::bigint), string_agg(tags->>'sid7' || '豚は誰も好', 'なぜ18歳で' || (tags->>'sid17')::text) from sctbl4 GROUP BY (tags->>'sid8' COLLATE "en_US") ORDER BY (tags->>'sid8' COLLATE "en_US"); + stddev | sum | string_agg +-------------------+--------------+------------------------------------------------------------------------- + | 10753 | constraint豚は誰も好 + | 361657498609 | cooperation豚は誰も好 + 44165363438.80249 | 10796365666 | freighter豚は誰も好なぜ18歳で那就是他如何赢得100万美元attract豚は誰も好 + | 15027939 | average豚は誰も好 + | | (5 rows) --Testcase 68: @@ -801,7 +801,7 @@ select stddev((tags->>'sid3')::bigint * (tags->>'sid2')::bigint - (tags->>'sid20 -- Select combine-aggregate --Testcase 69: -select stddev((tags->>'sid3')::bigint) + count(tags->>'sid10') + count(tags->>'sid4'), count(time) + count(tags->>'sid1') - sum((tags->>'sid2')::bigint), avg((tags->>'sid3')::bigint) * count(*) + count(tags->>'sid17') from sctbl4 GROUP BY fields->>'sig2' ORDER BY fields->>'sig2'; +select stddev((tags->>'sid3')::bigint) + count(tags->>'sid10') + count(tags->>'sid4'), count(time) + count(tags->>'sid1') - sum((tags->>'sid2')::bigint), avg((tags->>'sid3')::bigint) * count(*) + count(tags->>'sid17') from sctbl4 GROUP BY (fields->>'sig2' COLLATE "en_US") ORDER BY (fields->>'sig2' COLLATE "en_US"); ?column? | ?column? | ?column? ----------+----------+------------------------ | -5637125 | 15327.0000000000000000 @@ -886,7 +886,7 @@ select bool_and(time > '1900-09-09 23:59:00+00') AND bool_and((fields->>'sig4'): (6 rows) --Testcase 76: -select sum((tags->>'sid2')::bigint) + count(tags->>'sid1') - count(tags->>'sid8'), count((fields->>'sig3')::double precision) - count(tags->>'sid9') + count(tags->>'sid17'), string_agg(tags->>'sid19' || 'hf675578ytgu', tags->>'sid17' || (tags->>'sid14')::text) from sctbl4 GROUP BY tags->>'sid8' ORDER BY tags->>'sid8'; +select sum((tags->>'sid2')::bigint) + count(tags->>'sid1') - count(tags->>'sid8'), count((fields->>'sig3')::double precision) - count(tags->>'sid9') + count(tags->>'sid17'), string_agg(tags->>'sid19' || 'hf675578ytgu', tags->>'sid17' || (tags->>'sid14')::text) from sctbl4 GROUP BY (tags->>'sid8' COLLATE "en_US") ORDER BY (tags->>'sid8' COLLATE "en_US"); ?column? | ?column? | string_agg ----------+----------+-------------------------------------------------------------------------------- 9655923 | 1 | 誰が作ったのか誰も質問しませんhf675578ytgu @@ -897,7 +897,7 @@ select sum((tags->>'sid2')::bigint) + count(tags->>'sid1') - count(tags->>'sid8' (5 rows) --Testcase 77: -select sum((tags->>'sid3')::bigint) - avg((tags->>'sid12')::bigint) * count(tags->>'sid9'), bool_and((tags->>'sid11')::boolean) AND bool_and((tags->>'sid20')::bigint >= -16735467) OR every(tags->>'sid16' != 'id3'), sum((tags->>'sid20')::bigint) + avg((tags->>'sid12')::bigint) / count(tags->>'sid19') from sctbl4 GROUP BY fields->>'sig2' ORDER BY fields->>'sig2'; +select sum((tags->>'sid3')::bigint) - avg((tags->>'sid12')::bigint) * count(tags->>'sid9'), bool_and((tags->>'sid11')::boolean) AND bool_and((tags->>'sid20')::bigint >= -16735467) OR every(tags->>'sid16' != 'id3'), sum((tags->>'sid20')::bigint) + avg((tags->>'sid12')::bigint) / count(tags->>'sid19') from sctbl4 GROUP BY (fields->>'sig2' COLLATE "en_US") ORDER BY (fields->>'sig2' COLLATE "en_US"); ?column? | ?column? | ?column? ------------------------+----------+--------------------------- -6139051.000000000000 | t | 15035602.000000000000 @@ -915,7 +915,7 @@ select sum((tags->>'sid3')::bigint) - avg((tags->>'sid12')::bigint) * count(tags (12 rows) --Testcase 78: -select string_agg(tags->>'sid19' || (tags->>'sid17')::text || (tags->>'sid10')::text, tags->>'sid9' || (tags->>'sid8')::text || (tags->>'sid7')::text), avg((tags->>'sid20')::bigint) / avg((tags->>'sid2')::bigint) + stddev((tags->>'sid12')::bigint), count(tags->>'sid1') - count(tags->>'sid14') + count((fields->>'sig3')::double precision) from sctbl4 GROUP BY tags->>'sid10' ORDER BY tags->>'sid10'; +select string_agg(tags->>'sid19' || (tags->>'sid17')::text || (tags->>'sid10')::text, tags->>'sid9' || (tags->>'sid8')::text || (tags->>'sid7')::text), avg((tags->>'sid20')::bigint) / avg((tags->>'sid2')::bigint) + stddev((tags->>'sid12')::bigint), count(tags->>'sid1') - count(tags->>'sid14') + count((fields->>'sig3')::double precision) from sctbl4 GROUP BY (tags->>'sid10' COLLATE "en_US") ORDER BY (tags->>'sid10' COLLATE "en_US"); string_agg | ?column? | ?column? --------------------------------------------------------------------------------------------+----------+---------- 彼はなぜ18歳で彼がHHJAHJGYJB黎明起床是为了鸟"1 chồng 2 ck " | | 1 @@ -929,10 +929,10 @@ select string_agg(tags->>'sid19' || (tags->>'sid17')::text || (tags->>'sid10'):: -- Select with WHERE multi-condition --Testcase 79: select avg((fields->>'sig3')::double precision + (tags->>'sid3')::bigint / (tags->>'sid12')::bigint), count(time) + count(tags->>'sid1') - sum((tags->>'sid2')::bigint), every((tags->>'sid11')::boolean = (tags->>'sid15')::boolean) from sctbl4 WHERE tags->>'sid9' LIKE '%挫败%' OR (tags->>'sid5')::boolean <> true OR tags->>'sid16' ILIKE 'id4' AND (tags->>'sid20')::bigint < 0 GROUP BY tags->>'sid11' ORDER BY tags->>'sid11'; - avg | ?column? | every --------+-----------+------- - 15.35 | -7293145 | t - 10.15 | -14717634 | t + avg | ?column? | every +--------------------+-----------+------- + 15.35 | -7293145 | t + 10.149999999999999 | -14717634 | t (2 rows) --Testcase 80: @@ -987,32 +987,32 @@ select stddev((tags->>'sid13')::double precision + (fields->>'sig1')::bigint * ( -- Select with HAVING LIMIT OFFSET --Testcase 84: select stddev((tags->>'sid2')::bigint * 0.9804754 + (tags->>'sid3')::bigint), min((tags->>'sid13')::double precision / ((fields->>'sig1')::bigint + 3.144)), stddev((tags->>'sid20')::bigint * (tags->>'sid2')::bigint - (tags->>'sid13')::double precision) from sctbl4 WHERE (fields->>'sig3')::double precision >= -999995.955 GROUP BY (fields->>'sig1')::bigint,(fields->>'sig3')::double precision HAVING (fields->>'sig3')::double precision > 0 ORDER BY (fields->>'sig1')::bigint LIMIT 10 OFFSET 10; - stddev | min | stddev ---------+------------------+-------- - | 524.997933198419 | - | | - | 4.65509362530285 | - | | - | | - | | - | 12.7509232266811 | - | | + stddev | min | stddev +--------+--------------------+-------- + | 524.9979331984193 | + | | + | 4.655093625302854 | + | | + | | + | | + | 12.750923226681131 | + | | (8 rows) --Testcase 85: select sum((fields->>'sig3')::double precision + (tags->>'sid3')::bigint * (tags->>'sid12')::bigint), string_agg(tags->>'sid7', tags->>'sid8'), string_agg(fields->>'sig2' || '568hvsvbka', 'も9質18問' || (tags->>'sid9')::text) from sctbl4 WHERE (fields->>'sig3')::double precision >= 0.3871647691 GROUP BY (fields->>'sig1')::bigint,(fields->>'sig3')::double precision,tags->>'sid15' HAVING (fields->>'sig3')::double precision <> 0 ORDER BY tags->>'sid15' LIMIT 10 OFFSET 0; - sum | string_agg | string_agg -----------------------+-------------+---------------------------- - 1.57894288862502e+15 | cooperation | 装置開発機能仕568hvsvbka - 409702609532.3 | freighter | C)@maEFJAe=3kake568hvsvbka - 47102269402.5 | average | システム568hvsvbka - 48006892.2 | constraint | BAEFOAWJ#AWEK568hvsvbka - 117115444.1 | attract | aoaowejf568hvsvbka - | | 装置開発機能仕568hvsvbka - | | C)@maEFJAe=3kake568hvsvbka - | | 012002'akewo02568hvsvbka - | | 012002'akewo02568hvsvbka - | | g029012568hvsvbka + sum | string_agg | string_agg +------------------------+-------------+---------------------------- + 1.5789428886250205e+15 | cooperation | 装置開発機能仕568hvsvbka + 409702609532.3 | freighter | C)@maEFJAe=3kake568hvsvbka + 47102269402.5 | average | システム568hvsvbka + 48006892.2 | constraint | BAEFOAWJ#AWEK568hvsvbka + 117115444.1 | attract | aoaowejf568hvsvbka + | | 装置開発機能仕568hvsvbka + | | C)@maEFJAe=3kake568hvsvbka + | | 012002'akewo02568hvsvbka + | | 012002'akewo02568hvsvbka + | | g029012568hvsvbka (10 rows) --Testcase 86: @@ -1293,7 +1293,11 @@ select sctbl4.tags->>'sid8' sid8, sctbl4.tags->>'sid9' sid9, (sctbl9.fields->>'s -- Clean --Testcase 103: DROP FOREIGN TABLE sctbl4; +--Testcase 104: DROP FOREIGN TABLE sctbl9; +--Testcase 105: DROP USER MAPPING FOR CURRENT_USER SERVER influxdb_svr; +--Testcase 106: DROP SERVER influxdb_svr CASCADE; +--Testcase 107: DROP EXTENSION influxdb_fdw; diff --git a/expected/15.0/schemaless/aggregate.out b/expected/16.0/schemaless/aggregate.out similarity index 100% rename from expected/15.0/schemaless/aggregate.out rename to expected/16.0/schemaless/aggregate.out diff --git a/expected/11.17/schemaless/extra/aggregates.out b/expected/16.0/schemaless/extra/aggregates.out similarity index 82% rename from expected/11.17/schemaless/extra/aggregates.out rename to expected/16.0/schemaless/extra/aggregates.out index 89c0b81..c411ad2 100644 --- a/expected/11.17/schemaless/extra/aggregates.out +++ b/expected/16.0/schemaless/extra/aggregates.out @@ -39,6 +39,14 @@ CREATE FOREIGN TABLE FLOAT8_TBL (fields jsonb OPTIONS(fields 'true')) SERVER inf -- -- AGGREGATES -- +-- directory paths are passed to us in environment variables +--\getenv abs_srcdir PG_ABS_SRCDIR +-- avoid bit-exact output here because operations may not be bit-exact. +--Testcase 19: +SET extra_float_digits = 0; +--\set filename :abs_srcdir '/init/agg.txt' +--COPY aggtest_nsc FROM :'filename'; +--ANALYZE aggtest_nsc; -- avoid bit-exact output here because operations may not be bit-exact. --Testcase 19: SET extra_float_digits = 0; @@ -56,6 +64,63 @@ SELECT avg((fields->>'a')::int2) AS avg_32 FROM aggtest WHERE (fields->>'a')::in 32.6666666666666667 (1 row) +--Testcase 538: +CREATE FOREIGN TABLE v1_nsc (v int4) SERVER influxdb_svr OPTIONS (table 'v1'); +--Testcase 539: +CREATE FOREIGN TABLE v1(fields jsonb OPTIONS(fields 'true')) SERVER influxdb_svr OPTIONS (schemaless 'true'); +--Testcase 540: +INSERT INTO v1_nsc (v) VALUES (1), (2), (3); +--Testcase 541: +SELECT any_value((fields->>'v')::int2) FROM v1; + any_value +----------- + 1 +(1 row) + +--Testcase 542: +DELETE FROM v1_nsc; +-- NULL datatype is not supported in influxdb. Expectation is error. +--Testcase 543: +INSERT INTO v1_nsc (v) VALUES (NULL); +ERROR: influxdb_fdw : point without fields is unsupported +--Testcase 544: +SELECT any_value((fields->>'v')::int2) FROM v1; + any_value +----------- + +(1 row) + +--Testcase 545: +DELETE FROM v1_nsc; +-- NULL datatype is not supported in influxdb. Expectation is error. +--Testcase 546: +INSERT INTO v1_nsc (v) VALUES (NULL), (1), (2); +ERROR: influxdb_fdw : point without fields is unsupported +--Testcase 547: +SELECT any_value((fields->>'v')::int2) FROM v1; + any_value +----------- + +(1 row) + +--Testcase 548: +DELETE FROM v1_nsc; +--Testcase 524: +CREATE FOREIGN TABLE v2_nsc (v text[]) SERVER influxdb_svr OPTIONS (table 'v2'); +--Testcase 549: +CREATE FOREIGN TABLE v2(fields jsonb OPTIONS(fields 'true')) SERVER influxdb_svr OPTIONS (schemaless 'true'); +-- Cannot binding text array. Expectation is error. +--Testcase 550: +INSERT INTO v2_nsc (v) VALUES (array['hello', 'world']); +ERROR: cannot convert constant value to InfluxDB value 1009 +HINT: Constant value data type: 1009 +--Testcase 551: +SELECT any_value(v) FROM v2; +ERROR: column "v" does not exist +LINE 1: SELECT any_value(v) FROM v2; + ^ +--Testcase 552: +DELETE FROM v2_nsc; -- In 7.1, avg(float4) is computed using float8 arithmetic. -- Round the result to 3 digits to avoid platform-specific results. --Testcase 22: @@ -288,22 +353,30 @@ SELECT stddev_pop((fields->>'a')::numeric), stddev_samp((fields->>'b')::numeric) --Testcase 55: SELECT var_pop((fields->>'a')::numeric), var_samp((fields->>'b')::numeric) FROM agg_t5 WHERE (fields->>'id')::int = 3; -ERROR: invalid input syntax for type numeric: "inf" + var_pop | var_samp +---------+---------- + NaN | +(1 row) + --Testcase 56: SELECT stddev_pop((fields->>'a')::numeric), stddev_samp((fields->>'b')::numeric) FROM agg_t5 WHERE (fields->>'id')::int = 3; -ERROR: invalid input syntax for type numeric: "inf" + stddev_pop | stddev_samp +------------+------------- + NaN | +(1 row) + --Testcase 57: SELECT var_pop((fields->>'a')::numeric), var_samp((fields->>'b')::numeric) FROM agg_t5 WHERE (fields->>'id')::int = 4; var_pop | var_samp ---------+---------- - NaN | NaN + NaN | (1 row) --Testcase 58: SELECT stddev_pop((fields->>'a')::numeric), stddev_samp((fields->>'b')::numeric) FROM agg_t5 WHERE (fields->>'id')::int = 4; stddev_pop | stddev_samp ------------+------------- - NaN | NaN + NaN | (1 row) -- verify correct results for null and NaN inputs @@ -425,23 +498,43 @@ FROM infinite1 WHERE (fields->>'id')::int = 5; --Testcase 76: SELECT sum((fields->>'x')::numeric), avg((fields->>'x')::numeric), var_pop((fields->>'x')::numeric) FROM infinite1 WHERE (fields->>'id')::int = 1; -ERROR: invalid input syntax for type numeric: "infinity" + sum | avg | var_pop +----------+----------+--------- + Infinity | Infinity | NaN +(1 row) + --Testcase 77: SELECT sum((fields->>'x')::numeric), avg((fields->>'x')::numeric), var_pop((fields->>'x')::numeric) FROM infinite1 WHERE (fields->>'id')::int = 2; -ERROR: invalid input syntax for type numeric: "infinity" + sum | avg | var_pop +----------+----------+--------- + Infinity | Infinity | NaN +(1 row) + --Testcase 78: SELECT sum((fields->>'x')::numeric), avg((fields->>'x')::numeric), var_pop((fields->>'x')::numeric) FROM infinite1 WHERE (fields->>'id')::int = 3; -ERROR: invalid input syntax for type numeric: "infinity" + sum | avg | var_pop +----------+----------+--------- + Infinity | Infinity | NaN +(1 row) + --Testcase 79: SELECT sum((fields->>'x')::numeric), avg((fields->>'x')::numeric), var_pop((fields->>'x')::numeric) FROM infinite1 WHERE (fields->>'id')::int = 4; -ERROR: invalid input syntax for type numeric: "-infinity" + sum | avg | var_pop +-----+-----+--------- + NaN | NaN | NaN +(1 row) + --Testcase 80: SELECT sum((fields->>'x')::numeric), avg((fields->>'x')::numeric), var_pop((fields->>'x')::numeric) FROM infinite1 WHERE (fields->>'id')::int = 5; -ERROR: invalid input syntax for type numeric: "-infinity" + sum | avg | var_pop +-----------+-----------+--------- + -Infinity | -Infinity | NaN +(1 row) + -- test accuracy with a large input offset --Testcase 81: create foreign table large_input1 (fields jsonb OPTIONS(fields 'true')) SERVER influxdb_svr OPTIONS (schemaless 'true'); @@ -450,7 +543,7 @@ SELECT avg((fields->>'x')::float8), var_pop((fields->>'x')::float8) FROM large_input1 WHERE (fields->>'id')::int=1; avg | var_pop -----------+--------- - 100000005 | 4 + 100000005 | 2.5 (1 row) --Testcase 83: @@ -458,7 +551,7 @@ SELECT avg((fields->>'x')::float8), var_pop((fields->>'x')::float8) FROM large_input1 WHERE (fields->>'id')::int=2; avg | var_pop ---------------+--------- - 7000000000006 | 0 + 7000000000006 | 1 (1 row) -- SQL2003 binary aggregates @@ -572,16 +665,16 @@ FROM regr_test; CREATE FOREIGN TABLE float8_arr (fields jsonb OPTIONS(fields 'true')) SERVER influxdb_svr OPTIONS (schemaless 'true'); --Testcase 101: SELECT float8_accum((fields->>'x')::float8[], 100) FROM float8_arr WHERE (fields->>'id')::int=1; - float8_accum ---------------- - {5,240,12900} + float8_accum +-------------- + {5,240,6280} (1 row) --Testcase 102: SELECT float8_regr_accum((fields->>'x')::float8[], 200, 100) FROM float8_arr WHERE (fields->>'id')::int=2; - float8_regr_accum ---------------------------------- - {5,240,12900,1490,123075,35050} + float8_regr_accum +------------------------------ + {5,240,6280,1490,95080,8680} (1 row) --Testcase 103: @@ -602,22 +695,46 @@ FROM regr_test WHERE (fields->>'x')::int IN (80,100); --Testcase 105: SELECT float8_combine((fields->>'x')::float8[], (fields->>'y')::float8[]) FROM float8_arr WHERE (fields->>'id')::int=3; -ERROR: aggregate function called in non-aggregate context + float8_combine +---------------- + {3,60,200} +(1 row) + --Testcase 106: SELECT float8_combine((fields->>'x')::float8[], (fields->>'y')::float8[]) FROM float8_arr WHERE (fields->>'id')::int=4; -ERROR: aggregate function called in non-aggregate context + float8_combine +---------------- + {2,180,200} +(1 row) + --Testcase 107: SELECT float8_combine((fields->>'x')::float8[], (fields->>'y')::float8[]) FROM float8_arr WHERE (fields->>'id')::int=5; -ERROR: aggregate function called in non-aggregate context + float8_combine +---------------- + {5,240,6280} +(1 row) + --Testcase 108: SELECT float8_regr_combine((fields->>'x')::float8[],(fields->>'y')::float8[]) FROM float8_arr WHERE (fields->>'id')::int=6; -ERROR: aggregate function called in non-aggregate context + float8_regr_combine +--------------------------- + {3,60,200,750,20000,2000} +(1 row) + --Testcase 109: SELECT float8_regr_combine((fields->>'x')::float8[],(fields->>'y')::float8[]) FROM float8_arr WHERE (fields->>'id')::int=7; -ERROR: aggregate function called in non-aggregate context + float8_regr_combine +----------------------------- + {2,180,200,740,57800,-3400} +(1 row) + --Testcase 110: SELECT float8_regr_combine((fields->>'x')::float8[],(fields->>'y')::float8[]) FROM float8_arr WHERE (fields->>'id')::int=8; -ERROR: aggregate function called in non-aggregate context + float8_regr_combine +------------------------------ + {5,240,6280,1490,95080,8680} +(1 row) + --Testcase 111: DROP FOREIGN TABLE regr_test; -- test count, distinct @@ -874,11 +991,12 @@ CREATE FOREIGN TABLE bitwise_test_empty (fields jsonb OPTIONS(fields 'true')) SE --Testcase 137: SELECT BIT_AND((fields->>'i2')::INT2) AS "?", - BIT_OR((fields->>'i4')::INT4) AS "?" + BIT_OR((fields->>'i4')::INT4) AS "?", + BIT_XOR((fields->>'i8')::INT8) AS "?" FROM bitwise_test_empty; - ? | ? ----+--- - | + ? | ? | ? +---+---+--- + | | (1 row) --Testcase 138: @@ -896,11 +1014,17 @@ SELECT BIT_OR((fields->>'i8')::INT8) AS "7", BIT_OR((fields->>'i')::INT) AS "?", BIT_OR((fields->>'x')::INT2) AS "7", - BIT_OR((fields->>'y')::BIT(4)) AS "1101" + BIT_OR((fields->>'y')::BIT(4)) AS "1101", + BIT_XOR((fields->>'i2')::INT2) AS "5", + BIT_XOR((fields->>'i4')::INT4) AS "5", + BIT_XOR((fields->>'i8')::INT8) AS "5", + BIT_XOR((fields->>'i')::INT) AS "?", + BIT_XOR((fields->>'x')::INT2) AS "7", + BIT_XOR((fields->>'y')::BIT(4)) AS "1101" FROM bitwise_test; - 1 | 1 | 1 | ? | 0 | 0100 | 7 | 7 | 7 | ? | 7 | 1101 ----+---+---+---+---+------+---+---+---+---+---+------ - 1 | 1 | 1 | 1 | 0 | 0100 | 7 | 7 | 7 | 3 | 7 | 1101 + 1 | 1 | 1 | ? | 0 | 0100 | 7 | 7 | 7 | ? | 7 | 1101 | 5 | 5 | 5 | ? | 7 | 1101 +---+---+---+---+---+------+---+---+---+---+---+------+---+---+---+---+---+------ + 1 | 1 | 1 | 1 | 0 | 0100 | 7 | 7 | 7 | 3 | 7 | 1101 | 5 | 5 | 5 | 2 | 7 | 1101 (1 row) -- @@ -1260,6 +1384,7 @@ select max(100) from tenk1; -- try it on an inheritance tree --Testcase 178: create foreign table minmaxtest(fields jsonb OPTIONS(fields 'true')) SERVER influxdb_svr OPTIONS (schemaless 'true'); +--Testcase 485: create foreign table minmaxtest_nsc(f1 int) server influxdb_svr OPTIONS (table 'minmaxtest'); --Testcase 179: create table minmaxtest1() inherits (minmaxtest); @@ -1287,14 +1412,14 @@ insert into minmaxtest3 values('{"f1": "17"}'), ('{"f1": "18"}'); --Testcase 189: explain (costs off) select min((fields->>'f1')::int), max((fields->>'f1')::int) from minmaxtest; - QUERY PLAN ----------------------------------------- + QUERY PLAN +----------------------------------------------------- Aggregate -> Append - -> Foreign Scan on minmaxtest - -> Seq Scan on minmaxtest1 - -> Seq Scan on minmaxtest2 - -> Seq Scan on minmaxtest3 + -> Foreign Scan on minmaxtest minmaxtest_1 + -> Seq Scan on minmaxtest1 minmaxtest_2 + -> Seq Scan on minmaxtest2 minmaxtest_3 + -> Seq Scan on minmaxtest3 minmaxtest_4 (6 rows) --Testcase 190: @@ -1315,10 +1440,10 @@ explain (costs off) Sort Key: (min(((minmaxtest.fields ->> 'f1'::text))::integer)), (max(((minmaxtest.fields ->> 'f1'::text))::integer)) -> Aggregate -> Append - -> Foreign Scan on minmaxtest - -> Seq Scan on minmaxtest1 - -> Seq Scan on minmaxtest2 - -> Seq Scan on minmaxtest3 + -> Foreign Scan on minmaxtest minmaxtest_1 + -> Seq Scan on minmaxtest1 minmaxtest_2 + -> Seq Scan on minmaxtest2 minmaxtest_3 + -> Seq Scan on minmaxtest3 minmaxtest_4 (9 rows) --Testcase 192: @@ -1334,6 +1459,7 @@ NOTICE: drop cascades to 3 other objects DETAIL: drop cascades to table minmaxtest1 drop cascades to table minmaxtest2 drop cascades to table minmaxtest3 +--Testcase 486: drop foreign table minmaxtest_nsc cascade; -- check for correct detection of nested-aggregate errors --Testcase 194: @@ -1346,6 +1472,16 @@ select (select max(min((fields->>'unique1')::int4)) from int8_tbl) from tenk1; ERROR: aggregate function calls cannot be nested LINE 1: select (select max(min((fields->>'unique1')::int4)) from int... ^ +-- Data in schemaless table is jsonb, so need to specific a column to be converted to number. +-- Asume the column is selected is odd, so this test case does not get error by avg function. +-- Expectation is get error: aggregate function calls cannot be nested. +--Testcase 553: +select avg((select avg((a1.col1->>'odd')::int order by (select avg((a2.col2->>'odd')::int) from tenk1 a3)) + from tenk1 a1(col1))) +from tenk1 a2(col2); +ERROR: aggregate function calls cannot be nested +LINE 1: ...elect avg((a1.col1->>'odd')::int order by (select avg((a2.co... + ^ -- -- Test removal of redundant GROUP BY columns -- @@ -1380,12 +1516,13 @@ explain (costs off) select (fields->>'a')::int a,(fields->>'c')::int c from agg_ explain (costs off) select agg_t1.a, agg_t1.b, agg_t1.c, agg_t1.d, agg_t2.x, agg_t2.y, agg_t2.z from (select (agg_t1.fields->>'a')::int a, (agg_t1.fields->>'b')::int b, (agg_t1.fields->>'c')::int c, (agg_t1.fields->>'d')::int d from agg_t1 agg_t1) agg_t1 inner join (select (agg_t2.fields->>'x')::int x, (agg_t2.fields->>'y')::int y, (agg_t2.fields->>'z')::int z from agg_t2 agg_t2) agg_t2 on (agg_t1.a)::int = (agg_t2.x)::int and (agg_t1.b)::int = (agg_t2.y)::int group by (agg_t1.a)::int,(agg_t1.b)::int,(agg_t1.c)::int,(agg_t1.d)::int,(agg_t2.x)::int,(agg_t2.y)::int,(agg_t2.z)::int; - QUERY PLAN ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- + QUERY PLAN +---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- Group - Group Key: (((agg_t1.fields ->> 'a'::text))::integer), (((agg_t1.fields ->> 'b'::text))::integer), (((agg_t1.fields ->> 'c'::text))::integer), (((agg_t1.fields ->> 'd'::text))::integer), (((agg_t2.fields ->> 'x'::text))::integer), (((agg_t2.fields ->> 'y'::text))::integer), (((agg_t2.fields ->> 'z'::text))::integer) - -> Sort + Group Key: (((agg_t1.fields ->> 'a'::text))::integer), (((agg_t1.fields ->> 'b'::text))::integer), (((agg_t1.fields ->> 'c'::text))::integer), (((agg_t1.fields ->> 'd'::text))::integer), (((agg_t2.fields ->> 'z'::text))::integer) + -> Incremental Sort Sort Key: (((agg_t1.fields ->> 'a'::text))::integer), (((agg_t1.fields ->> 'b'::text))::integer), (((agg_t1.fields ->> 'c'::text))::integer), (((agg_t1.fields ->> 'd'::text))::integer), (((agg_t2.fields ->> 'z'::text))::integer) + Presorted Key: (((agg_t1.fields ->> 'a'::text))::integer), (((agg_t1.fields ->> 'b'::text))::integer) -> Merge Join Merge Cond: (((((agg_t1.fields ->> 'a'::text))::integer) = (((agg_t2.fields ->> 'x'::text))::integer)) AND ((((agg_t1.fields ->> 'b'::text))::integer) = (((agg_t2.fields ->> 'y'::text))::integer))) -> Sort @@ -1394,19 +1531,20 @@ group by (agg_t1.a)::int,(agg_t1.b)::int,(agg_t1.c)::int,(agg_t1.d)::int,(agg_t2 -> Sort Sort Key: (((agg_t2.fields ->> 'x'::text))::integer), (((agg_t2.fields ->> 'y'::text))::integer) -> Foreign Scan on agg_t2 -(12 rows) +(13 rows) -- Test case where agg_t1 can be optimized but not agg_t2 --Testcase 202: explain (costs off) select agg_t1.*,agg_t2.x, agg_t2.z from (select (agg_t1.fields->>'a')::int a, (agg_t1.fields->>'b')::int b, (agg_t1.fields->>'c')::int c, (agg_t1.fields->>'d')::int d from agg_t1 agg_t1) agg_t1 inner join (select (agg_t2.fields->>'x')::int x, (agg_t2.fields->>'y')::int y, (agg_t2.fields->>'z')::int z from agg_t2 agg_t2) agg_t2 on (agg_t1.a)::int = (agg_t2.x)::int and (agg_t1.b)::int = (agg_t2.y)::int group by (agg_t1.a)::int,(agg_t1.b)::int,(agg_t1.c)::int,(agg_t1.d)::int,(agg_t2.x)::int,(agg_t2.z)::int; - QUERY PLAN -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- + QUERY PLAN +---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- Group - Group Key: (((agg_t1.fields ->> 'a'::text))::integer), (((agg_t1.fields ->> 'b'::text))::integer), (((agg_t1.fields ->> 'c'::text))::integer), (((agg_t1.fields ->> 'd'::text))::integer), (((agg_t2.fields ->> 'x'::text))::integer), (((agg_t2.fields ->> 'z'::text))::integer) - -> Sort + Group Key: (((agg_t1.fields ->> 'a'::text))::integer), (((agg_t1.fields ->> 'b'::text))::integer), (((agg_t1.fields ->> 'c'::text))::integer), (((agg_t1.fields ->> 'd'::text))::integer), (((agg_t2.fields ->> 'z'::text))::integer) + -> Incremental Sort Sort Key: (((agg_t1.fields ->> 'a'::text))::integer), (((agg_t1.fields ->> 'b'::text))::integer), (((agg_t1.fields ->> 'c'::text))::integer), (((agg_t1.fields ->> 'd'::text))::integer), (((agg_t2.fields ->> 'z'::text))::integer) + Presorted Key: (((agg_t1.fields ->> 'a'::text))::integer), (((agg_t1.fields ->> 'b'::text))::integer) -> Merge Join Merge Cond: (((((agg_t1.fields ->> 'a'::text))::integer) = (((agg_t2.fields ->> 'x'::text))::integer)) AND ((((agg_t1.fields ->> 'b'::text))::integer) = (((agg_t2.fields ->> 'y'::text))::integer))) -> Sort @@ -1415,7 +1553,7 @@ group by (agg_t1.a)::int,(agg_t1.b)::int,(agg_t1.c)::int,(agg_t1.d)::int,(agg_t2 -> Sort Sort Key: (((agg_t2.fields ->> 'x'::text))::integer), (((agg_t2.fields ->> 'y'::text))::integer) -> Foreign Scan on agg_t2 -(12 rows) +(13 rows) -- Cannot optimize when PK is deferrable --Testcase 203: @@ -1438,8 +1576,8 @@ explain (costs off) select (fields->>'a')::int a,(fields->>'b')::int b,(fields-> Group Key: ((agg_t1.fields ->> 'a'::text))::integer, ((agg_t1.fields ->> 'b'::text))::integer, ((agg_t1.fields ->> 'c'::text))::integer, ((agg_t1.fields ->> 'd'::text))::integer -> Result -> Append - -> Foreign Scan on agg_t1 - -> Seq Scan on agg_t1c + -> Foreign Scan on agg_t1 agg_t1_1 + -> Seq Scan on agg_t1c agg_t1_2 (6 rows) -- Okay to remove columns if we're only querying the parent. @@ -1467,10 +1605,10 @@ create temp table p_agg_t1_2 partition of p_agg_t1 for values in(2); -- Ensure we can remove non-PK columns for partitioned tables. --Testcase 210: explain (costs off) select * from p_agg_t1 group by a,b,c,d; - QUERY PLAN ------------------------------------------ + QUERY PLAN +------------------------------------- HashAggregate - Group Key: p_agg_t1_1.a, p_agg_t1_1.b + Group Key: p_agg_t1.a, p_agg_t1.b -> Append -> Seq Scan on p_agg_t1_1 -> Seq Scan on p_agg_t1_2 @@ -1516,11 +1654,152 @@ select (agg_t1.fields->>'f1')::int f1 from agg_t1 left join (select (fields->>'f ERROR: column "agg_t1.fields" must appear in the GROUP BY clause or be used in an aggregate function LINE 1: select (agg_t1.fields->>'f1')::int f1 from agg_t1 left join ... ^ +-- check case where we have to inject nullingrels into coerced join alias +-- Table agg_t1 and agg_t2 is schemaless table, there is only 1 column. +-- This table does not have data. +-- So do not port x1 column, and replace f1 column by fields column. +--Testcase 554: +select fields, count(*) from +agg_t1 x(x0) left join (agg_t1 left join agg_t2 using(fields)) on (x0::int = 0) +group by fields; + fields | count +--------+------- +(0 rows) + +-- Comment out because tables agg_t1 and agg_t2 only have one column. There is no column f1 and f2, so we do not separate this test case from previous test cases. +-- same, for a RelabelType coercion +-- select (fields->>'f1')::int, count(*) from +-- agg_t1 x((fields->>'x0')::int,(fields->>'x1')::int) left join (agg_t1 left join agg_t2 using((fields->>'f1')::int)) on ((fields->>'x0')::int = 0) +-- group by (fields->>'f1')::int; --Testcase 221: drop foreign table agg_t1 cascade; --Testcase 222: drop foreign table agg_t2 cascade; -- +-- Test planner's selection of pathkeys for ORDER BY aggregates +-- +-- Ensure we order by four. This suits the most aggregate functions. +--Testcase 555: +explain (costs off) +select sum((fields->>'one')::int4 order by (fields->>'two')::int4),max((fields->>'four')::int4 order by (fields->>'four')::int4), min((fields->>'four')::int4 order by (fields->>'four')::int4) +from tenk1; + QUERY PLAN +---------------------------------------------------------- + Aggregate + -> Sort + Sort Key: (((fields ->> 'four'::text))::integer) + -> Foreign Scan on tenk1 +(4 rows) + +-- Ensure we order by two. It's a tie between ordering by two and four but +-- we tiebreak on the aggregate's position. +--Testcase 556: +explain (costs off) +select + sum((fields->>'two')::int4 order by (fields->>'two')::int4), max((fields->>'four')::int4 order by (fields->>'four')::int4), + min((fields->>'four')::int4 order by (fields->>'four')::int4), max((fields->>'two')::int4 order by (fields->>'two')::int4) +from tenk1; + QUERY PLAN +--------------------------------------------------------- + Aggregate + -> Sort + Sort Key: (((fields ->> 'two'::text))::integer) + -> Foreign Scan on tenk1 +(4 rows) + +-- Similar to above, but tiebreak on ordering by four +--Testcase 557: +explain (costs off) +select + max((fields->>'four')::int4 order by (fields->>'four')::int4), sum((fields->>'two')::int4 order by (fields->>'two')::int4), + min((fields->>'four')::int4 order by (fields->>'four')::int4), max((fields->>'two')::int4 order by (fields->>'two')::int4) +from tenk1; + QUERY PLAN +---------------------------------------------------------- + Aggregate + -> Sort + Sort Key: (((fields ->> 'four'::text))::integer) + -> Foreign Scan on tenk1 +(4 rows) + +-- Ensure this one orders by ten since there are 3 aggregates that require ten +-- vs two that suit two and four. +--Testcase 558: +explain (costs off) +select + max((fields->>'four')::int4 order by (fields->>'four')::int4), sum((fields->>'two')::int4 order by (fields->>'two')::int4), + min((fields->>'four')::int4 order by (fields->>'four')::int4), max((fields->>'two')::int4 order by (fields->>'two')::int4), + sum((fields->>'ten')::int4 order by (fields->>'ten')::int4), min((fields->>'ten')::int4 order by (fields->>'ten')::int4), max((fields->>'ten')::int4 order by (fields->>'ten')::int4) +from tenk1; + QUERY PLAN +--------------------------------------------------------- + Aggregate + -> Sort + Sort Key: (((fields ->> 'ten'::text))::integer) + -> Foreign Scan on tenk1 +(4 rows) + +-- 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. +--Testcase 559: +explain (costs off) +select + sum((fields->>'unique1')::int4 order by (fields->>'ten')::int4, (fields->>'two')::int4), sum((fields->>'unique1')::int4 order by (fields->>'four')::int4), + sum((fields->>'unique1')::int4 order by (fields->>'two')::int4, (fields->>'four')::int4) +from tenk1 +group by (fields->>'ten')::int4; + QUERY PLAN +---------------------------------------------------------------------------------------------------------------------------------------- + GroupAggregate + Group Key: (((fields ->> 'ten'::text))::integer) + -> Sort + Sort Key: (((fields ->> 'ten'::text))::integer), (((fields ->> 'two'::text))::integer), (((fields ->> 'four'::text))::integer) + -> Foreign Scan on tenk1 +(5 rows) + +-- 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. +--Testcase 560: +explain (costs off) +select + sum((fields->>'unique1')::int4 order by (fields->>'two')::int4), sum((fields->>'unique1')::int4 order by (fields->>'four')::int4), + sum((fields->>'unique1')::int4 order by (fields->>'four')::int4, (fields->>'two')::int4), sum((fields->>'unique1')::int4 order by (fields->>'two')::int4, random()), + sum((fields->>'unique1')::int4 order by (fields->>'two')::int4, random(), random() + 1) +from tenk1 +group by (fields->>'ten')::int4; + QUERY PLAN +---------------------------------------------------------------------------------------------------------------------------------------- + GroupAggregate + Group Key: (((fields ->> 'ten'::text))::integer) + -> Sort + Sort Key: (((fields ->> 'ten'::text))::integer), (((fields ->> 'four'::text))::integer), (((fields ->> 'two'::text))::integer) + -> Foreign Scan on tenk1 +(5 rows) + +-- Ensure consecutive NULLs are properly treated as distinct from each other +--Testcase 561: +select array_agg(distinct val) +from (select null as val from generate_series(1, 2)); + array_agg +----------- + {NULL} +(1 row) + +-- Ensure no ordering is requested when enable_presorted_aggregate is off +set enable_presorted_aggregate to off; +--Testcase 562: +explain (costs off) +select sum((fields->>'two')::int4 order by (fields->>'two')::int4) from tenk1; + QUERY PLAN +----------------------------- + Aggregate + -> Foreign Scan on tenk1 +(2 rows) + +reset enable_presorted_aggregate; +-- -- Test combinations of DISTINCT and/or ORDER BY -- begin; @@ -1714,9 +1993,9 @@ select * from agg_view1; --Testcase 248: select pg_get_viewdef('agg_view1'::regclass); - pg_get_viewdef ------------------------------------------------------------------------------------------------------------------------------------------------------------------- - SELECT aggfns(((multi_arg_agg.fields ->> 'a'::text))::integer, ((multi_arg_agg.fields ->> 'b'::text))::integer, (multi_arg_agg.fields ->> 'c'::text)) AS aggfns+ + pg_get_viewdef +------------------------------------------------------------------------------------------------------------------------ + SELECT aggfns(((fields ->> 'a'::text))::integer, ((fields ->> 'b'::text))::integer, (fields ->> 'c'::text)) AS aggfns+ FROM multi_arg_agg; (1 row) @@ -1775,9 +2054,9 @@ select * from agg_view1; --Testcase 257: select pg_get_viewdef('agg_view1'::regclass); - pg_get_viewdef ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- - SELECT aggfns(((multi_arg_agg.fields ->> 'a'::text))::integer, ((multi_arg_agg.fields ->> 'b'::text))::integer, (multi_arg_agg.fields ->> 'c'::text) ORDER BY (((multi_arg_agg.fields ->> 'b'::text))::integer + 1)) AS aggfns+ + pg_get_viewdef +------------------------------------------------------------------------------------------------------------------------------------------------------------------------- + SELECT aggfns(((fields ->> 'a'::text))::integer, ((fields ->> 'b'::text))::integer, (fields ->> 'c'::text) ORDER BY (((fields ->> 'b'::text))::integer + 1)) AS aggfns+ FROM multi_arg_agg; (1 row) @@ -1794,9 +2073,9 @@ select * from agg_view1; --Testcase 260: select pg_get_viewdef('agg_view1'::regclass); - pg_get_viewdef ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- - SELECT aggfns(((multi_arg_agg.fields ->> 'a'::text))::integer, ((multi_arg_agg.fields ->> 'a'::text))::integer, (multi_arg_agg.fields ->> 'c'::text) ORDER BY ((multi_arg_agg.fields ->> 'b'::text))::integer) AS aggfns+ + pg_get_viewdef +------------------------------------------------------------------------------------------------------------------------------------------------------------------- + SELECT aggfns(((fields ->> 'a'::text))::integer, ((fields ->> 'a'::text))::integer, (fields ->> 'c'::text) ORDER BY ((fields ->> 'b'::text))::integer) AS aggfns+ FROM multi_arg_agg; (1 row) @@ -1813,9 +2092,9 @@ select * from agg_view1; --Testcase 263: select pg_get_viewdef('agg_view1'::regclass); - pg_get_viewdef -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- - SELECT aggfns(((multi_arg_agg.fields ->> 'a'::text))::integer, ((multi_arg_agg.fields ->> 'b'::text))::integer, (multi_arg_agg.fields ->> 'c'::text) ORDER BY (multi_arg_agg.fields ->> 'c'::text) USING ~<~ NULLS LAST) AS aggfns+ + pg_get_viewdef +----------------------------------------------------------------------------------------------------------------------------------------------------------------------------- + SELECT aggfns(((fields ->> 'a'::text))::integer, ((fields ->> 'b'::text))::integer, (fields ->> 'c'::text) ORDER BY (fields ->> 'c'::text) USING ~<~ NULLS LAST) AS aggfns+ FROM multi_arg_agg; (1 row) @@ -1949,6 +2228,119 @@ select string_agg(v, decode('ee', 'hex')) from bytea_test_table; drop table bytea_test_table; */ +-- Test parallel string_agg and array_agg +--Testcase 563: +create foreign table pagg_test_nsc ( + x int, + y int +) server influxdb_svr options (table 'pagg_test'); +--Testcase 564: +create foreign table pagg_test ( + fields jsonb options(fields 'true') +) server influxdb_svr options (schemaless 'true'); +--Testcase 565: +insert into pagg_test_nsc +select (case x % 4 when 1 then null else x end), x % 10 +from generate_series(1,5000) x; +set parallel_setup_cost TO 0; +set parallel_tuple_cost TO 0; +set parallel_leader_participation TO 0; +set min_parallel_table_scan_size = 0; +set bytea_output = 'escape'; +set max_parallel_workers_per_gather = 2; +-- create a view as we otherwise have to repeat this query a few times. +--Testcase 566: +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 + (fields->>'y')::int4 AS y, + string_agg((fields->>'x')::text, ',') AS t, + string_agg((fields->>'x')::text::bytea, ',') AS b, + array_agg((fields->>'x')::int) AS a, + array_agg(ARRAY[(fields->>'x')::int]) AS aa + from pagg_test + group by y + ) a1 +) a2 +group by y; +-- Ensure results are correct. +--Testcase 567: +select * from v_pagg_test; + y | tmin | tmax | tndistinct | bmin | bmax | bndistinct | amin | amax | andistinct | aamin | aamax | aandistinct +---+------+------+------------+------+------+------------+------+------+------------+-------+-------+------------- + 0 | 10 | 5000 | 500 | 10 | 990 | 500 | 10 | 5000 | 500 | 10 | 5000 | 500 + 1 | 11 | 4991 | 250 | 1011 | 991 | 250 | 11 | 4991 | 250 | 11 | 4991 | 250 + 2 | 2 | 4992 | 500 | 1002 | 992 | 500 | 2 | 4992 | 500 | 2 | 4992 | 500 + 3 | 3 | 4983 | 250 | 1003 | 983 | 250 | 3 | 4983 | 250 | 3 | 4983 | 250 + 4 | 4 | 4994 | 500 | 1004 | 994 | 500 | 4 | 4994 | 500 | 4 | 4994 | 500 + 5 | 15 | 4995 | 250 | 1015 | 995 | 250 | 15 | 4995 | 250 | 15 | 4995 | 250 + 6 | 6 | 4996 | 500 | 1006 | 996 | 500 | 6 | 4996 | 500 | 6 | 4996 | 500 + 7 | 7 | 4987 | 250 | 1007 | 987 | 250 | 7 | 4987 | 250 | 7 | 4987 | 250 + 8 | 8 | 4998 | 500 | 1008 | 998 | 500 | 8 | 4998 | 500 | 8 | 4998 | 500 + 9 | 19 | 4999 | 250 | 1019 | 999 | 250 | 19 | 4999 | 250 | 19 | 4999 | 250 +(10 rows) + +-- Ensure parallel aggregation is actually being used. +-- influxdb_fdw: parallel execution is not supported +--Testcase 568: +explain (costs off) select * from v_pagg_test; + QUERY PLAN +------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- + GroupAggregate + Group Key: (((pagg_test.fields ->> 'y'::text))::integer) + -> Sort + Sort Key: (((pagg_test.fields ->> 'y'::text))::integer), (((unnest(regexp_split_to_array((string_agg((pagg_test.fields ->> 'x'::text), ','::text)), ','::text))))::integer) + -> Result + -> ProjectSet + -> HashAggregate + Group Key: ((pagg_test.fields ->> 'y'::text))::integer + -> Foreign Scan on pagg_test +(9 rows) + +set max_parallel_workers_per_gather = 0; +-- Ensure results are the same without parallel aggregation. +--Testcase 569: +select * from v_pagg_test; + y | tmin | tmax | tndistinct | bmin | bmax | bndistinct | amin | amax | andistinct | aamin | aamax | aandistinct +---+------+------+------------+------+------+------------+------+------+------------+-------+-------+------------- + 0 | 10 | 5000 | 500 | 10 | 990 | 500 | 10 | 5000 | 500 | 10 | 5000 | 500 + 1 | 11 | 4991 | 250 | 1011 | 991 | 250 | 11 | 4991 | 250 | 11 | 4991 | 250 + 2 | 2 | 4992 | 500 | 1002 | 992 | 500 | 2 | 4992 | 500 | 2 | 4992 | 500 + 3 | 3 | 4983 | 250 | 1003 | 983 | 250 | 3 | 4983 | 250 | 3 | 4983 | 250 + 4 | 4 | 4994 | 500 | 1004 | 994 | 500 | 4 | 4994 | 500 | 4 | 4994 | 500 + 5 | 15 | 4995 | 250 | 1015 | 995 | 250 | 15 | 4995 | 250 | 15 | 4995 | 250 + 6 | 6 | 4996 | 500 | 1006 | 996 | 500 | 6 | 4996 | 500 | 6 | 4996 | 500 + 7 | 7 | 4987 | 250 | 1007 | 987 | 250 | 7 | 4987 | 250 | 7 | 4987 | 250 + 8 | 8 | 4998 | 500 | 1008 | 998 | 500 | 8 | 4998 | 500 | 8 | 4998 | 500 + 9 | 19 | 4999 | 250 | 1019 | 999 | 250 | 19 | 4999 | 250 | 19 | 4999 | 250 +(10 rows) + +-- Clean up +reset max_parallel_workers_per_gather; +reset bytea_output; +reset min_parallel_table_scan_size; +reset parallel_leader_participation; +reset parallel_tuple_cost; +reset parallel_setup_cost; +--Testcase 570: +drop view v_pagg_test; +--Testcase 571: +drop foreign table pagg_test_nsc; +--Testcase 572: +drop foreign table pagg_test; -- FILTER tests --Testcase 284: select min((fields->>'unique1')::int4) filter (where (fields->>'unique1')::int4 > 100) from tenk1; @@ -2002,6 +2394,13 @@ from (values ('a', 'b')) AS v(foo,bar); a (1 row) +--Testcase 573: +select any_value(v) filter (where v > 2) from (values (1), (2), (3)) as v (v); + any_value +----------- + 3 +(1 row) + -- outer reference in FILTER (PostgreSQL extension) --Testcase 289: select (select count(*) @@ -2063,6 +2462,42 @@ select aggfns(distinct (fields->>'a')::int,(fields->>'b')::int,fields->>'c' orde (1 row) rollback; +-- check handling of bare boolean Var in FILTER +--Testcase 454: +select max(0) filter (where (fields->>'b1')::boolean) from bool_test; + max +----- + 0 +(1 row) + +--Testcase 455: +select (select max(0) filter (where (fields->>'b1')::boolean)) from bool_test; + max +----- + 0 +(1 row) + +-- check for correct detection of nested-aggregate errors in FILTER +--Testcase 456: +select max((fields->>'unique1')::int) filter (where sum((fields->>'ten')::int) > 0) from tenk1; +ERROR: aggregate functions are not allowed in FILTER +LINE 1: ...lect max((fields->>'unique1')::int) filter (where sum((field... + ^ +--Testcase 457: +select (select max((fields->>'unique1')::int) filter (where sum((fields->>'ten')::int) > 0) from int8_tbl) from tenk1; +ERROR: aggregate functions are not allowed in FILTER +LINE 1: ...lect max((fields->>'unique1')::int) filter (where sum((field... + ^ +--Testcase 458: +select max((fields->>'unique1')::int) filter (where bool_or((fields->>'ten')::int > 0)) from tenk1; +ERROR: aggregate functions are not allowed in FILTER +LINE 1: ...lect max((fields->>'unique1')::int) filter (where bool_or((f... + ^ +--Testcase 459: +select (select max((fields->>'unique1')::int) filter (where bool_or((fields->>'ten')::int > 0)) from int8_tbl) from tenk1; +ERROR: aggregate functions are not allowed in FILTER +LINE 1: ...lect max((fields->>'unique1')::int) filter (where bool_or((f... + ^ -- ordered-set aggregates begin; --Testcase 295: @@ -2314,7 +2749,7 @@ LINE 1: select rank(3) within group (order by (fields->>'stringu1'):... HINT: To use the hypothetical-set aggregate rank, the number of hypothetical direct arguments (here 1) must match the number of ordering columns (here 2). --Testcase 328: select rank('fred') within group (order by (fields->>'x')::int) from generate_series3 x; -ERROR: invalid input syntax for integer: "fred" +ERROR: invalid input syntax for type integer: "fred" LINE 1: select rank('fred') within group (order by (fields->>'x')::i... ^ --Testcase 329: @@ -2357,15 +2792,15 @@ select (fields->>'ten')::int4 ten, group by (fields->>'ten')::int order by (fields->>'ten')::int; --Testcase 334: select pg_get_viewdef('aggordview1'); - pg_get_viewdef ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- - SELECT ((tenk1.fields ->> 'ten'::text))::integer AS ten, + - percentile_disc((0.5)::double precision) WITHIN GROUP (ORDER BY ((tenk1.fields ->> 'thousand'::text))::integer) AS p50, + - percentile_disc((0.5)::double precision) WITHIN GROUP (ORDER BY ((tenk1.fields ->> 'thousand'::text))::integer) FILTER (WHERE (((tenk1.fields ->> 'hundred'::text))::integer = 1)) AS px, + - rank(5, 'AZZZZ'::name, 50) WITHIN GROUP (ORDER BY ((tenk1.fields ->> 'hundred'::text))::integer, (((tenk1.fields ->> 'string4'::text))::name) DESC, ((tenk1.fields ->> 'hundred'::text))::integer) AS rank+ - FROM tenk1 + - GROUP BY ((tenk1.fields ->> 'ten'::text))::integer + - ORDER BY ((tenk1.fields ->> 'ten'::text))::integer; + pg_get_viewdef +---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- + SELECT ((fields ->> 'ten'::text))::integer AS ten, + + percentile_disc((0.5)::double precision) WITHIN GROUP (ORDER BY ((fields ->> 'thousand'::text))::integer) AS p50, + + percentile_disc((0.5)::double precision) WITHIN GROUP (ORDER BY ((fields ->> 'thousand'::text))::integer) FILTER (WHERE (((fields ->> 'hundred'::text))::integer = 1)) AS px, + + rank(5, 'AZZZZ'::name, 50) WITHIN GROUP (ORDER BY ((fields ->> 'hundred'::text))::integer, (((fields ->> 'string4'::text))::name)::name DESC, ((fields ->> 'hundred'::text))::integer) AS rank+ + FROM tenk1 + + GROUP BY ((fields ->> 'ten'::text))::integer + + ORDER BY ((fields ->> 'ten'::text))::integer; (1 row) --Testcase 335: @@ -2399,12 +2834,10 @@ create aggregate least_agg(variadic items anyarray) ( 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)'; -ERROR: type anycompatible does not exist --Testcase 340: create aggregate cleast_agg(variadic items anycompatiblearray) ( stype = anycompatible, sfunc = cleast_accum ); -ERROR: type anycompatiblearray does not exist -- variadic aggregates --Testcase 341: select least_agg((fields->>'q1')::int8,(fields->>'q2')::int8) from int8_tbl; @@ -2422,28 +2855,32 @@ select least_agg(variadic array[(fields->>'q1')::int8,(fields->>'q2')::int8]) fr --Testcase 343: select cleast_agg((fields->>'q1')::int8,(fields->>'q2')::int8) from int8_tbl; -ERROR: function cleast_agg(bigint, bigint) does not exist -LINE 1: select cleast_agg((fields->>'q1')::int8,(fields->>'q2')::int... - ^ -HINT: No function matches the given name and argument types. You might need to add explicit type casts. + cleast_agg +------------------- + -4567890123456789 +(1 row) + --Testcase 344: select cleast_agg(4.5,(fields->>'f1')::int4) from int4_tbl; -ERROR: function cleast_agg(numeric, integer) does not exist -LINE 1: select cleast_agg(4.5,(fields->>'f1')::int4) from int4_tbl; - ^ -HINT: No function matches the given name and argument types. You might need to add explicit type casts. + cleast_agg +------------- + -2147483647 +(1 row) + --Testcase 345: select cleast_agg(variadic array[4.5,(fields->>'f1')::int4]) from int4_tbl; -ERROR: function cleast_agg(numeric[]) does not exist -LINE 1: select cleast_agg(variadic array[4.5,(fields->>'f1')::int4])... - ^ -HINT: No function matches the given name and argument types. You might need to add explicit type casts. + cleast_agg +------------- + -2147483647 +(1 row) + --Testcase 346: select pg_typeof(cleast_agg(variadic array[4.5,(fields->>'f1')::int4])) from int4_tbl; -ERROR: function cleast_agg(numeric[]) does not exist -LINE 1: select pg_typeof(cleast_agg(variadic array[4.5,(fields->>'f1... - ^ -HINT: No function matches the given name and argument types. You might need to add explicit type casts. + pg_typeof +----------- + numeric +(1 row) + --Testcase 347: drop aggregate least_agg(variadic items anyarray); --Testcase 348: @@ -2546,8 +2983,8 @@ NOTICE: avg_transfn called with 3 --Testcase 359: select my_avg(distinct (fields->>'one')::int4),my_sum((fields->>'one')::int4) from my_avg1; NOTICE: avg_transfn called with 1 -NOTICE: avg_transfn called with 3 NOTICE: avg_transfn called with 1 +NOTICE: avg_transfn called with 3 NOTICE: avg_transfn called with 3 my_avg | my_sum --------+-------- @@ -2570,10 +3007,10 @@ NOTICE: avg_transfn called with 3 create foreign table my_avg2 (fields jsonb OPTIONS(fields 'true')) SERVER influxdb_svr OPTIONS (schemaless 'true'); --Testcase 362: select my_avg((fields->>'one')::int4),my_sum((fields->>'two')::int4) from my_avg2; -NOTICE: avg_transfn called with 2 NOTICE: avg_transfn called with 1 -NOTICE: avg_transfn called with 4 +NOTICE: avg_transfn called with 2 NOTICE: avg_transfn called with 3 +NOTICE: avg_transfn called with 4 my_avg | my_sum --------+-------- 2 | 6 @@ -2753,6 +3190,48 @@ SELECT balk((fields->>'hundred')::int4) FROM tenk1; (1 row) +ROLLBACK; +-- test multiple usage of an aggregate whose finalfn returns a R/W datum +BEGIN; +--Testcase 574: +CREATE FUNCTION rwagg_sfunc(x anyarray, y anyarray) RETURNS anyarray +LANGUAGE plpgsql IMMUTABLE AS $$ +BEGIN + RETURN array_fill(y[1], ARRAY[4]); +END; +$$; +--Testcase 575: +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; +$$; +--Testcase 576: +CREATE AGGREGATE rwagg(anyarray) ( + STYPE = anyarray, + SFUNC = rwagg_sfunc, + FINALFUNC = rwagg_finalfunc +); +--Testcase 577: +CREATE FUNCTION eatarray(x real[]) RETURNS real[] +LANGUAGE plpgsql STRICT IMMUTABLE AS $$ +BEGIN + x[1] := x[1] + 1; + RETURN x; +END; +$$; +--Testcase 578: +SELECT eatarray(rwagg(ARRAY[1.0::real])), eatarray(rwagg(ARRAY[1.0::real])); + eatarray | eatarray +-----------+----------- + {2,1,1,1} | {2,1,1,1} +(1 row) + ROLLBACK; -- Secondly test the case of a parallel aggregate combiner function -- returning NULL. For that use normal transition function, but a @@ -2934,6 +3413,8 @@ select v||'a', case when v||'a' = 'aa' then 1 else 0 end, count(*) -- does not lead to array overflow due to unexpected duplicate hash keys -- see CAFeeJoKKu0u+A_A9R9316djW-YW3-+Gtgvy3ju655qRHR3jtdA@mail.gmail.com --Testcase 399: +set enable_memoize to off; +--Testcase 400: explain (costs off) select 1 from tenk1 where ((fields->>'hundred')::int, (fields->>'thousand')::int) in (select (fields->>'twothousand')::int, (fields->>'twothousand')::int from onek); @@ -2948,12 +3429,14 @@ explain (costs off) -> Foreign Scan on tenk1 (7 rows) +--Testcase 401: +reset enable_memoize; -- -- Hash Aggregation Spill tests -- ---Testcase 400: +--Testcase 402: set enable_sort=false; ---Testcase 401: +--Testcase 403: set work_mem='64kB'; --Testcase 404: select (fields->>'unique1')::int unique1, count(*), sum((fields->>'twothousand')::int) from tenk1 @@ -3012,58 +3495,68 @@ order by sum((fields->>'twothousand')::int); 9999 | 1 | 1999 (48 rows) ---Testcase 403: +--Testcase 405: set work_mem to default; ---Testcase 404: +--Testcase 406: set enable_sort to default; -- -- Compare results between plans using sorting and plans using hash -- aggregation. Force spilling in both cases by setting work_mem low. -- ---Testcase 405: +--Testcase 407: set work_mem='64kB'; ---Testcase 406: -create foreign table agg_data_2k(fields jsonb OPTIONS(fields 'true')) server influxdb_svr OPTIONS (schemaless 'true'); +--Testcase 408: +create foreign table agg_data_2k (fields jsonb OPTIONS(fields 'true')) SERVER influxdb_svr OPTIONS (schemaless 'true'); +--Testcase 489: create foreign table agg_data_2k_nsc (g int) server influxdb_svr OPTIONS (table 'agg_data_2k'); ---Testcase 407: -create foreign table agg_data_20k(fields jsonb OPTIONS(fields 'true')) server influxdb_svr OPTIONS (schemaless 'true'); +--Testcase 409: +create foreign table agg_data_20k (fields jsonb OPTIONS(fields 'true')) SERVER influxdb_svr OPTIONS (schemaless 'true'); +--Testcase 490: create foreign table agg_data_20k_nsc (g int) server influxdb_svr OPTIONS (table 'agg_data_20k'); ---Testcase 408: +--Testcase 410: create foreign table agg_group_1 (fields jsonb OPTIONS(fields 'true')) SERVER influxdb_svr OPTIONS (schemaless 'true'); +--Testcase 491: create foreign table agg_group_1_nsc (c1 int, c2 numeric, c3 int) server influxdb_svr OPTIONS (table 'agg_group_1'); ---Testcase 409: +--Testcase 411: create foreign table agg_group_2 (fields jsonb OPTIONS(fields 'true')) SERVER influxdb_svr OPTIONS (schemaless 'true'); +--Testcase 492: create foreign table agg_group_2_nsc (a int, c1 numeric, c2 text, c3 int) server influxdb_svr OPTIONS (table 'agg_group_2'); ---Testcase 410: +--Testcase 412: create foreign table agg_group_3 (fields jsonb OPTIONS(fields 'true')) SERVER influxdb_svr OPTIONS (schemaless 'true'); +--Testcase 493: create foreign table agg_group_3_nsc (c1 numeric, c2 int4, c3 int) server influxdb_svr OPTIONS (table 'agg_group_3'); ---Testcase 411: +--Testcase 413: create foreign table agg_group_4 (fields jsonb OPTIONS(fields 'true')) SERVER influxdb_svr OPTIONS (schemaless 'true'); +--Testcase 494: create foreign table agg_group_4_nsc (c1 numeric, c2 text, c3 int) server influxdb_svr OPTIONS (table 'agg_group_4'); ---Testcase 412: +--Testcase 414: create foreign table agg_hash_1 (fields jsonb OPTIONS(fields 'true')) SERVER influxdb_svr OPTIONS (schemaless 'true'); +--Testcase 495: create foreign table agg_hash_1_nsc (c1 int, c2 numeric, c3 int) server influxdb_svr OPTIONS (table 'agg_hash_1'); ---Testcase 413: +--Testcase 415: create foreign table agg_hash_2 (fields jsonb OPTIONS(fields 'true')) SERVER influxdb_svr OPTIONS (schemaless 'true'); +--Testcase 496: create foreign table agg_hash_2_nsc (a int, c1 numeric, c2 text, c3 int) server influxdb_svr OPTIONS (table 'agg_hash_2'); ---Testcase 414: +--Testcase 416: create foreign table agg_hash_3 (fields jsonb OPTIONS(fields 'true')) SERVER influxdb_svr OPTIONS (schemaless 'true'); +--Testcase 497: create foreign table agg_hash_3_nsc (c1 numeric, c2 int4, c3 int) server influxdb_svr OPTIONS (table 'agg_hash_3'); ---Testcase 415: +--Testcase 417: create foreign table agg_hash_4 (fields jsonb OPTIONS(fields 'true')) SERVER influxdb_svr OPTIONS (schemaless 'true'); +--Testcase 498: create foreign table agg_hash_4_nsc (c1 numeric, c2 text, c3 int) server influxdb_svr OPTIONS (table 'agg_hash_4'); ---Testcase 416: +--Testcase 418: insert into agg_data_2k_nsc select g from generate_series(0, 1999) g; --analyze agg_data_2k; ---Testcase 417: +--Testcase 419: insert into agg_data_20k_nsc select g from generate_series(0, 19999) g; --analyze agg_data_20k; -- Produce results with sorting. ---Testcase 418: +--Testcase 420: set enable_hashagg = false; ---Testcase 419: +--Testcase 421: set jit_above_cost = 0; ---Testcase 420: +--Testcase 422: explain (costs off) select (fields->>'g')::int%10000 as c1, sum((fields->>'g')::numeric) as c2, count(*) as c3 from agg_data_20k group by (fields->>'g')::int%10000; @@ -3076,11 +3569,11 @@ select (fields->>'g')::int%10000 as c1, sum((fields->>'g')::numeric) as c2, coun -> Foreign Scan on agg_data_20k (5 rows) ---Testcase 421: +--Testcase 423: insert into agg_group_1_nsc select g%10000 as c1, sum(g::numeric) as c2, count(*) as c3 from agg_data_20k_nsc group by g%10000; ---Testcase 422: +--Testcase 424: insert into agg_group_2_nsc select * from (values (100), (300), (500)) as r(a), @@ -3091,24 +3584,24 @@ select * from from agg_data_2k_nsc where g < r.a group by g/2) as s; ---Testcase 423: +--Testcase 425: set jit_above_cost to default; ---Testcase 424: +--Testcase 426: insert into agg_group_3_nsc select (g/2)::numeric as c1, sum(7::int4) as c2, count(*) as c3 from agg_data_2k_nsc group by g/2; ---Testcase 425: +--Testcase 427: insert into agg_group_4_nsc select (g/2)::numeric as c1, array_agg(g::numeric) as c2, count(*) as c3 from agg_data_2k_nsc group by g/2; -- Produce results with hash aggregation ---Testcase 426: +--Testcase 428: set enable_hashagg = true; ---Testcase 427: +--Testcase 429: set enable_sort = false; ---Testcase 428: +--Testcase 430: set jit_above_cost = 0; ---Testcase 429: +--Testcase 431: explain (costs off) select (fields->>'g')::int%10000 as c1, sum((fields->>'g')::numeric) as c2, count(*) as c3 from agg_data_20k group by (fields->>'g')::int%10000; @@ -3119,11 +3612,11 @@ select (fields->>'g')::int%10000 as c1, sum((fields->>'g')::numeric) as c2, coun -> Foreign Scan on agg_data_20k (3 rows) ---Testcase 430: +--Testcase 432: insert into agg_hash_1_nsc select g%10000 as c1, sum(g::numeric) as c2, count(*) as c3 from agg_data_20k_nsc group by g%10000; ---Testcase 431: +--Testcase 433: insert into agg_hash_2_nsc select * from (values (100), (300), (500)) as r(a), @@ -3134,22 +3627,22 @@ select * from from agg_data_2k_nsc where g < r.a group by g/2) as s; ---Testcase 432: +--Testcase 434: set jit_above_cost to default; ---Testcase 433: +--Testcase 435: insert into agg_hash_3_nsc select (g/2)::numeric as c1, sum(7::int4) as c2, count(*) as c3 from agg_data_2k_nsc group by g/2; ---Testcase 434: +--Testcase 436: insert into agg_hash_4_nsc select (g/2)::numeric as c1, array_agg(g::numeric) as c2, count(*) as c3 from agg_data_2k_nsc group by g/2; ---Testcase 435: +--Testcase 437: set enable_sort = true; ---Testcase 436: +--Testcase 438: set work_mem to default; -- Compare group aggregation results to hash aggregation results ---Testcase 437: +--Testcase 439: (select * from agg_hash_1 except select * from agg_group_1) union all (select * from agg_group_1 except select * from agg_hash_1); @@ -3157,7 +3650,7 @@ set work_mem to default; -------- (0 rows) ---Testcase 438: +--Testcase 440: (select * from agg_hash_2 except select * from agg_group_2) union all (select * from agg_group_2 except select * from agg_hash_2); @@ -3165,7 +3658,7 @@ set work_mem to default; -------- (0 rows) ---Testcase 439: +--Testcase 441: (select * from agg_hash_3 except select * from agg_group_3) union all (select * from agg_group_3 except select * from agg_hash_3); @@ -3173,7 +3666,7 @@ set work_mem to default; -------- (0 rows) ---Testcase 440: +--Testcase 442: (select * from agg_hash_4 except select * from agg_group_4) union all (select * from agg_group_4 except select * from agg_hash_4); @@ -3181,44 +3674,67 @@ set work_mem to default; -------- (0 rows) ---Testcase 441: +--Testcase 443: -- Clean up: +--Testcase 499: delete from agg_data_2k_nsc; +--Testcase 500: delete from agg_data_20k_nsc; +--Testcase 501: delete from agg_group_1_nsc; +--Testcase 502: delete from agg_group_2_nsc; +--Testcase 503: delete from agg_group_3_nsc; +--Testcase 504: delete from agg_group_4_nsc; +--Testcase 505: delete from agg_hash_1_nsc; +--Testcase 506: delete from agg_hash_2_nsc; +--Testcase 507: delete from agg_hash_3_nsc; +--Testcase 508: delete from agg_hash_4_nsc; +--Testcase 509: drop foreign table agg_data_2k; +--Testcase 510: drop foreign table agg_data_2k_nsc; +--Testcase 511: drop foreign table agg_data_20k; +--Testcase 512: drop foreign table agg_data_20k_nsc; +--Testcase 513: drop foreign table agg_group_1; +--Testcase 514: drop foreign table agg_group_1_nsc; ---Testcase 442: +--Testcase 444: drop foreign table agg_group_2; +--Testcase 515: drop foreign table agg_group_2_nsc; ---Testcase 443: +--Testcase 445: drop foreign table agg_group_3; +--Testcase 516: drop foreign table agg_group_3_nsc; ---Testcase 444: +--Testcase 446: drop foreign table agg_group_4; +--Testcase 517: drop foreign table agg_group_4_nsc; ---Testcase 445: +--Testcase 447: drop foreign table agg_hash_1; +--Testcase 518: drop foreign table agg_hash_1_nsc; ---Testcase 446: +--Testcase 448: drop foreign table agg_hash_2; +--Testcase 519: drop foreign table agg_hash_2_nsc; ---Testcase 447: +--Testcase 449: drop foreign table agg_hash_3; +--Testcase 520: drop foreign table agg_hash_3_nsc; ---Testcase 448: +--Testcase 450: drop foreign table agg_hash_4; +--Testcase 521: drop foreign table agg_hash_4_nsc; -- Clean up DO $d$ @@ -3232,27 +3748,41 @@ begin end; $d$; -- Clean up: +--Testcase 522: DROP AGGREGATE IF EXISTS newavg (int4); +--Testcase 523: DROP AGGREGATE IF EXISTS newsum (int4); +--Testcase 524: DROP AGGREGATE IF EXISTS newcnt (*); +--Testcase 525: DROP AGGREGATE IF EXISTS oldcnt (*); +--Testcase 526: DROP AGGREGATE IF EXISTS newcnt ("any"); +--Testcase 527: DROP AGGREGATE IF EXISTS sum2(int8,int8); +--Testcase 528: DROP FUNCTION IF EXISTS sum3(int8,int8,int8); +--Testcase 529: DROP AGGREGATE IF EXISTS aggfns(integer,integer,text); +--Testcase 530: DROP AGGREGATE IF EXISTS aggfstr(integer,integer,text); +--Testcase 531: DROP FUNCTION IF EXISTS aggfns_trans(aggtype[],integer,integer,text); +--Testcase 532: DROP FUNCTION IF EXISTS aggf_trans(aggtype[],integer,integer,text); +--Testcase 533: DROP TYPE IF EXISTS aggtype; +--Testcase 534: DROP AGGREGATE IF EXISTS test_percentile_disc(float8 ORDER BY anyelement); +--Testcase 535: DROP AGGREGATE IF EXISTS test_rank(VARIADIC "any" ORDER BY VARIADIC "any"); +--Testcase 536: DROP AGGREGATE IF EXISTS cleast_agg(variadic items anycompatiblearray); -NOTICE: type "anycompatiblearray" does not exist, skipping +--Testcase 537: DROP FUNCTION IF EXISTS cleast_accum(anycompatible, variadic anycompatiblearray); -NOTICE: type "anycompatible" does not exist, skipping ---Testcase 449: +--Testcase 451: DROP USER MAPPING FOR CURRENT_USER SERVER influxdb_svr; ---Testcase 450: +--Testcase 452: DROP SERVER influxdb_svr CASCADE; ---Testcase 451: +--Testcase 453: DROP EXTENSION influxdb_fdw; diff --git a/expected/16.0/schemaless/extra/influxdb_fdw_post.out b/expected/16.0/schemaless/extra/influxdb_fdw_post.out new file mode 100644 index 0000000..67c9a71 --- /dev/null +++ b/expected/16.0/schemaless/extra/influxdb_fdw_post.out @@ -0,0 +1,11245 @@ +-- =================================================================== +-- create FDW objects +-- =================================================================== +\set ECHO none +--Testcase 1: +CREATE EXTENSION influxdb_fdw; +--Testcase 2: +CREATE SERVER testserver1 FOREIGN DATA WRAPPER influxdb_fdw; +--Testcase 3: +CREATE SERVER influxdb_svr FOREIGN DATA WRAPPER influxdb_fdw + OPTIONS (dbname 'postdb', :SERVER); +--Testcase 4: +CREATE SERVER influxdb_svr2 FOREIGN DATA WRAPPER influxdb_fdw + OPTIONS (dbname 'postdb', :SERVER); +--Testcase 5: +CREATE USER MAPPING FOR public SERVER testserver1 OPTIONS (user 'value', password 'value'); +--Testcase 6: +CREATE USER MAPPING FOR CURRENT_USER SERVER influxdb_svr OPTIONS (:AUTHENTICATION); +--Testcase 7: +CREATE USER MAPPING FOR CURRENT_USER SERVER influxdb_svr2 OPTIONS (:AUTHENTICATION); +-- =================================================================== +-- create objects used through FDW influxdb server +-- =================================================================== +--Testcase 8: +CREATE TYPE user_enum AS ENUM ('foo', 'bar', 'buz'); +--Testcase 9: +CREATE SCHEMA "S 1"; +--Testcase 10: +CREATE FOREIGN TABLE "S 1"."T 0" (time timestamptz, tags jsonb OPTIONS(tags 'true'), fields jsonb OPTIONS(fields 'true')) SERVER influxdb_svr OPTIONS (table 'T0', tags 'c3', schemaless 'true'); +--Testcase 783: +CREATE FOREIGN TABLE "S 1".s1t0 ( + "C 1" int NOT NULL, + c2 int NOT NULL, + c3 text, + time timestamptz, + c6 varchar(10), + c7 char(10), + c8 text +) SERVER influxdb_svr OPTIONS (table 'T0', tags 'c3'); +--Testcase 11: +CREATE FOREIGN TABLE "S 1"."T 1" (time timestamptz, tags jsonb OPTIONS(tags 'true'), fields jsonb OPTIONS(fields 'true')) SERVER influxdb_svr OPTIONS (table 'T1', tags 'c3', schemaless 'true'); +--Testcase 784: +CREATE FOREIGN TABLE "S 1".s1t1 ( + "C 1" int NOT NULL, + c2 int NOT NULL, + c3 text, + time timestamptz, + c6 varchar(10), + c7 char(10), + c8 text +) SERVER influxdb_svr OPTIONS (table 'T1', tags 'c3'); +--Testcase 12: +CREATE FOREIGN TABLE "S 1"."T 2" (tags jsonb OPTIONS(tags 'true'), fields jsonb OPTIONS(fields 'true')) SERVER influxdb_svr OPTIONS (table 'T2', tags 'c2', schemaless 'true'); +--Testcase 785: +CREATE FOREIGN TABLE "S 1".s1t2 ( + c1 int NOT NULL, + c2 text +) SERVER influxdb_svr OPTIONS (table 'T2', tags 'c2'); +--Testcase 13: +CREATE FOREIGN TABLE "S 1"."T 3" (tags jsonb OPTIONS(tags 'true'), fields jsonb OPTIONS(fields 'true')) SERVER influxdb_svr OPTIONS (table 'T3', tags 'c3', schemaless 'true'); +--Testcase 786: +CREATE FOREIGN TABLE "S 1".s1t3 ( + c1 int NOT NULL, + c2 int NOT NULL, + c3 text +) SERVER influxdb_svr OPTIONS (table 'T3', tags 'c3'); +--Testcase 14: +CREATE FOREIGN TABLE "S 1"."T 4" (tags jsonb OPTIONS(tags 'true'), fields jsonb OPTIONS(fields 'true')) SERVER influxdb_svr OPTIONS (table 'T4', tags 'c3', schemaless 'true'); +--Testcase 787: +CREATE FOREIGN TABLE "S 1".s1t4 ( + c1 int NOT NULL, + c2 int NOT NULL, + c3 text +) SERVER influxdb_svr OPTIONS (table 'T4', tags 'c3'); +-- Disable autovacuum for these tables to avoid unexpected effects of that +--ALTER TABLE "S 1"."T 1" SET (autovacuum_enabled = 'false'); +--ALTER TABLE "S 1"."T 2" SET (autovacuum_enabled = 'false'); +--ALTER TABLE "S 1"."T 3" SET (autovacuum_enabled = 'false'); +--ALTER TABLE "S 1"."T 4" SET (autovacuum_enabled = 'false'); +--Testcase 15: +INSERT INTO "S 1".s1t1 + SELECT id, + id % 10, + to_char(id, 'FM00000'), + '1970-01-01'::timestamptz + ((id % 100) || ' days')::interval, + id % 10, + id % 10, + 'foo'::text + FROM generate_series(1, 1000) id; +--Testcase 16: +INSERT INTO "S 1".s1t2 + SELECT id, + 'AAA' || to_char(id, 'FM000') + FROM generate_series(1, 100) id; +--Testcase 17: +INSERT INTO "S 1".s1t3 + SELECT id, + id + 1, + 'AAA' || to_char(id, 'FM000') + FROM generate_series(1, 100) id; +--Testcase 18: +DELETE FROM "S 1".s1t3 WHERE c1 % 2 != 0; -- delete for outer join tests +--Testcase 19: +INSERT INTO "S 1".s1t4 + SELECT id, + id + 1, + 'AAA' || to_char(id, 'FM000') + FROM generate_series(1, 100) id; +--Testcase 20: +DELETE FROM "S 1".s1t4 WHERE c1 % 3 != 0; -- delete for outer join tests +--ANALYZE "S 1"."T 1"; +--ANALYZE "S 1"."T 2"; +--ANALYZE "S 1"."T 3"; +--ANALYZE "S 1"."T 4"; +-- =================================================================== +-- create foreign tables +-- =================================================================== +--Testcase 21: +CREATE FOREIGN TABLE ft1 (time timestamptz, tags jsonb OPTIONS(tags 'true'), fields jsonb OPTIONS(fields 'true')) SERVER influxdb_svr OPTIONS (schemaless 'true'); +--Testcase 788: +CREATE FOREIGN TABLE ft1_nsc ( + c0 int, + c1 int NOT NULL, + c2 int NOT NULL, + c3 text, + time timestamptz, + c6 varchar(10), + c7 char(10) default 'ft1', + c8 text +) SERVER influxdb_svr; +--Testcase 22: +ALTER FOREIGN TABLE ft1_nsc DROP COLUMN c0; +--Testcase 23: +CREATE FOREIGN TABLE ft2 (time timestamptz, tags jsonb OPTIONS(tags 'true'), fields jsonb OPTIONS(fields 'true')) SERVER influxdb_svr OPTIONS (schemaless 'true'); +--Testcase 789: +CREATE FOREIGN TABLE ft2_nsc ( + c1 int NOT NULL, + c2 int NOT NULL, + cx int, + c3 text, + time timestamptz, + c6 varchar(10), + c7 char(10) default 'ft2', + c8 text +) SERVER influxdb_svr; +--Testcase 24: +ALTER FOREIGN TABLE ft2_nsc DROP COLUMN cx; +--Testcase 25: +CREATE FOREIGN TABLE ft4 (tags jsonb OPTIONS(tags 'true'), fields jsonb OPTIONS(fields 'true')) SERVER influxdb_svr OPTIONS (table 'T3', tags 'c3', schemaless 'true'); +--Testcase 790: +CREATE FOREIGN TABLE ft4_nsc ( + c1 int NOT NULL, + c2 int NOT NULL, + c3 text +) SERVER influxdb_svr OPTIONS (table 'T3', tags 'c3'); +--Testcase 26: +CREATE FOREIGN TABLE ft5 (tags jsonb OPTIONS(tags 'true'), fields jsonb OPTIONS(fields 'true')) SERVER influxdb_svr OPTIONS (table 'T4', tags 'c3', schemaless 'true'); +--Testcase 791: +CREATE FOREIGN TABLE ft5_nsc ( + c1 int NOT NULL, + c2 int NOT NULL, + c3 text +) SERVER influxdb_svr OPTIONS (table 'T4', tags 'c3'); +--Testcase 27: +CREATE FOREIGN TABLE ft6 (tags jsonb OPTIONS(tags 'true'), fields jsonb OPTIONS(fields 'true')) SERVER influxdb_svr2 OPTIONS (table 'T4', tags 'c3', schemaless 'true'); +-- =================================================================== +-- tests for validator +-- =================================================================== +-- requiressl and some other parameters are omitted because +-- valid values for them depend on configure options +--Testcase 28: +ALTER SERVER testserver1 OPTIONS ( + -- use_remote_estimate 'false', + -- updatable 'true', + -- fdw_startup_cost '123.456', + -- fdw_tuple_cost '0.123', + -- service 'value', + -- connect_timeout 'value', + dbname 'value', + host 'value', + -- hostaddr 'value', + port 'value' + --client_encoding 'value', + -- application_name 'value', + --fallback_application_name 'value', + -- keepalives 'value', + -- keepalives_idle 'value', + -- keepalives_interval 'value', + -- tcp_user_timeout 'value', + -- requiressl 'value', + -- sslcompression 'value', + -- sslmode 'value', + -- sslcert 'value', + -- sslkey 'value', + -- sslrootcert 'value', + -- sslcrl 'value', + --requirepeer 'value', + -- krbsrvname 'value', + -- gsslib 'value', + --replication 'value' +); +-- influxdb_fdw does not support option extensions +-- Error, invalid list syntax +--ALTER SERVER testserver1 OPTIONS (ADD extensions 'foo; bar'); +-- OK but gets a warning +--ALTER SERVER testserver1 OPTIONS (ADD extensions 'foo, bar'); +--ALTER SERVER testserver1 OPTIONS (DROP extensions); +--Testcase 29: +ALTER USER MAPPING FOR public SERVER testserver1 + OPTIONS (DROP user, DROP password); +-- Attempt to add a valid option that's not allowed in a user mapping +--ALTER USER MAPPING FOR public SERVER testserver1 +-- OPTIONS (ADD sslmode 'require'); +-- But we can add valid ones fine +--ALTER USER MAPPING FOR public SERVER testserver1 +-- OPTIONS (ADD sslpassword 'dummy'); +-- Ensure valid options we haven't used in a user mapping yet are +-- permitted to check validation. +--ALTER USER MAPPING FOR public SERVER testserver1 +-- OPTIONS (ADD sslkey 'value', ADD sslcert 'value'); +--Testcase 30: +ALTER FOREIGN TABLE ft1 OPTIONS (table 'T1', tags 'c3'); +ALTER FOREIGN TABLE ft1_nsc OPTIONS (table 'T1', tags 'c3'); +--Testcase 31: +ALTER FOREIGN TABLE ft2 OPTIONS (table 'T1', tags 'c3'); +ALTER FOREIGN TABLE ft2_nsc OPTIONS (table 'T1', tags 'c3'); +--Testcase 32: +ALTER FOREIGN TABLE ft1_nsc ALTER COLUMN c1 OPTIONS (column_name 'C 1'); +--Testcase 33: +ALTER FOREIGN TABLE ft2_nsc ALTER COLUMN c1 OPTIONS (column_name 'C 1'); +--Testcase 34: +\det+ + List of foreign tables + Schema | Table | Server | FDW options | Description +--------+---------+---------------+----------------------------------------------+------------- + public | ft1 | influxdb_svr | (schemaless 'true', "table" 'T1', tags 'c3') | + public | ft1_nsc | influxdb_svr | ("table" 'T1', tags 'c3') | + public | ft2 | influxdb_svr | (schemaless 'true', "table" 'T1', tags 'c3') | + public | ft2_nsc | influxdb_svr | ("table" 'T1', tags 'c3') | + public | ft4 | influxdb_svr | ("table" 'T3', tags 'c3', schemaless 'true') | + public | ft4_nsc | influxdb_svr | ("table" 'T3', tags 'c3') | + public | ft5 | influxdb_svr | ("table" 'T4', tags 'c3', schemaless 'true') | + public | ft5_nsc | influxdb_svr | ("table" 'T4', tags 'c3') | + public | ft6 | influxdb_svr2 | ("table" 'T4', tags 'c3', schemaless 'true') | +(9 rows) + +-- Test that alteration of server options causes reconnection +-- Remote's errors might be non-English, so hide them to ensure stable results +\set VERBOSITY terse +--Testcase 35: +SELECT tags->>'c3' c3, time FROM ft1 ORDER BY tags->>'c3', (fields->>'C 1')::int LIMIT 1; -- should work + c3 | time +-------+------------------------------ + 00001 | Fri Jan 02 00:00:00 1970 PST +(1 row) + +--Testcase 36: +ALTER SERVER influxdb_svr OPTIONS (SET dbname 'no such database'); +--Testcase 37: +SELECT tags->>'c3' c3, time FROM ft1 ORDER BY tags->>'c3', (fields->>'C 1')::int LIMIT 1; -- should fail +ERROR: influxdb_fdw : database not found: no such database +DO $d$ + BEGIN + EXECUTE $$ALTER SERVER influxdb_svr + OPTIONS (SET dbname 'postdb')$$; + END; +$d$; +--Testcase 38: +SELECT tags->>'c3' c3, time FROM ft1 ORDER BY tags->>'c3', (fields->>'C 1')::int LIMIT 1; -- should work again + c3 | time +-------+------------------------------ + 00001 | Fri Jan 02 00:00:00 1970 PST +(1 row) + +\set VERBOSITY default +-- =================================================================== +-- test error case for create publication on foreign table +-- =================================================================== +--Testcase 765: +CREATE PUBLICATION testpub_ftbl FOR TABLE ft1; -- should fail +ERROR: cannot add relation "ft1" to publication +DETAIL: This operation is not supported for foreign tables. +-- =================================================================== +-- simple queries +-- =================================================================== +-- single table without alias +--Testcase 39: +EXPLAIN (COSTS OFF) SELECT * FROM ft1 ORDER BY tags->>'c3', (fields->>'C 1')::int OFFSET 100 LIMIT 10; + QUERY PLAN +---------------------------------------------------------------------------------- + Limit + -> Sort + Sort Key: ((tags ->> 'c3'::text)), (((fields ->> 'C 1'::text))::integer) + -> Foreign Scan on ft1 +(4 rows) + +--Testcase 40: +SELECT * FROM ft1 ORDER BY tags->>'c3', (fields->>'C 1')::int OFFSET 100 LIMIT 10; + time | tags | fields +------------------------------+-----------------+----------------------------------------------------------------------- + Fri Jan 02 00:00:00 1970 PST | {"c3": "00101"} | {"c2": "1", "c6": "1", "c7": "1 ", "c8": "foo", "C 1": "101"} + Sat Jan 03 00:00:00 1970 PST | {"c3": "00102"} | {"c2": "2", "c6": "2", "c7": "2 ", "c8": "foo", "C 1": "102"} + Sun Jan 04 00:00:00 1970 PST | {"c3": "00103"} | {"c2": "3", "c6": "3", "c7": "3 ", "c8": "foo", "C 1": "103"} + Mon Jan 05 00:00:00 1970 PST | {"c3": "00104"} | {"c2": "4", "c6": "4", "c7": "4 ", "c8": "foo", "C 1": "104"} + Tue Jan 06 00:00:00 1970 PST | {"c3": "00105"} | {"c2": "5", "c6": "5", "c7": "5 ", "c8": "foo", "C 1": "105"} + Wed Jan 07 00:00:00 1970 PST | {"c3": "00106"} | {"c2": "6", "c6": "6", "c7": "6 ", "c8": "foo", "C 1": "106"} + Thu Jan 08 00:00:00 1970 PST | {"c3": "00107"} | {"c2": "7", "c6": "7", "c7": "7 ", "c8": "foo", "C 1": "107"} + Fri Jan 09 00:00:00 1970 PST | {"c3": "00108"} | {"c2": "8", "c6": "8", "c7": "8 ", "c8": "foo", "C 1": "108"} + Sat Jan 10 00:00:00 1970 PST | {"c3": "00109"} | {"c2": "9", "c6": "9", "c7": "9 ", "c8": "foo", "C 1": "109"} + Sun Jan 11 00:00:00 1970 PST | {"c3": "00110"} | {"c2": "0", "c6": "0", "c7": "0 ", "c8": "foo", "C 1": "110"} +(10 rows) + +-- single table with alias - also test that tableoid sort is not pushed to remote side +--Testcase 41: +EXPLAIN (VERBOSE, COSTS OFF) SELECT * FROM ft1 t1 ORDER BY t1.tags->>'c3', (t1.fields->>'C 1')::int, t1.tableoid OFFSET 100 LIMIT 10; + QUERY PLAN +------------------------------------------------------------------------------------------------------------------ + Limit + Output: "time", tags, fields, ((tags ->> 'c3'::text)), (((fields ->> 'C 1'::text))::integer), tableoid + -> Sort + Output: "time", tags, fields, ((tags ->> 'c3'::text)), (((fields ->> 'C 1'::text))::integer), tableoid + Sort Key: ((t1.tags ->> 'c3'::text)), (((t1.fields ->> 'C 1'::text))::integer), t1.tableoid + -> Foreign Scan on public.ft1 t1 + Output: "time", tags, fields, (tags ->> 'c3'::text), ((fields ->> 'C 1'::text))::integer, tableoid + InfluxDB query: SELECT * FROM "T1" +(8 rows) + +--Testcase 42: +SELECT * FROM ft1 t1 ORDER BY t1.tags->>'c3', (t1.fields->>'C 1')::int, t1.tableoid OFFSET 100 LIMIT 10; + time | tags | fields +------------------------------+-----------------+----------------------------------------------------------------------- + Fri Jan 02 00:00:00 1970 PST | {"c3": "00101"} | {"c2": "1", "c6": "1", "c7": "1 ", "c8": "foo", "C 1": "101"} + Sat Jan 03 00:00:00 1970 PST | {"c3": "00102"} | {"c2": "2", "c6": "2", "c7": "2 ", "c8": "foo", "C 1": "102"} + Sun Jan 04 00:00:00 1970 PST | {"c3": "00103"} | {"c2": "3", "c6": "3", "c7": "3 ", "c8": "foo", "C 1": "103"} + Mon Jan 05 00:00:00 1970 PST | {"c3": "00104"} | {"c2": "4", "c6": "4", "c7": "4 ", "c8": "foo", "C 1": "104"} + Tue Jan 06 00:00:00 1970 PST | {"c3": "00105"} | {"c2": "5", "c6": "5", "c7": "5 ", "c8": "foo", "C 1": "105"} + Wed Jan 07 00:00:00 1970 PST | {"c3": "00106"} | {"c2": "6", "c6": "6", "c7": "6 ", "c8": "foo", "C 1": "106"} + Thu Jan 08 00:00:00 1970 PST | {"c3": "00107"} | {"c2": "7", "c6": "7", "c7": "7 ", "c8": "foo", "C 1": "107"} + Fri Jan 09 00:00:00 1970 PST | {"c3": "00108"} | {"c2": "8", "c6": "8", "c7": "8 ", "c8": "foo", "C 1": "108"} + Sat Jan 10 00:00:00 1970 PST | {"c3": "00109"} | {"c2": "9", "c6": "9", "c7": "9 ", "c8": "foo", "C 1": "109"} + Sun Jan 11 00:00:00 1970 PST | {"c3": "00110"} | {"c2": "0", "c6": "0", "c7": "0 ", "c8": "foo", "C 1": "110"} +(10 rows) + +-- whole-row reference +--Testcase 43: +EXPLAIN (VERBOSE, COSTS OFF) SELECT t1 FROM ft1 t1 ORDER BY t1.tags->>'c3', (t1.fields->>'C 1')::int OFFSET 100 LIMIT 10; + QUERY PLAN +---------------------------------------------------------------------------------------- + Limit + Output: t1.*, ((tags ->> 'c3'::text)), (((fields ->> 'C 1'::text))::integer) + -> Sort + Output: t1.*, ((tags ->> 'c3'::text)), (((fields ->> 'C 1'::text))::integer) + Sort Key: ((t1.tags ->> 'c3'::text)), (((t1.fields ->> 'C 1'::text))::integer) + -> Foreign Scan on public.ft1 t1 + Output: t1.*, (tags ->> 'c3'::text), ((fields ->> 'C 1'::text))::integer + InfluxDB query: SELECT * FROM "T1" +(8 rows) + +--Testcase 44: +SELECT t1 FROM ft1 t1 ORDER BY t1.tags->>'c3', (t1.fields->>'C 1')::int OFFSET 100 LIMIT 10; + t1 +---------------------------------------------------------------------------------------------------------------------------------------------------- + ("Fri Jan 02 00:00:00 1970 PST","{""c3"": ""00101""}","{""c2"": ""1"", ""c6"": ""1"", ""c7"": ""1 "", ""c8"": ""foo"", ""C 1"": ""101""}") + ("Sat Jan 03 00:00:00 1970 PST","{""c3"": ""00102""}","{""c2"": ""2"", ""c6"": ""2"", ""c7"": ""2 "", ""c8"": ""foo"", ""C 1"": ""102""}") + ("Sun Jan 04 00:00:00 1970 PST","{""c3"": ""00103""}","{""c2"": ""3"", ""c6"": ""3"", ""c7"": ""3 "", ""c8"": ""foo"", ""C 1"": ""103""}") + ("Mon Jan 05 00:00:00 1970 PST","{""c3"": ""00104""}","{""c2"": ""4"", ""c6"": ""4"", ""c7"": ""4 "", ""c8"": ""foo"", ""C 1"": ""104""}") + ("Tue Jan 06 00:00:00 1970 PST","{""c3"": ""00105""}","{""c2"": ""5"", ""c6"": ""5"", ""c7"": ""5 "", ""c8"": ""foo"", ""C 1"": ""105""}") + ("Wed Jan 07 00:00:00 1970 PST","{""c3"": ""00106""}","{""c2"": ""6"", ""c6"": ""6"", ""c7"": ""6 "", ""c8"": ""foo"", ""C 1"": ""106""}") + ("Thu Jan 08 00:00:00 1970 PST","{""c3"": ""00107""}","{""c2"": ""7"", ""c6"": ""7"", ""c7"": ""7 "", ""c8"": ""foo"", ""C 1"": ""107""}") + ("Fri Jan 09 00:00:00 1970 PST","{""c3"": ""00108""}","{""c2"": ""8"", ""c6"": ""8"", ""c7"": ""8 "", ""c8"": ""foo"", ""C 1"": ""108""}") + ("Sat Jan 10 00:00:00 1970 PST","{""c3"": ""00109""}","{""c2"": ""9"", ""c6"": ""9"", ""c7"": ""9 "", ""c8"": ""foo"", ""C 1"": ""109""}") + ("Sun Jan 11 00:00:00 1970 PST","{""c3"": ""00110""}","{""c2"": ""0"", ""c6"": ""0"", ""c7"": ""0 "", ""c8"": ""foo"", ""C 1"": ""110""}") +(10 rows) + +-- empty result +--Testcase 45: +SELECT * FROM ft1 WHERE false; + time | tags | fields +------+------+-------- +(0 rows) + +-- with WHERE clause +--Testcase 46: +EXPLAIN (VERBOSE, COSTS OFF) SELECT * FROM ft1 t1 WHERE (t1.fields->>'C 1')::int = 101 AND t1.fields->>'c6' = '1' AND t1.fields->>'c7' >= '1'; + QUERY PLAN +------------------------------------------------------------------------------- + Foreign Scan on public.ft1 t1 + Output: "time", tags, fields + Filter: ((t1.fields ->> 'c7'::text) >= '1'::text) + InfluxDB query: SELECT * FROM "T1" WHERE (("c6" = '1')) AND (("C 1" = 101)) +(4 rows) + +--Testcase 47: +SELECT * FROM ft1 t1 WHERE (t1.fields->>'C 1')::int = 101 AND t1.fields->>'c6' = '1' AND t1.fields->>'c7' >= '1'; + time | tags | fields +------------------------------+-----------------+----------------------------------------------------------------------- + Fri Jan 02 00:00:00 1970 PST | {"c3": "00101"} | {"c2": "1", "c6": "1", "c7": "1 ", "c8": "foo", "C 1": "101"} +(1 row) + +-- with FOR UPDATE/SHARE +--Testcase 48: +EXPLAIN (VERBOSE, COSTS OFF) SELECT * FROM ft1 t1 WHERE (fields->>'C 1')::int = 101 FOR UPDATE; + QUERY PLAN +------------------------------------------------------------------ + LockRows + Output: "time", tags, fields, t1.* + -> Foreign Scan on public.ft1 t1 + Output: "time", tags, fields, t1.* + InfluxDB query: SELECT * FROM "T1" WHERE (("C 1" = 101)) +(5 rows) + +--Testcase 49: +SELECT * FROM ft1 t1 WHERE (fields->>'C 1')::int = 101 FOR UPDATE; + time | tags | fields +------------------------------+-----------------+----------------------------------------------------------------------- + Fri Jan 02 00:00:00 1970 PST | {"c3": "00101"} | {"c2": "1", "c6": "1", "c7": "1 ", "c8": "foo", "C 1": "101"} +(1 row) + +--Testcase 50: +EXPLAIN (VERBOSE, COSTS OFF) SELECT * FROM ft1 t1 WHERE (fields->>'C 1')::int = 102 FOR SHARE; + QUERY PLAN +------------------------------------------------------------------ + LockRows + Output: "time", tags, fields, t1.* + -> Foreign Scan on public.ft1 t1 + Output: "time", tags, fields, t1.* + InfluxDB query: SELECT * FROM "T1" WHERE (("C 1" = 102)) +(5 rows) + +--Testcase 51: +SELECT * FROM ft1 t1 WHERE (fields->>'C 1')::int = 102 FOR SHARE; + time | tags | fields +------------------------------+-----------------+----------------------------------------------------------------------- + Sat Jan 03 00:00:00 1970 PST | {"c3": "00102"} | {"c2": "2", "c6": "2", "c7": "2 ", "c8": "foo", "C 1": "102"} +(1 row) + +-- aggregate +--Testcase 52: +SELECT COUNT(*) FROM ft1 t1; + count +------- + 1000 +(1 row) + +-- subquery +--Testcase 53: +SELECT * FROM ft1 t1 WHERE t1.tags->>'c3' IN (SELECT tags->>'c3' FROM ft2 t2 WHERE (fields->>'C 1')::int <= 10) ORDER BY (fields->>'C 1')::int; + time | tags | fields +------------------------------+-----------------+---------------------------------------------------------------------- + Fri Jan 02 00:00:00 1970 PST | {"c3": "00001"} | {"c2": "1", "c6": "1", "c7": "1 ", "c8": "foo", "C 1": "1"} + Sat Jan 03 00:00:00 1970 PST | {"c3": "00002"} | {"c2": "2", "c6": "2", "c7": "2 ", "c8": "foo", "C 1": "2"} + Sun Jan 04 00:00:00 1970 PST | {"c3": "00003"} | {"c2": "3", "c6": "3", "c7": "3 ", "c8": "foo", "C 1": "3"} + Mon Jan 05 00:00:00 1970 PST | {"c3": "00004"} | {"c2": "4", "c6": "4", "c7": "4 ", "c8": "foo", "C 1": "4"} + Tue Jan 06 00:00:00 1970 PST | {"c3": "00005"} | {"c2": "5", "c6": "5", "c7": "5 ", "c8": "foo", "C 1": "5"} + Wed Jan 07 00:00:00 1970 PST | {"c3": "00006"} | {"c2": "6", "c6": "6", "c7": "6 ", "c8": "foo", "C 1": "6"} + Thu Jan 08 00:00:00 1970 PST | {"c3": "00007"} | {"c2": "7", "c6": "7", "c7": "7 ", "c8": "foo", "C 1": "7"} + Fri Jan 09 00:00:00 1970 PST | {"c3": "00008"} | {"c2": "8", "c6": "8", "c7": "8 ", "c8": "foo", "C 1": "8"} + Sat Jan 10 00:00:00 1970 PST | {"c3": "00009"} | {"c2": "9", "c6": "9", "c7": "9 ", "c8": "foo", "C 1": "9"} + Sun Jan 11 00:00:00 1970 PST | {"c3": "00010"} | {"c2": "0", "c6": "0", "c7": "0 ", "c8": "foo", "C 1": "10"} +(10 rows) + +-- subquery+MAX +--Testcase 54: +SELECT * FROM ft1 t1 WHERE t1.tags->>'c3' = (SELECT MAX(tags->>'c3') FROM ft2 t2) ORDER BY (fields->>'C 1')::int; + time | tags | fields +------------------------------+-----------------+------------------------------------------------------------------------ + Thu Jan 01 00:00:00 1970 PST | {"c3": "01000"} | {"c2": "0", "c6": "0", "c7": "0 ", "c8": "foo", "C 1": "1000"} +(1 row) + +-- used in CTE +--Testcase 55: +WITH t1 AS (SELECT * FROM ft1 WHERE (fields->>'C 1')::int <= 10) SELECT (t2.fields->>'C 1')::int c1, (t2.fields->>'c2')::int c2, t2.tags->>'c3' c3, t2.time FROM t1, ft2 t2 WHERE (t1.fields->>'C 1')::int = (t2.fields->>'C 1')::int ORDER BY (t1.fields->>'C 1')::int; + c1 | c2 | c3 | time +----+----+-------+------------------------------ + 1 | 1 | 00001 | Fri Jan 02 00:00:00 1970 PST + 2 | 2 | 00002 | Sat Jan 03 00:00:00 1970 PST + 3 | 3 | 00003 | Sun Jan 04 00:00:00 1970 PST + 4 | 4 | 00004 | Mon Jan 05 00:00:00 1970 PST + 5 | 5 | 00005 | Tue Jan 06 00:00:00 1970 PST + 6 | 6 | 00006 | Wed Jan 07 00:00:00 1970 PST + 7 | 7 | 00007 | Thu Jan 08 00:00:00 1970 PST + 8 | 8 | 00008 | Fri Jan 09 00:00:00 1970 PST + 9 | 9 | 00009 | Sat Jan 10 00:00:00 1970 PST + 10 | 0 | 00010 | Sun Jan 11 00:00:00 1970 PST +(10 rows) + +-- fixed values +--Testcase 56: +SELECT 'fixed', NULL FROM ft1 t1 WHERE (fields->>'C 1')::int = 1; + ?column? | ?column? +----------+---------- + fixed | +(1 row) + +-- Test forcing the remote server to produce sorted data for a merge join. +--Testcase 57: +SET enable_hashjoin TO false; +--Testcase 58: +SET enable_nestloop TO false; +-- inner join; expressions in the clauses appear in the equivalence class list +--Testcase 59: +EXPLAIN (VERBOSE, COSTS OFF) + SELECT t1.c1, t2."C 1" FROM (SELECT (fields->>'C 1')::int c1, (fields->>'c2')::int c2, tags->>'c3' c3, fields->>'c4' c4, fields->>'c5' c5, fields->>'c6' c6, fields->>'c7' c7, fields->>'c8' c8 FROM ft2 t1) t1 JOIN (SELECT (fields->>'C 1')::int "C 1", (fields->>'c2')::int c2, tags->>'c3' c3, fields->>'c4' c4, fields->>'c5' c5, fields->>'c6' c6, fields->>'c7' c7, fields->>'c8' c8 FROM "S 1"."T 1" t2) t2 ON ((t1.c1)::int = (t2."C 1")::int) OFFSET 100 LIMIT 10; + QUERY PLAN +----------------------------------------------------------------------------------------------------------- + Limit + Output: (((t1.fields ->> 'C 1'::text))::integer), (((t2.fields ->> 'C 1'::text))::integer) + -> Merge Join + Output: (((t1.fields ->> 'C 1'::text))::integer), (((t2.fields ->> 'C 1'::text))::integer) + Merge Cond: ((((t1.fields ->> 'C 1'::text))::integer) = (((t2.fields ->> 'C 1'::text))::integer)) + -> Sort + Output: t1.fields, (((t1.fields ->> 'C 1'::text))::integer) + Sort Key: (((t1.fields ->> 'C 1'::text))::integer) + -> Foreign Scan on public.ft2 t1 + Output: t1.fields, ((t1.fields ->> 'C 1'::text))::integer + InfluxDB query: SELECT * FROM "T1" + -> Sort + Output: t2.fields, (((t2.fields ->> 'C 1'::text))::integer) + Sort Key: (((t2.fields ->> 'C 1'::text))::integer) + -> Foreign Scan on "S 1"."T 1" t2 + Output: t2.fields, ((t2.fields ->> 'C 1'::text))::integer + InfluxDB query: SELECT * FROM "T1" +(17 rows) + +--Testcase 60: +SELECT t1.c1, t2."C 1" FROM (SELECT (fields->>'C 1')::int c1, (fields->>'c2')::int c2, tags->>'c3' c3, fields->>'c4' c4, fields->>'c5' c5, fields->>'c6' c6, fields->>'c7' c7, fields->>'c8' c8 FROM ft2 t1) t1 JOIN (SELECT (fields->>'C 1')::int "C 1", (fields->>'c2')::int c2, tags->>'c3' c3, fields->>'c4' c4, fields->>'c5' c5, fields->>'c6' c6, fields->>'c7' c7, fields->>'c8' c8 FROM "S 1"."T 1" t2) t2 ON ((t1.c1)::int = (t2."C 1")::int) OFFSET 100 LIMIT 10; + c1 | C 1 +-----+----- + 101 | 101 + 102 | 102 + 103 | 103 + 104 | 104 + 105 | 105 + 106 | 106 + 107 | 107 + 108 | 108 + 109 | 109 + 110 | 110 +(10 rows) + +-- outer join; expressions in the clauses do not appear in equivalence class +-- list but no output change as compared to the previous query +--Testcase 61: +EXPLAIN (VERBOSE, COSTS OFF) + SELECT t1.c1, t2."C 1" FROM (SELECT (fields->>'C 1')::int c1, (fields->>'c2')::int c2, tags->>'c3' c3, fields->>'c4' c4, fields->>'c5' c5, fields->>'c6' c6, fields->>'c7' c7, fields->>'c8' c8 FROM ft2 t1) t1 LEFT JOIN (SELECT (fields->>'C 1')::int "C 1", (fields->>'c2')::int c2, tags->>'c3' c3, fields->>'c4' c4, fields->>'c5' c5, fields->>'c6' c6, fields->>'c7' c7, fields->>'c8' c8 FROM "S 1"."T 1" t2) t2 ON ((t1.c1)::int = (t2."C 1")::int) OFFSET 100 LIMIT 10; + QUERY PLAN +----------------------------------------------------------------------------------------------------------------------- + Limit + Output: (((t1.fields ->> 'C 1'::text))::integer), (((t2.fields ->> 'C 1'::text))::integer) + -> Merge Right Join + Output: (((t1.fields ->> 'C 1'::text))::integer), (((t2.fields ->> 'C 1'::text))::integer) + Merge Cond: ((((t2.fields ->> 'C 1'::text))::integer) = (((t1.fields ->> 'C 1'::text))::integer)) + -> Sort + Output: t2.fields, (((t2.fields ->> 'C 1'::text))::integer), (((t2.fields ->> 'C 1'::text))::integer) + Sort Key: (((t2.fields ->> 'C 1'::text))::integer) + -> Foreign Scan on "S 1"."T 1" t2 + Output: t2.fields, ((t2.fields ->> 'C 1'::text))::integer, ((t2.fields ->> 'C 1'::text))::integer + InfluxDB query: SELECT * FROM "T1" + -> Sort + Output: t1.fields, (((t1.fields ->> 'C 1'::text))::integer) + Sort Key: (((t1.fields ->> 'C 1'::text))::integer) + -> Foreign Scan on public.ft2 t1 + Output: t1.fields, ((t1.fields ->> 'C 1'::text))::integer + InfluxDB query: SELECT * FROM "T1" +(17 rows) + +--Testcase 62: +SELECT t1.c1, t2."C 1" FROM (SELECT (fields->>'C 1')::int c1, (fields->>'c2')::int c2, tags->>'c3' c3, fields->>'c4' c4, fields->>'c5' c5, fields->>'c6' c6, fields->>'c7' c7, fields->>'c8' c8 FROM ft2 t1) t1 LEFT JOIN (SELECT (fields->>'C 1')::int "C 1", (fields->>'c2')::int c2, tags->>'c3' c3, fields->>'c4' c4, fields->>'c5' c5, fields->>'c6' c6, fields->>'c7' c7, fields->>'c8' c8 FROM "S 1"."T 1" t2) t2 ON ((t1.c1)::int = (t2."C 1")::int) OFFSET 100 LIMIT 10; + c1 | C 1 +-----+----- + 101 | 101 + 102 | 102 + 103 | 103 + 104 | 104 + 105 | 105 + 106 | 106 + 107 | 107 + 108 | 108 + 109 | 109 + 110 | 110 +(10 rows) + +-- A join between 2 foreign tables. ORDER BY clause is added to the +-- foreign join so that the other table can be joined using merge join strategy. +--Testcase 63: +EXPLAIN (VERBOSE, COSTS OFF) + SELECT t1."C 1" FROM (SELECT (fields->>'C 1')::int "C 1", (fields->>'c2')::int c2, tags->>'c3' c3, fields->>'c4' c4, fields->>'c5' c5, fields->>'c6' c6, fields->>'c7' c7, fields->>'c8' c8 FROM "S 1"."T 1" t1) t1 left join (SELECT (fields->>'C 1')::int c1, (fields->>'c2')::int c2, tags->>'c3' c3, fields->>'c4' c4, fields->>'c5' c5, fields->>'c6' c6, fields->>'c7' c7, fields->>'c8' c8 FROM ft1 t2) t2 join (SELECT (fields->>'C 1')::int c1, (fields->>'c2')::int c2, tags->>'c3' c3, fields->>'c4' c4, fields->>'c5' c5, fields->>'c6' c6, fields->>'c7' c7, fields->>'c8' c8 FROM ft2 t3) t3 on ((t2.c1)::int = (t3.c1)::int) on ((t3.c1)::int = (t1."C 1")::int) OFFSET 100 LIMIT 10; + QUERY PLAN +----------------------------------------------------------------------------------------------------------------------- + Limit + Output: (((t1.fields ->> 'C 1'::text))::integer) + -> Merge Left Join + Output: (((t1.fields ->> 'C 1'::text))::integer) + Merge Cond: ((((t1.fields ->> 'C 1'::text))::integer) = ((t3.fields ->> 'C 1'::text))::integer) + -> Sort + Output: t1.fields, (((t1.fields ->> 'C 1'::text))::integer) + Sort Key: (((t1.fields ->> 'C 1'::text))::integer) + -> Foreign Scan on "S 1"."T 1" t1 + Output: t1.fields, ((t1.fields ->> 'C 1'::text))::integer + InfluxDB query: SELECT * FROM "T1" + -> Materialize + Output: t3.fields + -> Merge Join + Output: t3.fields + Merge Cond: ((((t2.fields ->> 'C 1'::text))::integer) = (((t3.fields ->> 'C 1'::text))::integer)) + -> Sort + Output: t2.fields, (((t2.fields ->> 'C 1'::text))::integer) + Sort Key: (((t2.fields ->> 'C 1'::text))::integer) + -> Foreign Scan on public.ft1 t2 + Output: t2.fields, ((t2.fields ->> 'C 1'::text))::integer + InfluxDB query: SELECT * FROM "T1" + -> Sort + Output: t3.fields, (((t3.fields ->> 'C 1'::text))::integer) + Sort Key: (((t3.fields ->> 'C 1'::text))::integer) + -> Foreign Scan on public.ft2 t3 + Output: t3.fields, ((t3.fields ->> 'C 1'::text))::integer + InfluxDB query: SELECT * FROM "T1" +(28 rows) + +--Testcase 64: +SELECT t1."C 1" FROM (SELECT (fields->>'C 1')::int "C 1", (fields->>'c2')::int c2, tags->>'c3' c3, fields->>'c4' c4, fields->>'c5' c5, fields->>'c6' c6, fields->>'c7' c7, fields->>'c8' c8 FROM "S 1"."T 1" t1) t1 left join (SELECT (fields->>'C 1')::int c1, (fields->>'c2')::int c2, tags->>'c3' c3, fields->>'c4' c4, fields->>'c5' c5, fields->>'c6' c6, fields->>'c7' c7, fields->>'c8' c8 FROM ft1 t2) t2 join (SELECT (fields->>'C 1')::int c1, (fields->>'c2')::int c2, tags->>'c3' c3, fields->>'c4' c4, fields->>'c5' c5, fields->>'c6' c6, fields->>'c7' c7, fields->>'c8' c8 FROM ft2 t3) t3 on ((t2.c1)::int = (t3.c1)::int) on ((t3.c1)::int = (t1."C 1")::int) OFFSET 100 LIMIT 10; + C 1 +----- + 101 + 102 + 103 + 104 + 105 + 106 + 107 + 108 + 109 + 110 +(10 rows) + +-- Test similar to above, except that the full join prevents any equivalence +-- classes from being merged. This produces single relation equivalence classes +-- included in join restrictions. +--Testcase 65: +EXPLAIN (VERBOSE, COSTS OFF) + SELECT t1."C 1", t2.c1, t3.c1 FROM (SELECT (fields->>'C 1')::int "C 1", (fields->>'c2')::int c2, tags->>'c3' c3, fields->>'c4' c4, fields->>'c5' c5, fields->>'c6' c6, fields->>'c7' c7, fields->>'c8' c8 FROM "S 1"."T 1" t1) t1 left join (SELECT (fields->>'C 1')::int c1, (fields->>'c2')::int c2, tags->>'c3' c3, fields->>'c4' c4, fields->>'c5' c5, fields->>'c6' c6, fields->>'c7' c7, fields->>'c8' c8 FROM ft1 t2) t2 full join (SELECT (fields->>'C 1')::int c1, (fields->>'c2')::int c2, tags->>'c3' c3, fields->>'c4' c4, fields->>'c5' c5, fields->>'c6' c6, fields->>'c7' c7, fields->>'c8' c8 FROM ft2 t3) t3 on ((t2.c1)::int = (t3.c1)::int) on ((t3.c1)::int = (t1."C 1")::int) OFFSET 100 LIMIT 10; + QUERY PLAN +---------------------------------------------------------------------------------------------------------------------------------------------- + Limit + Output: (((t1.fields ->> 'C 1'::text))::integer), (((t2.fields ->> 'C 1'::text))::integer), (((t3.fields ->> 'C 1'::text))::integer) + -> Merge Left Join + Output: (((t1.fields ->> 'C 1'::text))::integer), (((t2.fields ->> 'C 1'::text))::integer), (((t3.fields ->> 'C 1'::text))::integer) + Merge Cond: ((((t1.fields ->> 'C 1'::text))::integer) = (((t3.fields ->> 'C 1'::text))::integer)) + -> Sort + Output: t1.fields, (((t1.fields ->> 'C 1'::text))::integer) + Sort Key: (((t1.fields ->> 'C 1'::text))::integer) + -> Foreign Scan on "S 1"."T 1" t1 + Output: t1.fields, ((t1.fields ->> 'C 1'::text))::integer + InfluxDB query: SELECT * FROM "T1" + -> Materialize + Output: (((t3.fields ->> 'C 1'::text))::integer), (((t2.fields ->> 'C 1'::text))::integer) + -> Merge Left Join + Output: (((t3.fields ->> 'C 1'::text))::integer), (((t2.fields ->> 'C 1'::text))::integer) + Merge Cond: ((((t3.fields ->> 'C 1'::text))::integer) = (((t2.fields ->> 'C 1'::text))::integer)) + -> Sort + Output: (((t3.fields ->> 'C 1'::text))::integer) + Sort Key: (((t3.fields ->> 'C 1'::text))::integer) + -> Foreign Scan on public.ft2 t3 + Output: ((t3.fields ->> 'C 1'::text))::integer + InfluxDB query: SELECT "C 1" FROM "T1" + -> Sort + Output: (((t2.fields ->> 'C 1'::text))::integer) + Sort Key: (((t2.fields ->> 'C 1'::text))::integer) + -> Foreign Scan on public.ft1 t2 + Output: ((t2.fields ->> 'C 1'::text))::integer + InfluxDB query: SELECT "C 1" FROM "T1" +(28 rows) + +--Testcase 66: +SELECT t1."C 1", t2.c1, t3.c1 FROM (SELECT (fields->>'C 1')::int "C 1", (fields->>'c2')::int c2, tags->>'c3' c3, fields->>'c4' c4, fields->>'c5' c5, fields->>'c6' c6, fields->>'c7' c7, fields->>'c8' c8 FROM "S 1"."T 1" t1) t1 left join (SELECT (fields->>'C 1')::int c1, (fields->>'c2')::int c2, tags->>'c3' c3, fields->>'c4' c4, fields->>'c5' c5, fields->>'c6' c6, fields->>'c7' c7, fields->>'c8' c8 FROM ft1 t2) t2 full join (SELECT (fields->>'C 1')::int c1, (fields->>'c2')::int c2, tags->>'c3' c3, fields->>'c4' c4, fields->>'c5' c5, fields->>'c6' c6, fields->>'c7' c7, fields->>'c8' c8 FROM ft2 t3) t3 on ((t2.c1)::int = (t3.c1)::int) on ((t3.c1)::int = (t1."C 1")::int) OFFSET 100 LIMIT 10; + C 1 | c1 | c1 +-----+-----+----- + 101 | 101 | 101 + 102 | 102 | 102 + 103 | 103 | 103 + 104 | 104 | 104 + 105 | 105 | 105 + 106 | 106 | 106 + 107 | 107 | 107 + 108 | 108 | 108 + 109 | 109 | 109 + 110 | 110 | 110 +(10 rows) + +-- Test similar to above with all full outer joins +--Testcase 67: +EXPLAIN (VERBOSE, COSTS OFF) + SELECT t1."C 1", t2.c1, t3.c1 FROM (SELECT (fields->>'C 1')::int "C 1", (fields->>'c2')::int c2, tags->>'c3' c3, fields->>'c4' c4, fields->>'c5' c5, fields->>'c6' c6, fields->>'c7' c7, fields->>'c8' c8 FROM "S 1"."T 1" t1) t1 full join (SELECT (fields->>'C 1')::int c1, (fields->>'c2')::int c2, tags->>'c3' c3, fields->>'c4' c4, fields->>'c5' c5, fields->>'c6' c6, fields->>'c7' c7, fields->>'c8' c8 FROM ft1 t2) t2 full join (SELECT (fields->>'C 1')::int c1, (fields->>'c2')::int c2, tags->>'c3' c3, fields->>'c4' c4, fields->>'c5' c5, fields->>'c6' c6, fields->>'c7' c7, fields->>'c8' c8 FROM ft2 t3) t3 on ((t2.c1)::int = (t3.c1)::int) on ((t3.c1)::int = (t1."C 1")::int) OFFSET 100 LIMIT 10; + QUERY PLAN +---------------------------------------------------------------------------------------------------------------------------------------------- + Limit + Output: (((t1.fields ->> 'C 1'::text))::integer), (((t2.fields ->> 'C 1'::text))::integer), (((t3.fields ->> 'C 1'::text))::integer) + -> Merge Full Join + Output: (((t1.fields ->> 'C 1'::text))::integer), (((t2.fields ->> 'C 1'::text))::integer), (((t3.fields ->> 'C 1'::text))::integer) + Merge Cond: ((((t1.fields ->> 'C 1'::text))::integer) = (((t3.fields ->> 'C 1'::text))::integer)) + -> Sort + Output: (((t1.fields ->> 'C 1'::text))::integer) + Sort Key: (((t1.fields ->> 'C 1'::text))::integer) + -> Foreign Scan on "S 1"."T 1" t1 + Output: ((t1.fields ->> 'C 1'::text))::integer + InfluxDB query: SELECT "C 1" FROM "T1" + -> Sort + Output: (((t2.fields ->> 'C 1'::text))::integer), (((t3.fields ->> 'C 1'::text))::integer) + Sort Key: (((t3.fields ->> 'C 1'::text))::integer) + -> Merge Full Join + Output: (((t2.fields ->> 'C 1'::text))::integer), (((t3.fields ->> 'C 1'::text))::integer) + Merge Cond: ((((t2.fields ->> 'C 1'::text))::integer) = (((t3.fields ->> 'C 1'::text))::integer)) + -> Sort + Output: (((t2.fields ->> 'C 1'::text))::integer) + Sort Key: (((t2.fields ->> 'C 1'::text))::integer) + -> Foreign Scan on public.ft1 t2 + Output: ((t2.fields ->> 'C 1'::text))::integer + InfluxDB query: SELECT "C 1" FROM "T1" + -> Sort + Output: (((t3.fields ->> 'C 1'::text))::integer) + Sort Key: (((t3.fields ->> 'C 1'::text))::integer) + -> Foreign Scan on public.ft2 t3 + Output: ((t3.fields ->> 'C 1'::text))::integer + InfluxDB query: SELECT "C 1" FROM "T1" +(29 rows) + +--Testcase 68: +SELECT t1."C 1", t2.c1, t3.c1 FROM (SELECT (fields->>'C 1')::int "C 1", (fields->>'c2')::int c2, tags->>'c3' c3, fields->>'c4' c4, fields->>'c5' c5, fields->>'c6' c6, fields->>'c7' c7, fields->>'c8' c8 FROM "S 1"."T 1" t1) t1 full join (SELECT (fields->>'C 1')::int c1, (fields->>'c2')::int c2, tags->>'c3' c3, fields->>'c4' c4, fields->>'c5' c5, fields->>'c6' c6, fields->>'c7' c7, fields->>'c8' c8 FROM ft1 t2) t2 full join (SELECT (fields->>'C 1')::int c1, (fields->>'c2')::int c2, tags->>'c3' c3, fields->>'c4' c4, fields->>'c5' c5, fields->>'c6' c6, fields->>'c7' c7, fields->>'c8' c8 FROM ft2 t3) t3 on ((t2.c1)::int = (t3.c1)::int) on ((t3.c1)::int = (t1."C 1")::int) OFFSET 100 LIMIT 10; + C 1 | c1 | c1 +-----+-----+----- + 101 | 101 | 101 + 102 | 102 | 102 + 103 | 103 | 103 + 104 | 104 | 104 + 105 | 105 | 105 + 106 | 106 | 106 + 107 | 107 | 107 + 108 | 108 | 108 + 109 | 109 | 109 + 110 | 110 | 110 +(10 rows) + +--Testcase 69: +RESET enable_hashjoin; +--Testcase 70: +RESET enable_nestloop; +-- Test executing assertion in estimate_path_cost_size() that makes sure that +-- retrieved_rows for foreign rel re-used to cost pre-sorted foreign paths is +-- a sensible value even when the rel has tuples=0 +--Testcase 71: +CREATE FOREIGN TABLE loct_empty (fields jsonb OPTIONS(fields 'true')) SERVER influxdb_svr OPTIONS (schemaless 'true'); +--Testcase 792: +CREATE FOREIGN TABLE loct_empty_nsc (c1 int NOT NULL, c2 text) SERVER influxdb_svr OPTIONS (table 'loct_empty'); +--Testcase 72: +CREATE FOREIGN TABLE ft_empty (fields jsonb OPTIONS(fields 'true')) SERVER influxdb_svr OPTIONS (table 'loct_empty', schemaless 'true'); +--Testcase 73: +INSERT INTO loct_empty_nsc + SELECT id, 'AAA' || to_char(id, 'FM000') FROM generate_series(1, 100) id; +--Testcase 74: +DELETE FROM loct_empty_nsc; +--Testcase 793: +DROP FOREIGN TABLE loct_empty_nsc; +--ANALYZE ft_empty; +--Testcase 75: +EXPLAIN (VERBOSE, COSTS OFF) SELECT * FROM ft_empty ORDER BY (fields->>'c1')::int; + QUERY PLAN +------------------------------------------------------------ + Sort + Output: fields, (((fields ->> 'c1'::text))::integer) + Sort Key: (((ft_empty.fields ->> 'c1'::text))::integer) + -> Foreign Scan on public.ft_empty + Output: fields, ((fields ->> 'c1'::text))::integer + InfluxDB query: SELECT * FROM "loct_empty" +(6 rows) + +-- =================================================================== +-- WHERE with remotely-executable conditions +-- =================================================================== +--Testcase 76: +EXPLAIN (VERBOSE, COSTS OFF) SELECT * FROM ft1 t1 WHERE (t1.fields->>'C 1')::int = 1; -- Var, OpExpr(b), Const + QUERY PLAN +---------------------------------------------------------- + Foreign Scan on public.ft1 t1 + Output: "time", tags, fields + InfluxDB query: SELECT * FROM "T1" WHERE (("C 1" = 1)) +(3 rows) + +--Testcase 77: +EXPLAIN (VERBOSE, COSTS OFF) SELECT * FROM ft1 t1 WHERE (t1.fields->>'C 1')::int = 100 AND (t1.fields->>'c2')::int = 0; -- BoolExpr + QUERY PLAN +----------------------------------------------------------------------------- + Foreign Scan on public.ft1 t1 + Output: "time", tags, fields + InfluxDB query: SELECT * FROM "T1" WHERE (("C 1" = 100)) AND (("c2" = 0)) +(3 rows) + +--Testcase 78: +EXPLAIN (VERBOSE, COSTS OFF) SELECT * FROM ft1 t1 WHERE (t1.fields->>'C 1')::int IS NULL; -- NullTest + QUERY PLAN +------------------------------------------------------------ + Foreign Scan on public.ft1 t1 + Output: "time", tags, fields + Filter: (((t1.fields ->> 'C 1'::text))::integer IS NULL) + InfluxDB query: SELECT * FROM "T1" +(4 rows) + +--Testcase 79: +EXPLAIN (VERBOSE, COSTS OFF) SELECT * FROM ft1 t1 WHERE (t1.fields->>'C 1')::int IS NOT NULL; -- NullTest + QUERY PLAN +---------------------------------------------------------------- + Foreign Scan on public.ft1 t1 + Output: "time", tags, fields + Filter: (((t1.fields ->> 'C 1'::text))::integer IS NOT NULL) + InfluxDB query: SELECT * FROM "T1" +(4 rows) + +--Testcase 80: +EXPLAIN (VERBOSE, COSTS OFF) SELECT * FROM ft1 t1 WHERE round(abs((t1.fields->>'C 1')::int), 0) = 1; -- FuncExpr + QUERY PLAN +--------------------------------------------------------------------------------------------- + Foreign Scan on public.ft1 t1 + Output: "time", tags, fields + Filter: (round((abs(((t1.fields ->> 'C 1'::text))::integer))::numeric, 0) = '1'::numeric) + InfluxDB query: SELECT * FROM "T1" +(4 rows) + +--Testcase 81: +EXPLAIN (VERBOSE, COSTS OFF) SELECT * FROM ft1 t1 WHERE (t1.fields->>'C 1')::int = -(t1.fields->>'C 1')::int; -- OpExpr(l) + QUERY PLAN +------------------------------------------------------------------ + Foreign Scan on public.ft1 t1 + Output: "time", tags, fields + InfluxDB query: SELECT * FROM "T1" WHERE (("C 1" = (- "C 1"))) +(3 rows) + +--Testcase 82: +EXPLAIN (VERBOSE, COSTS OFF) SELECT * FROM ft1 t1 WHERE ((t1.fields->>'C 1')::int IS NOT NULL) IS DISTINCT FROM ((t1.fields->>'C 1')::int IS NOT NULL); -- DistinctExpr + QUERY PLAN +---------------------------------------------------------------------------------------------------------------------------------------- + Foreign Scan on public.ft1 t1 + Output: "time", tags, fields + Filter: ((((t1.fields ->> 'C 1'::text))::integer IS NOT NULL) IS DISTINCT FROM (((t1.fields ->> 'C 1'::text))::integer IS NOT NULL)) + InfluxDB query: SELECT * FROM "T1" +(4 rows) + +--Testcase 83: +EXPLAIN (VERBOSE, COSTS OFF) SELECT * FROM ft1 t1 WHERE (t1.fields->>'C 1')::int = ANY(ARRAY[(fields->>'c2')::int, 1, (t1.fields->>'C 1')::int + 0]); -- ScalarArrayOpExpr + QUERY PLAN +----------------------------------------------------------------------------------------------------- + Foreign Scan on public.ft1 t1 + Output: "time", tags, fields + InfluxDB query: SELECT * FROM "T1" WHERE (("C 1" = "c2") OR ("C 1" = 1) OR ("C 1" = ("C 1" + 0))) +(3 rows) + +--Testcase 84: +EXPLAIN (VERBOSE, COSTS OFF) SELECT * FROM ft1 t1 WHERE (t1.fields->>'C 1')::int = (ARRAY[(t1.fields->>'C 1')::int,(fields->>'c2')::int,3])[1]; -- SubscriptingRef + QUERY PLAN +--------------------------------------------------------------------------------------------------------------------------------------------------- + Foreign Scan on public.ft1 t1 + Output: "time", tags, fields + Filter: (((t1.fields ->> 'C 1'::text))::integer = (ARRAY[((t1.fields ->> 'C 1'::text))::integer, ((t1.fields ->> 'c2'::text))::integer, 3])[1]) + InfluxDB query: SELECT * FROM "T1" +(4 rows) + +--Testcase 85: +EXPLAIN (VERBOSE, COSTS OFF) SELECT * FROM ft1 t1 WHERE fields->>'c6' = E'foo''s\\bar'; -- check special chars + QUERY PLAN +--------------------------------------------------------------------- + Foreign Scan on public.ft1 t1 + Output: "time", tags, fields + InfluxDB query: SELECT * FROM "T1" WHERE (("c6" = 'foo''s\\bar')) +(3 rows) + +--Testcase 86: +EXPLAIN (VERBOSE, COSTS OFF) SELECT * FROM ft1 t1 WHERE fields->>'c8' = 'foo'; -- can't be sent to remote + QUERY PLAN +------------------------------------------------------------- + Foreign Scan on public.ft1 t1 + Output: "time", tags, fields + InfluxDB query: SELECT * FROM "T1" WHERE (("c8" = 'foo')) +(3 rows) + +-- parameterized remote path for foreign table +--Testcase 87: +EXPLAIN (VERBOSE, COSTS OFF) + SELECT * FROM "S 1"."T 1" a, ft2 b WHERE (a.fields->>'C 1')::int = 47 AND (b.fields->>'C 1')::int = (a.fields->>'c2')::int; + QUERY PLAN +--------------------------------------------------------------------------------------------- + Hash Join + Output: a."time", a.tags, a.fields, b."time", b.tags, b.fields + Hash Cond: (((b.fields ->> 'C 1'::text))::integer = ((a.fields ->> 'c2'::text))::integer) + -> Foreign Scan on public.ft2 b + Output: b."time", b.tags, b.fields + InfluxDB query: SELECT * FROM "T1" + -> Hash + Output: a."time", a.tags, a.fields + -> Foreign Scan on "S 1"."T 1" a + Output: a."time", a.tags, a.fields + InfluxDB query: SELECT * FROM "T1" WHERE (("C 1" = 47)) +(11 rows) + +--Testcase 88: +SELECT * FROM "S 1"."T 1" a, ft2 b WHERE (a.fields->>'C 1')::int = 47 AND (b.fields->>'C 1')::int = (a.fields->>'c2')::int; + time | tags | fields | time | tags | fields +------------------------------+-----------------+----------------------------------------------------------------------+------------------------------+-----------------+--------------------------------------------------------------------- + Tue Feb 17 00:00:00 1970 PST | {"c3": "00047"} | {"c2": "7", "c6": "7", "c7": "7 ", "c8": "foo", "C 1": "47"} | Thu Jan 08 00:00:00 1970 PST | {"c3": "00007"} | {"c2": "7", "c6": "7", "c7": "7 ", "c8": "foo", "C 1": "7"} +(1 row) + +-- check both safe and unsafe join conditions +--Testcase 89: +EXPLAIN (VERBOSE, COSTS OFF) + SELECT * FROM ft2 a, ft2 b + WHERE (a.fields->>'c2')::int = 6 AND (b.fields->>'C 1')::int = (a.fields->>'C 1')::int AND a.fields->>'c8' = 'foo' AND b.fields->>'c7' = upper(a.fields->>'c7'); + QUERY PLAN +------------------------------------------------------------------------------------------------------------------------------------------------------------------- + Hash Join + Output: a."time", a.tags, a.fields, b."time", b.tags, b.fields + Hash Cond: ((((b.fields ->> 'C 1'::text))::integer = ((a.fields ->> 'C 1'::text))::integer) AND ((b.fields ->> 'c7'::text) = upper((a.fields ->> 'c7'::text)))) + -> Foreign Scan on public.ft2 b + Output: b."time", b.tags, b.fields + InfluxDB query: SELECT * FROM "T1" + -> Hash + Output: a."time", a.tags, a.fields + -> Foreign Scan on public.ft2 a + Output: a."time", a.tags, a.fields + InfluxDB query: SELECT * FROM "T1" WHERE (("c8" = 'foo')) AND (("c2" = 6)) +(11 rows) + +--Testcase 90: +SELECT * FROM ft2 a, ft2 b +WHERE (a.fields->>'c2')::int = 6 AND (b.fields->>'C 1')::int = (a.fields->>'C 1')::int AND a.fields->>'c8' = 'foo' AND b.fields->>'c7' = upper(a.fields->>'c7') ORDER BY (a.fields->>'C 1')::int; + time | tags | fields | time | tags | fields +------------------------------+-----------------+-----------------------------------------------------------------------+------------------------------+-----------------+----------------------------------------------------------------------- + Wed Jan 07 00:00:00 1970 PST | {"c3": "00006"} | {"c2": "6", "c6": "6", "c7": "6 ", "c8": "foo", "C 1": "6"} | Wed Jan 07 00:00:00 1970 PST | {"c3": "00006"} | {"c2": "6", "c6": "6", "c7": "6 ", "c8": "foo", "C 1": "6"} + Sat Jan 17 00:00:00 1970 PST | {"c3": "00016"} | {"c2": "6", "c6": "6", "c7": "6 ", "c8": "foo", "C 1": "16"} | Sat Jan 17 00:00:00 1970 PST | {"c3": "00016"} | {"c2": "6", "c6": "6", "c7": "6 ", "c8": "foo", "C 1": "16"} + Tue Jan 27 00:00:00 1970 PST | {"c3": "00026"} | {"c2": "6", "c6": "6", "c7": "6 ", "c8": "foo", "C 1": "26"} | Tue Jan 27 00:00:00 1970 PST | {"c3": "00026"} | {"c2": "6", "c6": "6", "c7": "6 ", "c8": "foo", "C 1": "26"} + Fri Feb 06 00:00:00 1970 PST | {"c3": "00036"} | {"c2": "6", "c6": "6", "c7": "6 ", "c8": "foo", "C 1": "36"} | Fri Feb 06 00:00:00 1970 PST | {"c3": "00036"} | {"c2": "6", "c6": "6", "c7": "6 ", "c8": "foo", "C 1": "36"} + Mon Feb 16 00:00:00 1970 PST | {"c3": "00046"} | {"c2": "6", "c6": "6", "c7": "6 ", "c8": "foo", "C 1": "46"} | Mon Feb 16 00:00:00 1970 PST | {"c3": "00046"} | {"c2": "6", "c6": "6", "c7": "6 ", "c8": "foo", "C 1": "46"} + Thu Feb 26 00:00:00 1970 PST | {"c3": "00056"} | {"c2": "6", "c6": "6", "c7": "6 ", "c8": "foo", "C 1": "56"} | Thu Feb 26 00:00:00 1970 PST | {"c3": "00056"} | {"c2": "6", "c6": "6", "c7": "6 ", "c8": "foo", "C 1": "56"} + Sun Mar 08 00:00:00 1970 PST | {"c3": "00066"} | {"c2": "6", "c6": "6", "c7": "6 ", "c8": "foo", "C 1": "66"} | Sun Mar 08 00:00:00 1970 PST | {"c3": "00066"} | {"c2": "6", "c6": "6", "c7": "6 ", "c8": "foo", "C 1": "66"} + Wed Mar 18 00:00:00 1970 PST | {"c3": "00076"} | {"c2": "6", "c6": "6", "c7": "6 ", "c8": "foo", "C 1": "76"} | Wed Mar 18 00:00:00 1970 PST | {"c3": "00076"} | {"c2": "6", "c6": "6", "c7": "6 ", "c8": "foo", "C 1": "76"} + Sat Mar 28 00:00:00 1970 PST | {"c3": "00086"} | {"c2": "6", "c6": "6", "c7": "6 ", "c8": "foo", "C 1": "86"} | Sat Mar 28 00:00:00 1970 PST | {"c3": "00086"} | {"c2": "6", "c6": "6", "c7": "6 ", "c8": "foo", "C 1": "86"} + Tue Apr 07 00:00:00 1970 PST | {"c3": "00096"} | {"c2": "6", "c6": "6", "c7": "6 ", "c8": "foo", "C 1": "96"} | Tue Apr 07 00:00:00 1970 PST | {"c3": "00096"} | {"c2": "6", "c6": "6", "c7": "6 ", "c8": "foo", "C 1": "96"} + Wed Jan 07 00:00:00 1970 PST | {"c3": "00106"} | {"c2": "6", "c6": "6", "c7": "6 ", "c8": "foo", "C 1": "106"} | Wed Jan 07 00:00:00 1970 PST | {"c3": "00106"} | {"c2": "6", "c6": "6", "c7": "6 ", "c8": "foo", "C 1": "106"} + Sat Jan 17 00:00:00 1970 PST | {"c3": "00116"} | {"c2": "6", "c6": "6", "c7": "6 ", "c8": "foo", "C 1": "116"} | Sat Jan 17 00:00:00 1970 PST | {"c3": "00116"} | {"c2": "6", "c6": "6", "c7": "6 ", "c8": "foo", "C 1": "116"} + Tue Jan 27 00:00:00 1970 PST | {"c3": "00126"} | {"c2": "6", "c6": "6", "c7": "6 ", "c8": "foo", "C 1": "126"} | Tue Jan 27 00:00:00 1970 PST | {"c3": "00126"} | {"c2": "6", "c6": "6", "c7": "6 ", "c8": "foo", "C 1": "126"} + Fri Feb 06 00:00:00 1970 PST | {"c3": "00136"} | {"c2": "6", "c6": "6", "c7": "6 ", "c8": "foo", "C 1": "136"} | Fri Feb 06 00:00:00 1970 PST | {"c3": "00136"} | {"c2": "6", "c6": "6", "c7": "6 ", "c8": "foo", "C 1": "136"} + Mon Feb 16 00:00:00 1970 PST | {"c3": "00146"} | {"c2": "6", "c6": "6", "c7": "6 ", "c8": "foo", "C 1": "146"} | Mon Feb 16 00:00:00 1970 PST | {"c3": "00146"} | {"c2": "6", "c6": "6", "c7": "6 ", "c8": "foo", "C 1": "146"} + Thu Feb 26 00:00:00 1970 PST | {"c3": "00156"} | {"c2": "6", "c6": "6", "c7": "6 ", "c8": "foo", "C 1": "156"} | Thu Feb 26 00:00:00 1970 PST | {"c3": "00156"} | {"c2": "6", "c6": "6", "c7": "6 ", "c8": "foo", "C 1": "156"} + Sun Mar 08 00:00:00 1970 PST | {"c3": "00166"} | {"c2": "6", "c6": "6", "c7": "6 ", "c8": "foo", "C 1": "166"} | Sun Mar 08 00:00:00 1970 PST | {"c3": "00166"} | {"c2": "6", "c6": "6", "c7": "6 ", "c8": "foo", "C 1": "166"} + Wed Mar 18 00:00:00 1970 PST | {"c3": "00176"} | {"c2": "6", "c6": "6", "c7": "6 ", "c8": "foo", "C 1": "176"} | Wed Mar 18 00:00:00 1970 PST | {"c3": "00176"} | {"c2": "6", "c6": "6", "c7": "6 ", "c8": "foo", "C 1": "176"} + Sat Mar 28 00:00:00 1970 PST | {"c3": "00186"} | {"c2": "6", "c6": "6", "c7": "6 ", "c8": "foo", "C 1": "186"} | Sat Mar 28 00:00:00 1970 PST | {"c3": "00186"} | {"c2": "6", "c6": "6", "c7": "6 ", "c8": "foo", "C 1": "186"} + Tue Apr 07 00:00:00 1970 PST | {"c3": "00196"} | {"c2": "6", "c6": "6", "c7": "6 ", "c8": "foo", "C 1": "196"} | Tue Apr 07 00:00:00 1970 PST | {"c3": "00196"} | {"c2": "6", "c6": "6", "c7": "6 ", "c8": "foo", "C 1": "196"} + Wed Jan 07 00:00:00 1970 PST | {"c3": "00206"} | {"c2": "6", "c6": "6", "c7": "6 ", "c8": "foo", "C 1": "206"} | Wed Jan 07 00:00:00 1970 PST | {"c3": "00206"} | {"c2": "6", "c6": "6", "c7": "6 ", "c8": "foo", "C 1": "206"} + Sat Jan 17 00:00:00 1970 PST | {"c3": "00216"} | {"c2": "6", "c6": "6", "c7": "6 ", "c8": "foo", "C 1": "216"} | Sat Jan 17 00:00:00 1970 PST | {"c3": "00216"} | {"c2": "6", "c6": "6", "c7": "6 ", "c8": "foo", "C 1": "216"} + Tue Jan 27 00:00:00 1970 PST | {"c3": "00226"} | {"c2": "6", "c6": "6", "c7": "6 ", "c8": "foo", "C 1": "226"} | Tue Jan 27 00:00:00 1970 PST | {"c3": "00226"} | {"c2": "6", "c6": "6", "c7": "6 ", "c8": "foo", "C 1": "226"} + Fri Feb 06 00:00:00 1970 PST | {"c3": "00236"} | {"c2": "6", "c6": "6", "c7": "6 ", "c8": "foo", "C 1": "236"} | Fri Feb 06 00:00:00 1970 PST | {"c3": "00236"} | {"c2": "6", "c6": "6", "c7": "6 ", "c8": "foo", "C 1": "236"} + Mon Feb 16 00:00:00 1970 PST | {"c3": "00246"} | {"c2": "6", "c6": "6", "c7": "6 ", "c8": "foo", "C 1": "246"} | Mon Feb 16 00:00:00 1970 PST | {"c3": "00246"} | {"c2": "6", "c6": "6", "c7": "6 ", "c8": "foo", "C 1": "246"} + Thu Feb 26 00:00:00 1970 PST | {"c3": "00256"} | {"c2": "6", "c6": "6", "c7": "6 ", "c8": "foo", "C 1": "256"} | Thu Feb 26 00:00:00 1970 PST | {"c3": "00256"} | {"c2": "6", "c6": "6", "c7": "6 ", "c8": "foo", "C 1": "256"} + Sun Mar 08 00:00:00 1970 PST | {"c3": "00266"} | {"c2": "6", "c6": "6", "c7": "6 ", "c8": "foo", "C 1": "266"} | Sun Mar 08 00:00:00 1970 PST | {"c3": "00266"} | {"c2": "6", "c6": "6", "c7": "6 ", "c8": "foo", "C 1": "266"} + Wed Mar 18 00:00:00 1970 PST | {"c3": "00276"} | {"c2": "6", "c6": "6", "c7": "6 ", "c8": "foo", "C 1": "276"} | Wed Mar 18 00:00:00 1970 PST | {"c3": "00276"} | {"c2": "6", "c6": "6", "c7": "6 ", "c8": "foo", "C 1": "276"} + Sat Mar 28 00:00:00 1970 PST | {"c3": "00286"} | {"c2": "6", "c6": "6", "c7": "6 ", "c8": "foo", "C 1": "286"} | Sat Mar 28 00:00:00 1970 PST | {"c3": "00286"} | {"c2": "6", "c6": "6", "c7": "6 ", "c8": "foo", "C 1": "286"} + Tue Apr 07 00:00:00 1970 PST | {"c3": "00296"} | {"c2": "6", "c6": "6", "c7": "6 ", "c8": "foo", "C 1": "296"} | Tue Apr 07 00:00:00 1970 PST | {"c3": "00296"} | {"c2": "6", "c6": "6", "c7": "6 ", "c8": "foo", "C 1": "296"} + Wed Jan 07 00:00:00 1970 PST | {"c3": "00306"} | {"c2": "6", "c6": "6", "c7": "6 ", "c8": "foo", "C 1": "306"} | Wed Jan 07 00:00:00 1970 PST | {"c3": "00306"} | {"c2": "6", "c6": "6", "c7": "6 ", "c8": "foo", "C 1": "306"} + Sat Jan 17 00:00:00 1970 PST | {"c3": "00316"} | {"c2": "6", "c6": "6", "c7": "6 ", "c8": "foo", "C 1": "316"} | Sat Jan 17 00:00:00 1970 PST | {"c3": "00316"} | {"c2": "6", "c6": "6", "c7": "6 ", "c8": "foo", "C 1": "316"} + Tue Jan 27 00:00:00 1970 PST | {"c3": "00326"} | {"c2": "6", "c6": "6", "c7": "6 ", "c8": "foo", "C 1": "326"} | Tue Jan 27 00:00:00 1970 PST | {"c3": "00326"} | {"c2": "6", "c6": "6", "c7": "6 ", "c8": "foo", "C 1": "326"} + Fri Feb 06 00:00:00 1970 PST | {"c3": "00336"} | {"c2": "6", "c6": "6", "c7": "6 ", "c8": "foo", "C 1": "336"} | Fri Feb 06 00:00:00 1970 PST | {"c3": "00336"} | {"c2": "6", "c6": "6", "c7": "6 ", "c8": "foo", "C 1": "336"} + Mon Feb 16 00:00:00 1970 PST | {"c3": "00346"} | {"c2": "6", "c6": "6", "c7": "6 ", "c8": "foo", "C 1": "346"} | Mon Feb 16 00:00:00 1970 PST | {"c3": "00346"} | {"c2": "6", "c6": "6", "c7": "6 ", "c8": "foo", "C 1": "346"} + Thu Feb 26 00:00:00 1970 PST | {"c3": "00356"} | {"c2": "6", "c6": "6", "c7": "6 ", "c8": "foo", "C 1": "356"} | Thu Feb 26 00:00:00 1970 PST | {"c3": "00356"} | {"c2": "6", "c6": "6", "c7": "6 ", "c8": "foo", "C 1": "356"} + Sun Mar 08 00:00:00 1970 PST | {"c3": "00366"} | {"c2": "6", "c6": "6", "c7": "6 ", "c8": "foo", "C 1": "366"} | Sun Mar 08 00:00:00 1970 PST | {"c3": "00366"} | {"c2": "6", "c6": "6", "c7": "6 ", "c8": "foo", "C 1": "366"} + Wed Mar 18 00:00:00 1970 PST | {"c3": "00376"} | {"c2": "6", "c6": "6", "c7": "6 ", "c8": "foo", "C 1": "376"} | Wed Mar 18 00:00:00 1970 PST | {"c3": "00376"} | {"c2": "6", "c6": "6", "c7": "6 ", "c8": "foo", "C 1": "376"} + Sat Mar 28 00:00:00 1970 PST | {"c3": "00386"} | {"c2": "6", "c6": "6", "c7": "6 ", "c8": "foo", "C 1": "386"} | Sat Mar 28 00:00:00 1970 PST | {"c3": "00386"} | {"c2": "6", "c6": "6", "c7": "6 ", "c8": "foo", "C 1": "386"} + Tue Apr 07 00:00:00 1970 PST | {"c3": "00396"} | {"c2": "6", "c6": "6", "c7": "6 ", "c8": "foo", "C 1": "396"} | Tue Apr 07 00:00:00 1970 PST | {"c3": "00396"} | {"c2": "6", "c6": "6", "c7": "6 ", "c8": "foo", "C 1": "396"} + Wed Jan 07 00:00:00 1970 PST | {"c3": "00406"} | {"c2": "6", "c6": "6", "c7": "6 ", "c8": "foo", "C 1": "406"} | Wed Jan 07 00:00:00 1970 PST | {"c3": "00406"} | {"c2": "6", "c6": "6", "c7": "6 ", "c8": "foo", "C 1": "406"} + Sat Jan 17 00:00:00 1970 PST | {"c3": "00416"} | {"c2": "6", "c6": "6", "c7": "6 ", "c8": "foo", "C 1": "416"} | Sat Jan 17 00:00:00 1970 PST | {"c3": "00416"} | {"c2": "6", "c6": "6", "c7": "6 ", "c8": "foo", "C 1": "416"} + Tue Jan 27 00:00:00 1970 PST | {"c3": "00426"} | {"c2": "6", "c6": "6", "c7": "6 ", "c8": "foo", "C 1": "426"} | Tue Jan 27 00:00:00 1970 PST | {"c3": "00426"} | {"c2": "6", "c6": "6", "c7": "6 ", "c8": "foo", "C 1": "426"} + Fri Feb 06 00:00:00 1970 PST | {"c3": "00436"} | {"c2": "6", "c6": "6", "c7": "6 ", "c8": "foo", "C 1": "436"} | Fri Feb 06 00:00:00 1970 PST | {"c3": "00436"} | {"c2": "6", "c6": "6", "c7": "6 ", "c8": "foo", "C 1": "436"} + Mon Feb 16 00:00:00 1970 PST | {"c3": "00446"} | {"c2": "6", "c6": "6", "c7": "6 ", "c8": "foo", "C 1": "446"} | Mon Feb 16 00:00:00 1970 PST | {"c3": "00446"} | {"c2": "6", "c6": "6", "c7": "6 ", "c8": "foo", "C 1": "446"} + Thu Feb 26 00:00:00 1970 PST | {"c3": "00456"} | {"c2": "6", "c6": "6", "c7": "6 ", "c8": "foo", "C 1": "456"} | Thu Feb 26 00:00:00 1970 PST | {"c3": "00456"} | {"c2": "6", "c6": "6", "c7": "6 ", "c8": "foo", "C 1": "456"} + Sun Mar 08 00:00:00 1970 PST | {"c3": "00466"} | {"c2": "6", "c6": "6", "c7": "6 ", "c8": "foo", "C 1": "466"} | Sun Mar 08 00:00:00 1970 PST | {"c3": "00466"} | {"c2": "6", "c6": "6", "c7": "6 ", "c8": "foo", "C 1": "466"} + Wed Mar 18 00:00:00 1970 PST | {"c3": "00476"} | {"c2": "6", "c6": "6", "c7": "6 ", "c8": "foo", "C 1": "476"} | Wed Mar 18 00:00:00 1970 PST | {"c3": "00476"} | {"c2": "6", "c6": "6", "c7": "6 ", "c8": "foo", "C 1": "476"} + Sat Mar 28 00:00:00 1970 PST | {"c3": "00486"} | {"c2": "6", "c6": "6", "c7": "6 ", "c8": "foo", "C 1": "486"} | Sat Mar 28 00:00:00 1970 PST | {"c3": "00486"} | {"c2": "6", "c6": "6", "c7": "6 ", "c8": "foo", "C 1": "486"} + Tue Apr 07 00:00:00 1970 PST | {"c3": "00496"} | {"c2": "6", "c6": "6", "c7": "6 ", "c8": "foo", "C 1": "496"} | Tue Apr 07 00:00:00 1970 PST | {"c3": "00496"} | {"c2": "6", "c6": "6", "c7": "6 ", "c8": "foo", "C 1": "496"} + Wed Jan 07 00:00:00 1970 PST | {"c3": "00506"} | {"c2": "6", "c6": "6", "c7": "6 ", "c8": "foo", "C 1": "506"} | Wed Jan 07 00:00:00 1970 PST | {"c3": "00506"} | {"c2": "6", "c6": "6", "c7": "6 ", "c8": "foo", "C 1": "506"} + Sat Jan 17 00:00:00 1970 PST | {"c3": "00516"} | {"c2": "6", "c6": "6", "c7": "6 ", "c8": "foo", "C 1": "516"} | Sat Jan 17 00:00:00 1970 PST | {"c3": "00516"} | {"c2": "6", "c6": "6", "c7": "6 ", "c8": "foo", "C 1": "516"} + Tue Jan 27 00:00:00 1970 PST | {"c3": "00526"} | {"c2": "6", "c6": "6", "c7": "6 ", "c8": "foo", "C 1": "526"} | Tue Jan 27 00:00:00 1970 PST | {"c3": "00526"} | {"c2": "6", "c6": "6", "c7": "6 ", "c8": "foo", "C 1": "526"} + Fri Feb 06 00:00:00 1970 PST | {"c3": "00536"} | {"c2": "6", "c6": "6", "c7": "6 ", "c8": "foo", "C 1": "536"} | Fri Feb 06 00:00:00 1970 PST | {"c3": "00536"} | {"c2": "6", "c6": "6", "c7": "6 ", "c8": "foo", "C 1": "536"} + Mon Feb 16 00:00:00 1970 PST | {"c3": "00546"} | {"c2": "6", "c6": "6", "c7": "6 ", "c8": "foo", "C 1": "546"} | Mon Feb 16 00:00:00 1970 PST | {"c3": "00546"} | {"c2": "6", "c6": "6", "c7": "6 ", "c8": "foo", "C 1": "546"} + Thu Feb 26 00:00:00 1970 PST | {"c3": "00556"} | {"c2": "6", "c6": "6", "c7": "6 ", "c8": "foo", "C 1": "556"} | Thu Feb 26 00:00:00 1970 PST | {"c3": "00556"} | {"c2": "6", "c6": "6", "c7": "6 ", "c8": "foo", "C 1": "556"} + Sun Mar 08 00:00:00 1970 PST | {"c3": "00566"} | {"c2": "6", "c6": "6", "c7": "6 ", "c8": "foo", "C 1": "566"} | Sun Mar 08 00:00:00 1970 PST | {"c3": "00566"} | {"c2": "6", "c6": "6", "c7": "6 ", "c8": "foo", "C 1": "566"} + Wed Mar 18 00:00:00 1970 PST | {"c3": "00576"} | {"c2": "6", "c6": "6", "c7": "6 ", "c8": "foo", "C 1": "576"} | Wed Mar 18 00:00:00 1970 PST | {"c3": "00576"} | {"c2": "6", "c6": "6", "c7": "6 ", "c8": "foo", "C 1": "576"} + Sat Mar 28 00:00:00 1970 PST | {"c3": "00586"} | {"c2": "6", "c6": "6", "c7": "6 ", "c8": "foo", "C 1": "586"} | Sat Mar 28 00:00:00 1970 PST | {"c3": "00586"} | {"c2": "6", "c6": "6", "c7": "6 ", "c8": "foo", "C 1": "586"} + Tue Apr 07 00:00:00 1970 PST | {"c3": "00596"} | {"c2": "6", "c6": "6", "c7": "6 ", "c8": "foo", "C 1": "596"} | Tue Apr 07 00:00:00 1970 PST | {"c3": "00596"} | {"c2": "6", "c6": "6", "c7": "6 ", "c8": "foo", "C 1": "596"} + Wed Jan 07 00:00:00 1970 PST | {"c3": "00606"} | {"c2": "6", "c6": "6", "c7": "6 ", "c8": "foo", "C 1": "606"} | Wed Jan 07 00:00:00 1970 PST | {"c3": "00606"} | {"c2": "6", "c6": "6", "c7": "6 ", "c8": "foo", "C 1": "606"} + Sat Jan 17 00:00:00 1970 PST | {"c3": "00616"} | {"c2": "6", "c6": "6", "c7": "6 ", "c8": "foo", "C 1": "616"} | Sat Jan 17 00:00:00 1970 PST | {"c3": "00616"} | {"c2": "6", "c6": "6", "c7": "6 ", "c8": "foo", "C 1": "616"} + Tue Jan 27 00:00:00 1970 PST | {"c3": "00626"} | {"c2": "6", "c6": "6", "c7": "6 ", "c8": "foo", "C 1": "626"} | Tue Jan 27 00:00:00 1970 PST | {"c3": "00626"} | {"c2": "6", "c6": "6", "c7": "6 ", "c8": "foo", "C 1": "626"} + Fri Feb 06 00:00:00 1970 PST | {"c3": "00636"} | {"c2": "6", "c6": "6", "c7": "6 ", "c8": "foo", "C 1": "636"} | Fri Feb 06 00:00:00 1970 PST | {"c3": "00636"} | {"c2": "6", "c6": "6", "c7": "6 ", "c8": "foo", "C 1": "636"} + Mon Feb 16 00:00:00 1970 PST | {"c3": "00646"} | {"c2": "6", "c6": "6", "c7": "6 ", "c8": "foo", "C 1": "646"} | Mon Feb 16 00:00:00 1970 PST | {"c3": "00646"} | {"c2": "6", "c6": "6", "c7": "6 ", "c8": "foo", "C 1": "646"} + Thu Feb 26 00:00:00 1970 PST | {"c3": "00656"} | {"c2": "6", "c6": "6", "c7": "6 ", "c8": "foo", "C 1": "656"} | Thu Feb 26 00:00:00 1970 PST | {"c3": "00656"} | {"c2": "6", "c6": "6", "c7": "6 ", "c8": "foo", "C 1": "656"} + Sun Mar 08 00:00:00 1970 PST | {"c3": "00666"} | {"c2": "6", "c6": "6", "c7": "6 ", "c8": "foo", "C 1": "666"} | Sun Mar 08 00:00:00 1970 PST | {"c3": "00666"} | {"c2": "6", "c6": "6", "c7": "6 ", "c8": "foo", "C 1": "666"} + Wed Mar 18 00:00:00 1970 PST | {"c3": "00676"} | {"c2": "6", "c6": "6", "c7": "6 ", "c8": "foo", "C 1": "676"} | Wed Mar 18 00:00:00 1970 PST | {"c3": "00676"} | {"c2": "6", "c6": "6", "c7": "6 ", "c8": "foo", "C 1": "676"} + Sat Mar 28 00:00:00 1970 PST | {"c3": "00686"} | {"c2": "6", "c6": "6", "c7": "6 ", "c8": "foo", "C 1": "686"} | Sat Mar 28 00:00:00 1970 PST | {"c3": "00686"} | {"c2": "6", "c6": "6", "c7": "6 ", "c8": "foo", "C 1": "686"} + Tue Apr 07 00:00:00 1970 PST | {"c3": "00696"} | {"c2": "6", "c6": "6", "c7": "6 ", "c8": "foo", "C 1": "696"} | Tue Apr 07 00:00:00 1970 PST | {"c3": "00696"} | {"c2": "6", "c6": "6", "c7": "6 ", "c8": "foo", "C 1": "696"} + Wed Jan 07 00:00:00 1970 PST | {"c3": "00706"} | {"c2": "6", "c6": "6", "c7": "6 ", "c8": "foo", "C 1": "706"} | Wed Jan 07 00:00:00 1970 PST | {"c3": "00706"} | {"c2": "6", "c6": "6", "c7": "6 ", "c8": "foo", "C 1": "706"} + Sat Jan 17 00:00:00 1970 PST | {"c3": "00716"} | {"c2": "6", "c6": "6", "c7": "6 ", "c8": "foo", "C 1": "716"} | Sat Jan 17 00:00:00 1970 PST | {"c3": "00716"} | {"c2": "6", "c6": "6", "c7": "6 ", "c8": "foo", "C 1": "716"} + Tue Jan 27 00:00:00 1970 PST | {"c3": "00726"} | {"c2": "6", "c6": "6", "c7": "6 ", "c8": "foo", "C 1": "726"} | Tue Jan 27 00:00:00 1970 PST | {"c3": "00726"} | {"c2": "6", "c6": "6", "c7": "6 ", "c8": "foo", "C 1": "726"} + Fri Feb 06 00:00:00 1970 PST | {"c3": "00736"} | {"c2": "6", "c6": "6", "c7": "6 ", "c8": "foo", "C 1": "736"} | Fri Feb 06 00:00:00 1970 PST | {"c3": "00736"} | {"c2": "6", "c6": "6", "c7": "6 ", "c8": "foo", "C 1": "736"} + Mon Feb 16 00:00:00 1970 PST | {"c3": "00746"} | {"c2": "6", "c6": "6", "c7": "6 ", "c8": "foo", "C 1": "746"} | Mon Feb 16 00:00:00 1970 PST | {"c3": "00746"} | {"c2": "6", "c6": "6", "c7": "6 ", "c8": "foo", "C 1": "746"} + Thu Feb 26 00:00:00 1970 PST | {"c3": "00756"} | {"c2": "6", "c6": "6", "c7": "6 ", "c8": "foo", "C 1": "756"} | Thu Feb 26 00:00:00 1970 PST | {"c3": "00756"} | {"c2": "6", "c6": "6", "c7": "6 ", "c8": "foo", "C 1": "756"} + Sun Mar 08 00:00:00 1970 PST | {"c3": "00766"} | {"c2": "6", "c6": "6", "c7": "6 ", "c8": "foo", "C 1": "766"} | Sun Mar 08 00:00:00 1970 PST | {"c3": "00766"} | {"c2": "6", "c6": "6", "c7": "6 ", "c8": "foo", "C 1": "766"} + Wed Mar 18 00:00:00 1970 PST | {"c3": "00776"} | {"c2": "6", "c6": "6", "c7": "6 ", "c8": "foo", "C 1": "776"} | Wed Mar 18 00:00:00 1970 PST | {"c3": "00776"} | {"c2": "6", "c6": "6", "c7": "6 ", "c8": "foo", "C 1": "776"} + Sat Mar 28 00:00:00 1970 PST | {"c3": "00786"} | {"c2": "6", "c6": "6", "c7": "6 ", "c8": "foo", "C 1": "786"} | Sat Mar 28 00:00:00 1970 PST | {"c3": "00786"} | {"c2": "6", "c6": "6", "c7": "6 ", "c8": "foo", "C 1": "786"} + Tue Apr 07 00:00:00 1970 PST | {"c3": "00796"} | {"c2": "6", "c6": "6", "c7": "6 ", "c8": "foo", "C 1": "796"} | Tue Apr 07 00:00:00 1970 PST | {"c3": "00796"} | {"c2": "6", "c6": "6", "c7": "6 ", "c8": "foo", "C 1": "796"} + Wed Jan 07 00:00:00 1970 PST | {"c3": "00806"} | {"c2": "6", "c6": "6", "c7": "6 ", "c8": "foo", "C 1": "806"} | Wed Jan 07 00:00:00 1970 PST | {"c3": "00806"} | {"c2": "6", "c6": "6", "c7": "6 ", "c8": "foo", "C 1": "806"} + Sat Jan 17 00:00:00 1970 PST | {"c3": "00816"} | {"c2": "6", "c6": "6", "c7": "6 ", "c8": "foo", "C 1": "816"} | Sat Jan 17 00:00:00 1970 PST | {"c3": "00816"} | {"c2": "6", "c6": "6", "c7": "6 ", "c8": "foo", "C 1": "816"} + Tue Jan 27 00:00:00 1970 PST | {"c3": "00826"} | {"c2": "6", "c6": "6", "c7": "6 ", "c8": "foo", "C 1": "826"} | Tue Jan 27 00:00:00 1970 PST | {"c3": "00826"} | {"c2": "6", "c6": "6", "c7": "6 ", "c8": "foo", "C 1": "826"} + Fri Feb 06 00:00:00 1970 PST | {"c3": "00836"} | {"c2": "6", "c6": "6", "c7": "6 ", "c8": "foo", "C 1": "836"} | Fri Feb 06 00:00:00 1970 PST | {"c3": "00836"} | {"c2": "6", "c6": "6", "c7": "6 ", "c8": "foo", "C 1": "836"} + Mon Feb 16 00:00:00 1970 PST | {"c3": "00846"} | {"c2": "6", "c6": "6", "c7": "6 ", "c8": "foo", "C 1": "846"} | Mon Feb 16 00:00:00 1970 PST | {"c3": "00846"} | {"c2": "6", "c6": "6", "c7": "6 ", "c8": "foo", "C 1": "846"} + Thu Feb 26 00:00:00 1970 PST | {"c3": "00856"} | {"c2": "6", "c6": "6", "c7": "6 ", "c8": "foo", "C 1": "856"} | Thu Feb 26 00:00:00 1970 PST | {"c3": "00856"} | {"c2": "6", "c6": "6", "c7": "6 ", "c8": "foo", "C 1": "856"} + Sun Mar 08 00:00:00 1970 PST | {"c3": "00866"} | {"c2": "6", "c6": "6", "c7": "6 ", "c8": "foo", "C 1": "866"} | Sun Mar 08 00:00:00 1970 PST | {"c3": "00866"} | {"c2": "6", "c6": "6", "c7": "6 ", "c8": "foo", "C 1": "866"} + Wed Mar 18 00:00:00 1970 PST | {"c3": "00876"} | {"c2": "6", "c6": "6", "c7": "6 ", "c8": "foo", "C 1": "876"} | Wed Mar 18 00:00:00 1970 PST | {"c3": "00876"} | {"c2": "6", "c6": "6", "c7": "6 ", "c8": "foo", "C 1": "876"} + Sat Mar 28 00:00:00 1970 PST | {"c3": "00886"} | {"c2": "6", "c6": "6", "c7": "6 ", "c8": "foo", "C 1": "886"} | Sat Mar 28 00:00:00 1970 PST | {"c3": "00886"} | {"c2": "6", "c6": "6", "c7": "6 ", "c8": "foo", "C 1": "886"} + Tue Apr 07 00:00:00 1970 PST | {"c3": "00896"} | {"c2": "6", "c6": "6", "c7": "6 ", "c8": "foo", "C 1": "896"} | Tue Apr 07 00:00:00 1970 PST | {"c3": "00896"} | {"c2": "6", "c6": "6", "c7": "6 ", "c8": "foo", "C 1": "896"} + Wed Jan 07 00:00:00 1970 PST | {"c3": "00906"} | {"c2": "6", "c6": "6", "c7": "6 ", "c8": "foo", "C 1": "906"} | Wed Jan 07 00:00:00 1970 PST | {"c3": "00906"} | {"c2": "6", "c6": "6", "c7": "6 ", "c8": "foo", "C 1": "906"} + Sat Jan 17 00:00:00 1970 PST | {"c3": "00916"} | {"c2": "6", "c6": "6", "c7": "6 ", "c8": "foo", "C 1": "916"} | Sat Jan 17 00:00:00 1970 PST | {"c3": "00916"} | {"c2": "6", "c6": "6", "c7": "6 ", "c8": "foo", "C 1": "916"} + Tue Jan 27 00:00:00 1970 PST | {"c3": "00926"} | {"c2": "6", "c6": "6", "c7": "6 ", "c8": "foo", "C 1": "926"} | Tue Jan 27 00:00:00 1970 PST | {"c3": "00926"} | {"c2": "6", "c6": "6", "c7": "6 ", "c8": "foo", "C 1": "926"} + Fri Feb 06 00:00:00 1970 PST | {"c3": "00936"} | {"c2": "6", "c6": "6", "c7": "6 ", "c8": "foo", "C 1": "936"} | Fri Feb 06 00:00:00 1970 PST | {"c3": "00936"} | {"c2": "6", "c6": "6", "c7": "6 ", "c8": "foo", "C 1": "936"} + Mon Feb 16 00:00:00 1970 PST | {"c3": "00946"} | {"c2": "6", "c6": "6", "c7": "6 ", "c8": "foo", "C 1": "946"} | Mon Feb 16 00:00:00 1970 PST | {"c3": "00946"} | {"c2": "6", "c6": "6", "c7": "6 ", "c8": "foo", "C 1": "946"} + Thu Feb 26 00:00:00 1970 PST | {"c3": "00956"} | {"c2": "6", "c6": "6", "c7": "6 ", "c8": "foo", "C 1": "956"} | Thu Feb 26 00:00:00 1970 PST | {"c3": "00956"} | {"c2": "6", "c6": "6", "c7": "6 ", "c8": "foo", "C 1": "956"} + Sun Mar 08 00:00:00 1970 PST | {"c3": "00966"} | {"c2": "6", "c6": "6", "c7": "6 ", "c8": "foo", "C 1": "966"} | Sun Mar 08 00:00:00 1970 PST | {"c3": "00966"} | {"c2": "6", "c6": "6", "c7": "6 ", "c8": "foo", "C 1": "966"} + Wed Mar 18 00:00:00 1970 PST | {"c3": "00976"} | {"c2": "6", "c6": "6", "c7": "6 ", "c8": "foo", "C 1": "976"} | Wed Mar 18 00:00:00 1970 PST | {"c3": "00976"} | {"c2": "6", "c6": "6", "c7": "6 ", "c8": "foo", "C 1": "976"} + Sat Mar 28 00:00:00 1970 PST | {"c3": "00986"} | {"c2": "6", "c6": "6", "c7": "6 ", "c8": "foo", "C 1": "986"} | Sat Mar 28 00:00:00 1970 PST | {"c3": "00986"} | {"c2": "6", "c6": "6", "c7": "6 ", "c8": "foo", "C 1": "986"} + Tue Apr 07 00:00:00 1970 PST | {"c3": "00996"} | {"c2": "6", "c6": "6", "c7": "6 ", "c8": "foo", "C 1": "996"} | Tue Apr 07 00:00:00 1970 PST | {"c3": "00996"} | {"c2": "6", "c6": "6", "c7": "6 ", "c8": "foo", "C 1": "996"} +(100 rows) + +-- bug before 9.3.5 due to sloppy handling of remote-estimate parameters +--Testcase 91: +SELECT * FROM ft1 WHERE (fields->>'C 1')::int = ANY (ARRAY(SELECT (fields->>'C 1')::int FROM ft2 WHERE (fields->>'C 1')::int < 5)); + time | tags | fields +------------------------------+-----------------+--------------------------------------------------------------------- + Fri Jan 02 00:00:00 1970 PST | {"c3": "00001"} | {"c2": "1", "c6": "1", "c7": "1 ", "c8": "foo", "C 1": "1"} + Sat Jan 03 00:00:00 1970 PST | {"c3": "00002"} | {"c2": "2", "c6": "2", "c7": "2 ", "c8": "foo", "C 1": "2"} + Sun Jan 04 00:00:00 1970 PST | {"c3": "00003"} | {"c2": "3", "c6": "3", "c7": "3 ", "c8": "foo", "C 1": "3"} + Mon Jan 05 00:00:00 1970 PST | {"c3": "00004"} | {"c2": "4", "c6": "4", "c7": "4 ", "c8": "foo", "C 1": "4"} +(4 rows) + +--Testcase 92: +SELECT * FROM ft2 WHERE (fields->>'C 1')::int = ANY (ARRAY(SELECT (fields->>'C 1')::int FROM ft1 WHERE (fields->>'C 1')::int < 5)); + time | tags | fields +------------------------------+-----------------+--------------------------------------------------------------------- + Fri Jan 02 00:00:00 1970 PST | {"c3": "00001"} | {"c2": "1", "c6": "1", "c7": "1 ", "c8": "foo", "C 1": "1"} + Sat Jan 03 00:00:00 1970 PST | {"c3": "00002"} | {"c2": "2", "c6": "2", "c7": "2 ", "c8": "foo", "C 1": "2"} + Sun Jan 04 00:00:00 1970 PST | {"c3": "00003"} | {"c2": "3", "c6": "3", "c7": "3 ", "c8": "foo", "C 1": "3"} + Mon Jan 05 00:00:00 1970 PST | {"c3": "00004"} | {"c2": "4", "c6": "4", "c7": "4 ", "c8": "foo", "C 1": "4"} +(4 rows) + +-- we should not push order by clause with volatile expressions or unsafe +-- collations +--Testcase 93: +EXPLAIN (VERBOSE, COSTS OFF) + SELECT * FROM ft2 ORDER BY (ft2.fields->>'C 1')::int, random(); + QUERY PLAN +------------------------------------------------------------------------------------- + Sort + Output: "time", tags, fields, (((fields ->> 'C 1'::text))::integer), (random()) + Sort Key: (((ft2.fields ->> 'C 1'::text))::integer), (random()) + -> Foreign Scan on public.ft2 + Output: "time", tags, fields, ((fields ->> 'C 1'::text))::integer, random() + InfluxDB query: SELECT * FROM "T1" +(6 rows) + +--Testcase 94: +EXPLAIN (VERBOSE, COSTS OFF) + SELECT * FROM ft2 ORDER BY (ft2.fields->>'C 1')::int, ft2.tags->>'c3' collate "C"; + QUERY PLAN +-------------------------------------------------------------------------------------------------------------- + Sort + Output: "time", tags, fields, (((fields ->> 'C 1'::text))::integer), ((tags ->> 'c3'::text COLLATE "C")) + Sort Key: (((ft2.fields ->> 'C 1'::text))::integer), ((ft2.tags ->> 'c3'::text COLLATE "C")) COLLATE "C" + -> Foreign Scan on public.ft2 + Output: "time", tags, fields, ((fields ->> 'C 1'::text))::integer, (tags ->> 'c3'::text COLLATE "C") + InfluxDB query: SELECT * FROM "T1" +(6 rows) + +-- user-defined operator/function +--Testcase 95: +CREATE FUNCTION influxdb_fdw_abs(int) RETURNS int AS $$ +BEGIN +RETURN abs($1); +END +$$ LANGUAGE plpgsql IMMUTABLE; +--Testcase 96: +CREATE OPERATOR === ( + LEFTARG = int, + RIGHTARG = int, + PROCEDURE = int4eq, + COMMUTATOR = === +); +-- built-in operators and functions can be shipped for remote execution +--Testcase 97: +EXPLAIN (VERBOSE, COSTS OFF) + SELECT count(tags->>'c3') FROM ft1 t1 WHERE (t1.fields->>'C 1')::int = abs((t1.fields->>'c2')::int); + QUERY PLAN +------------------------------------------------------------------------ + Aggregate + Output: count((tags ->> 'c3'::text)) + -> Foreign Scan on public.ft1 t1 + Output: "time", tags, fields + InfluxDB query: SELECT * FROM "T1" WHERE (("C 1" = abs("c2"))) +(5 rows) + +--Testcase 98: +SELECT count(tags->>'c3') FROM ft1 t1 WHERE (t1.fields->>'C 1')::int = abs((t1.fields->>'c2')::int); + count +------- + 9 +(1 row) + +--Testcase 99: +EXPLAIN (VERBOSE, COSTS OFF) + SELECT count(tags->>'c3') FROM ft1 t1 WHERE (t1.fields->>'C 1')::int = (t1.fields->>'c2')::int; + QUERY PLAN +------------------------------------------------------------------- + Aggregate + Output: count((tags ->> 'c3'::text)) + -> Foreign Scan on public.ft1 t1 + Output: "time", tags, fields + InfluxDB query: SELECT * FROM "T1" WHERE (("C 1" = "c2")) +(5 rows) + +--Testcase 100: +SELECT count(tags->>'c3') FROM ft1 t1 WHERE (t1.fields->>'C 1')::int = (t1.fields->>'c2')::int; + count +------- + 9 +(1 row) + +-- by default, user-defined ones cannot +--Testcase 101: +EXPLAIN (VERBOSE, COSTS OFF) + SELECT count(tags->>'c3') FROM ft1 t1 WHERE (t1.fields->>'C 1')::int = influxdb_fdw_abs((t1.fields->>'c2')::int); + QUERY PLAN +-------------------------------------------------------------------------------------------------------------------- + Aggregate + Output: count((tags ->> 'c3'::text)) + -> Foreign Scan on public.ft1 t1 + Output: "time", tags, fields + Filter: (((t1.fields ->> 'C 1'::text))::integer = influxdb_fdw_abs(((t1.fields ->> 'c2'::text))::integer)) + InfluxDB query: SELECT * FROM "T1" +(6 rows) + +--Testcase 102: +SELECT count(tags->>'c3') FROM ft1 t1 WHERE (t1.fields->>'C 1')::int = influxdb_fdw_abs((t1.fields->>'c2')::int); + count +------- + 9 +(1 row) + +--Testcase 103: +EXPLAIN (VERBOSE, COSTS OFF) + SELECT count(tags->>'c3') FROM ft1 t1 WHERE (t1.fields->>'C 1')::int === (t1.fields->>'c2')::int; + QUERY PLAN +---------------------------------------------------------------------------------------------------- + Aggregate + Output: count((tags ->> 'c3'::text)) + -> Foreign Scan on public.ft1 t1 + Output: "time", tags, fields + Filter: (((t1.fields ->> 'C 1'::text))::integer === ((t1.fields ->> 'c2'::text))::integer) + InfluxDB query: SELECT * FROM "T1" +(6 rows) + +--Testcase 104: +SELECT count(tags->>'c3') FROM ft1 t1 WHERE (t1.fields->>'C 1')::int === (t1.fields->>'c2')::int; + count +------- + 9 +(1 row) + +-- ORDER BY can be shipped, though +--Testcase 105: +EXPLAIN (VERBOSE, COSTS OFF) + SELECT * FROM ft1 t1 WHERE (t1.fields->>'C 1')::int === (t1.fields->>'c2')::int order by (t1.fields->>'c2')::int limit 1; + QUERY PLAN +---------------------------------------------------------------------------------------------------------- + Limit + Output: "time", tags, fields, (((fields ->> 'c2'::text))::integer) + -> Sort + Output: "time", tags, fields, (((fields ->> 'c2'::text))::integer) + Sort Key: (((t1.fields ->> 'c2'::text))::integer) + -> Foreign Scan on public.ft1 t1 + Output: "time", tags, fields, ((fields ->> 'c2'::text))::integer + Filter: (((t1.fields ->> 'C 1'::text))::integer === ((t1.fields ->> 'c2'::text))::integer) + InfluxDB query: SELECT * FROM "T1" +(9 rows) + +--Testcase 106: +SELECT * FROM ft1 t1 WHERE (t1.fields->>'C 1')::int === (t1.fields->>'c2')::int order by (t1.fields->>'c2')::int limit 1; + time | tags | fields +------------------------------+-----------------+--------------------------------------------------------------------- + Fri Jan 02 00:00:00 1970 PST | {"c3": "00001"} | {"c2": "1", "c6": "1", "c7": "1 ", "c8": "foo", "C 1": "1"} +(1 row) + +-- but let's put them in an extension ... +--Testcase 107: +ALTER EXTENSION influxdb_fdw ADD FUNCTION influxdb_fdw_abs(int); +--Testcase 108: +ALTER EXTENSION influxdb_fdw ADD OPERATOR === (int, int); +-- ALTER SERVER loopback OPTIONS (ADD extensions 'influxdb_fdw'); +-- ... now they can be shipped +--Testcase 109: +EXPLAIN (VERBOSE, COSTS OFF) + SELECT count(tags->>'c3') FROM ft1 t1 WHERE (t1.fields->>'C 1')::int = influxdb_fdw_abs((t1.fields->>'c2')::int); + QUERY PLAN +-------------------------------------------------------------------------------------------------------------------- + Aggregate + Output: count((tags ->> 'c3'::text)) + -> Foreign Scan on public.ft1 t1 + Output: "time", tags, fields + Filter: (((t1.fields ->> 'C 1'::text))::integer = influxdb_fdw_abs(((t1.fields ->> 'c2'::text))::integer)) + InfluxDB query: SELECT * FROM "T1" +(6 rows) + +--Testcase 110: +SELECT count(tags->>'c3') FROM ft1 t1 WHERE (t1.fields->>'C 1')::int = influxdb_fdw_abs((t1.fields->>'c2')::int); + count +------- + 9 +(1 row) + +--Testcase 111: +EXPLAIN (VERBOSE, COSTS OFF) + SELECT count(tags->>'c3') FROM ft1 t1 WHERE (t1.fields->>'C 1')::int === (t1.fields->>'c2')::int; + QUERY PLAN +---------------------------------------------------------------------------------------------------- + Aggregate + Output: count((tags ->> 'c3'::text)) + -> Foreign Scan on public.ft1 t1 + Output: "time", tags, fields + Filter: (((t1.fields ->> 'C 1'::text))::integer === ((t1.fields ->> 'c2'::text))::integer) + InfluxDB query: SELECT * FROM "T1" +(6 rows) + +--Testcase 112: +SELECT count(tags->>'c3') FROM ft1 t1 WHERE (t1.fields->>'C 1')::int === (t1.fields->>'c2')::int; + count +------- + 9 +(1 row) + +-- and both ORDER BY and LIMIT can be shipped +--Testcase 113: +EXPLAIN (VERBOSE, COSTS OFF) + SELECT * FROM ft1 t1 WHERE (t1.fields->>'C 1')::int === (t1.fields->>'c2')::int order by (t1.fields->>'c2')::int limit 1; + QUERY PLAN +---------------------------------------------------------------------------------------------------------- + Limit + Output: "time", tags, fields, (((fields ->> 'c2'::text))::integer) + -> Sort + Output: "time", tags, fields, (((fields ->> 'c2'::text))::integer) + Sort Key: (((t1.fields ->> 'c2'::text))::integer) + -> Foreign Scan on public.ft1 t1 + Output: "time", tags, fields, ((fields ->> 'c2'::text))::integer + Filter: (((t1.fields ->> 'C 1'::text))::integer === ((t1.fields ->> 'c2'::text))::integer) + InfluxDB query: SELECT * FROM "T1" +(9 rows) + +--Testcase 114: +SELECT * FROM ft1 t1 WHERE (t1.fields->>'C 1')::int === (t1.fields->>'c2')::int order by (t1.fields->>'c2')::int limit 1; + time | tags | fields +------------------------------+-----------------+--------------------------------------------------------------------- + Fri Jan 02 00:00:00 1970 PST | {"c3": "00001"} | {"c2": "1", "c6": "1", "c7": "1 ", "c8": "foo", "C 1": "1"} +(1 row) + +-- Test CASE pushdown +--Testcase 854: +EXPLAIN (VERBOSE, COSTS OFF) +SELECT fields->>'C 1',fields->>'c2',tags->>'c3' FROM ft2 WHERE CASE WHEN (fields->>'C 1')::int > 990 THEN (fields->>'C 1')::int END < 1000 ORDER BY (fields->>'C 1')::int; + QUERY PLAN +-------------------------------------------------------------------------------------------------------------------------------------------------------- + Sort + Output: ((fields ->> 'C 1'::text)), ((fields ->> 'c2'::text)), ((tags ->> 'c3'::text)), (((fields ->> 'C 1'::text))::integer) + Sort Key: (((ft2.fields ->> 'C 1'::text))::integer) + -> Foreign Scan on public.ft2 + Output: (fields ->> 'C 1'::text), (fields ->> 'c2'::text), (tags ->> 'c3'::text), ((fields ->> 'C 1'::text))::integer + Filter: (CASE WHEN (((ft2.fields ->> 'C 1'::text))::integer > 990) THEN ((ft2.fields ->> 'C 1'::text))::integer ELSE NULL::integer END < 1000) + InfluxDB query: SELECT "C 1", "c2", "c3" FROM "T1" +(7 rows) + +--Testcase 855: +SELECT fields->>'C 1',fields->>'c2',tags->>'c3' FROM ft2 WHERE CASE WHEN (fields->>'C 1')::int > 990 THEN (fields->>'C 1')::int END < 1000 ORDER BY (fields->>'C 1')::int; + ?column? | ?column? | ?column? +----------+----------+---------- + 991 | 1 | 00991 + 992 | 2 | 00992 + 993 | 3 | 00993 + 994 | 4 | 00994 + 995 | 5 | 00995 + 996 | 6 | 00996 + 997 | 7 | 00997 + 998 | 8 | 00998 + 999 | 9 | 00999 +(9 rows) + +-- Nested CASE +--Testcase 856: +EXPLAIN (VERBOSE, COSTS OFF) +SELECT fields->>'C 1',fields->>'c2',tags->>'c3' FROM ft2 WHERE CASE CASE WHEN (fields->>'c2')::int > 0 THEN (fields->>'c2')::int END WHEN 100 THEN 601 WHEN (fields->>'c2')::int THEN (fields->>'c2')::int ELSE 0 END > 600 ORDER BY (fields->>'C 1')::int; + QUERY PLAN +----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- + Sort + Output: ((fields ->> 'C 1'::text)), ((fields ->> 'c2'::text)), ((tags ->> 'c3'::text)), (((fields ->> 'C 1'::text))::integer) + Sort Key: (((ft2.fields ->> 'C 1'::text))::integer) + -> Foreign Scan on public.ft2 + Output: (fields ->> 'C 1'::text), (fields ->> 'c2'::text), (tags ->> 'c3'::text), ((fields ->> 'C 1'::text))::integer + Filter: (CASE CASE WHEN (((ft2.fields ->> 'c2'::text))::integer > 0) THEN ((ft2.fields ->> 'c2'::text))::integer ELSE NULL::integer END WHEN 100 THEN 601 WHEN ((ft2.fields ->> 'c2'::text))::integer THEN ((ft2.fields ->> 'c2'::text))::integer ELSE 0 END > 600) + InfluxDB query: SELECT "C 1", "c2", "c3" FROM "T1" +(7 rows) + +--Testcase 857: +SELECT fields->>'C 1',fields->>'c2',tags->>'c3' FROM ft2 WHERE CASE CASE WHEN (fields->>'c2')::int > 0 THEN (fields->>'c2')::int END WHEN 100 THEN 601 WHEN (fields->>'c2')::int THEN (fields->>'c2')::int ELSE 0 END > 600 ORDER BY (fields->>'C 1')::int; + ?column? | ?column? | ?column? +----------+----------+---------- +(0 rows) + +-- CASE arg WHEN +--Testcase 858: +EXPLAIN (VERBOSE, COSTS OFF) +SELECT * FROM ft1 WHERE (fields->>'C 1')::int > (CASE mod((fields->>'C 1')::int, 4) WHEN 0 THEN 1 WHEN 2 THEN 50 ELSE 100 END); + QUERY PLAN +------------------------------------------------------------------------------------------------------------------------------------------------------ + Foreign Scan on public.ft1 + Output: "time", tags, fields + Filter: (((ft1.fields ->> 'C 1'::text))::integer > CASE mod(((ft1.fields ->> 'C 1'::text))::integer, 4) WHEN 0 THEN 1 WHEN 2 THEN 50 ELSE 100 END) + InfluxDB query: SELECT * FROM "T1" +(4 rows) + +-- CASE cannot be pushed down because of unshippable arg clause +--Testcase 859: +EXPLAIN (VERBOSE, COSTS OFF) +SELECT * FROM ft1 WHERE (fields->>'C 1')::int > (CASE random()::integer WHEN 0 THEN 1 WHEN 2 THEN 50 ELSE 100 END); + QUERY PLAN +-------------------------------------------------------------------------------------------------------------------------- + Foreign Scan on public.ft1 + Output: "time", tags, fields + Filter: (((ft1.fields ->> 'C 1'::text))::integer > CASE (random())::integer WHEN 0 THEN 1 WHEN 2 THEN 50 ELSE 100 END) + InfluxDB query: SELECT * FROM "T1" +(4 rows) + +-- these are shippable +--Testcase 860: +EXPLAIN (VERBOSE, COSTS OFF) +SELECT * FROM ft1 WHERE CASE (fields->>'c6')::text WHEN 'foo' THEN true ELSE (tags->>'c3')::text < 'bar' END; + QUERY PLAN +-------------------------------------------------------------------------------------------------------------------------- + Foreign Scan on public.ft1 + Output: "time", tags, fields + Filter: CASE (ft1.fields ->> 'c6'::text) WHEN 'foo'::text THEN true ELSE ((ft1.tags ->> 'c3'::text) < 'bar'::text) END + InfluxDB query: SELECT * FROM "T1" +(4 rows) + +--Testcase 861: +EXPLAIN (VERBOSE, COSTS OFF) +SELECT * FROM ft1 WHERE CASE (tags->>'c3')::text WHEN (fields->>'c6')::text THEN true ELSE (tags->>'c3')::text < 'bar' END; + QUERY PLAN +---------------------------------------------------------------------------------------------------------------------------------------- + Foreign Scan on public.ft1 + Output: "time", tags, fields + Filter: CASE (ft1.tags ->> 'c3'::text) WHEN (ft1.fields ->> 'c6'::text) THEN true ELSE ((ft1.tags ->> 'c3'::text) < 'bar'::text) END + InfluxDB query: SELECT * FROM "T1" +(4 rows) + +-- but this is not because of collation +--Testcase 862: +EXPLAIN (VERBOSE, COSTS OFF) +SELECT * FROM ft1 WHERE CASE (tags->>'c3')::text COLLATE "C" WHEN (fields->>'c6')::text THEN true ELSE (tags->>'c3')::text < 'bar' END; + QUERY PLAN +------------------------------------------------------------------------------------------------------------------------------------------------ + Foreign Scan on public.ft1 + Output: "time", tags, fields + Filter: CASE ((ft1.tags ->> 'c3'::text))::text WHEN (ft1.fields ->> 'c6'::text) THEN true ELSE ((ft1.tags ->> 'c3'::text) < 'bar'::text) END + InfluxDB query: SELECT * FROM "T1" +(4 rows) + +-- This test case drop configuration when execute non-schemaless before +--Testcase 863: +DROP TEXT SEARCH CONFIGURATION IF EXISTS public.custom_search; +NOTICE: text search configuration "public.custom_search" does not exist, skipping +-- a regconfig constant referring to this text search configuration +-- is initially unshippable +--Testcase 864: +CREATE TEXT SEARCH CONFIGURATION public.custom_search + (COPY = pg_catalog.english); +--Testcase 865: +EXPLAIN (VERBOSE, COSTS OFF) +SELECT (fields->>'C 1')::int c1, to_tsvector('custom_search'::regconfig, tags->>'c3') FROM ft1 +WHERE (fields->>'C 1')::int = 642 AND length(to_tsvector('custom_search'::regconfig, tags->>'c3')) > 0; + QUERY PLAN +--------------------------------------------------------------------------------------------------------------- + Foreign Scan on public.ft1 + Output: ((fields ->> 'C 1'::text))::integer, to_tsvector('custom_search'::regconfig, (tags ->> 'c3'::text)) + Filter: (length(to_tsvector('custom_search'::regconfig, (ft1.tags ->> 'c3'::text))) > 0) + InfluxDB query: SELECT "C 1", "c3" FROM "T1" WHERE (("C 1" = 642)) +(4 rows) + +--Testcase 866: +SELECT (fields->>'C 1')::int c1, to_tsvector('custom_search'::regconfig, tags->>'c3') FROM ft1 +WHERE (fields->>'C 1')::int = 642 AND length(to_tsvector('custom_search'::regconfig, tags->>'c3')) > 0; + c1 | to_tsvector +-----+------------- + 642 | '00642':1 +(1 row) + +-- but if it's in a shippable extension, it can be shipped +ALTER EXTENSION influxdb_fdw ADD TEXT SEARCH CONFIGURATION public.custom_search; +-- however, that doesn't flush the shippability cache, so do a quick reconnect +\c - +EXPLAIN (VERBOSE, COSTS OFF) +SELECT (fields->>'C 1')::int c1, to_tsvector('custom_search'::regconfig, tags->>'c3') FROM ft1 +WHERE (fields->>'C 1')::int = 642 AND length(to_tsvector('custom_search'::regconfig, tags->>'c3')) > 0; + QUERY PLAN +--------------------------------------------------------------------------------------------------------------- + Foreign Scan on public.ft1 + Output: ((fields ->> 'C 1'::text))::integer, to_tsvector('custom_search'::regconfig, (tags ->> 'c3'::text)) + Filter: (length(to_tsvector('custom_search'::regconfig, (ft1.tags ->> 'c3'::text))) > 0) + InfluxDB query: SELECT "C 1", "c3" FROM "T1" WHERE (("C 1" = 642)) +(4 rows) + +SELECT (fields->>'C 1')::int c1, to_tsvector('custom_search'::regconfig, tags->>'c3') FROM ft1 +WHERE (fields->>'C 1')::int = 642 AND length(to_tsvector('custom_search'::regconfig, tags->>'c3')) > 0; + c1 | to_tsvector +-----+------------- + 642 | '00642':1 +(1 row) + +-- =================================================================== +-- JOIN queries +-- =================================================================== +-- join two tables +--Testcase 115: +EXPLAIN (VERBOSE, COSTS OFF) +SELECT t1.c1, t2.c1 FROM (SELECT (fields->>'C 1')::int c1, (fields->>'c2')::int c2, tags->>'c3' c3, fields->>'c4' c4, fields->>'c5' c5, fields->>'c6' c6, fields->>'c7' c7, fields->>'c8' c8 FROM ft1 t1) t1 JOIN (SELECT (fields->>'C 1')::int c1, (fields->>'c2')::int c2, tags->>'c3' c3, fields->>'c4' c4, fields->>'c5' c5, fields->>'c6' c6, fields->>'c7' c7, fields->>'c8' c8 FROM ft2 t2) t2 ON ((t1.c1)::int = (t2.c1)::int) ORDER BY t1.c3, (t1.c1)::int OFFSET 100 LIMIT 10; + QUERY PLAN +------------------------------------------------------------------------------------------------------------------------------------ + Limit + Output: (((t1.fields ->> 'C 1'::text))::integer), (((t2.fields ->> 'C 1'::text))::integer), ((t1.tags ->> 'c3'::text)) + -> Sort + Output: (((t1.fields ->> 'C 1'::text))::integer), (((t2.fields ->> 'C 1'::text))::integer), ((t1.tags ->> 'c3'::text)) + Sort Key: ((t1.tags ->> 'c3'::text)), (((t1.fields ->> 'C 1'::text))::integer) + -> Merge Join + Output: (((t1.fields ->> 'C 1'::text))::integer), (((t2.fields ->> 'C 1'::text))::integer), (t1.tags ->> 'c3'::text) + Merge Cond: ((((t1.fields ->> 'C 1'::text))::integer) = (((t2.fields ->> 'C 1'::text))::integer)) + -> Sort + Output: t1.fields, t1.tags, (((t1.fields ->> 'C 1'::text))::integer) + Sort Key: (((t1.fields ->> 'C 1'::text))::integer) + -> Foreign Scan on public.ft1 t1 + Output: t1.fields, t1.tags, ((t1.fields ->> 'C 1'::text))::integer + InfluxDB query: SELECT * FROM "T1" + -> Sort + Output: t2.fields, (((t2.fields ->> 'C 1'::text))::integer) + Sort Key: (((t2.fields ->> 'C 1'::text))::integer) + -> Foreign Scan on public.ft2 t2 + Output: t2.fields, ((t2.fields ->> 'C 1'::text))::integer + InfluxDB query: SELECT * FROM "T1" +(20 rows) + +--Testcase 116: +SELECT t1.c1, t2.c1 FROM (SELECT (fields->>'C 1')::int c1, (fields->>'c2')::int c2, tags->>'c3' c3, fields->>'c4' c4, fields->>'c5' c5, fields->>'c6' c6, fields->>'c7' c7, fields->>'c8' c8 FROM ft1 t1) t1 JOIN (SELECT (fields->>'C 1')::int c1, (fields->>'c2')::int c2, tags->>'c3' c3, fields->>'c4' c4, fields->>'c5' c5, fields->>'c6' c6, fields->>'c7' c7, fields->>'c8' c8 FROM ft2 t2) t2 ON ((t1.c1)::int = (t2.c1)::int) ORDER BY t1.c3, (t1.c1)::int OFFSET 100 LIMIT 10; + c1 | c1 +-----+----- + 101 | 101 + 102 | 102 + 103 | 103 + 104 | 104 + 105 | 105 + 106 | 106 + 107 | 107 + 108 | 108 + 109 | 109 + 110 | 110 +(10 rows) + +-- join three tables +--Testcase 117: +EXPLAIN (VERBOSE, COSTS OFF) +SELECT t1.c1, t2.c2, t3.c3 FROM (SELECT (fields->>'C 1')::int c1, (fields->>'c2')::int c2, tags->>'c3' c3, fields->>'c4' c4, fields->>'c5' c5, fields->>'c6' c6, fields->>'c7' c7, fields->>'c8' c8 FROM ft1 t1) t1 JOIN (SELECT (fields->>'C 1')::int c1, (fields->>'c2')::int c2, tags->>'c3' c3, fields->>'c4' c4, fields->>'c5' c5, fields->>'c6' c6, fields->>'c7' c7, fields->>'c8' c8 FROM ft2 t2) t2 ON ((t1.c1)::int = (t2.c1)::int) JOIN (SELECT (fields->>'c1')::int c1, (fields->>'c2')::int c2, tags->>'c3' c3 FROM ft4 t3) t3 ON ((t3.c1)::int = (t1.c1)::int) ORDER BY t1.c3, (t1.c1)::int OFFSET 10 LIMIT 10; + QUERY PLAN +----------------------------------------------------------------------------------------------------------------------------------------------------------- + Limit + Output: (((t1.fields ->> 'C 1'::text))::integer), (((t2.fields ->> 'c2'::text))::integer), ((t3.tags ->> 'c3'::text)), ((t1.tags ->> 'c3'::text)) + -> Sort + Output: (((t1.fields ->> 'C 1'::text))::integer), (((t2.fields ->> 'c2'::text))::integer), ((t3.tags ->> 'c3'::text)), ((t1.tags ->> 'c3'::text)) + Sort Key: ((t1.tags ->> 'c3'::text)), (((t1.fields ->> 'C 1'::text))::integer) + -> Merge Join + Output: ((t1.fields ->> 'C 1'::text))::integer, ((t2.fields ->> 'c2'::text))::integer, (t3.tags ->> 'c3'::text), (t1.tags ->> 'c3'::text) + Merge Cond: ((((t2.fields ->> 'C 1'::text))::integer) = ((t1.fields ->> 'C 1'::text))::integer) + -> Sort + Output: t2.fields, (((t2.fields ->> 'C 1'::text))::integer) + Sort Key: (((t2.fields ->> 'C 1'::text))::integer) + -> Foreign Scan on public.ft2 t2 + Output: t2.fields, ((t2.fields ->> 'C 1'::text))::integer + InfluxDB query: SELECT * FROM "T1" + -> Materialize + Output: t1.fields, t1.tags, t3.tags, t3.fields + -> Merge Join + Output: t1.fields, t1.tags, t3.tags, t3.fields + Merge Cond: ((((t1.fields ->> 'C 1'::text))::integer) = (((t3.fields ->> 'c1'::text))::integer)) + -> Sort + Output: t1.fields, t1.tags, (((t1.fields ->> 'C 1'::text))::integer) + Sort Key: (((t1.fields ->> 'C 1'::text))::integer) + -> Foreign Scan on public.ft1 t1 + Output: t1.fields, t1.tags, ((t1.fields ->> 'C 1'::text))::integer + InfluxDB query: SELECT * FROM "T1" + -> Sort + Output: t3.tags, t3.fields, (((t3.fields ->> 'c1'::text))::integer) + Sort Key: (((t3.fields ->> 'c1'::text))::integer) + -> Foreign Scan on public.ft4 t3 + Output: t3.tags, t3.fields, ((t3.fields ->> 'c1'::text))::integer + InfluxDB query: SELECT * FROM "T3" +(31 rows) + +--Testcase 118: +SELECT t1.c1, t2.c2, t3.c3 FROM (SELECT (fields->>'C 1')::int c1, (fields->>'c2')::int c2, tags->>'c3' c3, fields->>'c4' c4, fields->>'c5' c5, fields->>'c6' c6, fields->>'c7' c7, fields->>'c8' c8 FROM ft1 t1) t1 JOIN (SELECT (fields->>'C 1')::int c1, (fields->>'c2')::int c2, tags->>'c3' c3, fields->>'c4' c4, fields->>'c5' c5, fields->>'c6' c6, fields->>'c7' c7, fields->>'c8' c8 FROM ft2 t2) t2 ON ((t1.c1)::int = (t2.c1)::int) JOIN (SELECT (fields->>'c1')::int c1, (fields->>'c2')::int c2, tags->>'c3' c3 FROM ft4 t3) t3 ON ((t3.c1)::int = (t1.c1)::int) ORDER BY t1.c3, (t1.c1)::int OFFSET 10 LIMIT 10; + c1 | c2 | c3 +----+----+-------- + 22 | 2 | AAA022 + 24 | 4 | AAA024 + 26 | 6 | AAA026 + 28 | 8 | AAA028 + 30 | 0 | AAA030 + 32 | 2 | AAA032 + 34 | 4 | AAA034 + 36 | 6 | AAA036 + 38 | 8 | AAA038 + 40 | 0 | AAA040 +(10 rows) + +-- left outer join +--Testcase 119: +EXPLAIN (VERBOSE, COSTS OFF) +SELECT t1.c1, t2.c1 FROM (SELECT (fields->>'c1')::int c1, (fields->>'c2')::int c2, tags->>'c3' c3 FROM ft4 t1) t1 LEFT JOIN (SELECT (fields->>'c1')::int c1, (fields->>'c2')::int c2, tags->>'c3' c3 FROM ft5 t2) t2 ON ((t1.c1)::int = (t2.c1)::int) ORDER BY (t1.c1)::int, (t2.c1)::int OFFSET 10 LIMIT 10; + QUERY PLAN +--------------------------------------------------------------------------------------------------------------------------- + Limit + Output: (((t1.fields ->> 'c1'::text))::integer), (((t2.fields ->> 'c1'::text))::integer) + -> Incremental Sort + Output: (((t1.fields ->> 'c1'::text))::integer), (((t2.fields ->> 'c1'::text))::integer) + Sort Key: (((t1.fields ->> 'c1'::text))::integer), (((t2.fields ->> 'c1'::text))::integer) + Presorted Key: (((t1.fields ->> 'c1'::text))::integer) + -> Merge Left Join + Output: (((t1.fields ->> 'c1'::text))::integer), (((t2.fields ->> 'c1'::text))::integer) + Merge Cond: ((((t1.fields ->> 'c1'::text))::integer) = (((t2.fields ->> 'c1'::text))::integer)) + -> Sort + Output: t1.fields, (((t1.fields ->> 'c1'::text))::integer) + Sort Key: (((t1.fields ->> 'c1'::text))::integer) + -> Foreign Scan on public.ft4 t1 + Output: t1.fields, ((t1.fields ->> 'c1'::text))::integer + InfluxDB query: SELECT * FROM "T3" + -> Sort + Output: t2.fields, (((t2.fields ->> 'c1'::text))::integer), (((t2.fields ->> 'c1'::text))::integer) + Sort Key: (((t2.fields ->> 'c1'::text))::integer) + -> Foreign Scan on public.ft5 t2 + Output: t2.fields, ((t2.fields ->> 'c1'::text))::integer, ((t2.fields ->> 'c1'::text))::integer + InfluxDB query: SELECT * FROM "T4" +(21 rows) + +--Testcase 120: +SELECT t1.c1, t2.c1 FROM (SELECT (fields->>'c1')::int c1, (fields->>'c2')::int c2, tags->>'c3' c3 FROM ft4 t1) t1 LEFT JOIN (SELECT (fields->>'c1')::int c1, (fields->>'c2')::int c2, tags->>'c3' c3 FROM ft5 t2) t2 ON ((t1.c1)::int = (t2.c1)::int) ORDER BY (t1.c1)::int, (t2.c1)::int OFFSET 10 LIMIT 10; + c1 | c1 +----+---- + 22 | + 24 | 24 + 26 | + 28 | + 30 | 30 + 32 | + 34 | + 36 | 36 + 38 | + 40 | +(10 rows) + +-- left outer join three tables +--Testcase 121: +EXPLAIN (VERBOSE, COSTS OFF) +SELECT t1.c1, t2.c2, t3.c3 FROM (SELECT (fields->>'C 1')::int c1, (fields->>'c2')::int c2, tags->>'c3' c3, fields->>'c4' c4, fields->>'c5' c5, fields->>'c6' c6, fields->>'c7' c7, fields->>'c8' c8 FROM ft2 t1) t1 LEFT JOIN (SELECT (fields->>'C 1')::int c1, (fields->>'c2')::int c2, tags->>'c3' c3, fields->>'c4' c4, fields->>'c5' c5, fields->>'c6' c6, fields->>'c7' c7, fields->>'c8' c8 FROM ft2 t2) t2 ON ((t1.c1)::int = (t2.c1)::int) LEFT JOIN (SELECT (fields->>'c1')::int c1, (fields->>'c2')::int c2, tags->>'c3' c3 FROM ft4 t3) t3 ON ((t2.c1)::int = (t3.c1)::int) OFFSET 10 LIMIT 10; + QUERY PLAN +----------------------------------------------------------------------------------------------------------------------------- + Limit + Output: (((t1.fields ->> 'C 1'::text))::integer), (((t2.fields ->> 'c2'::text))::integer), ((t3.tags ->> 'c3'::text)) + -> Nested Loop Left Join + Output: ((t1.fields ->> 'C 1'::text))::integer, (((t2.fields ->> 'c2'::text))::integer), ((t3.tags ->> 'c3'::text)) + Join Filter: ((((t2.fields ->> 'C 1'::text))::integer) = ((t3.fields ->> 'c1'::text))::integer) + -> Nested Loop Left Join + Output: t1.fields, (((t2.fields ->> 'c2'::text))::integer), (((t2.fields ->> 'C 1'::text))::integer) + Join Filter: (((t1.fields ->> 'C 1'::text))::integer = ((t2.fields ->> 'C 1'::text))::integer) + -> Foreign Scan on public.ft2 t1 + Output: t1."time", t1.tags, t1.fields + InfluxDB query: SELECT * FROM "T1" + -> Materialize + Output: t2.fields, (((t2.fields ->> 'c2'::text))::integer), (((t2.fields ->> 'C 1'::text))::integer) + -> Foreign Scan on public.ft2 t2 + Output: t2.fields, ((t2.fields ->> 'c2'::text))::integer, ((t2.fields ->> 'C 1'::text))::integer + InfluxDB query: SELECT * FROM "T1" + -> Materialize + Output: t3.fields, ((t3.tags ->> 'c3'::text)) + -> Foreign Scan on public.ft4 t3 + Output: t3.fields, (t3.tags ->> 'c3'::text) + InfluxDB query: SELECT * FROM "T3" +(21 rows) + +--Testcase 122: +SELECT t1.c1, t2.c2, t3.c3 FROM (SELECT (fields->>'C 1')::int c1, (fields->>'c2')::int c2, tags->>'c3' c3, fields->>'c4' c4, fields->>'c5' c5, fields->>'c6' c6, fields->>'c7' c7, fields->>'c8' c8 FROM ft2 t1) t1 LEFT JOIN (SELECT (fields->>'C 1')::int c1, (fields->>'c2')::int c2, tags->>'c3' c3, fields->>'c4' c4, fields->>'c5' c5, fields->>'c6' c6, fields->>'c7' c7, fields->>'c8' c8 FROM ft2 t2) t2 ON ((t1.c1)::int = (t2.c1)::int) LEFT JOIN (SELECT (fields->>'c1')::int c1, (fields->>'c2')::int c2, tags->>'c3' c3 FROM ft4 t3) t3 ON ((t2.c1)::int = (t3.c1)::int) ORDER BY (t1.c1)::int OFFSET 10 LIMIT 10; + c1 | c2 | c3 +----+----+-------- + 11 | 1 | + 12 | 2 | AAA012 + 13 | 3 | + 14 | 4 | AAA014 + 15 | 5 | + 16 | 6 | AAA016 + 17 | 7 | + 18 | 8 | AAA018 + 19 | 9 | + 20 | 0 | AAA020 +(10 rows) + +-- left outer join + placement of clauses. +-- clauses within the nullable side are not pulled up, but top level clause on +-- non-nullable side is pushed into non-nullable side +--Testcase 123: +EXPLAIN (VERBOSE, COSTS OFF) +SELECT t1.c1, t1.c2, (t2.fields->>'c1')::int c1, (t2.fields->>'c2')::int c2 FROM (SELECT (fields->>'c1')::int c1, (fields->>'c2')::int c2, tags->>'c3' c3 FROM ft4 t1) t1 LEFT JOIN (SELECT * FROM ft5 t2 WHERE (fields->>'c1')::int < 10) t2 ON ((t1.c1)::int = (t2.fields->>'c1')::int) WHERE (t1.c1)::int < 10; + QUERY PLAN +------------------------------------------------------------------------------------------------------------------------------------------------------------------------ + Merge Left Join + Output: (((t1.fields ->> 'c1'::text))::integer), ((t1.fields ->> 'c2'::text))::integer, ((t2.fields ->> 'c1'::text))::integer, ((t2.fields ->> 'c2'::text))::integer + Merge Cond: ((((t1.fields ->> 'c1'::text))::integer) = (((t2.fields ->> 'c1'::text))::integer)) + -> Sort + Output: t1.fields, (((t1.fields ->> 'c1'::text))::integer) + Sort Key: (((t1.fields ->> 'c1'::text))::integer) + -> Foreign Scan on public.ft4 t1 + Output: t1.fields, ((t1.fields ->> 'c1'::text))::integer + InfluxDB query: SELECT * FROM "T3" WHERE (("c1" < 10)) + -> Sort + Output: t2.fields, (((t2.fields ->> 'c1'::text))::integer) + Sort Key: (((t2.fields ->> 'c1'::text))::integer) + -> Foreign Scan on public.ft5 t2 + Output: t2.fields, ((t2.fields ->> 'c1'::text))::integer + InfluxDB query: SELECT * FROM "T4" WHERE (("c1" < 10)) +(15 rows) + +--Testcase 124: +SELECT t1.c1, t1.c2, (t2.fields->>'c1')::int c1, (t2.fields->>'c2')::int c2 FROM (SELECT (fields->>'c1')::int c1, (fields->>'c2')::int c2, tags->>'c3' c3 FROM ft4 t1) t1 LEFT JOIN (SELECT * FROM ft5 t2 WHERE (fields->>'c1')::int < 10) t2 ON ((t1.c1)::int = (t2.fields->>'c1')::int) WHERE (t1.c1)::int < 10; + c1 | c2 | c1 | c2 +----+----+----+---- + 2 | 3 | | + 4 | 5 | | + 6 | 7 | 6 | 7 + 8 | 9 | | +(4 rows) + +-- clauses within the nullable side are not pulled up, but the top level clause +-- on nullable side is not pushed down into nullable side +--Testcase 125: +EXPLAIN (VERBOSE, COSTS OFF) +SELECT t1.c1, t1.c2, (t2.fields->>'c1')::int c1, (t2.fields->>'c2')::int c2 FROM (SELECT (fields->>'c1')::int c1, (fields->>'c2')::int c2, tags->>'c3' c3 FROM ft4 t1) t1 LEFT JOIN (SELECT * FROM ft5 t2 WHERE (fields->>'c1')::int < 10) t2 ON ((t1.c1)::int = (t2.fields->>'c1')::int) + WHERE ((t2.fields->>'c1')::int < 10 OR (t2.fields->>'c1')::int IS NULL) AND (t1.c1)::int < 10; + QUERY PLAN +------------------------------------------------------------------------------------------------------------------------------------------------------------------------ + Merge Left Join + Output: (((t1.fields ->> 'c1'::text))::integer), ((t1.fields ->> 'c2'::text))::integer, ((t2.fields ->> 'c1'::text))::integer, ((t2.fields ->> 'c2'::text))::integer + Merge Cond: ((((t1.fields ->> 'c1'::text))::integer) = (((t2.fields ->> 'c1'::text))::integer)) + Filter: ((((t2.fields ->> 'c1'::text))::integer < 10) OR (((t2.fields ->> 'c1'::text))::integer IS NULL)) + -> Sort + Output: t1.fields, (((t1.fields ->> 'c1'::text))::integer) + Sort Key: (((t1.fields ->> 'c1'::text))::integer) + -> Foreign Scan on public.ft4 t1 + Output: t1.fields, ((t1.fields ->> 'c1'::text))::integer + InfluxDB query: SELECT * FROM "T3" WHERE (("c1" < 10)) + -> Sort + Output: t2.fields, (((t2.fields ->> 'c1'::text))::integer) + Sort Key: (((t2.fields ->> 'c1'::text))::integer) + -> Foreign Scan on public.ft5 t2 + Output: t2.fields, ((t2.fields ->> 'c1'::text))::integer + InfluxDB query: SELECT * FROM "T4" WHERE (("c1" < 10)) +(16 rows) + +--Testcase 126: +SELECT t1.c1, t1.c2, (t2.fields->>'c1')::int c1, (t2.fields->>'c2')::int c2 FROM (SELECT (fields->>'c1')::int c1, (fields->>'c2')::int c2, tags->>'c3' c3 FROM ft4 t1) t1 LEFT JOIN (SELECT * FROM ft5 t2 WHERE (fields->>'c1')::int < 10) t2 ON ((t1.c1)::int = (t2.fields->>'c1')::int) + WHERE ((t2.fields->>'c1')::int < 10 OR (t2.fields->>'c1')::int IS NULL) AND (t1.c1)::int < 10; + c1 | c2 | c1 | c2 +----+----+----+---- + 2 | 3 | | + 4 | 5 | | + 6 | 7 | 6 | 7 + 8 | 9 | | +(4 rows) + +-- right outer join +--Testcase 127: +EXPLAIN (VERBOSE, COSTS OFF) +SELECT t1.c1, t2.c1 FROM (SELECT (fields->>'c1')::int c1, (fields->>'c2')::int c2, tags->>'c3' c3 FROM ft5 t1) t1 RIGHT JOIN (SELECT (fields->>'c1')::int c1, (fields->>'c2')::int c2, tags->>'c3' c3 FROM ft4 t2) t2 ON ((t1.c1)::int = (t2.c1)::int) ORDER BY (t2.c1)::int, (t1.c1)::int OFFSET 10 LIMIT 10; + QUERY PLAN +--------------------------------------------------------------------------------------------------------------------------- + Limit + Output: (((t1.fields ->> 'c1'::text))::integer), (((t2.fields ->> 'c1'::text))::integer) + -> Incremental Sort + Output: (((t1.fields ->> 'c1'::text))::integer), (((t2.fields ->> 'c1'::text))::integer) + Sort Key: (((t2.fields ->> 'c1'::text))::integer), (((t1.fields ->> 'c1'::text))::integer) + Presorted Key: (((t2.fields ->> 'c1'::text))::integer) + -> Merge Left Join + Output: (((t1.fields ->> 'c1'::text))::integer), (((t2.fields ->> 'c1'::text))::integer) + Merge Cond: ((((t2.fields ->> 'c1'::text))::integer) = (((t1.fields ->> 'c1'::text))::integer)) + -> Sort + Output: t2.fields, (((t2.fields ->> 'c1'::text))::integer) + Sort Key: (((t2.fields ->> 'c1'::text))::integer) + -> Foreign Scan on public.ft4 t2 + Output: t2.fields, ((t2.fields ->> 'c1'::text))::integer + InfluxDB query: SELECT * FROM "T3" + -> Sort + Output: t1.fields, (((t1.fields ->> 'c1'::text))::integer), (((t1.fields ->> 'c1'::text))::integer) + Sort Key: (((t1.fields ->> 'c1'::text))::integer) + -> Foreign Scan on public.ft5 t1 + Output: t1.fields, ((t1.fields ->> 'c1'::text))::integer, ((t1.fields ->> 'c1'::text))::integer + InfluxDB query: SELECT * FROM "T4" +(21 rows) + +--Testcase 128: +SELECT t1.c1, t2.c1 FROM (SELECT (fields->>'c1')::int c1, (fields->>'c2')::int c2, tags->>'c3' c3 FROM ft5 t1) t1 RIGHT JOIN (SELECT (fields->>'c1')::int c1, (fields->>'c2')::int c2, tags->>'c3' c3 FROM ft4 t2) t2 ON ((t1.c1)::int = (t2.c1)::int) ORDER BY (t2.c1)::int, (t1.c1)::int OFFSET 10 LIMIT 10; + c1 | c1 +----+---- + | 22 + 24 | 24 + | 26 + | 28 + 30 | 30 + | 32 + | 34 + 36 | 36 + | 38 + | 40 +(10 rows) + +-- right outer join three tables +--Testcase 129: +EXPLAIN (VERBOSE, COSTS OFF) +SELECT t1.c1, t2.c2, t3.c3 FROM (SELECT (fields->>'C 1')::int c1, (fields->>'c2')::int c2, tags->>'c3' c3, fields->>'c4' c4, fields->>'c5' c5, fields->>'c6' c6, fields->>'c7' c7, fields->>'c8' c8 FROM ft2 t1) t1 RIGHT JOIN (SELECT (fields->>'C 1')::int c1, (fields->>'c2')::int c2, tags->>'c3' c3, fields->>'c4' c4, fields->>'c5' c5, fields->>'c6' c6, fields->>'c7' c7, fields->>'c8' c8 FROM ft2 t2) t2 ON ((t1.c1)::int = (t2.c1)::int) RIGHT JOIN (SELECT (fields->>'c1')::int c1, (fields->>'c2')::int c2, tags->>'c3' c3 FROM ft4 t3) t3 ON ((t2.c1)::int = (t3.c1)::int) OFFSET 10 LIMIT 10; + QUERY PLAN +----------------------------------------------------------------------------------------------------------------------------- + Limit + Output: (((t1.fields ->> 'C 1'::text))::integer), (((t2.fields ->> 'c2'::text))::integer), ((t3.tags ->> 'c3'::text)) + -> Hash Right Join + Output: (((t1.fields ->> 'C 1'::text))::integer), (((t2.fields ->> 'c2'::text))::integer), (t3.tags ->> 'c3'::text) + Hash Cond: (((t2.fields ->> 'C 1'::text))::integer = ((t3.fields ->> 'c1'::text))::integer) + -> Nested Loop Left Join + Output: t2.fields, (((t2.fields ->> 'c2'::text))::integer), (((t1.fields ->> 'C 1'::text))::integer) + Join Filter: (((t1.fields ->> 'C 1'::text))::integer = ((t2.fields ->> 'C 1'::text))::integer) + -> Foreign Scan on public.ft2 t2 + Output: t2.fields, ((t2.fields ->> 'c2'::text))::integer + InfluxDB query: SELECT * FROM "T1" + -> Materialize + Output: t1.fields, (((t1.fields ->> 'C 1'::text))::integer) + -> Foreign Scan on public.ft2 t1 + Output: t1.fields, ((t1.fields ->> 'C 1'::text))::integer + InfluxDB query: SELECT * FROM "T1" + -> Hash + Output: t3.tags, t3.fields + -> Foreign Scan on public.ft4 t3 + Output: t3.tags, t3.fields + InfluxDB query: SELECT * FROM "T3" +(21 rows) + +--Testcase 130: +SELECT t1.c1, t2.c2, t3.c3 FROM (SELECT (fields->>'C 1')::int c1, (fields->>'c2')::int c2, tags->>'c3' c3, fields->>'c4' c4, fields->>'c5' c5, fields->>'c6' c6, fields->>'c7' c7, fields->>'c8' c8 FROM ft2 t1) t1 RIGHT JOIN (SELECT (fields->>'C 1')::int c1, (fields->>'c2')::int c2, tags->>'c3' c3, fields->>'c4' c4, fields->>'c5' c5, fields->>'c6' c6, fields->>'c7' c7, fields->>'c8' c8 FROM ft2 t2) t2 ON ((t1.c1)::int = (t2.c1)::int) RIGHT JOIN (SELECT (fields->>'c1')::int c1, (fields->>'c2')::int c2, tags->>'c3' c3 FROM ft4 t3) t3 ON ((t2.c1)::int = (t3.c1)::int) OFFSET 10 LIMIT 10; + c1 | c2 | c3 +----+----+-------- + 20 | 0 | AAA020 + 22 | 2 | AAA022 + 24 | 4 | AAA024 + 26 | 6 | AAA026 + 28 | 8 | AAA028 + 30 | 0 | AAA030 + 32 | 2 | AAA032 + 34 | 4 | AAA034 + 36 | 6 | AAA036 + 38 | 8 | AAA038 +(10 rows) + +-- full outer join +--Testcase 131: +EXPLAIN (VERBOSE, COSTS OFF) +SELECT t1.c1, t2.c1 FROM (SELECT (fields->>'c1')::int c1, (fields->>'c2')::int c2, tags->>'c3' c3 FROM ft4 t1) t1 FULL JOIN (SELECT (fields->>'c1')::int c1, (fields->>'c2')::int c2, tags->>'c3' c3 FROM ft5 t2) t2 ON ((t1.c1)::int = (t2.c1)::int) ORDER BY (t1.c1)::int, (t2.c1)::int OFFSET 45 LIMIT 10; + QUERY PLAN +--------------------------------------------------------------------------------------------------------------- + Limit + Output: (((t1.fields ->> 'c1'::text))::integer), (((t2.fields ->> 'c1'::text))::integer) + -> Sort + Output: (((t1.fields ->> 'c1'::text))::integer), (((t2.fields ->> 'c1'::text))::integer) + Sort Key: (((t1.fields ->> 'c1'::text))::integer), (((t2.fields ->> 'c1'::text))::integer) + -> Merge Full Join + Output: (((t1.fields ->> 'c1'::text))::integer), (((t2.fields ->> 'c1'::text))::integer) + Merge Cond: ((((t1.fields ->> 'c1'::text))::integer) = (((t2.fields ->> 'c1'::text))::integer)) + -> Sort + Output: (((t1.fields ->> 'c1'::text))::integer) + Sort Key: (((t1.fields ->> 'c1'::text))::integer) + -> Foreign Scan on public.ft4 t1 + Output: ((t1.fields ->> 'c1'::text))::integer + InfluxDB query: SELECT "c1" FROM "T3" + -> Sort + Output: (((t2.fields ->> 'c1'::text))::integer) + Sort Key: (((t2.fields ->> 'c1'::text))::integer) + -> Foreign Scan on public.ft5 t2 + Output: ((t2.fields ->> 'c1'::text))::integer + InfluxDB query: SELECT "c1" FROM "T4" +(20 rows) + +--Testcase 132: +SELECT t1.c1, t2.c1 FROM (SELECT (fields->>'c1')::int c1, (fields->>'c2')::int c2, tags->>'c3' c3 FROM ft4 t1) t1 FULL JOIN (SELECT (fields->>'c1')::int c1, (fields->>'c2')::int c2, tags->>'c3' c3 FROM ft5 t2) t2 ON ((t1.c1)::int = (t2.c1)::int) ORDER BY (t1.c1)::int, (t2.c1)::int OFFSET 45 LIMIT 10; + c1 | c1 +-----+---- + 92 | + 94 | + 96 | 96 + 98 | + 100 | + | 3 + | 9 + | 15 + | 21 + | 27 +(10 rows) + +-- full outer join with restrictions on the joining relations +-- a. the joining relations are both base relations +--Testcase 133: +EXPLAIN (VERBOSE, COSTS OFF) +SELECT t1.c1, t2.c1 FROM (SELECT (fields->>'c1')::int c1 FROM ft4 t1 WHERE (fields->>'c1')::int between 50 and 60) t1 FULL JOIN (SELECT (fields->>'c1')::int c1 FROM ft5 t2 WHERE (fields->>'c1')::int between 50 and 60) t2 ON ((t1.c1)::int = (t2.c1)::int) ORDER BY (t1.c1)::int, (t2.c1)::int; + QUERY PLAN +-------------------------------------------------------------------------------------------------------- + Sort + Output: (((t1.fields ->> 'c1'::text))::integer), (((t2.fields ->> 'c1'::text))::integer) + Sort Key: (((t1.fields ->> 'c1'::text))::integer), (((t2.fields ->> 'c1'::text))::integer) + -> Hash Full Join + Output: (((t1.fields ->> 'c1'::text))::integer), (((t2.fields ->> 'c1'::text))::integer) + Hash Cond: ((((t1.fields ->> 'c1'::text))::integer) = (((t2.fields ->> 'c1'::text))::integer)) + -> Foreign Scan on public.ft4 t1 + Output: ((t1.fields ->> 'c1'::text))::integer + InfluxDB query: SELECT "c1" FROM "T3" WHERE (("c1" >= 50)) AND (("c1" <= 60)) + -> Hash + Output: (((t2.fields ->> 'c1'::text))::integer) + -> Foreign Scan on public.ft5 t2 + Output: ((t2.fields ->> 'c1'::text))::integer + InfluxDB query: SELECT "c1" FROM "T4" WHERE (("c1" >= 50)) AND (("c1" <= 60)) +(14 rows) + +--Testcase 134: +SELECT t1.c1, t2.c1 FROM (SELECT (fields->>'c1')::int c1 FROM ft4 t1 WHERE (fields->>'c1')::int between 50 and 60) t1 FULL JOIN (SELECT (fields->>'c1')::int c1 FROM ft5 t2 WHERE (fields->>'c1')::int between 50 and 60) t2 ON ((t1.c1)::int = (t2.c1)::int) ORDER BY (t1.c1)::int, (t2.c1)::int; + c1 | c1 +----+---- + 50 | + 52 | + 54 | 54 + 56 | + 58 | + 60 | 60 + | 51 + | 57 +(8 rows) + +--Testcase 135: +EXPLAIN (VERBOSE, COSTS OFF) +SELECT 1 FROM (SELECT (fields->>'c1')::int c1 FROM ft4 t1 WHERE (fields->>'c1')::int between 50 and 60) t1 FULL JOIN (SELECT (fields->>'c1')::int c1 FROM ft5 t2 WHERE (fields->>'c1')::int between 50 and 60) t2 ON (TRUE) OFFSET 10 LIMIT 10; + QUERY PLAN +------------------------------------------------------------------------------------------------ + Limit + Output: 1 + -> Merge Full Join + Output: 1 + -> Foreign Scan on public.ft4 t1 + Output: t1.tags, t1.fields + InfluxDB query: SELECT * FROM "T3" WHERE (("c1" >= 50)) AND (("c1" <= 60)) + -> Materialize + Output: t2.tags, t2.fields + -> Foreign Scan on public.ft5 t2 + Output: t2.tags, t2.fields + InfluxDB query: SELECT * FROM "T4" WHERE (("c1" >= 50)) AND (("c1" <= 60)) +(12 rows) + +--Testcase 136: +SELECT 1 FROM (SELECT (fields->>'c1')::int c1 FROM ft4 t1 WHERE (fields->>'c1')::int between 50 and 60) t1 FULL JOIN (SELECT (fields->>'c1')::int c1 FROM ft5 t2 WHERE (fields->>'c1')::int between 50 and 60) t2 ON (TRUE) OFFSET 10 LIMIT 10; + ?column? +---------- + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 1 +(10 rows) + +-- b. one of the joining relations is a base relation and the other is a join +-- relation +--Testcase 137: +EXPLAIN (VERBOSE, COSTS OFF) +SELECT t1.c1, ss.a, ss.b FROM (SELECT (fields->>'c1')::int c1 FROM ft4 t1 WHERE (fields->>'c1')::int between 50 and 60) t1 FULL JOIN (SELECT (t2.c1)::int, (t3.c1)::int FROM (SELECT (fields->>'c1')::int c1, (fields->>'c2')::int c2, tags->>'c3' c3 FROM ft4 t2) t2 LEFT JOIN (SELECT (fields->>'c1')::int c1, fields->>'c2' c2, tags->>'c3' c3 FROM ft5 t3) t3 ON ((t2.c1)::int = (t3.c1)::int) WHERE ((t2.c1)::int between 50 and 60)) ss(a, b) ON ((t1.c1)::int = ss.a) ORDER BY (t1.c1)::int, ss.a, ss.b; + QUERY PLAN +------------------------------------------------------------------------------------------------------------------------------------------- + Sort + Output: (((t1.fields ->> 'c1'::text))::integer), (((t2.fields ->> 'c1'::text))::integer), (((t3.fields ->> 'c1'::text))::integer) + Sort Key: (((t1.fields ->> 'c1'::text))::integer), (((t2.fields ->> 'c1'::text))::integer), (((t3.fields ->> 'c1'::text))::integer) + -> Hash Full Join + Output: (((t1.fields ->> 'c1'::text))::integer), (((t2.fields ->> 'c1'::text))::integer), (((t3.fields ->> 'c1'::text))::integer) + Hash Cond: ((((t2.fields ->> 'c1'::text))::integer) = (((t1.fields ->> 'c1'::text))::integer)) + -> Hash Right Join + Output: (((t2.fields ->> 'c1'::text))::integer), (((t3.fields ->> 'c1'::text))::integer) + Hash Cond: (((t3.fields ->> 'c1'::text))::integer = ((t2.fields ->> 'c1'::text))::integer) + -> Foreign Scan on public.ft5 t3 + Output: t3.fields, ((t3.fields ->> 'c1'::text))::integer + InfluxDB query: SELECT * FROM "T4" + -> Hash + Output: t2.fields, (((t2.fields ->> 'c1'::text))::integer) + -> Foreign Scan on public.ft4 t2 + Output: t2.fields, ((t2.fields ->> 'c1'::text))::integer + InfluxDB query: SELECT * FROM "T3" WHERE (("c1" >= 50)) AND (("c1" <= 60)) + -> Hash + Output: (((t1.fields ->> 'c1'::text))::integer) + -> Foreign Scan on public.ft4 t1 + Output: ((t1.fields ->> 'c1'::text))::integer + InfluxDB query: SELECT "c1" FROM "T3" WHERE (("c1" >= 50)) AND (("c1" <= 60)) +(22 rows) + +--Testcase 138: +SELECT t1.c1, ss.a, ss.b FROM (SELECT (fields->>'c1')::int c1 FROM ft4 t1 WHERE (fields->>'c1')::int between 50 and 60) t1 FULL JOIN (SELECT (t2.c1)::int, (t3.c1)::int FROM (SELECT (fields->>'c1')::int c1, (fields->>'c2')::int c2, tags->>'c3' c3 FROM ft4 t2) t2 LEFT JOIN (SELECT (fields->>'c1')::int c1, fields->>'c2' c2, tags->>'c3' c3 FROM ft5 t3) t3 ON ((t2.c1)::int = (t3.c1)::int) WHERE ((t2.c1)::int between 50 and 60)) ss(a, b) ON ((t1.c1)::int = ss.a) ORDER BY (t1.c1)::int, ss.a, ss.b; + c1 | a | b +----+----+---- + 50 | 50 | + 52 | 52 | + 54 | 54 | 54 + 56 | 56 | + 58 | 58 | + 60 | 60 | 60 +(6 rows) + +-- c. test deparsing the remote query as nested subqueries +--Testcase 139: +EXPLAIN (VERBOSE, COSTS OFF) +SELECT t1.c1, ss.a, ss.b FROM (SELECT (fields->>'c1')::int c1 FROM ft4 t1 WHERE (fields->>'c1')::int between 50 and 60) t1 FULL JOIN (SELECT (t2.c1)::int, (t3.c1)::int FROM (SELECT (fields->>'c1')::int c1 FROM ft4 t2 WHERE (fields->>'c1')::int between 50 and 60) t2 FULL JOIN (SELECT (fields->>'c1')::int c1 FROM ft5 t3 WHERE (fields->>'c1')::int between 50 and 60) t3 ON ((t2.c1)::int = (t3.c1)::int) WHERE (t2.c1)::int IS NULL OR (t2.c1)::int IS NOT NULL) ss(a, b) ON ((t1.c1)::int = ss.a) ORDER BY (t1.c1)::int, ss.a, ss.b; + QUERY PLAN +------------------------------------------------------------------------------------------------------------------------------------------- + Sort + Output: (((t1.fields ->> 'c1'::text))::integer), (((t2.fields ->> 'c1'::text))::integer), (((t3.fields ->> 'c1'::text))::integer) + Sort Key: (((t1.fields ->> 'c1'::text))::integer), (((t2.fields ->> 'c1'::text))::integer), (((t3.fields ->> 'c1'::text))::integer) + -> Hash Full Join + Output: (((t1.fields ->> 'c1'::text))::integer), (((t2.fields ->> 'c1'::text))::integer), (((t3.fields ->> 'c1'::text))::integer) + Hash Cond: ((((t2.fields ->> 'c1'::text))::integer) = (((t1.fields ->> 'c1'::text))::integer)) + -> Hash Full Join + Output: (((t2.fields ->> 'c1'::text))::integer), (((t3.fields ->> 'c1'::text))::integer) + Hash Cond: ((((t2.fields ->> 'c1'::text))::integer) = (((t3.fields ->> 'c1'::text))::integer)) + Filter: (((((t2.fields ->> 'c1'::text))::integer) IS NULL) OR ((((t2.fields ->> 'c1'::text))::integer) IS NOT NULL)) + -> Foreign Scan on public.ft4 t2 + Output: ((t2.fields ->> 'c1'::text))::integer + InfluxDB query: SELECT "c1" FROM "T3" WHERE (("c1" >= 50)) AND (("c1" <= 60)) + -> Hash + Output: (((t3.fields ->> 'c1'::text))::integer) + -> Foreign Scan on public.ft5 t3 + Output: ((t3.fields ->> 'c1'::text))::integer + InfluxDB query: SELECT "c1" FROM "T4" WHERE (("c1" >= 50)) AND (("c1" <= 60)) + -> Hash + Output: (((t1.fields ->> 'c1'::text))::integer) + -> Foreign Scan on public.ft4 t1 + Output: ((t1.fields ->> 'c1'::text))::integer + InfluxDB query: SELECT "c1" FROM "T3" WHERE (("c1" >= 50)) AND (("c1" <= 60)) +(23 rows) + +--Testcase 140: +SELECT t1.c1, ss.a, ss.b FROM (SELECT (fields->>'c1')::int c1 FROM ft4 t1 WHERE (fields->>'c1')::int between 50 and 60) t1 FULL JOIN (SELECT (t2.c1)::int, (t3.c1)::int FROM (SELECT (fields->>'c1')::int c1 FROM ft4 t2 WHERE (fields->>'c1')::int between 50 and 60) t2 FULL JOIN (SELECT (fields->>'c1')::int c1 FROM ft5 t3 WHERE (fields->>'c1')::int between 50 and 60) t3 ON ((t2.c1)::int = (t3.c1)::int) WHERE (t2.c1)::int IS NULL OR (t2.c1)::int IS NOT NULL) ss(a, b) ON ((t1.c1)::int = ss.a) ORDER BY (t1.c1)::int, ss.a, ss.b; + c1 | a | b +----+----+---- + 50 | 50 | + 52 | 52 | + 54 | 54 | 54 + 56 | 56 | + 58 | 58 | + 60 | 60 | 60 + | | 51 + | | 57 +(8 rows) + +-- d. test deparsing rowmarked relations as subqueries +--Testcase 141: +EXPLAIN (VERBOSE, COSTS OFF) +SELECT t1.c1, ss.a, ss.b FROM (SELECT (fields->>'c1')::int c1 FROM "S 1"."T 3" t1 WHERE (fields->>'c1')::int = 50) t1 INNER JOIN (SELECT (t2.c1)::int, (t3.c1)::int FROM (SELECT (fields->>'c1')::int c1 FROM ft4 t2 WHERE (fields->>'c1')::int between 50 and 60) t2 FULL JOIN (SELECT (fields->>'c1')::int c1 FROM ft5 t3 WHERE (fields->>'c1')::int between 50 and 60) t3 ON ((t2.c1)::int = (t3.c1)::int) WHERE (t2.c1)::int IS NULL OR (t2.c1)::int IS NOT NULL) ss(a, b) ON (TRUE) ORDER BY (t1.c1)::int, ss.a, ss.b FOR UPDATE OF t1; + QUERY PLAN +----------------------------------------------------------------------------------------------------------------------------------------------------------------- + LockRows + Output: (((t1.fields ->> 'c1'::text))::integer), (((t2.fields ->> 'c1'::text))::integer), (((t3.fields ->> 'c1'::text))::integer), t1.*, t2.*, t3.* + -> Sort + Output: (((t1.fields ->> 'c1'::text))::integer), (((t2.fields ->> 'c1'::text))::integer), (((t3.fields ->> 'c1'::text))::integer), t1.*, t2.*, t3.* + Sort Key: (((t2.fields ->> 'c1'::text))::integer), (((t3.fields ->> 'c1'::text))::integer) + -> Nested Loop + Output: ((t1.fields ->> 'c1'::text))::integer, (((t2.fields ->> 'c1'::text))::integer), (((t3.fields ->> 'c1'::text))::integer), t1.*, t2.*, t3.* + -> Merge Full Join + Output: t2.*, (((t2.fields ->> 'c1'::text))::integer), t3.*, (((t3.fields ->> 'c1'::text))::integer) + Merge Cond: ((((t2.fields ->> 'c1'::text))::integer) = (((t3.fields ->> 'c1'::text))::integer)) + Filter: (((((t2.fields ->> 'c1'::text))::integer) IS NULL) OR ((((t2.fields ->> 'c1'::text))::integer) IS NOT NULL)) + -> Sort + Output: t2.*, (((t2.fields ->> 'c1'::text))::integer) + Sort Key: (((t2.fields ->> 'c1'::text))::integer) + -> Foreign Scan on public.ft4 t2 + Output: t2.*, ((t2.fields ->> 'c1'::text))::integer + InfluxDB query: SELECT * FROM "T3" WHERE (("c1" >= 50)) AND (("c1" <= 60)) + -> Sort + Output: t3.*, (((t3.fields ->> 'c1'::text))::integer) + Sort Key: (((t3.fields ->> 'c1'::text))::integer) + -> Foreign Scan on public.ft5 t3 + Output: t3.*, ((t3.fields ->> 'c1'::text))::integer + InfluxDB query: SELECT * FROM "T4" WHERE (("c1" >= 50)) AND (("c1" <= 60)) + -> Materialize + Output: t1.fields, t1.* + -> Foreign Scan on "S 1"."T 3" t1 + Output: t1.fields, t1.* + InfluxDB query: SELECT * FROM "T3" WHERE (("c1" = 50)) +(28 rows) + +--Testcase 142: +SELECT t1.c1, ss.a, ss.b FROM (SELECT (fields->>'c1')::int c1 FROM "S 1"."T 3" t1 WHERE (fields->>'c1')::int = 50) t1 INNER JOIN (SELECT (t2.c1)::int, (t3.c1)::int FROM (SELECT (fields->>'c1')::int c1 FROM ft4 t2 WHERE (fields->>'c1')::int between 50 and 60) t2 FULL JOIN (SELECT (fields->>'c1')::int c1 FROM ft5 t3 WHERE (fields->>'c1')::int between 50 and 60) t3 ON ((t2.c1)::int = (t3.c1)::int) WHERE (t2.c1)::int IS NULL OR (t2.c1)::int IS NOT NULL) ss(a, b) ON (TRUE) ORDER BY (t1.c1)::int, ss.a, ss.b FOR UPDATE OF t1; + c1 | a | b +----+----+---- + 50 | 50 | + 50 | 52 | + 50 | 54 | 54 + 50 | 56 | + 50 | 58 | + 50 | 60 | 60 + 50 | | 51 + 50 | | 57 +(8 rows) + +-- full outer join + inner join +--Testcase 143: +EXPLAIN (VERBOSE, COSTS OFF) +SELECT t1.c1, t2.c1, t3.c1 FROM (SELECT (fields->>'c1')::int c1, (fields->>'c2')::int c2, tags->>'c3' c3 FROM ft4 t1) t1 INNER JOIN (SELECT (fields->>'c1')::int c1, (fields->>'c2')::int c2, tags->>'c3' c3 FROM ft5 t2) t2 ON ((t1.c1)::int = (t2.c1)::int + 1 and (t1.c1)::int between 50 and 60) FULL JOIN (SELECT (fields->>'c1')::int c1, (fields->>'c2')::int c2, tags->>'c3' c3 FROM ft4 t3) t3 ON ((t2.c1)::int = (t3.c1)::int) ORDER BY (t1.c1)::int, (t2.c1)::int, (t3.c1)::int LIMIT 10; + QUERY PLAN +------------------------------------------------------------------------------------------------------------------------------------------------- + Limit + Output: (((t1.fields ->> 'c1'::text))::integer), (((t2.fields ->> 'c1'::text))::integer), (((t3.fields ->> 'c1'::text))::integer) + -> Sort + Output: (((t1.fields ->> 'c1'::text))::integer), (((t2.fields ->> 'c1'::text))::integer), (((t3.fields ->> 'c1'::text))::integer) + Sort Key: (((t1.fields ->> 'c1'::text))::integer), (((t2.fields ->> 'c1'::text))::integer), (((t3.fields ->> 'c1'::text))::integer) + -> Hash Full Join + Output: (((t1.fields ->> 'c1'::text))::integer), (((t2.fields ->> 'c1'::text))::integer), (((t3.fields ->> 'c1'::text))::integer) + Hash Cond: ((((t3.fields ->> 'c1'::text))::integer) = (((t2.fields ->> 'c1'::text))::integer)) + -> Foreign Scan on public.ft4 t3 + Output: ((t3.fields ->> 'c1'::text))::integer + InfluxDB query: SELECT "c1" FROM "T3" + -> Hash + Output: (((t1.fields ->> 'c1'::text))::integer), (((t2.fields ->> 'c1'::text))::integer) + -> Hash Join + Output: (((t1.fields ->> 'c1'::text))::integer), (((t2.fields ->> 'c1'::text))::integer) + Hash Cond: ((((t2.fields ->> 'c1'::text))::integer + 1) = ((t1.fields ->> 'c1'::text))::integer) + -> Foreign Scan on public.ft5 t2 + Output: t2.fields, ((t2.fields ->> 'c1'::text))::integer + InfluxDB query: SELECT * FROM "T4" + -> Hash + Output: t1.fields, (((t1.fields ->> 'c1'::text))::integer) + -> Foreign Scan on public.ft4 t1 + Output: t1.fields, ((t1.fields ->> 'c1'::text))::integer + InfluxDB query: SELECT * FROM "T3" WHERE (("c1" >= 50)) AND (("c1" <= 60)) +(24 rows) + +--Testcase 144: +SELECT t1.c1, t2.c1, t3.c1 FROM (SELECT (fields->>'c1')::int c1, (fields->>'c2')::int c2, tags->>'c3' c3 FROM ft4 t1) t1 INNER JOIN (SELECT (fields->>'c1')::int c1, (fields->>'c2')::int c2, tags->>'c3' c3 FROM ft5 t2) t2 ON ((t1.c1)::int = (t2.c1)::int + 1 and (t1.c1)::int between 50 and 60) FULL JOIN (SELECT (fields->>'c1')::int c1, (fields->>'c2')::int c2, tags->>'c3' c3 FROM ft4 t3) t3 ON ((t2.c1)::int = (t3.c1)::int) ORDER BY (t1.c1)::int, (t2.c1)::int, (t3.c1)::int LIMIT 10; + c1 | c1 | c1 +----+----+---- + 52 | 51 | + 58 | 57 | + | | 2 + | | 4 + | | 6 + | | 8 + | | 10 + | | 12 + | | 14 + | | 16 +(10 rows) + +-- full outer join three tables +--Testcase 145: +EXPLAIN (VERBOSE, COSTS OFF) +SELECT t1.c1, t2.c2, t3.c3 FROM (SELECT (fields->>'C 1')::int c1, (fields->>'c2')::int c2, tags->>'c3' c3, fields->>'c4' c4, fields->>'c5' c5, fields->>'c6' c6, fields->>'c7' c7, fields->>'c8' c8 FROM ft2 t1) t1 FULL JOIN (SELECT (fields->>'C 1')::int c1, (fields->>'c2')::int c2, tags->>'c3' c3, fields->>'c4' c4, fields->>'c5' c5, fields->>'c6' c6, fields->>'c7' c7, fields->>'c8' c8 FROM ft2 t2) t2 ON ((t1.c1)::int = (t2.c1)::int) FULL JOIN (SELECT (fields->>'c1')::int c1, (fields->>'c2')::int c2, tags->>'c3' c3 FROM ft4 t3) t3 ON ((t2.c1)::int = (t3.c1)::int) OFFSET 10 LIMIT 10; + QUERY PLAN +--------------------------------------------------------------------------------------------------------------------------------------------------- + Limit + Output: (((t1.fields ->> 'C 1'::text))::integer), (((t2.fields ->> 'c2'::text))::integer), ((t3.tags ->> 'c3'::text)) + -> Hash Full Join + Output: (((t1.fields ->> 'C 1'::text))::integer), (((t2.fields ->> 'c2'::text))::integer), ((t3.tags ->> 'c3'::text)) + Hash Cond: ((((t2.fields ->> 'C 1'::text))::integer) = (((t3.fields ->> 'c1'::text))::integer)) + -> Hash Full Join + Output: (((t1.fields ->> 'C 1'::text))::integer), (((t2.fields ->> 'c2'::text))::integer), (((t2.fields ->> 'C 1'::text))::integer) + Hash Cond: ((((t1.fields ->> 'C 1'::text))::integer) = (((t2.fields ->> 'C 1'::text))::integer)) + -> Foreign Scan on public.ft2 t1 + Output: ((t1.fields ->> 'C 1'::text))::integer + InfluxDB query: SELECT "C 1" FROM "T1" + -> Hash + Output: (((t2.fields ->> 'c2'::text))::integer), (((t2.fields ->> 'C 1'::text))::integer) + -> Foreign Scan on public.ft2 t2 + Output: ((t2.fields ->> 'c2'::text))::integer, ((t2.fields ->> 'C 1'::text))::integer + InfluxDB query: SELECT "c2", "C 1" FROM "T1" + -> Hash + Output: ((t3.tags ->> 'c3'::text)), (((t3.fields ->> 'c1'::text))::integer) + -> Foreign Scan on public.ft4 t3 + Output: (t3.tags ->> 'c3'::text), ((t3.fields ->> 'c1'::text))::integer + InfluxDB query: SELECT "c3", "c1" FROM "T3" +(21 rows) + +--Testcase 146: +SELECT t1.c1, t2.c2, t3.c3 FROM (SELECT (fields->>'C 1')::int c1, (fields->>'c2')::int c2, tags->>'c3' c3, fields->>'c4' c4, fields->>'c5' c5, fields->>'c6' c6, fields->>'c7' c7, fields->>'c8' c8 FROM ft2 t1) t1 FULL JOIN (SELECT (fields->>'C 1')::int c1, (fields->>'c2')::int c2, tags->>'c3' c3, fields->>'c4' c4, fields->>'c5' c5, fields->>'c6' c6, fields->>'c7' c7, fields->>'c8' c8 FROM ft2 t2) t2 ON ((t1.c1)::int = (t2.c1)::int) FULL JOIN (SELECT (fields->>'c1')::int c1, (fields->>'c2')::int c2, tags->>'c3' c3 FROM ft4 t3) t3 ON ((t2.c1)::int = (t3.c1)::int) ORDER BY (t1.c1)::int OFFSET 10 LIMIT 10; + c1 | c2 | c3 +----+----+-------- + 11 | 1 | + 12 | 2 | AAA012 + 13 | 3 | + 14 | 4 | AAA014 + 15 | 5 | + 16 | 6 | AAA016 + 17 | 7 | + 18 | 8 | AAA018 + 19 | 9 | + 20 | 0 | AAA020 +(10 rows) + +-- full outer join + right outer join +--Testcase 147: +EXPLAIN (VERBOSE, COSTS OFF) +SELECT t1.c1, t2.c2, t3.c3 FROM (SELECT (fields->>'C 1')::int c1, (fields->>'c2')::int c2, tags->>'c3' c3, fields->>'c4' c4, fields->>'c5' c5, fields->>'c6' c6, fields->>'c7' c7, fields->>'c8' c8 FROM ft2 t1) t1 FULL JOIN (SELECT (fields->>'C 1')::int c1, (fields->>'c2')::int c2, tags->>'c3' c3, fields->>'c4' c4, fields->>'c5' c5, fields->>'c6' c6, fields->>'c7' c7, fields->>'c8' c8 FROM ft2 t2) t2 ON ((t1.c1)::int = (t2.c1)::int) RIGHT JOIN (SELECT (fields->>'c1')::int c1, (fields->>'c2')::int c2, tags->>'c3' c3 FROM ft4 t3) t3 ON ((t2.c1)::int = (t3.c1)::int) OFFSET 10 LIMIT 10; + QUERY PLAN +--------------------------------------------------------------------------------------------------------------------------------------------------- + Limit + Output: (((t1.fields ->> 'C 1'::text))::integer), (((t2.fields ->> 'c2'::text))::integer), ((t3.tags ->> 'c3'::text)) + -> Hash Right Join + Output: (((t1.fields ->> 'C 1'::text))::integer), (((t2.fields ->> 'c2'::text))::integer), (t3.tags ->> 'c3'::text) + Hash Cond: ((((t2.fields ->> 'C 1'::text))::integer) = ((t3.fields ->> 'c1'::text))::integer) + -> Nested Loop Left Join + Output: (((t2.fields ->> 'c2'::text))::integer), (((t2.fields ->> 'C 1'::text))::integer), (((t1.fields ->> 'C 1'::text))::integer) + Join Filter: ((((t1.fields ->> 'C 1'::text))::integer) = (((t2.fields ->> 'C 1'::text))::integer)) + -> Foreign Scan on public.ft2 t2 + Output: ((t2.fields ->> 'c2'::text))::integer, ((t2.fields ->> 'C 1'::text))::integer + InfluxDB query: SELECT "c2", "C 1" FROM "T1" + -> Materialize + Output: (((t1.fields ->> 'C 1'::text))::integer) + -> Foreign Scan on public.ft2 t1 + Output: ((t1.fields ->> 'C 1'::text))::integer + InfluxDB query: SELECT "C 1" FROM "T1" + -> Hash + Output: t3.tags, t3.fields + -> Foreign Scan on public.ft4 t3 + Output: t3.tags, t3.fields + InfluxDB query: SELECT * FROM "T3" +(21 rows) + +--Testcase 148: +SELECT t1.c1, t2.c2, t3.c3 FROM (SELECT (fields->>'C 1')::int c1, (fields->>'c2')::int c2, tags->>'c3' c3, fields->>'c4' c4, fields->>'c5' c5, fields->>'c6' c6, fields->>'c7' c7, fields->>'c8' c8 FROM ft2 t1) t1 FULL JOIN (SELECT (fields->>'C 1')::int c1, (fields->>'c2')::int c2, tags->>'c3' c3, fields->>'c4' c4, fields->>'c5' c5, fields->>'c6' c6, fields->>'c7' c7, fields->>'c8' c8 FROM ft2 t2) t2 ON ((t1.c1)::int = (t2.c1)::int) RIGHT JOIN (SELECT (fields->>'c1')::int c1, (fields->>'c2')::int c2, tags->>'c3' c3 FROM ft4 t3) t3 ON ((t2.c1)::int = (t3.c1)::int) OFFSET 10 LIMIT 10; + c1 | c2 | c3 +----+----+-------- + 20 | 0 | AAA020 + 22 | 2 | AAA022 + 24 | 4 | AAA024 + 26 | 6 | AAA026 + 28 | 8 | AAA028 + 30 | 0 | AAA030 + 32 | 2 | AAA032 + 34 | 4 | AAA034 + 36 | 6 | AAA036 + 38 | 8 | AAA038 +(10 rows) + +-- right outer join + full outer join +--Testcase 149: +EXPLAIN (VERBOSE, COSTS OFF) +SELECT t1.c1, t2.c2, t3.c3 FROM (SELECT (fields->>'C 1')::int c1, (fields->>'c2')::int c2, tags->>'c3' c3, fields->>'c4' c4, fields->>'c5' c5, fields->>'c6' c6, fields->>'c7' c7, fields->>'c8' c8 FROM ft2 t1) t1 RIGHT JOIN (SELECT (fields->>'C 1')::int c1, (fields->>'c2')::int c2, tags->>'c3' c3, fields->>'c4' c4, fields->>'c5' c5, fields->>'c6' c6, fields->>'c7' c7, fields->>'c8' c8 FROM ft2 t2) t2 ON ((t1.c1)::int = (t2.c1)::int) FULL JOIN (SELECT (fields->>'c1')::int c1, (fields->>'c2')::int c2, tags->>'c3' c3 FROM ft4 t3) t3 ON ((t2.c1)::int = (t3.c1)::int) OFFSET 10 LIMIT 10; + QUERY PLAN +--------------------------------------------------------------------------------------------------------------------------------------------------- + Limit + Output: (((t1.fields ->> 'C 1'::text))::integer), (((t2.fields ->> 'c2'::text))::integer), ((t3.tags ->> 'c3'::text)) + -> Hash Full Join + Output: (((t1.fields ->> 'C 1'::text))::integer), (((t2.fields ->> 'c2'::text))::integer), ((t3.tags ->> 'c3'::text)) + Hash Cond: ((((t2.fields ->> 'C 1'::text))::integer) = (((t3.fields ->> 'c1'::text))::integer)) + -> Nested Loop Left Join + Output: (((t2.fields ->> 'c2'::text))::integer), (((t2.fields ->> 'C 1'::text))::integer), (((t1.fields ->> 'C 1'::text))::integer) + Join Filter: (((t1.fields ->> 'C 1'::text))::integer = ((t2.fields ->> 'C 1'::text))::integer) + -> Foreign Scan on public.ft2 t2 + Output: t2.fields, ((t2.fields ->> 'c2'::text))::integer, ((t2.fields ->> 'C 1'::text))::integer + InfluxDB query: SELECT * FROM "T1" + -> Materialize + Output: t1.fields, (((t1.fields ->> 'C 1'::text))::integer) + -> Foreign Scan on public.ft2 t1 + Output: t1.fields, ((t1.fields ->> 'C 1'::text))::integer + InfluxDB query: SELECT * FROM "T1" + -> Hash + Output: ((t3.tags ->> 'c3'::text)), (((t3.fields ->> 'c1'::text))::integer) + -> Foreign Scan on public.ft4 t3 + Output: (t3.tags ->> 'c3'::text), ((t3.fields ->> 'c1'::text))::integer + InfluxDB query: SELECT "c3", "c1" FROM "T3" +(21 rows) + +--Testcase 150: +SELECT t1.c1, t2.c2, t3.c3 FROM (SELECT (fields->>'C 1')::int c1, (fields->>'c2')::int c2, tags->>'c3' c3, fields->>'c4' c4, fields->>'c5' c5, fields->>'c6' c6, fields->>'c7' c7, fields->>'c8' c8 FROM ft2 t1) t1 RIGHT JOIN (SELECT (fields->>'C 1')::int c1, (fields->>'c2')::int c2, tags->>'c3' c3, fields->>'c4' c4, fields->>'c5' c5, fields->>'c6' c6, fields->>'c7' c7, fields->>'c8' c8 FROM ft2 t2) t2 ON ((t1.c1)::int = (t2.c1)::int) FULL JOIN (SELECT (fields->>'c1')::int c1, (fields->>'c2')::int c2, tags->>'c3' c3 FROM ft4 t3) t3 ON ((t2.c1)::int = (t3.c1)::int) ORDER BY (t1.c1)::int OFFSET 10 LIMIT 10; + c1 | c2 | c3 +----+----+-------- + 11 | 1 | + 12 | 2 | AAA012 + 13 | 3 | + 14 | 4 | AAA014 + 15 | 5 | + 16 | 6 | AAA016 + 17 | 7 | + 18 | 8 | AAA018 + 19 | 9 | + 20 | 0 | AAA020 +(10 rows) + +-- full outer join + left outer join +--Testcase 151: +EXPLAIN (VERBOSE, COSTS OFF) +SELECT t1.c1, t2.c2, t3.c3 FROM (SELECT (fields->>'C 1')::int c1, (fields->>'c2')::int c2, tags->>'c3' c3, fields->>'c4' c4, fields->>'c5' c5, fields->>'c6' c6, fields->>'c7' c7, fields->>'c8' c8 FROM ft2 t1) t1 FULL JOIN (SELECT (fields->>'C 1')::int c1, (fields->>'c2')::int c2, tags->>'c3' c3, fields->>'c4' c4, fields->>'c5' c5, fields->>'c6' c6, fields->>'c7' c7, fields->>'c8' c8 FROM ft2 t2) t2 ON ((t1.c1)::int = (t2.c1)::int) LEFT JOIN (SELECT (fields->>'c1')::int c1, (fields->>'c2')::int c2, tags->>'c3' c3 FROM ft4 t3) t3 ON ((t2.c1)::int = (t3.c1)::int) OFFSET 10 LIMIT 10; + QUERY PLAN +--------------------------------------------------------------------------------------------------------------------------------------------------- + Limit + Output: (((t1.fields ->> 'C 1'::text))::integer), (((t2.fields ->> 'c2'::text))::integer), ((t3.tags ->> 'c3'::text)) + -> Nested Loop Left Join + Output: (((t1.fields ->> 'C 1'::text))::integer), (((t2.fields ->> 'c2'::text))::integer), ((t3.tags ->> 'c3'::text)) + Join Filter: ((((t2.fields ->> 'C 1'::text))::integer) = ((t3.fields ->> 'c1'::text))::integer) + -> Hash Full Join + Output: (((t1.fields ->> 'C 1'::text))::integer), (((t2.fields ->> 'c2'::text))::integer), (((t2.fields ->> 'C 1'::text))::integer) + Hash Cond: ((((t1.fields ->> 'C 1'::text))::integer) = (((t2.fields ->> 'C 1'::text))::integer)) + -> Foreign Scan on public.ft2 t1 + Output: ((t1.fields ->> 'C 1'::text))::integer + InfluxDB query: SELECT "C 1" FROM "T1" + -> Hash + Output: (((t2.fields ->> 'c2'::text))::integer), (((t2.fields ->> 'C 1'::text))::integer) + -> Foreign Scan on public.ft2 t2 + Output: ((t2.fields ->> 'c2'::text))::integer, ((t2.fields ->> 'C 1'::text))::integer + InfluxDB query: SELECT "c2", "C 1" FROM "T1" + -> Materialize + Output: t3.fields, ((t3.tags ->> 'c3'::text)) + -> Foreign Scan on public.ft4 t3 + Output: t3.fields, (t3.tags ->> 'c3'::text) + InfluxDB query: SELECT * FROM "T3" +(21 rows) + +--Testcase 152: +SELECT t1.c1, t2.c2, t3.c3 FROM (SELECT (fields->>'C 1')::int c1, (fields->>'c2')::int c2, tags->>'c3' c3, fields->>'c4' c4, fields->>'c5' c5, fields->>'c6' c6, fields->>'c7' c7, fields->>'c8' c8 FROM ft2 t1) t1 FULL JOIN (SELECT (fields->>'C 1')::int c1, (fields->>'c2')::int c2, tags->>'c3' c3, fields->>'c4' c4, fields->>'c5' c5, fields->>'c6' c6, fields->>'c7' c7, fields->>'c8' c8 FROM ft2 t2) t2 ON ((t1.c1)::int = (t2.c1)::int) LEFT JOIN (SELECT (fields->>'c1')::int c1, (fields->>'c2')::int c2, tags->>'c3' c3 FROM ft4 t3) t3 ON ((t2.c1)::int = (t3.c1)::int) ORDER BY (t1.c1)::int OFFSET 10 LIMIT 10; + c1 | c2 | c3 +----+----+-------- + 11 | 1 | + 12 | 2 | AAA012 + 13 | 3 | + 14 | 4 | AAA014 + 15 | 5 | + 16 | 6 | AAA016 + 17 | 7 | + 18 | 8 | AAA018 + 19 | 9 | + 20 | 0 | AAA020 +(10 rows) + +-- left outer join + full outer join +--Testcase 153: +EXPLAIN (VERBOSE, COSTS OFF) +SELECT t1.c1, t2.c2, t3.c3 FROM (SELECT (fields->>'C 1')::int c1, (fields->>'c2')::int c2, tags->>'c3' c3, fields->>'c4' c4, fields->>'c5' c5, fields->>'c6' c6, fields->>'c7' c7, fields->>'c8' c8 FROM ft2 t1) t1 LEFT JOIN (SELECT (fields->>'C 1')::int c1, (fields->>'c2')::int c2, tags->>'c3' c3, fields->>'c4' c4, fields->>'c5' c5, fields->>'c6' c6, fields->>'c7' c7, fields->>'c8' c8 FROM ft2 t2) t2 ON ((t1.c1)::int = (t2.c1)::int) FULL JOIN (SELECT (fields->>'c1')::int c1, (fields->>'c2')::int c2, tags->>'c3' c3 FROM ft4 t3) t3 ON ((t2.c1)::int = (t3.c1)::int) OFFSET 10 LIMIT 10; + QUERY PLAN +--------------------------------------------------------------------------------------------------------------------------------------------------- + Limit + Output: (((t1.fields ->> 'C 1'::text))::integer), (((t2.fields ->> 'c2'::text))::integer), ((t3.tags ->> 'c3'::text)) + -> Hash Full Join + Output: (((t1.fields ->> 'C 1'::text))::integer), (((t2.fields ->> 'c2'::text))::integer), ((t3.tags ->> 'c3'::text)) + Hash Cond: ((((t2.fields ->> 'C 1'::text))::integer) = (((t3.fields ->> 'c1'::text))::integer)) + -> Nested Loop Left Join + Output: (((t1.fields ->> 'C 1'::text))::integer), (((t2.fields ->> 'c2'::text))::integer), (((t2.fields ->> 'C 1'::text))::integer) + Join Filter: (((t1.fields ->> 'C 1'::text))::integer = ((t2.fields ->> 'C 1'::text))::integer) + -> Foreign Scan on public.ft2 t1 + Output: t1.fields, ((t1.fields ->> 'C 1'::text))::integer + InfluxDB query: SELECT * FROM "T1" + -> Materialize + Output: t2.fields, (((t2.fields ->> 'c2'::text))::integer), (((t2.fields ->> 'C 1'::text))::integer) + -> Foreign Scan on public.ft2 t2 + Output: t2.fields, ((t2.fields ->> 'c2'::text))::integer, ((t2.fields ->> 'C 1'::text))::integer + InfluxDB query: SELECT * FROM "T1" + -> Hash + Output: ((t3.tags ->> 'c3'::text)), (((t3.fields ->> 'c1'::text))::integer) + -> Foreign Scan on public.ft4 t3 + Output: (t3.tags ->> 'c3'::text), ((t3.fields ->> 'c1'::text))::integer + InfluxDB query: SELECT "c3", "c1" FROM "T3" +(21 rows) + +--Testcase 154: +SELECT t1.c1, t2.c2, t3.c3 FROM (SELECT (fields->>'C 1')::int c1, (fields->>'c2')::int c2, tags->>'c3' c3, fields->>'c4' c4, fields->>'c5' c5, fields->>'c6' c6, fields->>'c7' c7, fields->>'c8' c8 FROM ft2 t1) t1 LEFT JOIN (SELECT (fields->>'C 1')::int c1, (fields->>'c2')::int c2, tags->>'c3' c3, fields->>'c4' c4, fields->>'c5' c5, fields->>'c6' c6, fields->>'c7' c7, fields->>'c8' c8 FROM ft2 t2) t2 ON ((t1.c1)::int = (t2.c1)::int) FULL JOIN (SELECT (fields->>'c1')::int c1, (fields->>'c2')::int c2, tags->>'c3' c3 FROM ft4 t3) t3 ON ((t2.c1)::int = (t3.c1)::int) ORDER BY (t1.c1)::int OFFSET 10 LIMIT 10; + c1 | c2 | c3 +----+----+-------- + 11 | 1 | + 12 | 2 | AAA012 + 13 | 3 | + 14 | 4 | AAA014 + 15 | 5 | + 16 | 6 | AAA016 + 17 | 7 | + 18 | 8 | AAA018 + 19 | 9 | + 20 | 0 | AAA020 +(10 rows) + +--Testcase 155: +SET enable_memoize TO off; +-- right outer join + left outer join +--Testcase 156: +EXPLAIN (VERBOSE, COSTS OFF) +SELECT t1.c1, t2.c2, t3.c3 FROM (SELECT (fields->>'C 1')::int c1, (fields->>'c2')::int c2, tags->>'c3' c3, fields->>'c4' c4, fields->>'c5' c5, fields->>'c6' c6, fields->>'c7' c7, fields->>'c8' c8 FROM ft2 t1) t1 RIGHT JOIN (SELECT (fields->>'C 1')::int c1, (fields->>'c2')::int c2, tags->>'c3' c3, fields->>'c4' c4, fields->>'c5' c5, fields->>'c6' c6, fields->>'c7' c7, fields->>'c8' c8 FROM ft2 t2) t2 ON ((t1.c1)::int = (t2.c1)::int) LEFT JOIN (SELECT (fields->>'c1')::int c1, (fields->>'c2')::int c2, tags->>'c3' c3 FROM ft4 t3) t3 ON ((t2.c1)::int = (t3.c1)::int) OFFSET 10 LIMIT 10; + QUERY PLAN +----------------------------------------------------------------------------------------------------------------------------- + Limit + Output: (((t1.fields ->> 'C 1'::text))::integer), (((t2.fields ->> 'c2'::text))::integer), ((t3.tags ->> 'c3'::text)) + -> Nested Loop Left Join + Output: (((t1.fields ->> 'C 1'::text))::integer), ((t2.fields ->> 'c2'::text))::integer, ((t3.tags ->> 'c3'::text)) + Join Filter: (((t1.fields ->> 'C 1'::text))::integer = ((t2.fields ->> 'C 1'::text))::integer) + -> Nested Loop Left Join + Output: t2.fields, ((t3.tags ->> 'c3'::text)) + Join Filter: (((t2.fields ->> 'C 1'::text))::integer = ((t3.fields ->> 'c1'::text))::integer) + -> Foreign Scan on public.ft2 t2 + Output: t2."time", t2.tags, t2.fields + InfluxDB query: SELECT * FROM "T1" + -> Materialize + Output: t3.fields, ((t3.tags ->> 'c3'::text)) + -> Foreign Scan on public.ft4 t3 + Output: t3.fields, (t3.tags ->> 'c3'::text) + InfluxDB query: SELECT * FROM "T3" + -> Materialize + Output: t1.fields, (((t1.fields ->> 'C 1'::text))::integer) + -> Foreign Scan on public.ft2 t1 + Output: t1.fields, ((t1.fields ->> 'C 1'::text))::integer + InfluxDB query: SELECT * FROM "T1" +(21 rows) + +--Testcase 157: +SELECT t1.c1, t2.c2, t3.c3 FROM (SELECT (fields->>'C 1')::int c1, (fields->>'c2')::int c2, tags->>'c3' c3, fields->>'c4' c4, fields->>'c5' c5, fields->>'c6' c6, fields->>'c7' c7, fields->>'c8' c8 FROM ft2 t1) t1 RIGHT JOIN (SELECT (fields->>'C 1')::int c1, (fields->>'c2')::int c2, tags->>'c3' c3, fields->>'c4' c4, fields->>'c5' c5, fields->>'c6' c6, fields->>'c7' c7, fields->>'c8' c8 FROM ft2 t2) t2 ON ((t1.c1)::int = (t2.c1)::int) LEFT JOIN (SELECT (fields->>'c1')::int c1, (fields->>'c2')::int c2, tags->>'c3' c3 FROM ft4 t3) t3 ON ((t2.c1)::int = (t3.c1)::int) ORDER BY (t1.c1)::int OFFSET 10 LIMIT 10; + c1 | c2 | c3 +----+----+-------- + 11 | 1 | + 12 | 2 | AAA012 + 13 | 3 | + 14 | 4 | AAA014 + 15 | 5 | + 16 | 6 | AAA016 + 17 | 7 | + 18 | 8 | AAA018 + 19 | 9 | + 20 | 0 | AAA020 +(10 rows) + +--Testcase 158: +RESET enable_memoize; +-- left outer join + right outer join +--Testcase 159: +EXPLAIN (VERBOSE, COSTS OFF) +SELECT t1.c1, t2.c2, t3.c3 FROM (SELECT (fields->>'C 1')::int c1, (fields->>'c2')::int c2, tags->>'c3' c3, fields->>'c4' c4, fields->>'c5' c5, fields->>'c6' c6, fields->>'c7' c7, fields->>'c8' c8 FROM ft2 t1) t1 LEFT JOIN (SELECT (fields->>'C 1')::int c1, (fields->>'c2')::int c2, tags->>'c3' c3, fields->>'c4' c4, fields->>'c5' c5, fields->>'c6' c6, fields->>'c7' c7, fields->>'c8' c8 FROM ft2 t2) t2 ON ((t1.c1)::int = (t2.c1)::int) RIGHT JOIN (SELECT (fields->>'c1')::int c1, (fields->>'c2')::int c2, tags->>'c3' c3 FROM ft4 t3) t3 ON ((t2.c1)::int = (t3.c1)::int) OFFSET 10 LIMIT 10; + QUERY PLAN +--------------------------------------------------------------------------------------------------------------------------------------------------- + Limit + Output: (((t1.fields ->> 'C 1'::text))::integer), (((t2.fields ->> 'c2'::text))::integer), ((t3.tags ->> 'c3'::text)) + -> Hash Right Join + Output: (((t1.fields ->> 'C 1'::text))::integer), (((t2.fields ->> 'c2'::text))::integer), (t3.tags ->> 'c3'::text) + Hash Cond: ((((t2.fields ->> 'C 1'::text))::integer) = ((t3.fields ->> 'c1'::text))::integer) + -> Nested Loop + Output: (((t1.fields ->> 'C 1'::text))::integer), (((t2.fields ->> 'c2'::text))::integer), (((t2.fields ->> 'C 1'::text))::integer) + Join Filter: (((t1.fields ->> 'C 1'::text))::integer = ((t2.fields ->> 'C 1'::text))::integer) + -> Foreign Scan on public.ft2 t1 + Output: t1.fields, ((t1.fields ->> 'C 1'::text))::integer + InfluxDB query: SELECT * FROM "T1" + -> Materialize + Output: t2.fields, (((t2.fields ->> 'c2'::text))::integer), (((t2.fields ->> 'C 1'::text))::integer) + -> Foreign Scan on public.ft2 t2 + Output: t2.fields, ((t2.fields ->> 'c2'::text))::integer, ((t2.fields ->> 'C 1'::text))::integer + InfluxDB query: SELECT * FROM "T1" + -> Hash + Output: t3.tags, t3.fields + -> Foreign Scan on public.ft4 t3 + Output: t3.tags, t3.fields + InfluxDB query: SELECT * FROM "T3" +(21 rows) + +--Testcase 160: +SELECT t1.c1, t2.c2, t3.c3 FROM (SELECT (fields->>'C 1')::int c1, (fields->>'c2')::int c2, tags->>'c3' c3, fields->>'c4' c4, fields->>'c5' c5, fields->>'c6' c6, fields->>'c7' c7, fields->>'c8' c8 FROM ft2 t1) t1 LEFT JOIN (SELECT (fields->>'C 1')::int c1, (fields->>'c2')::int c2, tags->>'c3' c3, fields->>'c4' c4, fields->>'c5' c5, fields->>'c6' c6, fields->>'c7' c7, fields->>'c8' c8 FROM ft2 t2) t2 ON ((t1.c1)::int = (t2.c1)::int) RIGHT JOIN (SELECT (fields->>'c1')::int c1, (fields->>'c2')::int c2, tags->>'c3' c3 FROM ft4 t3) t3 ON ((t2.c1)::int = (t3.c1)::int) ORDER BY (t1.c1)::int OFFSET 10 LIMIT 10; + c1 | c2 | c3 +----+----+-------- + 22 | 2 | AAA022 + 24 | 4 | AAA024 + 26 | 6 | AAA026 + 28 | 8 | AAA028 + 30 | 0 | AAA030 + 32 | 2 | AAA032 + 34 | 4 | AAA034 + 36 | 6 | AAA036 + 38 | 8 | AAA038 + 40 | 0 | AAA040 +(10 rows) + +-- full outer join + WHERE clause, only matched rows +--Testcase 161: +EXPLAIN (VERBOSE, COSTS OFF) +SELECT t1.c1, t2.c1 FROM (SELECT (fields->>'c1')::int c1, (fields->>'c2')::int c2, tags->>'c3' c3 FROM ft4 t1) t1 FULL JOIN (SELECT (fields->>'c1')::int c1, (fields->>'c2')::int c2, tags->>'c3' c3 FROM ft5 t2) t2 ON ((t1.c1)::int = (t2.c1)::int) WHERE ((t1.c1)::int = (t2.c1)::int OR (t1.c1)::int IS NULL) ORDER BY (t1.c1)::int, (t2.c1)::int OFFSET 10 LIMIT 10; + QUERY PLAN +------------------------------------------------------------------------------------------------------------------------------------------------------------------ + Limit + Output: (((t1.fields ->> 'c1'::text))::integer), (((t2.fields ->> 'c1'::text))::integer) + -> Sort + Output: (((t1.fields ->> 'c1'::text))::integer), (((t2.fields ->> 'c1'::text))::integer) + Sort Key: (((t1.fields ->> 'c1'::text))::integer), (((t2.fields ->> 'c1'::text))::integer) + -> Merge Full Join + Output: (((t1.fields ->> 'c1'::text))::integer), (((t2.fields ->> 'c1'::text))::integer) + Merge Cond: ((((t1.fields ->> 'c1'::text))::integer) = (((t2.fields ->> 'c1'::text))::integer)) + Filter: (((((t1.fields ->> 'c1'::text))::integer) = (((t2.fields ->> 'c1'::text))::integer)) OR ((((t1.fields ->> 'c1'::text))::integer) IS NULL)) + -> Sort + Output: (((t1.fields ->> 'c1'::text))::integer) + Sort Key: (((t1.fields ->> 'c1'::text))::integer) + -> Foreign Scan on public.ft4 t1 + Output: ((t1.fields ->> 'c1'::text))::integer + InfluxDB query: SELECT "c1" FROM "T3" + -> Sort + Output: (((t2.fields ->> 'c1'::text))::integer) + Sort Key: (((t2.fields ->> 'c1'::text))::integer) + -> Foreign Scan on public.ft5 t2 + Output: ((t2.fields ->> 'c1'::text))::integer + InfluxDB query: SELECT "c1" FROM "T4" +(21 rows) + +--Testcase 162: +SELECT t1.c1, t2.c1 FROM (SELECT (fields->>'c1')::int c1, (fields->>'c2')::int c2, tags->>'c3' c3 FROM ft4 t1) t1 FULL JOIN (SELECT (fields->>'c1')::int c1, (fields->>'c2')::int c2, tags->>'c3' c3 FROM ft5 t2) t2 ON ((t1.c1)::int = (t2.c1)::int) WHERE ((t1.c1)::int = (t2.c1)::int OR (t1.c1)::int IS NULL) ORDER BY (t1.c1)::int, (t2.c1)::int OFFSET 10 LIMIT 10; + c1 | c1 +----+---- + 66 | 66 + 72 | 72 + 78 | 78 + 84 | 84 + 90 | 90 + 96 | 96 + | 3 + | 9 + | 15 + | 21 +(10 rows) + +-- full outer join + WHERE clause with shippable extensions set +--Testcase 163: +EXPLAIN (VERBOSE, COSTS OFF) +SELECT t1.c1, t2.c2, t1.c3 FROM (SELECT (fields->>'C 1')::int c1, (fields->>'c2')::int c2, tags->>'c3' c3, fields->>'c4' c4, fields->>'c5' c5, fields->>'c6' c6, fields->>'c7' c7, fields->>'c8' c8 FROM ft1 t1) t1 FULL JOIN (SELECT (fields->>'C 1')::int c1, (fields->>'c2')::int c2, tags->>'c3' c3, fields->>'c4' c4, fields->>'c5' c5, fields->>'c6' c6, fields->>'c7' c7, fields->>'c8' c8 FROM ft2 t2) t2 ON ((t1.c1)::int = (t2.c1)::int) WHERE influxdb_fdw_abs((t1.c1)::int) > 0 OFFSET 10 LIMIT 10; + QUERY PLAN +------------------------------------------------------------------------------------------------------------------------------- + Limit + Output: (((t1.fields ->> 'C 1'::text))::integer), (((t2.fields ->> 'c2'::text))::integer), ((t1.tags ->> 'c3'::text)) + -> Hash Full Join + Output: (((t1.fields ->> 'C 1'::text))::integer), (((t2.fields ->> 'c2'::text))::integer), ((t1.tags ->> 'c3'::text)) + Hash Cond: ((((t2.fields ->> 'C 1'::text))::integer) = (((t1.fields ->> 'C 1'::text))::integer)) + Filter: (influxdb_fdw_abs((((t1.fields ->> 'C 1'::text))::integer)) > 0) + -> Foreign Scan on public.ft2 t2 + Output: ((t2.fields ->> 'c2'::text))::integer, ((t2.fields ->> 'C 1'::text))::integer + InfluxDB query: SELECT "c2", "C 1" FROM "T1" + -> Hash + Output: (((t1.fields ->> 'C 1'::text))::integer), ((t1.tags ->> 'c3'::text)) + -> Foreign Scan on public.ft1 t1 + Output: ((t1.fields ->> 'C 1'::text))::integer, (t1.tags ->> 'c3'::text) + InfluxDB query: SELECT "C 1", "c3" FROM "T1" +(14 rows) + +-- skip, influxdb does not have option 'extensions' +-- ALTER SERVER influxdb_svr OPTIONS (DROP extensions); +-- full outer join + WHERE clause with shippable extensions not set +-- EXPLAIN (VERBOSE, COSTS OFF) +-- SELECT t1.c1, t2.c2, t1.c3 FROM ft1 t1 FULL JOIN ft2 t2 ON (t1.c1 = t2.c1) WHERE influxdb_fdw_abs(t1.c1) > 0 OFFSET 10 LIMIT 10; +-- ALTER SERVER loopback OPTIONS (ADD extensions 'influxdb_fdw'); +-- join two tables with FOR UPDATE clause +-- tests whole-row reference for row marks +--Testcase 164: +EXPLAIN (VERBOSE, COSTS OFF) +SELECT t1.c1, t2.c1 FROM (SELECT (fields->>'C 1')::int c1, (fields->>'c2')::int c2, tags->>'c3' c3, fields->>'c4' c4, fields->>'c5' c5, fields->>'c6' c6, fields->>'c7' c7, fields->>'c8' c8 FROM ft1 t1) t1 JOIN (SELECT (fields->>'C 1')::int c1, (fields->>'c2')::int c2, tags->>'c3' c3, fields->>'c4' c4, fields->>'c5' c5, fields->>'c6' c6, fields->>'c7' c7, fields->>'c8' c8 FROM ft2 t2) t2 ON ((t1.c1)::int = (t2.c1)::int) ORDER BY t1.c3, (t1.c1)::int OFFSET 100 LIMIT 10 FOR UPDATE OF t1; + QUERY PLAN +------------------------------------------------------------------------------------------------------------------------------------------------------ + Limit + Output: (((t1.fields ->> 'C 1'::text))::integer), (((t2.fields ->> 'C 1'::text))::integer), ((t1.tags ->> 'c3'::text)), t1.*, t2.* + -> LockRows + Output: (((t1.fields ->> 'C 1'::text))::integer), (((t2.fields ->> 'C 1'::text))::integer), ((t1.tags ->> 'c3'::text)), t1.*, t2.* + -> Sort + Output: (((t1.fields ->> 'C 1'::text))::integer), (((t2.fields ->> 'C 1'::text))::integer), ((t1.tags ->> 'c3'::text)), t1.*, t2.* + Sort Key: ((t1.tags ->> 'c3'::text)), (((t1.fields ->> 'C 1'::text))::integer) + -> Merge Join + Output: (((t1.fields ->> 'C 1'::text))::integer), (((t2.fields ->> 'C 1'::text))::integer), (t1.tags ->> 'c3'::text), t1.*, t2.* + Merge Cond: ((((t1.fields ->> 'C 1'::text))::integer) = (((t2.fields ->> 'C 1'::text))::integer)) + -> Sort + Output: t1.fields, t1.tags, t1.*, (((t1.fields ->> 'C 1'::text))::integer) + Sort Key: (((t1.fields ->> 'C 1'::text))::integer) + -> Foreign Scan on public.ft1 t1 + Output: t1.fields, t1.tags, t1.*, ((t1.fields ->> 'C 1'::text))::integer + InfluxDB query: SELECT * FROM "T1" + -> Sort + Output: t2.fields, t2.*, (((t2.fields ->> 'C 1'::text))::integer) + Sort Key: (((t2.fields ->> 'C 1'::text))::integer) + -> Foreign Scan on public.ft2 t2 + Output: t2.fields, t2.*, ((t2.fields ->> 'C 1'::text))::integer + InfluxDB query: SELECT * FROM "T1" +(22 rows) + +--Testcase 165: +SELECT t1.c1, t2.c1 FROM (SELECT (fields->>'C 1')::int c1, (fields->>'c2')::int c2, tags->>'c3' c3, fields->>'c4' c4, fields->>'c5' c5, fields->>'c6' c6, fields->>'c7' c7, fields->>'c8' c8 FROM ft1 t1) t1 JOIN (SELECT (fields->>'C 1')::int c1, (fields->>'c2')::int c2, tags->>'c3' c3, fields->>'c4' c4, fields->>'c5' c5, fields->>'c6' c6, fields->>'c7' c7, fields->>'c8' c8 FROM ft2 t2) t2 ON ((t1.c1)::int = (t2.c1)::int) ORDER BY t1.c3, (t1.c1)::int OFFSET 100 LIMIT 10 FOR UPDATE OF t1; + c1 | c1 +-----+----- + 101 | 101 + 102 | 102 + 103 | 103 + 104 | 104 + 105 | 105 + 106 | 106 + 107 | 107 + 108 | 108 + 109 | 109 + 110 | 110 +(10 rows) + +--Testcase 166: +EXPLAIN (VERBOSE, COSTS OFF) +SELECT t1.c1, t2.c1 FROM (SELECT (fields->>'C 1')::int c1, (fields->>'c2')::int c2, tags->>'c3' c3, fields->>'c4' c4, fields->>'c5' c5, fields->>'c6' c6, fields->>'c7' c7, fields->>'c8' c8 FROM ft1 t1) t1 JOIN (SELECT (fields->>'C 1')::int c1, (fields->>'c2')::int c2, tags->>'c3' c3, fields->>'c4' c4, fields->>'c5' c5, fields->>'c6' c6, fields->>'c7' c7, fields->>'c8' c8 FROM ft2 t2) t2 ON ((t1.c1)::int = (t2.c1)::int) ORDER BY t1.c3, (t1.c1)::int OFFSET 100 LIMIT 10 FOR UPDATE; + QUERY PLAN +------------------------------------------------------------------------------------------------------------------------------------------------------ + Limit + Output: (((t1.fields ->> 'C 1'::text))::integer), (((t2.fields ->> 'C 1'::text))::integer), ((t1.tags ->> 'c3'::text)), t1.*, t2.* + -> LockRows + Output: (((t1.fields ->> 'C 1'::text))::integer), (((t2.fields ->> 'C 1'::text))::integer), ((t1.tags ->> 'c3'::text)), t1.*, t2.* + -> Sort + Output: (((t1.fields ->> 'C 1'::text))::integer), (((t2.fields ->> 'C 1'::text))::integer), ((t1.tags ->> 'c3'::text)), t1.*, t2.* + Sort Key: ((t1.tags ->> 'c3'::text)), (((t1.fields ->> 'C 1'::text))::integer) + -> Merge Join + Output: (((t1.fields ->> 'C 1'::text))::integer), (((t2.fields ->> 'C 1'::text))::integer), (t1.tags ->> 'c3'::text), t1.*, t2.* + Merge Cond: ((((t1.fields ->> 'C 1'::text))::integer) = (((t2.fields ->> 'C 1'::text))::integer)) + -> Sort + Output: t1.fields, t1.tags, t1.*, (((t1.fields ->> 'C 1'::text))::integer) + Sort Key: (((t1.fields ->> 'C 1'::text))::integer) + -> Foreign Scan on public.ft1 t1 + Output: t1.fields, t1.tags, t1.*, ((t1.fields ->> 'C 1'::text))::integer + InfluxDB query: SELECT * FROM "T1" + -> Sort + Output: t2.fields, t2.*, (((t2.fields ->> 'C 1'::text))::integer) + Sort Key: (((t2.fields ->> 'C 1'::text))::integer) + -> Foreign Scan on public.ft2 t2 + Output: t2.fields, t2.*, ((t2.fields ->> 'C 1'::text))::integer + InfluxDB query: SELECT * FROM "T1" +(22 rows) + +--Testcase 167: +SELECT t1.c1, t2.c1 FROM (SELECT (fields->>'C 1')::int c1, (fields->>'c2')::int c2, tags->>'c3' c3, fields->>'c4' c4, fields->>'c5' c5, fields->>'c6' c6, fields->>'c7' c7, fields->>'c8' c8 FROM ft1 t1) t1 JOIN (SELECT (fields->>'C 1')::int c1, (fields->>'c2')::int c2, tags->>'c3' c3, fields->>'c4' c4, fields->>'c5' c5, fields->>'c6' c6, fields->>'c7' c7, fields->>'c8' c8 FROM ft2 t2) t2 ON ((t1.c1)::int = (t2.c1)::int) ORDER BY t1.c3, (t1.c1)::int OFFSET 100 LIMIT 10 FOR UPDATE; + c1 | c1 +-----+----- + 101 | 101 + 102 | 102 + 103 | 103 + 104 | 104 + 105 | 105 + 106 | 106 + 107 | 107 + 108 | 108 + 109 | 109 + 110 | 110 +(10 rows) + +-- join two tables with FOR SHARE clause +--Testcase 168: +EXPLAIN (VERBOSE, COSTS OFF) +SELECT t1.c1, t2.c1 FROM (SELECT (fields->>'C 1')::int c1, (fields->>'c2')::int c2, tags->>'c3' c3, fields->>'c4' c4, fields->>'c5' c5, fields->>'c6' c6, fields->>'c7' c7, fields->>'c8' c8 FROM ft1 t1) t1 JOIN (SELECT (fields->>'C 1')::int c1, (fields->>'c2')::int c2, tags->>'c3' c3, fields->>'c4' c4, fields->>'c5' c5, fields->>'c6' c6, fields->>'c7' c7, fields->>'c8' c8 FROM ft2 t2) t2 ON ((t1.c1)::int = (t2.c1)::int) ORDER BY t1.c3, (t1.c1)::int OFFSET 100 LIMIT 10 FOR SHARE OF t1; + QUERY PLAN +------------------------------------------------------------------------------------------------------------------------------------------------------ + Limit + Output: (((t1.fields ->> 'C 1'::text))::integer), (((t2.fields ->> 'C 1'::text))::integer), ((t1.tags ->> 'c3'::text)), t1.*, t2.* + -> LockRows + Output: (((t1.fields ->> 'C 1'::text))::integer), (((t2.fields ->> 'C 1'::text))::integer), ((t1.tags ->> 'c3'::text)), t1.*, t2.* + -> Sort + Output: (((t1.fields ->> 'C 1'::text))::integer), (((t2.fields ->> 'C 1'::text))::integer), ((t1.tags ->> 'c3'::text)), t1.*, t2.* + Sort Key: ((t1.tags ->> 'c3'::text)), (((t1.fields ->> 'C 1'::text))::integer) + -> Merge Join + Output: (((t1.fields ->> 'C 1'::text))::integer), (((t2.fields ->> 'C 1'::text))::integer), (t1.tags ->> 'c3'::text), t1.*, t2.* + Merge Cond: ((((t1.fields ->> 'C 1'::text))::integer) = (((t2.fields ->> 'C 1'::text))::integer)) + -> Sort + Output: t1.fields, t1.tags, t1.*, (((t1.fields ->> 'C 1'::text))::integer) + Sort Key: (((t1.fields ->> 'C 1'::text))::integer) + -> Foreign Scan on public.ft1 t1 + Output: t1.fields, t1.tags, t1.*, ((t1.fields ->> 'C 1'::text))::integer + InfluxDB query: SELECT * FROM "T1" + -> Sort + Output: t2.fields, t2.*, (((t2.fields ->> 'C 1'::text))::integer) + Sort Key: (((t2.fields ->> 'C 1'::text))::integer) + -> Foreign Scan on public.ft2 t2 + Output: t2.fields, t2.*, ((t2.fields ->> 'C 1'::text))::integer + InfluxDB query: SELECT * FROM "T1" +(22 rows) + +--Testcase 169: +SELECT t1.c1, t2.c1 FROM (SELECT (fields->>'C 1')::int c1, (fields->>'c2')::int c2, tags->>'c3' c3, fields->>'c4' c4, fields->>'c5' c5, fields->>'c6' c6, fields->>'c7' c7, fields->>'c8' c8 FROM ft1 t1) t1 JOIN (SELECT (fields->>'C 1')::int c1, (fields->>'c2')::int c2, tags->>'c3' c3, fields->>'c4' c4, fields->>'c5' c5, fields->>'c6' c6, fields->>'c7' c7, fields->>'c8' c8 FROM ft2 t2) t2 ON ((t1.c1)::int = (t2.c1)::int) ORDER BY t1.c3, (t1.c1)::int OFFSET 100 LIMIT 10 FOR SHARE OF t1; + c1 | c1 +-----+----- + 101 | 101 + 102 | 102 + 103 | 103 + 104 | 104 + 105 | 105 + 106 | 106 + 107 | 107 + 108 | 108 + 109 | 109 + 110 | 110 +(10 rows) + +--Testcase 170: +EXPLAIN (VERBOSE, COSTS OFF) +SELECT t1.c1, t2.c1 FROM (SELECT (fields->>'C 1')::int c1, (fields->>'c2')::int c2, tags->>'c3' c3, fields->>'c4' c4, fields->>'c5' c5, fields->>'c6' c6, fields->>'c7' c7, fields->>'c8' c8 FROM ft1 t1) t1 JOIN (SELECT (fields->>'C 1')::int c1, (fields->>'c2')::int c2, tags->>'c3' c3, fields->>'c4' c4, fields->>'c5' c5, fields->>'c6' c6, fields->>'c7' c7, fields->>'c8' c8 FROM ft2 t2) t2 ON ((t1.c1)::int = (t2.c1)::int) ORDER BY t1.c3, (t1.c1)::int OFFSET 100 LIMIT 10 FOR SHARE; + QUERY PLAN +------------------------------------------------------------------------------------------------------------------------------------------------------ + Limit + Output: (((t1.fields ->> 'C 1'::text))::integer), (((t2.fields ->> 'C 1'::text))::integer), ((t1.tags ->> 'c3'::text)), t1.*, t2.* + -> LockRows + Output: (((t1.fields ->> 'C 1'::text))::integer), (((t2.fields ->> 'C 1'::text))::integer), ((t1.tags ->> 'c3'::text)), t1.*, t2.* + -> Sort + Output: (((t1.fields ->> 'C 1'::text))::integer), (((t2.fields ->> 'C 1'::text))::integer), ((t1.tags ->> 'c3'::text)), t1.*, t2.* + Sort Key: ((t1.tags ->> 'c3'::text)), (((t1.fields ->> 'C 1'::text))::integer) + -> Merge Join + Output: (((t1.fields ->> 'C 1'::text))::integer), (((t2.fields ->> 'C 1'::text))::integer), (t1.tags ->> 'c3'::text), t1.*, t2.* + Merge Cond: ((((t1.fields ->> 'C 1'::text))::integer) = (((t2.fields ->> 'C 1'::text))::integer)) + -> Sort + Output: t1.fields, t1.tags, t1.*, (((t1.fields ->> 'C 1'::text))::integer) + Sort Key: (((t1.fields ->> 'C 1'::text))::integer) + -> Foreign Scan on public.ft1 t1 + Output: t1.fields, t1.tags, t1.*, ((t1.fields ->> 'C 1'::text))::integer + InfluxDB query: SELECT * FROM "T1" + -> Sort + Output: t2.fields, t2.*, (((t2.fields ->> 'C 1'::text))::integer) + Sort Key: (((t2.fields ->> 'C 1'::text))::integer) + -> Foreign Scan on public.ft2 t2 + Output: t2.fields, t2.*, ((t2.fields ->> 'C 1'::text))::integer + InfluxDB query: SELECT * FROM "T1" +(22 rows) + +--Testcase 171: +SELECT t1.c1, t2.c1 FROM (SELECT (fields->>'C 1')::int c1, (fields->>'c2')::int c2, tags->>'c3' c3, fields->>'c4' c4, fields->>'c5' c5, fields->>'c6' c6, fields->>'c7' c7, fields->>'c8' c8 FROM ft1 t1) t1 JOIN (SELECT (fields->>'C 1')::int c1, (fields->>'c2')::int c2, tags->>'c3' c3, fields->>'c4' c4, fields->>'c5' c5, fields->>'c6' c6, fields->>'c7' c7, fields->>'c8' c8 FROM ft2 t2) t2 ON ((t1.c1)::int = (t2.c1)::int) ORDER BY t1.c3, (t1.c1)::int OFFSET 100 LIMIT 10 FOR SHARE; + c1 | c1 +-----+----- + 101 | 101 + 102 | 102 + 103 | 103 + 104 | 104 + 105 | 105 + 106 | 106 + 107 | 107 + 108 | 108 + 109 | 109 + 110 | 110 +(10 rows) + +-- join in CTE +--Testcase 172: +EXPLAIN (VERBOSE, COSTS OFF) +WITH t (c1_1, c1_3, c2_1) AS MATERIALIZED (SELECT t1.c1, t1.c3, t2.c1 FROM (SELECT (fields->>'C 1')::int c1, (fields->>'c2')::int c2, tags->>'c3' c3, fields->>'c4' c4, fields->>'c5' c5, fields->>'c6' c6, fields->>'c7' c7, fields->>'c8' c8 FROM ft1 t1) t1 JOIN (SELECT (fields->>'C 1')::int c1, (fields->>'c2')::int c2, tags->>'c3' c3, fields->>'c4' c4, fields->>'c5' c5, fields->>'c6' c6, fields->>'c7' c7, fields->>'c8' c8 FROM ft2 t2) t2 ON ((t1.c1)::int = (t2.c1)::int)) SELECT c1_1, c2_1 FROM t ORDER BY c1_3, c1_1 OFFSET 100 LIMIT 10; + QUERY PLAN +-------------------------------------------------------------------------------------------------------------------------------- + Limit + Output: t.c1_1, t.c2_1, t.c1_3 + CTE t + -> Merge Join + Output: (((t1.fields ->> 'C 1'::text))::integer), (t1.tags ->> 'c3'::text), (((t2.fields ->> 'C 1'::text))::integer) + Merge Cond: ((((t1.fields ->> 'C 1'::text))::integer) = (((t2.fields ->> 'C 1'::text))::integer)) + -> Sort + Output: t1.fields, t1.tags, (((t1.fields ->> 'C 1'::text))::integer) + Sort Key: (((t1.fields ->> 'C 1'::text))::integer) + -> Foreign Scan on public.ft1 t1 + Output: t1.fields, t1.tags, ((t1.fields ->> 'C 1'::text))::integer + InfluxDB query: SELECT * FROM "T1" + -> Sort + Output: t2.fields, (((t2.fields ->> 'C 1'::text))::integer) + Sort Key: (((t2.fields ->> 'C 1'::text))::integer) + -> Foreign Scan on public.ft2 t2 + Output: t2.fields, ((t2.fields ->> 'C 1'::text))::integer + InfluxDB query: SELECT * FROM "T1" + -> Sort + Output: t.c1_1, t.c2_1, t.c1_3 + Sort Key: t.c1_3, t.c1_1 + -> CTE Scan on t + Output: t.c1_1, t.c2_1, t.c1_3 +(23 rows) + +--Testcase 173: +WITH t (c1_1, c1_3, c2_1) AS MATERIALIZED (SELECT t1.c1, t1.c3, t2.c1 FROM (SELECT (fields->>'C 1')::int c1, (fields->>'c2')::int c2, tags->>'c3' c3, fields->>'c4' c4, fields->>'c5' c5, fields->>'c6' c6, fields->>'c7' c7, fields->>'c8' c8 FROM ft1 t1) t1 JOIN (SELECT (fields->>'C 1')::int c1, (fields->>'c2')::int c2, tags->>'c3' c3, fields->>'c4' c4, fields->>'c5' c5, fields->>'c6' c6, fields->>'c7' c7, fields->>'c8' c8 FROM ft2 t2) t2 ON ((t1.c1)::int = (t2.c1)::int)) SELECT c1_1, c2_1 FROM t ORDER BY c1_3, c1_1 OFFSET 100 LIMIT 10; + c1_1 | c2_1 +------+------ + 101 | 101 + 102 | 102 + 103 | 103 + 104 | 104 + 105 | 105 + 106 | 106 + 107 | 107 + 108 | 108 + 109 | 109 + 110 | 110 +(10 rows) + +-- ctid with whole-row reference +--Testcase 174: +EXPLAIN (VERBOSE, COSTS OFF) +SELECT t1.ctid, t1, t2, t1.c1 FROM (SELECT ctid, fields->>'C 1' c1, fields->>'c2' c2, tags->>'c3' c3, fields->>'c4' c4, fields->>'c5' c5, fields->>'c6' c6, fields->>'c7' c7, fields->>'c8' c8 FROM ft1 t1) t1 JOIN (SELECT (fields->>'C 1')::int c1, (fields->>'c2')::int c2, tags->>'c3' c3, fields->>'c4' c4, fields->>'c5' c5, fields->>'c6' c6, fields->>'c7' c7, fields->>'c8' c8 FROM ft2 t2) t2 ON ((t1.c1)::int = (t2.c1)::int) ORDER BY t1.c3, (t1.c1)::int OFFSET 100 LIMIT 10; + QUERY PLAN +--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- + Limit + Output: t1.ctid, (ROW(t1.ctid, (t1.fields ->> 'C 1'::text), (t1.fields ->> 'c2'::text), (t1.tags ->> 'c3'::text), (t1.fields ->> 'c4'::text), (t1.fields ->> 'c5'::text), (t1.fields ->> 'c6'::text), (t1.fields ->> 'c7'::text), (t1.fields ->> 'c8'::text))), (ROW(((t2.fields ->> 'C 1'::text))::integer, ((t2.fields ->> 'c2'::text))::integer, (t2.tags ->> 'c3'::text), (t2.fields ->> 'c4'::text), (t2.fields ->> 'c5'::text), (t2.fields ->> 'c6'::text), (t2.fields ->> 'c7'::text), (t2.fields ->> 'c8'::text))), ((t1.fields ->> 'C 1'::text)), ((t1.tags ->> 'c3'::text)), (((t1.fields ->> 'C 1'::text))::integer) + -> Result + Output: t1.ctid, (ROW(t1.ctid, (t1.fields ->> 'C 1'::text), (t1.fields ->> 'c2'::text), (t1.tags ->> 'c3'::text), (t1.fields ->> 'c4'::text), (t1.fields ->> 'c5'::text), (t1.fields ->> 'c6'::text), (t1.fields ->> 'c7'::text), (t1.fields ->> 'c8'::text))), ROW(((t2.fields ->> 'C 1'::text))::integer, ((t2.fields ->> 'c2'::text))::integer, (t2.tags ->> 'c3'::text), (t2.fields ->> 'c4'::text), (t2.fields ->> 'c5'::text), (t2.fields ->> 'c6'::text), (t2.fields ->> 'c7'::text), (t2.fields ->> 'c8'::text)), ((t1.fields ->> 'C 1'::text)), ((t1.tags ->> 'c3'::text)), (((t1.fields ->> 'C 1'::text))::integer) + -> Sort + Output: t1.ctid, (ROW(t1.ctid, (t1.fields ->> 'C 1'::text), (t1.fields ->> 'c2'::text), (t1.tags ->> 'c3'::text), (t1.fields ->> 'c4'::text), (t1.fields ->> 'c5'::text), (t1.fields ->> 'c6'::text), (t1.fields ->> 'c7'::text), (t1.fields ->> 'c8'::text))), ((t1.fields ->> 'C 1'::text)), ((t1.tags ->> 'c3'::text)), (((t1.fields ->> 'C 1'::text))::integer), t2.fields, t2.tags + Sort Key: ((t1.tags ->> 'c3'::text)), (((t1.fields ->> 'C 1'::text))::integer) + -> Merge Join + Output: t1.ctid, ROW(t1.ctid, (t1.fields ->> 'C 1'::text), (t1.fields ->> 'c2'::text), (t1.tags ->> 'c3'::text), (t1.fields ->> 'c4'::text), (t1.fields ->> 'c5'::text), (t1.fields ->> 'c6'::text), (t1.fields ->> 'c7'::text), (t1.fields ->> 'c8'::text)), (t1.fields ->> 'C 1'::text), (t1.tags ->> 'c3'::text), (((t1.fields ->> 'C 1'::text))::integer), t2.fields, t2.tags + Merge Cond: ((((t1.fields ->> 'C 1'::text))::integer) = (((t2.fields ->> 'C 1'::text))::integer)) + -> Sort + Output: t1.ctid, t1.fields, t1.tags, (((t1.fields ->> 'C 1'::text))::integer) + Sort Key: (((t1.fields ->> 'C 1'::text))::integer) + -> Foreign Scan on public.ft1 t1 + Output: t1.ctid, t1.fields, t1.tags, ((t1.fields ->> 'C 1'::text))::integer + InfluxDB query: SELECT * FROM "T1" + -> Sort + Output: t2.fields, t2.tags, (((t2.fields ->> 'C 1'::text))::integer) + Sort Key: (((t2.fields ->> 'C 1'::text))::integer) + -> Foreign Scan on public.ft2 t2 + Output: t2.fields, t2.tags, ((t2.fields ->> 'C 1'::text))::integer + InfluxDB query: SELECT * FROM "T1" +(22 rows) + +-- SEMI JOIN, not pushed down +--Testcase 175: +EXPLAIN (VERBOSE, COSTS OFF) +SELECT (t1.fields->>'C 1')::int c1 FROM ft1 t1 WHERE EXISTS (SELECT 1 FROM ft2 t2 WHERE (t1.fields->>'C 1')::int = (t2.fields->>'C 1')::int) ORDER BY (t1.fields->>'C 1')::int OFFSET 100 LIMIT 10; + QUERY PLAN +------------------------------------------------------------------------------------------------------------ + Limit + Output: (((t1.fields ->> 'C 1'::text))::integer) + -> Sort + Output: (((t1.fields ->> 'C 1'::text))::integer) + Sort Key: (((t1.fields ->> 'C 1'::text))::integer) + -> Hash Join + Output: ((t1.fields ->> 'C 1'::text))::integer + Inner Unique: true + Hash Cond: (((t1.fields ->> 'C 1'::text))::integer = ((t2.fields ->> 'C 1'::text))::integer) + -> Foreign Scan on public.ft1 t1 + Output: t1."time", t1.tags, t1.fields + InfluxDB query: SELECT * FROM "T1" + -> Hash + Output: t2.fields + -> HashAggregate + Output: t2.fields + Group Key: ((t2.fields ->> 'C 1'::text))::integer + -> Foreign Scan on public.ft2 t2 + Output: t2.fields, ((t2.fields ->> 'C 1'::text))::integer + InfluxDB query: SELECT * FROM "T1" +(20 rows) + +--Testcase 176: +SELECT (t1.fields->>'C 1')::int c1 FROM ft1 t1 WHERE EXISTS (SELECT 1 FROM ft2 t2 WHERE (t1.fields->>'C 1')::int = (t2.fields->>'C 1')::int) ORDER BY (t1.fields->>'C 1')::int OFFSET 100 LIMIT 10; + c1 +----- + 101 + 102 + 103 + 104 + 105 + 106 + 107 + 108 + 109 + 110 +(10 rows) + +-- ANTI JOIN, not pushed down +--Testcase 177: +EXPLAIN (VERBOSE, COSTS OFF) +SELECT (t1.fields->>'C 1')::int c1 FROM ft1 t1 WHERE NOT EXISTS (SELECT 1 FROM ft2 t2 WHERE (t1.fields->>'C 1')::int = (t2.fields->>'c2')::int) ORDER BY (t1.fields->>'C 1')::int OFFSET 100 LIMIT 10; + QUERY PLAN +---------------------------------------------------------------------------------------------------------- + Limit + Output: (((t1.fields ->> 'C 1'::text))::integer) + -> Merge Anti Join + Output: (((t1.fields ->> 'C 1'::text))::integer) + Merge Cond: ((((t1.fields ->> 'C 1'::text))::integer) = (((t2.fields ->> 'c2'::text))::integer)) + -> Sort + Output: t1.fields, (((t1.fields ->> 'C 1'::text))::integer) + Sort Key: (((t1.fields ->> 'C 1'::text))::integer) + -> Foreign Scan on public.ft1 t1 + Output: t1.fields, ((t1.fields ->> 'C 1'::text))::integer + InfluxDB query: SELECT * FROM "T1" + -> Sort + Output: t2.fields, (((t2.fields ->> 'c2'::text))::integer) + Sort Key: (((t2.fields ->> 'c2'::text))::integer) + -> Foreign Scan on public.ft2 t2 + Output: t2.fields, ((t2.fields ->> 'c2'::text))::integer + InfluxDB query: SELECT * FROM "T1" +(17 rows) + +--Testcase 178: +SELECT (t1.fields->>'C 1')::int c1 FROM ft1 t1 WHERE NOT EXISTS (SELECT 1 FROM ft2 t2 WHERE (t1.fields->>'C 1')::int = (t2.fields->>'c2')::int) ORDER BY (t1.fields->>'C 1')::int OFFSET 100 LIMIT 10; + c1 +----- + 110 + 111 + 112 + 113 + 114 + 115 + 116 + 117 + 118 + 119 +(10 rows) + +-- CROSS JOIN can be pushed down +--Testcase 179: +EXPLAIN (VERBOSE, COSTS OFF) +SELECT t1.c1, t2.c1 FROM (SELECT (fields->>'C 1')::int c1, (fields->>'c2')::int c2, tags->>'c3' c3, fields->>'c4' c4, fields->>'c5' c5, fields->>'c6' c6, fields->>'c7' c7, fields->>'c8' c8 FROM ft1 t1) t1 CROSS JOIN (SELECT (fields->>'C 1')::int c1, (fields->>'c2')::int c2, tags->>'c3' c3, fields->>'c4' c4, fields->>'c5' c5, fields->>'c6' c6, fields->>'c7' c7, fields->>'c8' c8 FROM ft2 t2) t2 ORDER BY (t1.c1)::int, (t2.c1)::int OFFSET 100 LIMIT 10; + QUERY PLAN +------------------------------------------------------------------------------------------------------ + Limit + Output: (((t1.fields ->> 'C 1'::text))::integer), (((t2.fields ->> 'C 1'::text))::integer) + -> Sort + Output: (((t1.fields ->> 'C 1'::text))::integer), (((t2.fields ->> 'C 1'::text))::integer) + Sort Key: (((t1.fields ->> 'C 1'::text))::integer), (((t2.fields ->> 'C 1'::text))::integer) + -> Nested Loop + Output: ((t1.fields ->> 'C 1'::text))::integer, ((t2.fields ->> 'C 1'::text))::integer + -> Foreign Scan on public.ft1 t1 + Output: t1."time", t1.tags, t1.fields + InfluxDB query: SELECT * FROM "T1" + -> Materialize + Output: t2.fields + -> Foreign Scan on public.ft2 t2 + Output: t2.fields + InfluxDB query: SELECT * FROM "T1" +(15 rows) + +--Testcase 180: +SELECT t1.c1, t2.c1 FROM (SELECT (fields->>'C 1')::int c1, (fields->>'c2')::int c2, tags->>'c3' c3, fields->>'c4' c4, fields->>'c5' c5, fields->>'c6' c6, fields->>'c7' c7, fields->>'c8' c8 FROM ft1 t1) t1 CROSS JOIN (SELECT (fields->>'C 1')::int c1, (fields->>'c2')::int c2, tags->>'c3' c3, fields->>'c4' c4, fields->>'c5' c5, fields->>'c6' c6, fields->>'c7' c7, fields->>'c8' c8 FROM ft2 t2) t2 ORDER BY (t1.c1)::int, (t2.c1)::int OFFSET 100 LIMIT 10; + c1 | c1 +----+----- + 1 | 101 + 1 | 102 + 1 | 103 + 1 | 104 + 1 | 105 + 1 | 106 + 1 | 107 + 1 | 108 + 1 | 109 + 1 | 110 +(10 rows) + +-- different server, not pushed down. No result expected. +--Testcase 181: +EXPLAIN (VERBOSE, COSTS OFF) +SELECT t1.c1, t2.c1 FROM (SELECT (fields->>'c1')::int c1, (fields->>'c2')::int c2, tags->>'c3' c3 FROM ft5 t1) t1 JOIN (SELECT (fields->>'c1')::int c1, (fields->>'c2')::int c2, tags->>'c3' c3 FROM ft6 t2) t2 ON ((t1.c1)::int = (t2.c1)::int) ORDER BY (t1.c1)::int, (t2.c1)::int OFFSET 100 LIMIT 10; + QUERY PLAN +--------------------------------------------------------------------------------------------------------- + Limit + Output: (((t1.fields ->> 'c1'::text))::integer), (((t2.fields ->> 'c1'::text))::integer) + -> Merge Join + Output: (((t1.fields ->> 'c1'::text))::integer), (((t2.fields ->> 'c1'::text))::integer) + Merge Cond: ((((t1.fields ->> 'c1'::text))::integer) = (((t2.fields ->> 'c1'::text))::integer)) + -> Sort + Output: t1.fields, (((t1.fields ->> 'c1'::text))::integer) + Sort Key: (((t1.fields ->> 'c1'::text))::integer) + -> Foreign Scan on public.ft5 t1 + Output: t1.fields, ((t1.fields ->> 'c1'::text))::integer + InfluxDB query: SELECT * FROM "T4" + -> Sort + Output: t2.fields, (((t2.fields ->> 'c1'::text))::integer) + Sort Key: (((t2.fields ->> 'c1'::text))::integer) + -> Foreign Scan on public.ft6 t2 + Output: t2.fields, ((t2.fields ->> 'c1'::text))::integer + InfluxDB query: SELECT * FROM "T4" +(17 rows) + +--Testcase 182: +SELECT t1.c1, t2.c1 FROM (SELECT (fields->>'c1')::int c1, (fields->>'c2')::int c2, tags->>'c3' c3 FROM ft5 t1) t1 JOIN (SELECT (fields->>'c1')::int c1, (fields->>'c2')::int c2, tags->>'c3' c3 FROM ft6 t2) t2 ON ((t1.c1)::int = (t2.c1)::int) ORDER BY (t1.c1)::int, (t2.c1)::int OFFSET 100 LIMIT 10; + c1 | c1 +----+---- +(0 rows) + +-- unsafe join conditions (c8 has a UDT), not pushed down. Practically a CROSS +-- JOIN since c8 in both tables has same value. +--Testcase 183: +EXPLAIN (VERBOSE, COSTS OFF) +SELECT t1.c1, t2.c1 FROM (SELECT (fields->>'C 1')::int c1, (fields->>'c2')::int c2, tags->>'c3' c3, fields->>'c4' c4, fields->>'c5' c5, fields->>'c6' c6, fields->>'c7' c7, fields->>'c8' c8 FROM ft1 t1) t1 LEFT JOIN (SELECT (fields->>'C 1')::int c1, (fields->>'c2')::int c2, tags->>'c3' c3, fields->>'c4' c4, fields->>'c5' c5, fields->>'c6' c6, fields->>'c7' c7, fields->>'c8' c8 FROM ft2 t2) t2 ON (t1.c8 = t2.c8) ORDER BY (t1.c1)::int, (t2.c1)::int OFFSET 100 LIMIT 10; + QUERY PLAN +----------------------------------------------------------------------------------------------------------------- + Limit + Output: (((t1.fields ->> 'C 1'::text))::integer), (((t2.fields ->> 'C 1'::text))::integer) + -> Sort + Output: (((t1.fields ->> 'C 1'::text))::integer), (((t2.fields ->> 'C 1'::text))::integer) + Sort Key: (((t1.fields ->> 'C 1'::text))::integer), (((t2.fields ->> 'C 1'::text))::integer) + -> Merge Right Join + Output: ((t1.fields ->> 'C 1'::text))::integer, (((t2.fields ->> 'C 1'::text))::integer) + Merge Cond: (((t2.fields ->> 'c8'::text)) = ((t1.fields ->> 'c8'::text))) + -> Sort + Output: t2.fields, (((t2.fields ->> 'C 1'::text))::integer), ((t2.fields ->> 'c8'::text)) + Sort Key: ((t2.fields ->> 'c8'::text)) + -> Foreign Scan on public.ft2 t2 + Output: t2.fields, ((t2.fields ->> 'C 1'::text))::integer, (t2.fields ->> 'c8'::text) + InfluxDB query: SELECT * FROM "T1" + -> Sort + Output: t1.fields, ((t1.fields ->> 'c8'::text)) + Sort Key: ((t1.fields ->> 'c8'::text)) + -> Foreign Scan on public.ft1 t1 + Output: t1.fields, (t1.fields ->> 'c8'::text) + InfluxDB query: SELECT * FROM "T1" +(20 rows) + +--Testcase 184: +SELECT t1.c1, t2.c1 FROM (SELECT (fields->>'C 1')::int c1, (fields->>'c2')::int c2, tags->>'c3' c3, fields->>'c4' c4, fields->>'c5' c5, fields->>'c6' c6, fields->>'c7' c7, fields->>'c8' c8 FROM ft1 t1) t1 LEFT JOIN (SELECT (fields->>'C 1')::int c1, (fields->>'c2')::int c2, tags->>'c3' c3, fields->>'c4' c4, fields->>'c5' c5, fields->>'c6' c6, fields->>'c7' c7, fields->>'c8' c8 FROM ft2 t2) t2 ON (t1.c8 = t2.c8) ORDER BY (t1.c1)::int, (t2.c1)::int OFFSET 100 LIMIT 10; + c1 | c1 +----+----- + 1 | 101 + 1 | 102 + 1 | 103 + 1 | 104 + 1 | 105 + 1 | 106 + 1 | 107 + 1 | 108 + 1 | 109 + 1 | 110 +(10 rows) + +-- unsafe conditions on one side (c8 has a UDT), not pushed down. +--Testcase 185: +EXPLAIN (VERBOSE, COSTS OFF) +SELECT t1.c1, t2.c1 FROM (SELECT (fields->>'C 1')::int c1, (fields->>'c2')::int c2, tags->>'c3' c3, fields->>'c4' c4, fields->>'c5' c5, fields->>'c6' c6, fields->>'c7' c7, fields->>'c8' c8 FROM ft1 t1) t1 LEFT JOIN (SELECT (fields->>'C 1')::int c1, (fields->>'c2')::int c2, tags->>'c3' c3, fields->>'c4' c4, fields->>'c5' c5, fields->>'c6' c6, fields->>'c7' c7, fields->>'c8' c8 FROM ft2 t2) t2 ON ((t1.c1)::int = (t2.c1)::int) WHERE t1.c8 = 'foo' ORDER BY t1.c3, (t1.c1)::int OFFSET 100 LIMIT 10; + QUERY PLAN +---------------------------------------------------------------------------------------------------------------------------------- + Limit + Output: (((t1.fields ->> 'C 1'::text))::integer), (((t2.fields ->> 'C 1'::text))::integer), ((t1.tags ->> 'c3'::text)) + -> Sort + Output: (((t1.fields ->> 'C 1'::text))::integer), (((t2.fields ->> 'C 1'::text))::integer), ((t1.tags ->> 'c3'::text)) + Sort Key: ((t1.tags ->> 'c3'::text)), (((t1.fields ->> 'C 1'::text))::integer) + -> Hash Right Join + Output: ((t1.fields ->> 'C 1'::text))::integer, (((t2.fields ->> 'C 1'::text))::integer), (t1.tags ->> 'c3'::text) + Hash Cond: (((t2.fields ->> 'C 1'::text))::integer = ((t1.fields ->> 'C 1'::text))::integer) + -> Foreign Scan on public.ft2 t2 + Output: t2.fields, ((t2.fields ->> 'C 1'::text))::integer + InfluxDB query: SELECT * FROM "T1" + -> Hash + Output: t1.fields, t1.tags + -> Foreign Scan on public.ft1 t1 + Output: t1.fields, t1.tags + InfluxDB query: SELECT * FROM "T1" WHERE (("c8" = 'foo')) +(16 rows) + +--Testcase 186: +SELECT t1.c1, t2.c1 FROM (SELECT (fields->>'C 1')::int c1, (fields->>'c2')::int c2, tags->>'c3' c3, fields->>'c4' c4, fields->>'c5' c5, fields->>'c6' c6, fields->>'c7' c7, fields->>'c8' c8 FROM ft1 t1) t1 LEFT JOIN (SELECT (fields->>'C 1')::int c1, (fields->>'c2')::int c2, tags->>'c3' c3, fields->>'c4' c4, fields->>'c5' c5, fields->>'c6' c6, fields->>'c7' c7, fields->>'c8' c8 FROM ft2 t2) t2 ON ((t1.c1)::int = (t2.c1)::int) WHERE t1.c8 = 'foo' ORDER BY t1.c3, (t1.c1)::int OFFSET 100 LIMIT 10; + c1 | c1 +-----+----- + 101 | 101 + 102 | 102 + 103 | 103 + 104 | 104 + 105 | 105 + 106 | 106 + 107 | 107 + 108 | 108 + 109 | 109 + 110 | 110 +(10 rows) + +-- join where unsafe to pushdown condition in WHERE clause has a column not +-- in the SELECT clause. In this test unsafe clause needs to have column +-- references from both joining sides so that the clause is not pushed down +-- into one of the joining sides. +--Testcase 187: +EXPLAIN (VERBOSE, COSTS OFF) +SELECT t1.c1, t2.c1 FROM (SELECT (fields->>'C 1')::int c1, (fields->>'c2')::int c2, tags->>'c3' c3, fields->>'c4' c4, fields->>'c5' c5, fields->>'c6' c6, fields->>'c7' c7, fields->>'c8' c8 FROM ft1 t1) t1 JOIN (SELECT (fields->>'C 1')::int c1, (fields->>'c2')::int c2, tags->>'c3' c3, fields->>'c4' c4, fields->>'c5' c5, fields->>'c6' c6, fields->>'c7' c7, fields->>'c8' c8 FROM ft2 t2) t2 ON ((t1.c1)::int = (t2.c1)::int) WHERE t1.c8 = t2.c8 ORDER BY t1.c3, (t1.c1)::int OFFSET 100 LIMIT 10; + QUERY PLAN +------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- + Limit + Output: (((t1.fields ->> 'C 1'::text))::integer), (((t2.fields ->> 'C 1'::text))::integer), ((t1.tags ->> 'c3'::text)) + -> Sort + Output: (((t1.fields ->> 'C 1'::text))::integer), (((t2.fields ->> 'C 1'::text))::integer), ((t1.tags ->> 'c3'::text)) + Sort Key: ((t1.tags ->> 'c3'::text)), (((t1.fields ->> 'C 1'::text))::integer) + -> Merge Join + Output: (((t1.fields ->> 'C 1'::text))::integer), (((t2.fields ->> 'C 1'::text))::integer), (t1.tags ->> 'c3'::text) + Merge Cond: (((((t1.fields ->> 'C 1'::text))::integer) = (((t2.fields ->> 'C 1'::text))::integer)) AND (((t1.fields ->> 'c8'::text)) = ((t2.fields ->> 'c8'::text)))) + -> Sort + Output: t1.fields, t1.tags, (((t1.fields ->> 'C 1'::text))::integer), ((t1.fields ->> 'c8'::text)) + Sort Key: (((t1.fields ->> 'C 1'::text))::integer), ((t1.fields ->> 'c8'::text)) + -> Foreign Scan on public.ft1 t1 + Output: t1.fields, t1.tags, ((t1.fields ->> 'C 1'::text))::integer, (t1.fields ->> 'c8'::text) + InfluxDB query: SELECT * FROM "T1" + -> Sort + Output: t2.fields, (((t2.fields ->> 'C 1'::text))::integer), ((t2.fields ->> 'c8'::text)) + Sort Key: (((t2.fields ->> 'C 1'::text))::integer), ((t2.fields ->> 'c8'::text)) + -> Foreign Scan on public.ft2 t2 + Output: t2.fields, ((t2.fields ->> 'C 1'::text))::integer, (t2.fields ->> 'c8'::text) + InfluxDB query: SELECT * FROM "T1" +(20 rows) + +--Testcase 188: +SELECT t1.c1, t2.c1 FROM (SELECT (fields->>'C 1')::int c1, (fields->>'c2')::int c2, tags->>'c3' c3, fields->>'c4' c4, fields->>'c5' c5, fields->>'c6' c6, fields->>'c7' c7, fields->>'c8' c8 FROM ft1 t1) t1 JOIN (SELECT (fields->>'C 1')::int c1, (fields->>'c2')::int c2, tags->>'c3' c3, fields->>'c4' c4, fields->>'c5' c5, fields->>'c6' c6, fields->>'c7' c7, fields->>'c8' c8 FROM ft2 t2) t2 ON ((t1.c1)::int = (t2.c1)::int) WHERE t1.c8 = t2.c8 ORDER BY t1.c3, (t1.c1)::int OFFSET 100 LIMIT 10; + c1 | c1 +-----+----- + 101 | 101 + 102 | 102 + 103 | 103 + 104 | 104 + 105 | 105 + 106 | 106 + 107 | 107 + 108 | 108 + 109 | 109 + 110 | 110 +(10 rows) + +-- Aggregate after UNION, for testing setrefs +--Testcase 189: +EXPLAIN (VERBOSE, COSTS OFF) +SELECT t1c1, avg(t1c1 + t2c1) FROM (SELECT (t1.c1)::int, (t2.c1)::int FROM (SELECT (fields->>'C 1')::int c1, (fields->>'c2')::int c2, tags->>'c3' c3, fields->>'c4' c4, fields->>'c5' c5, fields->>'c6' c6, fields->>'c7' c7, fields->>'c8' c8 FROM ft1 t1) t1 JOIN (SELECT (fields->>'C 1')::int c1, (fields->>'c2')::int c2, tags->>'c3' c3, fields->>'c4' c4, fields->>'c5' c5, fields->>'c6' c6, fields->>'c7' c7, fields->>'c8' c8 FROM ft2 t2) t2 ON ((t1.c1)::int = (t2.c1)::int) UNION SELECT (t1.c1)::int, (t2.c1)::int FROM (SELECT (fields->>'C 1')::int c1, (fields->>'c2')::int c2, tags->>'c3' c3, fields->>'c4' c4, fields->>'c5' c5, fields->>'c6' c6, fields->>'c7' c7, fields->>'c8' c8 FROM ft1 t1) t1 JOIN (SELECT (fields->>'C 1')::int c1, (fields->>'c2')::int c2, tags->>'c3' c3, fields->>'c4' c4, fields->>'c5' c5, fields->>'c6' c6, fields->>'c7' c7, fields->>'c8' c8 FROM ft2 t2) t2 ON ((t1.c1)::int = (t2.c1)::int)) AS t (t1c1, t2c1) GROUP BY t1c1 ORDER BY t1c1 OFFSET 100 LIMIT 10; + QUERY PLAN +------------------------------------------------------------------------------------------------------------------------------------------------------------ + Limit + Output: (((t1.fields ->> 'C 1'::text))::integer), (avg(((((t1.fields ->> 'C 1'::text))::integer) + (((t2.fields ->> 'C 1'::text))::integer)))) + -> Sort + Output: (((t1.fields ->> 'C 1'::text))::integer), (avg(((((t1.fields ->> 'C 1'::text))::integer) + (((t2.fields ->> 'C 1'::text))::integer)))) + Sort Key: (((t1.fields ->> 'C 1'::text))::integer) + -> HashAggregate + Output: (((t1.fields ->> 'C 1'::text))::integer), avg(((((t1.fields ->> 'C 1'::text))::integer) + (((t2.fields ->> 'C 1'::text))::integer))) + Group Key: (((t1.fields ->> 'C 1'::text))::integer) + -> HashAggregate + Output: (((t1.fields ->> 'C 1'::text))::integer), (((t2.fields ->> 'C 1'::text))::integer) + Group Key: (((t1.fields ->> 'C 1'::text))::integer), (((t2.fields ->> 'C 1'::text))::integer) + -> Append + -> Merge Join + Output: (((t1.fields ->> 'C 1'::text))::integer), (((t2.fields ->> 'C 1'::text))::integer) + Merge Cond: ((((t1.fields ->> 'C 1'::text))::integer) = (((t2.fields ->> 'C 1'::text))::integer)) + -> Sort + Output: t1.fields, (((t1.fields ->> 'C 1'::text))::integer) + Sort Key: (((t1.fields ->> 'C 1'::text))::integer) + -> Foreign Scan on public.ft1 t1 + Output: t1.fields, ((t1.fields ->> 'C 1'::text))::integer + InfluxDB query: SELECT * FROM "T1" + -> Sort + Output: t2.fields, (((t2.fields ->> 'C 1'::text))::integer) + Sort Key: (((t2.fields ->> 'C 1'::text))::integer) + -> Foreign Scan on public.ft2 t2 + Output: t2.fields, ((t2.fields ->> 'C 1'::text))::integer + InfluxDB query: SELECT * FROM "T1" + -> Merge Join + Output: (((t1_1.fields ->> 'C 1'::text))::integer), (((t2_1.fields ->> 'C 1'::text))::integer) + Merge Cond: ((((t1_1.fields ->> 'C 1'::text))::integer) = (((t2_1.fields ->> 'C 1'::text))::integer)) + -> Sort + Output: t1_1.fields, (((t1_1.fields ->> 'C 1'::text))::integer) + Sort Key: (((t1_1.fields ->> 'C 1'::text))::integer) + -> Foreign Scan on public.ft1 t1_1 + Output: t1_1.fields, ((t1_1.fields ->> 'C 1'::text))::integer + InfluxDB query: SELECT * FROM "T1" + -> Sort + Output: t2_1.fields, (((t2_1.fields ->> 'C 1'::text))::integer) + Sort Key: (((t2_1.fields ->> 'C 1'::text))::integer) + -> Foreign Scan on public.ft2 t2_1 + Output: t2_1.fields, ((t2_1.fields ->> 'C 1'::text))::integer + InfluxDB query: SELECT * FROM "T1" +(42 rows) + +--Testcase 190: +SELECT t1c1, avg(t1c1 + t2c1) FROM (SELECT (t1.c1)::int, (t2.c1)::int FROM (SELECT (fields->>'C 1')::int c1, (fields->>'c2')::int c2, tags->>'c3' c3, fields->>'c4' c4, fields->>'c5' c5, fields->>'c6' c6, fields->>'c7' c7, fields->>'c8' c8 FROM ft1 t1) t1 JOIN (SELECT (fields->>'C 1')::int c1, (fields->>'c2')::int c2, tags->>'c3' c3, fields->>'c4' c4, fields->>'c5' c5, fields->>'c6' c6, fields->>'c7' c7, fields->>'c8' c8 FROM ft2 t2) t2 ON ((t1.c1)::int = (t2.c1)::int) UNION SELECT (t1.c1)::int, (t2.c1)::int FROM (SELECT (fields->>'C 1')::int c1, (fields->>'c2')::int c2, tags->>'c3' c3, fields->>'c4' c4, fields->>'c5' c5, fields->>'c6' c6, fields->>'c7' c7, fields->>'c8' c8 FROM ft1 t1) t1 JOIN (SELECT (fields->>'C 1')::int c1, (fields->>'c2')::int c2, tags->>'c3' c3, fields->>'c4' c4, fields->>'c5' c5, fields->>'c6' c6, fields->>'c7' c7, fields->>'c8' c8 FROM ft2 t2) t2 ON ((t1.c1)::int = (t2.c1)::int)) AS t (t1c1, t2c1) GROUP BY t1c1 ORDER BY t1c1 OFFSET 100 LIMIT 10; + t1c1 | avg +------+---------------------- + 101 | 202.0000000000000000 + 102 | 204.0000000000000000 + 103 | 206.0000000000000000 + 104 | 208.0000000000000000 + 105 | 210.0000000000000000 + 106 | 212.0000000000000000 + 107 | 214.0000000000000000 + 108 | 216.0000000000000000 + 109 | 218.0000000000000000 + 110 | 220.0000000000000000 +(10 rows) + +-- join with lateral reference +--Testcase 191: +EXPLAIN (VERBOSE, COSTS OFF) +SELECT t1."C 1" FROM (SELECT (fields->>'C 1')::int "C 1", (fields->>'c2')::int c2, tags->>'c3' c3, fields->>'c4' c4, fields->>'c5' c5, fields->>'c6' c6, fields->>'c7' c7, fields->>'c8' c8 FROM "S 1"."T 1" t1) t1, LATERAL (SELECT DISTINCT t2.fields->>'C 1', t3.fields->>'C 1' FROM ft1 t2, ft2 t3 WHERE (t2.fields->>'C 1')::int = (t3.fields->>'C 1')::int AND (t2.fields->>'c2')::int = (t1.c2)::int) q ORDER BY (t1."C 1")::int OFFSET 10 LIMIT 10; + QUERY PLAN +------------------------------------------------------------------------------------------------------------------------------ + Limit + Output: (((t1.fields ->> 'C 1'::text))::integer) + -> Sort + Output: (((t1.fields ->> 'C 1'::text))::integer) + Sort Key: (((t1.fields ->> 'C 1'::text))::integer) + -> Nested Loop + Output: ((t1.fields ->> 'C 1'::text))::integer + -> Foreign Scan on "S 1"."T 1" t1 + Output: t1."time", t1.tags, t1.fields + InfluxDB query: SELECT * FROM "T1" + -> Unique + Output: ((t2.fields ->> 'C 1'::text)), ((t3.fields ->> 'C 1'::text)) + -> Sort + Output: ((t2.fields ->> 'C 1'::text)), ((t3.fields ->> 'C 1'::text)) + Sort Key: ((t2.fields ->> 'C 1'::text)), ((t3.fields ->> 'C 1'::text)) + -> Hash Join + Output: (t2.fields ->> 'C 1'::text), (t3.fields ->> 'C 1'::text) + Hash Cond: (((t3.fields ->> 'C 1'::text))::integer = ((t2.fields ->> 'C 1'::text))::integer) + -> Foreign Scan on public.ft2 t3 + Output: t3."time", t3.tags, t3.fields + InfluxDB query: SELECT * FROM "T1" + -> Hash + Output: t2.fields + -> Foreign Scan on public.ft1 t2 + Output: t2.fields + InfluxDB query: SELECT * FROM "T1" WHERE (("c2" = $1)) +(26 rows) + +--Testcase 192: +SELECT t1."C 1" FROM (SELECT (fields->>'C 1')::int "C 1", (fields->>'c2')::int c2, tags->>'c3' c3, fields->>'c4' c4, fields->>'c5' c5, fields->>'c6' c6, fields->>'c7' c7, fields->>'c8' c8 FROM "S 1"."T 1" t1) t1, LATERAL (SELECT DISTINCT t2.fields->>'C 1', t3.fields->>'C 1' FROM ft1 t2, ft2 t3 WHERE (t2.fields->>'C 1')::int = (t3.fields->>'C 1')::int AND (t2.fields->>'c2')::int = (t1.c2)::int) q ORDER BY (t1."C 1")::int OFFSET 10 LIMIT 10; + C 1 +----- + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 1 +(10 rows) + +-- join with pseudoconstant quals, not pushed down. +EXPLAIN (VERBOSE, COSTS OFF) +SELECT t1.c1, t2.c1 FROM (SELECT (fields->>'C 1')::int c1, (fields->>'c2')::int c2, tags->>'c3' c3, fields->>'c4' c4, fields->>'c5' c5, fields->>'c6' c6, fields->>'c7' c7, fields->>'c8' c8 FROM ft1) t1 JOIN (SELECT (fields->>'C 1')::int c1, (fields->>'c2')::int c2, tags->>'c3' c3, fields->>'c4' c4, fields->>'c5' c5, fields->>'c6' c6, fields->>'c7' c7, fields->>'c8' c8 FROM ft2) t2 ON (t1.c1 = t2.c1 AND CURRENT_USER = SESSION_USER) ORDER BY t1.c3, t1.c1 OFFSET 100 LIMIT 10; + QUERY PLAN +----------------------------------------------------------------------------------------------------------------------------------- + Limit + Output: (((ft1.fields ->> 'C 1'::text))::integer), (((ft2.fields ->> 'C 1'::text))::integer), ((ft1.tags ->> 'c3'::text)) + -> Sort + Output: (((ft1.fields ->> 'C 1'::text))::integer), (((ft2.fields ->> 'C 1'::text))::integer), ((ft1.tags ->> 'c3'::text)) + Sort Key: ((ft1.tags ->> 'c3'::text)), (((ft1.fields ->> 'C 1'::text))::integer) + -> Result + Output: ((ft1.fields ->> 'C 1'::text))::integer, ((ft2.fields ->> 'C 1'::text))::integer, (ft1.tags ->> 'c3'::text) + One-Time Filter: (CURRENT_USER = SESSION_USER) + -> Merge Join + Output: ft1.fields, ft1.tags, ft2.fields + Merge Cond: ((((ft1.fields ->> 'C 1'::text))::integer) = (((ft2.fields ->> 'C 1'::text))::integer)) + -> Sort + Output: ft1.fields, ft1.tags, (((ft1.fields ->> 'C 1'::text))::integer) + Sort Key: (((ft1.fields ->> 'C 1'::text))::integer) + -> Foreign Scan on public.ft1 + Output: ft1.fields, ft1.tags, ((ft1.fields ->> 'C 1'::text))::integer + InfluxDB query: SELECT * FROM "T1" + -> Sort + Output: ft2.fields, (((ft2.fields ->> 'C 1'::text))::integer) + Sort Key: (((ft2.fields ->> 'C 1'::text))::integer) + -> Foreign Scan on public.ft2 + Output: ft2.fields, ((ft2.fields ->> 'C 1'::text))::integer + InfluxDB query: SELECT * FROM "T1" +(23 rows) + +-- non-Var items in targetlist of the nullable rel of a join preventing +-- push-down in some cases +-- unable to push {ft1, ft2} +--Testcase 193: +EXPLAIN (VERBOSE, COSTS OFF) +SELECT q.a, (ft2.fields->>'C 1')::int c1 FROM (SELECT 13 FROM ft1 WHERE (fields->>'C 1')::int = 13) q(a) RIGHT JOIN ft2 ON (q.a = (ft2.fields->>'C 1')::int) WHERE (ft2.fields->>'C 1')::int BETWEEN 10 AND 15; + QUERY PLAN +-------------------------------------------------------------------------------------- + Nested Loop Left Join + Output: (13), ((ft2.fields ->> 'C 1'::text))::integer + Join Filter: (13 = ((ft2.fields ->> 'C 1'::text))::integer) + -> Foreign Scan on public.ft2 + Output: ft2."time", ft2.tags, ft2.fields + InfluxDB query: SELECT * FROM "T1" WHERE (("C 1" >= 10)) AND (("C 1" <= 15)) + -> Materialize + Output: (13) + -> Foreign Scan on public.ft1 + Output: 13 + InfluxDB query: SELECT * FROM "T1" WHERE (("C 1" = 13)) +(11 rows) + +--Testcase 194: +SELECT q.a, (ft2.fields->>'C 1')::int c1 FROM (SELECT 13 FROM ft1 WHERE (fields->>'C 1')::int = 13) q(a) RIGHT JOIN ft2 ON (q.a = (ft2.fields->>'C 1')::int) WHERE (ft2.fields->>'C 1')::int BETWEEN 10 AND 15; + a | c1 +----+---- + | 10 + | 11 + | 12 + 13 | 13 + | 14 + | 15 +(6 rows) + +-- ok to push {ft1, ft2} but not {ft1, ft2, ft4} +--Testcase 195: +EXPLAIN (VERBOSE, COSTS OFF) +SELECT (ft4.fields->>'c1')::int c1, q.* FROM ft4 LEFT JOIN (SELECT 13, (ft1.fields->>'C 1')::int, (ft2.fields->>'C 1')::int FROM ft1 RIGHT JOIN ft2 ON ((ft1.fields->>'C 1')::int = (ft2.fields->>'C 1')::int) WHERE (ft1.fields->>'C 1')::int = 12) q(a, b, c) ON ((ft4.fields->>'c1')::int = q.b) WHERE (ft4.fields->>'c1')::int BETWEEN 10 AND 15; + QUERY PLAN +---------------------------------------------------------------------------------------------------------------------------------------------- + Hash Right Join + Output: ((ft4.fields ->> 'c1'::text))::integer, (13), (((ft1.fields ->> 'C 1'::text))::integer), (((ft2.fields ->> 'C 1'::text))::integer) + Hash Cond: (((ft1.fields ->> 'C 1'::text))::integer = ((ft4.fields ->> 'c1'::text))::integer) + -> Nested Loop + Output: ft1.fields, (((ft1.fields ->> 'C 1'::text))::integer), (((ft2.fields ->> 'C 1'::text))::integer), 13 + -> Foreign Scan on public.ft1 + Output: ft1.fields, ((ft1.fields ->> 'C 1'::text))::integer + InfluxDB query: SELECT * FROM "T1" WHERE (("C 1" = 12)) + -> Materialize + Output: ft2.fields, (((ft2.fields ->> 'C 1'::text))::integer) + -> Foreign Scan on public.ft2 + Output: ft2.fields, ((ft2.fields ->> 'C 1'::text))::integer + InfluxDB query: SELECT * FROM "T1" WHERE (("C 1" = 12)) + -> Hash + Output: ft4.fields + -> Foreign Scan on public.ft4 + Output: ft4.fields + InfluxDB query: SELECT * FROM "T3" WHERE (("c1" >= 10)) AND (("c1" <= 15)) +(18 rows) + +--Testcase 196: +SELECT (ft4.fields->>'c1')::int c1, q.* FROM ft4 LEFT JOIN (SELECT 13, (ft1.fields->>'C 1')::int, (ft2.fields->>'C 1')::int FROM ft1 RIGHT JOIN ft2 ON ((ft1.fields->>'C 1')::int = (ft2.fields->>'C 1')::int) WHERE (ft1.fields->>'C 1')::int = 12) q(a, b, c) ON ((ft4.fields->>'c1')::int = q.b) WHERE (ft4.fields->>'c1')::int BETWEEN 10 AND 15 ORDER BY (ft4.fields->>'c1')::int; + c1 | a | b | c +----+----+----+---- + 10 | | | + 12 | 13 | 12 | 12 + 14 | | | +(3 rows) + +-- join with nullable side with some columns with null values +-- influxdb_fdw does not support UPDATE +-- UPDATE ft5 SET c3 = null where c1 % 9 = 0; +--Testcase 197: +EXPLAIN (VERBOSE, COSTS OFF) +SELECT ft5, (ft5.fields->>'c1')::int c1, (ft5.fields->>'c2')::int c2, ft5.tags->>'c3' c3, (ft4.fields->>'c1')::int c1, (ft4.fields->>'c2')::int c2 FROM ft5 left join ft4 on (ft5.fields->>'c1')::int = (ft4.fields->>'c1')::int WHERE (ft4.fields->>'c1')::int BETWEEN 10 and 30 ORDER BY (ft5.fields->>'c1')::int, (ft4.fields->>'c1')::int; + QUERY PLAN +---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- + Sort + Output: ft5.*, (((ft5.fields ->> 'c1'::text))::integer), (((ft5.fields ->> 'c2'::text))::integer), ((ft5.tags ->> 'c3'::text)), (((ft4.fields ->> 'c1'::text))::integer), (((ft4.fields ->> 'c2'::text))::integer) + Sort Key: (((ft5.fields ->> 'c1'::text))::integer) + -> Hash Join + Output: ft5.*, ((ft5.fields ->> 'c1'::text))::integer, ((ft5.fields ->> 'c2'::text))::integer, (ft5.tags ->> 'c3'::text), ((ft4.fields ->> 'c1'::text))::integer, ((ft4.fields ->> 'c2'::text))::integer + Hash Cond: (((ft5.fields ->> 'c1'::text))::integer = ((ft4.fields ->> 'c1'::text))::integer) + -> Foreign Scan on public.ft5 + Output: ft5.*, ft5.fields, ft5.tags + InfluxDB query: SELECT * FROM "T4" + -> Hash + Output: ft4.fields + -> Foreign Scan on public.ft4 + Output: ft4.fields + InfluxDB query: SELECT * FROM "T3" WHERE (("c1" >= 10)) AND (("c1" <= 30)) +(14 rows) + +--Testcase 198: +SELECT ft5, (ft5.fields->>'c1')::int c1, (ft5.fields->>'c2')::int c2, ft5.tags->>'c3' c3, (ft4.fields->>'c1')::int c1, (ft4.fields->>'c2')::int c2 FROM ft5 left join ft4 on (ft5.fields->>'c1')::int = (ft4.fields->>'c1')::int WHERE (ft4.fields->>'c1')::int BETWEEN 10 and 30 ORDER BY (ft5.fields->>'c1')::int, (ft4.fields->>'c1')::int; + ft5 | c1 | c2 | c3 | c1 | c2 +-------------------------------------------------------------+----+----+--------+----+---- + ("{""c3"": ""AAA012""}","{""c1"": ""12"", ""c2"": ""13""}") | 12 | 13 | AAA012 | 12 | 13 + ("{""c3"": ""AAA018""}","{""c1"": ""18"", ""c2"": ""19""}") | 18 | 19 | AAA018 | 18 | 19 + ("{""c3"": ""AAA024""}","{""c1"": ""24"", ""c2"": ""25""}") | 24 | 25 | AAA024 | 24 | 25 + ("{""c3"": ""AAA030""}","{""c1"": ""30"", ""c2"": ""31""}") | 30 | 31 | AAA030 | 30 | 31 +(4 rows) + +-- multi-way join involving multiple merge joins +-- (this case used to have EPQ-related planning problems) +--Testcase 199: +CREATE FOREIGN TABLE local_tbl (fields jsonb OPTIONS(fields 'true')) SERVER influxdb_svr OPTIONS (table 'local_tbl', schemaless 'true'); +--Testcase 794: +CREATE FOREIGN TABLE local_tbl_nsc (c1 int NOT NULL, c2 int NOT NULL, c3 text) SERVER influxdb_svr OPTIONS (table 'local_tbl'); +--Testcase 200: +INSERT INTO local_tbl_nsc SELECT id, id % 10, to_char(id, 'FM0000') FROM generate_series(1, 1000) id; +--ANALYZE local_tbl; +--Testcase 201: +SET enable_nestloop TO false; +--Testcase 202: +SET enable_hashjoin TO false; +--Testcase 203: +EXPLAIN (VERBOSE, COSTS OFF) +SELECT * FROM ft1, ft2, ft4, ft5, local_tbl WHERE (ft1.fields->>'C 1')::int = (ft2.fields->>'C 1')::int AND (ft1.fields->>'c2')::int = (ft4.fields->>'c1')::int + AND (ft1.fields->>'c2')::int = (ft5.fields->>'c1')::int AND (ft1.fields->>'c2')::int = (local_tbl.fields->>'c1')::int AND (ft1.fields->>'C 1')::int < 100 AND (ft2.fields->>'C 1')::int < 100 ORDER BY (ft1.fields->>'C 1')::int FOR UPDATE; + QUERY PLAN +------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ + LockRows + Output: ft1."time", ft1.tags, ft1.fields, ft2."time", ft2.tags, ft2.fields, ft4.tags, ft4.fields, ft5.tags, ft5.fields, local_tbl.fields, (((ft1.fields ->> 'C 1'::text))::integer), ft1.*, ft2.*, ft4.*, ft5.*, local_tbl.* + -> Sort + Output: ft1."time", ft1.tags, ft1.fields, ft2."time", ft2.tags, ft2.fields, ft4.tags, ft4.fields, ft5.tags, ft5.fields, local_tbl.fields, (((ft1.fields ->> 'C 1'::text))::integer), ft1.*, ft2.*, ft4.*, ft5.*, local_tbl.* + Sort Key: (((ft1.fields ->> 'C 1'::text))::integer) + -> Merge Join + Output: ft1."time", ft1.tags, ft1.fields, ft2."time", ft2.tags, ft2.fields, ft4.tags, ft4.fields, ft5.tags, ft5.fields, local_tbl.fields, ((ft1.fields ->> 'C 1'::text))::integer, ft1.*, ft2.*, ft4.*, ft5.*, local_tbl.* + Merge Cond: (((ft1.fields ->> 'c2'::text))::integer = (((local_tbl.fields ->> 'c1'::text))::integer)) + -> Merge Join + Output: ft1."time", ft1.tags, ft1.fields, ft1.*, ft2."time", ft2.tags, ft2.fields, ft2.*, ft4.tags, ft4.fields, ft4.*, ft5.tags, ft5.fields, ft5.* + Merge Cond: (((ft1.fields ->> 'c2'::text))::integer = (((ft5.fields ->> 'c1'::text))::integer)) + -> Merge Join + Output: ft1."time", ft1.tags, ft1.fields, ft1.*, ft2."time", ft2.tags, ft2.fields, ft2.*, ft4.tags, ft4.fields, ft4.* + Merge Cond: ((((ft1.fields ->> 'c2'::text))::integer) = (((ft4.fields ->> 'c1'::text))::integer)) + -> Sort + Output: ft1."time", ft1.tags, ft1.fields, ft1.*, ft2."time", ft2.tags, ft2.fields, ft2.*, (((ft1.fields ->> 'c2'::text))::integer) + Sort Key: (((ft1.fields ->> 'c2'::text))::integer) + -> Merge Join + Output: ft1."time", ft1.tags, ft1.fields, ft1.*, ft2."time", ft2.tags, ft2.fields, ft2.*, ((ft1.fields ->> 'c2'::text))::integer + Merge Cond: ((((ft1.fields ->> 'C 1'::text))::integer) = (((ft2.fields ->> 'C 1'::text))::integer)) + -> Sort + Output: ft1."time", ft1.tags, ft1.fields, ft1.*, (((ft1.fields ->> 'C 1'::text))::integer) + Sort Key: (((ft1.fields ->> 'C 1'::text))::integer) + -> Foreign Scan on public.ft1 + Output: ft1."time", ft1.tags, ft1.fields, ft1.*, ((ft1.fields ->> 'C 1'::text))::integer + InfluxDB query: SELECT * FROM "T1" WHERE (("C 1" < 100)) + -> Sort + Output: ft2."time", ft2.tags, ft2.fields, ft2.*, (((ft2.fields ->> 'C 1'::text))::integer) + Sort Key: (((ft2.fields ->> 'C 1'::text))::integer) + -> Foreign Scan on public.ft2 + Output: ft2."time", ft2.tags, ft2.fields, ft2.*, ((ft2.fields ->> 'C 1'::text))::integer + InfluxDB query: SELECT * FROM "T1" WHERE (("C 1" < 100)) + -> Sort + Output: ft4.tags, ft4.fields, ft4.*, (((ft4.fields ->> 'c1'::text))::integer) + Sort Key: (((ft4.fields ->> 'c1'::text))::integer) + -> Foreign Scan on public.ft4 + Output: ft4.tags, ft4.fields, ft4.*, ((ft4.fields ->> 'c1'::text))::integer + InfluxDB query: SELECT * FROM "T3" + -> Sort + Output: ft5.tags, ft5.fields, ft5.*, (((ft5.fields ->> 'c1'::text))::integer) + Sort Key: (((ft5.fields ->> 'c1'::text))::integer) + -> Foreign Scan on public.ft5 + Output: ft5.tags, ft5.fields, ft5.*, ((ft5.fields ->> 'c1'::text))::integer + InfluxDB query: SELECT * FROM "T4" + -> Sort + Output: local_tbl.fields, local_tbl.*, (((local_tbl.fields ->> 'c1'::text))::integer) + Sort Key: (((local_tbl.fields ->> 'c1'::text))::integer) + -> Foreign Scan on public.local_tbl + Output: local_tbl.fields, local_tbl.*, ((local_tbl.fields ->> 'c1'::text))::integer + InfluxDB query: SELECT * FROM "local_tbl" +(50 rows) + +--Testcase 204: +SELECT * FROM ft1, ft2, ft4, ft5, local_tbl WHERE (ft1.fields->>'C 1')::int = (ft2.fields->>'C 1')::int AND (ft1.fields->>'c2')::int = (ft4.fields->>'c1')::int + AND (ft1.fields->>'c2')::int = (ft5.fields->>'c1')::int AND (ft1.fields->>'c2')::int = (local_tbl.fields->>'c1')::int AND (ft1.fields->>'C 1')::int < 100 AND (ft2.fields->>'C 1')::int < 100 ORDER BY (ft1.fields->>'C 1')::int FOR UPDATE; + time | tags | fields | time | tags | fields | tags | fields | tags | fields | fields +------------------------------+-----------------+----------------------------------------------------------------------+------------------------------+-----------------+----------------------------------------------------------------------+------------------+------------------------+------------------+------------------------+-------------------------------------- + Wed Jan 07 00:00:00 1970 PST | {"c3": "00006"} | {"c2": "6", "c6": "6", "c7": "6 ", "c8": "foo", "C 1": "6"} | Wed Jan 07 00:00:00 1970 PST | {"c3": "00006"} | {"c2": "6", "c6": "6", "c7": "6 ", "c8": "foo", "C 1": "6"} | {"c3": "AAA006"} | {"c1": "6", "c2": "7"} | {"c3": "AAA006"} | {"c1": "6", "c2": "7"} | {"c1": "6", "c2": "6", "c3": "0006"} + Sat Jan 17 00:00:00 1970 PST | {"c3": "00016"} | {"c2": "6", "c6": "6", "c7": "6 ", "c8": "foo", "C 1": "16"} | Sat Jan 17 00:00:00 1970 PST | {"c3": "00016"} | {"c2": "6", "c6": "6", "c7": "6 ", "c8": "foo", "C 1": "16"} | {"c3": "AAA006"} | {"c1": "6", "c2": "7"} | {"c3": "AAA006"} | {"c1": "6", "c2": "7"} | {"c1": "6", "c2": "6", "c3": "0006"} + Tue Jan 27 00:00:00 1970 PST | {"c3": "00026"} | {"c2": "6", "c6": "6", "c7": "6 ", "c8": "foo", "C 1": "26"} | Tue Jan 27 00:00:00 1970 PST | {"c3": "00026"} | {"c2": "6", "c6": "6", "c7": "6 ", "c8": "foo", "C 1": "26"} | {"c3": "AAA006"} | {"c1": "6", "c2": "7"} | {"c3": "AAA006"} | {"c1": "6", "c2": "7"} | {"c1": "6", "c2": "6", "c3": "0006"} + Fri Feb 06 00:00:00 1970 PST | {"c3": "00036"} | {"c2": "6", "c6": "6", "c7": "6 ", "c8": "foo", "C 1": "36"} | Fri Feb 06 00:00:00 1970 PST | {"c3": "00036"} | {"c2": "6", "c6": "6", "c7": "6 ", "c8": "foo", "C 1": "36"} | {"c3": "AAA006"} | {"c1": "6", "c2": "7"} | {"c3": "AAA006"} | {"c1": "6", "c2": "7"} | {"c1": "6", "c2": "6", "c3": "0006"} + Mon Feb 16 00:00:00 1970 PST | {"c3": "00046"} | {"c2": "6", "c6": "6", "c7": "6 ", "c8": "foo", "C 1": "46"} | Mon Feb 16 00:00:00 1970 PST | {"c3": "00046"} | {"c2": "6", "c6": "6", "c7": "6 ", "c8": "foo", "C 1": "46"} | {"c3": "AAA006"} | {"c1": "6", "c2": "7"} | {"c3": "AAA006"} | {"c1": "6", "c2": "7"} | {"c1": "6", "c2": "6", "c3": "0006"} + Thu Feb 26 00:00:00 1970 PST | {"c3": "00056"} | {"c2": "6", "c6": "6", "c7": "6 ", "c8": "foo", "C 1": "56"} | Thu Feb 26 00:00:00 1970 PST | {"c3": "00056"} | {"c2": "6", "c6": "6", "c7": "6 ", "c8": "foo", "C 1": "56"} | {"c3": "AAA006"} | {"c1": "6", "c2": "7"} | {"c3": "AAA006"} | {"c1": "6", "c2": "7"} | {"c1": "6", "c2": "6", "c3": "0006"} + Sun Mar 08 00:00:00 1970 PST | {"c3": "00066"} | {"c2": "6", "c6": "6", "c7": "6 ", "c8": "foo", "C 1": "66"} | Sun Mar 08 00:00:00 1970 PST | {"c3": "00066"} | {"c2": "6", "c6": "6", "c7": "6 ", "c8": "foo", "C 1": "66"} | {"c3": "AAA006"} | {"c1": "6", "c2": "7"} | {"c3": "AAA006"} | {"c1": "6", "c2": "7"} | {"c1": "6", "c2": "6", "c3": "0006"} + Wed Mar 18 00:00:00 1970 PST | {"c3": "00076"} | {"c2": "6", "c6": "6", "c7": "6 ", "c8": "foo", "C 1": "76"} | Wed Mar 18 00:00:00 1970 PST | {"c3": "00076"} | {"c2": "6", "c6": "6", "c7": "6 ", "c8": "foo", "C 1": "76"} | {"c3": "AAA006"} | {"c1": "6", "c2": "7"} | {"c3": "AAA006"} | {"c1": "6", "c2": "7"} | {"c1": "6", "c2": "6", "c3": "0006"} + Sat Mar 28 00:00:00 1970 PST | {"c3": "00086"} | {"c2": "6", "c6": "6", "c7": "6 ", "c8": "foo", "C 1": "86"} | Sat Mar 28 00:00:00 1970 PST | {"c3": "00086"} | {"c2": "6", "c6": "6", "c7": "6 ", "c8": "foo", "C 1": "86"} | {"c3": "AAA006"} | {"c1": "6", "c2": "7"} | {"c3": "AAA006"} | {"c1": "6", "c2": "7"} | {"c1": "6", "c2": "6", "c3": "0006"} + Tue Apr 07 00:00:00 1970 PST | {"c3": "00096"} | {"c2": "6", "c6": "6", "c7": "6 ", "c8": "foo", "C 1": "96"} | Tue Apr 07 00:00:00 1970 PST | {"c3": "00096"} | {"c2": "6", "c6": "6", "c7": "6 ", "c8": "foo", "C 1": "96"} | {"c3": "AAA006"} | {"c1": "6", "c2": "7"} | {"c3": "AAA006"} | {"c1": "6", "c2": "7"} | {"c1": "6", "c2": "6", "c3": "0006"} +(10 rows) + +--Testcase 205: +RESET enable_nestloop; +--Testcase 206: +RESET enable_hashjoin; +-- test that add_paths_with_pathkeys_for_rel() arranges for the epq_path to +-- return columns needed by the parent ForeignScan node +--Testcase 867: +EXPLAIN (VERBOSE, COSTS OFF) +SELECT * FROM local_tbl LEFT JOIN (SELECT ft1.*, COALESCE(ft1.tags->>'c3' || (ft2.tags->>'c3')::text, 'foobar') FROM ft1 INNER JOIN ft2 ON (ft1.fields->>'C 1' = ft2.fields->>'C 1' AND (ft1.fields->>'C 1')::int < 100)) ss ON (local_tbl.fields->>'c1' = ss.fields->>'C 1') ORDER BY local_tbl.fields->>'c1' FOR UPDATE OF local_tbl; + QUERY PLAN +-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- + LockRows + Output: local_tbl.fields, ft1."time", ft1.tags, ft1.fields, (COALESCE(((ft1.tags ->> 'c3'::text) || (ft2.tags ->> 'c3'::text)), 'foobar'::text)), ((local_tbl.fields ->> 'c1'::text)), local_tbl.*, ft1.*, ft2.* + -> Merge Left Join + Output: local_tbl.fields, ft1."time", ft1.tags, ft1.fields, (COALESCE(((ft1.tags ->> 'c3'::text) || (ft2.tags ->> 'c3'::text)), 'foobar'::text)), ((local_tbl.fields ->> 'c1'::text)), local_tbl.*, ft1.*, ft2.* + Merge Cond: (((local_tbl.fields ->> 'c1'::text)) = ((ft1.fields ->> 'C 1'::text))) + -> Sort + Output: local_tbl.fields, local_tbl.*, ((local_tbl.fields ->> 'c1'::text)) + Sort Key: ((local_tbl.fields ->> 'c1'::text)) + -> Foreign Scan on public.local_tbl + Output: local_tbl.fields, local_tbl.*, (local_tbl.fields ->> 'c1'::text) + InfluxDB query: SELECT * FROM "local_tbl" + -> Sort + Output: ft1."time", ft1.tags, ft1.fields, ft1.*, ft2.*, (COALESCE(((ft1.tags ->> 'c3'::text) || (ft2.tags ->> 'c3'::text)), 'foobar'::text)), ((ft1.fields ->> 'C 1'::text)) + Sort Key: ((ft1.fields ->> 'C 1'::text)) + -> Hash Join + Output: ft1."time", ft1.tags, ft1.fields, ft1.*, ft2.*, COALESCE(((ft1.tags ->> 'c3'::text) || (ft2.tags ->> 'c3'::text)), 'foobar'::text), (ft1.fields ->> 'C 1'::text) + Hash Cond: ((ft2.fields ->> 'C 1'::text) = (ft1.fields ->> 'C 1'::text)) + -> Foreign Scan on public.ft2 + Output: ft2.*, ft2.fields, ft2.tags + InfluxDB query: SELECT * FROM "T1" + -> Hash + Output: ft1."time", ft1.tags, ft1.fields, ft1.* + -> Foreign Scan on public.ft1 + Output: ft1."time", ft1.tags, ft1.fields, ft1.* + InfluxDB query: SELECT * FROM "T1" WHERE (("C 1" < 100)) +(25 rows) + +-- ALTER SERVER loopback OPTIONS (DROP extensions); +-- ALTER SERVER loopback OPTIONS (ADD fdw_startup_cost '10000.0'); +--Testcase 868: +EXPLAIN (VERBOSE, COSTS OFF) +SELECT * FROM local_tbl LEFT JOIN (SELECT ft1.* FROM ft1 INNER JOIN ft2 ON ((ft1.fields->>'C 1')::int = (ft2.fields->>'C 1')::int AND (ft1.fields->>'C 1')::int < 100 AND ((ft1.fields->>'C 1')::int - influxdb_fdw_abs((ft2.fields->>'C 1')::int)) = 0)) ss ON (local_tbl.fields->>'c3' = ss.tags->>'c3') ORDER BY local_tbl.fields->>'c1' FOR UPDATE OF local_tbl; + QUERY PLAN +-------------------------------------------------------------------------------------------------------------------------------------------------------- + LockRows + Output: local_tbl.fields, ft1."time", ft1.tags, ft1.fields, ((local_tbl.fields ->> 'c1'::text)), local_tbl.*, ft1.*, ft2.* + -> Sort + Output: local_tbl.fields, ft1."time", ft1.tags, ft1.fields, ((local_tbl.fields ->> 'c1'::text)), local_tbl.*, ft1.*, ft2.* + Sort Key: ((local_tbl.fields ->> 'c1'::text)) + -> Hash Left Join + Output: local_tbl.fields, ft1."time", ft1.tags, ft1.fields, (local_tbl.fields ->> 'c1'::text), local_tbl.*, ft1.*, ft2.* + Hash Cond: ((local_tbl.fields ->> 'c3'::text) = (ft1.tags ->> 'c3'::text)) + -> Foreign Scan on public.local_tbl + Output: local_tbl.fields, local_tbl.* + InfluxDB query: SELECT * FROM "local_tbl" + -> Hash + Output: ft1."time", ft1.tags, ft1.fields, ft1.*, ft2.* + -> Merge Join + Output: ft1."time", ft1.tags, ft1.fields, ft1.*, ft2.* + Merge Cond: ((((ft1.fields ->> 'C 1'::text))::integer) = (((ft2.fields ->> 'C 1'::text))::integer)) + Join Filter: (((((ft1.fields ->> 'C 1'::text))::integer) - influxdb_fdw_abs((((ft2.fields ->> 'C 1'::text))::integer))) = 0) + -> Sort + Output: ft1."time", ft1.tags, ft1.fields, ft1.*, (((ft1.fields ->> 'C 1'::text))::integer) + Sort Key: (((ft1.fields ->> 'C 1'::text))::integer) + -> Foreign Scan on public.ft1 + Output: ft1."time", ft1.tags, ft1.fields, ft1.*, ((ft1.fields ->> 'C 1'::text))::integer + InfluxDB query: SELECT * FROM "T1" WHERE (("C 1" < 100)) + -> Sort + Output: ft2.*, ft2.fields, (((ft2.fields ->> 'C 1'::text))::integer) + Sort Key: (((ft2.fields ->> 'C 1'::text))::integer) + -> Foreign Scan on public.ft2 + Output: ft2.*, ft2.fields, ((ft2.fields ->> 'C 1'::text))::integer + InfluxDB query: SELECT * FROM "T1" +(29 rows) + +-- ALTER SERVER loopback OPTIONS (DROP fdw_startup_cost); +-- ALTER SERVER loopback OPTIONS (ADD extensions 'postgres_fdw'); +--Testcase 207: +DELETE FROM local_tbl_nsc; +--Testcase 795: +DROP FOREIGN TABLE local_tbl; +--Testcase 796: +DROP FOREIGN TABLE local_tbl_nsc; +-- check join pushdown in situations where multiple userids are involved +--Testcase 208: +CREATE ROLE regress_view_owner SUPERUSER; +--Testcase 209: +CREATE USER MAPPING FOR regress_view_owner SERVER influxdb_svr OPTIONS (:AUTHENTICATION); +GRANT SELECT ON ft4 TO regress_view_owner; +GRANT SELECT ON ft5 TO regress_view_owner; +--Testcase 210: +CREATE VIEW v4 AS SELECT * FROM ft4; +--Testcase 211: +CREATE VIEW v5 AS SELECT * FROM ft5; +--Testcase 212: +ALTER VIEW v5 OWNER TO regress_view_owner; +--Testcase 213: +EXPLAIN (VERBOSE, COSTS OFF) +SELECT t1.c1, t2.c2 FROM (SELECT (fields->>'c1')::int c1, (fields->>'c2')::int c2, tags->>'c3' c3 FROM v4 t1) t1 LEFT JOIN (SELECT (fields->>'c1')::int c1, (fields->>'c2')::int c2, tags->>'c3' c3 FROM v5 t2) t2 ON ((t1.c1)::int = (t2.c1)::int) ORDER BY (t1.c1)::int, (t2.c1)::int OFFSET 10 LIMIT 10; -- can't be pushed down, different view owners + QUERY PLAN +---------------------------------------------------------------------------------------------------------------------------------------------------------------------- + Limit + Output: (((ft4.fields ->> 'c1'::text))::integer), (((ft5.fields ->> 'c2'::text))::integer), (((ft5.fields ->> 'c1'::text))::integer) + -> Incremental Sort + Output: (((ft4.fields ->> 'c1'::text))::integer), (((ft5.fields ->> 'c2'::text))::integer), (((ft5.fields ->> 'c1'::text))::integer) + Sort Key: (((ft4.fields ->> 'c1'::text))::integer), (((ft5.fields ->> 'c1'::text))::integer) + Presorted Key: (((ft4.fields ->> 'c1'::text))::integer) + -> Merge Left Join + Output: (((ft4.fields ->> 'c1'::text))::integer), (((ft5.fields ->> 'c2'::text))::integer), (((ft5.fields ->> 'c1'::text))::integer) + Merge Cond: ((((ft4.fields ->> 'c1'::text))::integer) = (((ft5.fields ->> 'c1'::text))::integer)) + -> Sort + Output: ft4.fields, (((ft4.fields ->> 'c1'::text))::integer) + Sort Key: (((ft4.fields ->> 'c1'::text))::integer) + -> Foreign Scan on public.ft4 + Output: ft4.fields, ((ft4.fields ->> 'c1'::text))::integer + InfluxDB query: SELECT * FROM "T3" + -> Sort + Output: ft5.fields, (((ft5.fields ->> 'c2'::text))::integer), (((ft5.fields ->> 'c1'::text))::integer), (((ft5.fields ->> 'c1'::text))::integer) + Sort Key: (((ft5.fields ->> 'c1'::text))::integer) + -> Foreign Scan on public.ft5 + Output: ft5.fields, ((ft5.fields ->> 'c2'::text))::integer, ((ft5.fields ->> 'c1'::text))::integer, ((ft5.fields ->> 'c1'::text))::integer + InfluxDB query: SELECT * FROM "T4" +(21 rows) + +--Testcase 214: +SELECT t1.c1, t2.c2 FROM (SELECT (fields->>'c1')::int c1, (fields->>'c2')::int c2, tags->>'c3' c3 FROM v4 t1) t1 LEFT JOIN (SELECT (fields->>'c1')::int c1, (fields->>'c2')::int c2, tags->>'c3' c3 FROM v5 t2) t2 ON ((t1.c1)::int = (t2.c1)::int) ORDER BY (t1.c1)::int, (t2.c1)::int OFFSET 10 LIMIT 10; + c1 | c2 +----+---- + 22 | + 24 | 25 + 26 | + 28 | + 30 | 31 + 32 | + 34 | + 36 | 37 + 38 | + 40 | +(10 rows) + +--Testcase 215: +ALTER VIEW v4 OWNER TO regress_view_owner; +--Testcase 216: +EXPLAIN (VERBOSE, COSTS OFF) +SELECT t1.c1, t2.c2 FROM (SELECT (fields->>'c1')::int c1, (fields->>'c2')::int c2, tags->>'c3' c3 FROM v4 t1) t1 LEFT JOIN (SELECT (fields->>'c1')::int c1, (fields->>'c2')::int c2, tags->>'c3' c3 FROM v5 t2) t2 ON ((t1.c1)::int = (t2.c1)::int) ORDER BY (t1.c1)::int, (t2.c1)::int OFFSET 10 LIMIT 10; -- can be pushed down + QUERY PLAN +---------------------------------------------------------------------------------------------------------------------------------------------------------------------- + Limit + Output: (((ft4.fields ->> 'c1'::text))::integer), (((ft5.fields ->> 'c2'::text))::integer), (((ft5.fields ->> 'c1'::text))::integer) + -> Incremental Sort + Output: (((ft4.fields ->> 'c1'::text))::integer), (((ft5.fields ->> 'c2'::text))::integer), (((ft5.fields ->> 'c1'::text))::integer) + Sort Key: (((ft4.fields ->> 'c1'::text))::integer), (((ft5.fields ->> 'c1'::text))::integer) + Presorted Key: (((ft4.fields ->> 'c1'::text))::integer) + -> Merge Left Join + Output: (((ft4.fields ->> 'c1'::text))::integer), (((ft5.fields ->> 'c2'::text))::integer), (((ft5.fields ->> 'c1'::text))::integer) + Merge Cond: ((((ft4.fields ->> 'c1'::text))::integer) = (((ft5.fields ->> 'c1'::text))::integer)) + -> Sort + Output: ft4.fields, (((ft4.fields ->> 'c1'::text))::integer) + Sort Key: (((ft4.fields ->> 'c1'::text))::integer) + -> Foreign Scan on public.ft4 + Output: ft4.fields, ((ft4.fields ->> 'c1'::text))::integer + InfluxDB query: SELECT * FROM "T3" + -> Sort + Output: ft5.fields, (((ft5.fields ->> 'c2'::text))::integer), (((ft5.fields ->> 'c1'::text))::integer), (((ft5.fields ->> 'c1'::text))::integer) + Sort Key: (((ft5.fields ->> 'c1'::text))::integer) + -> Foreign Scan on public.ft5 + Output: ft5.fields, ((ft5.fields ->> 'c2'::text))::integer, ((ft5.fields ->> 'c1'::text))::integer, ((ft5.fields ->> 'c1'::text))::integer + InfluxDB query: SELECT * FROM "T4" +(21 rows) + +--Testcase 217: +SELECT t1.c1, t2.c2 FROM (SELECT (fields->>'c1')::int c1, (fields->>'c2')::int c2, tags->>'c3' c3 FROM v4 t1) t1 LEFT JOIN (SELECT (fields->>'c1')::int c1, (fields->>'c2')::int c2, tags->>'c3' c3 FROM v5 t2) t2 ON ((t1.c1)::int = (t2.c1)::int) ORDER BY (t1.c1)::int, (t2.c1)::int OFFSET 10 LIMIT 10; + c1 | c2 +----+---- + 22 | + 24 | 25 + 26 | + 28 | + 30 | 31 + 32 | + 34 | + 36 | 37 + 38 | + 40 | +(10 rows) + +--Testcase 218: +EXPLAIN (VERBOSE, COSTS OFF) +SELECT t1.c1, t2.c2 FROM (SELECT (fields->>'c1')::int c1, (fields->>'c2')::int c2, tags->>'c3' c3 FROM v4 t1) t1 LEFT JOIN (SELECT (fields->>'c1')::int c1, (fields->>'c2')::int c2, tags->>'c3' c3 FROM ft5 t2) t2 ON ((t1.c1)::int = (t2.c1)::int) ORDER BY (t1.c1)::int, (t2.c1)::int OFFSET 10 LIMIT 10; -- can't be pushed down, view owner not current user + QUERY PLAN +------------------------------------------------------------------------------------------------------------------------------------------------------------------ + Limit + Output: (((ft4.fields ->> 'c1'::text))::integer), (((t2.fields ->> 'c2'::text))::integer), (((t2.fields ->> 'c1'::text))::integer) + -> Incremental Sort + Output: (((ft4.fields ->> 'c1'::text))::integer), (((t2.fields ->> 'c2'::text))::integer), (((t2.fields ->> 'c1'::text))::integer) + Sort Key: (((ft4.fields ->> 'c1'::text))::integer), (((t2.fields ->> 'c1'::text))::integer) + Presorted Key: (((ft4.fields ->> 'c1'::text))::integer) + -> Merge Left Join + Output: (((ft4.fields ->> 'c1'::text))::integer), (((t2.fields ->> 'c2'::text))::integer), (((t2.fields ->> 'c1'::text))::integer) + Merge Cond: ((((ft4.fields ->> 'c1'::text))::integer) = (((t2.fields ->> 'c1'::text))::integer)) + -> Sort + Output: ft4.fields, (((ft4.fields ->> 'c1'::text))::integer) + Sort Key: (((ft4.fields ->> 'c1'::text))::integer) + -> Foreign Scan on public.ft4 + Output: ft4.fields, ((ft4.fields ->> 'c1'::text))::integer + InfluxDB query: SELECT * FROM "T3" + -> Sort + Output: t2.fields, (((t2.fields ->> 'c2'::text))::integer), (((t2.fields ->> 'c1'::text))::integer), (((t2.fields ->> 'c1'::text))::integer) + Sort Key: (((t2.fields ->> 'c1'::text))::integer) + -> Foreign Scan on public.ft5 t2 + Output: t2.fields, ((t2.fields ->> 'c2'::text))::integer, ((t2.fields ->> 'c1'::text))::integer, ((t2.fields ->> 'c1'::text))::integer + InfluxDB query: SELECT * FROM "T4" +(21 rows) + +--Testcase 219: +SELECT t1.c1, t2.c2 FROM (SELECT (fields->>'c1')::int c1, (fields->>'c2')::int c2, tags->>'c3' c3 FROM v4 t1) t1 LEFT JOIN (SELECT (fields->>'c1')::int c1, (fields->>'c2')::int c2, tags->>'c3' c3 FROM ft5 t2) t2 ON ((t1.c1)::int = (t2.c1)::int) ORDER BY (t1.c1)::int, (t2.c1)::int OFFSET 10 LIMIT 10; + c1 | c2 +----+---- + 22 | + 24 | 25 + 26 | + 28 | + 30 | 31 + 32 | + 34 | + 36 | 37 + 38 | + 40 | +(10 rows) + +--Testcase 220: +ALTER VIEW v4 OWNER TO CURRENT_USER; +--Testcase 221: +EXPLAIN (VERBOSE, COSTS OFF) +SELECT t1.c1, t2.c2 FROM (SELECT (fields->>'c1')::int c1, (fields->>'c2')::int c2, tags->>'c3' c3 FROM v4 t1) t1 LEFT JOIN (SELECT (fields->>'c1')::int c1, (fields->>'c2')::int c2, tags->>'c3' c3 FROM ft5 t2) t2 ON ((t1.c1)::int = (t2.c1)::int) ORDER BY (t1.c1)::int, (t2.c1)::int OFFSET 10 LIMIT 10; -- can be pushed down + QUERY PLAN +------------------------------------------------------------------------------------------------------------------------------------------------------------------ + Limit + Output: (((ft4.fields ->> 'c1'::text))::integer), (((t2.fields ->> 'c2'::text))::integer), (((t2.fields ->> 'c1'::text))::integer) + -> Incremental Sort + Output: (((ft4.fields ->> 'c1'::text))::integer), (((t2.fields ->> 'c2'::text))::integer), (((t2.fields ->> 'c1'::text))::integer) + Sort Key: (((ft4.fields ->> 'c1'::text))::integer), (((t2.fields ->> 'c1'::text))::integer) + Presorted Key: (((ft4.fields ->> 'c1'::text))::integer) + -> Merge Left Join + Output: (((ft4.fields ->> 'c1'::text))::integer), (((t2.fields ->> 'c2'::text))::integer), (((t2.fields ->> 'c1'::text))::integer) + Merge Cond: ((((ft4.fields ->> 'c1'::text))::integer) = (((t2.fields ->> 'c1'::text))::integer)) + -> Sort + Output: ft4.fields, (((ft4.fields ->> 'c1'::text))::integer) + Sort Key: (((ft4.fields ->> 'c1'::text))::integer) + -> Foreign Scan on public.ft4 + Output: ft4.fields, ((ft4.fields ->> 'c1'::text))::integer + InfluxDB query: SELECT * FROM "T3" + -> Sort + Output: t2.fields, (((t2.fields ->> 'c2'::text))::integer), (((t2.fields ->> 'c1'::text))::integer), (((t2.fields ->> 'c1'::text))::integer) + Sort Key: (((t2.fields ->> 'c1'::text))::integer) + -> Foreign Scan on public.ft5 t2 + Output: t2.fields, ((t2.fields ->> 'c2'::text))::integer, ((t2.fields ->> 'c1'::text))::integer, ((t2.fields ->> 'c1'::text))::integer + InfluxDB query: SELECT * FROM "T4" +(21 rows) + +--Testcase 222: +SELECT t1.c1, t2.c2 FROM (SELECT (fields->>'c1')::int c1, (fields->>'c2')::int c2, tags->>'c3' c3 FROM v4 t1) t1 LEFT JOIN (SELECT (fields->>'c1')::int c1, (fields->>'c2')::int c2, tags->>'c3' c3 FROM ft5 t2) t2 ON ((t1.c1)::int = (t2.c1)::int) ORDER BY (t1.c1)::int, (t2.c1)::int OFFSET 10 LIMIT 10; + c1 | c2 +----+---- + 22 | + 24 | 25 + 26 | + 28 | + 30 | 31 + 32 | + 34 | + 36 | 37 + 38 | + 40 | +(10 rows) + +--Testcase 223: +ALTER VIEW v4 OWNER TO regress_view_owner; +-- ==================================================================== +-- Check that userid to use when querying the remote table is correctly +-- propagated into foreign rels present in subqueries under an UNION ALL +-- ==================================================================== +CREATE ROLE regress_view_owner_another; +ALTER VIEW v4 OWNER TO regress_view_owner_another; +GRANT SELECT ON ft4 TO regress_view_owner_another; +-- ALTER FOREIGN TABLE ft4 OPTIONS (ADD use_remote_estimate 'true'); +-- The following should query the remote backing table of ft4 as user +-- regress_view_owner_another, the view owner, though it fails as expected +-- due to the lack of a user mapping for that user. +EXPLAIN (VERBOSE, COSTS OFF) SELECT * FROM v4; +ERROR: user mapping not found for "regress_view_owner_another" +-- Likewise, but with the query under an UNION ALL +EXPLAIN (VERBOSE, COSTS OFF) SELECT * FROM (SELECT * FROM v4 UNION ALL SELECT * FROM v4); +ERROR: user mapping not found for "regress_view_owner_another" +-- Should not get that error once a user mapping is created +CREATE USER MAPPING FOR regress_view_owner_another SERVER influxdb_svr OPTIONS (:AUTHENTICATION); +EXPLAIN (VERBOSE, COSTS OFF) SELECT * FROM v4; + QUERY PLAN +-------------------------------------- + Foreign Scan on public.ft4 + Output: ft4.tags, ft4.fields + InfluxDB query: SELECT * FROM "T3" +(3 rows) + +EXPLAIN (VERBOSE, COSTS OFF) SELECT * FROM (SELECT * FROM v4 UNION ALL SELECT * FROM v4); + QUERY PLAN +-------------------------------------------- + Append + -> Foreign Scan on public.ft4 + Output: ft4.tags, ft4.fields + InfluxDB query: SELECT * FROM "T3" + -> Foreign Scan on public.ft4 ft4_1 + Output: ft4_1.tags, ft4_1.fields + InfluxDB query: SELECT * FROM "T3" +(7 rows) + +DROP USER MAPPING FOR regress_view_owner_another SERVER influxdb_svr; +DROP OWNED BY regress_view_owner_another; +DROP ROLE regress_view_owner_another; +-- ALTER FOREIGN TABLE ft4 OPTIONS (SET use_remote_estimate 'false'); +-- cleanup +--Testcase 224: +DROP OWNED BY regress_view_owner; +--Testcase 225: +DROP ROLE regress_view_owner; +-- =================================================================== +-- Aggregate and grouping queries +-- =================================================================== +-- Simple aggregates +--Testcase 226: +explain (verbose, costs off) +select count(fields->>'c6'), sum((fields->>'C 1')::int), avg((fields->>'C 1')::int), min((fields->>'c2')::int), max((fields->>'C 1')::int), stddev((fields->>'c2')::int), sum((fields->>'C 1')::int) * (random() <= 1)::int as sum2 from ft1 where (fields->>'c2')::int < 5 group by fields->>'c2' order by 1, 2; + QUERY PLAN +------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- + Result + Output: (count((fields ->> 'c6'::text))), (sum(((fields ->> 'C 1'::text))::integer)), (avg(((fields ->> 'C 1'::text))::integer)), (min((((fields ->> 'c2'::text)))::integer)), (max(((fields ->> 'C 1'::text))::integer)), (stddev((((fields ->> 'c2'::text)))::integer)), ((sum(((fields ->> 'C 1'::text))::integer)) * ((random() <= '1'::double precision))::integer), ((fields ->> 'c2'::text)) + -> Sort + Output: (count((fields ->> 'c6'::text))), (sum(((fields ->> 'C 1'::text))::integer)), (avg(((fields ->> 'C 1'::text))::integer)), (min((((fields ->> 'c2'::text)))::integer)), (max(((fields ->> 'C 1'::text))::integer)), (stddev((((fields ->> 'c2'::text)))::integer)), ((fields ->> 'c2'::text)) + Sort Key: (count((ft1.fields ->> 'c6'::text))), (sum(((ft1.fields ->> 'C 1'::text))::integer)) + -> HashAggregate + Output: count((fields ->> 'c6'::text)), sum(((fields ->> 'C 1'::text))::integer), avg(((fields ->> 'C 1'::text))::integer), min((((fields ->> 'c2'::text)))::integer), max(((fields ->> 'C 1'::text))::integer), stddev((((fields ->> 'c2'::text)))::integer), ((fields ->> 'c2'::text)) + Group Key: (ft1.fields ->> 'c2'::text) + -> Foreign Scan on public.ft1 + Output: (fields ->> 'c2'::text), fields + InfluxDB query: SELECT * FROM "T1" WHERE (("c2" < 5)) +(11 rows) + +--Testcase 227: +select count(fields->>'c6'), sum((fields->>'C 1')::int), avg((fields->>'C 1')::int), min((fields->>'c2')::int), max((fields->>'C 1')::int), stddev((fields->>'c2')::int), sum((fields->>'C 1')::int) * (random() <= 1)::int as sum2 from ft1 where (fields->>'c2')::int < 5 group by fields->>'c2' order by 1, 2; + count | sum | avg | min | max | stddev | sum2 +-------+-------+----------------------+-----+------+--------+------- + 100 | 49600 | 496.0000000000000000 | 1 | 991 | 0 | 49600 + 100 | 49700 | 497.0000000000000000 | 2 | 992 | 0 | 49700 + 100 | 49800 | 498.0000000000000000 | 3 | 993 | 0 | 49800 + 100 | 49900 | 499.0000000000000000 | 4 | 994 | 0 | 49900 + 100 | 50500 | 505.0000000000000000 | 0 | 1000 | 0 | 50500 +(5 rows) + +--Testcase 228: +explain (verbose, costs off) +select count(fields->>'c6'), sum((fields->>'C 1')::int), avg((fields->>'C 1')::int), min((fields->>'c2')::int), max((fields->>'C 1')::int), stddev((fields->>'c2')::int), sum((fields->>'C 1')::int) * (random() <= 1)::int as sum2 from ft1 where (fields->>'c2')::int < 5 group by fields->>'c2' order by 1, 2 limit 1; + QUERY PLAN +------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- + Limit + Output: (count((fields ->> 'c6'::text))), (sum(((fields ->> 'C 1'::text))::integer)), (avg(((fields ->> 'C 1'::text))::integer)), (min((((fields ->> 'c2'::text)))::integer)), (max(((fields ->> 'C 1'::text))::integer)), (stddev((((fields ->> 'c2'::text)))::integer)), (((sum(((fields ->> 'C 1'::text))::integer)) * ((random() <= '1'::double precision))::integer)), ((fields ->> 'c2'::text)) + -> Result + Output: (count((fields ->> 'c6'::text))), (sum(((fields ->> 'C 1'::text))::integer)), (avg(((fields ->> 'C 1'::text))::integer)), (min((((fields ->> 'c2'::text)))::integer)), (max(((fields ->> 'C 1'::text))::integer)), (stddev((((fields ->> 'c2'::text)))::integer)), ((sum(((fields ->> 'C 1'::text))::integer)) * ((random() <= '1'::double precision))::integer), ((fields ->> 'c2'::text)) + -> Sort + Output: (count((fields ->> 'c6'::text))), (sum(((fields ->> 'C 1'::text))::integer)), (avg(((fields ->> 'C 1'::text))::integer)), (min((((fields ->> 'c2'::text)))::integer)), (max(((fields ->> 'C 1'::text))::integer)), (stddev((((fields ->> 'c2'::text)))::integer)), ((fields ->> 'c2'::text)) + Sort Key: (count((ft1.fields ->> 'c6'::text))), (sum(((ft1.fields ->> 'C 1'::text))::integer)) + -> HashAggregate + Output: count((fields ->> 'c6'::text)), sum(((fields ->> 'C 1'::text))::integer), avg(((fields ->> 'C 1'::text))::integer), min((((fields ->> 'c2'::text)))::integer), max(((fields ->> 'C 1'::text))::integer), stddev((((fields ->> 'c2'::text)))::integer), ((fields ->> 'c2'::text)) + Group Key: (ft1.fields ->> 'c2'::text) + -> Foreign Scan on public.ft1 + Output: (fields ->> 'c2'::text), fields + InfluxDB query: SELECT * FROM "T1" WHERE (("c2" < 5)) +(13 rows) + +--Testcase 229: +select count(fields->>'c6'), sum((fields->>'C 1')::int), avg((fields->>'C 1')::int), min((fields->>'c2')::int), max((fields->>'C 1')::int), stddev((fields->>'c2')::int), sum((fields->>'C 1')::int) * (random() <= 1)::int as sum2 from ft1 where (fields->>'c2')::int < 5 group by fields->>'c2' order by 1, 2 limit 1; + count | sum | avg | min | max | stddev | sum2 +-------+-------+----------------------+-----+-----+--------+------- + 100 | 49600 | 496.0000000000000000 | 1 | 991 | 0 | 49600 +(1 row) + +-- Aggregate is not pushed down as aggregation contains random() +--Testcase 230: +explain (verbose, costs off) +select sum((fields->>'C 1')::int * (random() <= 1)::int) as sum, avg((fields->>'C 1')::int) from ft1; + QUERY PLAN +------------------------------------------------------------------------------------------------------------------------------------------------- + Aggregate + Output: sum((((fields ->> 'C 1'::text))::integer * ((random() <= '1'::double precision))::integer)), avg(((fields ->> 'C 1'::text))::integer) + -> Foreign Scan on public.ft1 + Output: "time", tags, fields + InfluxDB query: SELECT * FROM "T1" +(5 rows) + +-- Aggregate over join query +--Testcase 231: +explain (verbose, costs off) +select count(*), sum((t1.c1)::int), avg((t2.c1)::int) from (SELECT (fields->>'C 1')::int c1, (fields->>'c2')::int c2, tags->>'c3' c3, fields->>'c4' c4, fields->>'c5' c5, fields->>'c6' c6, fields->>'c7' c7, fields->>'c8' c8 FROM ft1 t1) t1 inner join (SELECT (fields->>'C 1')::int c1, (fields->>'c2')::int c2, tags->>'c3' c3, fields->>'c4' c4, fields->>'c5' c5, fields->>'c6' c6, fields->>'c7' c7, fields->>'c8' c8 FROM ft1 t2) t2 on ((t1.c2)::int = (t2.c2)::int) where (t1.c2)::int = 6; + QUERY PLAN +-------------------------------------------------------------------------------------------------------------- + Aggregate + Output: count(*), sum(((t1.fields ->> 'C 1'::text))::integer), avg(((t2.fields ->> 'C 1'::text))::integer) + -> Nested Loop + Output: t1.fields, t2.fields + -> Foreign Scan on public.ft1 t1 + Output: t1."time", t1.tags, t1.fields + InfluxDB query: SELECT * FROM "T1" WHERE (("c2" = 6)) + -> Materialize + Output: t2.fields + -> Foreign Scan on public.ft1 t2 + Output: t2.fields + InfluxDB query: SELECT * FROM "T1" WHERE (("c2" = 6)) +(12 rows) + +--Testcase 232: +select count(*), sum((t1.c1)::int), avg((t2.c1)::int) from (SELECT (fields->>'C 1')::int c1, (fields->>'c2')::int c2, tags->>'c3' c3, fields->>'c4' c4, fields->>'c5' c5, fields->>'c6' c6, fields->>'c7' c7, fields->>'c8' c8 FROM ft1 t1) t1 inner join (SELECT (fields->>'C 1')::int c1, (fields->>'c2')::int c2, tags->>'c3' c3, fields->>'c4' c4, fields->>'c5' c5, fields->>'c6' c6, fields->>'c7' c7, fields->>'c8' c8 FROM ft1 t2) t2 on ((t1.c2)::int = (t2.c2)::int) where (t1.c2)::int = 6; + count | sum | avg +-------+---------+---------------------- + 10000 | 5010000 | 501.0000000000000000 +(1 row) + +-- Not pushed down due to local conditions present in underneath input rel +--Testcase 233: +explain (verbose, costs off) +select sum((t1.c1)::int), count((t2.c1)::int) from (SELECT (fields->>'C 1')::int c1, (fields->>'c2')::int c2, tags->>'c3' c3, fields->>'c4' c4, fields->>'c5' c5, fields->>'c6' c6, fields->>'c7' c7, fields->>'c8' c8 FROM ft1 t1) t1 inner join (SELECT (fields->>'C 1')::int c1, (fields->>'c2')::int c2, tags->>'c3' c3, fields->>'c4' c4, fields->>'c5' c5, fields->>'c6' c6, fields->>'c7' c7, fields->>'c8' c8 FROM ft2 t2) t2 on ((t1.c1)::int = (t2.c1)::int) where (((t1.c1)::int * (t2.c1)::int)/((t1.c1)::int * (t2.c1)::int)) * random() <= 1; + QUERY PLAN +------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ + Aggregate + Output: sum(((t1.fields ->> 'C 1'::text))::integer), count(((t2.fields ->> 'C 1'::text))::integer) + -> Merge Join + Output: t1.fields, t2.fields + Merge Cond: ((((t1.fields ->> 'C 1'::text))::integer) = (((t2.fields ->> 'C 1'::text))::integer)) + Join Filter: ((((((((t1.fields ->> 'C 1'::text))::integer) * (((t2.fields ->> 'C 1'::text))::integer)) / ((((t1.fields ->> 'C 1'::text))::integer) * (((t2.fields ->> 'C 1'::text))::integer))))::double precision * random()) <= '1'::double precision) + -> Sort + Output: t1.fields, (((t1.fields ->> 'C 1'::text))::integer) + Sort Key: (((t1.fields ->> 'C 1'::text))::integer) + -> Foreign Scan on public.ft1 t1 + Output: t1.fields, ((t1.fields ->> 'C 1'::text))::integer + InfluxDB query: SELECT * FROM "T1" + -> Sort + Output: t2.fields, (((t2.fields ->> 'C 1'::text))::integer) + Sort Key: (((t2.fields ->> 'C 1'::text))::integer) + -> Foreign Scan on public.ft2 t2 + Output: t2.fields, ((t2.fields ->> 'C 1'::text))::integer + InfluxDB query: SELECT * FROM "T1" +(18 rows) + +-- GROUP BY clause having expressions +--Testcase 234: +explain (verbose, costs off) +select (fields->>'c2')::int/2, sum((fields->>'c2')::int) * ((fields->>'c2')::int/2) from ft1 group by (fields->>'c2')::int/2 order by (fields->>'c2')::int/2; + QUERY PLAN +---------------------------------------------------------------------------------------------------------------------------------------------------- + Sort + Output: ((((fields ->> 'c2'::text))::integer / 2)), ((sum(((fields ->> 'c2'::text))::integer) * ((((fields ->> 'c2'::text))::integer / 2)))) + Sort Key: ((((ft1.fields ->> 'c2'::text))::integer / 2)) + -> HashAggregate + Output: ((((fields ->> 'c2'::text))::integer / 2)), (sum(((fields ->> 'c2'::text))::integer) * ((((fields ->> 'c2'::text))::integer / 2))) + Group Key: (((ft1.fields ->> 'c2'::text))::integer / 2) + -> Foreign Scan on public.ft1 + Output: (((fields ->> 'c2'::text))::integer / 2), fields + InfluxDB query: SELECT * FROM "T1" +(9 rows) + +--Testcase 235: +select (fields->>'c2')::int/2, sum((fields->>'c2')::int) * ((fields->>'c2')::int/2) from ft1 group by (fields->>'c2')::int/2 order by (fields->>'c2')::int/2; + ?column? | ?column? +----------+---------- + 0 | 0 + 1 | 500 + 2 | 1800 + 3 | 3900 + 4 | 6800 +(5 rows) + +-- Aggregates in subquery are pushed down. +set enable_incremental_sort = off; +--Testcase 236: +explain (verbose, costs off) +select count(x.a), sum(x.a) from (select (fields->>'c2')::int a, sum((fields->>'C 1')::int) b from ft1 group by fields->>'c2', sqrt((fields->>'C 1')::int) order by 1, 2) x; + QUERY PLAN +------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ + Aggregate + Output: count(((((ft1.fields ->> 'c2'::text)))::integer)), sum(((((ft1.fields ->> 'c2'::text)))::integer)) + -> Sort + Output: ((((ft1.fields ->> 'c2'::text)))::integer), (sum(((ft1.fields ->> 'C 1'::text))::integer)), ((ft1.fields ->> 'c2'::text)), (sqrt((((ft1.fields ->> 'C 1'::text))::integer)::double precision)) + Sort Key: ((((ft1.fields ->> 'c2'::text)))::integer), (sum(((ft1.fields ->> 'C 1'::text))::integer)) + -> HashAggregate + Output: (((ft1.fields ->> 'c2'::text)))::integer, sum(((ft1.fields ->> 'C 1'::text))::integer), ((ft1.fields ->> 'c2'::text)), (sqrt((((ft1.fields ->> 'C 1'::text))::integer)::double precision)) + Group Key: (ft1.fields ->> 'c2'::text), sqrt((((ft1.fields ->> 'C 1'::text))::integer)::double precision) + -> Foreign Scan on public.ft1 + Output: (ft1.fields ->> 'c2'::text), sqrt((((ft1.fields ->> 'C 1'::text))::integer)::double precision), ft1.fields + InfluxDB query: SELECT * FROM "T1" +(11 rows) + +--Testcase 237: +select count(x.a), sum(x.a) from (select (fields->>'c2')::int a, sum((fields->>'C 1')::int) b from ft1 group by fields->>'c2', sqrt((fields->>'C 1')::int) order by 1, 2) x; + count | sum +-------+------ + 1000 | 4500 +(1 row) + +reset enable_incremental_sort; +-- Aggregate is still pushed down by taking unshippable expression out +--Testcase 238: +explain (verbose, costs off) +select (fields->>'c2')::int * (random() <= 1)::int as sum1, sum((fields->>'C 1')::int) * (fields->>'c2')::int as sum2 from ft1 group by fields->>'c2' order by 1, 2; + QUERY PLAN +----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- + Sort + Output: (((((fields ->> 'c2'::text)))::integer * ((random() <= '1'::double precision))::integer)), ((sum(((fields ->> 'C 1'::text))::integer) * (((fields ->> 'c2'::text)))::integer)), ((fields ->> 'c2'::text)) + Sort Key: (((((ft1.fields ->> 'c2'::text)))::integer * ((random() <= '1'::double precision))::integer)), ((sum(((ft1.fields ->> 'C 1'::text))::integer) * (((ft1.fields ->> 'c2'::text)))::integer)) + -> HashAggregate + Output: ((((fields ->> 'c2'::text)))::integer * ((random() <= '1'::double precision))::integer), (sum(((fields ->> 'C 1'::text))::integer) * (((fields ->> 'c2'::text)))::integer), ((fields ->> 'c2'::text)) + Group Key: (ft1.fields ->> 'c2'::text) + -> Foreign Scan on public.ft1 + Output: (fields ->> 'c2'::text), fields + InfluxDB query: SELECT * FROM "T1" +(9 rows) + +--Testcase 239: +select (fields->>'c2')::int * (random() <= 1)::int as sum1, sum((fields->>'C 1')::int) * (fields->>'c2')::int as sum2 from ft1 group by fields->>'c2' order by 1, 2; + sum1 | sum2 +------+-------- + 0 | 0 + 1 | 49600 + 2 | 99400 + 3 | 149400 + 4 | 199600 + 5 | 250000 + 6 | 300600 + 7 | 351400 + 8 | 402400 + 9 | 453600 +(10 rows) + +-- Aggregate with unshippable GROUP BY clause are not pushed +--Testcase 240: +explain (verbose, costs off) +select (fields->>'c2')::int * (random() <= 1)::int as c2 from ft2 group by (fields->>'c2')::int * (random() <= 1)::int order by 1; + QUERY PLAN +-------------------------------------------------------------------------------------------------------------- + Sort + Output: ((((fields ->> 'c2'::text))::integer * ((random() <= '1'::double precision))::integer)) + Sort Key: ((((ft2.fields ->> 'c2'::text))::integer * ((random() <= '1'::double precision))::integer)) + -> HashAggregate + Output: ((((fields ->> 'c2'::text))::integer * ((random() <= '1'::double precision))::integer)) + Group Key: (((ft2.fields ->> 'c2'::text))::integer * ((random() <= '1'::double precision))::integer) + -> Foreign Scan on public.ft2 + Output: (((fields ->> 'c2'::text))::integer * ((random() <= '1'::double precision))::integer) + InfluxDB query: SELECT "c2" FROM "T1" +(9 rows) + +-- GROUP BY clause in various forms, cardinal, alias and constant expression +--Testcase 241: +explain (verbose, costs off) +select count(fields->>'c2') w, fields->>'c2' x, 5 y, 7.0 z from ft1 group by 2, y, 9.0::int order by 2; + QUERY PLAN +---------------------------------------------------------------------------------------- + Sort + Output: (count(((fields ->> 'c2'::text)))), ((fields ->> 'c2'::text)), 5, 7.0, 9 + Sort Key: ((ft1.fields ->> 'c2'::text)) + -> HashAggregate + Output: count(((fields ->> 'c2'::text))), ((fields ->> 'c2'::text)), 5, 7.0, 9 + Group Key: (ft1.fields ->> 'c2'::text) + -> Foreign Scan on public.ft1 + Output: (fields ->> 'c2'::text), fields + InfluxDB query: SELECT * FROM "T1" +(9 rows) + +--Testcase 242: +select count(fields->>'c2') w, fields->>'c2' x, 5 y, 7.0 z from ft1 group by 2, y, 9.0::int order by 2; + w | x | y | z +-----+---+---+----- + 100 | 0 | 5 | 7.0 + 100 | 1 | 5 | 7.0 + 100 | 2 | 5 | 7.0 + 100 | 3 | 5 | 7.0 + 100 | 4 | 5 | 7.0 + 100 | 5 | 5 | 7.0 + 100 | 6 | 5 | 7.0 + 100 | 7 | 5 | 7.0 + 100 | 8 | 5 | 7.0 + 100 | 9 | 5 | 7.0 +(10 rows) + +-- GROUP BY clause referring to same column multiple times +-- Also, ORDER BY contains an aggregate function +--Testcase 243: +explain (verbose, costs off) +select (fields->>'c2')::int c2, (fields->>'c2')::int c2 from ft1 where (fields->>'c2')::int > 6 group by 1, 2 order by sum((fields->>'C 1')::int); + QUERY PLAN +-------------------------------------------------------------------------------------------------------------------------------------- + Sort + Output: (((fields ->> 'c2'::text))::integer), (((fields ->> 'c2'::text))::integer), (sum(((fields ->> 'C 1'::text))::integer)) + Sort Key: (sum(((ft1.fields ->> 'C 1'::text))::integer)) + -> HashAggregate + Output: (((fields ->> 'c2'::text))::integer), (((fields ->> 'c2'::text))::integer), sum(((fields ->> 'C 1'::text))::integer) + Group Key: ((ft1.fields ->> 'c2'::text))::integer + -> Foreign Scan on public.ft1 + Output: ((fields ->> 'c2'::text))::integer, fields + InfluxDB query: SELECT * FROM "T1" WHERE (("c2" > 6)) +(9 rows) + +--Testcase 244: +select (fields->>'c2')::int c2, (fields->>'c2')::int c2 from ft1 where (fields->>'c2')::int > 6 group by 1, 2 order by sum((fields->>'C 1')::int); + c2 | c2 +----+---- + 7 | 7 + 8 | 8 + 9 | 9 +(3 rows) + +-- Testing HAVING clause shippability +--Testcase 245: +explain (verbose, costs off) +select(fields->>'c2')::int c2, sum((fields->>'C 1')::int) from ft2 group by fields->>'c2' having avg((fields->>'C 1')::int) < 500 and sum((fields->>'C 1')::int) < 49800 order by (fields->>'c2')::int; + QUERY PLAN +---------------------------------------------------------------------------------------------------------------------------------------------- + Sort + Output: ((((fields ->> 'c2'::text)))::integer), (sum(((fields ->> 'C 1'::text))::integer)), ((fields ->> 'c2'::text)) + Sort Key: ((((ft2.fields ->> 'c2'::text)))::integer) + -> HashAggregate + Output: (((fields ->> 'c2'::text)))::integer, sum(((fields ->> 'C 1'::text))::integer), ((fields ->> 'c2'::text)) + Group Key: (ft2.fields ->> 'c2'::text) + Filter: ((avg(((ft2.fields ->> 'C 1'::text))::integer) < '500'::numeric) AND (sum(((ft2.fields ->> 'C 1'::text))::integer) < 49800)) + -> Foreign Scan on public.ft2 + Output: (fields ->> 'c2'::text), fields + InfluxDB query: SELECT * FROM "T1" +(10 rows) + +--Testcase 246: +select(fields->>'c2')::int c2, sum((fields->>'C 1')::int) from ft2 group by fields->>'c2' having avg((fields->>'C 1')::int) < 500 and sum((fields->>'C 1')::int) < 49800 order by (fields->>'c2')::int; + c2 | sum +----+------- + 1 | 49600 + 2 | 49700 +(2 rows) + +-- Unshippable HAVING clause will be evaluated locally, and other qual in HAVING clause is pushed down +--Testcase 247: +explain (verbose, costs off) +select count(*) from (select time, count((fields->>'C 1')::int) from ft1 group by time, sqrt((fields->>'c2')::int) having (avg((fields->>'C 1')::int) / avg((fields->>'C 1')::int)) * random() <= 1 and avg((fields->>'C 1')::int) < 500) x; + QUERY PLAN +------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- + Aggregate + Output: count(*) + -> HashAggregate + Output: ft1."time", NULL::bigint, (sqrt((((ft1.fields ->> 'c2'::text))::integer)::double precision)) + Group Key: ft1."time", sqrt((((ft1.fields ->> 'c2'::text))::integer)::double precision) + Filter: ((avg(((ft1.fields ->> 'C 1'::text))::integer) < '500'::numeric) AND ((((avg(((ft1.fields ->> 'C 1'::text))::integer) / avg(((ft1.fields ->> 'C 1'::text))::integer)))::double precision * random()) <= '1'::double precision)) + -> Foreign Scan on public.ft1 + Output: ft1."time", sqrt((((ft1.fields ->> 'c2'::text))::integer)::double precision), ft1.fields + InfluxDB query: SELECT * FROM "T1" +(9 rows) + +--Testcase 248: +select count(*) from (select time, count((fields->>'C 1')::int) from ft1 group by time, sqrt((fields->>'c2')::int) having (avg((fields->>'C 1')::int) / avg((fields->>'C 1')::int)) * random() <= 1 and avg((fields->>'C 1')::int) < 500) x; + count +------- + 49 +(1 row) + +-- Aggregate in HAVING clause is not pushable, and thus aggregation is not pushed down +--Testcase 249: +explain (verbose, costs off) +select sum((fields->>'C 1')::int) from ft1 group by fields->>'c2' having avg((fields->>'C 1')::int * (random() <= 1)::int) > 100 order by 1; + QUERY PLAN +------------------------------------------------------------------------------------------------------------------------------------ + Sort + Output: (sum(((fields ->> 'C 1'::text))::integer)), ((fields ->> 'c2'::text)) + Sort Key: (sum(((ft1.fields ->> 'C 1'::text))::integer)) + -> HashAggregate + Output: sum(((fields ->> 'C 1'::text))::integer), ((fields ->> 'c2'::text)) + Group Key: (ft1.fields ->> 'c2'::text) + Filter: (avg((((ft1.fields ->> 'C 1'::text))::integer * ((random() <= '1'::double precision))::integer)) > '100'::numeric) + -> Foreign Scan on public.ft1 + Output: (fields ->> 'c2'::text), fields + InfluxDB query: SELECT * FROM "T1" +(10 rows) + +-- Remote aggregate in combination with a local Param (for the output +-- of an initplan) can be trouble, per bug #15781 +--Testcase 250: +explain (verbose, costs off) +select exists(select 1 from pg_enum), sum((fields->>'C 1')::int) from ft1; + QUERY PLAN +-------------------------------------------------------------- + Foreign Scan + Output: $0, (sum(((ft1.fields ->> 'C 1'::text))::integer)) + InfluxDB query: SELECT sum("C 1") FROM "T1" + InitPlan 1 (returns $0) + -> Seq Scan on pg_catalog.pg_enum +(5 rows) + +--Testcase 251: +select exists(select 1 from pg_enum), sum((fields->>'C 1')::int) from ft1; + exists | sum +--------+-------- + t | 500500 +(1 row) + +--Testcase 252: +explain (verbose, costs off) +select exists(select 1 from pg_enum), sum((fields->>'C 1')::int) from ft1 group by 1; + QUERY PLAN +------------------------------------------------------------ + GroupAggregate + Output: $0, sum(((ft1.fields ->> 'C 1'::text))::integer) + InitPlan 1 (returns $0) + -> Seq Scan on pg_catalog.pg_enum + -> Foreign Scan on public.ft1 + Output: ft1."time", ft1.tags, ft1.fields + InfluxDB query: SELECT * FROM "T1" +(7 rows) + +--Testcase 253: +select exists(select 1 from pg_enum), sum((fields->>'C 1')::int) from ft1 group by 1; + exists | sum +--------+-------- + t | 500500 +(1 row) + +-- Testing ORDER BY, DISTINCT, FILTER, Ordered-sets and VARIADIC within aggregates +-- ORDER BY within aggregate, same column used to order +--Testcase 254: +explain (verbose, costs off) +select array_agg((fields->>'C 1')::int order by (fields->>'C 1')::int) from ft1 where (fields->>'C 1')::int < 100 group by fields->>'c2' order by 1; + QUERY PLAN +-------------------------------------------------------------------------------------------------------------------------------------------- + Sort + Output: (array_agg((((fields ->> 'C 1'::text))::integer) ORDER BY (((fields ->> 'C 1'::text))::integer))), ((fields ->> 'c2'::text)) + Sort Key: (array_agg((((ft1.fields ->> 'C 1'::text))::integer) ORDER BY (((ft1.fields ->> 'C 1'::text))::integer))) + -> GroupAggregate + Output: array_agg((((fields ->> 'C 1'::text))::integer) ORDER BY (((fields ->> 'C 1'::text))::integer)), ((fields ->> 'c2'::text)) + Group Key: ((ft1.fields ->> 'c2'::text)) + -> Sort + Output: ((fields ->> 'c2'::text)), fields, (((fields ->> 'C 1'::text))::integer) + Sort Key: ((ft1.fields ->> 'c2'::text)), (((ft1.fields ->> 'C 1'::text))::integer) + -> Foreign Scan on public.ft1 + Output: (fields ->> 'c2'::text), fields, ((fields ->> 'C 1'::text))::integer + InfluxDB query: SELECT * FROM "T1" WHERE (("C 1" < 100)) +(12 rows) + +--Testcase 255: +select array_agg((fields->>'C 1')::int order by (fields->>'C 1')::int) from ft1 where (fields->>'C 1')::int < 100 group by fields->>'c2' order by 1; + array_agg +-------------------------------- + {1,11,21,31,41,51,61,71,81,91} + {2,12,22,32,42,52,62,72,82,92} + {3,13,23,33,43,53,63,73,83,93} + {4,14,24,34,44,54,64,74,84,94} + {5,15,25,35,45,55,65,75,85,95} + {6,16,26,36,46,56,66,76,86,96} + {7,17,27,37,47,57,67,77,87,97} + {8,18,28,38,48,58,68,78,88,98} + {9,19,29,39,49,59,69,79,89,99} + {10,20,30,40,50,60,70,80,90} +(10 rows) + +-- ORDER BY within aggregate, different column used to order also using DESC +--Testcase 256: +explain (verbose, costs off) +select array_agg(time order by (fields->>'C 1')::int desc) from ft2 where (fields->>'c2')::int = 6 and (fields->>'C 1')::int < 50; + QUERY PLAN +---------------------------------------------------------------------------------------- + Aggregate + Output: array_agg("time" ORDER BY (((fields ->> 'C 1'::text))::integer) DESC) + -> Sort + Output: "time", fields, (((fields ->> 'C 1'::text))::integer) + Sort Key: (((ft2.fields ->> 'C 1'::text))::integer) DESC + -> Foreign Scan on public.ft2 + Output: "time", fields, ((fields ->> 'C 1'::text))::integer + InfluxDB query: SELECT * FROM "T1" WHERE (("C 1" < 50)) AND (("c2" = 6)) +(8 rows) + +--Testcase 257: +select array_agg(time order by (fields->>'C 1')::int desc) from ft2 where (fields->>'c2')::int = 6 and (fields->>'C 1')::int < 50; + array_agg +-------------------------------------------------------------------------------------------------------------------------------------------------------------- + {"Mon Feb 16 00:00:00 1970 PST","Fri Feb 06 00:00:00 1970 PST","Tue Jan 27 00:00:00 1970 PST","Sat Jan 17 00:00:00 1970 PST","Wed Jan 07 00:00:00 1970 PST"} +(1 row) + +-- DISTINCT within aggregate +--Testcase 258: +explain (verbose, costs off) +select array_agg(distinct ((t1.c1)::int)%5) from (SELECT (fields->>'c1')::int c1, (fields->>'c2')::int c2, tags->>'c3' c3 FROM ft4 t1) t1 full join (SELECT (fields->>'c1')::int c1, (fields->>'c2')::int c2, tags->>'c3' c3 FROM ft5 t2) t2 on ((t1.c1)::int = (t2.c1)::int) where (t1.c1)::int < 20 or ((t1.c1)::int is null and (t2.c1)::int < 5) group by ((t2.c1)::int)%3 order by 1; + QUERY PLAN +--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- + Sort + Output: (array_agg(DISTINCT (((((t1.fields ->> 'c1'::text))::integer) % 5)))), (((((t2.fields ->> 'c1'::text))::integer) % 3)) + Sort Key: (array_agg(DISTINCT (((((t1.fields ->> 'c1'::text))::integer) % 5)))) + -> GroupAggregate + Output: array_agg(DISTINCT (((((t1.fields ->> 'c1'::text))::integer) % 5))), (((((t2.fields ->> 'c1'::text))::integer) % 3)) + Group Key: (((((t2.fields ->> 'c1'::text))::integer) % 3)) + -> Sort + Output: (((((t2.fields ->> 'c1'::text))::integer) % 3)), (((t1.fields ->> 'c1'::text))::integer), (((((t1.fields ->> 'c1'::text))::integer) % 5)) + Sort Key: (((((t2.fields ->> 'c1'::text))::integer) % 3)), (((((t1.fields ->> 'c1'::text))::integer) % 5)) + -> Merge Full Join + Output: ((((t2.fields ->> 'c1'::text))::integer) % 3), (((t1.fields ->> 'c1'::text))::integer), ((((t1.fields ->> 'c1'::text))::integer) % 5) + Merge Cond: ((((t1.fields ->> 'c1'::text))::integer) = (((t2.fields ->> 'c1'::text))::integer)) + Filter: (((((t1.fields ->> 'c1'::text))::integer) < 20) OR (((((t1.fields ->> 'c1'::text))::integer) IS NULL) AND ((((t2.fields ->> 'c1'::text))::integer) < 5))) + -> Sort + Output: (((t1.fields ->> 'c1'::text))::integer) + Sort Key: (((t1.fields ->> 'c1'::text))::integer) + -> Foreign Scan on public.ft4 t1 + Output: ((t1.fields ->> 'c1'::text))::integer + InfluxDB query: SELECT "c1" FROM "T3" + -> Sort + Output: (((t2.fields ->> 'c1'::text))::integer) + Sort Key: (((t2.fields ->> 'c1'::text))::integer) + -> Foreign Scan on public.ft5 t2 + Output: ((t2.fields ->> 'c1'::text))::integer + InfluxDB query: SELECT "c1" FROM "T4" +(25 rows) + +--Testcase 259: +select array_agg(distinct ((t1.c1)::int)%5) from (SELECT (fields->>'c1')::int c1, (fields->>'c2')::int c2, tags->>'c3' c3 FROM ft4 t1) t1 full join (SELECT (fields->>'c1')::int c1, (fields->>'c2')::int c2, tags->>'c3' c3 FROM ft5 t2) t2 on ((t1.c1)::int = (t2.c1)::int) where (t1.c1)::int < 20 or ((t1.c1)::int is null and (t2.c1)::int < 5) group by ((t2.c1)::int)%3 order by 1; + array_agg +-------------- + {0,1,2,3,4} + {1,2,3,NULL} +(2 rows) + +-- DISTINCT combined with ORDER BY within aggregate +--Testcase 260: +explain (verbose, costs off) +select array_agg(distinct ((t1.c1)::int)%5 order by ((t1.c1)::int)%5) from (SELECT (fields->>'c1')::int c1, (fields->>'c2')::int c2, tags->>'c3' c3 FROM ft4 t1) t1 full join (SELECT (fields->>'c1')::int c1, (fields->>'c2')::int c2, tags->>'c3' c3 FROM ft5 t2) t2 on ((t1.c1)::int = (t2.c1)::int) where (t1.c1)::int < 20 or ((t1.c1)::int is null and (t2.c1)::int < 5) group by ((t2.c1)::int)%3 order by 1; + QUERY PLAN +----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- + Sort + Output: (array_agg(DISTINCT (((((t1.fields ->> 'c1'::text))::integer) % 5)) ORDER BY (((((t1.fields ->> 'c1'::text))::integer) % 5)))), (((((t2.fields ->> 'c1'::text))::integer) % 3)) + Sort Key: (array_agg(DISTINCT (((((t1.fields ->> 'c1'::text))::integer) % 5)) ORDER BY (((((t1.fields ->> 'c1'::text))::integer) % 5)))) + -> GroupAggregate + Output: array_agg(DISTINCT (((((t1.fields ->> 'c1'::text))::integer) % 5)) ORDER BY (((((t1.fields ->> 'c1'::text))::integer) % 5))), (((((t2.fields ->> 'c1'::text))::integer) % 3)) + Group Key: (((((t2.fields ->> 'c1'::text))::integer) % 3)) + -> Sort + Output: (((((t2.fields ->> 'c1'::text))::integer) % 3)), (((t1.fields ->> 'c1'::text))::integer), (((((t1.fields ->> 'c1'::text))::integer) % 5)) + Sort Key: (((((t2.fields ->> 'c1'::text))::integer) % 3)), (((((t1.fields ->> 'c1'::text))::integer) % 5)) + -> Merge Full Join + Output: ((((t2.fields ->> 'c1'::text))::integer) % 3), (((t1.fields ->> 'c1'::text))::integer), ((((t1.fields ->> 'c1'::text))::integer) % 5) + Merge Cond: ((((t1.fields ->> 'c1'::text))::integer) = (((t2.fields ->> 'c1'::text))::integer)) + Filter: (((((t1.fields ->> 'c1'::text))::integer) < 20) OR (((((t1.fields ->> 'c1'::text))::integer) IS NULL) AND ((((t2.fields ->> 'c1'::text))::integer) < 5))) + -> Sort + Output: (((t1.fields ->> 'c1'::text))::integer) + Sort Key: (((t1.fields ->> 'c1'::text))::integer) + -> Foreign Scan on public.ft4 t1 + Output: ((t1.fields ->> 'c1'::text))::integer + InfluxDB query: SELECT "c1" FROM "T3" + -> Sort + Output: (((t2.fields ->> 'c1'::text))::integer) + Sort Key: (((t2.fields ->> 'c1'::text))::integer) + -> Foreign Scan on public.ft5 t2 + Output: ((t2.fields ->> 'c1'::text))::integer + InfluxDB query: SELECT "c1" FROM "T4" +(25 rows) + +--Testcase 261: +select array_agg(distinct ((t1.c1)::int)%5 order by ((t1.c1)::int)%5) from (SELECT (fields->>'c1')::int c1, (fields->>'c2')::int c2, tags->>'c3' c3 FROM ft4 t1) t1 full join (SELECT (fields->>'c1')::int c1, (fields->>'c2')::int c2, tags->>'c3' c3 FROM ft5 t2) t2 on ((t1.c1)::int = (t2.c1)::int) where (t1.c1)::int < 20 or ((t1.c1)::int is null and (t2.c1)::int < 5) group by ((t2.c1)::int)%3 order by 1; + array_agg +-------------- + {0,1,2,3,4} + {1,2,3,NULL} +(2 rows) + +--Testcase 262: +explain (verbose, costs off) +select array_agg(distinct ((t1.c1)::int)%5 order by ((t1.c1)::int)%5 desc nulls last) from (SELECT (fields->>'c1')::int c1, (fields->>'c2')::int c2, tags->>'c3' c3 FROM ft4 t1) t1 full join (SELECT (fields->>'c1')::int c1, (fields->>'c2')::int c2, tags->>'c3' c3 FROM ft5 t2) t2 on ((t1.c1)::int = (t2.c1)::int) where (t1.c1)::int < 20 or ((t1.c1)::int is null and (t2.c1)::int < 5) group by ((t2.c1)::int)%3 order by 1; + QUERY PLAN +--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- + Sort + Output: (array_agg(DISTINCT (((((t1.fields ->> 'c1'::text))::integer) % 5)) ORDER BY (((((t1.fields ->> 'c1'::text))::integer) % 5)) DESC NULLS LAST)), (((((t2.fields ->> 'c1'::text))::integer) % 3)) + Sort Key: (array_agg(DISTINCT (((((t1.fields ->> 'c1'::text))::integer) % 5)) ORDER BY (((((t1.fields ->> 'c1'::text))::integer) % 5)) DESC NULLS LAST)) + -> GroupAggregate + Output: array_agg(DISTINCT (((((t1.fields ->> 'c1'::text))::integer) % 5)) ORDER BY (((((t1.fields ->> 'c1'::text))::integer) % 5)) DESC NULLS LAST), (((((t2.fields ->> 'c1'::text))::integer) % 3)) + Group Key: (((((t2.fields ->> 'c1'::text))::integer) % 3)) + -> Sort + Output: (((((t2.fields ->> 'c1'::text))::integer) % 3)), (((t1.fields ->> 'c1'::text))::integer), (((((t1.fields ->> 'c1'::text))::integer) % 5)) + Sort Key: (((((t2.fields ->> 'c1'::text))::integer) % 3)), (((((t1.fields ->> 'c1'::text))::integer) % 5)) DESC NULLS LAST + -> Merge Full Join + Output: ((((t2.fields ->> 'c1'::text))::integer) % 3), (((t1.fields ->> 'c1'::text))::integer), ((((t1.fields ->> 'c1'::text))::integer) % 5) + Merge Cond: ((((t1.fields ->> 'c1'::text))::integer) = (((t2.fields ->> 'c1'::text))::integer)) + Filter: (((((t1.fields ->> 'c1'::text))::integer) < 20) OR (((((t1.fields ->> 'c1'::text))::integer) IS NULL) AND ((((t2.fields ->> 'c1'::text))::integer) < 5))) + -> Sort + Output: (((t1.fields ->> 'c1'::text))::integer) + Sort Key: (((t1.fields ->> 'c1'::text))::integer) + -> Foreign Scan on public.ft4 t1 + Output: ((t1.fields ->> 'c1'::text))::integer + InfluxDB query: SELECT "c1" FROM "T3" + -> Sort + Output: (((t2.fields ->> 'c1'::text))::integer) + Sort Key: (((t2.fields ->> 'c1'::text))::integer) + -> Foreign Scan on public.ft5 t2 + Output: ((t2.fields ->> 'c1'::text))::integer + InfluxDB query: SELECT "c1" FROM "T4" +(25 rows) + +--Testcase 263: +select array_agg(distinct ((t1.c1)::int)%5 order by ((t1.c1)::int)%5 desc nulls last) from (SELECT (fields->>'c1')::int c1, (fields->>'c2')::int c2, tags->>'c3' c3 FROM ft4 t1) t1 full join (SELECT (fields->>'c1')::int c1, (fields->>'c2')::int c2, tags->>'c3' c3 FROM ft5 t2) t2 on ((t1.c1)::int = (t2.c1)::int) where (t1.c1)::int < 20 or ((t1.c1)::int is null and (t2.c1)::int < 5) group by ((t2.c1)::int)%3 order by 1; + array_agg +-------------- + {3,2,1,NULL} + {4,3,2,1,0} +(2 rows) + +-- FILTER within aggregate +--Testcase 264: +explain (verbose, costs off) +select sum((fields->>'C 1')::int) filter (where (fields->>'C 1')::int < 100 and (fields->>'c2')::int > 5) from ft1 group by fields->>'c2' order by 1 nulls last; + QUERY PLAN +------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- + Sort + Output: (sum(((fields ->> 'C 1'::text))::integer) FILTER (WHERE ((((fields ->> 'C 1'::text))::integer < 100) AND ((((fields ->> 'c2'::text)))::integer > 5)))), ((fields ->> 'c2'::text)) + Sort Key: (sum(((ft1.fields ->> 'C 1'::text))::integer) FILTER (WHERE ((((ft1.fields ->> 'C 1'::text))::integer < 100) AND ((((ft1.fields ->> 'c2'::text)))::integer > 5)))) + -> HashAggregate + Output: sum(((fields ->> 'C 1'::text))::integer) FILTER (WHERE ((((fields ->> 'C 1'::text))::integer < 100) AND ((((fields ->> 'c2'::text)))::integer > 5))), ((fields ->> 'c2'::text)) + Group Key: (ft1.fields ->> 'c2'::text) + -> Foreign Scan on public.ft1 + Output: (fields ->> 'c2'::text), fields + InfluxDB query: SELECT * FROM "T1" +(9 rows) + +--Testcase 265: +select sum((fields->>'C 1')::int) filter (where (fields->>'C 1')::int < 100 and (fields->>'c2')::int > 5) from ft1 group by fields->>'c2' order by 1 nulls last; + sum +----- + 510 + 520 + 530 + 540 + + + + + + +(10 rows) + +-- DISTINCT, ORDER BY and FILTER within aggregate +--Testcase 266: +explain (verbose, costs off) +select sum((fields->>'C 1')::int%3), sum(distinct (fields->>'C 1')::int%3 order by (fields->>'C 1')::int%3) filter (where (fields->>'C 1')::int%3 < 2), (fields->>'c2')::int c2 from ft1 where (fields->>'c2')::int = 6 group by fields->>'c2'; + QUERY PLAN +-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- + GroupAggregate + Output: sum(((((fields ->> 'C 1'::text))::integer % 3))), sum(DISTINCT ((((fields ->> 'C 1'::text))::integer % 3)) ORDER BY ((((fields ->> 'C 1'::text))::integer % 3))) FILTER (WHERE (((((fields ->> 'C 1'::text))::integer % 3)) < 2)), (((fields ->> 'c2'::text)))::integer, ((fields ->> 'c2'::text)) + Group Key: ((ft1.fields ->> 'c2'::text)) + -> Sort + Output: ((fields ->> 'c2'::text)), fields, ((((fields ->> 'C 1'::text))::integer % 3)) + Sort Key: ((ft1.fields ->> 'c2'::text)), ((((ft1.fields ->> 'C 1'::text))::integer % 3)) + -> Foreign Scan on public.ft1 + Output: (fields ->> 'c2'::text), fields, (((fields ->> 'C 1'::text))::integer % 3) + InfluxDB query: SELECT * FROM "T1" WHERE (("c2" = 6)) +(9 rows) + +--Testcase 267: +select sum((fields->>'C 1')::int%3), sum(distinct (fields->>'C 1')::int%3 order by (fields->>'C 1')::int%3) filter (where (fields->>'C 1')::int%3 < 2), (fields->>'c2')::int c2 from ft1 where (fields->>'c2')::int = 6 group by fields->>'c2'; + sum | sum | c2 +-----+-----+---- + 99 | 1 | 6 +(1 row) + +-- Outer query is aggregation query +--Testcase 268: +explain (verbose, costs off) +select distinct (select count(*) filter (where (t2.fields->>'c2')::int = 6 and (t2.fields->>'C 1')::int < 10) from ft1 t1 where (t1.fields->>'C 1')::int = 6) from ft2 t2 where (t2.fields->>'c2')::int % 6 = 0 order by 1; + QUERY PLAN +------------------------------------------------------------------------------------------------------------------------------------------------------- + Unique + Output: ((SubPlan 1)) + -> Sort + Output: ((SubPlan 1)) + Sort Key: ((SubPlan 1)) + -> Aggregate + Output: (SubPlan 1) + -> Foreign Scan on public.ft2 t2 + Output: t2."time", t2.tags, t2.fields + InfluxDB query: SELECT * FROM "T1" WHERE ((("c2" % 6) = 0)) + SubPlan 1 + -> Foreign Scan on public.ft1 t1 + Output: count(*) FILTER (WHERE ((((t2.fields ->> 'c2'::text))::integer = 6) AND (((t2.fields ->> 'C 1'::text))::integer < 10))) + InfluxDB query: SELECT * FROM "T1" WHERE (("C 1" = 6)) +(14 rows) + +--Testcase 269: +select distinct (select count(*) filter (where (t2.fields->>'c2')::int = 6 and (t2.fields->>'C 1')::int < 10) from ft1 t1 where (t1.fields->>'C 1')::int = 6) from ft2 t2 where (t2.fields->>'c2')::int % 6 = 0 order by 1; + count +------- + 1 +(1 row) + +-- Inner query is aggregation query +--Testcase 270: +explain (verbose, costs off) +select distinct (select count(t1.fields->>'C 1') filter (where (t2.fields->>'c2')::int = 6 and (t2.fields->>'C 1')::int < 10) from ft1 t1 where (t1.fields->>'C 1')::int = 6) from ft2 t2 where (t2.fields->>'c2')::int % 6 = 0 order by 1; + QUERY PLAN +--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- + Unique + Output: ((SubPlan 1)) + -> Sort + Output: ((SubPlan 1)) + Sort Key: ((SubPlan 1)) + -> Foreign Scan on public.ft2 t2 + Output: (SubPlan 1) + InfluxDB query: SELECT * FROM "T1" WHERE ((("c2" % 6) = 0)) + SubPlan 1 + -> Aggregate + Output: count((t1.fields ->> 'C 1'::text)) FILTER (WHERE ((((t2.fields ->> 'c2'::text))::integer = 6) AND (((t2.fields ->> 'C 1'::text))::integer < 10))) + -> Foreign Scan on public.ft1 t1 + Output: t1."time", t1.tags, t1.fields + InfluxDB query: SELECT * FROM "T1" WHERE (("C 1" = 6)) +(14 rows) + +--Testcase 271: +select distinct (select count(t1.fields->>'C 1') filter (where (t2.fields->>'c2')::int = 6 and (t2.fields->>'C 1')::int < 10) from ft1 t1 where (t1.fields->>'C 1')::int = 6) from ft2 t2 where (t2.fields->>'c2')::int % 6 = 0 order by 1; + count +------- + 0 + 1 +(2 rows) + +-- Aggregate not pushed down as FILTER condition is not pushable +--Testcase 272: +explain (verbose, costs off) +select sum((fields->>'C 1')::int) filter (where ((fields->>'C 1')::int / (fields->>'C 1')::int) * random() <= 1) from ft1 group by fields->>'c2' order by 1; + QUERY PLAN +-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- + Sort + Output: (sum(((fields ->> 'C 1'::text))::integer) FILTER (WHERE ((((((fields ->> 'C 1'::text))::integer / ((fields ->> 'C 1'::text))::integer))::double precision * random()) <= '1'::double precision))), ((fields ->> 'c2'::text)) + Sort Key: (sum(((ft1.fields ->> 'C 1'::text))::integer) FILTER (WHERE ((((((ft1.fields ->> 'C 1'::text))::integer / ((ft1.fields ->> 'C 1'::text))::integer))::double precision * random()) <= '1'::double precision))) + -> HashAggregate + Output: sum(((fields ->> 'C 1'::text))::integer) FILTER (WHERE ((((((fields ->> 'C 1'::text))::integer / ((fields ->> 'C 1'::text))::integer))::double precision * random()) <= '1'::double precision)), ((fields ->> 'c2'::text)) + Group Key: (ft1.fields ->> 'c2'::text) + -> Foreign Scan on public.ft1 + Output: (fields ->> 'c2'::text), fields + InfluxDB query: SELECT * FROM "T1" +(9 rows) + +--Testcase 273: +explain (verbose, costs off) +select sum((fields->>'c2')::int) filter (where (fields->>'c2')::int in (select (fields->>'c2')::int from ft1 where (fields->>'c2')::int < 5)) from ft1; + QUERY PLAN +----------------------------------------------------------------------------------------- + Aggregate + Output: sum(((ft1.fields ->> 'c2'::text))::integer) FILTER (WHERE (hashed SubPlan 1)) + -> Foreign Scan on public.ft1 + Output: ft1."time", ft1.tags, ft1.fields + InfluxDB query: SELECT * FROM "T1" + SubPlan 1 + -> Foreign Scan on public.ft1 ft1_1 + Output: ((ft1_1.fields ->> 'c2'::text))::integer + InfluxDB query: SELECT "c2" FROM "T1" WHERE (("c2" < 5)) +(9 rows) + +-- Ordered-sets within aggregate +--Testcase 274: +explain (verbose, costs off) +select (fields->>'c2')::int c2, rank('10'::varchar) within group (order by fields->>'c6'), percentile_cont((fields->>'c2')::int/10::numeric) within group (order by (fields->>'C 1')::int) from ft1 where (fields->>'c2')::int < 10 group by fields->>'c2' having percentile_cont((fields->>'c2')::int/10::numeric) within group (order by (fields->>'C 1')::int) < 500 order by (fields->>'c2')::int; + QUERY PLAN +--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- + Sort + Output: ((((fields ->> 'c2'::text)))::integer), (rank('10'::text) WITHIN GROUP (ORDER BY (fields ->> 'c6'::text))), (percentile_cont(((((((fields ->> 'c2'::text)))::integer)::numeric / '10'::numeric))::double precision) WITHIN GROUP (ORDER BY ((((fields ->> 'C 1'::text))::integer)::double precision))), ((fields ->> 'c2'::text)) + Sort Key: ((((ft1.fields ->> 'c2'::text)))::integer) + -> GroupAggregate + Output: (((fields ->> 'c2'::text)))::integer, rank('10'::text) WITHIN GROUP (ORDER BY (fields ->> 'c6'::text)), percentile_cont(((((((fields ->> 'c2'::text)))::integer)::numeric / '10'::numeric))::double precision) WITHIN GROUP (ORDER BY ((((fields ->> 'C 1'::text))::integer)::double precision)), ((fields ->> 'c2'::text)) + Group Key: ((ft1.fields ->> 'c2'::text)) + Filter: (percentile_cont(((((((ft1.fields ->> 'c2'::text)))::integer)::numeric / '10'::numeric))::double precision) WITHIN GROUP (ORDER BY ((((ft1.fields ->> 'C 1'::text))::integer)::double precision)) < '500'::double precision) + -> Sort + Output: ((fields ->> 'c2'::text)), fields + Sort Key: ((ft1.fields ->> 'c2'::text)) + -> Foreign Scan on public.ft1 + Output: (fields ->> 'c2'::text), fields + InfluxDB query: SELECT * FROM "T1" WHERE (("c2" < 10)) +(13 rows) + +--Testcase 275: +select (fields->>'c2')::int c2, rank('10'::varchar) within group (order by fields->>'c6'), percentile_cont((fields->>'c2')::int/10::numeric) within group (order by (fields->>'C 1')::int) from ft1 where (fields->>'c2')::int < 10 group by fields->>'c2' having percentile_cont((fields->>'c2')::int/10::numeric) within group (order by (fields->>'C 1')::int) < 500 order by (fields->>'c2')::int; + c2 | rank | percentile_cont +----+------+----------------- + 0 | 101 | 10 + 1 | 101 | 100 + 2 | 1 | 200 + 3 | 1 | 300 + 4 | 1 | 400 +(5 rows) + +-- Using multiple arguments within aggregates +--Testcase 276: +explain (verbose, costs off) +select (fields->>'C 1')::int c1, rank(fields->>'C 1', fields->>'c2') within group (order by fields->>'C 1', fields->>'c2') from ft1 group by fields->>'C 1', fields->>'c2' having (fields->>'C 1')::int = 6 order by 1; + QUERY PLAN +--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- + GroupAggregate + Output: (((fields ->> 'C 1'::text)))::integer, rank(((fields ->> 'C 1'::text)), ((fields ->> 'c2'::text))) WITHIN GROUP (ORDER BY ((fields ->> 'C 1'::text)), ((fields ->> 'c2'::text))), ((fields ->> 'C 1'::text)), ((fields ->> 'c2'::text)) + Group Key: ((ft1.fields ->> 'C 1'::text)), ((ft1.fields ->> 'c2'::text)) + -> Sort + Output: ((fields ->> 'C 1'::text)), ((fields ->> 'c2'::text)), fields + Sort Key: ((ft1.fields ->> 'C 1'::text)), ((ft1.fields ->> 'c2'::text)) + -> Foreign Scan on public.ft1 + Output: (fields ->> 'C 1'::text), (fields ->> 'c2'::text), fields + InfluxDB query: SELECT * FROM "T1" WHERE (("C 1" = 6)) +(9 rows) + +--Testcase 277: +select (fields->>'C 1')::int c1, rank(fields->>'C 1', fields->>'c2') within group (order by fields->>'C 1', fields->>'c2') from ft1 group by fields->>'C 1', fields->>'c2' having (fields->>'C 1')::int = 6 order by 1; + c1 | rank +----+------ + 6 | 1 +(1 row) + +-- User defined function for user defined aggregate, VARIADIC +--Testcase 278: +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)'; +--Testcase 279: +create aggregate least_agg(variadic items anyarray) ( + stype = anyelement, sfunc = least_accum +); +-- Disable hash aggregation for plan stability. +--Testcase 280: +set enable_hashagg to false; +-- Not pushed down due to user defined aggregate +--Testcase 281: +explain (verbose, costs off) +select (fields->>'c2')::int c2, least_agg((fields->>'C 1')::int) from ft1 group by fields->>'c2' order by (fields->>'c2')::int; + QUERY PLAN +------------------------------------------------------------------------------------------------------------------------------------------------- + Sort + Output: ((((fields ->> 'c2'::text)))::integer), (least_agg(VARIADIC ARRAY[((fields ->> 'C 1'::text))::integer])), ((fields ->> 'c2'::text)) + Sort Key: ((((ft1.fields ->> 'c2'::text)))::integer) + -> GroupAggregate + Output: (((fields ->> 'c2'::text)))::integer, least_agg(VARIADIC ARRAY[((fields ->> 'C 1'::text))::integer]), ((fields ->> 'c2'::text)) + Group Key: ((ft1.fields ->> 'c2'::text)) + -> Sort + Output: ((fields ->> 'c2'::text)), fields + Sort Key: ((ft1.fields ->> 'c2'::text)) + -> Foreign Scan on public.ft1 + Output: (fields ->> 'c2'::text), fields + InfluxDB query: SELECT * FROM "T1" +(12 rows) + +-- Add function and aggregate into extension +--Testcase 282: +alter extension influxdb_fdw add function least_accum(anyelement, variadic anyarray); +--Testcase 283: +alter extension influxdb_fdw add aggregate least_agg(variadic items anyarray); +-- Now aggregate will be pushed. Aggregate will display VARIADIC argument. +--Testcase 284: +explain (verbose, costs off) +select (fields->>'c2')::int c2, least_agg((fields->>'C 1')::int) from ft1 where (fields->>'c2')::int < 100 group by fields->>'c2' order by (fields->>'c2')::int; + QUERY PLAN +------------------------------------------------------------------------------------------------------------------------------------------------- + Sort + Output: ((((fields ->> 'c2'::text)))::integer), (least_agg(VARIADIC ARRAY[((fields ->> 'C 1'::text))::integer])), ((fields ->> 'c2'::text)) + Sort Key: ((((ft1.fields ->> 'c2'::text)))::integer) + -> GroupAggregate + Output: (((fields ->> 'c2'::text)))::integer, least_agg(VARIADIC ARRAY[((fields ->> 'C 1'::text))::integer]), ((fields ->> 'c2'::text)) + Group Key: ((ft1.fields ->> 'c2'::text)) + -> Sort + Output: ((fields ->> 'c2'::text)), fields + Sort Key: ((ft1.fields ->> 'c2'::text)) + -> Foreign Scan on public.ft1 + Output: (fields ->> 'c2'::text), fields + InfluxDB query: SELECT * FROM "T1" WHERE (("c2" < 100)) +(12 rows) + +--Testcase 285: +select (fields->>'c2')::int c2, least_agg((fields->>'C 1')::int) from ft1 where (fields->>'c2')::int < 100 group by fields->>'c2' order by (fields->>'c2')::int; + c2 | least_agg +----+----------- + 0 | 10 + 1 | 1 + 2 | 2 + 3 | 3 + 4 | 4 + 5 | 5 + 6 | 6 + 7 | 7 + 8 | 8 + 9 | 9 +(10 rows) + +-- Remove function and aggregate from extension +--Testcase 286: +alter extension influxdb_fdw drop function least_accum(anyelement, variadic anyarray); +--Testcase 287: +alter extension influxdb_fdw drop aggregate least_agg(variadic items anyarray); +-- Not pushed down as we have dropped objects from extension. +--Testcase 288: +explain (verbose, costs off) +select (fields->>'c2')::int c2, least_agg((fields->>'C 1')::int) from ft1 group by fields->>'c2' order by (fields->>'c2')::int; + QUERY PLAN +------------------------------------------------------------------------------------------------------------------------------------------------- + Sort + Output: ((((fields ->> 'c2'::text)))::integer), (least_agg(VARIADIC ARRAY[((fields ->> 'C 1'::text))::integer])), ((fields ->> 'c2'::text)) + Sort Key: ((((ft1.fields ->> 'c2'::text)))::integer) + -> GroupAggregate + Output: (((fields ->> 'c2'::text)))::integer, least_agg(VARIADIC ARRAY[((fields ->> 'C 1'::text))::integer]), ((fields ->> 'c2'::text)) + Group Key: ((ft1.fields ->> 'c2'::text)) + -> Sort + Output: ((fields ->> 'c2'::text)), fields + Sort Key: ((ft1.fields ->> 'c2'::text)) + -> Foreign Scan on public.ft1 + Output: (fields ->> 'c2'::text), fields + InfluxDB query: SELECT * FROM "T1" +(12 rows) + +-- Cleanup +--Testcase 289: +reset enable_hashagg; +--Testcase 290: +drop aggregate least_agg(variadic items anyarray); +--Testcase 291: +drop function least_accum(anyelement, variadic anyarray); +-- Testing USING OPERATOR() in ORDER BY within aggregate. +-- For this, we need user defined operators along with operator family and +-- operator class. Create those and then add them in extension. Note that +-- user defined objects are considered unshippable unless they are part of +-- the extension. +--Testcase 292: +create operator public.<^ ( + leftarg = int4, + rightarg = int4, + procedure = int4eq +); +--Testcase 293: +create operator public.=^ ( + leftarg = int4, + rightarg = int4, + procedure = int4lt +); +--Testcase 294: +create operator public.>^ ( + leftarg = int4, + rightarg = int4, + procedure = int4gt +); +--Testcase 295: +create operator family my_op_family using btree; +--Testcase 296: +create function my_op_cmp(a int, b int) returns int as + $$begin return btint4cmp(a, b); end $$ language plpgsql; +--Testcase 297: +create operator class my_op_class for type int using btree family my_op_family as + operator 1 public.<^, + operator 3 public.=^, + operator 5 public.>^, + function 1 my_op_cmp(int, int); +-- This will not be pushed as user defined sort operator is not part of the +-- extension yet. +--Testcase 298: +explain (verbose, costs off) +select array_agg((fields->>'C 1')::int order by (fields->>'C 1')::int using operator(public.<^)) from ft2 where (fields->>'c2')::int = 6 and (fields->>'C 1')::int < 100 group by fields->>'c2'; + QUERY PLAN +---------------------------------------------------------------------------------------------------------------------------------------------------------- + GroupAggregate + Output: array_agg((((fields ->> 'C 1'::text))::integer) ORDER BY (((fields ->> 'C 1'::text))::integer) USING <^ NULLS LAST), ((fields ->> 'c2'::text)) + Group Key: ((ft2.fields ->> 'c2'::text)) + -> Sort + Output: ((fields ->> 'c2'::text)), fields, (((fields ->> 'C 1'::text))::integer) + Sort Key: ((ft2.fields ->> 'c2'::text)), (((ft2.fields ->> 'C 1'::text))::integer) USING <^ + -> Foreign Scan on public.ft2 + Output: (fields ->> 'c2'::text), fields, ((fields ->> 'C 1'::text))::integer + InfluxDB query: SELECT * FROM "T1" WHERE (("C 1" < 100)) AND (("c2" = 6)) +(9 rows) + +-- This should not be pushed either. +--Testcase 766: +explain (verbose, costs off) +select * from ft2 order by (fields->>'C 1')::int using operator(public.<^); + QUERY PLAN +--------------------------------------------------------------------------- + Sort + Output: "time", tags, fields, (((fields ->> 'C 1'::text))::integer) + Sort Key: (((ft2.fields ->> 'C 1'::text))::integer) USING <^ + -> Foreign Scan on public.ft2 + Output: "time", tags, fields, ((fields ->> 'C 1'::text))::integer + InfluxDB query: SELECT * FROM "T1" +(6 rows) + +-- Update local stats on ft2 +--ANALYZE ft2; +-- Add into extension +--Testcase 299: +alter extension influxdb_fdw add operator class my_op_class using btree; +--Testcase 300: +alter extension influxdb_fdw add function my_op_cmp(a int, b int); +--Testcase 301: +alter extension influxdb_fdw add operator family my_op_family using btree; +--Testcase 302: +alter extension influxdb_fdw add operator public.<^(int, int); +--Testcase 303: +alter extension influxdb_fdw add operator public.=^(int, int); +--Testcase 304: +alter extension influxdb_fdw add operator public.>^(int, int); +-- Now this will be pushed as sort operator is part of the extension. +-- alter server loopback options (add fdw_tuple_cost '0.5'); +--Testcase 305: +explain (verbose, costs off) +select array_agg((fields->>'C 1')::int order by (fields->>'C 1')::int using operator(public.<^)) from ft2 where (fields->>'c2')::int = 6 and (fields->>'C 1')::int < 100 group by fields->>'c2'; + QUERY PLAN +---------------------------------------------------------------------------------------------------------------------------------------------------------- + GroupAggregate + Output: array_agg((((fields ->> 'C 1'::text))::integer) ORDER BY (((fields ->> 'C 1'::text))::integer) USING <^ NULLS LAST), ((fields ->> 'c2'::text)) + Group Key: ((ft2.fields ->> 'c2'::text)) + -> Sort + Output: ((fields ->> 'c2'::text)), fields, (((fields ->> 'C 1'::text))::integer) + Sort Key: ((ft2.fields ->> 'c2'::text)), (((ft2.fields ->> 'C 1'::text))::integer) USING <^ + -> Foreign Scan on public.ft2 + Output: (fields ->> 'c2'::text), fields, ((fields ->> 'C 1'::text))::integer + InfluxDB query: SELECT * FROM "T1" WHERE (("C 1" < 100)) AND (("c2" = 6)) +(9 rows) + +--Testcase 306: +select array_agg((fields->>'C 1')::int order by (fields->>'C 1')::int using operator(public.<^)) from ft2 where (fields->>'c2')::int = 6 and (fields->>'C 1')::int < 100 group by fields->>'c2'; + array_agg +-------------------------------- + {6,16,26,36,46,56,66,76,86,96} +(1 row) + +-- alter server loopback options (drop fdw_tuple_cost); +-- This should be pushed too. +-- Influx not support user-defined operator +--Testcase 767: +explain (verbose, costs off) +select * from ft2 order by (fields->>'C 1')::int using operator(public.<^); + QUERY PLAN +--------------------------------------------------------------------------- + Sort + Output: "time", tags, fields, (((fields ->> 'C 1'::text))::integer) + Sort Key: (((ft2.fields ->> 'C 1'::text))::integer) USING <^ + -> Foreign Scan on public.ft2 + Output: "time", tags, fields, ((fields ->> 'C 1'::text))::integer + InfluxDB query: SELECT * FROM "T1" +(6 rows) + +-- Remove from extension +--Testcase 307: +alter extension influxdb_fdw drop operator class my_op_class using btree; +--Testcase 308: +alter extension influxdb_fdw drop function my_op_cmp(a int, b int); +--Testcase 309: +alter extension influxdb_fdw drop operator family my_op_family using btree; +--Testcase 310: +alter extension influxdb_fdw drop operator public.<^(int, int); +--Testcase 311: +alter extension influxdb_fdw drop operator public.=^(int, int); +--Testcase 312: +alter extension influxdb_fdw drop operator public.>^(int, int); +-- This will not be pushed as sort operator is now removed from the extension. +--Testcase 313: +explain (verbose, costs off) +select array_agg((fields->>'C 1')::int order by (fields->>'C 1')::int using operator(public.<^)) from ft2 where (fields->>'c2')::int = 6 and (fields->>'C 1')::int < 100 group by fields->>'c2'; + QUERY PLAN +---------------------------------------------------------------------------------------------------------------------------------------------------------- + GroupAggregate + Output: array_agg((((fields ->> 'C 1'::text))::integer) ORDER BY (((fields ->> 'C 1'::text))::integer) USING <^ NULLS LAST), ((fields ->> 'c2'::text)) + Group Key: ((ft2.fields ->> 'c2'::text)) + -> Sort + Output: ((fields ->> 'c2'::text)), fields, (((fields ->> 'C 1'::text))::integer) + Sort Key: ((ft2.fields ->> 'c2'::text)), (((ft2.fields ->> 'C 1'::text))::integer) USING <^ + -> Foreign Scan on public.ft2 + Output: (fields ->> 'c2'::text), fields, ((fields ->> 'C 1'::text))::integer + InfluxDB query: SELECT * FROM "T1" WHERE (("C 1" < 100)) AND (("c2" = 6)) +(9 rows) + +-- Cleanup +--Testcase 314: +drop operator class my_op_class using btree; +--Testcase 315: +drop function my_op_cmp(a int, b int); +--Testcase 316: +drop operator family my_op_family using btree; +--Testcase 317: +drop operator public.>^(int, int); +--Testcase 318: +drop operator public.=^(int, int); +--Testcase 319: +drop operator public.<^(int, int); +-- Input relation to aggregate push down hook is not safe to pushdown and thus +-- the aggregate cannot be pushed down to foreign server. +--Testcase 320: +explain (verbose, costs off) +select count(t1.c3) from ((SELECT fields->>'C 1' c1, fields->>'c2' c2, tags->>'c3' c3, fields->>'c4' c4, fields->>'c5' c5, fields->>'c6' c6, fields->>'c7' c7, fields->>'c8' c8 FROM ft2)) t1 left join ((SELECT fields->>'C 1' c1, fields->>'c2' c2, tags->>'c3' c3, fields->>'c4' c4, fields->>'c5' c5, fields->>'c6' c6, fields->>'c7' c7, fields->>'c8' c8 FROM ft2)) t2 on ((t1.c1)::int = random() * (t2.c2)::int); + QUERY PLAN +---------------------------------------------------------------------------------------------------------------------------------------------------------------- + Aggregate + Output: count((ft2.tags ->> 'c3'::text)) + -> Nested Loop Left Join + Output: ft2.tags + Join Filter: ((((ft2.fields ->> 'C 1'::text))::integer)::double precision = (random() * (((ft2_1.fields ->> 'c2'::text))::integer)::double precision)) + -> Foreign Scan on public.ft2 + Output: ft2."time", ft2.tags, ft2.fields + InfluxDB query: SELECT * FROM "T1" + -> Materialize + Output: ft2_1.fields + -> Foreign Scan on public.ft2 ft2_1 + Output: ft2_1.fields + InfluxDB query: SELECT * FROM "T1" +(13 rows) + +-- Subquery in FROM clause having aggregate +--Testcase 321: +explain (verbose, costs off) +select count(*), x.b from ft1, (select (fields->>'c2')::int a, sum((fields->>'C 1')::int) b from ft1 group by fields->>'c2') x where (ft1.fields->>'c2')::int = x.a group by x.b order by 1, 2; + QUERY PLAN +--------------------------------------------------------------------------------------------------------------------------------------------------------------------- + Sort + Output: (count(*)), x.b + Sort Key: (count(*)), x.b + -> HashAggregate + Output: count(*), x.b + Group Key: x.b + -> Merge Join + Output: x.b + Merge Cond: (x.a = (((ft1.fields ->> 'c2'::text))::integer)) + -> Sort + Output: x.b, x.a + Sort Key: x.a + -> Subquery Scan on x + Output: x.b, x.a + -> HashAggregate + Output: (((ft1_1.fields ->> 'c2'::text)))::integer, sum(((ft1_1.fields ->> 'C 1'::text))::integer), ((ft1_1.fields ->> 'c2'::text)) + Group Key: (ft1_1.fields ->> 'c2'::text) + -> Foreign Scan on public.ft1 ft1_1 + Output: (ft1_1.fields ->> 'c2'::text), ft1_1.fields + InfluxDB query: SELECT * FROM "T1" + -> Sort + Output: ft1.fields, (((ft1.fields ->> 'c2'::text))::integer) + Sort Key: (((ft1.fields ->> 'c2'::text))::integer) + -> Foreign Scan on public.ft1 + Output: ft1.fields, ((ft1.fields ->> 'c2'::text))::integer + InfluxDB query: SELECT * FROM "T1" +(26 rows) + +--Testcase 322: +select count(*), x.b from ft1, (select (fields->>'c2')::int a, sum((fields->>'C 1')::int) b from ft1 group by fields->>'c2') x where (ft1.fields->>'c2')::int = x.a group by x.b order by 1, 2; + count | b +-------+------- + 100 | 49600 + 100 | 49700 + 100 | 49800 + 100 | 49900 + 100 | 50000 + 100 | 50100 + 100 | 50200 + 100 | 50300 + 100 | 50400 + 100 | 50500 +(10 rows) + +-- FULL join with IS NULL check in HAVING +--Testcase 323: +explain (verbose, costs off) +select avg((t1.c1)::int), sum((t2.c1)::int) from (SELECT (fields->>'c1')::int c1, (fields->>'c2')::int c2, tags->>'c3' c3 FROM ft4 t1) t1 full join (SELECT (fields->>'c1')::int c1, (fields->>'c2')::int c2, tags->>'c3' c3 FROM ft5 t2) t2 on ((t1.c1)::int = (t2.c1)::int) group by t2.c1 having (avg((t1.c1)::int) is null and sum((t2.c1)::int) < 10) or sum((t2.c1)::int) is null order by 1 nulls last, 2; + QUERY PLAN +---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- + Sort + Output: (avg((((t1.fields ->> 'c1'::text))::integer))), (sum((((t2.fields ->> 'c1'::text))::integer))), (((t2.fields ->> 'c1'::text))::integer) + Sort Key: (avg((((t1.fields ->> 'c1'::text))::integer))), (sum((((t2.fields ->> 'c1'::text))::integer))) + -> HashAggregate + Output: avg((((t1.fields ->> 'c1'::text))::integer)), sum((((t2.fields ->> 'c1'::text))::integer)), (((t2.fields ->> 'c1'::text))::integer) + Group Key: (((t2.fields ->> 'c1'::text))::integer) + Filter: (((avg((((t1.fields ->> 'c1'::text))::integer)) IS NULL) AND (sum((((t2.fields ->> 'c1'::text))::integer)) < 10)) OR (sum((((t2.fields ->> 'c1'::text))::integer)) IS NULL)) + -> Merge Full Join + Output: (((t2.fields ->> 'c1'::text))::integer), (((t1.fields ->> 'c1'::text))::integer) + Merge Cond: ((((t1.fields ->> 'c1'::text))::integer) = (((t2.fields ->> 'c1'::text))::integer)) + -> Sort + Output: (((t1.fields ->> 'c1'::text))::integer) + Sort Key: (((t1.fields ->> 'c1'::text))::integer) + -> Foreign Scan on public.ft4 t1 + Output: ((t1.fields ->> 'c1'::text))::integer + InfluxDB query: SELECT "c1" FROM "T3" + -> Sort + Output: (((t2.fields ->> 'c1'::text))::integer) + Sort Key: (((t2.fields ->> 'c1'::text))::integer) + -> Foreign Scan on public.ft5 t2 + Output: ((t2.fields ->> 'c1'::text))::integer + InfluxDB query: SELECT "c1" FROM "T4" +(22 rows) + +--Testcase 324: +select avg((t1.c1)::int), sum((t2.c1)::int) from (SELECT (fields->>'c1')::int c1, (fields->>'c2')::int c2, tags->>'c3' c3 FROM ft4 t1) t1 full join (SELECT (fields->>'c1')::int c1, (fields->>'c2')::int c2, tags->>'c3' c3 FROM ft5 t2) t2 on ((t1.c1)::int = (t2.c1)::int) group by t2.c1 having (avg((t1.c1)::int) is null and sum((t2.c1)::int) < 10) or sum((t2.c1)::int) is null order by 1 nulls last, 2; + avg | sum +---------------------+----- + 51.0000000000000000 | + | 3 + | 9 +(3 rows) + +-- Aggregate over FULL join needing to deparse the joining relations as +-- subqueries. +--Testcase 325: +explain (verbose, costs off) +select count(*), sum((t1.c1)::int), avg((t2.c1)::int) from (SELECT (fields->>'c1')::int c1 FROM ft4 t1 WHERE (fields->>'c1')::int between 50 and 60) t1 full join (SELECT (fields->>'c1')::int c1 FROM ft5 t2 WHERE (fields->>'c1')::int between 50 and 60) t2 on ((t1.c1)::int = (t2.c1)::int); + QUERY PLAN +---------------------------------------------------------------------------------------------------------------- + Aggregate + Output: count(*), sum((((t1.fields ->> 'c1'::text))::integer)), avg((((t2.fields ->> 'c1'::text))::integer)) + -> Hash Full Join + Output: (((t1.fields ->> 'c1'::text))::integer), (((t2.fields ->> 'c1'::text))::integer) + Hash Cond: ((((t1.fields ->> 'c1'::text))::integer) = (((t2.fields ->> 'c1'::text))::integer)) + -> Foreign Scan on public.ft4 t1 + Output: ((t1.fields ->> 'c1'::text))::integer + InfluxDB query: SELECT "c1" FROM "T3" WHERE (("c1" >= 50)) AND (("c1" <= 60)) + -> Hash + Output: (((t2.fields ->> 'c1'::text))::integer) + -> Foreign Scan on public.ft5 t2 + Output: ((t2.fields ->> 'c1'::text))::integer + InfluxDB query: SELECT "c1" FROM "T4" WHERE (("c1" >= 50)) AND (("c1" <= 60)) +(13 rows) + +--Testcase 326: +select count(*), sum((t1.c1)::int), avg((t2.c1)::int) from (SELECT (fields->>'c1')::int c1 FROM ft4 t1 WHERE (fields->>'c1')::int between 50 and 60) t1 full join (SELECT (fields->>'c1')::int c1 FROM ft5 t2 WHERE (fields->>'c1')::int between 50 and 60) t2 on ((t1.c1)::int = (t2.c1)::int); + count | sum | avg +-------+-----+--------------------- + 8 | 330 | 55.5000000000000000 +(1 row) + +-- ORDER BY expression is part of the target list but not pushed down to +-- foreign server. +--Testcase 327: +explain (verbose, costs off) +select sum((fields->>'c2')::int) * (random() <= 1)::int as sum from ft1 order by 1; + QUERY PLAN +---------------------------------------------------------------------------------------------------------------- + Sort + Output: (((sum(((fields ->> 'c2'::text))::integer)) * ((random() <= '1'::double precision))::integer)) + Sort Key: (((sum(((ft1.fields ->> 'c2'::text))::integer)) * ((random() <= '1'::double precision))::integer)) + -> Foreign Scan + Output: ((sum(((fields ->> 'c2'::text))::integer)) * ((random() <= '1'::double precision))::integer) + InfluxDB query: SELECT sum("c2") FROM "T1" +(6 rows) + +--Testcase 328: +select sum((fields->>'c2')::int) * (random() <= 1)::int as sum from ft1 order by 1; + sum +------ + 4500 +(1 row) + +-- LATERAL join, with parameterization +--Testcase 329: +set enable_hashagg to false; +--Testcase 330: +explain (verbose, costs off) +select (fields->>'c2')::int c2, sum from "S 1"."T 1" t1, lateral (select sum((t2.fields->>'C 1')::int + (t1.fields->>'C 1')::int) sum from ft2 t2 group by t2.fields->>'C 1') qry where (t1.fields->>'c2')::int * 2 = qry.sum and (t1.fields->>'c2')::int < 3 and (t1.fields->>'C 1')::int < 100 order by 1; + QUERY PLAN +----------------------------------------------------------------------------------------------------------------------------------------------------- + Sort + Output: (((t1.fields ->> 'c2'::text))::integer), qry.sum + Sort Key: (((t1.fields ->> 'c2'::text))::integer) + -> Nested Loop + Output: ((t1.fields ->> 'c2'::text))::integer, qry.sum + -> Foreign Scan on "S 1"."T 1" t1 + Output: t1."time", t1.tags, t1.fields + InfluxDB query: SELECT * FROM "T1" WHERE (("c2" < 3)) AND (("C 1" < 100)) + -> Subquery Scan on qry + Output: qry.sum, ((t2.fields ->> 'C 1'::text)) + Filter: ((((t1.fields ->> 'c2'::text))::integer * 2) = qry.sum) + -> GroupAggregate + Output: sum(((((t2.fields ->> 'C 1'::text)))::integer + ((t1.fields ->> 'C 1'::text))::integer)), ((t2.fields ->> 'C 1'::text)) + Group Key: ((t2.fields ->> 'C 1'::text)) + -> Sort + Output: ((t2.fields ->> 'C 1'::text)), t2.fields + Sort Key: ((t2.fields ->> 'C 1'::text)) + -> Foreign Scan on public.ft2 t2 + Output: (t2.fields ->> 'C 1'::text), t2.fields + InfluxDB query: SELECT * FROM "T1" +(20 rows) + +--Testcase 331: +select (fields->>'c2')::int c2, sum from "S 1"."T 1" t1, lateral (select sum((t2.fields->>'C 1')::int + (t1.fields->>'C 1')::int) sum from ft2 t2 group by t2.fields->>'C 1') qry where (t1.fields->>'c2')::int * 2 = qry.sum and (t1.fields->>'c2')::int < 3 and (t1.fields->>'C 1')::int < 100 order by 1; + c2 | sum +----+----- + 1 | 2 + 2 | 4 +(2 rows) + +--Testcase 332: +reset enable_hashagg; +-- bug #15613: bad plan for foreign table scan with lateral reference +--Testcase 333: +EXPLAIN (VERBOSE, COSTS OFF) +SELECT (ref_0.fields->>'c2')::int c2, subq_1.* +FROM + "S 1"."T 1" AS ref_0, + LATERAL ( + SELECT (ref_0.fields->>'C 1')::int c1, subq_0.* + FROM (SELECT (ref_0.fields->>'c2')::int c2, ref_1.tags->>'c3' c3 + FROM ft1 AS ref_1) AS subq_0 + RIGHT JOIN ft2 AS ref_3 ON (subq_0.c3 = ref_3.tags->>'c3') + ) AS subq_1 +WHERE (ref_0.fields->>'C 1')::int < 10 AND subq_1.c3 = '00001' +ORDER BY (ref_0.fields->>'C 1')::int; + QUERY PLAN +--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- + Sort + Output: (((ref_0.fields ->> 'c2'::text))::integer), (((ref_0.fields ->> 'C 1'::text))::integer), (((ref_0.fields ->> 'c2'::text))::integer), ((ref_1.tags ->> 'c3'::text)), (((ref_0.fields ->> 'C 1'::text))::integer) + Sort Key: (((ref_0.fields ->> 'C 1'::text))::integer) + -> Merge Join + Output: ((ref_0.fields ->> 'c2'::text))::integer, ((ref_0.fields ->> 'C 1'::text))::integer, (((ref_0.fields ->> 'c2'::text))::integer), ((ref_1.tags ->> 'c3'::text)), ((ref_0.fields ->> 'C 1'::text))::integer + Merge Cond: (((ref_3.tags ->> 'c3'::text)) = ((ref_1.tags ->> 'c3'::text))) + -> Sort + Output: ref_3.tags, ((ref_3.tags ->> 'c3'::text)) + Sort Key: ((ref_3.tags ->> 'c3'::text)) + -> Foreign Scan on public.ft2 ref_3 + Output: ref_3.tags, (ref_3.tags ->> 'c3'::text) + InfluxDB query: SELECT * FROM "T1" + -> Sort + Output: ref_0.fields, ref_1.tags, (((ref_0.fields ->> 'c2'::text))::integer), ((ref_1.tags ->> 'c3'::text)), ((ref_1.tags ->> 'c3'::text)) + Sort Key: ((ref_1.tags ->> 'c3'::text)) + -> Nested Loop + Output: ref_0.fields, ref_1.tags, (((ref_0.fields ->> 'c2'::text))::integer), ((ref_1.tags ->> 'c3'::text)), (ref_1.tags ->> 'c3'::text) + -> Foreign Scan on "S 1"."T 1" ref_0 + Output: ref_0."time", ref_0.tags, ref_0.fields + InfluxDB query: SELECT * FROM "T1" WHERE (("C 1" < 10)) + -> Foreign Scan on public.ft1 ref_1 + Output: ref_1.tags, ((ref_0.fields ->> 'c2'::text))::integer, (ref_1.tags ->> 'c3'::text) + Filter: ((ref_1.tags ->> 'c3'::text) = '00001'::text) + InfluxDB query: SELECT * FROM "T1" +(24 rows) + +--Testcase 334: +SELECT (ref_0.fields->>'c2')::int c2, subq_1.* +FROM + "S 1"."T 1" AS ref_0, + LATERAL ( + SELECT (ref_0.fields->>'C 1')::int c1, subq_0.* + FROM (SELECT (ref_0.fields->>'c2')::int c2, ref_1.tags->>'c3' c3 + FROM ft1 AS ref_1) AS subq_0 + RIGHT JOIN ft2 AS ref_3 ON (subq_0.c3 = ref_3.tags->>'c3') + ) AS subq_1 +WHERE (ref_0.fields->>'C 1')::int < 10 AND subq_1.c3 = '00001' +ORDER BY (ref_0.fields->>'C 1')::int; + c2 | c1 | c2 | c3 +----+----+----+------- + 1 | 1 | 1 | 00001 + 2 | 2 | 2 | 00001 + 3 | 3 | 3 | 00001 + 4 | 4 | 4 | 00001 + 5 | 5 | 5 | 00001 + 6 | 6 | 6 | 00001 + 7 | 7 | 7 | 00001 + 8 | 8 | 8 | 00001 + 9 | 9 | 9 | 00001 +(9 rows) + +-- Check with placeHolderVars +--Testcase 335: +explain (verbose, costs off) +select sum(q.a), count(q.b) from ft4 left join (select 13, avg((ft1.fields->>'C 1')::int), sum((ft2.fields->>'C 1')::int) from ft1 right join ft2 on ((ft1.fields->>'C 1')::int = (ft2.fields->>'C 1')::int)) q(a, b, c) on ((ft4.fields->>'c1')::int <= q.b); + QUERY PLAN +------------------------------------------------------------------------------------------------------------------------------------- + Aggregate + Output: sum(q.a), count(q.b) + -> Nested Loop Left Join + Output: q.a, q.b + Inner Unique: true + Join Filter: ((((ft4.fields ->> 'c1'::text))::integer)::numeric <= q.b) + -> Foreign Scan on public.ft4 + Output: ft4.tags, ft4.fields + InfluxDB query: SELECT * FROM "T3" + -> Materialize + Output: q.a, q.b + -> Subquery Scan on q + Output: q.a, q.b + -> Aggregate + Output: 13, avg(((ft1.fields ->> 'C 1'::text))::integer), NULL::bigint + -> Merge Left Join + Output: ft1.fields + Merge Cond: ((((ft2.fields ->> 'C 1'::text))::integer) = (((ft1.fields ->> 'C 1'::text))::integer)) + -> Sort + Output: ft2.fields, (((ft2.fields ->> 'C 1'::text))::integer) + Sort Key: (((ft2.fields ->> 'C 1'::text))::integer) + -> Foreign Scan on public.ft2 + Output: ft2.fields, ((ft2.fields ->> 'C 1'::text))::integer + InfluxDB query: SELECT * FROM "T1" + -> Sort + Output: ft1.fields, (((ft1.fields ->> 'C 1'::text))::integer) + Sort Key: (((ft1.fields ->> 'C 1'::text))::integer) + -> Foreign Scan on public.ft1 + Output: ft1.fields, ((ft1.fields ->> 'C 1'::text))::integer + InfluxDB query: SELECT * FROM "T1" +(30 rows) + +--Testcase 336: +select sum(q.a), count(q.b) from ft4 left join (select 13, avg((ft1.fields->>'C 1')::int), sum((ft2.fields->>'C 1')::int) from ft1 right join ft2 on ((ft1.fields->>'C 1')::int = (ft2.fields->>'C 1')::int)) q(a, b, c) on ((ft4.fields->>'c1')::int <= q.b); + sum | count +-----+------- + 650 | 50 +(1 row) + +-- Not supported cases +-- Grouping sets +--Testcase 337: +explain (verbose, costs off) +select (fields->>'c2')::int c2, sum((fields->>'C 1')::int) from ft1 where (fields->>'c2')::int < 3 group by rollup((fields->>'c2')::int) order by 1 nulls last; + QUERY PLAN +------------------------------------------------------------------------------------------------ + Sort + Output: (((fields ->> 'c2'::text))::integer), (sum(((fields ->> 'C 1'::text))::integer)) + Sort Key: (((ft1.fields ->> 'c2'::text))::integer) + -> MixedAggregate + Output: (((fields ->> 'c2'::text))::integer), sum(((fields ->> 'C 1'::text))::integer) + Hash Key: ((ft1.fields ->> 'c2'::text))::integer + Group Key: () + -> Foreign Scan on public.ft1 + Output: ((fields ->> 'c2'::text))::integer, fields + InfluxDB query: SELECT * FROM "T1" WHERE (("c2" < 3)) +(10 rows) + +--Testcase 338: +select (fields->>'c2')::int c2, sum((fields->>'C 1')::int) from ft1 where (fields->>'c2')::int < 3 group by rollup((fields->>'c2')::int) order by 1 nulls last; + c2 | sum +----+-------- + 0 | 50500 + 1 | 49600 + 2 | 49700 + | 149800 +(4 rows) + +--Testcase 339: +explain (verbose, costs off) +select (fields->>'c2')::int c2, sum((fields->>'C 1')::int) from ft1 where (fields->>'c2')::int < 3 group by cube((fields->>'c2')::int) order by 1 nulls last; + QUERY PLAN +------------------------------------------------------------------------------------------------ + Sort + Output: (((fields ->> 'c2'::text))::integer), (sum(((fields ->> 'C 1'::text))::integer)) + Sort Key: (((ft1.fields ->> 'c2'::text))::integer) + -> MixedAggregate + Output: (((fields ->> 'c2'::text))::integer), sum(((fields ->> 'C 1'::text))::integer) + Hash Key: ((ft1.fields ->> 'c2'::text))::integer + Group Key: () + -> Foreign Scan on public.ft1 + Output: ((fields ->> 'c2'::text))::integer, fields + InfluxDB query: SELECT * FROM "T1" WHERE (("c2" < 3)) +(10 rows) + +--Testcase 340: +select (fields->>'c2')::int c2, sum((fields->>'C 1')::int) from ft1 where (fields->>'c2')::int < 3 group by cube((fields->>'c2')::int) order by 1 nulls last; + c2 | sum +----+-------- + 0 | 50500 + 1 | 49600 + 2 | 49700 + | 149800 +(4 rows) + +--Testcase 341: +explain (verbose, costs off) +select (fields->>'c2')::int c2, fields->>'c6' c6, sum((fields->>'C 1')::int) from ft1 where (fields->>'c2')::int < 3 group by grouping sets(fields->>'c2', fields->>'c6') order by 1 nulls last, 2 nulls last; + QUERY PLAN +------------------------------------------------------------------------------------------------------------------------------------------------------ + Sort + Output: ((((fields ->> 'c2'::text)))::integer), ((fields ->> 'c6'::text)), (sum(((fields ->> 'C 1'::text))::integer)), ((fields ->> 'c2'::text)) + Sort Key: ((((ft1.fields ->> 'c2'::text)))::integer), ((ft1.fields ->> 'c6'::text)) + -> HashAggregate + Output: (((fields ->> 'c2'::text)))::integer, ((fields ->> 'c6'::text)), sum(((fields ->> 'C 1'::text))::integer), ((fields ->> 'c2'::text)) + Hash Key: (ft1.fields ->> 'c2'::text) + Hash Key: (ft1.fields ->> 'c6'::text) + -> Foreign Scan on public.ft1 + Output: (fields ->> 'c6'::text), (fields ->> 'c2'::text), fields + InfluxDB query: SELECT * FROM "T1" WHERE (("c2" < 3)) +(10 rows) + +--Testcase 342: +select (fields->>'c2')::int c2, fields->>'c6' c6, sum((fields->>'C 1')::int) from ft1 where (fields->>'c2')::int < 3 group by grouping sets(fields->>'c2', fields->>'c6') order by 1 nulls last, 2 nulls last; + c2 | c6 | sum +----+----+------- + 0 | | 50500 + 1 | | 49600 + 2 | | 49700 + | 0 | 50500 + | 1 | 49600 + | 2 | 49700 +(6 rows) + +--Testcase 343: +explain (verbose, costs off) +select (fields->>'c2')::int c2, sum((fields->>'C 1')::int), grouping(fields->>'c2') from ft1 where (fields->>'c2')::int < 3 group by fields->>'c2' order by 1 nulls last; + QUERY PLAN +---------------------------------------------------------------------------------------------------------------------------------------------------------------- + Sort + Output: ((((fields ->> 'c2'::text)))::integer), (sum(((fields ->> 'C 1'::text))::integer)), (GROUPING(((fields ->> 'c2'::text)))), ((fields ->> 'c2'::text)) + Sort Key: ((((ft1.fields ->> 'c2'::text)))::integer) + -> HashAggregate + Output: (((fields ->> 'c2'::text)))::integer, sum(((fields ->> 'C 1'::text))::integer), GROUPING(((fields ->> 'c2'::text))), ((fields ->> 'c2'::text)) + Group Key: (ft1.fields ->> 'c2'::text) + -> Foreign Scan on public.ft1 + Output: (fields ->> 'c2'::text), fields + InfluxDB query: SELECT * FROM "T1" WHERE (("c2" < 3)) +(9 rows) + +--Testcase 344: +select (fields->>'c2')::int c2, sum((fields->>'C 1')::int), grouping(fields->>'c2') from ft1 where (fields->>'c2')::int < 3 group by fields->>'c2' order by 1 nulls last; + c2 | sum | grouping +----+-------+---------- + 0 | 50500 | 0 + 1 | 49600 | 0 + 2 | 49700 | 0 +(3 rows) + +-- DISTINCT itself is not pushed down, whereas underneath aggregate is pushed +--Testcase 345: +explain (verbose, costs off) +select distinct sum((fields->>'C 1')::int)/1000 s from ft2 where (fields->>'c2')::int < 6 group by fields->>'c2' order by 1; + QUERY PLAN +---------------------------------------------------------------------------------------------------- + Unique + Output: ((sum(((fields ->> 'C 1'::text))::integer) / 1000)), ((fields ->> 'c2'::text)) + -> Sort + Output: ((sum(((fields ->> 'C 1'::text))::integer) / 1000)), ((fields ->> 'c2'::text)) + Sort Key: ((sum(((ft2.fields ->> 'C 1'::text))::integer) / 1000)) + -> HashAggregate + Output: (sum(((fields ->> 'C 1'::text))::integer) / 1000), ((fields ->> 'c2'::text)) + Group Key: (ft2.fields ->> 'c2'::text) + -> Foreign Scan on public.ft2 + Output: (fields ->> 'c2'::text), fields + InfluxDB query: SELECT * FROM "T1" WHERE (("c2" < 6)) +(11 rows) + +--Testcase 346: +select distinct sum((fields->>'C 1')::int)/1000 s from ft2 where (fields->>'c2')::int < 6 group by fields->>'c2' order by 1; + s +---- + 49 + 50 +(2 rows) + +-- WindowAgg +--Testcase 347: +explain (verbose, costs off) +select (fields->>'c2')::int c2, sum((fields->>'c2')::int), count((fields->>'c2')::int) over (partition by (fields->>'c2')::int%2) from ft2 where (fields->>'c2')::int < 10 group by fields->>'c2' order by 1; + QUERY PLAN +---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- + Sort + Output: ((((fields ->> 'c2'::text)))::integer), (sum((((fields ->> 'c2'::text)))::integer)), (count((((fields ->> 'c2'::text)))::integer) OVER (?)), ((fields ->> 'c2'::text)), (((((fields ->> 'c2'::text)))::integer % 2)) + Sort Key: ((((ft2.fields ->> 'c2'::text)))::integer) + -> WindowAgg + Output: (((fields ->> 'c2'::text)))::integer, (sum((((fields ->> 'c2'::text)))::integer)), count((((fields ->> 'c2'::text)))::integer) OVER (?), ((fields ->> 'c2'::text)), (((((fields ->> 'c2'::text)))::integer % 2)) + -> Sort + Output: ((fields ->> 'c2'::text)), (((((fields ->> 'c2'::text)))::integer % 2)), fields, (sum((((fields ->> 'c2'::text)))::integer)) + Sort Key: (((((ft2.fields ->> 'c2'::text)))::integer % 2)) + -> HashAggregate + Output: ((fields ->> 'c2'::text)), ((((fields ->> 'c2'::text)))::integer % 2), fields, sum((((fields ->> 'c2'::text)))::integer) + Group Key: (ft2.fields ->> 'c2'::text) + -> Foreign Scan on public.ft2 + Output: (fields ->> 'c2'::text), fields + InfluxDB query: SELECT * FROM "T1" WHERE (("c2" < 10)) +(14 rows) + +--Testcase 348: +select (fields->>'c2')::int c2, sum((fields->>'c2')::int), count((fields->>'c2')::int) over (partition by (fields->>'c2')::int%2) from ft2 where (fields->>'c2')::int < 10 group by fields->>'c2' order by 1; + c2 | sum | count +----+-----+------- + 0 | 0 | 5 + 1 | 100 | 5 + 2 | 200 | 5 + 3 | 300 | 5 + 4 | 400 | 5 + 5 | 500 | 5 + 6 | 600 | 5 + 7 | 700 | 5 + 8 | 800 | 5 + 9 | 900 | 5 +(10 rows) + +--Testcase 349: +explain (verbose, costs off) +select (fields->>'c2')::int c2, array_agg((fields->>'c2')::int) over (partition by (fields->>'c2')::int%2 order by (fields->>'c2')::int desc) from ft1 where (fields->>'c2')::int < 10 group by fields->>'c2' order by 1; + QUERY PLAN +--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- + Sort + Output: ((((fields ->> 'c2'::text)))::integer), (array_agg(((((fields ->> 'c2'::text)))::integer)) OVER (?)), ((fields ->> 'c2'::text)), (((((fields ->> 'c2'::text)))::integer % 2)) + Sort Key: ((((ft1.fields ->> 'c2'::text)))::integer) + -> WindowAgg + Output: ((((fields ->> 'c2'::text)))::integer), array_agg(((((fields ->> 'c2'::text)))::integer)) OVER (?), ((fields ->> 'c2'::text)), (((((fields ->> 'c2'::text)))::integer % 2)) + -> Sort + Output: ((((fields ->> 'c2'::text)))::integer), ((fields ->> 'c2'::text)), (((((fields ->> 'c2'::text)))::integer % 2)), fields + Sort Key: (((((ft1.fields ->> 'c2'::text)))::integer % 2)), ((((ft1.fields ->> 'c2'::text)))::integer) DESC + -> HashAggregate + Output: (((fields ->> 'c2'::text)))::integer, ((fields ->> 'c2'::text)), ((((fields ->> 'c2'::text)))::integer % 2), fields + Group Key: (ft1.fields ->> 'c2'::text) + -> Foreign Scan on public.ft1 + Output: (fields ->> 'c2'::text), fields + InfluxDB query: SELECT * FROM "T1" WHERE (("c2" < 10)) +(14 rows) + +--Testcase 350: +select (fields->>'c2')::int c2, array_agg((fields->>'c2')::int) over (partition by (fields->>'c2')::int%2 order by (fields->>'c2')::int desc) from ft1 where (fields->>'c2')::int < 10 group by fields->>'c2' order by 1; + c2 | array_agg +----+------------- + 0 | {8,6,4,2,0} + 1 | {9,7,5,3,1} + 2 | {8,6,4,2} + 3 | {9,7,5,3} + 4 | {8,6,4} + 5 | {9,7,5} + 6 | {8,6} + 7 | {9,7} + 8 | {8} + 9 | {9} +(10 rows) + +--Testcase 351: +explain (verbose, costs off) +select (fields->>'c2')::int c2, array_agg((fields->>'c2')::int) over (partition by (fields->>'c2')::int%2 order by (fields->>'c2')::int range between current row and unbounded following) from ft1 where (fields->>'c2')::int < 10 group by fields->>'c2' order by 1; + QUERY PLAN +--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- + Sort + Output: ((((fields ->> 'c2'::text)))::integer), (array_agg(((((fields ->> 'c2'::text)))::integer)) OVER (?)), ((fields ->> 'c2'::text)), (((((fields ->> 'c2'::text)))::integer % 2)) + Sort Key: ((((ft1.fields ->> 'c2'::text)))::integer) + -> WindowAgg + Output: ((((fields ->> 'c2'::text)))::integer), array_agg(((((fields ->> 'c2'::text)))::integer)) OVER (?), ((fields ->> 'c2'::text)), (((((fields ->> 'c2'::text)))::integer % 2)) + -> Sort + Output: ((((fields ->> 'c2'::text)))::integer), ((fields ->> 'c2'::text)), (((((fields ->> 'c2'::text)))::integer % 2)), fields + Sort Key: (((((ft1.fields ->> 'c2'::text)))::integer % 2)), ((((ft1.fields ->> 'c2'::text)))::integer) + -> HashAggregate + Output: (((fields ->> 'c2'::text)))::integer, ((fields ->> 'c2'::text)), ((((fields ->> 'c2'::text)))::integer % 2), fields + Group Key: (ft1.fields ->> 'c2'::text) + -> Foreign Scan on public.ft1 + Output: (fields ->> 'c2'::text), fields + InfluxDB query: SELECT * FROM "T1" WHERE (("c2" < 10)) +(14 rows) + +--Testcase 352: +select (fields->>'c2')::int c2, array_agg((fields->>'c2')::int) over (partition by (fields->>'c2')::int%2 order by (fields->>'c2')::int range between current row and unbounded following) from ft1 where (fields->>'c2')::int < 10 group by fields->>'c2' order by 1; + c2 | array_agg +----+------------- + 0 | {0,2,4,6,8} + 1 | {1,3,5,7,9} + 2 | {2,4,6,8} + 3 | {3,5,7,9} + 4 | {4,6,8} + 5 | {5,7,9} + 6 | {6,8} + 7 | {7,9} + 8 | {8} + 9 | {9} +(10 rows) + +-- =================================================================== +-- parameterized queries +-- =================================================================== +-- simple join +--Testcase 353: +PREPARE st1(int, int) AS SELECT t1.tags->>'c3' c3, t2.tags->>'c3' c3 FROM ft1 t1, ft2 t2 WHERE (t1.fields->>'C 1')::int = $1 AND (t2.fields->>'C 1')::int = $2; +--Testcase 354: +EXPLAIN (VERBOSE, COSTS OFF) EXECUTE st1(1, 2); + QUERY PLAN +---------------------------------------------------------------------- + Nested Loop + Output: (t1.tags ->> 'c3'::text), (t2.tags ->> 'c3'::text) + -> Foreign Scan on public.ft1 t1 + Output: t1."time", t1.tags, t1.fields + InfluxDB query: SELECT * FROM "T1" WHERE (("C 1" = 1)) + -> Materialize + Output: t2.tags + -> Foreign Scan on public.ft2 t2 + Output: t2.tags + InfluxDB query: SELECT * FROM "T1" WHERE (("C 1" = 2)) +(10 rows) + +--Testcase 355: +EXECUTE st1(1, 1); + c3 | c3 +-------+------- + 00001 | 00001 +(1 row) + +--Testcase 356: +EXECUTE st1(101, 101); + c3 | c3 +-------+------- + 00101 | 00101 +(1 row) + +-- subquery using stable function (can't be sent to remote) +--Testcase 357: +PREPARE st2(int) AS SELECT * FROM ft1 t1 WHERE (t1.fields->>'C 1')::int < $2 AND t1.tags->>'c3' IN (SELECT tags->>'c3' FROM ft2 t2 WHERE (fields->>'C 1')::int > $1 AND date(time) = '1970-01-17'::date) ORDER BY (fields->>'C 1')::int; +--Testcase 358: +EXPLAIN (VERBOSE, COSTS OFF) EXECUTE st2(10, 20); + QUERY PLAN +--------------------------------------------------------------------------------------- + Sort + Output: t1."time", t1.tags, t1.fields, (((t1.fields ->> 'C 1'::text))::integer) + Sort Key: (((t1.fields ->> 'C 1'::text))::integer) + -> Hash Semi Join + Output: t1."time", t1.tags, t1.fields, ((t1.fields ->> 'C 1'::text))::integer + Hash Cond: ((t1.tags ->> 'c3'::text) = (t2.tags ->> 'c3'::text)) + -> Foreign Scan on public.ft1 t1 + Output: t1."time", t1.tags, t1.fields + InfluxDB query: SELECT * FROM "T1" WHERE (("C 1" < 20)) + -> Hash + Output: t2.tags + -> Foreign Scan on public.ft2 t2 + Output: t2.tags + Filter: (date(t2."time") = '01-17-1970'::date) + InfluxDB query: SELECT * FROM "T1" WHERE (("C 1" > 10)) +(15 rows) + +--Testcase 359: +EXECUTE st2(10, 20); + time | tags | fields +------------------------------+-----------------+---------------------------------------------------------------------- + Sat Jan 17 00:00:00 1970 PST | {"c3": "00016"} | {"c2": "6", "c6": "6", "c7": "6 ", "c8": "foo", "C 1": "16"} +(1 row) + +--Testcase 360: +EXECUTE st2(101, 121); + time | tags | fields +------------------------------+-----------------+----------------------------------------------------------------------- + Sat Jan 17 00:00:00 1970 PST | {"c3": "00116"} | {"c2": "6", "c6": "6", "c7": "6 ", "c8": "foo", "C 1": "116"} +(1 row) + +-- subquery using immutable function (can be sent to remote) +--Testcase 361: +PREPARE st3(int) AS SELECT * FROM ft1 t1 WHERE (t1.fields->>'C 1')::int < $2 AND t1.tags->>'c3' IN (SELECT tags->>'c3' FROM ft2 t2 WHERE (fields->>'C 1')::int > $1 AND date(time) = '1970-01-17'::date) ORDER BY (fields->>'C 1')::int; +--Testcase 362: +EXPLAIN (VERBOSE, COSTS OFF) EXECUTE st3(10, 20); + QUERY PLAN +--------------------------------------------------------------------------------------- + Sort + Output: t1."time", t1.tags, t1.fields, (((t1.fields ->> 'C 1'::text))::integer) + Sort Key: (((t1.fields ->> 'C 1'::text))::integer) + -> Hash Semi Join + Output: t1."time", t1.tags, t1.fields, ((t1.fields ->> 'C 1'::text))::integer + Hash Cond: ((t1.tags ->> 'c3'::text) = (t2.tags ->> 'c3'::text)) + -> Foreign Scan on public.ft1 t1 + Output: t1."time", t1.tags, t1.fields + InfluxDB query: SELECT * FROM "T1" WHERE (("C 1" < 20)) + -> Hash + Output: t2.tags + -> Foreign Scan on public.ft2 t2 + Output: t2.tags + Filter: (date(t2."time") = '01-17-1970'::date) + InfluxDB query: SELECT * FROM "T1" WHERE (("C 1" > 10)) +(15 rows) + +--Testcase 363: +EXECUTE st3(10, 20); + time | tags | fields +------------------------------+-----------------+---------------------------------------------------------------------- + Sat Jan 17 00:00:00 1970 PST | {"c3": "00016"} | {"c2": "6", "c6": "6", "c7": "6 ", "c8": "foo", "C 1": "16"} +(1 row) + +--Testcase 364: +EXECUTE st3(20, 30); + time | tags | fields +------+------+-------- +(0 rows) + +-- custom plan should be chosen initially +--Testcase 365: +PREPARE st4(int) AS SELECT * FROM ft1 t1 WHERE (t1.fields->>'C 1')::int = $1; +--Testcase 366: +EXPLAIN (VERBOSE, COSTS OFF) EXECUTE st4(1); + QUERY PLAN +---------------------------------------------------------- + Foreign Scan on public.ft1 t1 + Output: "time", tags, fields + InfluxDB query: SELECT * FROM "T1" WHERE (("C 1" = 1)) +(3 rows) + +--Testcase 367: +EXPLAIN (VERBOSE, COSTS OFF) EXECUTE st4(1); + QUERY PLAN +---------------------------------------------------------- + Foreign Scan on public.ft1 t1 + Output: "time", tags, fields + InfluxDB query: SELECT * FROM "T1" WHERE (("C 1" = 1)) +(3 rows) + +--Testcase 368: +EXPLAIN (VERBOSE, COSTS OFF) EXECUTE st4(1); + QUERY PLAN +---------------------------------------------------------- + Foreign Scan on public.ft1 t1 + Output: "time", tags, fields + InfluxDB query: SELECT * FROM "T1" WHERE (("C 1" = 1)) +(3 rows) + +--Testcase 369: +EXPLAIN (VERBOSE, COSTS OFF) EXECUTE st4(1); + QUERY PLAN +---------------------------------------------------------- + Foreign Scan on public.ft1 t1 + Output: "time", tags, fields + InfluxDB query: SELECT * FROM "T1" WHERE (("C 1" = 1)) +(3 rows) + +--Testcase 370: +EXPLAIN (VERBOSE, COSTS OFF) EXECUTE st4(1); + QUERY PLAN +---------------------------------------------------------- + Foreign Scan on public.ft1 t1 + Output: "time", tags, fields + InfluxDB query: SELECT * FROM "T1" WHERE (("C 1" = 1)) +(3 rows) + +-- once we try it enough times, should switch to generic plan +--Testcase 371: +EXPLAIN (VERBOSE, COSTS OFF) EXECUTE st4(1); + QUERY PLAN +----------------------------------------------------------- + Foreign Scan on public.ft1 t1 + Output: "time", tags, fields + InfluxDB query: SELECT * FROM "T1" WHERE (("C 1" = $1)) +(3 rows) + +-- value of $1 should not be sent to remote +--Testcase 372: +PREPARE st5(text,int) AS SELECT * FROM ft1 t1 WHERE fields->>'c8' = $1 and (fields->>'C 1')::int = $2; +--Testcase 373: +EXPLAIN (VERBOSE, COSTS OFF) EXECUTE st5('foo', 1); + QUERY PLAN +------------------------------------------------------------------------------- + Foreign Scan on public.ft1 t1 + Output: "time", tags, fields + InfluxDB query: SELECT * FROM "T1" WHERE (("c8" = 'foo')) AND (("C 1" = 1)) +(3 rows) + +--Testcase 374: +EXPLAIN (VERBOSE, COSTS OFF) EXECUTE st5('foo', 1); + QUERY PLAN +------------------------------------------------------------------------------- + Foreign Scan on public.ft1 t1 + Output: "time", tags, fields + InfluxDB query: SELECT * FROM "T1" WHERE (("c8" = 'foo')) AND (("C 1" = 1)) +(3 rows) + +--Testcase 375: +EXPLAIN (VERBOSE, COSTS OFF) EXECUTE st5('foo', 1); + QUERY PLAN +------------------------------------------------------------------------------- + Foreign Scan on public.ft1 t1 + Output: "time", tags, fields + InfluxDB query: SELECT * FROM "T1" WHERE (("c8" = 'foo')) AND (("C 1" = 1)) +(3 rows) + +--Testcase 376: +EXPLAIN (VERBOSE, COSTS OFF) EXECUTE st5('foo', 1); + QUERY PLAN +------------------------------------------------------------------------------- + Foreign Scan on public.ft1 t1 + Output: "time", tags, fields + InfluxDB query: SELECT * FROM "T1" WHERE (("c8" = 'foo')) AND (("C 1" = 1)) +(3 rows) + +--Testcase 377: +EXPLAIN (VERBOSE, COSTS OFF) EXECUTE st5('foo', 1); + QUERY PLAN +------------------------------------------------------------------------------- + Foreign Scan on public.ft1 t1 + Output: "time", tags, fields + InfluxDB query: SELECT * FROM "T1" WHERE (("c8" = 'foo')) AND (("C 1" = 1)) +(3 rows) + +--Testcase 378: +EXPLAIN (VERBOSE, COSTS OFF) EXECUTE st5('foo', 1); + QUERY PLAN +----------------------------------------------------------------------------- + Foreign Scan on public.ft1 t1 + Output: "time", tags, fields + InfluxDB query: SELECT * FROM "T1" WHERE (("c8" = $1)) AND (("C 1" = $2)) +(3 rows) + +--Testcase 379: +EXECUTE st5('foo', 1); + time | tags | fields +------------------------------+-----------------+--------------------------------------------------------------------- + Fri Jan 02 00:00:00 1970 PST | {"c3": "00001"} | {"c2": "1", "c6": "1", "c7": "1 ", "c8": "foo", "C 1": "1"} +(1 row) + +-- altering FDW options requires replanning +--Testcase 380: +PREPARE st6 AS SELECT * FROM ft1 t1 WHERE (t1.fields->>'C 1')::int = (t1.fields->>'c2')::int; +--Testcase 381: +EXPLAIN (VERBOSE, COSTS OFF) EXECUTE st6; + QUERY PLAN +------------------------------------------------------------- + Foreign Scan on public.ft1 t1 + Output: "time", tags, fields + InfluxDB query: SELECT * FROM "T1" WHERE (("C 1" = "c2")) +(3 rows) + +--Testcase 382: +PREPARE st7 AS INSERT INTO ft1_nsc (c1,c2,c3) VALUES (1001,101,'foo'); +--Testcase 383: +EXPLAIN (VERBOSE, COSTS OFF) EXECUTE st7; + QUERY PLAN +--------------------------------------------------------------------------------------------------------------------------------------------------------- + Insert on public.ft1_nsc + Batch Size: 1 + -> Result + Output: NULL::integer, 1001, 101, 'foo'::text, NULL::timestamp with time zone, NULL::character varying, 'ft1 '::character(10), NULL::text +(4 rows) + +--Testcase 384: +INSERT INTO "S 1".s1t0 SELECT * FROM "S 1".s1t1; +--Testcase 385: +ALTER FOREIGN TABLE ft1 OPTIONS (SET table 'T0'); +--Testcase 386: +EXPLAIN (VERBOSE, COSTS OFF) EXECUTE st6; + QUERY PLAN +------------------------------------------------------------- + Foreign Scan on public.ft1 t1 + Output: "time", tags, fields + InfluxDB query: SELECT * FROM "T0" WHERE (("C 1" = "c2")) +(3 rows) + +--Testcase 387: +EXECUTE st6; + time | tags | fields +------------------------------+-----------------+--------------------------------------------------------------------- + Fri Jan 02 00:00:00 1970 PST | {"c3": "00001"} | {"c2": "1", "c6": "1", "c7": "1 ", "c8": "foo", "C 1": "1"} + Sat Jan 03 00:00:00 1970 PST | {"c3": "00002"} | {"c2": "2", "c6": "2", "c7": "2 ", "c8": "foo", "C 1": "2"} + Sun Jan 04 00:00:00 1970 PST | {"c3": "00003"} | {"c2": "3", "c6": "3", "c7": "3 ", "c8": "foo", "C 1": "3"} + Mon Jan 05 00:00:00 1970 PST | {"c3": "00004"} | {"c2": "4", "c6": "4", "c7": "4 ", "c8": "foo", "C 1": "4"} + Tue Jan 06 00:00:00 1970 PST | {"c3": "00005"} | {"c2": "5", "c6": "5", "c7": "5 ", "c8": "foo", "C 1": "5"} + Wed Jan 07 00:00:00 1970 PST | {"c3": "00006"} | {"c2": "6", "c6": "6", "c7": "6 ", "c8": "foo", "C 1": "6"} + Thu Jan 08 00:00:00 1970 PST | {"c3": "00007"} | {"c2": "7", "c6": "7", "c7": "7 ", "c8": "foo", "C 1": "7"} + Fri Jan 09 00:00:00 1970 PST | {"c3": "00008"} | {"c2": "8", "c6": "8", "c7": "8 ", "c8": "foo", "C 1": "8"} + Sat Jan 10 00:00:00 1970 PST | {"c3": "00009"} | {"c2": "9", "c6": "9", "c7": "9 ", "c8": "foo", "C 1": "9"} +(9 rows) + +--Testcase 388: +EXPLAIN (VERBOSE, COSTS OFF) EXECUTE st7; + QUERY PLAN +--------------------------------------------------------------------------------------------------------------------------------------------------------- + Insert on public.ft1_nsc + Batch Size: 1 + -> Result + Output: NULL::integer, 1001, 101, 'foo'::text, NULL::timestamp with time zone, NULL::character varying, 'ft1 '::character(10), NULL::text +(4 rows) + +--Testcase 389: +DELETE FROM "S 1".s1t0; +--Testcase 390: +ALTER FOREIGN TABLE ft1 OPTIONS (SET table 'T1'); +--Testcase 391: +PREPARE st8 AS SELECT count(tags->>'c3') FROM ft1 t1 WHERE (t1.fields->>'C 1')::int === (t1.fields->>'c2')::int; +--Testcase 392: +EXPLAIN (VERBOSE, COSTS OFF) EXECUTE st8; + QUERY PLAN +---------------------------------------------------------------------------------------------------- + Aggregate + Output: count((tags ->> 'c3'::text)) + -> Foreign Scan on public.ft1 t1 + Output: "time", tags, fields + Filter: (((t1.fields ->> 'C 1'::text))::integer === ((t1.fields ->> 'c2'::text))::integer) + InfluxDB query: SELECT * FROM "T1" +(6 rows) + +-- Skip, influxdb_fdw does not support extensions +-- ALTER SERVER loopback OPTIONS (DROP extensions); +--Testcase 393: +EXPLAIN (VERBOSE, COSTS OFF) EXECUTE st8; + QUERY PLAN +---------------------------------------------------------------------------------------------------- + Aggregate + Output: count((tags ->> 'c3'::text)) + -> Foreign Scan on public.ft1 t1 + Output: "time", tags, fields + Filter: (((t1.fields ->> 'C 1'::text))::integer === ((t1.fields ->> 'c2'::text))::integer) + InfluxDB query: SELECT * FROM "T1" +(6 rows) + +--Testcase 394: +EXECUTE st8; + count +------- + 9 +(1 row) + +-- ALTER SERVER loopback OPTIONS (ADD extensions 'influxdb_fdw'); +-- cleanup +DEALLOCATE st1; +DEALLOCATE st2; +DEALLOCATE st3; +DEALLOCATE st4; +DEALLOCATE st5; +DEALLOCATE st6; +DEALLOCATE st7; +DEALLOCATE st8; +-- System columns, except ctid and oid, should not be sent to remote +--Testcase 395: +EXPLAIN (VERBOSE, COSTS OFF) +SELECT * FROM ft1 t1 WHERE t1.tableoid = 'pg_class'::regclass LIMIT 1; + QUERY PLAN +--------------------------------------------- + Limit + Output: "time", tags, fields + -> Foreign Scan on public.ft1 t1 + Output: "time", tags, fields + Filter: (t1.tableoid = '1259'::oid) + InfluxDB query: SELECT * FROM "T1" +(6 rows) + +--Testcase 396: +SELECT * FROM ft1 t1 WHERE t1.tableoid = 'ft1'::regclass ORDER BY (fields->>'C 1')::int LIMIT 1; + time | tags | fields +------------------------------+-----------------+--------------------------------------------------------------------- + Fri Jan 02 00:00:00 1970 PST | {"c3": "00001"} | {"c2": "1", "c6": "1", "c7": "1 ", "c8": "foo", "C 1": "1"} +(1 row) + +--Testcase 397: +EXPLAIN (VERBOSE, COSTS OFF) +SELECT tableoid::regclass, * FROM ft1 t1 LIMIT 1; + QUERY PLAN +------------------------------------------------------ + Foreign Scan on public.ft1 t1 + Output: (tableoid)::regclass, "time", tags, fields + InfluxDB query: SELECT * FROM "T1" LIMIT 1 +(3 rows) + +--Testcase 398: +SELECT tableoid::regclass, * FROM ft1 t1 ORDER BY (fields->>'C 1')::int LIMIT 1; + tableoid | time | tags | fields +----------+------------------------------+-----------------+--------------------------------------------------------------------- + ft1 | Fri Jan 02 00:00:00 1970 PST | {"c3": "00001"} | {"c2": "1", "c6": "1", "c7": "1 ", "c8": "foo", "C 1": "1"} +(1 row) + +--Testcase 399: +EXPLAIN (VERBOSE, COSTS OFF) +SELECT * FROM ft1 t1 WHERE t1.ctid = '(0,2)'; + QUERY PLAN +-------------------------------------- + Foreign Scan on public.ft1 t1 + Output: "time", tags, fields + Filter: (t1.ctid = '(0,2)'::tid) + InfluxDB query: SELECT * FROM "T1" +(4 rows) + +--Testcase 400: +SELECT * FROM ft1 t1 WHERE t1.ctid = '(0,2)'; + time | tags | fields +------+------+-------- +(0 rows) + +--Testcase 401: +EXPLAIN (VERBOSE, COSTS OFF) +SELECT ctid, * FROM ft1 t1 LIMIT 1; + QUERY PLAN +---------------------------------------------- + Foreign Scan on public.ft1 t1 + Output: ctid, "time", tags, fields + InfluxDB query: SELECT * FROM "T1" LIMIT 1 +(3 rows) + +--Testcase 402: +SELECT ctid, * FROM ft1 t1 ORDER BY (fields->>'C 1')::int LIMIT 1; + ctid | time | tags | fields +----------------+------------------------------+-----------------+--------------------------------------------------------------------- + (4294967295,0) | Fri Jan 02 00:00:00 1970 PST | {"c3": "00001"} | {"c2": "1", "c6": "1", "c7": "1 ", "c8": "foo", "C 1": "1"} +(1 row) + +-- =================================================================== +-- used in PL/pgSQL function +-- =================================================================== +--Testcase 403: +CREATE OR REPLACE FUNCTION f_test(p_c1 int) RETURNS int AS $$ +DECLARE + v_c1 int; +BEGIN +--Testcase 404: + SELECT fields->>'C 1' INTO v_c1 FROM ft1 WHERE (fields->>'C 1')::int = p_c1 LIMIT 1; + PERFORM fields->>'C 1' FROM ft1 WHERE (fields->>'C 1')::int = p_c1 AND p_c1 = v_c1 LIMIT 1; + RETURN v_c1; +END; +$$ LANGUAGE plpgsql; +--Testcase 405: +SELECT f_test(100); + f_test +-------- + 100 +(1 row) + +--Testcase 406: +DROP FUNCTION f_test(int); +-- =================================================================== +-- REINDEX +-- =================================================================== +-- remote table is not created here +--Testcase 407: +CREATE FOREIGN TABLE reindex_foreign (fields jsonb OPTIONS(fields 'true')) SERVER influxdb_svr2 OPTIONS (table 'reindex_local', schemaless 'true'); +REINDEX TABLE reindex_foreign; -- error +ERROR: "reindex_foreign" is not a table or materialized view +REINDEX TABLE CONCURRENTLY reindex_foreign; -- error +ERROR: "reindex_foreign" is not a table or materialized view +--Testcase 408: +DROP FOREIGN TABLE reindex_foreign; +-- partitions and foreign tables +--Testcase 409: +CREATE TABLE reind_fdw_parent (c1 int) PARTITION BY RANGE (c1); +--Testcase 410: +CREATE TABLE reind_fdw_0_10 PARTITION OF reind_fdw_parent + FOR VALUES FROM (0) TO (10); +--Testcase 411: +CREATE FOREIGN TABLE reind_fdw_10_20 PARTITION OF reind_fdw_parent + FOR VALUES FROM (10) TO (20) + SERVER influxdb_svr OPTIONS (table 'reind_local_10_20'); +REINDEX TABLE reind_fdw_parent; -- ok +REINDEX TABLE CONCURRENTLY reind_fdw_parent; -- ok +--Testcase 412: +DROP TABLE reind_fdw_parent; +-- =================================================================== +-- conversion error +-- =================================================================== +--Testcase 413: +--ALTER FOREIGN TABLE ft1 ALTER COLUMN c8 TYPE int; +--Testcase 414: +--SELECT * FROM ft1 ftx(x1,x2,x3,x4,x6,x7,x8) WHERE x1 = 1; -- ERROR +--Testcase 415: +--SELECT ftx.x1, ft2.c2, ftx.x8 FROM ft1 ftx(x1,x2,x3,x4,x6,x7,x8), ft2 +-- WHERE ftx.x1 = (ft2.fields->>'C 1')::int AND ftx.x1 = 1; -- ERROR +--Testcase 416: +--SELECT ftx.x1, ft2.c2, ftx FROM ft1 ftx(x1,x2,x3,x4,x6,x7,x8), ft2 +-- WHERE ftx.x1 = (ft2.fields->>'C 1')::int AND ftx.x1 = 1; -- ERROR +--Testcase 417: +--SELECT sum(c2), array_agg(c8) FROM ft1 GROUP BY c8; -- ERROR +-- ANALYZE ft1; -- ERROR +--ALTER FOREIGN TABLE ft1 ALTER COLUMN c8 TYPE user_enum; +-- =================================================================== +-- local type can be different from remote type in some cases, +-- in particular if similarly-named operators do equivalent things +-- =================================================================== +--Testcase 768: +EXPLAIN (VERBOSE, COSTS OFF) +SELECT * FROM ft1 WHERE (fields->>'c8')::text = 'foo' LIMIT 1; + QUERY PLAN +--------------------------------------------------------------------- + Foreign Scan on public.ft1 + Output: "time", tags, fields + InfluxDB query: SELECT * FROM "T1" WHERE (("c8" = 'foo')) LIMIT 1 +(3 rows) + +--Testcase 769: +SELECT * FROM ft1 WHERE (fields->>'c8')::text = 'foo' LIMIT 1; + time | tags | fields +------------------------------+-----------------+----------------------------------------------------------------------- + Thu Jan 01 00:00:00 1970 PST | {"c3": "00100"} | {"c2": "0", "c6": "0", "c7": "0 ", "c8": "foo", "C 1": "100"} +(1 row) + +--Testcase 770: +EXPLAIN (VERBOSE, COSTS OFF) +SELECT * FROM ft1 WHERE 'foo' = (fields->>'c8')::text LIMIT 1; + QUERY PLAN +--------------------------------------------------------------------- + Foreign Scan on public.ft1 + Output: "time", tags, fields + InfluxDB query: SELECT * FROM "T1" WHERE (('foo' = "c8")) LIMIT 1 +(3 rows) + +--Testcase 771: +SELECT * FROM ft1 WHERE 'foo' = (fields->>'c8')::text LIMIT 1; + time | tags | fields +------------------------------+-----------------+----------------------------------------------------------------------- + Thu Jan 01 00:00:00 1970 PST | {"c3": "00100"} | {"c2": "0", "c6": "0", "c7": "0 ", "c8": "foo", "C 1": "100"} +(1 row) + +-- we declared c8 to be text locally, but it's still the same type on +-- the remote which will balk if we try to do anything incompatible +-- with that remote type +-- Can not create user define type in InfluxDB. +-- Type c8 of foreign table ft1 and remote table T1 are +-- match. These case below not error with influxdb_fdw. +--Testcase 772: +SELECT * FROM ft1 WHERE (fields->>'c8')::text LIKE 'foo' LIMIT 1; -- ERROR + time | tags | fields +------------------------------+-----------------+----------------------------------------------------------------------- + Thu Jan 01 00:00:00 1970 PST | {"c3": "00100"} | {"c2": "0", "c6": "0", "c7": "0 ", "c8": "foo", "C 1": "100"} +(1 row) + +--Testcase 773: +SELECT * FROM ft1 WHERE ((fields->>'c8')::text)::text LIKE 'foo' LIMIT 1; -- ERROR; cast not pushed down + time | tags | fields +------------------------------+-----------------+----------------------------------------------------------------------- + Thu Jan 01 00:00:00 1970 PST | {"c3": "00100"} | {"c2": "0", "c6": "0", "c7": "0 ", "c8": "foo", "C 1": "100"} +(1 row) + +/* +-- influxdb_fdw does not support transactions +-- =================================================================== +-- subtransaction +-- + local/remote error doesn't break cursor +-- =================================================================== +BEGIN; +DECLARE c CURSOR FOR SELECT * FROM ft1 ORDER BY c1; +FETCH c; +SAVEPOINT s; +ERROR OUT; -- ERROR +ROLLBACK TO s; +FETCH c; +SAVEPOINT s; +SELECT * FROM ft1 WHERE 1 / (c1 - 1) > 0; -- ERROR +ROLLBACK TO s; +FETCH c; +SELECT * FROM ft1 ORDER BY c1 LIMIT 1; +COMMIT; +*/ +-- =================================================================== +-- test handling of collations +-- =================================================================== +--Testcase 419: +create foreign table loct3 (fields jsonb OPTIONS(fields 'true')) SERVER influxdb_svr OPTIONS (table 'loct3', schemaless 'true'); +--Testcase 420: +create foreign table ft3 (fields jsonb OPTIONS(fields 'true')) SERVER influxdb_svr OPTIONS (table 'loct3', schemaless 'true'); +-- can be sent to remote +--Testcase 421: +explain (verbose, costs off) select * from ft3 where fields->>'f1' = 'foo'; + QUERY PLAN +---------------------------------------------------------------- + Foreign Scan on public.ft3 + Output: fields + InfluxDB query: SELECT * FROM "loct3" WHERE (("f1" = 'foo')) +(3 rows) + +--Testcase 422: +explain (verbose, costs off) select * from ft3 where fields->>'f1' COLLATE "C" = 'foo'; + QUERY PLAN +---------------------------------------------------------------- + Foreign Scan on public.ft3 + Output: fields + InfluxDB query: SELECT * FROM "loct3" WHERE (("f1" = 'foo')) +(3 rows) + +--Testcase 423: +explain (verbose, costs off) select * from ft3 where fields->>'f2' = 'foo'; + QUERY PLAN +---------------------------------------------------------------- + Foreign Scan on public.ft3 + Output: fields + InfluxDB query: SELECT * FROM "loct3" WHERE (("f2" = 'foo')) +(3 rows) + +--Testcase 424: +explain (verbose, costs off) select * from ft3 where fields->>'f3' = 'foo'; + QUERY PLAN +---------------------------------------------------------------- + Foreign Scan on public.ft3 + Output: fields + InfluxDB query: SELECT * FROM "loct3" WHERE (("f3" = 'foo')) +(3 rows) + +--Testcase 425: +explain (verbose, costs off) select * from ft3 f, loct3 l + where f.fields->>'f3' = l.fields->>'f3' and l.fields->>'f1' = 'foo'; + QUERY PLAN +---------------------------------------------------------------------------- + Hash Join + Output: f.fields, l.fields + Hash Cond: ((f.fields ->> 'f3'::text) = (l.fields ->> 'f3'::text)) + -> Foreign Scan on public.ft3 f + Output: f.fields + InfluxDB query: SELECT * FROM "loct3" + -> Hash + Output: l.fields + -> Foreign Scan on public.loct3 l + Output: l.fields + InfluxDB query: SELECT * FROM "loct3" WHERE (("f1" = 'foo')) +(11 rows) + +-- can't be sent to remote +--Testcase 426: +explain (verbose, costs off) select * from ft3 where fields->>'f1' COLLATE "POSIX" = 'foo'; + QUERY PLAN +---------------------------------------------------------------- + Foreign Scan on public.ft3 + Output: fields + InfluxDB query: SELECT * FROM "loct3" WHERE (("f1" = 'foo')) +(3 rows) + +--Testcase 427: +explain (verbose, costs off) select * from ft3 where fields->>'f1' = 'foo' COLLATE "C"; + QUERY PLAN +------------------------------------------------------------------- + Foreign Scan on public.ft3 + Output: fields + Filter: ((ft3.fields ->> 'f1'::text) = 'foo'::text COLLATE "C") + InfluxDB query: SELECT * FROM "loct3" +(4 rows) + +--Testcase 428: +explain (verbose, costs off) select * from ft3 where fields->>'f2' COLLATE "C" = 'foo'; + QUERY PLAN +---------------------------------------------------------------- + Foreign Scan on public.ft3 + Output: fields + InfluxDB query: SELECT * FROM "loct3" WHERE (("f2" = 'foo')) +(3 rows) + +--Testcase 429: +explain (verbose, costs off) select * from ft3 where fields->>'f2' = 'foo' COLLATE "C"; + QUERY PLAN +------------------------------------------------------------------- + Foreign Scan on public.ft3 + Output: fields + Filter: ((ft3.fields ->> 'f2'::text) = 'foo'::text COLLATE "C") + InfluxDB query: SELECT * FROM "loct3" +(4 rows) + +--Testcase 430: +explain (verbose, costs off) select * from ft3 f, loct3 l + where f.fields->>'f3' = l.fields->>'f3' COLLATE "POSIX" and l.fields->>'f1' = 'foo'; + QUERY PLAN +---------------------------------------------------------------------------------------------- + Hash Join + Output: f.fields, l.fields + Hash Cond: (((f.fields ->> 'f3'::text))::text = (l.fields ->> 'f3'::text COLLATE "POSIX")) + -> Foreign Scan on public.ft3 f + Output: f.fields + InfluxDB query: SELECT * FROM "loct3" + -> Hash + Output: l.fields + -> Foreign Scan on public.loct3 l + Output: l.fields + InfluxDB query: SELECT * FROM "loct3" WHERE (("f1" = 'foo')) +(11 rows) + +-- influxdb_fdw does not support UPDATE +-- =================================================================== +-- test writable foreign table stuff +-- =================================================================== +--Testcase 431: +EXPLAIN (verbose, costs off) +INSERT INTO ft2_nsc (c1,c2,c3) SELECT c1+1000,c2+100, c3 || c3 FROM ft2_nsc ORDER BY c1 LIMIT 20; + QUERY PLAN +---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- + Insert on public.ft2_nsc + Batch Size: 1 + -> Subquery Scan on "*SELECT*" + Output: "*SELECT*"."?column?", "*SELECT*"."?column?_1", NULL::integer, "*SELECT*"."?column?_2", NULL::timestamp with time zone, NULL::character varying, 'ft2 '::character(10), NULL::text + -> Limit + Output: ((ft2_nsc_1.c1 + 1000)), ((ft2_nsc_1.c2 + 100)), ((ft2_nsc_1.c3 || ft2_nsc_1.c3)), ft2_nsc_1.c1 + -> Sort + Output: ((ft2_nsc_1.c1 + 1000)), ((ft2_nsc_1.c2 + 100)), ((ft2_nsc_1.c3 || ft2_nsc_1.c3)), ft2_nsc_1.c1 + Sort Key: ft2_nsc_1.c1 + -> Foreign Scan on public.ft2_nsc ft2_nsc_1 + Output: (ft2_nsc_1.c1 + 1000), (ft2_nsc_1.c2 + 100), (ft2_nsc_1.c3 || ft2_nsc_1.c3), ft2_nsc_1.c1 + InfluxDB query: SELECT "C 1", "c2", "c3" FROM "T1" +(12 rows) + +--Testcase 432: +INSERT INTO ft2_nsc (c1,c2,c3) SELECT c1+1000,c2+100, c3 || c3 FROM ft2_nsc ORDER BY c1 LIMIT 20; +--Testcase 433: +INSERT INTO ft2_nsc (c1,c2,c3) VALUES (1101,201,'aaa'), (1102,202,'bbb'), (1103,203,'ccc'); +--Testcase 434: +SELECT (fields->>'C 1')::int c1, (fields->>'c2')::int c2, tags->>'c3' c3, fields->>'c6' c6, fields->>'c7' c7, fields->>'c8' c8 FROM ft2 WHERE (fields->>'c2')::int > 200; + c1 | c2 | c3 | c6 | c7 | c8 +------+-----+-----+----+------------+---- + 1101 | 201 | aaa | | ft2 | + 1102 | 202 | bbb | | ft2 | + 1103 | 203 | ccc | | ft2 | +(3 rows) + +--Testcase 435: +INSERT INTO ft2_nsc (c1,c2,c3) VALUES (1104,204,'ddd'), (1105,205,'eee'); +--EXPLAIN (verbose, costs off) +--UPDATE ft2 SET c2 = c2 + 300, c3 = c3 || '_update3' WHERE c1 % 10 = 3; -- can be pushed down +--UPDATE ft2 SET c2 = c2 + 300, c3 = c3 || '_update3' WHERE c1 % 10 = 3; +--EXPLAIN (verbose, costs off) +--UPDATE ft2 SET c2 = c2 + 400, c3 = c3 || '_update7' WHERE c1 % 10 = 7 RETURNING *; -- can be pushed down +--UPDATE ft2 SET c2 = c2 + 400, c3 = c3 || '_update7' WHERE c1 % 10 = 7 RETURNING *; +--EXPLAIN (verbose, costs off) +--UPDATE ft2 SET c2 = ft2.c2 + 500, c3 = ft2.c3 || '_update9', c7 = DEFAULT +-- FROM ft1 WHERE ft1.c1 = ft2.c2 AND ft1.c1 % 10 = 9; -- can be pushed down +--UPDATE ft2 SET c2 = ft2.c2 + 500, c3 = ft2.c3 || '_update9', c7 = DEFAULT +-- FROM ft1 WHERE ft1.c1 = ft2.c2 AND ft1.c1 % 10 = 9; +--Testcase 436: +EXPLAIN (verbose, costs off) + DELETE FROM ft2_nsc WHERE c1 % 10 = 5; -- can be pushed down + QUERY PLAN +--------------------------------------------------------------------------------- + Delete on public.ft2_nsc + -> Foreign Scan on public.ft2_nsc + Output: c3, "time" + InfluxDB query: SELECT "c3", "C 1" FROM "T1" WHERE ((("C 1" % 10) = 5)) +(4 rows) + +--Testcase 437: +SELECT (fields->>'C 1')::int c1 FROM ft2 WHERE (fields->>'C 1')::int % 10 = 5 ORDER BY (fields->>'C 1')::int; + c1 +------ + 5 + 15 + 25 + 35 + 45 + 55 + 65 + 75 + 85 + 95 + 105 + 115 + 125 + 135 + 145 + 155 + 165 + 175 + 185 + 195 + 205 + 215 + 225 + 235 + 245 + 255 + 265 + 275 + 285 + 295 + 305 + 315 + 325 + 335 + 345 + 355 + 365 + 375 + 385 + 395 + 405 + 415 + 425 + 435 + 445 + 455 + 465 + 475 + 485 + 495 + 505 + 515 + 525 + 535 + 545 + 555 + 565 + 575 + 585 + 595 + 605 + 615 + 625 + 635 + 645 + 655 + 665 + 675 + 685 + 695 + 705 + 715 + 725 + 735 + 745 + 755 + 765 + 775 + 785 + 795 + 805 + 815 + 825 + 835 + 845 + 855 + 865 + 875 + 885 + 895 + 905 + 915 + 925 + 935 + 945 + 955 + 965 + 975 + 985 + 995 + 1005 + 1015 + 1105 +(103 rows) + +--Testcase 438: +DELETE FROM ft2_nsc WHERE c1 % 10 = 5; +--Testcase 439: +SELECT (fields->>'C 1')::int c1 FROM ft2 WHERE (fields->>'C 1')::int % 10 = 5; + c1 +---- +(0 rows) + +--Testcase 440: +EXPLAIN (verbose, costs off) +DELETE FROM ft2_nsc USING ft1_nsc WHERE ft1_nsc.c1 = ft2_nsc.c2 AND ft1_nsc.c1 % 10 = 2; + QUERY PLAN +--------------------------------------------------------------------------------------------------------------------- + Delete on public.ft2_nsc + -> Hash Join + Output: ft2_nsc.c3, ft2_nsc."time", ft1_nsc.* + Hash Cond: (ft2_nsc.c2 = ft1_nsc.c1) + -> Foreign Scan on public.ft2_nsc + Output: ft2_nsc.c3, ft2_nsc."time", ft2_nsc.c2 + InfluxDB query: SELECT "c2", "c3" FROM "T1" + -> Hash + Output: ft1_nsc.*, ft1_nsc.c1 + -> Foreign Scan on public.ft1_nsc + Output: ft1_nsc.*, ft1_nsc.c1 + InfluxDB query: SELECT "C 1", "c2", "c3", "c6", "c7", "c8" FROM "T1" WHERE ((("C 1" % 10) = 2)) +(12 rows) + +--Testcase 441: +DELETE FROM ft2_nsc USING ft1_nsc WHERE ft1_nsc.c1 = ft2_nsc.c2 AND ft1_nsc.c1 % 10 = 2; +--Testcase 442: +SELECT (fields->>'C 1')::int c1, (fields->>'c2')::int c2, tags->>'c3' c3 FROM ft2 ORDER BY (fields->>'C 1')::int; + c1 | c2 | c3 +------+-----+------------ + 1 | 1 | 00001 + 3 | 3 | 00003 + 4 | 4 | 00004 + 6 | 6 | 00006 + 7 | 7 | 00007 + 8 | 8 | 00008 + 9 | 9 | 00009 + 10 | 0 | 00010 + 11 | 1 | 00011 + 13 | 3 | 00013 + 14 | 4 | 00014 + 16 | 6 | 00016 + 17 | 7 | 00017 + 18 | 8 | 00018 + 19 | 9 | 00019 + 20 | 0 | 00020 + 21 | 1 | 00021 + 23 | 3 | 00023 + 24 | 4 | 00024 + 26 | 6 | 00026 + 27 | 7 | 00027 + 28 | 8 | 00028 + 29 | 9 | 00029 + 30 | 0 | 00030 + 31 | 1 | 00031 + 33 | 3 | 00033 + 34 | 4 | 00034 + 36 | 6 | 00036 + 37 | 7 | 00037 + 38 | 8 | 00038 + 39 | 9 | 00039 + 40 | 0 | 00040 + 41 | 1 | 00041 + 43 | 3 | 00043 + 44 | 4 | 00044 + 46 | 6 | 00046 + 47 | 7 | 00047 + 48 | 8 | 00048 + 49 | 9 | 00049 + 50 | 0 | 00050 + 51 | 1 | 00051 + 53 | 3 | 00053 + 54 | 4 | 00054 + 56 | 6 | 00056 + 57 | 7 | 00057 + 58 | 8 | 00058 + 59 | 9 | 00059 + 60 | 0 | 00060 + 61 | 1 | 00061 + 63 | 3 | 00063 + 64 | 4 | 00064 + 66 | 6 | 00066 + 67 | 7 | 00067 + 68 | 8 | 00068 + 69 | 9 | 00069 + 70 | 0 | 00070 + 71 | 1 | 00071 + 73 | 3 | 00073 + 74 | 4 | 00074 + 76 | 6 | 00076 + 77 | 7 | 00077 + 78 | 8 | 00078 + 79 | 9 | 00079 + 80 | 0 | 00080 + 81 | 1 | 00081 + 83 | 3 | 00083 + 84 | 4 | 00084 + 86 | 6 | 00086 + 87 | 7 | 00087 + 88 | 8 | 00088 + 89 | 9 | 00089 + 90 | 0 | 00090 + 91 | 1 | 00091 + 93 | 3 | 00093 + 94 | 4 | 00094 + 96 | 6 | 00096 + 97 | 7 | 00097 + 98 | 8 | 00098 + 99 | 9 | 00099 + 100 | 0 | 00100 + 101 | 1 | 00101 + 103 | 3 | 00103 + 104 | 4 | 00104 + 106 | 6 | 00106 + 107 | 7 | 00107 + 108 | 8 | 00108 + 109 | 9 | 00109 + 110 | 0 | 00110 + 111 | 1 | 00111 + 113 | 3 | 00113 + 114 | 4 | 00114 + 116 | 6 | 00116 + 117 | 7 | 00117 + 118 | 8 | 00118 + 119 | 9 | 00119 + 120 | 0 | 00120 + 121 | 1 | 00121 + 123 | 3 | 00123 + 124 | 4 | 00124 + 126 | 6 | 00126 + 127 | 7 | 00127 + 128 | 8 | 00128 + 129 | 9 | 00129 + 130 | 0 | 00130 + 131 | 1 | 00131 + 133 | 3 | 00133 + 134 | 4 | 00134 + 136 | 6 | 00136 + 137 | 7 | 00137 + 138 | 8 | 00138 + 139 | 9 | 00139 + 140 | 0 | 00140 + 141 | 1 | 00141 + 143 | 3 | 00143 + 144 | 4 | 00144 + 146 | 6 | 00146 + 147 | 7 | 00147 + 148 | 8 | 00148 + 149 | 9 | 00149 + 150 | 0 | 00150 + 151 | 1 | 00151 + 153 | 3 | 00153 + 154 | 4 | 00154 + 156 | 6 | 00156 + 157 | 7 | 00157 + 158 | 8 | 00158 + 159 | 9 | 00159 + 160 | 0 | 00160 + 161 | 1 | 00161 + 163 | 3 | 00163 + 164 | 4 | 00164 + 166 | 6 | 00166 + 167 | 7 | 00167 + 168 | 8 | 00168 + 169 | 9 | 00169 + 170 | 0 | 00170 + 171 | 1 | 00171 + 173 | 3 | 00173 + 174 | 4 | 00174 + 176 | 6 | 00176 + 177 | 7 | 00177 + 178 | 8 | 00178 + 179 | 9 | 00179 + 180 | 0 | 00180 + 181 | 1 | 00181 + 183 | 3 | 00183 + 184 | 4 | 00184 + 186 | 6 | 00186 + 187 | 7 | 00187 + 188 | 8 | 00188 + 189 | 9 | 00189 + 190 | 0 | 00190 + 191 | 1 | 00191 + 193 | 3 | 00193 + 194 | 4 | 00194 + 196 | 6 | 00196 + 197 | 7 | 00197 + 198 | 8 | 00198 + 199 | 9 | 00199 + 200 | 0 | 00200 + 201 | 1 | 00201 + 203 | 3 | 00203 + 204 | 4 | 00204 + 206 | 6 | 00206 + 207 | 7 | 00207 + 208 | 8 | 00208 + 209 | 9 | 00209 + 210 | 0 | 00210 + 211 | 1 | 00211 + 213 | 3 | 00213 + 214 | 4 | 00214 + 216 | 6 | 00216 + 217 | 7 | 00217 + 218 | 8 | 00218 + 219 | 9 | 00219 + 220 | 0 | 00220 + 221 | 1 | 00221 + 223 | 3 | 00223 + 224 | 4 | 00224 + 226 | 6 | 00226 + 227 | 7 | 00227 + 228 | 8 | 00228 + 229 | 9 | 00229 + 230 | 0 | 00230 + 231 | 1 | 00231 + 233 | 3 | 00233 + 234 | 4 | 00234 + 236 | 6 | 00236 + 237 | 7 | 00237 + 238 | 8 | 00238 + 239 | 9 | 00239 + 240 | 0 | 00240 + 241 | 1 | 00241 + 243 | 3 | 00243 + 244 | 4 | 00244 + 246 | 6 | 00246 + 247 | 7 | 00247 + 248 | 8 | 00248 + 249 | 9 | 00249 + 250 | 0 | 00250 + 251 | 1 | 00251 + 253 | 3 | 00253 + 254 | 4 | 00254 + 256 | 6 | 00256 + 257 | 7 | 00257 + 258 | 8 | 00258 + 259 | 9 | 00259 + 260 | 0 | 00260 + 261 | 1 | 00261 + 263 | 3 | 00263 + 264 | 4 | 00264 + 266 | 6 | 00266 + 267 | 7 | 00267 + 268 | 8 | 00268 + 269 | 9 | 00269 + 270 | 0 | 00270 + 271 | 1 | 00271 + 273 | 3 | 00273 + 274 | 4 | 00274 + 276 | 6 | 00276 + 277 | 7 | 00277 + 278 | 8 | 00278 + 279 | 9 | 00279 + 280 | 0 | 00280 + 281 | 1 | 00281 + 283 | 3 | 00283 + 284 | 4 | 00284 + 286 | 6 | 00286 + 287 | 7 | 00287 + 288 | 8 | 00288 + 289 | 9 | 00289 + 290 | 0 | 00290 + 291 | 1 | 00291 + 293 | 3 | 00293 + 294 | 4 | 00294 + 296 | 6 | 00296 + 297 | 7 | 00297 + 298 | 8 | 00298 + 299 | 9 | 00299 + 300 | 0 | 00300 + 301 | 1 | 00301 + 303 | 3 | 00303 + 304 | 4 | 00304 + 306 | 6 | 00306 + 307 | 7 | 00307 + 308 | 8 | 00308 + 309 | 9 | 00309 + 310 | 0 | 00310 + 311 | 1 | 00311 + 313 | 3 | 00313 + 314 | 4 | 00314 + 316 | 6 | 00316 + 317 | 7 | 00317 + 318 | 8 | 00318 + 319 | 9 | 00319 + 320 | 0 | 00320 + 321 | 1 | 00321 + 323 | 3 | 00323 + 324 | 4 | 00324 + 326 | 6 | 00326 + 327 | 7 | 00327 + 328 | 8 | 00328 + 329 | 9 | 00329 + 330 | 0 | 00330 + 331 | 1 | 00331 + 333 | 3 | 00333 + 334 | 4 | 00334 + 336 | 6 | 00336 + 337 | 7 | 00337 + 338 | 8 | 00338 + 339 | 9 | 00339 + 340 | 0 | 00340 + 341 | 1 | 00341 + 343 | 3 | 00343 + 344 | 4 | 00344 + 346 | 6 | 00346 + 347 | 7 | 00347 + 348 | 8 | 00348 + 349 | 9 | 00349 + 350 | 0 | 00350 + 351 | 1 | 00351 + 353 | 3 | 00353 + 354 | 4 | 00354 + 356 | 6 | 00356 + 357 | 7 | 00357 + 358 | 8 | 00358 + 359 | 9 | 00359 + 360 | 0 | 00360 + 361 | 1 | 00361 + 363 | 3 | 00363 + 364 | 4 | 00364 + 366 | 6 | 00366 + 367 | 7 | 00367 + 368 | 8 | 00368 + 369 | 9 | 00369 + 370 | 0 | 00370 + 371 | 1 | 00371 + 373 | 3 | 00373 + 374 | 4 | 00374 + 376 | 6 | 00376 + 377 | 7 | 00377 + 378 | 8 | 00378 + 379 | 9 | 00379 + 380 | 0 | 00380 + 381 | 1 | 00381 + 383 | 3 | 00383 + 384 | 4 | 00384 + 386 | 6 | 00386 + 387 | 7 | 00387 + 388 | 8 | 00388 + 389 | 9 | 00389 + 390 | 0 | 00390 + 391 | 1 | 00391 + 393 | 3 | 00393 + 394 | 4 | 00394 + 396 | 6 | 00396 + 397 | 7 | 00397 + 398 | 8 | 00398 + 399 | 9 | 00399 + 400 | 0 | 00400 + 401 | 1 | 00401 + 403 | 3 | 00403 + 404 | 4 | 00404 + 406 | 6 | 00406 + 407 | 7 | 00407 + 408 | 8 | 00408 + 409 | 9 | 00409 + 410 | 0 | 00410 + 411 | 1 | 00411 + 413 | 3 | 00413 + 414 | 4 | 00414 + 416 | 6 | 00416 + 417 | 7 | 00417 + 418 | 8 | 00418 + 419 | 9 | 00419 + 420 | 0 | 00420 + 421 | 1 | 00421 + 423 | 3 | 00423 + 424 | 4 | 00424 + 426 | 6 | 00426 + 427 | 7 | 00427 + 428 | 8 | 00428 + 429 | 9 | 00429 + 430 | 0 | 00430 + 431 | 1 | 00431 + 433 | 3 | 00433 + 434 | 4 | 00434 + 436 | 6 | 00436 + 437 | 7 | 00437 + 438 | 8 | 00438 + 439 | 9 | 00439 + 440 | 0 | 00440 + 441 | 1 | 00441 + 443 | 3 | 00443 + 444 | 4 | 00444 + 446 | 6 | 00446 + 447 | 7 | 00447 + 448 | 8 | 00448 + 449 | 9 | 00449 + 450 | 0 | 00450 + 451 | 1 | 00451 + 453 | 3 | 00453 + 454 | 4 | 00454 + 456 | 6 | 00456 + 457 | 7 | 00457 + 458 | 8 | 00458 + 459 | 9 | 00459 + 460 | 0 | 00460 + 461 | 1 | 00461 + 463 | 3 | 00463 + 464 | 4 | 00464 + 466 | 6 | 00466 + 467 | 7 | 00467 + 468 | 8 | 00468 + 469 | 9 | 00469 + 470 | 0 | 00470 + 471 | 1 | 00471 + 473 | 3 | 00473 + 474 | 4 | 00474 + 476 | 6 | 00476 + 477 | 7 | 00477 + 478 | 8 | 00478 + 479 | 9 | 00479 + 480 | 0 | 00480 + 481 | 1 | 00481 + 483 | 3 | 00483 + 484 | 4 | 00484 + 486 | 6 | 00486 + 487 | 7 | 00487 + 488 | 8 | 00488 + 489 | 9 | 00489 + 490 | 0 | 00490 + 491 | 1 | 00491 + 493 | 3 | 00493 + 494 | 4 | 00494 + 496 | 6 | 00496 + 497 | 7 | 00497 + 498 | 8 | 00498 + 499 | 9 | 00499 + 500 | 0 | 00500 + 501 | 1 | 00501 + 503 | 3 | 00503 + 504 | 4 | 00504 + 506 | 6 | 00506 + 507 | 7 | 00507 + 508 | 8 | 00508 + 509 | 9 | 00509 + 510 | 0 | 00510 + 511 | 1 | 00511 + 513 | 3 | 00513 + 514 | 4 | 00514 + 516 | 6 | 00516 + 517 | 7 | 00517 + 518 | 8 | 00518 + 519 | 9 | 00519 + 520 | 0 | 00520 + 521 | 1 | 00521 + 523 | 3 | 00523 + 524 | 4 | 00524 + 526 | 6 | 00526 + 527 | 7 | 00527 + 528 | 8 | 00528 + 529 | 9 | 00529 + 530 | 0 | 00530 + 531 | 1 | 00531 + 533 | 3 | 00533 + 534 | 4 | 00534 + 536 | 6 | 00536 + 537 | 7 | 00537 + 538 | 8 | 00538 + 539 | 9 | 00539 + 540 | 0 | 00540 + 541 | 1 | 00541 + 543 | 3 | 00543 + 544 | 4 | 00544 + 546 | 6 | 00546 + 547 | 7 | 00547 + 548 | 8 | 00548 + 549 | 9 | 00549 + 550 | 0 | 00550 + 551 | 1 | 00551 + 553 | 3 | 00553 + 554 | 4 | 00554 + 556 | 6 | 00556 + 557 | 7 | 00557 + 558 | 8 | 00558 + 559 | 9 | 00559 + 560 | 0 | 00560 + 561 | 1 | 00561 + 563 | 3 | 00563 + 564 | 4 | 00564 + 566 | 6 | 00566 + 567 | 7 | 00567 + 568 | 8 | 00568 + 569 | 9 | 00569 + 570 | 0 | 00570 + 571 | 1 | 00571 + 573 | 3 | 00573 + 574 | 4 | 00574 + 576 | 6 | 00576 + 577 | 7 | 00577 + 578 | 8 | 00578 + 579 | 9 | 00579 + 580 | 0 | 00580 + 581 | 1 | 00581 + 583 | 3 | 00583 + 584 | 4 | 00584 + 586 | 6 | 00586 + 587 | 7 | 00587 + 588 | 8 | 00588 + 589 | 9 | 00589 + 590 | 0 | 00590 + 591 | 1 | 00591 + 593 | 3 | 00593 + 594 | 4 | 00594 + 596 | 6 | 00596 + 597 | 7 | 00597 + 598 | 8 | 00598 + 599 | 9 | 00599 + 600 | 0 | 00600 + 601 | 1 | 00601 + 603 | 3 | 00603 + 604 | 4 | 00604 + 606 | 6 | 00606 + 607 | 7 | 00607 + 608 | 8 | 00608 + 609 | 9 | 00609 + 610 | 0 | 00610 + 611 | 1 | 00611 + 613 | 3 | 00613 + 614 | 4 | 00614 + 616 | 6 | 00616 + 617 | 7 | 00617 + 618 | 8 | 00618 + 619 | 9 | 00619 + 620 | 0 | 00620 + 621 | 1 | 00621 + 623 | 3 | 00623 + 624 | 4 | 00624 + 626 | 6 | 00626 + 627 | 7 | 00627 + 628 | 8 | 00628 + 629 | 9 | 00629 + 630 | 0 | 00630 + 631 | 1 | 00631 + 633 | 3 | 00633 + 634 | 4 | 00634 + 636 | 6 | 00636 + 637 | 7 | 00637 + 638 | 8 | 00638 + 639 | 9 | 00639 + 640 | 0 | 00640 + 641 | 1 | 00641 + 643 | 3 | 00643 + 644 | 4 | 00644 + 646 | 6 | 00646 + 647 | 7 | 00647 + 648 | 8 | 00648 + 649 | 9 | 00649 + 650 | 0 | 00650 + 651 | 1 | 00651 + 653 | 3 | 00653 + 654 | 4 | 00654 + 656 | 6 | 00656 + 657 | 7 | 00657 + 658 | 8 | 00658 + 659 | 9 | 00659 + 660 | 0 | 00660 + 661 | 1 | 00661 + 663 | 3 | 00663 + 664 | 4 | 00664 + 666 | 6 | 00666 + 667 | 7 | 00667 + 668 | 8 | 00668 + 669 | 9 | 00669 + 670 | 0 | 00670 + 671 | 1 | 00671 + 673 | 3 | 00673 + 674 | 4 | 00674 + 676 | 6 | 00676 + 677 | 7 | 00677 + 678 | 8 | 00678 + 679 | 9 | 00679 + 680 | 0 | 00680 + 681 | 1 | 00681 + 683 | 3 | 00683 + 684 | 4 | 00684 + 686 | 6 | 00686 + 687 | 7 | 00687 + 688 | 8 | 00688 + 689 | 9 | 00689 + 690 | 0 | 00690 + 691 | 1 | 00691 + 693 | 3 | 00693 + 694 | 4 | 00694 + 696 | 6 | 00696 + 697 | 7 | 00697 + 698 | 8 | 00698 + 699 | 9 | 00699 + 700 | 0 | 00700 + 701 | 1 | 00701 + 703 | 3 | 00703 + 704 | 4 | 00704 + 706 | 6 | 00706 + 707 | 7 | 00707 + 708 | 8 | 00708 + 709 | 9 | 00709 + 710 | 0 | 00710 + 711 | 1 | 00711 + 713 | 3 | 00713 + 714 | 4 | 00714 + 716 | 6 | 00716 + 717 | 7 | 00717 + 718 | 8 | 00718 + 719 | 9 | 00719 + 720 | 0 | 00720 + 721 | 1 | 00721 + 723 | 3 | 00723 + 724 | 4 | 00724 + 726 | 6 | 00726 + 727 | 7 | 00727 + 728 | 8 | 00728 + 729 | 9 | 00729 + 730 | 0 | 00730 + 731 | 1 | 00731 + 733 | 3 | 00733 + 734 | 4 | 00734 + 736 | 6 | 00736 + 737 | 7 | 00737 + 738 | 8 | 00738 + 739 | 9 | 00739 + 740 | 0 | 00740 + 741 | 1 | 00741 + 743 | 3 | 00743 + 744 | 4 | 00744 + 746 | 6 | 00746 + 747 | 7 | 00747 + 748 | 8 | 00748 + 749 | 9 | 00749 + 750 | 0 | 00750 + 751 | 1 | 00751 + 753 | 3 | 00753 + 754 | 4 | 00754 + 756 | 6 | 00756 + 757 | 7 | 00757 + 758 | 8 | 00758 + 759 | 9 | 00759 + 760 | 0 | 00760 + 761 | 1 | 00761 + 763 | 3 | 00763 + 764 | 4 | 00764 + 766 | 6 | 00766 + 767 | 7 | 00767 + 768 | 8 | 00768 + 769 | 9 | 00769 + 770 | 0 | 00770 + 771 | 1 | 00771 + 773 | 3 | 00773 + 774 | 4 | 00774 + 776 | 6 | 00776 + 777 | 7 | 00777 + 778 | 8 | 00778 + 779 | 9 | 00779 + 780 | 0 | 00780 + 781 | 1 | 00781 + 783 | 3 | 00783 + 784 | 4 | 00784 + 786 | 6 | 00786 + 787 | 7 | 00787 + 788 | 8 | 00788 + 789 | 9 | 00789 + 790 | 0 | 00790 + 791 | 1 | 00791 + 793 | 3 | 00793 + 794 | 4 | 00794 + 796 | 6 | 00796 + 797 | 7 | 00797 + 798 | 8 | 00798 + 799 | 9 | 00799 + 800 | 0 | 00800 + 801 | 1 | 00801 + 803 | 3 | 00803 + 804 | 4 | 00804 + 806 | 6 | 00806 + 807 | 7 | 00807 + 808 | 8 | 00808 + 809 | 9 | 00809 + 810 | 0 | 00810 + 811 | 1 | 00811 + 813 | 3 | 00813 + 814 | 4 | 00814 + 816 | 6 | 00816 + 817 | 7 | 00817 + 818 | 8 | 00818 + 819 | 9 | 00819 + 820 | 0 | 00820 + 821 | 1 | 00821 + 823 | 3 | 00823 + 824 | 4 | 00824 + 826 | 6 | 00826 + 827 | 7 | 00827 + 828 | 8 | 00828 + 829 | 9 | 00829 + 830 | 0 | 00830 + 831 | 1 | 00831 + 833 | 3 | 00833 + 834 | 4 | 00834 + 836 | 6 | 00836 + 837 | 7 | 00837 + 838 | 8 | 00838 + 839 | 9 | 00839 + 840 | 0 | 00840 + 841 | 1 | 00841 + 843 | 3 | 00843 + 844 | 4 | 00844 + 846 | 6 | 00846 + 847 | 7 | 00847 + 848 | 8 | 00848 + 849 | 9 | 00849 + 850 | 0 | 00850 + 851 | 1 | 00851 + 853 | 3 | 00853 + 854 | 4 | 00854 + 856 | 6 | 00856 + 857 | 7 | 00857 + 858 | 8 | 00858 + 859 | 9 | 00859 + 860 | 0 | 00860 + 861 | 1 | 00861 + 863 | 3 | 00863 + 864 | 4 | 00864 + 866 | 6 | 00866 + 867 | 7 | 00867 + 868 | 8 | 00868 + 869 | 9 | 00869 + 870 | 0 | 00870 + 871 | 1 | 00871 + 873 | 3 | 00873 + 874 | 4 | 00874 + 876 | 6 | 00876 + 877 | 7 | 00877 + 878 | 8 | 00878 + 879 | 9 | 00879 + 880 | 0 | 00880 + 881 | 1 | 00881 + 883 | 3 | 00883 + 884 | 4 | 00884 + 886 | 6 | 00886 + 887 | 7 | 00887 + 888 | 8 | 00888 + 889 | 9 | 00889 + 890 | 0 | 00890 + 891 | 1 | 00891 + 893 | 3 | 00893 + 894 | 4 | 00894 + 896 | 6 | 00896 + 897 | 7 | 00897 + 898 | 8 | 00898 + 899 | 9 | 00899 + 900 | 0 | 00900 + 901 | 1 | 00901 + 903 | 3 | 00903 + 904 | 4 | 00904 + 906 | 6 | 00906 + 907 | 7 | 00907 + 908 | 8 | 00908 + 909 | 9 | 00909 + 910 | 0 | 00910 + 911 | 1 | 00911 + 913 | 3 | 00913 + 914 | 4 | 00914 + 916 | 6 | 00916 + 917 | 7 | 00917 + 918 | 8 | 00918 + 919 | 9 | 00919 + 920 | 0 | 00920 + 921 | 1 | 00921 + 923 | 3 | 00923 + 924 | 4 | 00924 + 926 | 6 | 00926 + 927 | 7 | 00927 + 928 | 8 | 00928 + 929 | 9 | 00929 + 930 | 0 | 00930 + 931 | 1 | 00931 + 933 | 3 | 00933 + 934 | 4 | 00934 + 936 | 6 | 00936 + 937 | 7 | 00937 + 938 | 8 | 00938 + 939 | 9 | 00939 + 940 | 0 | 00940 + 941 | 1 | 00941 + 943 | 3 | 00943 + 944 | 4 | 00944 + 946 | 6 | 00946 + 947 | 7 | 00947 + 948 | 8 | 00948 + 949 | 9 | 00949 + 950 | 0 | 00950 + 951 | 1 | 00951 + 953 | 3 | 00953 + 954 | 4 | 00954 + 956 | 6 | 00956 + 957 | 7 | 00957 + 958 | 8 | 00958 + 959 | 9 | 00959 + 960 | 0 | 00960 + 961 | 1 | 00961 + 963 | 3 | 00963 + 964 | 4 | 00964 + 966 | 6 | 00966 + 967 | 7 | 00967 + 968 | 8 | 00968 + 969 | 9 | 00969 + 970 | 0 | 00970 + 971 | 1 | 00971 + 973 | 3 | 00973 + 974 | 4 | 00974 + 976 | 6 | 00976 + 977 | 7 | 00977 + 978 | 8 | 00978 + 979 | 9 | 00979 + 980 | 0 | 00980 + 981 | 1 | 00981 + 983 | 3 | 00983 + 984 | 4 | 00984 + 986 | 6 | 00986 + 987 | 7 | 00987 + 988 | 8 | 00988 + 989 | 9 | 00989 + 990 | 0 | 00990 + 991 | 1 | 00991 + 993 | 3 | 00993 + 994 | 4 | 00994 + 996 | 6 | 00996 + 997 | 7 | 00997 + 998 | 8 | 00998 + 999 | 9 | 00999 + 1000 | 0 | 01000 + 1001 | 101 | 0000100001 + 1003 | 103 | 0000300003 + 1004 | 104 | 0000400004 + 1006 | 106 | 0000600006 + 1007 | 107 | 0000700007 + 1008 | 108 | 0000800008 + 1009 | 109 | 0000900009 + 1010 | 100 | 0001000010 + 1011 | 101 | 0001100011 + 1013 | 103 | 0001300013 + 1014 | 104 | 0001400014 + 1016 | 106 | 0001600016 + 1017 | 107 | 0001700017 + 1018 | 108 | 0001800018 + 1019 | 109 | 0001900019 + 1020 | 100 | 0002000020 + 1101 | 201 | aaa + 1103 | 203 | ccc + 1104 | 204 | ddd +(819 rows) + +--Testcase 443: +EXPLAIN (verbose, costs off) +INSERT INTO ft2_nsc (c1,c2,c3) VALUES (1200,999,'foo'); + QUERY PLAN +--------------------------------------------------------------------------------------------------------------------------------------------------------- + Insert on public.ft2_nsc + Batch Size: 1 + -> Result + Output: 1200, 999, NULL::integer, 'foo'::text, NULL::timestamp with time zone, NULL::character varying, 'ft2 '::character(10), NULL::text +(4 rows) + +--Testcase 444: +INSERT INTO ft2_nsc (c1,c2,c3) VALUES (1200,999,'foo'); +--Testcase 445: +SELECT (fields->>'C 1')::int c1 FROM ft2 WHERE (fields->>'C 1')::int = 1200 AND (fields->>'c2')::int = 999; + c1 +------ + 1200 +(1 row) + +--EXPLAIN (verbose, costs off) +--UPDATE ft2 SET c3 = 'bar' WHERE c1 = 1200 RETURNING tableoid::regclass; -- can be pushed down +--UPDATE ft2 SET c3 = 'bar' WHERE c1 = 1200 RETURNING tableoid::regclass; +--Testcase 446: +EXPLAIN (verbose, costs off) +DELETE FROM ft2_nsc WHERE c1 = 1200; + QUERY PLAN +----------------------------------------------------------------------------- + Delete on public.ft2_nsc + -> Foreign Scan on public.ft2_nsc + Output: c3, "time" + InfluxDB query: SELECT "c3", "C 1" FROM "T1" WHERE (("C 1" = 1200)) +(4 rows) + +--Testcase 447: +SELECT (fields->>'C 1')::int c1 FROM ft2 WHERE (fields->>'C 1')::int = 1200; + c1 +------ + 1200 +(1 row) + +--Testcase 448: +DELETE FROM ft2_nsc WHERE c1 = 1200; +--Testcase 449: +SELECT (fields->>'C 1')::int c1 FROM ft2 WHERE (fields->>'C 1')::int = 1200; + c1 +---- +(0 rows) + +-- Test UPDATE/DELETE with RETURNING on a three-table join +--Testcase 450: +INSERT INTO ft2_nsc (c1,c2,c3) + SELECT id, id - 1200, to_char(id, 'FM00000') FROM generate_series(1201, 1300) id; +--EXPLAIN (verbose, costs off) +--UPDATE ft2 SET c3 = 'foo' +-- FROM ft4 INNER JOIN ft5 ON (ft4.c1 = ft5.c1) +-- WHERE ft2.c1 > 1200 AND ft2.c2 = ft4.c1 +-- RETURNING ft2, ft2.*, ft4, ft4.*; -- can be pushed down +--UPDATE ft2 SET c3 = 'foo' +-- FROM ft4 INNER JOIN ft5 ON (ft4.c1 = ft5.c1) +-- WHERE ft2.c1 > 1200 AND ft2.c2 = ft4.c1 +-- RETURNING ft2, ft2.*, ft4, ft4.*; +--Testcase 451: +EXPLAIN (verbose, costs off) +DELETE FROM ft2_nsc + USING ft4_nsc LEFT JOIN ft5_nsc ON (ft4_nsc.c1 = ft5_nsc.c1) + WHERE ft2_nsc.c1 > 1200 AND ft2_nsc.c1 % 10 = 0 AND ft2_nsc.c2 = ft4_nsc.c1; -- can be pushed down + QUERY PLAN +----------------------------------------------------------------------------------------------------------------------------- + Delete on public.ft2_nsc + -> Hash Right Join + Output: ft2_nsc.c3, ft2_nsc."time", ft4_nsc.*, ft5_nsc.* + Hash Cond: (ft5_nsc.c1 = ft4_nsc.c1) + -> Foreign Scan on public.ft5_nsc + Output: ft5_nsc.*, ft5_nsc.c1 + InfluxDB query: SELECT "c1", "c2", "c3" FROM "T4" + -> Hash + Output: ft2_nsc.c3, ft2_nsc."time", ft4_nsc.*, ft4_nsc.c1 + -> Hash Join + Output: ft2_nsc.c3, ft2_nsc."time", ft4_nsc.*, ft4_nsc.c1 + Hash Cond: (ft4_nsc.c1 = ft2_nsc.c2) + -> Foreign Scan on public.ft4_nsc + Output: ft4_nsc.*, ft4_nsc.c1 + InfluxDB query: SELECT "c1", "c2", "c3" FROM "T3" + -> Hash + Output: ft2_nsc.c3, ft2_nsc."time", ft2_nsc.c2 + -> Foreign Scan on public.ft2_nsc + Output: ft2_nsc.c3, ft2_nsc."time", ft2_nsc.c2 + InfluxDB query: SELECT "c2", "c3" FROM "T1" WHERE (("C 1" > 1200)) AND ((("C 1" % 10) = 0)) +(20 rows) + +--Testcase 452: +SELECT 100 FROM ft2, + ft4 LEFT JOIN ft5 ON ((ft4.fields->>'c1')::int = (ft5.fields->>'c1')::int) + WHERE (ft2.fields->>'C 1')::int > 1200 AND (ft2.fields->>'C 1')::int % 10 = 0 AND (ft2.fields->>'c2')::int = (ft4.fields->>'c1')::int; + ?column? +---------- + 100 + 100 + 100 + 100 + 100 + 100 + 100 + 100 + 100 + 100 +(10 rows) + +--Testcase 453: +DELETE FROM ft2_nsc + USING ft4_nsc LEFT JOIN ft5_nsc ON (ft4_nsc.c1 = ft5_nsc.c1) + WHERE ft2_nsc.c1 > 1200 AND ft2_nsc.c1 % 10 = 0 AND ft2_nsc.c2 = ft4_nsc.c1; +--Testcase 454: +SELECT 100 FROM ft2, + ft4 LEFT JOIN ft5 ON ((ft4.fields->>'c1')::int = (ft5.fields->>'c1')::int) + WHERE (ft2.fields->>'C 1')::int > 1200 AND (ft2.fields->>'C 1')::int % 10 = 0 AND (ft2.fields->>'c2')::int = (ft4.fields->>'c1')::int; + ?column? +---------- +(0 rows) + +--Testcase 455: +DELETE FROM ft2_nsc WHERE ft2_nsc.c1 > 1200; +-- Test UPDATE with a MULTIEXPR sub-select +-- (maybe someday this'll be remotely executable, but not today) +--EXPLAIN (verbose, costs off) +--UPDATE ft2 AS target SET (c2, c7) = ( +-- SELECT c2 * 10, c7 +-- FROM ft2 AS src +-- WHERE target.c1 = src.c1 +--) WHERE c1 > 1100; +--UPDATE ft2 AS target SET (c2, c7) = ( +-- SELECT c2 * 10, c7 +-- FROM ft2 AS src +-- WHERE targ--et.c1 = src.c1 +--) WHERE c1 > 1100; +--UPDATE ft2 AS target SET (c2) = ( +-- SELECT c2 / 10 +-- FROM ft2 AS src +-- WHERE targ--et.c1 = src.c1 +--) WHERE c1 > 1100; +-- Test UPDATE involving a join that can be pushed down, +-- but a SET clause that can't be +-- EXPLAIN (VERBOSE, COSTS OFF) +-- UPDATE ft2 d SET c2 = CASE WHEN random() >= 0 THEN d.c2 ELSE 0 END +-- FROM ft2 AS t WHERE d.c1 = t.c1 AND d.c1 > 1000; +-- UPDATE ft2 d SET c2 = CASE WHEN random() >= 0 THEN d.c2 ELSE 0 END +-- FROM ft2 AS t WHERE d.c1 = t.c1 AND d.c1 > 1000; +-- Test UPDATE/DELETE with WHERE or JOIN/ON conditions containing +-- user-defined operators/functions +--Testcase 456: +INSERT INTO ft2_nsc (c1,c2,c3) + SELECT id, id % 10, to_char(id, 'FM00000') FROM generate_series(2001, 2010) id; +--EXPLAIN (verbose, costs off) +--UPDATE ft2 SET c3 = 'bar' WHERE influxdb_fdw_abs(c1) > 2000 RETURNING *; -- can't be pushed down +--UPDATE ft2 SET c3 = 'bar' WHERE influxdb_fdw_abs(c1) > 2000 RETURNING *; +--EXPLAIN (verbose, costs off) +--UPDATE ft2 SET c3 = 'baz' +-- FROM ft4 INNER JOIN ft5 ON (ft4.c1 = ft5.c1) +-- WHERE ft2.c1 > 2000 AND ft2.c2 === ft4.c1 +-- RETURNING ft2.*, ft4.*, ft5.*; -- can't be pushed down +--UPDATE ft2 SET c3 = 'baz' +-- FROM ft4 INNER JOIN ft5 ON (ft4.c1 = ft5.c1) +-- WHERE ft2.c1 > 2000 AND ft2.c2 === ft4.c1 +-- RETURNING ft2.*, ft4.*, ft5.*; +--Testcase 457: +EXPLAIN (verbose, costs off) +DELETE FROM ft2_nsc + USING ft4_nsc INNER JOIN ft5_nsc ON (ft4_nsc.c1 === ft5_nsc.c1) + WHERE ft2_nsc.c1 > 2000 AND ft2_nsc.c2 = ft4_nsc.c1; -- can't be pushed down + QUERY PLAN +---------------------------------------------------------------------------------------------- + Delete on public.ft2_nsc + -> Nested Loop + Output: ft2_nsc.c3, ft2_nsc."time", ft4_nsc.*, ft5_nsc.* + Join Filter: (ft4_nsc.c1 === ft5_nsc.c1) + -> Hash Join + Output: ft2_nsc.c3, ft2_nsc."time", ft4_nsc.*, ft4_nsc.c1 + Hash Cond: (ft4_nsc.c1 = ft2_nsc.c2) + -> Foreign Scan on public.ft4_nsc + Output: ft4_nsc.*, ft4_nsc.c1 + InfluxDB query: SELECT "c1", "c2", "c3" FROM "T3" + -> Hash + Output: ft2_nsc.c3, ft2_nsc."time", ft2_nsc.c2 + -> Foreign Scan on public.ft2_nsc + Output: ft2_nsc.c3, ft2_nsc."time", ft2_nsc.c2 + InfluxDB query: SELECT "c2", "c3" FROM "T1" WHERE (("C 1" > 2000)) + -> Materialize + Output: ft5_nsc.*, ft5_nsc.c1 + -> Foreign Scan on public.ft5_nsc + Output: ft5_nsc.*, ft5_nsc.c1 + InfluxDB query: SELECT "c1", "c2", "c3" FROM "T4" +(20 rows) + +--Testcase 458: +SELECT (ft2.fields->>'C 1')::int c1, (ft2.fields->>'c2')::int c2, ft2.tags->>'c3' c3 + FROM ft2, ft4 INNER JOIN ft5 ON ((ft4.fields->>'c1')::int === (ft5.fields->>'c1')::int) + WHERE (ft2.fields->>'C 1')::int > 2000 AND (ft2.fields->>'c2')::int = (ft4.fields->>'c1')::int; + c1 | c2 | c3 +------+----+------- + 2006 | 6 | 02006 +(1 row) + +--Testcase 459: +DELETE FROM ft2_nsc + USING ft4_nsc INNER JOIN ft5_nsc ON (ft4_nsc.c1 === ft5_nsc.c1) + WHERE ft2_nsc.c1 > 2000 AND ft2_nsc.c2 = ft4_nsc.c1; +--Testcase 460: +SELECT (ft2.fields->>'C 1')::int c1, (ft2.fields->>'c2')::int c2, ft2.tags->>'c3' c3 + FROM ft2, ft4 INNER JOIN ft5 ON ((ft4.fields->>'c1')::int === (ft5.fields->>'c1')::int) + WHERE (ft2.fields->>'C 1')::int > 2000 AND (ft2.fields->>'c2')::int = (ft4.fields->>'c1')::int; + c1 | c2 | c3 +----+----+---- +(0 rows) + +--Testcase 461: +DELETE FROM ft2_nsc WHERE ft2_nsc.c1 > 2000; +-- Test that trigger on remote table works as expected +--Testcase 462: +CREATE OR REPLACE FUNCTION "S 1".F_BRTRIG() RETURNS trigger AS $$ +BEGIN + NEW.c3 = NEW.c3 || '_trig_update'; + RETURN NEW; +END; +$$ LANGUAGE plpgsql; +--Testcase 463: +CREATE TRIGGER t1_br_insert BEFORE INSERT OR UPDATE + ON "S 1".s1t1 FOR EACH ROW EXECUTE PROCEDURE "S 1".F_BRTRIG(); +--Testcase 464: +INSERT INTO ft2_nsc (c1,c2,c3) VALUES (1208, 818, 'fff'); +--Testcase 465: +SELECT (fields->>'C 1')::int c1, (fields->>'c2')::int c2, tags->>'c3' c3, fields->>'c6' c6, fields->>'c7' c7, fields->>'c8' c8 FROM ft2 WHERE (fields->>'C 1')::int = 1208; + c1 | c2 | c3 | c6 | c7 | c8 +------+-----+-----+----+------------+---- + 1208 | 818 | fff | | ft2 | +(1 row) + +--Testcase 466: +INSERT INTO ft2_nsc (c1,c2,c3,c6) VALUES (1218, 818, 'ggg', '(--;'); +--Testcase 467: +SELECT (fields->>'C 1')::int c1, (fields->>'c2')::int c2, tags->>'c3' c3, fields->>'c6' c6, fields->>'c7' c7, fields->>'c8' c8 FROM ft2 WHERE (fields->>'C 1')::int = 1218; + c1 | c2 | c3 | c6 | c7 | c8 +------+-----+-----+------+------------+---- + 1218 | 818 | ggg | (--; | ft2 | +(1 row) + +--UPDATE ft2 SET c2 = c2 + 600 WHERE c1 % 10 = 8 AND c1 < 1200 RETURNING *; +-- Test errors thrown on remote side during update +--Testcase 468: +ALTER TABLE "S 1"."T 1" ADD CONSTRAINT c2positive CHECK ((fields->>'c2')::int >= 0); +-- influxdb_fdw does not support key, ON CONFLICT +--INSERT INTO ft1(c1, c2) VALUES(11, 12); -- duplicate key +--Testcase 469: +INSERT INTO ft1_nsc(c1, c2) VALUES(11, 12) ON CONFLICT DO NOTHING; -- works +ERROR: ON CONFLICT is not supported +--Testcase 470: +INSERT INTO ft1_nsc(c1, c2) VALUES(11, 12) ON CONFLICT (c1, c2) DO NOTHING; -- unsupported +ERROR: there is no unique or exclusion constraint matching the ON CONFLICT specification +--Testcase 471: +INSERT INTO ft1_nsc(c1, c2) VALUES(11, 12) ON CONFLICT (c1, c2) DO UPDATE SET c3 = 'ffg'; -- unsupported +ERROR: there is no unique or exclusion constraint matching the ON CONFLICT specification +--INSERT INTO ft1(c1, c2) VALUES(1111, -2); -- c2positive +--UPDATE ft1 SET c2 = -c2 WHERE c1 = 1; -- c2positive +/* +-- influxdb_fdw does not support transactions +-- Test savepoint/rollback behavior +select c2, count(*) from ft2 where c2 < 500 group by 1 order by 1; +select c2, count(*) from "S 1"."T 1" where c2 < 500 group by 1 order by 1; +begin; +update ft2 set c2 = 42 where c2 = 0; +select c2, count(*) from ft2 where c2 < 500 group by 1 order by 1; +savepoint s1; +update ft2 set c2 = 44 where c2 = 4; +select c2, count(*) from ft2 where c2 < 500 group by 1 order by 1; +release savepoint s1; +select c2, count(*) from ft2 where c2 < 500 group by 1 order by 1; +savepoint s2; +update ft2 set c2 = 46 where c2 = 6; +select c2, count(*) from ft2 where c2 < 500 group by 1 order by 1; +rollback to savepoint s2; +select c2, count(*) from ft2 where c2 < 500 group by 1 order by 1; +release savepoint s2; +select c2, count(*) from ft2 where c2 < 500 group by 1 order by 1; +savepoint s3; +update ft2 set c2 = -2 where c2 = 42 and c1 = 10; -- fail on remote side +rollback to savepoint s3; +select c2, count(*) from ft2 where c2 < 500 group by 1 order by 1; +release savepoint s3; +select c2, count(*) from ft2 where c2 < 500 group by 1 order by 1; +-- none of the above is committed yet remotely +select c2, count(*) from "S 1"."T 1" where c2 < 500 group by 1 order by 1; +commit; +select c2, count(*) from ft2 where c2 < 500 group by 1 order by 1; +select c2, count(*) from "S 1"."T 1" where c2 < 500 group by 1 order by 1; +*/ +-- Above DMLs add data with c6 as NULL in ft1, so test ORDER BY NULLS LAST and NULLs +-- FIRST behavior here. +-- ORDER BY DESC NULLS LAST options +--Testcase 472: +EXPLAIN (VERBOSE, COSTS OFF) SELECT * FROM ft1 ORDER BY fields->>'c6' DESC NULLS LAST, (fields->>'C 1')::int OFFSET 795 LIMIT 10; + QUERY PLAN +------------------------------------------------------------------------------------------------------------ + Limit + Output: "time", tags, fields, ((fields ->> 'c6'::text)), (((fields ->> 'C 1'::text))::integer) + -> Sort + Output: "time", tags, fields, ((fields ->> 'c6'::text)), (((fields ->> 'C 1'::text))::integer) + Sort Key: ((ft1.fields ->> 'c6'::text)) DESC NULLS LAST, (((ft1.fields ->> 'C 1'::text))::integer) + -> Foreign Scan on public.ft1 + Output: "time", tags, fields, (fields ->> 'c6'::text), ((fields ->> 'C 1'::text))::integer + InfluxDB query: SELECT * FROM "T1" +(8 rows) + +--Testcase 473: +SELECT (fields->>'C 1')::int c1, (fields->>'c2')::int c2, tags->>'c3' c3, fields->>'c6' c6, fields->>'c7' c7, fields->>'c8' c8 FROM ft1 ORDER BY fields->>'c6' DESC NULLS LAST, (fields->>'C 1')::int OFFSET 795 LIMIT 10; + c1 | c2 | c3 | c6 | c7 | c8 +------+-----+------------+------+------------+----- + 960 | 0 | 00960 | 0 | 0 | foo + 970 | 0 | 00970 | 0 | 0 | foo + 980 | 0 | 00980 | 0 | 0 | foo + 990 | 0 | 00990 | 0 | 0 | foo + 1000 | 0 | 01000 | 0 | 0 | foo + 1218 | 818 | ggg | (--; | ft2 | + 1001 | 101 | 0000100001 | | ft2 | + 1003 | 103 | 0000300003 | | ft2 | + 1004 | 104 | 0000400004 | | ft2 | + 1006 | 106 | 0000600006 | | ft2 | +(10 rows) + +-- ORDER BY DESC NULLS FIRST options +--Testcase 474: +EXPLAIN (VERBOSE, COSTS OFF) SELECT * FROM ft1 ORDER BY fields->>'c6' DESC NULLS FIRST, (fields->>'C 1')::int OFFSET 15 LIMIT 10; + QUERY PLAN +---------------------------------------------------------------------------------------------------------- + Limit + Output: "time", tags, fields, ((fields ->> 'c6'::text)), (((fields ->> 'C 1'::text))::integer) + -> Sort + Output: "time", tags, fields, ((fields ->> 'c6'::text)), (((fields ->> 'C 1'::text))::integer) + Sort Key: ((ft1.fields ->> 'c6'::text)) DESC, (((ft1.fields ->> 'C 1'::text))::integer) + -> Foreign Scan on public.ft1 + Output: "time", tags, fields, (fields ->> 'c6'::text), ((fields ->> 'C 1'::text))::integer + InfluxDB query: SELECT * FROM "T1" +(8 rows) + +--Testcase 475: +SELECT (fields->>'C 1')::int c1, (fields->>'c2')::int c2, tags->>'c3' c3, fields->>'c6' c6, fields->>'c7' c7, fields->>'c8' c8 FROM ft1 ORDER BY fields->>'c6' DESC NULLS FIRST, (fields->>'C 1')::int OFFSET 15 LIMIT 10; + c1 | c2 | c3 | c6 | c7 | c8 +------+-----+------------+----+------------+----- + 1020 | 100 | 0002000020 | | ft2 | + 1101 | 201 | aaa | | ft2 | + 1103 | 203 | ccc | | ft2 | + 1104 | 204 | ddd | | ft2 | + 1208 | 818 | fff | | ft2 | + 9 | 9 | 00009 | 9 | 9 | foo + 19 | 9 | 00019 | 9 | 9 | foo + 29 | 9 | 00029 | 9 | 9 | foo + 39 | 9 | 00039 | 9 | 9 | foo + 49 | 9 | 00049 | 9 | 9 | foo +(10 rows) + +-- ORDER BY ASC NULLS FIRST options +--Testcase 476: +EXPLAIN (VERBOSE, COSTS OFF) SELECT * FROM ft1 ORDER BY fields->>'c6' ASC NULLS FIRST, (fields->>'C 1')::int OFFSET 15 LIMIT 10; + QUERY PLAN +---------------------------------------------------------------------------------------------------------- + Limit + Output: "time", tags, fields, ((fields ->> 'c6'::text)), (((fields ->> 'C 1'::text))::integer) + -> Sort + Output: "time", tags, fields, ((fields ->> 'c6'::text)), (((fields ->> 'C 1'::text))::integer) + Sort Key: ((ft1.fields ->> 'c6'::text)) NULLS FIRST, (((ft1.fields ->> 'C 1'::text))::integer) + -> Foreign Scan on public.ft1 + Output: "time", tags, fields, (fields ->> 'c6'::text), ((fields ->> 'C 1'::text))::integer + InfluxDB query: SELECT * FROM "T1" +(8 rows) + +--Testcase 477: +SELECT (fields->>'C 1')::int c1, (fields->>'c2')::int c2, tags->>'c3' c3, fields->>'c6' c6, fields->>'c7' c7, fields->>'c8' c8 FROM ft1 ORDER BY fields->>'c6' ASC NULLS FIRST, (fields->>'C 1')::int OFFSET 15 LIMIT 10; + c1 | c2 | c3 | c6 | c7 | c8 +------+-----+------------+------+------------+----- + 1020 | 100 | 0002000020 | | ft2 | + 1101 | 201 | aaa | | ft2 | + 1103 | 203 | ccc | | ft2 | + 1104 | 204 | ddd | | ft2 | + 1208 | 818 | fff | | ft2 | + 1218 | 818 | ggg | (--; | ft2 | + 10 | 0 | 00010 | 0 | 0 | foo + 20 | 0 | 00020 | 0 | 0 | foo + 30 | 0 | 00030 | 0 | 0 | foo + 40 | 0 | 00040 | 0 | 0 | foo +(10 rows) + +-- =================================================================== +-- test check constraints +-- =================================================================== +-- Consistent check constraints provide consistent results +--Testcase 478: +ALTER FOREIGN TABLE ft1 ADD CONSTRAINT ft1_c2positive CHECK ((fields->>'c2')::int >= 0); +--Testcase 479: +EXPLAIN (VERBOSE, COSTS OFF) SELECT count(*) FROM ft1 WHERE (fields->>'c2')::int < 0; + QUERY PLAN +---------------------------------------------------------------- + Foreign Scan + Output: (count(*)) + InfluxDB query: SELECT count(*) FROM "T1" WHERE (("c2" < 0)) +(3 rows) + +-- InfluxDB return null value because it does not have any record. +--Testcase 480: +SELECT count(*) FROM ft1 WHERE (fields->>'c2')::int < 0; + count +------- +(0 rows) + +--Testcase 481: +SET constraint_exclusion = 'on'; +--Testcase 482: +EXPLAIN (VERBOSE, COSTS OFF) SELECT count(*) FROM ft1 WHERE (fields->>'c2')::int < 0; + QUERY PLAN +-------------------------------- + Aggregate + Output: count(*) + -> Result + One-Time Filter: false +(4 rows) + +--Testcase 483: +SELECT count(*) FROM ft1 WHERE (fields->>'c2')::int < 0; + count +------- + 0 +(1 row) + +--Testcase 484: +RESET constraint_exclusion; +-- check constraint is enforced on the remote side, not locally +-- INSERT INTO ft1(c1, c2) VALUES(1111, -2); -- c2positive +-- UPDATE ft1 SET c2 = -c2 WHERE c1 = 1; -- c2positive +--Testcase 485: +ALTER FOREIGN TABLE ft1 DROP CONSTRAINT ft1_c2positive; +-- But inconsistent check constraints provide inconsistent results +--Testcase 486: +ALTER FOREIGN TABLE ft1 ADD CONSTRAINT ft1_c2negative CHECK ((fields->>'c2')::int < 0); +--Testcase 487: +EXPLAIN (VERBOSE, COSTS OFF) SELECT count(*) FROM ft1 WHERE (fields->>'c2')::int >= 0; + QUERY PLAN +----------------------------------------------------------------- + Foreign Scan + Output: (count(*)) + InfluxDB query: SELECT count(*) FROM "T1" WHERE (("c2" >= 0)) +(3 rows) + +--Testcase 488: +SELECT count(*) FROM ft1 WHERE (fields->>'c2')::int >= 0; + count +------- + 821 +(1 row) + +--Testcase 489: +SET constraint_exclusion = 'on'; +--Testcase 490: +EXPLAIN (VERBOSE, COSTS OFF) SELECT count(*) FROM ft1 WHERE (fields->>'c2')::int >= 0; + QUERY PLAN +-------------------------------- + Aggregate + Output: count(*) + -> Result + One-Time Filter: false +(4 rows) + +--Testcase 491: +SELECT count(*) FROM ft1 WHERE (fields->>'c2')::int >= 0; + count +------- + 0 +(1 row) + +--Testcase 492: +RESET constraint_exclusion; +-- local check constraint is not actually enforced +--Testcase 493: +INSERT INTO ft1_nsc(c1, c2) VALUES(1111, 2); +-- UPDATE ft1 SET c2 = c2 + 1 WHERE c1 = 1; +--Testcase 494: +ALTER FOREIGN TABLE ft1 DROP CONSTRAINT ft1_c2negative; +-- influxdb_fdw does not support this feature +-- =================================================================== +-- test WITH CHECK OPTION constraints +-- =================================================================== +--Testcase 495: +CREATE FUNCTION row_before_insupd_trigfunc() RETURNS trigger AS $$BEGIN NEW.a := NEW.a + 10; RETURN NEW; END$$ LANGUAGE plpgsql; +--Testcase 496: +CREATE FOREIGN TABLE base_tbl (fields jsonb OPTIONS(fields 'true')) SERVER influxdb_svr OPTIONS (table 'base_tbl', schemaless 'true'); +--ALTER FOREIGN TABLE base_tbl SET (autovacuum_enabled = 'false'); +--Testcase 797: +CREATE FOREIGN TABLE base_tbl_nsc (a int, b int) SERVER influxdb_svr OPTIONS (table 'base_tbl'); +--Testcase 497: +CREATE TRIGGER row_before_insupd_trigger BEFORE INSERT OR UPDATE ON base_tbl_nsc FOR EACH ROW EXECUTE PROCEDURE row_before_insupd_trigfunc(); +--Testcase 498: +CREATE FOREIGN TABLE foreign_tbl (fields jsonb OPTIONS(fields 'true')) SERVER influxdb_svr OPTIONS (table 'base_tbl', schemaless 'true'); +--Testcase 499: +CREATE VIEW rw_view AS SELECT * FROM base_tbl + WHERE (fields->>'a')::int < (fields->>'b')::int WITH CHECK OPTION; +--Testcase 798: +CREATE VIEW rw_view_nsc AS SELECT * FROM base_tbl_nsc + WHERE a < b WITH CHECK OPTION; +--Testcase 500: +\d+ rw_view + View "public.rw_view" + Column | Type | Collation | Nullable | Default | Storage | Description +--------+-------+-----------+----------+---------+----------+------------- + fields | jsonb | | | | extended | +View definition: + SELECT fields + FROM base_tbl + WHERE ((fields ->> 'a'::text)::integer) < ((fields ->> 'b'::text)::integer); +Options: check_option=cascaded + +--Testcase 501: +EXPLAIN (VERBOSE, COSTS OFF) +INSERT INTO rw_view_nsc VALUES (0, 5); + QUERY PLAN +------------------------------- + Insert on public.base_tbl_nsc + Batch Size: 1 + -> Result + Output: 0, 5 +(4 rows) + +--Testcase 502: +INSERT INTO rw_view_nsc VALUES (0, 5); -- should fail +ERROR: new row violates check option for view "rw_view_nsc" +DETAIL: Failing row contains (10, 5). +--Testcase 503: +EXPLAIN (VERBOSE, COSTS OFF) +INSERT INTO rw_view_nsc VALUES (0, 15); + QUERY PLAN +------------------------------- + Insert on public.base_tbl_nsc + Batch Size: 1 + -> Result + Output: 0, 15 +(4 rows) + +--Testcase 504: +INSERT INTO rw_view_nsc VALUES (0, 15); -- ok +--Testcase 505: +SELECT * FROM foreign_tbl; + fields +------------------------ + {"a": "10", "b": "5"} + {"a": "10", "b": "15"} +(2 rows) + +--EXPLAIN (VERBOSE, COSTS OFF) +--UPDATE rw_view SET b = b + 5; +--UPDATE rw_view SET b = b + 5; -- should fail +--EXPLAIN (VERBOSE, COSTS OFF) +--UPDATE rw_view SET b = b + 15; +--UPDATE rw_view SET b = b + 15; -- ok +--SELECT * FROM foreign_tbl; +-- We don't allow batch insert when there are any WCO constraints +ALTER SERVER influxdb_svr OPTIONS (ADD batch_size '10'); +--Testcase 869: +EXPLAIN (VERBOSE, COSTS OFF) +INSERT INTO rw_view VALUES (0, 15), (0, 5); +ERROR: INSERT has more expressions than target columns +LINE 2: INSERT INTO rw_view VALUES (0, 15), (0, 5); + ^ +--Testcase 870: +INSERT INTO rw_view VALUES (0, 15), (0, 5); -- should fail +ERROR: INSERT has more expressions than target columns +LINE 1: INSERT INTO rw_view VALUES (0, 15), (0, 5); + ^ +--Testcase 871: +SELECT * FROM foreign_tbl; + fields +------------------------ + {"a": "10", "b": "5"} + {"a": "10", "b": "15"} +(2 rows) + +ALTER SERVER influxdb_svr OPTIONS (DROP batch_size); +--Testcase 506: +DELETE FROM foreign_tbl; +--Testcase 799: +DROP FOREIGN TABLE foreign_tbl CASCADE; +--Testcase 507: +DROP TRIGGER row_before_insupd_trigger ON base_tbl_nsc; +--Testcase 508: +DROP FOREIGN TABLE base_tbl CASCADE; +NOTICE: drop cascades to view rw_view +--Testcase 800: +DROP FOREIGN TABLE base_tbl_nsc CASCADE; +NOTICE: drop cascades to view rw_view_nsc +-- influxdb_fdw does not support partitions +-- test WCO for partitions +--Testcase 509: +CREATE FOREIGN TABLE child_tbl (fields jsonb OPTIONS(fields 'true')) SERVER influxdb_svr OPTIONS (table 'child_tbl', schemaless 'true'); +--ALTER FOREIGN TABLE child_tbl SET (autovacuum_enabled = 'false'); +--Testcase 801: +CREATE FOREIGN TABLE child_tbl_nsc (a int, b int) SERVER influxdb_svr OPTIONS (table 'child_tbl'); +--Testcase 510: +CREATE TRIGGER row_before_insupd_trigger BEFORE INSERT OR UPDATE ON child_tbl_nsc FOR EACH ROW EXECUTE PROCEDURE row_before_insupd_trigfunc(); +--Testcase 511: +CREATE FOREIGN TABLE foreign_tbl (fields jsonb OPTIONS(fields 'true')) SERVER influxdb_svr OPTIONS (table 'child_tbl', schemaless 'true'); +--Testcase 512: +CREATE TABLE parent_tbl (a int, b int) PARTITION BY RANGE(a); +--Testcase 513: +ALTER TABLE parent_tbl ATTACH PARTITION child_tbl_nsc FOR VALUES FROM (0) TO (100); +-- Detach and re-attach once, to stress the concurrent detach case. +--Testcase 774: +ALTER TABLE parent_tbl DETACH PARTITION child_tbl_nsc CONCURRENTLY; +--Testcase 775: +ALTER TABLE parent_tbl ATTACH PARTITION child_tbl_nsc FOR VALUES FROM (0) TO (100); +--Testcase 514: +CREATE VIEW rw_view AS SELECT * FROM parent_tbl + WHERE a < b WITH CHECK OPTION; +--Testcase 515: +\d+ rw_view + View "public.rw_view" + Column | Type | Collation | Nullable | Default | Storage | Description +--------+---------+-----------+----------+---------+---------+------------- + a | integer | | | | plain | + b | integer | | | | plain | +View definition: + SELECT a, + b + FROM parent_tbl + WHERE a < b; +Options: check_option=cascaded + +--Testcase 516: +EXPLAIN (VERBOSE, COSTS OFF) +INSERT INTO rw_view VALUES (0, 5); + QUERY PLAN +----------------------------- + Insert on public.parent_tbl + -> Result + Output: 0, 5 +(3 rows) + +--Testcase 517: +INSERT INTO rw_view VALUES (0, 5); -- should fail +ERROR: Not support partition insert +--Testcase 518: +EXPLAIN (VERBOSE, COSTS OFF) +INSERT INTO rw_view VALUES (0, 15); + QUERY PLAN +----------------------------- + Insert on public.parent_tbl + -> Result + Output: 0, 15 +(3 rows) + +--Testcase 519: +INSERT INTO rw_view VALUES (0, 15); -- ok +ERROR: Not support partition insert +--Testcase 520: +SELECT * FROM foreign_tbl; + fields +-------- +(0 rows) + +--EXPLAIN (VERBOSE, COSTS OFF) +--UPDATE rw_view SET b = b + 5; +--UPDATE rw_view SET b = b + 5; -- should fail +--EXPLAIN (VERBOSE, COSTS OFF) +--UPDATE rw_view SET b = b + 15; +--UPDATE rw_view SET b = b + 15; -- ok +--SELECT * FROM foreign_tbl; +-- We don't allow batch insert when there are any WCO constraints +ALTER SERVER influxdb_svr OPTIONS (ADD batch_size '10'); +--Testcase 872: +EXPLAIN (VERBOSE, COSTS OFF) +INSERT INTO rw_view VALUES (0, 15), (0, 5); + QUERY PLAN +-------------------------------------------------------- + Insert on public.parent_tbl + -> Values Scan on "*VALUES*" + Output: "*VALUES*".column1, "*VALUES*".column2 +(3 rows) + +--Testcase 873: +INSERT INTO rw_view VALUES (0, 15), (0, 5); -- should fail +ERROR: Not support partition insert +--Testcase 874: +SELECT * FROM foreign_tbl; + fields +-------- +(0 rows) + +ALTER SERVER influxdb_svr OPTIONS (DROP batch_size); +--Testcase 521: +DROP FOREIGN TABLE foreign_tbl CASCADE; +--Testcase 522: +DROP TRIGGER row_before_insupd_trigger ON child_tbl_nsc; +--Testcase 523: +DROP FOREIGN TABLE child_tbl CASCADE; +--Testcase 802: +DROP FOREIGN TABLE child_tbl_nsc CASCADE; +--Testcase 524: +DROP TABLE parent_tbl CASCADE; +NOTICE: drop cascades to view rw_view +--Testcase 525: +DROP FUNCTION row_before_insupd_trigfunc; +-- Try a more complex permutation of WCO where there are multiple levels of +-- partitioned tables with columns not all in the same order +CREATE TABLE parent_tbl (a int, b text, c numeric) PARTITION BY RANGE(a); +CREATE TABLE sub_parent (c numeric, a int, b text) PARTITION BY RANGE(a); +ALTER TABLE parent_tbl ATTACH PARTITION sub_parent FOR VALUES FROM (1) TO (10); +CREATE TABLE child_local (b text, c numeric, a int); +CREATE FOREIGN TABLE child_foreign_nsc (b text, c numeric, a int) + SERVER influxdb_svr OPTIONS (table 'child_local'); +CREATE FOREIGN TABLE child_foreign (fields jsonb OPTIONS(fields 'true')) SERVER influxdb_svr OPTIONS (table 'child_local', schemaless 'true'); +ALTER TABLE sub_parent ATTACH PARTITION child_foreign_nsc FOR VALUES FROM (1) TO (10); +CREATE VIEW rw_view AS SELECT * FROM parent_tbl WHERE a < 5 WITH CHECK OPTION; +-- Not support partition insert +INSERT INTO parent_tbl (a) VALUES(1),(5); +ERROR: Not support partition insert +-- UPDATE is not supported +EXPLAIN (VERBOSE, COSTS OFF) +UPDATE rw_view SET b = 'text', c = 123.456; +ERROR: UPDATE is not supported +-- UPDATE is not supported +UPDATE rw_view SET b = 'text', c = 123.456; +ERROR: UPDATE is not supported +SELECT * FROM parent_tbl ORDER BY a; + a | b | c +---+---+--- +(0 rows) + +DROP VIEW rw_view; +DROP TABLE child_local; +DROP FOREIGN TABLE child_foreign; +DROP FOREIGN TABLE child_foreign_nsc; +DROP TABLE sub_parent; +DROP TABLE parent_tbl; +-- =================================================================== +-- test serial columns (ie, sequence-based defaults) +-- =================================================================== +--Testcase 526: +create foreign table loc1 (fields jsonb OPTIONS(fields 'true')) SERVER influxdb_svr OPTIONS (table 'loc1', schemaless 'true'); +--alter foreign table loc1 set (autovacuum_enabled = 'false'); +--Testcase 803: +create foreign table loc1_nsc (f1 serial, f2 text) + server influxdb_svr options(table 'loc1'); +--Testcase 527: +create foreign table rem1 (fields jsonb OPTIONS(fields 'true')) SERVER influxdb_svr OPTIONS (table 'loc1', schemaless 'true'); +--Testcase 804: +create foreign table rem1_nsc (f1 serial, f2 text) + server influxdb_svr options(table 'loc1'); +--Testcase 528: +select pg_catalog.setval('rem1_nsc_f1_seq', 10, false); + setval +-------- + 10 +(1 row) + +--Testcase 529: +insert into loc1_nsc(f2) values('hi'); +--Testcase 530: +insert into rem1_nsc(f2) values('hi remote'); +--Testcase 531: +insert into loc1_nsc(f2) values('bye'); +--Testcase 532: +insert into rem1_nsc(f2) values('bye remote'); +--Testcase 533: +select * from loc1; + fields +---------------------------------- + {"f1": "1", "f2": "hi"} + {"f1": "10", "f2": "hi remote"} + {"f1": "2", "f2": "bye"} + {"f1": "11", "f2": "bye remote"} +(4 rows) + +--Testcase 534: +select * from rem1; + fields +---------------------------------- + {"f1": "1", "f2": "hi"} + {"f1": "10", "f2": "hi remote"} + {"f1": "2", "f2": "bye"} + {"f1": "11", "f2": "bye remote"} +(4 rows) + +-- =================================================================== +-- test generated columns +-- =================================================================== +--Testcase 535: +create foreign table gloc1 (fields jsonb OPTIONS(fields 'true')) SERVER influxdb_svr OPTIONS (table 'gloc1', schemaless 'true'); +--alter foreign table gloc1 set (autovacuum_enabled = 'false'); +--Testcase 805: +create foreign table gloc1_nsc ( + a int, + b int generated always as (a * 2) stored) + server influxdb_svr options(table 'gloc1'); +--Testcase 536: +create foreign table grem1 (fields jsonb OPTIONS(fields 'true')) SERVER influxdb_svr OPTIONS (table 'gloc1', schemaless 'true'); +--Testcase 806: +create foreign table grem1_nsc ( + a int, + b int generated always as (a * 2) stored) + server influxdb_svr options(table 'gloc1'); +--Testcase 537: +explain (verbose, costs off) +insert into grem1_nsc (a) values (1), (22); + QUERY PLAN +--------------------------------------------------- + Insert on public.grem1_nsc + Batch Size: 1 + -> Values Scan on "*VALUES*" + Output: "*VALUES*".column1, NULL::integer +(4 rows) + +--Testcase 765: +insert into grem1_nsc (a) values (1), (22); +--explain (verbose, costs off) +--update grem1 set a = 22 where a = 2; +--update grem1 set a = 22 where a = 2; +--Testcase 538: +select * from gloc1; + fields +------------------------ + {"a": "1", "b": "2"} + {"a": "22", "b": "44"} +(2 rows) + +--Testcase 539: +select * from grem1; + fields +------------------------ + {"a": "1", "b": "2"} + {"a": "22", "b": "44"} +(2 rows) + +--Testcase 766: +delete from grem1_nsc; +/* +-- InfluxDB FDW does not support partition insert +-- test copy from +copy grem1 from stdin; +1 +2 +\. +select * from gloc1; +select * from grem1; +delete from grem1; +*/ +-- test batch insert +--Testcase 767: +alter server influxdb_svr options (add batch_size '10'); +--Testcase 768: +explain (verbose, costs off) +insert into grem1_nsc (a) values (1), (2); + QUERY PLAN +--------------------------------------------------- + Insert on public.grem1_nsc + Batch Size: 10 + -> Values Scan on "*VALUES*" + Output: "*VALUES*".column1, NULL::integer +(4 rows) + +--Testcase 769: +insert into grem1_nsc (a) values (1), (2); +--Testcase 770: +select * from gloc1; + fields +---------------------- + {"a": "1", "b": "2"} + {"a": "2", "b": "4"} +(2 rows) + +--Testcase 771: +select * from grem1; + fields +---------------------- + {"a": "1", "b": "2"} + {"a": "2", "b": "4"} +(2 rows) + +--Testcase 772: +delete from grem1_nsc; +-- batch insert with foreign partitions. +-- This schema uses two partitions, one local and one remote with a modulo +-- to loop across all of them in batches. +create table tab_batch_local (id int, data text); +insert into tab_batch_local select i, 'test'|| i from generate_series(1, 45) i; +create table tab_batch_sharded (id int, data text) partition by hash(id); +create table tab_batch_sharded_p0 partition of tab_batch_sharded + for values with (modulus 2, remainder 0); +create table tab_batch_sharded_p1_remote (id int, data text); +create foreign table tab_batch_sharded_p1 partition of tab_batch_sharded + for values with (modulus 2, remainder 1) + server influxdb_svr options (table 'tab_batch_sharded_p1_remote'); +-- Not support partition insert +insert into tab_batch_sharded select * from tab_batch_local; +ERROR: Not support partition insert +select count(*) from tab_batch_sharded; + count +------- + 0 +(1 row) + +drop table tab_batch_local; +drop table tab_batch_sharded; +drop foreign table tab_batch_sharded_p1_remote; +ERROR: "tab_batch_sharded_p1_remote" is not a foreign table +HINT: Use DROP TABLE to remove a table. +drop foreign table tab_batch_sharded_p1; +ERROR: foreign table "tab_batch_sharded_p1" does not exist +--Testcase 773: +alter server influxdb_svr options (drop batch_size); +-- =================================================================== +-- test local triggers +-- =================================================================== +-- Trigger functions "borrowed" from triggers regress test. +--Testcase 540: +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;$$; +--Testcase 541: +CREATE TRIGGER trig_stmt_before BEFORE DELETE OR INSERT OR UPDATE OR TRUNCATE ON rem1_nsc + FOR EACH STATEMENT EXECUTE PROCEDURE trigger_func(); +--Testcase 542: +CREATE TRIGGER trig_stmt_after AFTER DELETE OR INSERT OR UPDATE OR TRUNCATE ON rem1_nsc + FOR EACH STATEMENT EXECUTE PROCEDURE trigger_func(); +--Testcase 543: +CREATE OR REPLACE FUNCTION trigger_data() RETURNS trigger +LANGUAGE plpgsql AS $$ + +declare + oldnew text[]; + relid text; + argstr text; +begin + + relid := TG_relid::regclass; + argstr := ''; + 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 '%(%) % % % ON %', + tg_name, argstr, TG_when, TG_level, TG_OP, relid; + oldnew := '{}'::text[]; + if TG_OP != 'INSERT' then + oldnew := array_append(oldnew, format('OLD: %s', OLD)); + end if; + + if TG_OP != 'DELETE' then + oldnew := array_append(oldnew, format('NEW: %s', NEW)); + end if; + + RAISE NOTICE '%', array_to_string(oldnew, ','); + + if TG_OP = 'DELETE' then + return OLD; + else + return NEW; + end if; +end; +$$; +-- Test basic functionality +--Testcase 544: +CREATE TRIGGER trig_row_before +BEFORE INSERT OR UPDATE OR DELETE ON rem1_nsc +FOR EACH ROW EXECUTE PROCEDURE trigger_data(23,'skidoo'); +--Testcase 545: +CREATE TRIGGER trig_row_after +AFTER INSERT OR UPDATE OR DELETE ON rem1_nsc +FOR EACH ROW EXECUTE PROCEDURE trigger_data(23,'skidoo'); +--Testcase 546: +delete from rem1_nsc; +NOTICE: trigger_func() called: action = DELETE, when = BEFORE, level = STATEMENT +NOTICE: trig_row_before(23, skidoo) BEFORE ROW DELETE ON rem1_nsc +NOTICE: OLD: (1,hi) +NOTICE: trig_row_before(23, skidoo) BEFORE ROW DELETE ON rem1_nsc +NOTICE: OLD: (10,"hi remote") +NOTICE: trig_row_before(23, skidoo) BEFORE ROW DELETE ON rem1_nsc +NOTICE: OLD: (2,bye) +NOTICE: trig_row_before(23, skidoo) BEFORE ROW DELETE ON rem1_nsc +NOTICE: OLD: (11,"bye remote") +NOTICE: trig_row_after(23, skidoo) AFTER ROW DELETE ON rem1_nsc +NOTICE: OLD: (1,hi) +NOTICE: trig_row_after(23, skidoo) AFTER ROW DELETE ON rem1_nsc +NOTICE: OLD: (10,"hi remote") +NOTICE: trig_row_after(23, skidoo) AFTER ROW DELETE ON rem1_nsc +NOTICE: OLD: (2,bye) +NOTICE: trig_row_after(23, skidoo) AFTER ROW DELETE ON rem1_nsc +NOTICE: OLD: (11,"bye remote") +NOTICE: trigger_func() called: action = DELETE, when = AFTER, level = STATEMENT +--Testcase 547: +insert into rem1_nsc values(1,'insert'); +NOTICE: trigger_func() called: action = INSERT, when = BEFORE, level = STATEMENT +NOTICE: trig_row_before(23, skidoo) BEFORE ROW INSERT ON rem1_nsc +NOTICE: NEW: (1,insert) +NOTICE: trig_row_after(23, skidoo) AFTER ROW INSERT ON rem1_nsc +NOTICE: NEW: (1,insert) +NOTICE: trigger_func() called: action = INSERT, when = AFTER, level = STATEMENT +--update rem1 set f2 = 'update' where f1 = 1; +--update rem1 set f2 = f2 || f2; +--truncate rem1; +-- cleanup +--Testcase 548: +DROP TRIGGER trig_row_before ON rem1_nsc; +--Testcase 549: +DROP TRIGGER trig_row_after ON rem1_nsc; +--Testcase 550: +DROP TRIGGER trig_stmt_before ON rem1_nsc; +--Testcase 551: +DROP TRIGGER trig_stmt_after ON rem1_nsc; +--Testcase 552: +DELETE from rem1_nsc; +-- Test multiple AFTER ROW triggers on a foreign table +--Testcase 553: +CREATE TRIGGER trig_row_after1 +AFTER INSERT OR UPDATE OR DELETE ON rem1_nsc +FOR EACH ROW EXECUTE PROCEDURE trigger_data(23,'skidoo'); +--Testcase 554: +CREATE TRIGGER trig_row_after2 +AFTER INSERT OR UPDATE OR DELETE ON rem1_nsc +FOR EACH ROW EXECUTE PROCEDURE trigger_data(23,'skidoo'); +--Testcase 555: +insert into rem1_nsc values(1,'insert'); +NOTICE: trig_row_after1(23, skidoo) AFTER ROW INSERT ON rem1_nsc +NOTICE: NEW: (1,insert) +NOTICE: trig_row_after2(23, skidoo) AFTER ROW INSERT ON rem1_nsc +NOTICE: NEW: (1,insert) +--update rem1 set f2 = 'update' where f1 = 1; +--update rem1 set f2 = f2 || f2; +--Testcase 556: +delete from rem1_nsc; +NOTICE: trig_row_after1(23, skidoo) AFTER ROW DELETE ON rem1_nsc +NOTICE: OLD: (1,insert) +NOTICE: trig_row_after2(23, skidoo) AFTER ROW DELETE ON rem1_nsc +NOTICE: OLD: (1,insert) +-- cleanup +--Testcase 557: +DROP TRIGGER trig_row_after1 ON rem1_nsc; +--Testcase 558: +DROP TRIGGER trig_row_after2 ON rem1_nsc; +-- Test WHEN conditions +--Testcase 559: +CREATE TRIGGER trig_row_before_insupd +BEFORE INSERT OR UPDATE ON rem1_nsc +FOR EACH ROW +WHEN (NEW.f2 like '%update%') +EXECUTE PROCEDURE trigger_data(23,'skidoo'); +--Testcase 560: +CREATE TRIGGER trig_row_after_insupd +AFTER INSERT OR UPDATE ON rem1_nsc +FOR EACH ROW +WHEN (NEW.f2 like '%update%') +EXECUTE PROCEDURE trigger_data(23,'skidoo'); +-- Insert or update not matching: nothing happens +--Testcase 561: +INSERT INTO rem1_nsc values(1, 'insert'); +--UPDATE rem1 set f2 = 'test'; +-- Insert or update matching: triggers are fired +--Testcase 562: +INSERT INTO rem1_nsc values(2, 'update'); +NOTICE: trig_row_before_insupd(23, skidoo) BEFORE ROW INSERT ON rem1_nsc +NOTICE: NEW: (2,update) +NOTICE: trig_row_after_insupd(23, skidoo) AFTER ROW INSERT ON rem1_nsc +NOTICE: NEW: (2,update) +--UPDATE rem1 set f2 = 'update update' where f1 = '2'; +--Testcase 563: +CREATE TRIGGER trig_row_before_delete +BEFORE DELETE ON rem1_nsc +FOR EACH ROW +WHEN (OLD.f2 like '%update%') +EXECUTE PROCEDURE trigger_data(23,'skidoo'); +--Testcase 564: +CREATE TRIGGER trig_row_after_delete +AFTER DELETE ON rem1_nsc +FOR EACH ROW +WHEN (OLD.f2 like '%update%') +EXECUTE PROCEDURE trigger_data(23,'skidoo'); +-- Trigger is fired for f1=2, not for f1=1 +--Testcase 565: +DELETE FROM rem1_nsc; +NOTICE: trig_row_before_delete(23, skidoo) BEFORE ROW DELETE ON rem1_nsc +NOTICE: OLD: (2,update) +NOTICE: trig_row_after_delete(23, skidoo) AFTER ROW DELETE ON rem1_nsc +NOTICE: OLD: (2,update) +-- cleanup +--Testcase 566: +DROP TRIGGER trig_row_before_insupd ON rem1_nsc; +--Testcase 567: +DROP TRIGGER trig_row_after_insupd ON rem1_nsc; +--Testcase 568: +DROP TRIGGER trig_row_before_delete ON rem1_nsc; +--Testcase 569: +DROP TRIGGER trig_row_after_delete ON rem1_nsc; +-- Test various RETURN statements in BEFORE triggers. +--Testcase 570: +CREATE FUNCTION trig_row_before_insupdate() RETURNS TRIGGER AS $$ + BEGIN + NEW.f2 := NEW.f2 || ' triggered !'; + RETURN NEW; + END +$$ language plpgsql; +--Testcase 571: +CREATE TRIGGER trig_row_before_insupd +BEFORE INSERT OR UPDATE ON rem1_nsc +FOR EACH ROW EXECUTE PROCEDURE trig_row_before_insupdate(); +-- The new values should have 'triggered' appended +--Testcase 572: +INSERT INTO rem1_nsc values(1, 'insert'); +--Testcase 573: +SELECT * from loc1; + fields +----------------------------------------- + {"f1": "1", "f2": "insert triggered !"} +(1 row) + +--Testcase 574: +INSERT INTO rem1_nsc values(2, 'insert'); +--Testcase 575: +SELECT fields->>'f2' f2 FROM rem1 WHERE (fields->>'f1')::int = 2; + f2 +-------------------- + insert triggered ! +(1 row) + +--Testcase 576: +SELECT * from loc1; + fields +----------------------------------------- + {"f1": "1", "f2": "insert triggered !"} + {"f1": "2", "f2": "insert triggered !"} +(2 rows) + +--UPDATE rem1 set f2 = ''; +--SELECT * from loc1; +--UPDATE rem1 set f2 = 'skidoo' RETURNING f2; +--SELECT * from loc1; +--EXPLAIN (verbose, costs off) +--UPDATE rem1 set f1 = 10; -- all columns should be transmitted +--UPDATE rem1 set f1 = 10; +--SELECT * from loc1; +--Testcase 577: +DELETE FROM rem1_nsc; +-- Add a second trigger, to check that the changes are propagated correctly +-- from trigger to trigger +--Testcase 578: +CREATE TRIGGER trig_row_before_insupd2 +BEFORE INSERT OR UPDATE ON rem1_nsc +FOR EACH ROW EXECUTE PROCEDURE trig_row_before_insupdate(); +--Testcase 579: +INSERT INTO rem1_nsc values(1, 'insert'); +--Testcase 580: +SELECT * from loc1; + fields +----------------------------------------------------- + {"f1": "1", "f2": "insert triggered ! triggered !"} +(1 row) + +--Testcase 581: +INSERT INTO rem1_nsc values(2, 'insert'); +--Testcase 582: +SELECT fields->>'f2' f2 FROM rem1 WHERE (fields->>'f1')::int = 2; + f2 +-------------------------------- + insert triggered ! triggered ! +(1 row) + +--Testcase 583: +SELECT * from loc1; + fields +----------------------------------------------------- + {"f1": "1", "f2": "insert triggered ! triggered !"} + {"f1": "2", "f2": "insert triggered ! triggered !"} +(2 rows) + +--UPDATE rem1 set f2 = ''; +--SELECT * from loc1; +--UPDATE rem1 set f2 = 'skidoo' RETURNING f2; +--SELECT * from loc1; +--Testcase 584: +DROP TRIGGER trig_row_before_insupd ON rem1_nsc; +--Testcase 585: +DROP TRIGGER trig_row_before_insupd2 ON rem1_nsc; +--Testcase 586: +DELETE from rem1_nsc; +--Testcase 587: +INSERT INTO rem1_nsc VALUES (1, 'test'); +-- Test with a trigger returning NULL +--Testcase 588: +CREATE FUNCTION trig_null() RETURNS TRIGGER AS $$ + BEGIN + RETURN NULL; + END +$$ language plpgsql; +--Testcase 589: +CREATE TRIGGER trig_null +BEFORE INSERT OR UPDATE OR DELETE ON rem1_nsc +FOR EACH ROW EXECUTE PROCEDURE trig_null(); +-- Nothing should have changed. +--Testcase 590: +INSERT INTO rem1_nsc VALUES (2, 'test2'); +--Testcase 591: +SELECT * from loc1; + fields +--------------------------- + {"f1": "1", "f2": "test"} +(1 row) + +--UPDATE rem1 SET f2 = 'test2'; +--SELECT * from loc1; +--Testcase 592: +DELETE from rem1_nsc; +--Testcase 593: +SELECT * from loc1; + fields +--------------------------- + {"f1": "1", "f2": "test"} +(1 row) + +--Testcase 594: +DROP TRIGGER trig_null ON rem1_nsc; +--Testcase 595: +DELETE from rem1_nsc; +-- Test a combination of local and remote triggers +--Testcase 596: +CREATE TRIGGER trig_row_before +BEFORE INSERT OR UPDATE OR DELETE ON rem1_nsc +FOR EACH ROW EXECUTE PROCEDURE trigger_data(23,'skidoo'); +--Testcase 597: +CREATE TRIGGER trig_row_after +AFTER INSERT OR UPDATE OR DELETE ON rem1_nsc +FOR EACH ROW EXECUTE PROCEDURE trigger_data(23,'skidoo'); +--Testcase 598: +CREATE TRIGGER trig_local_before BEFORE INSERT OR UPDATE ON loc1_nsc +FOR EACH ROW EXECUTE PROCEDURE trig_row_before_insupdate(); +--Testcase 599: +INSERT INTO rem1_nsc(f2) VALUES ('test'); +NOTICE: trig_row_before(23, skidoo) BEFORE ROW INSERT ON rem1_nsc +NOTICE: NEW: (12,test) +NOTICE: trig_row_after(23, skidoo) AFTER ROW INSERT ON rem1_nsc +NOTICE: NEW: (12,test) +--UPDATE rem1 SET f2 = 'testo'; +-- Test returning a system attribute +--Testcase 600: +INSERT INTO rem1_nsc(f2) VALUES ('test'); +NOTICE: trig_row_before(23, skidoo) BEFORE ROW INSERT ON rem1_nsc +NOTICE: NEW: (13,test) +NOTICE: trig_row_after(23, skidoo) AFTER ROW INSERT ON rem1_nsc +NOTICE: NEW: (13,test) +--Testcase 601: +SELECT * FROM rem1 WHERE fields->>'f2' = 'test'; + fields +---------------------------- + {"f1": "12", "f2": "test"} + {"f1": "13", "f2": "test"} +(2 rows) + +-- cleanup +--Testcase 602: +DROP TRIGGER trig_row_before ON rem1_nsc; +--Testcase 603: +DROP TRIGGER trig_row_after ON rem1_nsc; +--Testcase 604: +DROP TRIGGER trig_local_before ON loc1_nsc; +-- Test direct foreign table modification functionality +--Testcase 774: +EXPLAIN (verbose, costs off) +DELETE FROM rem1_nsc; -- can be pushed down + QUERY PLAN +-------------------------------------------- + Delete on public.rem1_nsc + -> Foreign Delete on public.rem1_nsc + InfluxDB query: DELETE FROM "loc1" +(3 rows) + +--Testcase 775: +EXPLAIN (verbose, costs off) +DELETE FROM rem1_nsc WHERE false; -- currently can't be pushed down + QUERY PLAN +-------------------------------- + Delete on public.rem1_nsc + -> Result + One-Time Filter: false +(3 rows) + +-- Test with statement-level triggers +--Testcase 605: +CREATE TRIGGER trig_stmt_before + BEFORE DELETE OR INSERT OR UPDATE ON rem1_nsc + FOR EACH STATEMENT EXECUTE PROCEDURE trigger_func(); +--EXPLAIN (verbose, costs off) +--UPDATE rem1 set f2 = ''; -- can be pushed down +--Testcase 606: +EXPLAIN (verbose, costs off) +DELETE FROM rem1_nsc; -- can be pushed down + QUERY PLAN +-------------------------------------------- + Delete on public.rem1_nsc + -> Foreign Delete on public.rem1_nsc + InfluxDB query: DELETE FROM "loc1" +(3 rows) + +--Testcase 607: +DROP TRIGGER trig_stmt_before ON rem1_nsc; +--Testcase 608: +CREATE TRIGGER trig_stmt_after + AFTER DELETE OR INSERT OR UPDATE ON rem1_nsc + FOR EACH STATEMENT EXECUTE PROCEDURE trigger_func(); +--EXPLAIN (verbose, costs off) +--UPDATE rem1 set f2 = ''; -- can be pushed down +--Testcase 609: +EXPLAIN (verbose, costs off) +DELETE FROM rem1_nsc; -- can be pushed down + QUERY PLAN +-------------------------------------------- + Delete on public.rem1_nsc + -> Foreign Delete on public.rem1_nsc + InfluxDB query: DELETE FROM "loc1" +(3 rows) + +--Testcase 610: +DROP TRIGGER trig_stmt_after ON rem1_nsc; +-- Test with row-level ON INSERT triggers +--Testcase 611: +CREATE TRIGGER trig_row_before_insert +BEFORE INSERT ON rem1_nsc +FOR EACH ROW EXECUTE PROCEDURE trigger_data(23,'skidoo'); +--EXPLAIN (verbose, costs off) +--UPDATE rem1 set f2 = ''; -- can be pushed down +--Testcase 612: +EXPLAIN (verbose, costs off) +DELETE FROM rem1_nsc; -- can be pushed down + QUERY PLAN +-------------------------------------------- + Delete on public.rem1_nsc + -> Foreign Delete on public.rem1_nsc + InfluxDB query: DELETE FROM "loc1" +(3 rows) + +--Testcase 613: +DROP TRIGGER trig_row_before_insert ON rem1_nsc; +--Testcase 614: +CREATE TRIGGER trig_row_after_insert +AFTER INSERT ON rem1_nsc +FOR EACH ROW EXECUTE PROCEDURE trigger_data(23,'skidoo'); +--EXPLAIN (verbose, costs off) +--UPDATE rem1 set f2 = ''; -- can be pushed down +--Testcase 615: +EXPLAIN (verbose, costs off) +DELETE FROM rem1_nsc; -- can be pushed down + QUERY PLAN +-------------------------------------------- + Delete on public.rem1_nsc + -> Foreign Delete on public.rem1_nsc + InfluxDB query: DELETE FROM "loc1" +(3 rows) + +--Testcase 616: +DROP TRIGGER trig_row_after_insert ON rem1_nsc; +-- Test with row-level ON UPDATE triggers +--Testcase 617: +CREATE TRIGGER trig_row_before_update +BEFORE UPDATE ON rem1_nsc +FOR EACH ROW EXECUTE PROCEDURE trigger_data(23,'skidoo'); +--EXPLAIN (verbose, costs off) +--UPDATE rem1 set f2 = ''; -- can't be pushed down +--Testcase 618: +EXPLAIN (verbose, costs off) +DELETE FROM rem1_nsc; -- can be pushed down + QUERY PLAN +-------------------------------------------- + Delete on public.rem1_nsc + -> Foreign Delete on public.rem1_nsc + InfluxDB query: DELETE FROM "loc1" +(3 rows) + +--Testcase 619: +DROP TRIGGER trig_row_before_update ON rem1_nsc; +--Testcase 620: +CREATE TRIGGER trig_row_after_update +AFTER UPDATE ON rem1_nsc +FOR EACH ROW EXECUTE PROCEDURE trigger_data(23,'skidoo'); +--EXPLAIN (verbose, costs off) +--UPDATE rem1 set f2 = ''; -- can't be pushed down +--Testcase 621: +EXPLAIN (verbose, costs off) +DELETE FROM rem1_nsc; -- can be pushed down + QUERY PLAN +-------------------------------------------- + Delete on public.rem1_nsc + -> Foreign Delete on public.rem1_nsc + InfluxDB query: DELETE FROM "loc1" +(3 rows) + +--Testcase 622: +DROP TRIGGER trig_row_after_update ON rem1_nsc; +-- Test with row-level ON DELETE triggers +--Testcase 623: +CREATE TRIGGER trig_row_before_delete +BEFORE DELETE ON rem1_nsc +FOR EACH ROW EXECUTE PROCEDURE trigger_data(23,'skidoo'); +--EXPLAIN (verbose, costs off) +--UPDATE rem1 set f2 = ''; -- can be pushed down +--Testcase 624: +EXPLAIN (verbose, costs off) +DELETE FROM rem1_nsc; -- can't be pushed down + QUERY PLAN +------------------------------------------------------- + Delete on public.rem1_nsc + -> Foreign Scan on public.rem1_nsc + Output: rem1_nsc.* + InfluxDB query: SELECT "f1", "f2" FROM "loc1" +(4 rows) + +--Testcase 625: +DROP TRIGGER trig_row_before_delete ON rem1_nsc; +--Testcase 626: +CREATE TRIGGER trig_row_after_delete +AFTER DELETE ON rem1_nsc +FOR EACH ROW EXECUTE PROCEDURE trigger_data(23,'skidoo'); +--EXPLAIN (verbose, costs off) +--UPDATE rem1 set f2 = ''; -- can be pushed down +--Testcase 627: +EXPLAIN (verbose, costs off) +DELETE FROM rem1_nsc; -- can't be pushed down + QUERY PLAN +------------------------------------------------------- + Delete on public.rem1_nsc + -> Foreign Scan on public.rem1_nsc + Output: rem1_nsc.* + InfluxDB query: SELECT "f1", "f2" FROM "loc1" +(4 rows) + +--Testcase 628: +DROP TRIGGER trig_row_after_delete ON rem1_nsc; +-- =================================================================== +-- test inheritance features +-- =================================================================== +--Testcase 629: +CREATE TABLE a (aa TEXT); +--CREATE TABLE loct (aa TEXT, bb TEXT); +--Testcase 630: +ALTER TABLE a SET (autovacuum_enabled = 'false'); +--ALTER TABLE loct SET (autovacuum_enabled = 'false'); +-- Because influxdb_fdw does not support UPDATE, to test locally +-- we create local table. +--Testcase 631: +CREATE TABLE b (bb TEXT) INHERITS (a); +--Testcase 632: +INSERT INTO a(aa) VALUES('aaa'); +--Testcase 633: +INSERT INTO a(aa) VALUES('aaaa'); +--Testcase 634: +INSERT INTO a(aa) VALUES('aaaaa'); +--Testcase 635: +INSERT INTO b(aa) VALUES('bbb'); +--Testcase 636: +INSERT INTO b(aa) VALUES('bbbb'); +--Testcase 637: +INSERT INTO b(aa) VALUES('bbbbb'); +--Testcase 638: +SELECT tableoid::regclass, * FROM a; + tableoid | aa +----------+------- + a | aaa + a | aaaa + a | aaaaa + b | bbb + b | bbbb + b | bbbbb +(6 rows) + +--Testcase 639: +SELECT tableoid::regclass, * FROM b; + tableoid | aa | bb +----------+-------+---- + b | bbb | + b | bbbb | + b | bbbbb | +(3 rows) + +--Testcase 640: +SELECT tableoid::regclass, * FROM ONLY a; + tableoid | aa +----------+------- + a | aaa + a | aaaa + a | aaaaa +(3 rows) + +--Testcase 641: +UPDATE a SET aa = 'zzzzzz' WHERE aa LIKE 'aaaa%'; +--Testcase 642: +SELECT tableoid::regclass, * FROM a; + tableoid | aa +----------+-------- + a | aaa + a | zzzzzz + a | zzzzzz + b | bbb + b | bbbb + b | bbbbb +(6 rows) + +--Testcase 643: +SELECT tableoid::regclass, * FROM b; + tableoid | aa | bb +----------+-------+---- + b | bbb | + b | bbbb | + b | bbbbb | +(3 rows) + +--Testcase 644: +SELECT tableoid::regclass, * FROM ONLY a; + tableoid | aa +----------+-------- + a | aaa + a | zzzzzz + a | zzzzzz +(3 rows) + +--Testcase 645: +UPDATE b SET aa = 'new'; +--Testcase 646: +SELECT tableoid::regclass, * FROM a; + tableoid | aa +----------+-------- + a | aaa + a | zzzzzz + a | zzzzzz + b | new + b | new + b | new +(6 rows) + +--Testcase 647: +SELECT tableoid::regclass, * FROM b; + tableoid | aa | bb +----------+-----+---- + b | new | + b | new | + b | new | +(3 rows) + +--Testcase 648: +SELECT tableoid::regclass, * FROM ONLY a; + tableoid | aa +----------+-------- + a | aaa + a | zzzzzz + a | zzzzzz +(3 rows) + +--Testcase 649: +UPDATE a SET aa = 'newtoo'; +--Testcase 650: +SELECT tableoid::regclass, * FROM a; + tableoid | aa +----------+-------- + a | newtoo + a | newtoo + a | newtoo + b | newtoo + b | newtoo + b | newtoo +(6 rows) + +--Testcase 651: +SELECT tableoid::regclass, * FROM b; + tableoid | aa | bb +----------+--------+---- + b | newtoo | + b | newtoo | + b | newtoo | +(3 rows) + +--Testcase 652: +SELECT tableoid::regclass, * FROM ONLY a; + tableoid | aa +----------+-------- + a | newtoo + a | newtoo + a | newtoo +(3 rows) + +--Testcase 653: +DELETE FROM a; +--Testcase 654: +SELECT tableoid::regclass, * FROM a; + tableoid | aa +----------+---- +(0 rows) + +--Testcase 655: +SELECT tableoid::regclass, * FROM b; + tableoid | aa | bb +----------+----+---- +(0 rows) + +--Testcase 656: +SELECT tableoid::regclass, * FROM ONLY a; + tableoid | aa +----------+---- +(0 rows) + +--Testcase 657: +DROP TABLE a CASCADE; +NOTICE: drop cascades to table b +--DROP TABLE loct; +-- Check SELECT FOR UPDATE/SHARE with an inherited source table +--Testcase 658: +create foreign table loct1 (fields jsonb OPTIONS(fields 'true')) SERVER influxdb_svr OPTIONS (table 'loct1', schemaless 'true'); +--Testcase 807: +create foreign table loct1_nsc (f1 int, f2 int, f3 int) server influxdb_svr options(table 'loct1'); +--Testcase 659: +create foreign table loct2 (fields jsonb OPTIONS(fields 'true')) SERVER influxdb_svr OPTIONS (table 'loct2', schemaless 'true'); +--Testcase 808: +create foreign table loct2_nsc (f1 int, f2 int, f3 int) server influxdb_svr options(table 'loct2'); +--alter table loct1 set (autovacuum_enabled = 'false'); +--alter table loct2 set (autovacuum_enabled = 'false'); +--Testcase 660: +create foreign table foo (fields jsonb OPTIONS(fields 'true')) SERVER influxdb_svr OPTIONS (table 'foo', schemaless 'true'); +--Testcase 809: +create foreign table foo_nsc (f1 int, f2 int) + server influxdb_svr options (table 'foo'); +--Testcase 661: +create foreign table foo2 (fields jsonb OPTIONS(fields 'true')) inherits (foo) + server influxdb_svr options (table 'loct1', schemaless 'true'); +NOTICE: merging column "fields" with inherited definition +--Testcase 810: +create foreign table foo2_nsc (f3 int) inherits (foo_nsc) + server influxdb_svr options (table 'loct1'); +--Testcase 662: +create foreign table bar (fields jsonb OPTIONS(fields 'true')) + server influxdb_svr options (table 'bar', schemaless 'true'); +--Testcase 811: +create foreign table bar_nsc (f1 int, f2 int) + server influxdb_svr options (table 'bar'); +--Testcase 663: +create foreign table bar2 (fields jsonb OPTIONS(fields 'true')) inherits (bar) + server influxdb_svr options (table 'loct2', schemaless 'true'); +NOTICE: merging column "fields" with inherited definition +--Testcase 812: +create foreign table bar2_nsc (f3 int) inherits (bar_nsc) + server influxdb_svr options (table 'loct2'); +--alter table foo set (autovacuum_enabled = 'false'); +--alter table bar set (autovacuum_enabled = 'false'); +--Testcase 664: +insert into foo_nsc values(1,1); +--Testcase 665: +insert into foo_nsc values(3,3); +--Testcase 666: +insert into foo2_nsc values(2,2,2); +--Testcase 667: +insert into foo2_nsc values(4,4,4); +--Testcase 668: +insert into bar_nsc values(1,11); +--Testcase 669: +insert into bar_nsc values(2,22); +--Testcase 670: +insert into bar_nsc values(6,66); +--Testcase 671: +insert into bar2_nsc values(3,33,33); +--Testcase 672: +insert into bar2_nsc values(4,44,44); +--Testcase 673: +insert into bar2_nsc values(7,77,77); +--Testcase 674: +explain (verbose, costs off) +select * from bar where fields->>'f1' in (select fields->>'f1' from foo); + QUERY PLAN +-------------------------------------------------------------------------- + Hash Join + Output: bar.fields + Inner Unique: true + Hash Cond: ((bar.fields ->> 'f1'::text) = (foo.fields ->> 'f1'::text)) + -> Append + -> Foreign Scan on public.bar bar_1 + Output: bar_1.fields + InfluxDB query: SELECT * FROM "bar" + -> Foreign Scan on public.bar2 bar_2 + Output: bar_2.fields + InfluxDB query: SELECT * FROM "loct2" + -> Hash + Output: foo.fields + -> HashAggregate + Output: foo.fields + Group Key: (foo.fields ->> 'f1'::text) + -> Result + Output: foo.fields, (foo.fields ->> 'f1'::text) + -> Append + -> Foreign Scan on public.foo foo_1 + Output: foo_1.fields + InfluxDB query: SELECT * FROM "foo" + -> Foreign Scan on public.foo2 foo_2 + Output: foo_2.fields + InfluxDB query: SELECT * FROM "loct1" +(25 rows) + +--Testcase 675: +select * from bar where fields->>'f1' in (select fields->>'f1' from foo); + fields +------------------------------------- + {"f1": "1", "f2": "11"} + {"f1": "2", "f2": "22"} + {"f1": "3", "f2": "33", "f3": "33"} + {"f1": "4", "f2": "44", "f3": "44"} +(4 rows) + +--Testcase 676: +explain (verbose, costs off) +select * from bar where fields->>'f1' in (select fields->>'f1' from foo); + QUERY PLAN +-------------------------------------------------------------------------- + Hash Join + Output: bar.fields + Inner Unique: true + Hash Cond: ((bar.fields ->> 'f1'::text) = (foo.fields ->> 'f1'::text)) + -> Append + -> Foreign Scan on public.bar bar_1 + Output: bar_1.fields + InfluxDB query: SELECT * FROM "bar" + -> Foreign Scan on public.bar2 bar_2 + Output: bar_2.fields + InfluxDB query: SELECT * FROM "loct2" + -> Hash + Output: foo.fields + -> HashAggregate + Output: foo.fields + Group Key: (foo.fields ->> 'f1'::text) + -> Result + Output: foo.fields, (foo.fields ->> 'f1'::text) + -> Append + -> Foreign Scan on public.foo foo_1 + Output: foo_1.fields + InfluxDB query: SELECT * FROM "foo" + -> Foreign Scan on public.foo2 foo_2 + Output: foo_2.fields + InfluxDB query: SELECT * FROM "loct1" +(25 rows) + +--Testcase 677: +select * from bar where fields->>'f1' in (select fields->>'f1' from foo); + fields +------------------------------------- + {"f1": "1", "f2": "11"} + {"f1": "2", "f2": "22"} + {"f1": "3", "f2": "33", "f3": "33"} + {"f1": "4", "f2": "44", "f3": "44"} +(4 rows) + +-- Now check SELECT FOR UPDATE/SHARE with an inherited source table, +-- where the parent is itself a foreign table +--Testcase 678: +create foreign table foo2child (fields jsonb OPTIONS(fields 'true')) inherits (foo2) + server influxdb_svr options (table 'loct4', schemaless 'true'); +NOTICE: merging column "fields" with inherited definition +--Testcase 679: +explain (verbose, costs off) +select * from bar where fields->>'f1' in (select fields->>'f1' from foo2) for share; + QUERY PLAN +---------------------------------------------------------------------------------------------------- + LockRows + Output: bar.fields, bar.*, foo2.*, bar.tableoid, foo2.tableoid + -> Hash Join + Output: bar.fields, bar.*, foo2.*, bar.tableoid, foo2.tableoid + Inner Unique: true + Hash Cond: ((bar.fields ->> 'f1'::text) = (foo2.fields ->> 'f1'::text)) + -> Append + -> Foreign Scan on public.bar bar_1 + Output: bar_1.fields, bar_1.*, bar_1.tableoid + InfluxDB query: SELECT * FROM "bar" + -> Foreign Scan on public.bar2 bar_2 + Output: bar_2.fields, bar_2.*, bar_2.tableoid + InfluxDB query: SELECT * FROM "loct2" + -> Hash + Output: foo2.*, foo2.fields, foo2.tableoid + -> HashAggregate + Output: foo2.*, foo2.fields, foo2.tableoid + Group Key: (foo2.fields ->> 'f1'::text) + -> Result + Output: foo2.*, foo2.fields, foo2.tableoid, (foo2.fields ->> 'f1'::text) + -> Append + -> Foreign Scan on public.foo2 foo2_1 + Output: foo2_1.*, foo2_1.fields, foo2_1.tableoid + InfluxDB query: SELECT * FROM "loct1" + -> Foreign Scan on public.foo2child foo2_2 + Output: foo2_2.*, foo2_2.fields, foo2_2.tableoid + InfluxDB query: SELECT * FROM "loct4" +(27 rows) + +--Testcase 680: +select * from bar where fields->>'f1' in (select fields->>'f1' from foo2) for share; + fields +------------------------------------- + {"f1": "2", "f2": "22"} + {"f1": "4", "f2": "44", "f3": "44"} +(2 rows) + +--Testcase 681: +drop foreign table foo2child; +-- And with a local child relation of the foreign table parent +--Testcase 682: +create foreign table foo2child (fields jsonb OPTIONS(fields 'true')) inherits (foo2) + server influxdb_svr options (table 'foo2child', schemaless 'true'); +NOTICE: merging column "fields" with inherited definition +--Testcase 683: +explain (verbose, costs off) +select * from bar where fields->>'f1' in (select fields->>'f1' from foo2) for share; + QUERY PLAN +---------------------------------------------------------------------------------------------------- + LockRows + Output: bar.fields, bar.*, foo2.*, bar.tableoid, foo2.tableoid + -> Hash Join + Output: bar.fields, bar.*, foo2.*, bar.tableoid, foo2.tableoid + Inner Unique: true + Hash Cond: ((bar.fields ->> 'f1'::text) = (foo2.fields ->> 'f1'::text)) + -> Append + -> Foreign Scan on public.bar bar_1 + Output: bar_1.fields, bar_1.*, bar_1.tableoid + InfluxDB query: SELECT * FROM "bar" + -> Foreign Scan on public.bar2 bar_2 + Output: bar_2.fields, bar_2.*, bar_2.tableoid + InfluxDB query: SELECT * FROM "loct2" + -> Hash + Output: foo2.*, foo2.fields, foo2.tableoid + -> HashAggregate + Output: foo2.*, foo2.fields, foo2.tableoid + Group Key: (foo2.fields ->> 'f1'::text) + -> Result + Output: foo2.*, foo2.fields, foo2.tableoid, (foo2.fields ->> 'f1'::text) + -> Append + -> Foreign Scan on public.foo2 foo2_1 + Output: foo2_1.*, foo2_1.fields, foo2_1.tableoid + InfluxDB query: SELECT * FROM "loct1" + -> Foreign Scan on public.foo2child foo2_2 + Output: foo2_2.*, foo2_2.fields, foo2_2.tableoid + InfluxDB query: SELECT * FROM "foo2child" +(27 rows) + +--Testcase 684: +select * from bar where fields->>'f1' in (select fields->>'f1' from foo2) for share; + fields +------------------------------------- + {"f1": "2", "f2": "22"} + {"f1": "4", "f2": "44", "f3": "44"} +(2 rows) + +--Testcase 685: +drop foreign table foo2child; +/* +-- influxdb_fdw does not support UPDATE +-- Check UPDATE with inherited target and an inherited source table +explain (verbose, costs off) +update bar set f2 = f2 + 100 where f1 in (select f1 from foo); +update bar set f2 = f2 + 100 where f1 in (select f1 from foo); + +select tableoid::regclass, * from bar order by 1,2; + +-- Check UPDATE with inherited target and an appendrel subquery +explain (verbose, costs off) +update bar set f2 = f2 + 100 +from + ( select f1 from foo union all select f1+3 from foo ) ss +where bar.f1 = ss.f1; +update bar set f2 = f2 + 100 +from + ( select f1 from foo union all select f1+3 from foo ) ss +where bar.f1 = ss.f1; + +select tableoid::regclass, * from bar order by 1,2; + +-- Test forcing the remote server to produce sorted data for a merge join, +-- but the foreign table is an inheritance child. +truncate table loct1; +truncate table only foo; +\set num_rows_foo 2000 +insert into loct1 select generate_series(0, :num_rows_foo, 2), generate_series(0, :num_rows_foo, 2), generate_series(0, :num_rows_foo, 2); +insert into foo select generate_series(1, :num_rows_foo, 2), generate_series(1, :num_rows_foo, 2); +SET enable_hashjoin to false; +SET enable_nestloop to false; +alter foreign table foo2 options (use_remote_estimate 'true'); +create index i_loct1_f1 on loct1(f1); +create index i_foo_f1 on foo(f1); +analyze foo; +analyze loct1; +-- inner join; expressions in the clauses appear in the equivalence class list +explain (verbose, costs off) + select foo.f1, loct1.f1 from foo join loct1 on (foo.f1 = loct1.f1) order by foo.f2 offset 10 limit 10; +select foo.f1, loct1.f1 from foo join loct1 on (foo.f1 = loct1.f1) order by foo.f2 offset 10 limit 10; +-- outer join; expressions in the clauses do not appear in equivalence class +-- list but no output change as compared to the previous query +explain (verbose, costs off) + select foo.f1, loct1.f1 from foo left join loct1 on (foo.f1 = loct1.f1) order by foo.f2 offset 10 limit 10; +select foo.f1, loct1.f1 from foo left join loct1 on (foo.f1 = loct1.f1) order by foo.f2 offset 10 limit 10; +RESET enable_hashjoin; +RESET enable_nestloop; + +-- Test that WHERE CURRENT OF is not supported +begin; +declare c cursor for select * from bar where f1 = 7; +fetch from c; +update bar set f2 = null where current of c; +rollback; + +explain (verbose, costs off) +delete from foo where f1 < 5 returning *; +delete from foo where f1 < 5 returning *; +explain (verbose, costs off) +update bar set f2 = f2 + 100 returning *; +update bar set f2 = f2 + 100 returning *; + +-- Test that UPDATE/DELETE with inherited target works with row-level triggers +CREATE TRIGGER trig_row_before +BEFORE UPDATE OR DELETE ON bar2 +FOR EACH ROW EXECUTE PROCEDURE trigger_data(23,'skidoo'); + +CREATE TRIGGER trig_row_after +AFTER UPDATE OR DELETE ON bar2 +FOR EACH ROW EXECUTE PROCEDURE trigger_data(23,'skidoo'); + +explain (verbose, costs off) +update bar set f2 = f2 + 100; +update bar set f2 = f2 + 100; + +explain (verbose, costs off) +delete from bar where f2 < 400; +delete from bar where f2 < 400; + +-- cleanup +drop table foo cascade; +drop table bar cascade; +drop table loct1; +drop table loct2; + +-- Test pushing down UPDATE/DELETE joins to the remote server +create table parent (a int, b text); +create table loct1 (a int, b text); +create table loct2 (a int, b text); +create foreign table remt1 (a int, b text) + server influxdb_svr options (table 'loct1'); +create foreign table remt2 (a int, b text) + server influxdb_svr options (table 'loct2'); +alter foreign table remt1 inherit parent; + +insert into remt1 values (1, 'foo'); +insert into remt1 values (2, 'bar'); +insert into remt2 values (1, 'foo'); +insert into remt2 values (2, 'bar'); + +analyze remt1; +analyze remt2; + +explain (verbose, costs off) +update parent set b = parent.b || remt2.b from remt2 where parent.a = remt2.a returning *; +update parent set b = parent.b || remt2.b from remt2 where parent.a = remt2.a returning *; +explain (verbose, costs off) +delete from parent using remt2 where parent.a = remt2.a returning parent; +delete from parent using remt2 where parent.a = remt2.a returning parent; + +-- cleanup +drop foreign table remt1; +drop foreign table remt2; +drop table loct1; +drop table loct2; +drop table parent; +*/ +/* +-- Skip test because influxdb does not support partitions table, COPY +-- =================================================================== +-- test tuple routing for foreign-table partitions +-- =================================================================== + +-- Test insert tuple routing +create table itrtest (a int, b text) partition by list (a); +create table loct1 (a int check (a in (1)), b text); +create foreign table remp1 (a int check (a in (1)), b text) server loopback options (table_name 'loct1'); +create table loct2 (a int check (a in (2)), b text); +create foreign table remp2 (b text, a int check (a in (2))) server loopback options (table_name 'loct2'); +alter table itrtest attach partition remp1 for values in (1); +alter table itrtest attach partition remp2 for values in (2); + +insert into itrtest values (1, 'foo'); +insert into itrtest values (1, 'bar') returning *; +insert into itrtest values (2, 'baz'); +insert into itrtest values (2, 'qux') returning *; +insert into itrtest values (1, 'test1'), (2, 'test2') returning *; + +select tableoid::regclass, * FROM itrtest; +select tableoid::regclass, * FROM remp1; +select tableoid::regclass, * FROM remp2; + +delete from itrtest; + +-- MERGE ought to fail cleanly +merge into itrtest using (select 1, 'foo') as source on (true) + when matched then do nothing; + +create unique index loct1_idx on loct1 (a); + +-- DO NOTHING without an inference specification is supported +insert into itrtest values (1, 'foo') on conflict do nothing returning *; +insert into itrtest values (1, 'foo') on conflict do nothing returning *; + +-- But other cases are not supported +insert into itrtest values (1, 'bar') on conflict (a) do nothing; +insert into itrtest values (1, 'bar') on conflict (a) do update set b = excluded.b; + +select tableoid::regclass, * FROM itrtest; + +delete from itrtest; + +drop index loct1_idx; + +-- Test that remote triggers work with insert tuple routing +create function br_insert_trigfunc() returns trigger as $$ +begin + new.b := new.b || ' triggered !'; + return new; +end +$$ language plpgsql; +create trigger loct1_br_insert_trigger before insert on loct1 + for each row execute procedure br_insert_trigfunc(); +create trigger loct2_br_insert_trigger before insert on loct2 + for each row execute procedure br_insert_trigfunc(); + +-- The new values are concatenated with ' triggered !' +insert into itrtest values (1, 'foo') returning *; +insert into itrtest values (2, 'qux') returning *; +insert into itrtest values (1, 'test1'), (2, 'test2') returning *; +with result as (insert into itrtest values (1, 'test1'), (2, 'test2') returning *) select * from result; + +drop trigger loct1_br_insert_trigger on loct1; +drop trigger loct2_br_insert_trigger on loct2; + +drop table itrtest; +drop table loct1; +drop table loct2; + +-- Test update tuple routing +create table utrtest (a int, b text) partition by list (a); +create table loct (a int check (a in (1)), b text); +create foreign table remp (a int check (a in (1)), b text) server loopback options (table_name 'loct'); +create table locp (a int check (a in (2)), b text); +alter table utrtest attach partition remp for values in (1); +alter table utrtest attach partition locp for values in (2); + +insert into utrtest values (1, 'foo'); +insert into utrtest values (2, 'qux'); + +select tableoid::regclass, * FROM utrtest; +select tableoid::regclass, * FROM remp; +select tableoid::regclass, * FROM locp; + +-- It's not allowed to move a row from a partition that is foreign to another +update utrtest set a = 2 where b = 'foo' returning *; + +-- But the reverse is allowed +update utrtest set a = 1 where b = 'qux' returning *; + +select tableoid::regclass, * FROM utrtest; +select tableoid::regclass, * FROM remp; +select tableoid::regclass, * FROM locp; + +-- The executor should not let unexercised FDWs shut down +update utrtest set a = 1 where b = 'foo'; + +-- Test that remote triggers work with update tuple routing +create trigger loct_br_insert_trigger before insert on loct + for each row execute procedure br_insert_trigfunc(); + +delete from utrtest; +insert into utrtest values (2, 'qux'); + +-- Check case where the foreign partition is a subplan target rel +explain (verbose, costs off) +update utrtest set a = 1 where a = 1 or a = 2 returning *; +-- The new values are concatenated with ' triggered !' +update utrtest set a = 1 where a = 1 or a = 2 returning *; + +delete from utrtest; +insert into utrtest values (2, 'qux'); + +-- Check case where the foreign partition isn't a subplan target rel +explain (verbose, costs off) +update utrtest set a = 1 where a = 2 returning *; +-- The new values are concatenated with ' triggered !' +update utrtest set a = 1 where a = 2 returning *; + +drop trigger loct_br_insert_trigger on loct; + +-- We can move rows to a foreign partition that has been updated already, +-- but can't move rows to a foreign partition that hasn't been updated yet + +delete from utrtest; +insert into utrtest values (1, 'foo'); +insert into utrtest values (2, 'qux'); + +-- Test the former case: +-- with a direct modification plan +explain (verbose, costs off) +update utrtest set a = 1 returning *; +update utrtest set a = 1 returning *; + +delete from utrtest; +insert into utrtest values (1, 'foo'); +insert into utrtest values (2, 'qux'); + +-- with a non-direct modification plan +explain (verbose, costs off) +update utrtest set a = 1 from (values (1), (2)) s(x) where a = s.x returning *; +update utrtest set a = 1 from (values (1), (2)) s(x) where a = s.x returning *; + +-- Change the definition of utrtest so that the foreign partition get updated +-- after the local partition +delete from utrtest; +alter table utrtest detach partition remp; +drop foreign table remp; +alter table loct drop constraint loct_a_check; +alter table loct add check (a in (3)); +create foreign table remp (a int check (a in (3)), b text) server loopback options (table_name 'loct'); +alter table utrtest attach partition remp for values in (3); +insert into utrtest values (2, 'qux'); +insert into utrtest values (3, 'xyzzy'); + +-- Test the latter case: +-- with a direct modification plan +explain (verbose, costs off) +update utrtest set a = 3 returning *; +update utrtest set a = 3 returning *; -- ERROR + +-- with a non-direct modification plan +explain (verbose, costs off) +update utrtest set a = 3 from (values (2), (3)) s(x) where a = s.x returning *; +update utrtest set a = 3 from (values (2), (3)) s(x) where a = s.x returning *; -- ERROR + +drop table utrtest; +drop table loct; + +-- Test copy tuple routing +create table ctrtest (a int, b text) partition by list (a); +create table loct1 (a int check (a in (1)), b text); +create foreign table remp1 (a int check (a in (1)), b text) server loopback options (table_name 'loct1'); +create table loct2 (a int check (a in (2)), b text); +create foreign table remp2 (b text, a int check (a in (2))) server loopback options (table_name 'loct2'); +alter table ctrtest attach partition remp1 for values in (1); +alter table ctrtest attach partition remp2 for values in (2); + +copy ctrtest from stdin; +1 foo +2 qux +\. + +select tableoid::regclass, * FROM ctrtest; +select tableoid::regclass, * FROM remp1; +select tableoid::regclass, * FROM remp2; + +-- Copying into foreign partitions directly should work as well +copy remp1 from stdin; +1 bar +\. + +select tableoid::regclass, * FROM remp1; + +delete from ctrtest; + +-- Test copy tuple routing with the batch_size option enabled +alter server loopback options (add batch_size '2'); + +copy ctrtest from stdin; +1 foo +1 bar +2 baz +2 qux +1 test1 +2 test2 +\. + +select tableoid::regclass, * FROM ctrtest; +select tableoid::regclass, * FROM remp1; +select tableoid::regclass, * FROM remp2; + +delete from ctrtest; + +alter server loopback options (drop batch_size); + +drop table ctrtest; +drop table loct1; +drop table loct2; + +-- =================================================================== +-- test COPY FROM +-- =================================================================== + +create table loc2 (f1 int, f2 text); +alter table loc2 set (autovacuum_enabled = 'false'); +create foreign table rem2 (f1 int, f2 text) server loopback options(table_name 'loc2'); + +-- Test basic functionality +copy rem2 from stdin; +1 foo +2 bar +\. +select * from rem2; + +delete from rem2; + +-- Test check constraints +alter table loc2 add constraint loc2_f1positive check (f1 >= 0); +alter foreign table rem2 add constraint rem2_f1positive check (f1 >= 0); + +-- check constraint is enforced on the remote side, not locally +copy rem2 from stdin; +1 foo +2 bar +\. +copy rem2 from stdin; -- ERROR +-1 xyzzy +\. +select * from rem2; + +alter foreign table rem2 drop constraint rem2_f1positive; +alter table loc2 drop constraint loc2_f1positive; + +delete from rem2; + +-- Test local triggers +create trigger trig_stmt_before before insert on rem2 + for each statement execute procedure trigger_func(); +create trigger trig_stmt_after after insert on rem2 + for each statement execute procedure trigger_func(); +create trigger trig_row_before before insert on rem2 + for each row execute procedure trigger_data(23,'skidoo'); +create trigger trig_row_after after insert on rem2 + for each row execute procedure trigger_data(23,'skidoo'); + +copy rem2 from stdin; +1 foo +2 bar +\. +select * from rem2; + +drop trigger trig_row_before on rem2; +drop trigger trig_row_after on rem2; +drop trigger trig_stmt_before on rem2; +drop trigger trig_stmt_after on rem2; + +delete from rem2; + +create trigger trig_row_before_insert before insert on rem2 + for each row execute procedure trig_row_before_insupdate(); + +-- The new values are concatenated with ' triggered !' +copy rem2 from stdin; +1 foo +2 bar +\. +select * from rem2; + +drop trigger trig_row_before_insert on rem2; + +delete from rem2; + +create trigger trig_null before insert on rem2 + for each row execute procedure trig_null(); + +-- Nothing happens +copy rem2 from stdin; +1 foo +2 bar +\. +select * from rem2; + +drop trigger trig_null on rem2; + +delete from rem2; + +-- Test remote triggers +create trigger trig_row_before_insert before insert on loc2 + for each row execute procedure trig_row_before_insupdate(); + +-- The new values are concatenated with ' triggered !' +copy rem2 from stdin; +1 foo +2 bar +\. +select * from rem2; + +drop trigger trig_row_before_insert on loc2; + +delete from rem2; + +create trigger trig_null before insert on loc2 + for each row execute procedure trig_null(); + +-- Nothing happens +copy rem2 from stdin; +1 foo +2 bar +\. +select * from rem2; + +drop trigger trig_null on loc2; + +delete from rem2; + +-- Test a combination of local and remote triggers +create trigger rem2_trig_row_before before insert on rem2 + for each row execute procedure trigger_data(23,'skidoo'); +create trigger rem2_trig_row_after after insert on rem2 + for each row execute procedure trigger_data(23,'skidoo'); +create trigger loc2_trig_row_before_insert before insert on loc2 + for each row execute procedure trig_row_before_insupdate(); + +copy rem2 from stdin; +1 foo +2 bar +\. +select * from rem2; + +drop trigger rem2_trig_row_before on rem2; +drop trigger rem2_trig_row_after on rem2; +drop trigger loc2_trig_row_before_insert on loc2; + +delete from rem2; + +-- test COPY FROM with foreign table created in the same transaction +create table loc3 (f1 int, f2 text); +begin; +create foreign table rem3 (f1 int, f2 text) + server loopback options(table_name 'loc3'); +copy rem3 from stdin; +1 foo +2 bar +\. +commit; +select * from rem3; +drop foreign table rem3; +drop table loc3; + +-- Test COPY FROM with the batch_size option enabled +alter server loopback options (add batch_size '2'); + +-- Test basic functionality +copy rem2 from stdin; +1 foo +2 bar +3 baz +\. +select * from rem2; + +delete from rem2; + +-- Test check constraints +alter table loc2 add constraint loc2_f1positive check (f1 >= 0); +alter foreign table rem2 add constraint rem2_f1positive check (f1 >= 0); + +-- check constraint is enforced on the remote side, not locally +copy rem2 from stdin; +1 foo +2 bar +3 baz +\. +copy rem2 from stdin; -- ERROR +-1 xyzzy +\. +select * from rem2; + +alter foreign table rem2 drop constraint rem2_f1positive; +alter table loc2 drop constraint loc2_f1positive; + +delete from rem2; + +-- Test remote triggers +create trigger trig_row_before_insert before insert on loc2 + for each row execute procedure trig_row_before_insupdate(); + +-- The new values are concatenated with ' triggered !' +copy rem2 from stdin; +1 foo +2 bar +3 baz +\. +select * from rem2; + +drop trigger trig_row_before_insert on loc2; + +delete from rem2; + +create trigger trig_null before insert on loc2 + for each row execute procedure trig_null(); + +-- Nothing happens +copy rem2 from stdin; +1 foo +2 bar +3 baz +\. +select * from rem2; + +drop trigger trig_null on loc2; + +delete from rem2; + +-- Check with zero-column foreign table; batch insert will be disabled +alter table loc2 drop column f1; +alter table loc2 drop column f2; +alter table rem2 drop column f1; +alter table rem2 drop column f2; +copy rem2 from stdin; + + + +\. +select * from rem2; + +delete from rem2; + +alter server loopback options (drop batch_size); +*/ +/* +-- Skip test because influxdb does not support TRUNCATE +-- =================================================================== +-- test for TRUNCATE +-- =================================================================== +CREATE TABLE tru_rtable0 (id int primary key); +CREATE FOREIGN TABLE tru_ftable (id int) + SERVER loopback OPTIONS (table_name 'tru_rtable0'); +INSERT INTO tru_rtable0 (SELECT x FROM generate_series(1,10) x); + +CREATE TABLE tru_ptable (id int) PARTITION BY HASH(id); +CREATE TABLE tru_ptable__p0 PARTITION OF tru_ptable + FOR VALUES WITH (MODULUS 2, REMAINDER 0); +CREATE TABLE tru_rtable1 (id int primary key); +CREATE FOREIGN TABLE tru_ftable__p1 PARTITION OF tru_ptable + FOR VALUES WITH (MODULUS 2, REMAINDER 1) + SERVER loopback OPTIONS (table_name 'tru_rtable1'); +INSERT INTO tru_ptable (SELECT x FROM generate_series(11,20) x); + +CREATE TABLE tru_pk_table(id int primary key); +CREATE TABLE tru_fk_table(fkey int references tru_pk_table(id)); +INSERT INTO tru_pk_table (SELECT x FROM generate_series(1,10) x); +INSERT INTO tru_fk_table (SELECT x % 10 + 1 FROM generate_series(5,25) x); +CREATE FOREIGN TABLE tru_pk_ftable (id int) + SERVER loopback OPTIONS (table_name 'tru_pk_table'); + +CREATE TABLE tru_rtable_parent (id int); +CREATE TABLE tru_rtable_child (id int); +CREATE FOREIGN TABLE tru_ftable_parent (id int) + SERVER loopback OPTIONS (table_name 'tru_rtable_parent'); +CREATE FOREIGN TABLE tru_ftable_child () INHERITS (tru_ftable_parent) + SERVER loopback OPTIONS (table_name 'tru_rtable_child'); +INSERT INTO tru_rtable_parent (SELECT x FROM generate_series(1,8) x); +INSERT INTO tru_rtable_child (SELECT x FROM generate_series(10, 18) x); + +-- normal truncate +SELECT sum(id) FROM tru_ftable; -- 55 +TRUNCATE tru_ftable; +SELECT count(*) FROM tru_rtable0; -- 0 +SELECT count(*) FROM tru_ftable; -- 0 + +-- 'truncatable' option +ALTER SERVER loopback OPTIONS (ADD truncatable 'false'); +TRUNCATE tru_ftable; -- error +ALTER FOREIGN TABLE tru_ftable OPTIONS (ADD truncatable 'true'); +TRUNCATE tru_ftable; -- accepted +ALTER FOREIGN TABLE tru_ftable OPTIONS (SET truncatable 'false'); +TRUNCATE tru_ftable; -- error +ALTER SERVER loopback OPTIONS (DROP truncatable); +ALTER FOREIGN TABLE tru_ftable OPTIONS (SET truncatable 'false'); +TRUNCATE tru_ftable; -- error +ALTER FOREIGN TABLE tru_ftable OPTIONS (SET truncatable 'true'); +TRUNCATE tru_ftable; -- accepted + +-- partitioned table with both local and foreign tables as partitions +SELECT sum(id) FROM tru_ptable; -- 155 +TRUNCATE tru_ptable; +SELECT count(*) FROM tru_ptable; -- 0 +SELECT count(*) FROM tru_ptable__p0; -- 0 +SELECT count(*) FROM tru_ftable__p1; -- 0 +SELECT count(*) FROM tru_rtable1; -- 0 + +-- 'CASCADE' option +SELECT sum(id) FROM tru_pk_ftable; -- 55 +TRUNCATE tru_pk_ftable; -- failed by FK reference +TRUNCATE tru_pk_ftable CASCADE; +SELECT count(*) FROM tru_pk_ftable; -- 0 +SELECT count(*) FROM tru_fk_table; -- also truncated,0 + +-- truncate two tables at a command +INSERT INTO tru_ftable (SELECT x FROM generate_series(1,8) x); +INSERT INTO tru_pk_ftable (SELECT x FROM generate_series(3,10) x); +SELECT count(*) from tru_ftable; -- 8 +SELECT count(*) from tru_pk_ftable; -- 8 +TRUNCATE tru_ftable, tru_pk_ftable CASCADE; +SELECT count(*) from tru_ftable; -- 0 +SELECT count(*) from tru_pk_ftable; -- 0 + +-- truncate with ONLY clause +-- Since ONLY is specified, the table tru_ftable_child that inherits +-- tru_ftable_parent locally is not truncated. +TRUNCATE ONLY tru_ftable_parent; +SELECT sum(id) FROM tru_ftable_parent; -- 126 +TRUNCATE tru_ftable_parent; +SELECT count(*) FROM tru_ftable_parent; -- 0 + +-- in case when remote table has inherited children +CREATE TABLE tru_rtable0_child () INHERITS (tru_rtable0); +INSERT INTO tru_rtable0 (SELECT x FROM generate_series(5,9) x); +INSERT INTO tru_rtable0_child (SELECT x FROM generate_series(10,14) x); +SELECT sum(id) FROM tru_ftable; -- 95 + +-- Both parent and child tables in the foreign server are truncated +-- even though ONLY is specified because ONLY has no effect +-- when truncating a foreign table. +TRUNCATE ONLY tru_ftable; +SELECT count(*) FROM tru_ftable; -- 0 + +INSERT INTO tru_rtable0 (SELECT x FROM generate_series(21,25) x); +INSERT INTO tru_rtable0_child (SELECT x FROM generate_series(26,30) x); +SELECT sum(id) FROM tru_ftable; -- 255 +TRUNCATE tru_ftable; -- truncate both of parent and child +SELECT count(*) FROM tru_ftable; -- 0 + +-- cleanup +DROP FOREIGN TABLE tru_ftable_parent, tru_ftable_child, tru_pk_ftable,tru_ftable__p1,tru_ftable; +DROP TABLE tru_rtable0, tru_rtable1, tru_ptable, tru_ptable__p0, tru_pk_table, tru_fk_table, +tru_rtable_parent,tru_rtable_child, tru_rtable0_child; +*/ +-- =================================================================== +-- test IMPORT FOREIGN SCHEMA +-- =================================================================== +--Testcase 686: +CREATE SCHEMA import_influx1; +IMPORT FOREIGN SCHEMA public FROM SERVER influxdb_svr INTO import_influx1 OPTIONS (schemaless 'true'); +--Testcase 687: +\det+ import_influx1.* + List of foreign tables + Schema | Table | Server | FDW options | Description +----------------+-------+--------------+----------------------------------------------+------------- + import_influx1 | T1 | influxdb_svr | ("table" 'T1', schemaless 'true', tags 'c3') | + import_influx1 | T2 | influxdb_svr | ("table" 'T2', schemaless 'true', tags 'c2') | + import_influx1 | T3 | influxdb_svr | ("table" 'T3', schemaless 'true', tags 'c3') | + import_influx1 | T4 | influxdb_svr | ("table" 'T4', schemaless 'true', tags 'c3') | + import_influx1 | bar | influxdb_svr | ("table" 'bar', schemaless 'true') | + import_influx1 | foo | influxdb_svr | ("table" 'foo', schemaless 'true') | + import_influx1 | loc1 | influxdb_svr | ("table" 'loc1', schemaless 'true') | + import_influx1 | loct1 | influxdb_svr | ("table" 'loct1', schemaless 'true') | + import_influx1 | loct2 | influxdb_svr | ("table" 'loct2', schemaless 'true') | +(9 rows) + +--Testcase 688: +\d import_influx1.* + Foreign table "import_influx1.T1" + Column | Type | Collation | Nullable | Default | FDW options +--------+--------------------------+-----------+----------+---------+----------------- + time | timestamp with time zone | | | | + tags | jsonb | | | | (tags 'true') + fields | jsonb | | | | (fields 'true') +Server: influxdb_svr +FDW options: ("table" 'T1', schemaless 'true', tags 'c3') + + Foreign table "import_influx1.T2" + Column | Type | Collation | Nullable | Default | FDW options +--------+--------------------------+-----------+----------+---------+----------------- + time | timestamp with time zone | | | | + tags | jsonb | | | | (tags 'true') + fields | jsonb | | | | (fields 'true') +Server: influxdb_svr +FDW options: ("table" 'T2', schemaless 'true', tags 'c2') + + Foreign table "import_influx1.T3" + Column | Type | Collation | Nullable | Default | FDW options +--------+--------------------------+-----------+----------+---------+----------------- + time | timestamp with time zone | | | | + tags | jsonb | | | | (tags 'true') + fields | jsonb | | | | (fields 'true') +Server: influxdb_svr +FDW options: ("table" 'T3', schemaless 'true', tags 'c3') + + Foreign table "import_influx1.T4" + Column | Type | Collation | Nullable | Default | FDW options +--------+--------------------------+-----------+----------+---------+----------------- + time | timestamp with time zone | | | | + tags | jsonb | | | | (tags 'true') + fields | jsonb | | | | (fields 'true') +Server: influxdb_svr +FDW options: ("table" 'T4', schemaless 'true', tags 'c3') + + Foreign table "import_influx1.bar" + Column | Type | Collation | Nullable | Default | FDW options +--------+--------------------------+-----------+----------+---------+----------------- + time | timestamp with time zone | | | | + tags | jsonb | | | | (tags 'true') + fields | jsonb | | | | (fields 'true') +Server: influxdb_svr +FDW options: ("table" 'bar', schemaless 'true') + + Foreign table "import_influx1.foo" + Column | Type | Collation | Nullable | Default | FDW options +--------+--------------------------+-----------+----------+---------+----------------- + time | timestamp with time zone | | | | + tags | jsonb | | | | (tags 'true') + fields | jsonb | | | | (fields 'true') +Server: influxdb_svr +FDW options: ("table" 'foo', schemaless 'true') + + Foreign table "import_influx1.loc1" + Column | Type | Collation | Nullable | Default | FDW options +--------+--------------------------+-----------+----------+---------+----------------- + time | timestamp with time zone | | | | + tags | jsonb | | | | (tags 'true') + fields | jsonb | | | | (fields 'true') +Server: influxdb_svr +FDW options: ("table" 'loc1', schemaless 'true') + + Foreign table "import_influx1.loct1" + Column | Type | Collation | Nullable | Default | FDW options +--------+--------------------------+-----------+----------+---------+----------------- + time | timestamp with time zone | | | | + tags | jsonb | | | | (tags 'true') + fields | jsonb | | | | (fields 'true') +Server: influxdb_svr +FDW options: ("table" 'loct1', schemaless 'true') + + Foreign table "import_influx1.loct2" + Column | Type | Collation | Nullable | Default | FDW options +--------+--------------------------+-----------+----------+---------+----------------- + time | timestamp with time zone | | | | + tags | jsonb | | | | (tags 'true') + fields | jsonb | | | | (fields 'true') +Server: influxdb_svr +FDW options: ("table" 'loct2', schemaless 'true') + +-- Options +--Testcase 689: +CREATE SCHEMA import_influx2; +IMPORT FOREIGN SCHEMA public FROM SERVER influxdb_svr INTO import_influx2 + OPTIONS (import_default 'true', schemaless 'true'); +ERROR: invalid option "import_default" +--Testcase 690: +\det+ import_influx2.* + List of foreign tables + Schema | Table | Server | FDW options | Description +--------+-------+--------+-------------+------------- +(0 rows) + +--Testcase 691: +\d import_influx2.* +--Testcase 692: +CREATE SCHEMA import_influx3; +IMPORT FOREIGN SCHEMA public FROM SERVER influxdb_svr INTO import_influx3 + OPTIONS (import_collate 'false', import_not_null 'false', schemaless 'true'); +ERROR: invalid option "import_collate" +--Testcase 693: +\det+ import_influx3.* + List of foreign tables + Schema | Table | Server | FDW options | Description +--------+-------+--------+-------------+------------- +(0 rows) + +--Testcase 694: +\d import_influx3.* +-- Check LIMIT TO and EXCEPT +--Testcase 695: +CREATE SCHEMA import_influx4; +IMPORT FOREIGN SCHEMA public LIMIT TO ("T1", loct, nonesuch) + FROM SERVER influxdb_svr INTO import_influx4 OPTIONS (schemaless 'true'); +--Testcase 696: +\det+ import_influx4.* + List of foreign tables + Schema | Table | Server | FDW options | Description +----------------+-------+--------------+----------------------------------------------+------------- + import_influx4 | T1 | influxdb_svr | ("table" 'T1', schemaless 'true', tags 'c3') | +(1 row) + +IMPORT FOREIGN SCHEMA public EXCEPT ("T1", loct, nonesuch) + FROM SERVER influxdb_svr INTO import_influx4 OPTIONS (schemaless 'true'); +--Testcase 697: +\det+ import_influx4.* + List of foreign tables + Schema | Table | Server | FDW options | Description +----------------+-------+--------------+----------------------------------------------+------------- + import_influx4 | T1 | influxdb_svr | ("table" 'T1', schemaless 'true', tags 'c3') | + import_influx4 | T2 | influxdb_svr | ("table" 'T2', schemaless 'true', tags 'c2') | + import_influx4 | T3 | influxdb_svr | ("table" 'T3', schemaless 'true', tags 'c3') | + import_influx4 | T4 | influxdb_svr | ("table" 'T4', schemaless 'true', tags 'c3') | + import_influx4 | bar | influxdb_svr | ("table" 'bar', schemaless 'true') | + import_influx4 | foo | influxdb_svr | ("table" 'foo', schemaless 'true') | + import_influx4 | loc1 | influxdb_svr | ("table" 'loc1', schemaless 'true') | + import_influx4 | loct1 | influxdb_svr | ("table" 'loct1', schemaless 'true') | + import_influx4 | loct2 | influxdb_svr | ("table" 'loct2', schemaless 'true') | +(9 rows) + +-- Assorted error cases +IMPORT FOREIGN SCHEMA public FROM SERVER influxdb_svr INTO import_influx4 OPTIONS (schemaless 'true'); +ERROR: relation "T1" already exists +CONTEXT: importing foreign table "T1" +IMPORT FOREIGN SCHEMA nonesuch FROM SERVER influxdb_svr INTO import_influx4 OPTIONS (schemaless 'true'); +ERROR: relation "T1" already exists +CONTEXT: importing foreign table "T1" +IMPORT FOREIGN SCHEMA nonesuch FROM SERVER influxdb_svr INTO notthere OPTIONS (schemaless 'true'); +ERROR: schema "notthere" does not exist +IMPORT FOREIGN SCHEMA nonesuch FROM SERVER nowhere INTO notthere OPTIONS (schemaless 'true'); +ERROR: server "nowhere" does not exist +/* +-- Skip these test, influxdb_fdw does not support fetch_size option, partition table +-- Check case of a type present only on the remote server. +-- We can fake this by dropping the type locally in our transaction. +CREATE TYPE "Colors" AS ENUM ('red', 'green', 'blue'); +CREATE TABLE import_source.t5 (c1 int, c2 text collate "C", "Col" "Colors"); + +CREATE SCHEMA import_dest5; +BEGIN; +DROP TYPE "Colors" CASCADE; +IMPORT FOREIGN SCHEMA import_source LIMIT TO (t5) + FROM SERVER loopback INTO import_dest5; -- ERROR + +ROLLBACK; + +BEGIN; + + +CREATE SERVER fetch101 FOREIGN DATA WRAPPER postgres_fdw OPTIONS( fetch_size '101' ); + +SELECT count(*) +FROM pg_foreign_server +WHERE srvname = 'fetch101' +AND srvoptions @> array['fetch_size=101']; + +ALTER SERVER fetch101 OPTIONS( SET fetch_size '202' ); + +SELECT count(*) +FROM pg_foreign_server +WHERE srvname = 'fetch101' +AND srvoptions @> array['fetch_size=101']; + +SELECT count(*) +FROM pg_foreign_server +WHERE srvname = 'fetch101' +AND srvoptions @> array['fetch_size=202']; + +CREATE FOREIGN TABLE table30000 ( x int ) SERVER fetch101 OPTIONS ( fetch_size '30000' ); + +SELECT COUNT(*) +FROM pg_foreign_table +WHERE ftrelid = 'table30000'::regclass +AND ftoptions @> array['fetch_size=30000']; + +ALTER FOREIGN TABLE table30000 OPTIONS ( SET fetch_size '60000'); + +SELECT COUNT(*) +FROM pg_foreign_table +WHERE ftrelid = 'table30000'::regclass +AND ftoptions @> array['fetch_size=30000']; + +SELECT COUNT(*) +FROM pg_foreign_table +WHERE ftrelid = 'table30000'::regclass +AND ftoptions @> array['fetch_size=60000']; + +ROLLBACK; + +-- =================================================================== +-- test partitionwise joins +-- =================================================================== +SET enable_partitionwise_join=on; + +CREATE TABLE fprt1 (a int, b int, c varchar) PARTITION BY RANGE(a); +CREATE TABLE fprt1_p1 (LIKE fprt1); +CREATE TABLE fprt1_p2 (LIKE fprt1); +ALTER TABLE fprt1_p1 SET (autovacuum_enabled = 'false'); +ALTER TABLE fprt1_p2 SET (autovacuum_enabled = 'false'); +INSERT INTO fprt1_p1 SELECT i, i, to_char(i/50, 'FM0000') FROM generate_series(0, 249, 2) i; +INSERT INTO fprt1_p2 SELECT i, i, to_char(i/50, 'FM0000') FROM generate_series(250, 499, 2) i; +CREATE FOREIGN TABLE ftprt1_p1 PARTITION OF fprt1 FOR VALUES FROM (0) TO (250) + SERVER loopback OPTIONS (table_name 'fprt1_p1', use_remote_estimate 'true'); +CREATE FOREIGN TABLE ftprt1_p2 PARTITION OF fprt1 FOR VALUES FROM (250) TO (500) + SERVER loopback OPTIONS (TABLE_NAME 'fprt1_p2'); +ANALYZE fprt1; +ANALYZE fprt1_p1; +ANALYZE fprt1_p2; + +CREATE TABLE fprt2 (a int, b int, c varchar) PARTITION BY RANGE(b); +CREATE TABLE fprt2_p1 (LIKE fprt2); +CREATE TABLE fprt2_p2 (LIKE fprt2); +ALTER TABLE fprt2_p1 SET (autovacuum_enabled = 'false'); +ALTER TABLE fprt2_p2 SET (autovacuum_enabled = 'false'); +INSERT INTO fprt2_p1 SELECT i, i, to_char(i/50, 'FM0000') FROM generate_series(0, 249, 3) i; +INSERT INTO fprt2_p2 SELECT i, i, to_char(i/50, 'FM0000') FROM generate_series(250, 499, 3) i; +CREATE FOREIGN TABLE ftprt2_p1 (b int, c varchar, a int) + SERVER loopback OPTIONS (table_name 'fprt2_p1', use_remote_estimate 'true'); +ALTER TABLE fprt2 ATTACH PARTITION ftprt2_p1 FOR VALUES FROM (0) TO (250); +CREATE FOREIGN TABLE ftprt2_p2 PARTITION OF fprt2 FOR VALUES FROM (250) TO (500) + SERVER loopback OPTIONS (table_name 'fprt2_p2', use_remote_estimate 'true'); +ANALYZE fprt2; +ANALYZE fprt2_p1; +ANALYZE fprt2_p2; + +-- inner join three tables +EXPLAIN (COSTS OFF) +SELECT t1.a,t2.b,t3.c FROM fprt1 t1 INNER JOIN fprt2 t2 ON (t1.a = t2.b) INNER JOIN fprt1 t3 ON (t2.b = t3.a) WHERE t1.a % 25 =0 ORDER BY 1,2,3; +SELECT t1.a,t2.b,t3.c FROM fprt1 t1 INNER JOIN fprt2 t2 ON (t1.a = t2.b) INNER JOIN fprt1 t3 ON (t2.b = t3.a) WHERE t1.a % 25 =0 ORDER BY 1,2,3; + +-- left outer join + nullable clause +EXPLAIN (VERBOSE, COSTS OFF) +SELECT t1.a,t2.b,t2.c FROM fprt1 t1 LEFT JOIN (SELECT * FROM fprt2 WHERE a < 10) t2 ON (t1.a = t2.b and t1.b = t2.a) WHERE t1.a < 10 ORDER BY 1,2,3; +SELECT t1.a,t2.b,t2.c FROM fprt1 t1 LEFT JOIN (SELECT * FROM fprt2 WHERE a < 10) t2 ON (t1.a = t2.b and t1.b = t2.a) WHERE t1.a < 10 ORDER BY 1,2,3; + +-- with whole-row reference; partitionwise join does not apply +EXPLAIN (COSTS OFF) +SELECT t1.wr, t2.wr FROM (SELECT t1 wr, a FROM fprt1 t1 WHERE t1.a % 25 = 0) t1 FULL JOIN (SELECT t2 wr, b FROM fprt2 t2 WHERE t2.b % 25 = 0) t2 ON (t1.a = t2.b) ORDER BY 1,2; +SELECT t1.wr, t2.wr FROM (SELECT t1 wr, a FROM fprt1 t1 WHERE t1.a % 25 = 0) t1 FULL JOIN (SELECT t2 wr, b FROM fprt2 t2 WHERE t2.b % 25 = 0) t2 ON (t1.a = t2.b) ORDER BY 1,2; + +-- join with lateral reference +EXPLAIN (COSTS OFF) +SELECT t1.a,t1.b FROM fprt1 t1, LATERAL (SELECT t2.a, t2.b FROM fprt2 t2 WHERE t1.a = t2.b AND t1.b = t2.a) q WHERE t1.a%25 = 0 ORDER BY 1,2; +SELECT t1.a,t1.b FROM fprt1 t1, LATERAL (SELECT t2.a, t2.b FROM fprt2 t2 WHERE t1.a = t2.b AND t1.b = t2.a) q WHERE t1.a%25 = 0 ORDER BY 1,2; + +-- with PHVs, partitionwise join selected but no join pushdown +EXPLAIN (COSTS OFF) +SELECT t1.a, t1.phv, t2.b, t2.phv FROM (SELECT 't1_phv' phv, * FROM fprt1 WHERE a % 25 = 0) t1 FULL JOIN (SELECT 't2_phv' phv, * FROM fprt2 WHERE b % 25 = 0) t2 ON (t1.a = t2.b) ORDER BY t1.a, t2.b; +SELECT t1.a, t1.phv, t2.b, t2.phv FROM (SELECT 't1_phv' phv, * FROM fprt1 WHERE a % 25 = 0) t1 FULL JOIN (SELECT 't2_phv' phv, * FROM fprt2 WHERE b % 25 = 0) t2 ON (t1.a = t2.b) ORDER BY t1.a, t2.b; + +-- test FOR UPDATE; partitionwise join does not apply +EXPLAIN (COSTS OFF) +SELECT t1.a, t2.b FROM fprt1 t1 INNER JOIN fprt2 t2 ON (t1.a = t2.b) WHERE t1.a % 25 = 0 ORDER BY 1,2 FOR UPDATE OF t1; +SELECT t1.a, t2.b FROM fprt1 t1 INNER JOIN fprt2 t2 ON (t1.a = t2.b) WHERE t1.a % 25 = 0 ORDER BY 1,2 FOR UPDATE OF t1; + +RESET enable_partitionwise_join; + + +-- =================================================================== +-- test partitionwise aggregates +-- =================================================================== + +CREATE TABLE pagg_tab (a int, b int, c text) PARTITION BY RANGE(a); + +CREATE TABLE pagg_tab_p1 (LIKE pagg_tab); +CREATE TABLE pagg_tab_p2 (LIKE pagg_tab); +CREATE TABLE pagg_tab_p3 (LIKE pagg_tab); + +INSERT INTO pagg_tab_p1 SELECT i % 30, i % 50, to_char(i/30, 'FM0000') FROM generate_series(1, 3000) i WHERE (i % 30) < 10; +INSERT INTO pagg_tab_p2 SELECT i % 30, i % 50, to_char(i/30, 'FM0000') FROM generate_series(1, 3000) i WHERE (i % 30) < 20 and (i % 30) >= 10; +INSERT INTO pagg_tab_p3 SELECT i % 30, i % 50, to_char(i/30, 'FM0000') FROM generate_series(1, 3000) i WHERE (i % 30) < 30 and (i % 30) >= 20; + +-- Create foreign partitions +CREATE FOREIGN TABLE fpagg_tab_p1 PARTITION OF pagg_tab FOR VALUES FROM (0) TO (10) SERVER loopback OPTIONS (table_name 'pagg_tab_p1'); +CREATE FOREIGN TABLE fpagg_tab_p2 PARTITION OF pagg_tab FOR VALUES FROM (10) TO (20) SERVER loopback OPTIONS (table_name 'pagg_tab_p2'); +CREATE FOREIGN TABLE fpagg_tab_p3 PARTITION OF pagg_tab FOR VALUES FROM (20) TO (30) SERVER loopback OPTIONS (table_name 'pagg_tab_p3'); + +ANALYZE pagg_tab; +ANALYZE fpagg_tab_p1; +ANALYZE fpagg_tab_p2; +ANALYZE fpagg_tab_p3; + +-- When GROUP BY clause matches with PARTITION KEY. +-- Plan with partitionwise aggregates is disabled +SET enable_partitionwise_aggregate TO false; +EXPLAIN (COSTS OFF) +SELECT a, sum(b), min(b), count(*) FROM pagg_tab GROUP BY a HAVING avg(b) < 22 ORDER BY 1; + +-- Plan with partitionwise aggregates is enabled +SET enable_partitionwise_aggregate TO true; +EXPLAIN (COSTS OFF) +SELECT a, sum(b), min(b), count(*) FROM pagg_tab GROUP BY a HAVING avg(b) < 22 ORDER BY 1; +SELECT a, sum(b), min(b), count(*) FROM pagg_tab GROUP BY a HAVING avg(b) < 22 ORDER BY 1; + +-- Check with whole-row reference +-- Should have all the columns in the target list for the given relation +EXPLAIN (VERBOSE, COSTS OFF) +SELECT a, count(t1) FROM pagg_tab t1 GROUP BY a HAVING avg(b) < 22 ORDER BY 1; +SELECT a, count(t1) FROM pagg_tab t1 GROUP BY a HAVING avg(b) < 22 ORDER BY 1; + +-- When GROUP BY clause does not match with PARTITION KEY. +EXPLAIN (COSTS OFF) +SELECT b, avg(a), max(a), count(*) FROM pagg_tab GROUP BY b HAVING sum(a) < 700 ORDER BY 1; +*/ +/* +-- Skip test, influxdb_fdw does not support nosuperuser +-- =================================================================== +-- access rights and superuser +-- =================================================================== + +-- Non-superuser cannot create a FDW without a password in the connstr +CREATE ROLE regress_nosuper NOSUPERUSER; + +GRANT USAGE ON FOREIGN DATA WRAPPER influxdb_fdw TO regress_nosuper; + +SET ROLE regress_nosuper; + +SHOW is_superuser; + +-- This will be OK, we can create the FDW +DO $d$ + BEGIN + EXECUTE $$CREATE SERVER loopback_nopw FOREIGN DATA WRAPPER influxdb_fdw + OPTIONS (dbname '$$||current_database()||$$', + port '$$||current_setting('port')||$$' + )$$; + END; +$d$; + +-- But creation of user mappings for non-superusers should fail +CREATE USER MAPPING FOR public SERVER loopback_nopw; +CREATE USER MAPPING FOR CURRENT_USER SERVER loopback_nopw; + +CREATE FOREIGN TABLE pg_temp.ft1_nopw ( + c1 int NOT NULL, + c2 int NOT NULL, + c3 text, + c4 timestamptz, + c5 timestamptz, + c6 varchar(10), + c7 char(10) default 'ft1', + c8 user_enum +) SERVER loopback_nopw OPTIONS (schema_name 'public', table_name 'ft1'); + +SELECT 1 FROM ft1_nopw LIMIT 1; + +-- If we add a password to the connstr it'll fail, because we don't allow passwords +-- in connstrs only in user mappings. + +ALTER SERVER loopback_nopw OPTIONS (ADD password 'dummypw'); + +DO $d$ + BEGIN + EXECUTE $$ALTER SERVER loopback_nopw OPTIONS (ADD password 'dummypw')$$; + END; +$d$; + +-- If we add a password for our user mapping instead, we should get a different +-- error because the password wasn't actually *used* when we run with trust auth. +-- +-- This won't work with installcheck, but neither will most of the FDW checks. + +ALTER USER MAPPING FOR CURRENT_USER SERVER loopback_nopw OPTIONS (ADD password 'dummypw'); + +SELECT 1 FROM ft1_nopw LIMIT 1; + +-- Unpriv user cannot make the mapping passwordless +ALTER USER MAPPING FOR CURRENT_USER SERVER loopback_nopw OPTIONS (ADD password_required 'false'); + + +SELECT 1 FROM ft1_nopw LIMIT 1; + +RESET ROLE; + +-- But the superuser can +ALTER USER MAPPING FOR regress_nosuper SERVER loopback_nopw OPTIONS (ADD password_required 'false'); + +SET ROLE regress_nosuper; + +-- Should finally work now +SELECT 1 FROM ft1_nopw LIMIT 1; + +-- unpriv user also cannot set sslcert / sslkey on the user mapping +-- first set password_required so we see the right error messages +ALTER USER MAPPING FOR CURRENT_USER SERVER loopback_nopw OPTIONS (SET password_required 'true'); +ALTER USER MAPPING FOR CURRENT_USER SERVER loopback_nopw OPTIONS (ADD sslcert 'foo.crt'); +ALTER USER MAPPING FOR CURRENT_USER SERVER loopback_nopw OPTIONS (ADD sslkey 'foo.key'); + +-- We're done with the role named after a specific user and need to check the +-- changes to the public mapping. +DROP USER MAPPING FOR CURRENT_USER SERVER loopback_nopw; + +-- This will fail again as it'll resolve the user mapping for public, which +-- lacks password_required=false +SELECT 1 FROM ft1_nopw LIMIT 1; + +RESET ROLE; + +-- The user mapping for public is passwordless and lacks the password_required=false +-- mapping option, but will work because the current user is a superuser. +SELECT 1 FROM ft1_nopw LIMIT 1; + +-- cleanup +DROP USER MAPPING FOR public SERVER loopback_nopw; +DROP OWNED BY regress_nosuper; +DROP ROLE regress_nosuper; +*/ +-- influxdb_fdw does not support transactions +-- Two-phase transactions are not supported. +--BEGIN; +--Testcase 698: +SELECT count(*) FROM ft1; + count +------- + 822 +(1 row) + +-- error here +--PREPARE TRANSACTION 'fdw_tpc'; +--ROLLBACK; +/* +-- Influxdb_fdw does not use connection, and does not support connection functions +-- =================================================================== +-- reestablish new connection +-- =================================================================== + +-- Change application_name of remote connection to special one +-- so that we can easily terminate the connection later. +ALTER SERVER loopback OPTIONS (application_name 'fdw_retry_check'); + +-- Make sure we have a remote connection. +SELECT 1 FROM ft1 LIMIT 1; + +-- Terminate the remote connection and wait for the termination to complete. +-- (If a cache flush happens, the remote connection might have already been +-- dropped; so code this step in a way that doesn't fail if no connection.) +DO $$ BEGIN +PERFORM pg_terminate_backend(pid, 180000) FROM pg_stat_activity + WHERE application_name = 'fdw_retry_check'; +END $$; + +-- This query should detect the broken connection when starting new remote +-- transaction, reestablish new connection, and then succeed. +BEGIN; +SELECT 1 FROM ft1 LIMIT 1; + +-- If we detect the broken connection when starting a new remote +-- subtransaction, we should fail instead of establishing a new connection. +-- Terminate the remote connection and wait for the termination to complete. +DO $$ BEGIN +PERFORM pg_terminate_backend(pid, 180000) FROM pg_stat_activity + WHERE application_name = 'fdw_retry_check'; +END $$; +SAVEPOINT s; +-- The text of the error might vary across platforms, so only show SQLSTATE. +\set VERBOSITY sqlstate +SELECT 1 FROM ft1 LIMIT 1; -- should fail +\set VERBOSITY default +COMMIT; + +-- ============================================================================= +-- test connection invalidation cases and postgres_fdw_get_connections function +-- ============================================================================= +-- Let's ensure to close all the existing cached connections. +SELECT 1 FROM postgres_fdw_disconnect_all(); +-- No cached connections, so no records should be output. +SELECT server_name FROM postgres_fdw_get_connections() ORDER BY 1; +-- This test case is for closing the connection in pgfdw_xact_callback +BEGIN; +-- Connection xact depth becomes 1 i.e. the connection is in midst of the xact. +SELECT 1 FROM ft1 LIMIT 1; +SELECT 1 FROM ft7 LIMIT 1; +-- List all the existing cached connections. loopback and loopback3 should be +-- output. +SELECT server_name FROM postgres_fdw_get_connections() ORDER BY 1; +-- Connections are not closed at the end of the alter and drop statements. +-- That's because the connections are in midst of this xact, +-- they are just marked as invalid in pgfdw_inval_callback. +ALTER SERVER loopback OPTIONS (ADD use_remote_estimate 'off'); +DROP SERVER loopback3 CASCADE; +-- List all the existing cached connections. loopback and loopback3 +-- should be output as invalid connections. Also the server name for +-- loopback3 should be NULL because the server was dropped. +SELECT * FROM postgres_fdw_get_connections() ORDER BY 1; +-- The invalid connections get closed in pgfdw_xact_callback during commit. +COMMIT; +-- All cached connections were closed while committing above xact, so no +-- records should be output. +SELECT server_name FROM postgres_fdw_get_connections() ORDER BY 1; + +-- ======================================================================= +-- test postgres_fdw_disconnect and postgres_fdw_disconnect_all functions +-- ======================================================================= +BEGIN; +-- Ensure to cache loopback connection. +SELECT 1 FROM ft1 LIMIT 1; +-- Ensure to cache loopback2 connection. +SELECT 1 FROM ft6 LIMIT 1; +-- List all the existing cached connections. loopback and loopback2 should be +-- output. +SELECT server_name FROM postgres_fdw_get_connections() ORDER BY 1; +-- Issue a warning and return false as loopback connection is still in use and +-- can not be closed. +SELECT postgres_fdw_disconnect('loopback'); +-- List all the existing cached connections. loopback and loopback2 should be +-- output. +SELECT server_name FROM postgres_fdw_get_connections() ORDER BY 1; +-- Return false as connections are still in use, warnings are issued. +-- But disable warnings temporarily because the order of them is not stable. +SET client_min_messages = 'ERROR'; +SELECT postgres_fdw_disconnect_all(); +RESET client_min_messages; +COMMIT; +-- Ensure that loopback2 connection is closed. +SELECT 1 FROM postgres_fdw_disconnect('loopback2'); +SELECT server_name FROM postgres_fdw_get_connections() WHERE server_name = 'loopback2'; +-- Return false as loopback2 connection is closed already. +SELECT postgres_fdw_disconnect('loopback2'); +-- Return an error as there is no foreign server with given name. +SELECT postgres_fdw_disconnect('unknownserver'); +-- Let's ensure to close all the existing cached connections. +SELECT 1 FROM postgres_fdw_disconnect_all(); +-- No cached connections, so no records should be output. +SELECT server_name FROM postgres_fdw_get_connections() ORDER BY 1; + +-- ============================================================================= +-- test case for having multiple cached connections for a foreign server +-- ============================================================================= +CREATE ROLE regress_multi_conn_user1 SUPERUSER; +CREATE ROLE regress_multi_conn_user2 SUPERUSER; +CREATE USER MAPPING FOR regress_multi_conn_user1 SERVER loopback; +CREATE USER MAPPING FOR regress_multi_conn_user2 SERVER loopback; + +BEGIN; +-- Will cache loopback connection with user mapping for regress_multi_conn_user1 +SET ROLE regress_multi_conn_user1; +SELECT 1 FROM ft1 LIMIT 1; +RESET ROLE; + +-- Will cache loopback connection with user mapping for regress_multi_conn_user2 +SET ROLE regress_multi_conn_user2; +SELECT 1 FROM ft1 LIMIT 1; +RESET ROLE; + +-- Should output two connections for loopback server +SELECT server_name FROM postgres_fdw_get_connections() ORDER BY 1; +COMMIT; +-- Let's ensure to close all the existing cached connections. +SELECT 1 FROM postgres_fdw_disconnect_all(); +-- No cached connections, so no records should be output. +SELECT server_name FROM postgres_fdw_get_connections() ORDER BY 1; + +-- Clean up +DROP USER MAPPING FOR regress_multi_conn_user1 SERVER loopback; +DROP USER MAPPING FOR regress_multi_conn_user2 SERVER loopback; +DROP ROLE regress_multi_conn_user1; +DROP ROLE regress_multi_conn_user2; + +-- =================================================================== +-- Test foreign server level option keep_connections +-- =================================================================== +-- By default, the connections associated with foreign server are cached i.e. +-- keep_connections option is on. Set it to off. +ALTER SERVER loopback OPTIONS (keep_connections 'off'); +-- connection to loopback server is closed at the end of xact +-- as keep_connections was set to off. +SELECT 1 FROM ft1 LIMIT 1; +-- No cached connections, so no records should be output. +SELECT server_name FROM postgres_fdw_get_connections() ORDER BY 1; +ALTER SERVER loopback OPTIONS (SET keep_connections 'on'); +*/ +-- =================================================================== +-- batch insert +-- =================================================================== +BEGIN; +--Testcase 699: +CREATE SERVER batch10 FOREIGN DATA WRAPPER influxdb_fdw + OPTIONS(dbname 'postdb', :SERVER, batch_size '10' ); +--Testcase 700: +SELECT count(*) +FROM pg_foreign_server +WHERE srvname = 'batch10' +AND srvoptions @> array['batch_size=10']; + count +------- + 1 +(1 row) + +--Testcase 701: +ALTER SERVER batch10 OPTIONS( SET batch_size '20' ); +--Testcase 702: +SELECT count(*) +FROM pg_foreign_server +WHERE srvname = 'batch10' +AND srvoptions @> array['batch_size=10']; + count +------- + 0 +(1 row) + +--Testcase 703: +SELECT count(*) +FROM pg_foreign_server +WHERE srvname = 'batch10' +AND srvoptions @> array['batch_size=20']; + count +------- + 1 +(1 row) + +--Testcase 704: +CREATE FOREIGN TABLE table30 (fields jsonb OPTIONS(fields 'true')) + server batch10 options ( batch_size '30', schemaless 'true'); +--Testcase 705: +SELECT COUNT(*) +FROM pg_foreign_table +WHERE ftrelid = 'table30'::regclass +AND ftoptions @> array['batch_size=30']; + count +------- + 1 +(1 row) + +--Testcase 706: +ALTER FOREIGN TABLE table30 OPTIONS ( SET batch_size '40'); +--Testcase 707: +SELECT COUNT(*) +FROM pg_foreign_table +WHERE ftrelid = 'table30'::regclass +AND ftoptions @> array['batch_size=30']; + count +------- + 0 +(1 row) + +--Testcase 708: +SELECT COUNT(*) +FROM pg_foreign_table +WHERE ftrelid = 'table30'::regclass +AND ftoptions @> array['batch_size=40']; + count +------- + 1 +(1 row) + +ROLLBACK; +--Testcase 709: +CREATE FOREIGN TABLE batch_table (fields jsonb OPTIONS(fields 'true')) + SERVER influxdb_svr options (schemaless 'true'); +--Testcase 813: +CREATE FOREIGN TABLE batch_table_nsc ( x int ) SERVER influxdb_svr OPTIONS (table 'batch_table'); +--Testcase 710: +CREATE FOREIGN TABLE ftable (fields jsonb OPTIONS(fields 'true')) + SERVER influxdb_svr options ( table 'batch_table', batch_size '10', schemaless 'true'); +--Testcase 814: +CREATE FOREIGN TABLE ftable_nsc ( x int ) SERVER influxdb_svr OPTIONS ( table 'batch_table', batch_size '10' ); +--Testcase 711: +EXPLAIN (VERBOSE, COSTS OFF) INSERT INTO ftable_nsc SELECT * FROM generate_series(1, 10) i; + QUERY PLAN +----------------------------------------------------- + Insert on public.ftable_nsc + Batch Size: 10 + -> Function Scan on pg_catalog.generate_series i + Output: i.i + Function Call: generate_series(1, 10) +(5 rows) + +--Testcase 712: +INSERT INTO ftable_nsc SELECT * FROM generate_series(1, 10) i; +--Testcase 713: +INSERT INTO ftable_nsc SELECT * FROM generate_series(11, 31) i; +--Testcase 714: +INSERT INTO ftable_nsc VALUES (32); +--Testcase 715: +INSERT INTO ftable_nsc VALUES (33), (34); +--Testcase 721: +SELECT COUNT(*) FROM ftable; + count +------- + 34 +(1 row) + +--Testcase 722: +DELETE FROM batch_table_nsc; +--Testcase 723: +DROP FOREIGN TABLE ftable; +--Testcase 817: +DROP FOREIGN TABLE ftable_nsc; +-- Disable batch insert +--Testcase 724: +CREATE FOREIGN TABLE ftable (fields jsonb OPTIONS(fields 'true')) + SERVER influxdb_svr OPTIONS ( table 'batch_table', batch_size '1', schemaless 'true' ); +--Testcase 818: +CREATE FOREIGN TABLE ftable_nsc ( x int ) SERVER influxdb_svr OPTIONS ( table 'batch_table', batch_size '1' ); +--Testcase 725: +EXPLAIN (VERBOSE, COSTS OFF) INSERT INTO ftable_nsc VALUES (1), (2); + QUERY PLAN +------------------------------------ + Insert on public.ftable_nsc + Batch Size: 1 + -> Values Scan on "*VALUES*" + Output: "*VALUES*".column1 +(4 rows) + +--Testcase 726: +INSERT INTO ftable_nsc VALUES (1), (2); +--Testcase 727: +SELECT COUNT(*) FROM ftable; + count +------- + 2 +(1 row) + +-- Disable batch inserting into foreign tables with BEFORE ROW INSERT triggers +-- even if the batch_size option is enabled. +--Testcase 776: +ALTER FOREIGN TABLE ftable OPTIONS ( SET batch_size '10' ); +--Testcase 777: +CREATE TRIGGER trig_row_before BEFORE INSERT ON ftable_nsc +FOR EACH ROW EXECUTE PROCEDURE trigger_data(23,'skidoo'); +--Testcase 778: +EXPLAIN (VERBOSE, COSTS OFF) INSERT INTO ftable_nsc VALUES (3), (4); + QUERY PLAN +------------------------------------ + Insert on public.ftable_nsc + Batch Size: 1 + -> Values Scan on "*VALUES*" + Output: "*VALUES*".column1 +(4 rows) + +--Testcase 779: +INSERT INTO ftable_nsc VALUES (3), (4); +NOTICE: trig_row_before(23, skidoo) BEFORE ROW INSERT ON ftable_nsc +NOTICE: NEW: (3) +NOTICE: trig_row_before(23, skidoo) BEFORE ROW INSERT ON ftable_nsc +NOTICE: NEW: (4) +--Testcase 780: +SELECT COUNT(*) FROM ftable; + count +------- + 4 +(1 row) + +-- Clean up +--Testcase 781: +DROP TRIGGER trig_row_before ON ftable_nsc; +--Testcase 728: +DROP FOREIGN TABLE ftable; +--Testcase 819: +DROP FOREIGN TABLE ftable_nsc; +--Testcase 729: +DELETE FROM batch_table_nsc; +--Testcase 820: +DROP FOREIGN TABLE batch_table; +--Testcase 821: +DROP FOREIGN TABLE batch_table_nsc; +-- influxdb_fdw does not support partition insert +-- Use partitioning +--Testcase 730: +CREATE TABLE batch_table ( x int ) PARTITION BY HASH (x); +--Testcase 731: +CREATE TABLE batch_table_p0 (LIKE batch_table); +--Testcase 732: +CREATE FOREIGN TABLE batch_table_p0f + PARTITION OF batch_table + FOR VALUES WITH (MODULUS 3, REMAINDER 0) + SERVER influxdb_svr + OPTIONS (table 'batch_table_p0', batch_size '10', schemaless 'true'); +--Testcase 733: +CREATE TABLE batch_table_p1 (LIKE batch_table); +--Testcase 734: +CREATE FOREIGN TABLE batch_table_p1f + PARTITION OF batch_table + FOR VALUES WITH (MODULUS 3, REMAINDER 1) + SERVER influxdb_svr + OPTIONS (table 'batch_table_p1', batch_size '1', schemaless 'true'); +--Testcase 735: +CREATE TABLE batch_table_p2 + PARTITION OF batch_table + FOR VALUES WITH (MODULUS 3, REMAINDER 2); +--Testcase 736: +INSERT INTO batch_table SELECT * FROM generate_series(1, 66) i; +ERROR: Not support partition insert +--Testcase 737: +SELECT COUNT(*) FROM batch_table; + count +------- + 0 +(1 row) + +-- Clean up +DROP TABLE batch_table; +DROP TABLE batch_table_p0; +DROP TABLE batch_table_p1; +-- Check that batched mode also works for some inserts made during +-- cross-partition updates +--Testcase 738: +CREATE TABLE batch_cp_upd_test (a int) PARTITION BY LIST (a); +--Testcase 739: +CREATE TABLE batch_cp_upd_test1 (LIKE batch_cp_upd_test); +--Testcase 740: +CREATE FOREIGN TABLE batch_cp_upd_test1_f + PARTITION OF batch_cp_upd_test + FOR VALUES IN (1) + SERVER influxdb_svr + OPTIONS (table 'batch_cp_upd_test1', batch_size '10', schemaless 'true'); +--Testcase 741: +CREATE TABLE batch_cp_upd_test2 PARTITION OF batch_cp_upd_test + FOR VALUES IN (2); +--Testcase 742: +CREATE TABLE batch_cp_upd_test3 (LIKE batch_cp_upd_test); +CREATE FOREIGN TABLE batch_cp_upd_test3_f + PARTITION OF batch_cp_upd_test + FOR VALUES IN (3) + SERVER influxdb_svr + OPTIONS (table 'batch_cp_upd_test3', batch_size '1'); +-- Create statement triggers on remote tables that "log" any INSERTs +-- performed on them. +CREATE TABLE cmdlog (cmd text); +CREATE FUNCTION log_stmt() RETURNS TRIGGER LANGUAGE plpgsql AS $$ + BEGIN INSERT INTO public.cmdlog VALUES (TG_OP || ' on ' || TG_RELNAME); RETURN NULL; END; +$$; +CREATE TRIGGER stmt_trig AFTER INSERT ON batch_cp_upd_test1 + FOR EACH STATEMENT EXECUTE FUNCTION log_stmt(); +CREATE TRIGGER stmt_trig AFTER INSERT ON batch_cp_upd_test3 + FOR EACH STATEMENT EXECUTE FUNCTION log_stmt(); +-- This update moves rows from the local partition 'batch_cp_upd_test2' to the +-- foreign partition 'batch_cp_upd_test1', one that has insert batching +-- enabled, so a single INSERT for both rows. +INSERT INTO batch_cp_upd_test VALUES (2), (2); +-- influxdb_fdw does not support update +-- UPDATE batch_cp_upd_test t SET a = 1 FROM (VALUES (1), (2)) s(a) WHERE t.a = s.a AND s.a = 2; +-- This one moves rows from the local partition 'batch_cp_upd_test2' to the +-- foreign partition 'batch_cp_upd_test2', one that has insert batching +-- disabled, so separate INSERTs for the two rows. +INSERT INTO batch_cp_upd_test VALUES (2), (2); +-- UPDATE batch_cp_upd_test t SET a = 3 FROM (VALUES (1), (2)) s(a) WHERE t.a = s.a AND s.a = 2; +SELECT tableoid::regclass, * FROM batch_cp_upd_test ORDER BY 1; + tableoid | a +--------------------+--- + batch_cp_upd_test2 | 2 + batch_cp_upd_test2 | 2 + batch_cp_upd_test2 | 2 + batch_cp_upd_test2 | 2 +(4 rows) + +-- Should see 1 INSERT on batch_cp_upd_test1 and 2 on batch_cp_upd_test3 as +-- described above. +SELECT * FROM cmdlog ORDER BY 1; + cmd +----- +(0 rows) + +-- Clean up +DROP TABLE batch_cp_upd_test; +DROP TABLE batch_cp_upd_test1; +DROP TABLE batch_cp_upd_test3; +DROP TABLE cmdlog; +DROP FUNCTION log_stmt(); +-- influxdb_fdw does not support partition insert +-- Use partitioning +--Testcase 745: +ALTER SERVER influxdb_svr OPTIONS (ADD batch_size '10'); +--Testcase 746: +CREATE TABLE batch_table ( x int, field1 text, field2 text) PARTITION BY HASH (x); +--Testcase 747: +CREATE TABLE batch_table_p0 (LIKE batch_table); +--Testcase 748: +ALTER TABLE batch_table_p0 ADD CONSTRAINT p0_pkey PRIMARY KEY (x); +--Testcase 749: +CREATE FOREIGN TABLE batch_table_p0f + PARTITION OF batch_table + FOR VALUES WITH (MODULUS 2, REMAINDER 0) + SERVER influxdb_svr + OPTIONS (table 'batch_table_p0', schemaless 'true'); +--Testcase 750: +CREATE TABLE batch_table_p1 (LIKE batch_table); +--Testcase 751: +ALTER TABLE batch_table_p1 ADD CONSTRAINT p1_pkey PRIMARY KEY (x); +--Testcase 752: +CREATE FOREIGN TABLE batch_table_p1f + PARTITION OF batch_table + FOR VALUES WITH (MODULUS 2, REMAINDER 1) + SERVER influxdb_svr + OPTIONS (table 'batch_table_p1', schemaless 'true'); +--Testcase 753: +INSERT INTO batch_table SELECT i, 'test'||i, 'test'|| i FROM generate_series(1, 50) i; +ERROR: Not support partition insert +--Testcase 754: +SELECT COUNT(*) FROM batch_table; + count +------- + 0 +(1 row) + +--Testcase 755: +SELECT * FROM batch_table ORDER BY x; + x | field1 | field2 +---+--------+-------- +(0 rows) + +-- Clean up +DROP TABLE batch_table; +DROP TABLE batch_table_p0; +DROP TABLE batch_table_p1; +--Testcase 756: +ALTER SERVER influxdb_svr OPTIONS (DROP batch_size); +-- Test that pending inserts are handled properly when needed +CREATE TABLE batch_table (a text, b int); +CREATE FOREIGN TABLE ftable_nsc (a text, b int) + SERVER influxdb_svr + OPTIONS (table 'batch_table', batch_size '2'); +CREATE FOREIGN TABLE ftable (fields jsonb OPTIONS(fields 'true')) + SERVER influxdb_svr OPTIONS ( table 'batch_table', batch_size '2', schemaless 'true' ); +CREATE TABLE ltable (a text, b int); +CREATE FUNCTION ftable_rowcount_trigf() RETURNS trigger LANGUAGE plpgsql AS +$$ +begin + raise notice '%: there are % rows in ftable', + TG_NAME, (SELECT count(*) FROM ftable); + if TG_OP = 'DELETE' then + return OLD; + else + return NEW; + end if; +end; +$$; +CREATE TRIGGER ftable_rowcount_trigger +BEFORE INSERT OR UPDATE OR DELETE ON ltable +FOR EACH ROW EXECUTE PROCEDURE ftable_rowcount_trigf(); +WITH t AS ( + INSERT INTO ltable VALUES ('AAA', 42), ('BBB', 42) RETURNING * +) +INSERT INTO ftable_nsc SELECT * FROM t; +NOTICE: ftable_rowcount_trigger: there are rows in ftable +NOTICE: ftable_rowcount_trigger: there are 1 rows in ftable +SELECT * FROM ltable; + a | b +-----+---- + AAA | 42 + BBB | 42 +(2 rows) + +SELECT * FROM ftable; + fields +------------------------- + {"a": "AAA", "b": "42"} + {"a": "BBB", "b": "42"} +(2 rows) + +DELETE FROM ftable; +WITH t AS ( + UPDATE ltable SET b = b + 100 RETURNING * +) +INSERT INTO ftable_nsc SELECT * FROM t; +NOTICE: ftable_rowcount_trigger: there are rows in ftable +NOTICE: ftable_rowcount_trigger: there are 1 rows in ftable +SELECT * FROM ltable; + a | b +-----+----- + AAA | 142 + BBB | 142 +(2 rows) + +SELECT * FROM ftable; + fields +-------------------------- + {"a": "AAA", "b": "142"} + {"a": "BBB", "b": "142"} +(2 rows) + +DELETE FROM ftable; +WITH t AS ( + DELETE FROM ltable RETURNING * +) +INSERT INTO ftable_nsc SELECT * FROM t; +NOTICE: ftable_rowcount_trigger: there are rows in ftable +NOTICE: ftable_rowcount_trigger: there are 1 rows in ftable +SELECT * FROM ltable; + a | b +---+--- +(0 rows) + +SELECT * FROM ftable; + fields +-------------------------- + {"a": "AAA", "b": "142"} + {"a": "BBB", "b": "142"} +(2 rows) + +DELETE FROM ftable; +-- Clean up +DROP FOREIGN TABLE ftable_nsc; +DROP FOREIGN TABLE ftable; +DROP TABLE batch_table; +DROP TRIGGER ftable_rowcount_trigger ON ltable; +DROP TABLE ltable; +CREATE TABLE parent (a text, b int) PARTITION BY LIST (a); +CREATE TABLE batch_table (a text, b int); +CREATE FOREIGN TABLE ftable + PARTITION OF parent + FOR VALUES IN ('AAA') + SERVER influxdb_svr + OPTIONS (table 'batch_table', batch_size '2'); +CREATE TABLE ltable + PARTITION OF parent + FOR VALUES IN ('BBB'); +CREATE TRIGGER ftable_rowcount_trigger +BEFORE INSERT ON ltable +FOR EACH ROW EXECUTE PROCEDURE ftable_rowcount_trigf(); +-- Not support partition insert +INSERT INTO parent VALUES ('AAA', 42), ('BBB', 42), ('AAA', 42), ('BBB', 42); +ERROR: Not support partition insert +SELECT tableoid::regclass, * FROM parent; + tableoid | a | b +----------+---+--- +(0 rows) + +-- Clean up +DROP FOREIGN TABLE ftable; +DROP TABLE batch_table; +DROP TRIGGER ftable_rowcount_trigger ON ltable; +DROP TABLE ltable; +DROP TABLE parent; +DROP FUNCTION ftable_rowcount_trigf; +/* InfluxDB does not support partition table +-- =================================================================== +-- test asynchronous execution +-- =================================================================== + +ALTER SERVER loopback OPTIONS (DROP extensions); +ALTER SERVER loopback OPTIONS (ADD async_capable 'true'); +ALTER SERVER loopback2 OPTIONS (ADD async_capable 'true'); + +CREATE TABLE async_pt (a int, b int, c text) PARTITION BY RANGE (a); +CREATE TABLE base_tbl1 (a int, b int, c text); +CREATE TABLE base_tbl2 (a int, b int, c text); +CREATE FOREIGN TABLE async_p1 PARTITION OF async_pt FOR VALUES FROM (1000) TO (2000) + SERVER loopback OPTIONS (table_name 'base_tbl1'); +CREATE FOREIGN TABLE async_p2 PARTITION OF async_pt FOR VALUES FROM (2000) TO (3000) + SERVER loopback2 OPTIONS (table_name 'base_tbl2'); +INSERT INTO async_p1 SELECT 1000 + i, i, to_char(i, 'FM0000') FROM generate_series(0, 999, 5) i; +INSERT INTO async_p2 SELECT 2000 + i, i, to_char(i, 'FM0000') FROM generate_series(0, 999, 5) i; +ANALYZE async_pt; + +-- simple queries +CREATE TABLE result_tbl (a int, b int, c text); + +EXPLAIN (VERBOSE, COSTS OFF) +INSERT INTO result_tbl SELECT * FROM async_pt WHERE b % 100 = 0; +INSERT INTO result_tbl SELECT * FROM async_pt WHERE b % 100 = 0; + +SELECT * FROM result_tbl ORDER BY a; +DELETE FROM result_tbl; + +EXPLAIN (VERBOSE, COSTS OFF) +INSERT INTO result_tbl SELECT * FROM async_pt WHERE b === 505; +INSERT INTO result_tbl SELECT * FROM async_pt WHERE b === 505; + +SELECT * FROM result_tbl ORDER BY a; +DELETE FROM result_tbl; + +EXPLAIN (VERBOSE, COSTS OFF) +INSERT INTO result_tbl SELECT a, b, 'AAA' || c FROM async_pt WHERE b === 505; +INSERT INTO result_tbl SELECT a, b, 'AAA' || c FROM async_pt WHERE b === 505; + +SELECT * FROM result_tbl ORDER BY a; +DELETE FROM result_tbl; + +-- Check case where multiple partitions use the same connection +CREATE TABLE base_tbl3 (a int, b int, c text); +CREATE FOREIGN TABLE async_p3 PARTITION OF async_pt FOR VALUES FROM (3000) TO (4000) + SERVER loopback2 OPTIONS (table_name 'base_tbl3'); +INSERT INTO async_p3 SELECT 3000 + i, i, to_char(i, 'FM0000') FROM generate_series(0, 999, 5) i; +ANALYZE async_pt; + +EXPLAIN (VERBOSE, COSTS OFF) +INSERT INTO result_tbl SELECT * FROM async_pt WHERE b === 505; +INSERT INTO result_tbl SELECT * FROM async_pt WHERE b === 505; + +SELECT * FROM result_tbl ORDER BY a; +DELETE FROM result_tbl; + +DROP FOREIGN TABLE async_p3; +DROP TABLE base_tbl3; + +-- Check case where the partitioned table has local/remote partitions +CREATE TABLE async_p3 PARTITION OF async_pt FOR VALUES FROM (3000) TO (4000); +INSERT INTO async_p3 SELECT 3000 + i, i, to_char(i, 'FM0000') FROM generate_series(0, 999, 5) i; +ANALYZE async_pt; + +EXPLAIN (VERBOSE, COSTS OFF) +INSERT INTO result_tbl SELECT * FROM async_pt WHERE b === 505; +INSERT INTO result_tbl SELECT * FROM async_pt WHERE b === 505; + +SELECT * FROM result_tbl ORDER BY a; +DELETE FROM result_tbl; + +-- partitionwise joins +SET enable_partitionwise_join TO true; + +CREATE TABLE join_tbl (a1 int, b1 int, c1 text, a2 int, b2 int, c2 text); + +EXPLAIN (VERBOSE, COSTS OFF) +INSERT INTO join_tbl SELECT * FROM async_pt t1, async_pt t2 WHERE t1.a = t2.a AND t1.b = t2.b AND t1.b % 100 = 0; +INSERT INTO join_tbl SELECT * FROM async_pt t1, async_pt t2 WHERE t1.a = t2.a AND t1.b = t2.b AND t1.b % 100 = 0; + +SELECT * FROM join_tbl ORDER BY a1; +DELETE FROM join_tbl; + +EXPLAIN (VERBOSE, COSTS OFF) +INSERT INTO join_tbl SELECT t1.a, t1.b, 'AAA' || t1.c, t2.a, t2.b, 'AAA' || t2.c FROM async_pt t1, async_pt t2 WHERE t1.a = t2.a AND t1.b = t2.b AND t1.b % 100 = 0; +INSERT INTO join_tbl SELECT t1.a, t1.b, 'AAA' || t1.c, t2.a, t2.b, 'AAA' || t2.c FROM async_pt t1, async_pt t2 WHERE t1.a = t2.a AND t1.b = t2.b AND t1.b % 100 = 0; + +SELECT * FROM join_tbl ORDER BY a1; +DELETE FROM join_tbl; + +RESET enable_partitionwise_join; + +-- Test rescan of an async Append node with do_exec_prune=false +SET enable_hashjoin TO false; + +EXPLAIN (VERBOSE, COSTS OFF) +INSERT INTO join_tbl SELECT * FROM async_p1 t1, async_pt t2 WHERE t1.a = t2.a AND t1.b = t2.b AND t1.b % 100 = 0; +INSERT INTO join_tbl SELECT * FROM async_p1 t1, async_pt t2 WHERE t1.a = t2.a AND t1.b = t2.b AND t1.b % 100 = 0; + +SELECT * FROM join_tbl ORDER BY a1; +DELETE FROM join_tbl; + +RESET enable_hashjoin; + +-- Test interaction of async execution with plan-time partition pruning +EXPLAIN (VERBOSE, COSTS OFF) +SELECT * FROM async_pt WHERE a < 3000; + +EXPLAIN (VERBOSE, COSTS OFF) +SELECT * FROM async_pt WHERE a < 2000; + +-- Test interaction of async execution with run-time partition pruning +SET plan_cache_mode TO force_generic_plan; + +PREPARE async_pt_query (int, int) AS + INSERT INTO result_tbl SELECT * FROM async_pt WHERE a < $1 AND b === $2; + +EXPLAIN (VERBOSE, COSTS OFF) +EXECUTE async_pt_query (3000, 505); +EXECUTE async_pt_query (3000, 505); + +SELECT * FROM result_tbl ORDER BY a; +DELETE FROM result_tbl; + +EXPLAIN (VERBOSE, COSTS OFF) +EXECUTE async_pt_query (2000, 505); +EXECUTE async_pt_query (2000, 505); + +SELECT * FROM result_tbl ORDER BY a; +DELETE FROM result_tbl; + +RESET plan_cache_mode; + +CREATE TABLE local_tbl(a int, b int, c text); +INSERT INTO local_tbl VALUES (1505, 505, 'foo'), (2505, 505, 'bar'); +ANALYZE local_tbl; + +CREATE INDEX base_tbl1_idx ON base_tbl1 (a); +CREATE INDEX base_tbl2_idx ON base_tbl2 (a); +CREATE INDEX async_p3_idx ON async_p3 (a); +ANALYZE base_tbl1; +ANALYZE base_tbl2; +ANALYZE async_p3; + +ALTER FOREIGN TABLE async_p1 OPTIONS (use_remote_estimate 'true'); +ALTER FOREIGN TABLE async_p2 OPTIONS (use_remote_estimate 'true'); + +EXPLAIN (VERBOSE, COSTS OFF) +SELECT * FROM local_tbl, async_pt WHERE local_tbl.a = async_pt.a AND local_tbl.c = 'bar'; +EXPLAIN (ANALYZE, COSTS OFF, SUMMARY OFF, TIMING OFF) +SELECT * FROM local_tbl, async_pt WHERE local_tbl.a = async_pt.a AND local_tbl.c = 'bar'; +SELECT * FROM local_tbl, async_pt WHERE local_tbl.a = async_pt.a AND local_tbl.c = 'bar'; + +ALTER FOREIGN TABLE async_p1 OPTIONS (DROP use_remote_estimate); +ALTER FOREIGN TABLE async_p2 OPTIONS (DROP use_remote_estimate); + +DROP TABLE local_tbl; +DROP INDEX base_tbl1_idx; +DROP INDEX base_tbl2_idx; +DROP INDEX async_p3_idx; + +-- UNION queries +EXPLAIN (VERBOSE, COSTS OFF) +INSERT INTO result_tbl +(SELECT a, b, 'AAA' || c FROM async_p1 ORDER BY a LIMIT 10) +UNION +(SELECT a, b, 'AAA' || c FROM async_p2 WHERE b < 10); +INSERT INTO result_tbl +(SELECT a, b, 'AAA' || c FROM async_p1 ORDER BY a LIMIT 10) +UNION +(SELECT a, b, 'AAA' || c FROM async_p2 WHERE b < 10); + +SELECT * FROM result_tbl ORDER BY a; +DELETE FROM result_tbl; + +EXPLAIN (VERBOSE, COSTS OFF) +INSERT INTO result_tbl +(SELECT a, b, 'AAA' || c FROM async_p1 ORDER BY a LIMIT 10) +UNION ALL +(SELECT a, b, 'AAA' || c FROM async_p2 WHERE b < 10); +INSERT INTO result_tbl +(SELECT a, b, 'AAA' || c FROM async_p1 ORDER BY a LIMIT 10) +UNION ALL +(SELECT a, b, 'AAA' || c FROM async_p2 WHERE b < 10); + +SELECT * FROM result_tbl ORDER BY a; +DELETE FROM result_tbl; + +-- Disable async execution if we use gating Result nodes for pseudoconstant +-- quals +EXPLAIN (VERBOSE, COSTS OFF) +SELECT * FROM async_pt WHERE CURRENT_USER = SESSION_USER; + +EXPLAIN (VERBOSE, COSTS OFF) +(SELECT * FROM async_p1 WHERE CURRENT_USER = SESSION_USER) +UNION ALL +(SELECT * FROM async_p2 WHERE CURRENT_USER = SESSION_USER); + +EXPLAIN (VERBOSE, COSTS OFF) +SELECT * FROM ((SELECT * FROM async_p1 WHERE b < 10) UNION ALL (SELECT * FROM async_p2 WHERE b < 10)) s WHERE CURRENT_USER = SESSION_USER; + +-- Test that pending requests are processed properly +SET enable_mergejoin TO false; +SET enable_hashjoin TO false; + +EXPLAIN (VERBOSE, COSTS OFF) +SELECT * FROM async_pt t1, async_p2 t2 WHERE t1.a = t2.a AND t1.b === 505; +SELECT * FROM async_pt t1, async_p2 t2 WHERE t1.a = t2.a AND t1.b === 505; + +CREATE TABLE local_tbl (a int, b int, c text); +INSERT INTO local_tbl VALUES (1505, 505, 'foo'); +ANALYZE local_tbl; + +EXPLAIN (VERBOSE, COSTS OFF) +SELECT * FROM local_tbl t1 LEFT JOIN (SELECT *, (SELECT count(*) FROM async_pt WHERE a < 3000) FROM async_pt WHERE a < 3000) t2 ON t1.a = t2.a; +EXPLAIN (ANALYZE, COSTS OFF, SUMMARY OFF, TIMING OFF) +SELECT * FROM local_tbl t1 LEFT JOIN (SELECT *, (SELECT count(*) FROM async_pt WHERE a < 3000) FROM async_pt WHERE a < 3000) t2 ON t1.a = t2.a; +SELECT * FROM local_tbl t1 LEFT JOIN (SELECT *, (SELECT count(*) FROM async_pt WHERE a < 3000) FROM async_pt WHERE a < 3000) t2 ON t1.a = t2.a; + +EXPLAIN (VERBOSE, COSTS OFF) +SELECT * FROM async_pt t1 WHERE t1.b === 505 LIMIT 1; +EXPLAIN (ANALYZE, COSTS OFF, SUMMARY OFF, TIMING OFF) +SELECT * FROM async_pt t1 WHERE t1.b === 505 LIMIT 1; +SELECT * FROM async_pt t1 WHERE t1.b === 505 LIMIT 1; + +-- Check with foreign modify +CREATE TABLE base_tbl3 (a int, b int, c text); +CREATE FOREIGN TABLE remote_tbl (a int, b int, c text) + SERVER loopback OPTIONS (table_name 'base_tbl3'); +INSERT INTO remote_tbl VALUES (2505, 505, 'bar'); + +CREATE TABLE base_tbl4 (a int, b int, c text); +CREATE FOREIGN TABLE insert_tbl (a int, b int, c text) + SERVER loopback OPTIONS (table_name 'base_tbl4'); + +EXPLAIN (VERBOSE, COSTS OFF) +INSERT INTO insert_tbl (SELECT * FROM local_tbl UNION ALL SELECT * FROM remote_tbl); +INSERT INTO insert_tbl (SELECT * FROM local_tbl UNION ALL SELECT * FROM remote_tbl); + +SELECT * FROM insert_tbl ORDER BY a; + +-- Check with direct modify +EXPLAIN (VERBOSE, COSTS OFF) +WITH t AS (UPDATE remote_tbl SET c = c || c RETURNING *) +INSERT INTO join_tbl SELECT * FROM async_pt LEFT JOIN t ON (async_pt.a = t.a AND async_pt.b = t.b) WHERE async_pt.b === 505; +WITH t AS (UPDATE remote_tbl SET c = c || c RETURNING *) +INSERT INTO join_tbl SELECT * FROM async_pt LEFT JOIN t ON (async_pt.a = t.a AND async_pt.b = t.b) WHERE async_pt.b === 505; + +SELECT * FROM join_tbl ORDER BY a1; +DELETE FROM join_tbl; + +DROP TABLE local_tbl; +DROP FOREIGN TABLE remote_tbl; +DROP FOREIGN TABLE insert_tbl; +DROP TABLE base_tbl3; +DROP TABLE base_tbl4; + +RESET enable_mergejoin; +RESET enable_hashjoin; + +-- Test that UPDATE/DELETE with inherited target works with async_capable enabled +EXPLAIN (VERBOSE, COSTS OFF) +UPDATE async_pt SET c = c || c WHERE b = 0 RETURNING *; +UPDATE async_pt SET c = c || c WHERE b = 0 RETURNING *; +EXPLAIN (VERBOSE, COSTS OFF) +DELETE FROM async_pt WHERE b = 0 RETURNING *; +DELETE FROM async_pt WHERE b = 0 RETURNING *; + +-- Check EXPLAIN ANALYZE for a query that scans empty partitions asynchronously +DELETE FROM async_p1; +DELETE FROM async_p2; +DELETE FROM async_p3; + +EXPLAIN (ANALYZE, COSTS OFF, SUMMARY OFF, TIMING OFF) +SELECT * FROM async_pt; + +-- Clean up +DROP TABLE async_pt; +DROP TABLE base_tbl1; +DROP TABLE base_tbl2; +DROP TABLE result_tbl; +DROP TABLE join_tbl; + +-- Test that an asynchronous fetch is processed before restarting the scan in +-- ReScanForeignScan +CREATE TABLE base_tbl (a int, b int); +INSERT INTO base_tbl VALUES (1, 11), (2, 22), (3, 33); +CREATE FOREIGN TABLE foreign_tbl (b int) + SERVER loopback OPTIONS (table_name 'base_tbl'); +CREATE FOREIGN TABLE foreign_tbl2 () INHERITS (foreign_tbl) + SERVER loopback OPTIONS (table_name 'base_tbl'); + +EXPLAIN (VERBOSE, COSTS OFF) +SELECT a FROM base_tbl WHERE a IN (SELECT a FROM foreign_tbl); +SELECT a FROM base_tbl WHERE a IN (SELECT a FROM foreign_tbl); + +-- Clean up +DROP FOREIGN TABLE foreign_tbl CASCADE; +DROP TABLE base_tbl; + +ALTER SERVER loopback OPTIONS (DROP async_capable); +ALTER SERVER loopback2 OPTIONS (DROP async_capable); +*/ +-- =================================================================== +-- test invalid server, foreign table and foreign data wrapper options +-- =================================================================== +/* +-- InfluxDB FDW does not have these options +-- Invalid fdw_startup_cost option +CREATE SERVER inv_scst FOREIGN DATA WRAPPER postgres_fdw + OPTIONS(fdw_startup_cost '100$%$#$#'); +-- Invalid fdw_tuple_cost option +CREATE SERVER inv_scst FOREIGN DATA WRAPPER postgres_fdw + OPTIONS(fdw_tuple_cost '100$%$#$#'); +-- Invalid fetch_size option +CREATE FOREIGN TABLE inv_fsz (c1 int ) + SERVER loopback OPTIONS (fetch_size '100$%$#$#'); +*/ +-- Invalid batch_size option +--Testcase 776: +CREATE FOREIGN TABLE inv_bsz (fields jsonb OPTIONS(fields 'true')) + SERVER influxdb_svr OPTIONS (batch_size '100$%$#$#', schemaless 'true'); +ERROR: invalid value for integer option "batch_size": 100$%$#$# +-- No option is allowed to be specified at foreign data wrapper level +--Testcase 782: +ALTER FOREIGN DATA WRAPPER influxdb_fdw OPTIONS (nonexistent 'fdw'); +ERROR: invalid option "nonexistent" +HINT: There are no valid options in this context. +/* +-- =================================================================== +-- application_name is an option in libpq of postgres +-- so Influxdb_fdw not support application_name. +-- test postgres_fdw.application_name GUC +-- =================================================================== +-- To avoid race conditions in checking the remote session's application_name, +-- use this view to make the remote session itself read its application_name. +CREATE VIEW my_application_name AS + SELECT application_name FROM pg_stat_activity WHERE pid = pg_backend_pid(); + +CREATE FOREIGN TABLE remote_application_name (application_name text) + SERVER loopback2 + OPTIONS (schema_name 'public', table_name 'my_application_name'); + +SELECT count(*) FROM remote_application_name; + +-- Specify escape sequences in application_name option of a server +-- object so as to test that they are replaced with status information +-- expectedly. Note that we are also relying on ALTER SERVER to force +-- the remote session to be restarted with its new application name. +-- +-- Since pg_stat_activity.application_name may be truncated to less than +-- NAMEDATALEN characters, note that substring() needs to be used +-- at the condition of test query to make sure that the string consisting +-- of database name and process ID is also less than that. +ALTER SERVER loopback2 OPTIONS (application_name 'fdw_%d%p'); +SELECT count(*) FROM remote_application_name + WHERE application_name = + substring('fdw_' || current_database() || pg_backend_pid() for + current_setting('max_identifier_length')::int); + +-- postgres_fdw.application_name overrides application_name option +-- of a server object if both settings are present. +ALTER SERVER loopback2 OPTIONS (SET application_name 'fdw_wrong'); +SET postgres_fdw.application_name TO 'fdw_%a%u%%'; +SELECT count(*) FROM remote_application_name + WHERE application_name = + substring('fdw_' || current_setting('application_name') || + CURRENT_USER || '%' for current_setting('max_identifier_length')::int); +RESET postgres_fdw.application_name; + +-- Test %c (session ID) and %C (cluster name) escape sequences. +ALTER SERVER loopback2 OPTIONS (SET application_name 'fdw_%C%c'); +SELECT count(*) FROM remote_application_name + WHERE application_name = + substring('fdw_' || current_setting('cluster_name') || + to_hex(trunc(EXTRACT(EPOCH FROM (SELECT backend_start FROM + pg_stat_get_activity(pg_backend_pid()))))::integer) || '.' || + to_hex(pg_backend_pid()) + for current_setting('max_identifier_length')::int); + +-- Clean up. +DROP FOREIGN TABLE remote_application_name; +DROP VIEW my_application_name; + +-- =================================================================== +-- test parallel commit and parallel abort +-- =================================================================== +ALTER SERVER loopback OPTIONS (ADD parallel_commit 'true'); +ALTER SERVER loopback OPTIONS (ADD parallel_abort 'true'); +ALTER SERVER loopback2 OPTIONS (ADD parallel_commit 'true'); +ALTER SERVER loopback2 OPTIONS (ADD parallel_abort 'true') + +CREATE TABLE ploc1 (f1 int, f2 text); +CREATE FOREIGN TABLE prem1 (f1 int, f2 text) + SERVER loopback OPTIONS (table_name 'ploc1'); +CREATE TABLE ploc2 (f1 int, f2 text); +CREATE FOREIGN TABLE prem2 (f1 int, f2 text) + SERVER loopback2 OPTIONS (table_name 'ploc2'); + +BEGIN; +INSERT INTO prem1 VALUES (101, 'foo'); +INSERT INTO prem2 VALUES (201, 'bar'); +COMMIT; +SELECT * FROM prem1; +SELECT * FROM prem2; + +BEGIN; +SAVEPOINT s; +INSERT INTO prem1 VALUES (102, 'foofoo'); +INSERT INTO prem2 VALUES (202, 'barbar'); +RELEASE SAVEPOINT s; +COMMIT; +SELECT * FROM prem1; +SELECT * FROM prem2; + +-- This tests executing DEALLOCATE ALL against foreign servers in parallel +-- during pre-commit +BEGIN; +SAVEPOINT s; +INSERT INTO prem1 VALUES (103, 'baz'); +INSERT INTO prem2 VALUES (203, 'qux'); +ROLLBACK TO SAVEPOINT s; +RELEASE SAVEPOINT s; +INSERT INTO prem1 VALUES (104, 'bazbaz'); +INSERT INTO prem2 VALUES (204, 'quxqux'); +COMMIT; +SELECT * FROM prem1; +SELECT * FROM prem2; + +BEGIN; +INSERT INTO prem1 VALUES (105, 'test1'); +INSERT INTO prem2 VALUES (205, 'test2'); +ABORT; +SELECT * FROM prem1; +SELECT * FROM prem2; + +-- This tests executing DEALLOCATE ALL against foreign servers in parallel +-- during post-abort +BEGIN; +SAVEPOINT s; +INSERT INTO prem1 VALUES (105, 'test1'); +INSERT INTO prem2 VALUES (205, 'test2'); +ROLLBACK TO SAVEPOINT s; +RELEASE SAVEPOINT s; +INSERT INTO prem1 VALUES (105, 'test1'); +INSERT INTO prem2 VALUES (205, 'test2'); +ABORT; +SELECT * FROM prem1; +SELECT * FROM prem2; + +ALTER SERVER loopback OPTIONS (DROP parallel_commit); +ALTER SERVER loopback OPTIONS (DROP parallel_abort); +ALTER SERVER loopback2 OPTIONS (DROP parallel_commit); +ALTER SERVER loopback2 OPTIONS (DROP parallel_abort); + +-- =================================================================== +-- test for ANALYZE sampling +-- =================================================================== + +CREATE TABLE analyze_table (id int, a text, b bigint); + +CREATE FOREIGN TABLE analyze_ftable (id int, a text, b bigint) + SERVER loopback OPTIONS (table_name 'analyze_rtable1'); + +INSERT INTO analyze_table (SELECT x FROM generate_series(1,1000) x); +ANALYZE analyze_table; + +SET default_statistics_target = 10; +ANALYZE analyze_table; + +ALTER SERVER loopback OPTIONS (analyze_sampling 'invalid'); + +ALTER SERVER loopback OPTIONS (analyze_sampling 'auto'); +ANALYZE analyze_table; + +ALTER SERVER loopback OPTIONS (SET analyze_sampling 'system'); +ANALYZE analyze_table; + +ALTER SERVER loopback OPTIONS (SET analyze_sampling 'bernoulli'); +ANALYZE analyze_table; + +ALTER SERVER loopback OPTIONS (SET analyze_sampling 'random'); +ANALYZE analyze_table; + +ALTER SERVER loopback OPTIONS (SET analyze_sampling 'off'); +ANALYZE analyze_table; + +-- cleanup +DROP FOREIGN TABLE analyze_ftable; +DROP TABLE analyze_table; +*/ +-- Clean-up +--Testcase 822: +DELETE FROM ft1_nsc; +--Testcase 823: +DELETE FROM ft2_nsc; +--Testcase 824: +DELETE FROM ft4_nsc; +--Testcase 825: +DELETE FROM ft5_nsc; +--Testcase 826: +DELETE FROM foo_nsc; +--Testcase 827: +DELETE FROM bar_nsc; +--Testcase 828: +DELETE FROM loct1_nsc; +--Testcase 829: +DELETE FROM loct2_nsc; +--Testcase 830: +DELETE FROM rem1_nsc; +--Testcase 831: +DROP FOREIGN TABLE foo_nsc cascade; +NOTICE: drop cascades to foreign table foo2_nsc +--Testcase 832: +DROP FOREIGN TABLE bar_nsc cascade; +NOTICE: drop cascades to foreign table bar2_nsc +--Testcase 833: +DROP FOREIGN TABLE loct1_nsc; +--Testcase 834: +DROP FOREIGN TABLE loct2_nsc; +--Testcase 835: +DROP FOREIGN TABLE "S 1".s1t0; +--Testcase 836: +DROP FOREIGN TABLE "S 1".s1t1; +--Testcase 837: +DROP FOREIGN TABLE "S 1".s1t2; +--Testcase 838: +DROP FOREIGN TABLE "S 1".s1t3; +--Testcase 839: +DROP FOREIGN TABLE "S 1".s1t4; +--Testcase 840: +DROP FOREIGN TABLE ft1_nsc; +--Testcase 841: +DROP FOREIGN TABLE ft2_nsc; +--Testcase 842: +DROP FOREIGN TABLE ft4_nsc; +--Testcase 843: +DROP FOREIGN TABLE ft5_nsc; +--Testcase 844: +DROP TYPE IF EXISTS user_enum; +--Testcase 845: +DROP SCHEMA IF EXISTS "S 1" CASCADE; +NOTICE: drop cascades to 6 other objects +DETAIL: drop cascades to foreign table "S 1"."T 0" +drop cascades to foreign table "S 1"."T 1" +drop cascades to foreign table "S 1"."T 2" +drop cascades to foreign table "S 1"."T 3" +drop cascades to foreign table "S 1"."T 4" +drop cascades to function "S 1".f_brtrig() +--Testcase 846: +DROP FUNCTION IF EXISTS trigger_func(); +--Testcase 847: +DROP FUNCTION IF EXISTS trig_row_before_insupdate(); +--Testcase 848: +DROP FUNCTION IF EXISTS trig_null(); +--Testcase 849: +DROP SCHEMA IF EXISTS import_influx1 CASCADE; +NOTICE: drop cascades to 9 other objects +DETAIL: drop cascades to foreign table import_influx1."T1" +drop cascades to foreign table import_influx1."T2" +drop cascades to foreign table import_influx1."T3" +drop cascades to foreign table import_influx1."T4" +drop cascades to foreign table import_influx1.bar +drop cascades to foreign table import_influx1.foo +drop cascades to foreign table import_influx1.loc1 +drop cascades to foreign table import_influx1.loct1 +drop cascades to foreign table import_influx1.loct2 +--Testcase 850: +DROP SCHEMA IF EXISTS import_influx2 CASCADE; +--Testcase 851: +DROP SCHEMA IF EXISTS import_influx3 CASCADE; +--Testcase 852: +DROP SCHEMA IF EXISTS import_influx4 CASCADE; +NOTICE: drop cascades to 9 other objects +DETAIL: drop cascades to foreign table import_influx4."T1" +drop cascades to foreign table import_influx4."T2" +drop cascades to foreign table import_influx4."T3" +drop cascades to foreign table import_influx4."T4" +drop cascades to foreign table import_influx4.bar +drop cascades to foreign table import_influx4.foo +drop cascades to foreign table import_influx4.loc1 +drop cascades to foreign table import_influx4.loct1 +drop cascades to foreign table import_influx4.loct2 +--Testcase 758: +DROP USER MAPPING FOR public SERVER testserver1; +--Testcase 759: +DROP USER MAPPING FOR CURRENT_USER SERVER influxdb_svr; +--Testcase 760: +DROP USER MAPPING FOR CURRENT_USER SERVER influxdb_svr2; +--Testcase 761: +DROP SERVER testserver1 CASCADE; +--Testcase 762: +DROP SERVER influxdb_svr CASCADE; +NOTICE: drop cascades to 22 other objects +DETAIL: drop cascades to foreign table ft1 +drop cascades to foreign table ft2 +drop cascades to foreign table ft4 +drop cascades to foreign table ft5 +drop cascades to foreign table loct_empty +drop cascades to foreign table ft_empty +drop cascades to foreign table loct3 +drop cascades to foreign table ft3 +drop cascades to foreign table loc1 +drop cascades to foreign table loc1_nsc +drop cascades to foreign table rem1 +drop cascades to foreign table rem1_nsc +drop cascades to foreign table gloc1 +drop cascades to foreign table gloc1_nsc +drop cascades to foreign table grem1 +drop cascades to foreign table grem1_nsc +drop cascades to foreign table loct1 +drop cascades to foreign table loct2 +drop cascades to foreign table foo +drop cascades to foreign table foo2 +drop cascades to foreign table bar +drop cascades to foreign table bar2 +--Testcase 763: +DROP SERVER influxdb_svr2 CASCADE; +NOTICE: drop cascades to foreign table ft6 +--Testcase 764: +DROP EXTENSION influxdb_fdw; diff --git a/expected/14.5/schemaless/extra/insert.out b/expected/16.0/schemaless/extra/insert.out similarity index 99% rename from expected/14.5/schemaless/extra/insert.out rename to expected/16.0/schemaless/extra/insert.out index 4465358..26fa3bb 100644 --- a/expected/14.5/schemaless/extra/insert.out +++ b/expected/16.0/schemaless/extra/insert.out @@ -11,6 +11,7 @@ CREATE USER MAPPING FOR CURRENT_USER SERVER influxdb_svr OPTIONS (:AUTHENTICATIO -- --Testcase 4: CREATE FOREIGN TABLE inserttest (fields jsonb OPTIONS (fields 'true')) SERVER influxdb_svr OPTIONS (schemaless 'true'); +--Testcase 24: CREATE FOREIGN TABLE inserttest_nsc (col1 int4, col2 int4 NOT NULL, col3 text default 'testing') SERVER influxdb_svr OPTIONS(table 'inserttest'); --Testcase 5: insert into inserttest_nsc (col1, col2, col3) values (DEFAULT, DEFAULT, DEFAULT); @@ -106,8 +107,11 @@ select (fields->>'col1')::int4 col1, (fields->>'col2')::int4 col2, char_length(f --Testcase 20: -- Clean up: +--Testcase 25: delete from inserttest_nsc; +--Testcase 26: drop foreign table inserttest; +--Testcase 27: drop foreign table inserttest_nsc; /* -- skip, influxdb does not support create table with WITH option diff --git a/expected/11.17/schemaless/extra/join.out b/expected/16.0/schemaless/extra/join.out similarity index 76% rename from expected/11.17/schemaless/extra/join.out rename to expected/16.0/schemaless/extra/join.out index 27d655b..f9ad797 100644 --- a/expected/11.17/schemaless/extra/join.out +++ b/expected/16.0/schemaless/extra/join.out @@ -16,6 +16,7 @@ CREATE USER MAPPING FOR CURRENT_USER SERVER influxdb_svr OPTIONS (:AUTHENTICATIO CREATE FOREIGN TABLE J1_TBL ( fields jsonb OPTIONS (fields 'true') ) SERVER influxdb_svr OPTIONS(schemaless 'true'); +--Testcase 575: CREATE FOREIGN TABLE j1_tbl_nsc ( i integer, j integer, @@ -25,6 +26,7 @@ CREATE FOREIGN TABLE j1_tbl_nsc ( CREATE FOREIGN TABLE J2_TBL ( fields jsonb OPTIONS (fields 'true') ) SERVER influxdb_svr OPTIONS(schemaless 'true'); +--Testcase 576: CREATE FOREIGN TABLE j2_tbl_nsc ( i integer, k integer @@ -69,6 +71,10 @@ INSERT INTO j2_tbl_nsc VALUES (0, NULL); --INSERT INTO J2_TBL VALUES (NULL, NULL); --Testcase 24: INSERT INTO j2_tbl_nsc VALUES (NULL, 0); +--Testcase 560: +CREATE FOREIGN TABLE onek ( + fields jsonb OPTIONS (fields 'true') +) SERVER influxdb_svr OPTIONS(schemaless 'true'); --Testcase 25: CREATE FOREIGN TABLE tenk1 ( fields jsonb OPTIONS (fields 'true') @@ -1455,11 +1461,73 @@ SELECT * 4 | 1 | one | 2 (4 rows) +-- test join using aliases +--Testcase 49: +SELECT * FROM (SELECT (fields->>'i')::int i, (fields->>'j')::int j, fields->>'t' t FROM J1_TBL) J1_TBL JOIN (SELECT (fields->>'i')::int i, (fields->>'k')::int k FROM J2_TBL) J2_TBL USING (i) WHERE J1_TBL.t = 'one'; -- ok + i | j | t | k +---+---+-----+---- + 1 | 4 | one | -1 +(1 row) + +--Testcase 50: +SELECT * FROM (SELECT (fields->>'i')::int i, (fields->>'j')::int j, fields->>'t' t FROM J1_TBL) J1_TBL JOIN (SELECT (fields->>'i')::int i, (fields->>'k')::int k FROM J2_TBL) J2_TBL USING (i) AS x WHERE J1_TBL.t = 'one'; -- ok + i | j | t | k +---+---+-----+---- + 1 | 4 | one | -1 +(1 row) + +--Testcase 51: +SELECT * FROM ((SELECT (fields->>'i')::int i, (fields->>'j')::int j, fields->>'t' t FROM J1_TBL) J1_TBL JOIN (SELECT (fields->>'i')::int i, (fields->>'k')::int k FROM J2_TBL) J2_TBL USING (i)) AS x WHERE J1_TBL.t = 'one'; -- error +ERROR: invalid reference to FROM-clause entry for table "j1_tbl" +LINE 1: ...::int k FROM J2_TBL) J2_TBL USING (i)) AS x WHERE J1_TBL.t =... + ^ +DETAIL: There is an entry for table "j1_tbl", but it cannot be referenced from this part of the query. +--Testcase 52: +SELECT * FROM (SELECT (fields->>'i')::int i, (fields->>'j')::int j, fields->>'t' t FROM J1_TBL) J1_TBL JOIN (SELECT (fields->>'i')::int i, (fields->>'k')::int k FROM J2_TBL) J2_TBL USING (i) AS x WHERE x.i::int = 1; -- ok + i | j | t | k +---+---+-----+---- + 1 | 4 | one | -1 +(1 row) + +--Testcase 53: +SELECT * FROM (SELECT (fields->>'i')::int i, (fields->>'j')::int j, fields->>'t' t FROM J1_TBL) J1_TBL JOIN (SELECT (fields->>'i')::int i, (fields->>'k')::int k FROM J2_TBL) J2_TBL USING (i) AS x WHERE x.t = 'one'; -- error +ERROR: column x.t does not exist +LINE 1: ...)::int k FROM J2_TBL) J2_TBL USING (i) AS x WHERE x.t = 'one... + ^ +--Testcase 54: +SELECT * FROM ((SELECT (fields->>'i')::int i, (fields->>'j')::int j, fields->>'t' t FROM J1_TBL) J1_TBL JOIN (SELECT (fields->>'i')::int i, (fields->>'k')::int k FROM J2_TBL) J2_TBL USING (i) AS x) AS xx WHERE x.i::int = 1; -- error (XXX could use better hint) +ERROR: missing FROM-clause entry for table "x" +LINE 1: ...k FROM J2_TBL) J2_TBL USING (i) AS x) AS xx WHERE x.i::int =... + ^ +--Testcase 55: +SELECT * FROM (SELECT (fields->>'i')::int i,(fields->>'j')::int j,fields->>'t' t FROM J1_TBL) a1 JOIN (SELECT (fields->>'i')::int i,(fields->>'k')::int k FROM J2_TBL) a2 USING (i) AS a1; -- error +ERROR: table name "a1" specified more than once +--Testcase 56: +SELECT x.* FROM (SELECT (fields->>'i')::int i, (fields->>'j')::int j, fields->>'t' t FROM J1_TBL) J1_TBL JOIN (SELECT (fields->>'i')::int i, (fields->>'k')::int k FROM J2_TBL) J2_TBL USING (i) AS x WHERE J1_TBL.t = 'one'; + i +--- + 1 +(1 row) + +--Testcase 57: +SELECT ROW(x.*) FROM (SELECT (fields->>'i')::int i, (fields->>'j')::int j, fields->>'t' t FROM J1_TBL) J1_TBL JOIN (SELECT (fields->>'i')::int i, (fields->>'k')::int k FROM J2_TBL) J2_TBL USING (i) AS x WHERE J1_TBL.t = 'one'; + row +----- + (1) +(1 row) + +--Testcase 58: +SELECT row_to_json(x.*) FROM (SELECT (fields->>'i')::int i, (fields->>'j')::int j, fields->>'t' t FROM J1_TBL) J1_TBL JOIN (SELECT (fields->>'i')::int i, (fields->>'k')::int k FROM J2_TBL) J2_TBL USING (i) AS x WHERE J1_TBL.t = 'one'; + row_to_json +------------- + {"i":1} +(1 row) + -- -- NATURAL JOIN -- Inner equi-join on all columns with the same name -- ---Testcase 49: +--Testcase 59: SELECT * FROM (SELECT (fields->>'i')::int i,(fields->>'j')::int j,fields->>'t' t FROM J1_TBL) J1_TBL NATURAL JOIN (SELECT (fields->>'i')::int i,(fields->>'k')::int k FROM J2_TBL) J2_TBL; i | j | t | k @@ -1473,7 +1541,7 @@ SELECT * 5 | 0 | five | -5 (7 rows) ---Testcase 50: +--Testcase 60: SELECT * FROM (SELECT (fields->>'i')::int i, (fields->>'j')::int j, fields->>'t' t FROM J1_TBL) t1 (a, b, c) NATURAL JOIN (SELECT (fields->>'i')::int i, (fields->>'k')::int k FROM J2_TBL) t2 (a, d); a | b | c | d @@ -1487,7 +1555,7 @@ SELECT * 5 | 0 | five | -5 (7 rows) ---Testcase 51: +--Testcase 61: SELECT * FROM (SELECT (fields->>'i')::int i, (fields->>'j')::int j, fields->>'t' t FROM J1_TBL) t1 (a, b, c) NATURAL JOIN (SELECT (fields->>'i')::int i, (fields->>'k')::int k FROM J2_TBL) t2 (d, a); a | b | c | d @@ -1499,7 +1567,7 @@ SELECT * -- mismatch number of columns -- currently, Postgres will fill in with underlying names ---Testcase 52: +--Testcase 62: SELECT * FROM (SELECT (fields->>'i')::int i,(fields->>'j')::int j,fields->>'t' t FROM J1_TBL) t1 (a, b) NATURAL JOIN (SELECT (fields->>'i')::int i,(fields->>'k')::int k FROM J2_TBL) t2 (a); a | b | t | k @@ -1516,7 +1584,7 @@ SELECT * -- -- Inner joins (equi-joins) -- ---Testcase 53: +--Testcase 63: SELECT * FROM (SELECT (fields->>'i')::int i,(fields->>'j')::int j,fields->>'t' t FROM J1_TBL) J1_TBL JOIN (select (fields->>'i')::int i, (fields->>'k')::int k from J2_TBL) J2_TBL ON ((J1_TBL.i)::bigint = (J2_TBL.i)::bigint); i | j | t | i | k @@ -1530,7 +1598,7 @@ SELECT * 5 | 0 | five | 5 | -5 (7 rows) ---Testcase 54: +--Testcase 64: SELECT * FROM (SELECT (fields->>'i')::int i,(fields->>'j')::int j,fields->>'t' t FROM J1_TBL) J1_TBL JOIN (select (fields->>'i')::int i, (fields->>'k')::int k from J2_TBL) J2_TBL ON ((J1_TBL.i)::bigint = (J2_TBL.k)::bigint); i | j | t | i | k @@ -1543,7 +1611,7 @@ SELECT * -- -- Non-equi-joins -- ---Testcase 55: +--Testcase 65: SELECT * FROM (select (fields->>'i')::int i, (fields->>'j')::int j,fields->>'t' t from J1_TBL) J1_TBL JOIN (select (fields->>'i')::int i, (fields->>'k')::int k from J2_TBL) J2_TBL ON ((J1_TBL.i)::bigint <= (J2_TBL.k)::bigint) ORDER BY J1_TBL.i, J1_TBL.j, J1_TBL.t, J2_TBL.i, J2_TBL.k; i | j | t | i | k @@ -1563,7 +1631,7 @@ SELECT * -- Outer joins -- Note that OUTER is a noise word -- ---Testcase 56: +--Testcase 66: SELECT * FROM (SELECT (fields->>'i')::int i, (fields->>'j')::int j ,fields->>'t' t FROM J1_TBL) J1_TBL LEFT OUTER JOIN (SELECT (fields->>'i')::int i,(fields->>'k')::int k FROM J2_TBL) J2_TBL USING (i) ORDER BY i, k, t; @@ -1584,7 +1652,7 @@ SELECT * | 0 | zero | (13 rows) ---Testcase 57: +--Testcase 67: SELECT * FROM (SELECT (fields->>'i')::int i,(fields->>'j')::int j,fields->>'t' t FROM J1_TBL) J1_TBL LEFT JOIN (SELECT (fields->>'i')::int i,(fields->>'k')::int k FROM J2_TBL) J2_TBL USING (i) ORDER BY i::int, k, t; @@ -1605,7 +1673,7 @@ SELECT * | 0 | zero | (13 rows) ---Testcase 58: +--Testcase 68: SELECT * FROM (SELECT (fields->>'i')::int i,(fields->>'j')::int j,fields->>'t' t FROM J1_TBL) J1_TBL RIGHT OUTER JOIN (SELECT (fields->>'i')::int i,(fields->>'k')::int k FROM J2_TBL) J2_TBL USING (i); i | j | t | k @@ -1620,7 +1688,7 @@ SELECT * | | | 0 (8 rows) ---Testcase 59: +--Testcase 69: SELECT * FROM (SELECT (fields->>'i')::int i,(fields->>'j')::int j,fields->>'t' t FROM J1_TBL) J1_TBL RIGHT JOIN (SELECT (fields->>'i')::int i,(fields->>'k')::int k FROM J2_TBL) J2_TBL USING (i); i | j | t | k @@ -1635,7 +1703,7 @@ SELECT * | | | 0 (8 rows) ---Testcase 60: +--Testcase 70: SELECT * FROM (SELECT (fields->>'i')::int i,(fields->>'j')::int j,fields->>'t' t FROM J1_TBL) J1_TBL FULL OUTER JOIN (SELECT (fields->>'i')::int i,(fields->>'k')::int k FROM J2_TBL) J2_TBL USING (i) ORDER BY i::int, k, t; @@ -1657,7 +1725,7 @@ SELECT * | 0 | zero | (14 rows) ---Testcase 61: +--Testcase 71: SELECT * FROM (SELECT (fields->>'i')::int i,(fields->>'j')::int j,fields->>'t' t FROM J1_TBL) J1_TBL FULL JOIN (SELECT (fields->>'i')::int i,(fields->>'k')::int k FROM J2_TBL) J2_TBL USING (i) ORDER BY i::int, k, t; @@ -1679,14 +1747,14 @@ SELECT * | 0 | zero | (14 rows) ---Testcase 62: +--Testcase 72: SELECT * FROM (SELECT (fields->>'i')::int i,(fields->>'j')::int j,fields->>'t' t FROM J1_TBL) J1_TBL LEFT JOIN (SELECT (fields->>'i')::int i,(fields->>'k')::int k FROM J2_TBL) J2_TBL USING (i) WHERE (k)::int = 1; i | j | t | k ---+---+---+--- (0 rows) ---Testcase 63: +--Testcase 73: SELECT * FROM (SELECT (fields->>'i')::int i,(fields->>'j')::int j,fields->>'t' t FROM J1_TBL) J1_TBL LEFT JOIN (SELECT (fields->>'i')::int i,(fields->>'k')::int k FROM J2_TBL) J2_TBL USING (i) WHERE (i)::int = 1; i | j | t | k @@ -1697,7 +1765,7 @@ SELECT * -- -- semijoin selectivity for <> -- ---Testcase 64: +--Testcase 74: explain (costs off) select * from (select (fields->>'f1')::int4 f1 from INT4_TBL i4) i4, (select (fields->>'unique1')::int4 unique1, (fields->>'unique2')::int4 unique2, (fields->>'two')::int4 two, (fields->>'four')::int4 four, (fields->>'ten')::int4 ten, (fields->>'twenty')::int4 twenty, (fields->>'hundred')::int4 hundred, (fields->>'thousand')::int4 thousand, (fields->>'twothousand')::int4 twothousand, (fields->>'fivethous')::int4 fivethous, (fields->>'tenthous')::int4 tenthous, (fields->>'odd')::int4 odd, (fields->>'even')::int4 even, (fields->>'stringu1')::name stringu1, (fields->>'stringu2')::name stringu2, (fields->>'string4')::name string4 from tenk1 a) a where exists(select * from (select (fields->>'unique1')::int4 unique1, (fields->>'unique2')::int4 unique2, (fields->>'two')::int4 two, (fields->>'four')::int4 four, (fields->>'ten')::int4 ten, (fields->>'twenty')::int4 twenty, (fields->>'hundred')::int4 hundred, (fields->>'thousand')::int4 thousand, (fields->>'twothousand')::int4 twothousand, (fields->>'fivethous')::int4 fivethous, (fields->>'tenthous')::int4 tenthous, (fields->>'odd')::int4 odd, (fields->>'even')::int4 even, (fields->>'stringu1')::name stringu1, (fields->>'stringu2')::name stringu2, (fields->>'string4')::name string4 from tenk1 b) b @@ -1726,30 +1794,33 @@ where exists(select * from (select (fields->>'unique1')::int4 unique1, (fields-> -- -- Multiway full join -- ---Testcase 65: +--Testcase 75: CREATE FOREIGN TABLE t1 (fields jsonb OPTIONS (fields 'true')) SERVER influxdb_svr OPTIONS(schemaless 'true'); +--Testcase 577: CREATE FOREIGN TABLE t1_nsc (name TEXT, n INTEGER) SERVER influxdb_svr OPTIONS (table 't1'); ---Testcase 66: +--Testcase 76: CREATE FOREIGN TABLE t2 (fields jsonb OPTIONS (fields 'true')) SERVER influxdb_svr OPTIONS(schemaless 'true'); +--Testcase 578: CREATE FOREIGN TABLE t2_nsc (name TEXT, n INTEGER) SERVER influxdb_svr OPTIONS (table 't2'); ---Testcase 67: +--Testcase 77: CREATE FOREIGN TABLE t3 (fields jsonb OPTIONS (fields 'true')) SERVER influxdb_svr OPTIONS(schemaless 'true'); +--Testcase 579: CREATE FOREIGN TABLE t3_nsc (name TEXT, n INTEGER) SERVER influxdb_svr OPTIONS (table 't3'); ---Testcase 68: +--Testcase 78: INSERT INTO t1_nsc VALUES ( 'bb', 11 ); ---Testcase 69: +--Testcase 79: INSERT INTO t2_nsc VALUES ( 'bb', 12 ); ---Testcase 70: +--Testcase 80: INSERT INTO t2_nsc VALUES ( 'cc', 22 ); ---Testcase 71: +--Testcase 81: INSERT INTO t2_nsc VALUES ( 'ee', 42 ); ---Testcase 72: +--Testcase 82: INSERT INTO t3_nsc VALUES ( 'bb', 13 ); ---Testcase 73: +--Testcase 83: INSERT INTO t3_nsc VALUES ( 'cc', 23 ); ---Testcase 74: +--Testcase 84: INSERT INTO t3_nsc VALUES ( 'dd', 33 ); ---Testcase 75: +--Testcase 85: SELECT * FROM (select fields->>'name' "name", (fields->>'n')::int n from t1) t1 FULL JOIN (select fields->>'name' "name", (fields->>'n')::int n from t2) t2 USING (name) FULL JOIN (select fields->>'name' "name", (fields->>'n')::int n from t3) t3 USING (name); name | n | n | n ------+----+----+---- @@ -1763,7 +1834,7 @@ SELECT * FROM (select fields->>'name' "name", (fields->>'n')::int n from t1) t1 -- Test interactions of join syntax and subqueries -- -- Basic cases (we expect planner to pull up the subquery here) ---Testcase 76: +--Testcase 86: SELECT * FROM (SELECT * FROM (select fields->>'name' "name", (fields->>'n')::int n from t2) t2) as s2 INNER JOIN @@ -1775,7 +1846,7 @@ USING (name); cc | 22 | 23 (2 rows) ---Testcase 77: +--Testcase 87: SELECT * FROM (SELECT * FROM (select fields->>'name' "name", (fields->>'n')::int n from t2) t2) as s2 LEFT JOIN @@ -1788,7 +1859,7 @@ USING (name); ee | 42 | (3 rows) ---Testcase 78: +--Testcase 88: SELECT * FROM (SELECT * FROM (select fields->>'name' "name", (fields->>'n')::int n from t2) t2) as s2 FULL JOIN @@ -1804,7 +1875,7 @@ USING (name); -- Cases with non-nullable expressions in subquery results; -- make sure these go to null as expected ---Testcase 79: +--Testcase 89: SELECT * FROM (SELECT fields->>'name' "name", (fields->>'n')::int as s2_n, 2 as s2_2 FROM t2) as s2 NATURAL INNER JOIN @@ -1815,7 +1886,7 @@ NATURAL INNER JOIN cc | 22 | 2 | 23 | 3 (2 rows) ---Testcase 80: +--Testcase 90: SELECT * FROM (SELECT fields->>'name' "name", (fields->>'n')::int as s2_n, 2 as s2_2 FROM t2) as s2 NATURAL LEFT JOIN @@ -1827,7 +1898,7 @@ NATURAL LEFT JOIN ee | 42 | 2 | | (3 rows) ---Testcase 81: +--Testcase 91: SELECT * FROM (SELECT fields->>'name' "name", (fields->>'n')::int as s2_n, 2 as s2_2 FROM t2) as s2 NATURAL FULL JOIN @@ -1840,7 +1911,7 @@ NATURAL FULL JOIN ee | 42 | 2 | | (4 rows) ---Testcase 82: +--Testcase 92: SELECT * FROM (SELECT fields->>'name' "name", (fields->>'n')::int as s1_n, 1 as s1_1 FROM t1) as s1 NATURAL INNER JOIN @@ -1852,7 +1923,7 @@ NATURAL INNER JOIN bb | 11 | 1 | 12 | 2 | 13 | 3 (1 row) ---Testcase 83: +--Testcase 93: SELECT * FROM (SELECT fields->>'name' "name", (fields->>'n')::int as s1_n, 1 as s1_1 FROM t1) as s1 NATURAL FULL JOIN @@ -1867,7 +1938,7 @@ NATURAL FULL JOIN ee | | | 42 | 2 | | (4 rows) ---Testcase 84: +--Testcase 94: SELECT * FROM (SELECT fields->>'name' "name", (fields->>'n')::int as s1_n FROM t1) as s1 NATURAL FULL JOIN @@ -1884,7 +1955,7 @@ NATURAL FULL JOIN ee | | 42 | (4 rows) ---Testcase 85: +--Testcase 95: SELECT * FROM (SELECT fields->>'name' "name", (fields->>'n')::int as s1_n FROM t1) as s1 NATURAL FULL JOIN @@ -1902,39 +1973,48 @@ NATURAL FULL JOIN (4 rows) -- Constants as join keys can also be problematic ---Testcase 86: +--Testcase 96: SELECT * FROM (SELECT fields->>'name' "name", (fields->>'n')::int as s1_n FROM t1) as s1 FULL JOIN (SELECT fields->>'name' "name", 2 as s2_n FROM t2) as s2 ON ((s1_n)::int = (s2_n)::int); -ERROR: FULL JOIN is only supported with merge-joinable or hash-joinable join conditions + name | s1_n | name | s2_n +------+------+------+------ + | | bb | 2 + | | cc | 2 + | | ee | 2 + bb | 11 | | +(4 rows) + -- Test for propagation of nullability constraints into sub-joins ---Testcase 87: +--Testcase 97: create foreign table x (fields jsonb OPTIONS (fields 'true')) server influxdb_svr OPTIONS(schemaless 'true'); +--Testcase 580: create foreign table x_nsc (x1 int, x2 int) server influxdb_svr OPTIONS (table 'x'); ---Testcase 88: +--Testcase 98: insert into x_nsc values (1,11); ---Testcase 89: +--Testcase 99: insert into x_nsc values (2,22); ---Testcase 90: +--Testcase 100: insert into x_nsc values (3,null); ---Testcase 91: +--Testcase 101: insert into x_nsc values (4,44); ---Testcase 92: +--Testcase 102: insert into x_nsc values (5,null); ---Testcase 93: +--Testcase 103: create foreign table y (fields jsonb OPTIONS (fields 'true')) server influxdb_svr OPTIONS(schemaless 'true'); +--Testcase 581: create foreign table y_nsc (y1 int, y2 int) server influxdb_svr OPTIONS (table 'y'); ---Testcase 94: +--Testcase 104: insert into y_nsc values (1,111); ---Testcase 95: +--Testcase 105: insert into y_nsc values (2,222); ---Testcase 96: +--Testcase 106: insert into y_nsc values (3,333); ---Testcase 97: +--Testcase 107: insert into y_nsc values (4,null); ---Testcase 98: +--Testcase 108: select * from x; fields ------------------------- @@ -1945,7 +2025,7 @@ select * from x; {"x1": "5", "x2": null} (5 rows) ---Testcase 99: +--Testcase 109: select * from y; fields -------------------------- @@ -1955,7 +2035,7 @@ select * from y; {"y1": "4", "y2": null} (4 rows) ---Testcase 100: +--Testcase 110: select * from (select (fields->>'x1')::int x1, (fields->>'x2')::int x2 from x) x left join (select (fields->>'y1')::int y1, (fields->>'y2')::int y2 from y) y on (x1::int = y1::int and x2 is not null); x1 | x2 | y1 | y2 ----+----+----+----- @@ -1966,7 +2046,7 @@ select * from (select (fields->>'x1')::int x1, (fields->>'x2')::int x2 from x) x 5 | | | (5 rows) ---Testcase 101: +--Testcase 111: select * from (select (fields->>'x1')::int x1, (fields->>'x2')::int x2 from x) x left join (select (fields->>'y1')::int y1, (fields->>'y2')::int y2 from y) y on (x1::int = y1::int and y2 is not null); x1 | x2 | y1 | y2 ----+----+----+----- @@ -1977,7 +2057,7 @@ select * from (select (fields->>'x1')::int x1, (fields->>'x2')::int x2 from x) x 5 | | | (5 rows) ---Testcase 102: +--Testcase 112: select * from ((select (fields->>'x1')::int x1, (fields->>'x2')::int x2 from x) x left join (select (fields->>'y1')::int y1, (fields->>'y2')::int y2 from y) y on (x1::int = y1::int)) left join (select (fields->>'x1')::int x1, (fields->>'x2')::int x2 from x) xx(xx1,xx2) on (x1::int = xx1::int); x1 | x2 | y1 | y2 | xx1 | xx2 @@ -1989,7 +2069,7 @@ on (x1::int = xx1::int); 5 | | | | 5 | (5 rows) ---Testcase 103: +--Testcase 113: select * from ((select (fields->>'x1')::int x1, (fields->>'x2')::int x2 from x) x left join (select (fields->>'y1')::int y1, (fields->>'y2')::int y2 from y) y on (x1::int = y1::int)) left join (select (fields->>'x1')::int x1, (fields->>'x2')::int x2 from x) xx(xx1,xx2) on (x1::int = xx1::int and x2 is not null); x1 | x2 | y1 | y2 | xx1 | xx2 @@ -2001,7 +2081,7 @@ on (x1::int = xx1::int and x2 is not null); 5 | | | | | (5 rows) ---Testcase 104: +--Testcase 114: select * from ((select (fields->>'x1')::int x1, (fields->>'x2')::int x2 from x) x left join (select (fields->>'y1')::int y1, (fields->>'y2')::int y2 from y) y on (x1::int = y1::int)) left join (select (fields->>'x1')::int x1, (fields->>'x2')::int x2 from x) xx(xx1,xx2) on (x1::int = xx1::int and y2 is not null); x1 | x2 | y1 | y2 | xx1 | xx2 @@ -2013,7 +2093,7 @@ on (x1::int = xx1::int and y2 is not null); 5 | | | | | (5 rows) ---Testcase 105: +--Testcase 115: select * from ((select (fields->>'x1')::int x1, (fields->>'x2')::int x2 from x) x left join (select (fields->>'y1')::int y1, (fields->>'y2')::int y2 from y) y on (x1::int = y1::int)) left join (select (fields->>'x1')::int x1, (fields->>'x2')::int x2 from x) xx(xx1,xx2) on (x1::int = xx1::int and xx2 is not null); x1 | x2 | y1 | y2 | xx1 | xx2 @@ -2026,7 +2106,7 @@ on (x1::int = xx1::int and xx2 is not null); (5 rows) -- these should NOT give the same answers as above ---Testcase 106: +--Testcase 116: select * from ((select (fields->>'x1')::int x1, (fields->>'x2')::int x2 from x) x left join (select (fields->>'y1')::int y1, (fields->>'y2')::int y2 from y) y on (x1::int = y1::int)) left join (select (fields->>'x1')::int x1, (fields->>'x2')::int x2 from x) xx(xx1,xx2) on (x1::int = xx1::int) where (x2 is not null); x1 | x2 | y1 | y2 | xx1 | xx2 @@ -2036,7 +2116,7 @@ on (x1::int = xx1::int) where (x2 is not null); 4 | 44 | 4 | | 4 | 44 (3 rows) ---Testcase 107: +--Testcase 117: select * from ((select (fields->>'x1')::int x1, (fields->>'x2')::int x2 from x) x left join (select (fields->>'y1')::int y1, (fields->>'y2')::int y2 from y) y on (x1::int = y1::int)) left join (select (fields->>'x1')::int x1, (fields->>'x2')::int x2 from x) xx(xx1,xx2) on (x1::int = xx1::int) where (y2 is not null); x1 | x2 | y1 | y2 | xx1 | xx2 @@ -2046,7 +2126,7 @@ on (x1::int = xx1::int) where (y2 is not null); 3 | | 3 | 333 | 3 | (3 rows) ---Testcase 108: +--Testcase 118: select * from ((select (fields->>'x1')::int x1, (fields->>'x2')::int x2 from x) x left join (select (fields->>'y1')::int y1, (fields->>'y2')::int y2 from y) y on (x1::int = y1::int)) left join (select (fields->>'x1')::int x1, (fields->>'x2')::int x2 from x) xx(xx1,xx2) on (x1::int = xx1::int) where (xx2 is not null); x1 | x2 | y1 | y2 | xx1 | xx2 @@ -2060,7 +2140,7 @@ on (x1::int = xx1::int) where (xx2 is not null); -- regression test: check for bug with propagation of implied equality -- to outside an IN -- ---Testcase 109: +--Testcase 119: select count(*) from (select (fields->>'unique1')::int4 unique1, (fields->>'unique2')::int4 unique2, (fields->>'two')::int4 two, (fields->>'four')::int4 four, (fields->>'ten')::int4 ten, (fields->>'twenty')::int4 twenty, (fields->>'hundred')::int4 hundred, (fields->>'thousand')::int4 thousand, (fields->>'twothousand')::int4 twothousand, (fields->>'fivethous')::int4 fivethous, (fields->>'tenthous')::int4 tenthous, (fields->>'odd')::int4 odd, (fields->>'even')::int4 even, (fields->>'stringu1')::name stringu1, (fields->>'stringu2')::name stringu2, (fields->>'string4')::name string4 from tenk1) a where unique1 in (select unique1 from (select (fields->>'unique1')::int4 unique1, (fields->>'unique2')::int4 unique2, (fields->>'two')::int4 two, (fields->>'four')::int4 four, (fields->>'ten')::int4 ten, (fields->>'twenty')::int4 twenty, (fields->>'hundred')::int4 hundred, (fields->>'thousand')::int4 thousand, (fields->>'twothousand')::int4 twothousand, (fields->>'fivethous')::int4 fivethous, (fields->>'tenthous')::int4 tenthous, (fields->>'odd')::int4 odd, (fields->>'even')::int4 even, (fields->>'stringu1')::name stringu1, (fields->>'stringu2')::name stringu2, (fields->>'string4')::name string4 from tenk1) b join (select (fields->>'unique1')::int4 unique1, (fields->>'unique2')::int4 unique2, (fields->>'two')::int4 two, (fields->>'four')::int4 four, (fields->>'ten')::int4 ten, (fields->>'twenty')::int4 twenty, (fields->>'hundred')::int4 hundred, (fields->>'thousand')::int4 thousand, (fields->>'twothousand')::int4 twothousand, (fields->>'fivethous')::int4 fivethous, (fields->>'tenthous')::int4 tenthous, (fields->>'odd')::int4 odd, (fields->>'even')::int4 even, (fields->>'stringu1')::name stringu1, (fields->>'stringu2')::name stringu2, (fields->>'string4')::name string4 from tenk1) c using (unique1) where b.unique2::int4 = 42); @@ -2073,7 +2153,7 @@ select count(*) from (select (fields->>'unique1')::int4 unique1, (fields->>'uniq -- regression test: check for failure to generate a plan with multiple -- degenerate IN clauses -- ---Testcase 110: +--Testcase 120: select count(*) from (select (fields->>'unique1')::int4 unique1, (fields->>'unique2')::int4 unique2, (fields->>'two')::int4 two, (fields->>'four')::int4 four, (fields->>'ten')::int4 ten, (fields->>'twenty')::int4 twenty, (fields->>'hundred')::int4 hundred, (fields->>'thousand')::int4 thousand, (fields->>'twothousand')::int4 twothousand, (fields->>'fivethous')::int4 fivethous, (fields->>'tenthous')::int4 tenthous, (fields->>'odd')::int4 odd, (fields->>'even')::int4 even, (fields->>'stringu1')::name stringu1, (fields->>'stringu2')::name stringu2, (fields->>'string4')::name string4 from tenk1) x where (x.unique1)::int4 in (select (a.fields->>'f1')::int4 from int4_tbl a,float8_tbl b where (a.fields->>'f1')::int4=(b.fields->>'f1')::float8) and (x.unique1)::int4 = 0 and @@ -2085,11 +2165,11 @@ select count(*) from (select (fields->>'unique1')::int4 unique1, (fields->>'uniq -- try that with GEQO too begin; ---Testcase 111: +--Testcase 121: set geqo = on; ---Testcase 112: +--Testcase 122: set geqo_threshold = 2; ---Testcase 113: +--Testcase 123: select count(*) from (select (fields->>'unique1')::int4 unique1, (fields->>'unique2')::int4 unique2, (fields->>'two')::int4 two, (fields->>'four')::int4 four, (fields->>'ten')::int4 ten, (fields->>'twenty')::int4 twenty, (fields->>'hundred')::int4 hundred, (fields->>'thousand')::int4 thousand, (fields->>'twothousand')::int4 twothousand, (fields->>'fivethous')::int4 fivethous, (fields->>'tenthous')::int4 tenthous, (fields->>'odd')::int4 odd, (fields->>'even')::int4 even, (fields->>'stringu1')::name stringu1, (fields->>'stringu2')::name stringu2, (fields->>'string4')::name string4 from tenk1) x where (x.unique1)::int4 in (select a.f1 from (select (fields->>'f1')::int4 f1 from INT4_TBL) a,(select (fields->>'f1')::float8 f1 from FLOAT8_TBL) b where a.f1::int4=b.f1::float8) and (x.unique1)::int4 = 0 and @@ -2103,37 +2183,37 @@ rollback; -- -- regression test: be sure we cope with proven-dummy append rels -- ---Testcase 114: -create table b (aa int, bb int); ---Testcase 115: +--Testcase 124: +CREATE FOREIGN TABLE b_star(fields jsonb OPTIONS (fields 'true')) SERVER influxdb_svr OPTIONS(schemaless 'true'); +--Testcase 125: explain (costs off) -select aa, bb, tenk1.unique1::int, tenk1.unique1::int - from (select (fields->>'unique1')::int unique1, fields->>'unique2' unique2, fields->>'two' two, fields->>'four' four, fields->>'ten' ten, fields->>'twenty' twenty, fields->>'hundred' hundred, fields->>'thousand' thousand, fields->>'twothousand' twothousand, fields->>'fivethous' fivethous, fields->>'tenthous' tenthous, fields->>'odd' odd, fields->>'even' even, fields->>'stringu1' stringu1, fields->>'stringu2' stringu2, fields->>'string4' string4 from tenk1) tenk1 right join b on aa = tenk1.unique1::int - where bb < bb and bb is null; - QUERY PLAN ---------------------------------------------------------------------- +select b_star.aa::int4, bb, tenk1.unique1::int, tenk1.unique1::int + from (select (fields->>'unique1')::int unique1, fields->>'unique2' unique2, fields->>'two' two, fields->>'four' four, fields->>'ten' ten, fields->>'twenty' twenty, fields->>'hundred' hundred, fields->>'thousand' thousand, fields->>'twothousand' twothousand, fields->>'fivethous' fivethous, fields->>'tenthous' tenthous, fields->>'odd' odd, fields->>'even' even, fields->>'stringu1' stringu1, fields->>'stringu2' stringu2, fields->>'string4' string4 from tenk1) tenk1 right join (select (fields->>'class')::char class, (fields->>'aa')::int4 aa, fields->>'bb' bb, (fields->>'a')::int4 a from b_star) b_star on b_star.aa::int4 = tenk1.unique1::int + where b_star.bb < b_star.bb and b_star.bb is null; + QUERY PLAN +------------------------------------------------------------------------------------------------------------------- Hash Right Join - Hash Cond: (((tenk1.fields ->> 'unique1'::text))::integer = b.aa) + Hash Cond: (((tenk1.fields ->> 'unique1'::text))::integer = ((b_star.fields ->> 'aa'::text))::integer) -> Foreign Scan on tenk1 -> Hash - -> Seq Scan on b - Filter: ((bb IS NULL) AND (bb < bb)) + -> Foreign Scan on b_star + Filter: (((fields ->> 'bb'::text) IS NULL) AND ((fields ->> 'bb'::text) < (fields ->> 'bb'::text))) (6 rows) ---Testcase 116: -select aa, bb, tenk1.unique1::int, tenk1.unique1::int - from (select (fields->>'unique1')::int unique1, fields->>'unique2' unique2, fields->>'two' two, fields->>'four' four, fields->>'ten' ten, fields->>'twenty' twenty, fields->>'hundred' hundred, fields->>'thousand' thousand, fields->>'twothousand' twothousand, fields->>'fivethous' fivethous, fields->>'tenthous' tenthous, fields->>'odd' odd, fields->>'even' even, fields->>'stringu1' stringu1, fields->>'stringu2' stringu2, fields->>'string4' string4 from tenk1) tenk1 right join b on aa = tenk1.unique1::int - where bb < bb and bb is null; +--Testcase 126: +select b_star.aa::int4, bb, tenk1.unique1::int, tenk1.unique1::int + from (select (fields->>'unique1')::int unique1, fields->>'unique2' unique2, fields->>'two' two, fields->>'four' four, fields->>'ten' ten, fields->>'twenty' twenty, fields->>'hundred' hundred, fields->>'thousand' thousand, fields->>'twothousand' twothousand, fields->>'fivethous' fivethous, fields->>'tenthous' tenthous, fields->>'odd' odd, fields->>'even' even, fields->>'stringu1' stringu1, fields->>'stringu2' stringu2, fields->>'string4' string4 from tenk1) tenk1 right join (select (fields->>'class')::char class, (fields->>'aa')::int4 aa, fields->>'bb' bb, (fields->>'a')::int4 a from b_star) b_star on b_star.aa::int4 = tenk1.unique1::int + where b_star.bb < b_star.bb and b_star.bb is null; aa | bb | unique1 | unique1 ----+----+---------+--------- (0 rows) ---Testcase 117: -drop table b; +--Testcase 127: +drop foreign table b_star; -- -- regression test: check handling of empty-FROM subquery underneath outer join -- ---Testcase 118: +--Testcase 128: explain (costs off) select (i1.fields->>'q1')::int8 q1, (i1.fields->>'q2')::int8 q2, (i2.fields->>'q1')::int8 q1, (i2.fields->>'q2')::int8 q2, x from int8_tbl i1 left join (int8_tbl i2 join (select 123 as x) ss on (i2.fields->>'q1')::int8 = x) on (i1.fields->>'q2')::int8 = (i2.fields->>'q2')::int8 @@ -2146,14 +2226,10 @@ order by 1, 2; Hash Cond: (((i1.fields ->> 'q2'::text))::bigint = ((i2.fields ->> 'q2'::text))::bigint) -> Foreign Scan on int8_tbl i1 -> Hash - -> Hash Join - Hash Cond: (((i2.fields ->> 'q1'::text))::bigint = (123)) - -> Foreign Scan on int8_tbl i2 - -> Hash - -> Result -(11 rows) + -> Foreign Scan on int8_tbl i2 +(7 rows) ---Testcase 119: +--Testcase 129: select (i1.fields->>'q1')::int8 q1, (i1.fields->>'q2')::int8 q2, (i2.fields->>'q1')::int8 q1, (i2.fields->>'q2')::int8 q2, x from int8_tbl i1 left join (int8_tbl i2 join (select 123 as x) ss on (i2.fields->>'q1')::int8 = x) on (i1.fields->>'q2')::int8= (i2.fields->>'q2')::int8 order by 1, 2; @@ -2167,10 +2243,10 @@ order by 1, 2; (5 rows) -- --- regression test: check a case where join_clause_is_movable_into() gives --- an imprecise result, causing an assertion failure +-- regression test: check a case where join_clause_is_movable_into() +-- used to give an imprecise result, causing an assertion failure -- ---Testcase 120: +--Testcase 130: select count(*) from (select (t3.fields->>'tenthous')::int4 as x1, coalesce((t1.fields->>'stringu1')::name, (t2.fields->>'stringu1')::name) as x2 @@ -2189,7 +2265,7 @@ where (t4.fields->>'thousand')::int4 = (t5.fields->>'unique1')::int4 and ss.x1 = -- regression test: check a case where we formerly missed including an EC -- enforcement clause because it was expected to be handled at scan level -- ---Testcase 121: +--Testcase 131: explain (costs off) select a.f1, b.f1, (t.fields->>'thousand')::int4 thousand, (t.fields->>'tenhous')::int4 tenthous from tenk1 t, @@ -2210,7 +2286,7 @@ where b.f1 = (t.fields->>'thousand')::int4 and a.f1 = b.f1 and (a.f1+b.f1+999) = -> Foreign Scan (10 rows) ---Testcase 122: +--Testcase 132: select a.f1, b.f1, (t.fields->>'thousand')::int4 thousand, (t.fields->>'tenhous')::int4 tenthous from tenk1 t, (select sum((fields->>'f1')::int4)+1 as f1 from int4_tbl i4a) a, @@ -2221,62 +2297,418 @@ where b.f1 = (t.fields->>'thousand')::int4 and a.f1 = b.f1 and (a.f1+b.f1+999) = (0 rows) -- --- check a case where we formerly got confused by conflicting sort orders --- in redundant merge join path keys +-- checks for correct handling of quals in multiway outer joins -- ---Testcase 123: explain (costs off) -select * from - (SELECT (fields->>'i')::int i,(fields->>'j')::int j,fields->>'t' t FROM J1_TBL j1_tbl) j1_tbl full join - (select * from (select (fields->>'i')::int i, (fields->>'k')::int k from J2_TBL j2_tbl) j2_tbl order by (j2_tbl.i)::int desc, (j2_tbl.k)::int asc) j2_tbl - on (j1_tbl.i)::int = (j2_tbl.i)::int and (j1_tbl.i)::int = (j2_tbl.k)::int; - QUERY PLAN ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- - Merge Full Join - Merge Cond: (((((j2_tbl.fields ->> 'i'::text))::integer) = (((j1_tbl.fields ->> 'i'::text))::integer)) AND ((((j2_tbl.fields ->> 'k'::text))::integer) = (((j1_tbl.fields ->> 'i'::text))::integer))) - -> Sort - Sort Key: (((j2_tbl.fields ->> 'i'::text))::integer) DESC, (((j2_tbl.fields ->> 'k'::text))::integer) - -> Foreign Scan on j2_tbl - -> Sort - Sort Key: (((j1_tbl.fields ->> 'i'::text))::integer) DESC - -> Foreign Scan on j1_tbl -(8 rows) +select (t1.fields->>'f1')::int4 as f1 +from int4_tbl t1, int4_tbl t2 + left join int4_tbl t3 on (t3.fields->>'f1')::int4 > 0 + left join int4_tbl t4 on (t3.fields->>'f1')::int4 > 1 +where (t4.fields->>'f1')::int4 is null; + QUERY PLAN +------------------------------------------------------------------------------ + Nested Loop + -> Nested Loop Left Join + Filter: (((t4.fields ->> 'f1'::text))::integer IS NULL) + -> Foreign Scan on int4_tbl t2 + -> Materialize + -> Nested Loop Left Join + Join Filter: (((t3.fields ->> 'f1'::text))::integer > 1) + -> Foreign Scan on int4_tbl t3 + -> Materialize + -> Foreign Scan on int4_tbl t4 + -> Materialize + -> Foreign Scan on int4_tbl t1 +(12 rows) ---Testcase 124: -select * from - (select (fields->>'i')::int i, (fields->>'j')::int j,fields->>'t' t from J1_TBL j1_tbl) j1_tbl full join - (select * from (select (fields->>'i')::int i, (fields->>'k')::int k from J2_TBL j2_tbl) j2_tbl order by (j2_tbl.i)::int desc, (j2_tbl.k)::int asc) j2_tbl - on j1_tbl.i = j2_tbl.i and j1_tbl.i = j2_tbl.k; - i | j | t | i | k ----+---+-------+---+---- - | | | | 0 - | 0 | zero | | - | | null | | - 8 | 8 | eight | | - 7 | 7 | seven | | - 6 | 6 | six | | - | | | 5 | -5 - | | | 5 | -5 - 5 | 0 | five | | - 4 | 1 | four | | - | | | 3 | -3 - 3 | 2 | three | | - 2 | 3 | two | 2 | 2 - | | | 2 | 4 - | | | 1 | -1 - | | | 0 | - 1 | 4 | one | | - 0 | | zero | | -(18 rows) +select (t1.fields->>'f1')::int4 as f1 +from int4_tbl t1, int4_tbl t2 + left join int4_tbl t3 on (t3.fields->>'f1')::int4 > 0 + left join int4_tbl t4 on (t3.fields->>'f1')::int4 > 1 +where (t4.fields->>'f1')::int4 is null; + f1 +---- +(0 rows) --- --- a different check for handling of redundant sort keys in merge joins --- ---Testcase 125: explain (costs off) -select count(*) from - (select * from tenk1 x order by (x.fields->>'thousand')::int4, (x.fields->>'twothousand')::int4, (x.fields->>'fivethous')::int4) x - left join +select * +from int4_tbl t1 left join int4_tbl t2 on true + left join int4_tbl t3 on (t2.fields->>'f1')::int4 > 0 + left join int4_tbl t4 on (t3.fields->>'f1')::int4 > 0; + QUERY PLAN +------------------------------------------------------------------------------ + Nested Loop Left Join + -> Foreign Scan on int4_tbl t1 + -> Materialize + -> Nested Loop Left Join + Join Filter: (((t3.fields ->> 'f1'::text))::integer > 0) + -> Nested Loop Left Join + Join Filter: (((t2.fields ->> 'f1'::text))::integer > 0) + -> Foreign Scan on int4_tbl t2 + -> Materialize + -> Foreign Scan on int4_tbl t3 + -> Materialize + -> Foreign Scan on int4_tbl t4 +(12 rows) + +explain (costs off) +select * from onek t1 + left join onek t2 on (t1.fields->>'unique1')::int4 = (t2.fields->>'unique1')::int4 + left join onek t3 on (t2.fields->>'unique1')::int4 != (t3.fields->>'unique1')::int4 + left join onek t4 on (t3.fields->>'unique1')::int4 = (t4.fields->>'unique1')::int4; + QUERY PLAN +------------------------------------------------------------------------------------------------------------------------- + Nested Loop Left Join + Join Filter: (((t2.fields ->> 'unique1'::text))::integer <> ((t3.fields ->> 'unique1'::text))::integer) + -> Merge Left Join + Merge Cond: ((((t1.fields ->> 'unique1'::text))::integer) = (((t2.fields ->> 'unique1'::text))::integer)) + -> Sort + Sort Key: (((t1.fields ->> 'unique1'::text))::integer) + -> Foreign Scan on onek t1 + -> Sort + Sort Key: (((t2.fields ->> 'unique1'::text))::integer) + -> Foreign Scan on onek t2 + -> Materialize + -> Merge Left Join + Merge Cond: ((((t3.fields ->> 'unique1'::text))::integer) = (((t4.fields ->> 'unique1'::text))::integer)) + -> Sort + Sort Key: (((t3.fields ->> 'unique1'::text))::integer) + -> Foreign Scan on onek t3 + -> Sort + Sort Key: (((t4.fields ->> 'unique1'::text))::integer) + -> Foreign Scan on onek t4 +(19 rows) + +explain (costs off) +select * from int4_tbl t1 + left join (select now() from int4_tbl t2 + left join int4_tbl t3 on (t2.fields->>'f1')::int4 = (t3.fields->>'f1')::int4 + left join int4_tbl t4 on (t3.fields->>'f1')::int4 = (t4.fields->>'f1')::int4) s on true + inner join int4_tbl t5 on true; + QUERY PLAN +--------------------------------------------------------------------------------------------------------------------------- + Nested Loop Left Join + -> Nested Loop + -> Foreign Scan on int4_tbl t5 + -> Materialize + -> Foreign Scan on int4_tbl t1 + -> Materialize + -> Merge Left Join + Merge Cond: ((((t2.fields ->> 'f1'::text))::integer) = ((t3.fields ->> 'f1'::text))::integer) + -> Sort + Sort Key: (((t2.fields ->> 'f1'::text))::integer) + -> Foreign Scan on int4_tbl t2 + -> Materialize + -> Merge Left Join + Merge Cond: ((((t3.fields ->> 'f1'::text))::integer) = (((t4.fields ->> 'f1'::text))::integer)) + -> Sort + Sort Key: (((t3.fields ->> 'f1'::text))::integer) + -> Foreign Scan on int4_tbl t3 + -> Sort + Sort Key: (((t4.fields ->> 'f1'::text))::integer) + -> Foreign Scan on int4_tbl t4 +(20 rows) + +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.fields->>'f1')::int4 = (t3.fields->>'f1')::int4; + QUERY PLAN +------------------------------------------------------------------------------------------------ + Nested Loop Left Join + Join Filter: (((t2.fields ->> 'f1'::text))::integer = ((t3.fields ->> 'f1'::text))::integer) + -> Nested Loop Left Join + -> Nested Loop Left Join + -> Foreign Scan on int4_tbl t1 + -> Materialize + -> Foreign Scan on int4_tbl t2 + -> Materialize + -> Foreign Scan on int4_tbl t3 + -> Materialize + -> Foreign Scan on int4_tbl t4 +(11 rows) + +explain (costs off) +select * from int4_tbl t1 + left join int4_tbl t2 on true + left join int4_tbl t3 on (t2.fields->>'f1')::int4 = (t3.fields->>'f1')::int4 + left join int4_tbl t4 on (t3.fields->>'f1')::int4 != (t4.fields->>'f1')::int4; + QUERY PLAN +--------------------------------------------------------------------------------------------------------------------- + Nested Loop Left Join + -> Foreign Scan on int4_tbl t1 + -> Materialize + -> Nested Loop Left Join + Join Filter: (((t3.fields ->> 'f1'::text))::integer <> ((t4.fields ->> 'f1'::text))::integer) + -> Merge Left Join + Merge Cond: ((((t2.fields ->> 'f1'::text))::integer) = (((t3.fields ->> 'f1'::text))::integer)) + -> Sort + Sort Key: (((t2.fields ->> 'f1'::text))::integer) + -> Foreign Scan on int4_tbl t2 + -> Sort + Sort Key: (((t3.fields ->> 'f1'::text))::integer) + -> Foreign Scan on int4_tbl t3 + -> Materialize + -> Foreign Scan on int4_tbl t4 +(15 rows) + +explain (costs off) +select * from int4_tbl t1 + left join (int4_tbl t2 left join int4_tbl t3 on (t2.fields->>'f1')::int4 > 0) on (t2.fields->>'f1')::int4 > 1 + left join int4_tbl t4 on (t2.fields->>'f1')::int4 > 2 and (t3.fields->>'f1')::int4 > 3 +where (t1.fields->>'f1')::int4 = coalesce((t2.fields->>'f1')::int4, 1); + QUERY PLAN +-------------------------------------------------------------------------------------------------------------------- + Nested Loop Left Join + Join Filter: ((((t2.fields ->> 'f1'::text))::integer > 2) AND (((t3.fields ->> 'f1'::text))::integer > 3)) + -> Nested Loop Left Join + Join Filter: (((t2.fields ->> 'f1'::text))::integer > 0) + -> Nested Loop Left Join + Filter: (((t1.fields ->> 'f1'::text))::integer = COALESCE(((t2.fields ->> 'f1'::text))::integer, 1)) + -> Foreign Scan on int4_tbl t1 + -> Materialize + -> Foreign Scan on int4_tbl t2 + -> Materialize + -> Foreign Scan on int4_tbl t3 + -> Materialize + -> Foreign Scan on int4_tbl t4 +(13 rows) + +explain (costs off) +select * from int4_tbl t1 + left join ((select (t2.fields->>'f1')::int4 as f1 from int4_tbl t2 + left join int4_tbl t3 on (t2.fields->>'f1')::int4 > 0 + where (t3.fields->>'f1')::int4 is null) s + left join tenk1 t4 on s.f1 > 1) + on s.f1 = (t1.fields->>'f1')::int4; + QUERY PLAN +--------------------------------------------------------------------------------------------------- + Merge Left Join + Merge Cond: ((((t1.fields ->> 'f1'::text))::integer) = (((t2.fields ->> 'f1'::text))::integer)) + -> Sort + Sort Key: (((t1.fields ->> 'f1'::text))::integer) + -> Foreign Scan on int4_tbl t1 + -> Materialize + -> Sort + Sort Key: (((t2.fields ->> 'f1'::text))::integer) + -> Nested Loop Left Join + Join Filter: (((t2.fields ->> 'f1'::text))::integer > 1) + -> Nested Loop Left Join + Join Filter: (((t2.fields ->> 'f1'::text))::integer > 0) + Filter: (((t3.fields ->> 'f1'::text))::integer IS NULL) + -> Foreign Scan on int4_tbl t2 + -> Materialize + -> Foreign Scan on int4_tbl t3 + -> Materialize + -> Foreign Scan on tenk1 t4 +(18 rows) + +explain (costs off) +select * from int4_tbl t1 + left join ((select (t2.fields->>'f1')::int4 as f1 from int4_tbl t2 + left join int4_tbl t3 on (t2.fields->>'f1')::int4 > 0 + where (t2.fields->>'f1')::int4 <> coalesce((t3.fields->>'f1')::int4, -1)) s + left join tenk1 t4 on s.f1 > 1) + on s.f1 = (t1.fields->>'f1')::int4; + QUERY PLAN +--------------------------------------------------------------------------------------------------------------------------------------------- + Nested Loop Left Join + Join Filter: (((t2.fields ->> 'f1'::text))::integer > 1) + -> Merge Left Join + Merge Cond: ((((t1.fields ->> 'f1'::text))::integer) = (((t2.fields ->> 'f1'::text))::integer)) + -> Sort + Sort Key: (((t1.fields ->> 'f1'::text))::integer) + -> Foreign Scan on int4_tbl t1 + -> Materialize + -> Sort + Sort Key: (((t2.fields ->> 'f1'::text))::integer) + -> Nested Loop Left Join + Join Filter: (((t2.fields ->> 'f1'::text))::integer > 0) + Filter: (((t2.fields ->> 'f1'::text))::integer <> COALESCE(((t3.fields ->> 'f1'::text))::integer, '-1'::integer)) + -> Foreign Scan on int4_tbl t2 + -> Materialize + -> Foreign Scan on int4_tbl t3 + -> Materialize + -> Foreign Scan on tenk1 t4 +(18 rows) + +explain (costs off) +select * from onek t1 + left join onek t2 on (t1.fields->>'unique1')::int4 = (t2.fields->>'unique1')::int4 + left join onek t3 on (t2.fields->>'unique1')::int4 = (t3.fields->>'unique1')::int4 + left join onek t4 on (t3.fields->>'unique1')::int4 = (t4.fields->>'unique1')::int4 and (t2.fields->>'unique2')::int4 = (t4.fields->>'unique2')::int4; + QUERY PLAN +----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- + Merge Left Join + Merge Cond: (((((t3.fields ->> 'unique1'::text))::integer) = (((t4.fields ->> 'unique1'::text))::integer)) AND ((((t2.fields ->> 'unique2'::text))::integer) = (((t4.fields ->> 'unique2'::text))::integer))) + -> Sort + Sort Key: (((t3.fields ->> 'unique1'::text))::integer), (((t2.fields ->> 'unique2'::text))::integer) + -> Merge Left Join + Merge Cond: ((((t1.fields ->> 'unique1'::text))::integer) = ((t2.fields ->> 'unique1'::text))::integer) + -> Sort + Sort Key: (((t1.fields ->> 'unique1'::text))::integer) + -> Foreign Scan on onek t1 + -> Materialize + -> Merge Left Join + Merge Cond: ((((t2.fields ->> 'unique1'::text))::integer) = (((t3.fields ->> 'unique1'::text))::integer)) + -> Sort + Sort Key: (((t2.fields ->> 'unique1'::text))::integer) + -> Foreign Scan on onek t2 + -> Sort + Sort Key: (((t3.fields ->> 'unique1'::text))::integer) + -> Foreign Scan on onek t3 + -> Sort + Sort Key: (((t4.fields ->> 'unique1'::text))::integer), (((t4.fields ->> 'unique2'::text))::integer) + -> Foreign Scan on onek t4 +(21 rows) + +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.fields->>'q1')::int4 = (t5.fields->>'q1')::int4 +on (t2.fields->>'q2')::int4 = 123; + QUERY PLAN +---------------------------------------------------------------------------------------------------------- + Nested Loop Left Join + -> Foreign Scan on int8_tbl t1 + -> Materialize + -> Hash Right Join + Hash Cond: (((t5.fields ->> 'q1'::text))::integer = ((t2.fields ->> 'q1'::text))::integer) + -> Foreign Scan on int8_tbl t5 + -> Hash + -> Nested Loop Left Join + Join Filter: false + -> Foreign Scan on int8_tbl t2 + -> Result + One-Time Filter: false +(12 rows) + +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.fields->>'q1')::int4 = (t2.fields->>'q1')::int4 offset 0) s + on (t2.fields->>'q1')::int4 = 1; + QUERY PLAN +------------------------------------------------------------------------ + Nested Loop Left Join + -> Foreign Scan on int8_tbl t1 + -> Materialize + -> Nested Loop Left Join + Join Filter: (((t2.fields ->> 'q1'::text))::integer = 1) + -> Foreign Scan on int8_tbl t2 + -> Foreign Scan on int8_tbl t3 +(7 rows) + +explain (costs off) +select * from int8_tbl t1 + left join int8_tbl t2 on true + left join lateral + (select * from generate_series((t2.fields->>'q1')::int4, 100)) s + on (t2.fields->>'q1')::int4 = 1; + QUERY PLAN +------------------------------------------------------------------------ + Nested Loop Left Join + -> Foreign Scan on int8_tbl t1 + -> Materialize + -> Nested Loop Left Join + Join Filter: (((t2.fields ->> 'q1'::text))::integer = 1) + -> Foreign Scan on int8_tbl t2 + -> Function Scan on generate_series +(7 rows) + +explain (costs off) +select * from int8_tbl t1 + left join int8_tbl t2 on true + left join lateral + (select (t2.fields->>'q1')::int4 from int8_tbl t3) s + on (t2.fields->>'q1')::int4 = 1; + QUERY PLAN +------------------------------------------------------------------------ + Nested Loop Left Join + -> Foreign Scan on int8_tbl t1 + -> Materialize + -> Nested Loop Left Join + Join Filter: (((t2.fields ->> 'q1'::text))::integer = 1) + -> Foreign Scan on int8_tbl t2 + -> Foreign Scan on int8_tbl t3 +(7 rows) + +explain (costs off) +select * from onek t1 + left join onek t2 on true + left join lateral + (select * from onek t3 where (t3.fields->>'two')::int4 = (t2.fields->>'two')::int4 offset 0) s + on (t2.fields->>'unique1')::int4 = 1; + QUERY PLAN +----------------------------------------------------------------------------- + Nested Loop Left Join + -> Foreign Scan on onek t1 + -> Materialize + -> Nested Loop Left Join + Join Filter: (((t2.fields ->> 'unique1'::text))::integer = 1) + -> Foreign Scan on onek t2 + -> Foreign Scan on onek t3 +(7 rows) + +-- +-- check a case where we formerly got confused by conflicting sort orders +-- in redundant merge join path keys +-- +--Testcase 133: +explain (costs off) +select * from + (SELECT (fields->>'i')::int i,(fields->>'j')::int j,fields->>'t' t FROM J1_TBL j1_tbl) j1_tbl full join + (select * from (select (fields->>'i')::int i, (fields->>'k')::int k from J2_TBL j2_tbl) j2_tbl order by (j2_tbl.i)::int desc, (j2_tbl.k)::int asc) j2_tbl + on (j1_tbl.i)::int = (j2_tbl.i)::int and (j1_tbl.i)::int = (j2_tbl.k)::int; + QUERY PLAN +--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- + Merge Full Join + Merge Cond: (((((j2_tbl.fields ->> 'i'::text))::integer) = (((j1_tbl.fields ->> 'i'::text))::integer)) AND ((((j2_tbl.fields ->> 'k'::text))::integer) = (((j1_tbl.fields ->> 'i'::text))::integer))) + -> Sort + Sort Key: (((j2_tbl.fields ->> 'i'::text))::integer) DESC, (((j2_tbl.fields ->> 'k'::text))::integer) + -> Foreign Scan on j2_tbl + -> Sort + Sort Key: (((j1_tbl.fields ->> 'i'::text))::integer) DESC + -> Foreign Scan on j1_tbl +(8 rows) + +--Testcase 134: +select * from + (select (fields->>'i')::int i, (fields->>'j')::int j,fields->>'t' t from J1_TBL j1_tbl) j1_tbl full join + (select * from (select (fields->>'i')::int i, (fields->>'k')::int k from J2_TBL j2_tbl) j2_tbl order by (j2_tbl.i)::int desc, (j2_tbl.k)::int asc) j2_tbl + on j1_tbl.i = j2_tbl.i and j1_tbl.i = j2_tbl.k; + i | j | t | i | k +---+---+-------+---+---- + | | | | 0 + | 0 | zero | | + | | null | | + 8 | 8 | eight | | + 7 | 7 | seven | | + 6 | 6 | six | | + | | | 5 | -5 + | | | 5 | -5 + 5 | 0 | five | | + 4 | 1 | four | | + | | | 3 | -3 + 3 | 2 | three | | + 2 | 3 | two | 2 | 2 + | | | 2 | 4 + | | | 1 | -1 + | | | 0 | + 1 | 4 | one | | + 0 | | zero | | +(18 rows) + +-- +-- a different check for handling of redundant sort keys in merge joins +-- +--Testcase 135: +explain (costs off) +select count(*) from + (select * from tenk1 x order by (x.fields->>'thousand')::int4, (x.fields->>'twothousand')::int4, (x.fields->>'fivethous')::int4) x + left join (select * from tenk1 y order by (y.fields->>'unique2')::int4) y on (x.fields->>'thousand')::int4 = (y.fields->>'unique2')::int4 and (x.fields->>'twothousand')::int4 = (y.fields->>'hundred')::int4 and (x.fields->>'fivethous')::int4 = (y.fields->>'unique2')::int4; QUERY PLAN @@ -2298,7 +2730,7 @@ select count(*) from -> Foreign Scan on tenk1 y_1 (15 rows) ---Testcase 126: +--Testcase 136: select count(*) from (select * from tenk1 x order by (x.fields->>'thousand')::int4, (x.fields->>'twothousand')::int4, (x.fields->>'fivethous')::int4) x left join @@ -2309,69 +2741,115 @@ select count(*) from 10000 (1 row) +set enable_hashjoin = 0; +set enable_nestloop = 0; +set enable_hashagg = 0; +-- +-- 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.fields->>'thousand')::int4 as thousand, (x.fields->>'twothousand')::int4 as twothousand, count(*) +from tenk1 x inner join tenk1 y on (x.fields->>'thousand')::int4 = (y.fields->>'thousand')::int4 +group by (x.fields->>'thousand'), (x.fields->>'twothousand') +order by (x.fields->>'thousand') desc, (x.fields->>'twothousand'); + QUERY PLAN +------------------------------------------------------------------------------------------------------------------------- + GroupAggregate + Group Key: ((x.fields ->> 'thousand'::text)), ((x.fields ->> 'twothousand'::text)) + -> Sort + Sort Key: ((x.fields ->> 'thousand'::text)) DESC, ((x.fields ->> 'twothousand'::text)) + -> Merge Join + Merge Cond: ((((x.fields ->> 'thousand'::text))::integer) = (((y.fields ->> 'thousand'::text))::integer)) + -> Sort + Sort Key: (((x.fields ->> 'thousand'::text))::integer) + -> Foreign Scan on tenk1 x + -> Sort + Sort Key: (((y.fields ->> 'thousand'::text))::integer) + -> Foreign Scan on tenk1 y +(12 rows) + +reset enable_hashagg; +reset enable_nestloop; +reset enable_hashjoin; -- -- Clean up -- ---Testcase 127: +--Testcase 137: DELETE FROM t1_nsc; ---Testcase 128: +--Testcase 138: DELETE FROM t2_nsc; ---Testcase 129: +--Testcase 139: DELETE FROM t3_nsc; ---Testcase 130: +--Testcase 140: DROP FOREIGN TABLE t1; +--Testcase 582: DROP FOREIGN TABLE t1_nsc; ---Testcase 131: +--Testcase 141: DROP FOREIGN TABLE t2; +--Testcase 583: DROP FOREIGN TABLE t2_nsc; ---Testcase 132: +--Testcase 142: DROP FOREIGN TABLE t3; +--Testcase 584: DROP FOREIGN TABLE t3_nsc; ---Testcase 133: +--Testcase 143: DELETE FROM j1_tbl_nsc; +--Testcase 585: DROP FOREIGN TABLE J1_TBL; +--Testcase 586: DROP FOREIGN TABLE j1_tbl_nsc; ---Testcase 134: +--Testcase 144: DELETE FROM j2_tbl_nsc; +--Testcase 587: DROP FOREIGN TABLE J2_TBL; +--Testcase 588: DROP FOREIGN TABLE j2_tbl_nsc; +--Testcase 589: DELETE FROM x_nsc; +--Testcase 590: DELETE FROM y_nsc; +--Testcase 591: DROP FOREIGN TABLE x_nsc; +--Testcase 592: DROP FOREIGN TABLE y_nsc; -- Both DELETE and UPDATE allow the specification of additional tables -- to "join" against to determine which rows should be modified. ---Testcase 135: +--Testcase 145: CREATE FOREIGN TABLE t1 (fields jsonb OPTIONS (fields 'true')) SERVER influxdb_svr OPTIONS(schemaless 'true'); +--Testcase 593: CREATE FOREIGN TABLE t1_nsc (a int, b int) SERVER influxdb_svr OPTIONS (table 't1'); ---Testcase 136: +--Testcase 146: CREATE FOREIGN TABLE t2 (fields jsonb OPTIONS (fields 'true')) SERVER influxdb_svr OPTIONS(schemaless 'true'); +--Testcase 594: CREATE FOREIGN TABLE t2_nsc (a int, b int) SERVER influxdb_svr OPTIONS (table 't2'); ---Testcase 137: +--Testcase 147: CREATE FOREIGN TABLE t3 (fields jsonb OPTIONS (fields 'true')) SERVER influxdb_svr OPTIONS(schemaless 'true'); +--Testcase 595: CREATE FOREIGN TABLE t3_nsc (x int, y int) SERVER influxdb_svr OPTIONS (table 't3'); ---Testcase 138: +--Testcase 148: INSERT INTO t1_nsc VALUES (5, 10); ---Testcase 139: +--Testcase 149: INSERT INTO t1_nsc VALUES (15, 20); ---Testcase 140: +--Testcase 150: INSERT INTO t1_nsc VALUES (100, 100); ---Testcase 141: +--Testcase 151: INSERT INTO t1_nsc VALUES (200, 1000); ---Testcase 142: +--Testcase 152: INSERT INTO t2_nsc VALUES (200, 2000); ---Testcase 143: +--Testcase 153: INSERT INTO t3_nsc VALUES (5, 20); ---Testcase 144: +--Testcase 154: INSERT INTO t3_nsc VALUES (6, 7); ---Testcase 145: +--Testcase 155: INSERT INTO t3_nsc VALUES (7, 8); ---Testcase 146: +--Testcase 156: INSERT INTO t3_nsc VALUES (500, 100); ---Testcase 147: +--Testcase 157: ALTER TABLE t3 ADD time timestamp; ALTER TABLE t3_nsc ADD time timestamp; ---Testcase 148: +--Testcase 158: SELECT (fields->>'x')::int x, (fields->>'y')::int y FROM t3; x | y -----+----- @@ -2381,9 +2859,9 @@ SELECT (fields->>'x')::int x, (fields->>'y')::int y FROM t3; 500 | 100 (4 rows) ---Testcase 149: +--Testcase 159: DELETE FROM t3_nsc USING t1_nsc table1 WHERE t3_nsc.x = table1.a; ---Testcase 150: +--Testcase 160: SELECT (fields->>'x')::int x, (fields->>'y')::int y FROM t3; x | y -----+----- @@ -2392,9 +2870,9 @@ SELECT (fields->>'x')::int x, (fields->>'y')::int y FROM t3; 500 | 100 (3 rows) ---Testcase 151: +--Testcase 161: DELETE FROM t3_nsc USING t1_nsc JOIN t2_nsc USING (a) WHERE t3_nsc.x > t1_nsc.a; ---Testcase 152: +--Testcase 162: SELECT (fields->>'x')::int x, (fields->>'y')::int y FROM t3; x | y ---+--- @@ -2402,20 +2880,20 @@ SELECT (fields->>'x')::int x, (fields->>'y')::int y FROM t3; 7 | 8 (2 rows) ---Testcase 153: +--Testcase 163: DELETE FROM t3_nsc USING t3_nsc t3_other WHERE t3_nsc.x = t3_other.x AND t3_nsc.y = t3_other.y; ---Testcase 154: +--Testcase 164: SELECT (fields->>'x')::int x, (fields->>'y')::int y FROM t3; x | y ---+--- (0 rows) -- Test join against inheritance tree ---Testcase 155: +--Testcase 165: create temp table t2a () inherits (t2); ---Testcase 156: +--Testcase 166: insert into t2a values ('{"a": "200", "b": "2001"}'); ---Testcase 157: +--Testcase 167: select * from (select (fields->>'a')::int a, (fields->>'b')::int b from t1) t1 left join (select (fields->>'a')::int a, (fields->>'b')::int b from t2) t2 on (t1.a::int = t2.a::int); a | b | a | b -----+------+-----+------ @@ -2427,13 +2905,14 @@ select * from (select (fields->>'a')::int a, (fields->>'b')::int b from t1) t1 l (5 rows) -- Test matching of column name with wrong alias ---Testcase 158: +--Testcase 168: select t1.x from (select (fields->>'a')::int a, (fields->>'b')::int b from t1) t1 join (select (fields->>'x')::int x, (fields->>'y')::int y from t3) t3 on (t1.a::int = t3.x::int); ERROR: column t1.x does not exist LINE 1: select t1.x from (select (fields->>'a')::int a, (fields->>'b... ^ HINT: Perhaps you meant to reference the column "t3.x". -- Test matching of locking clause with wrong alias +--Testcase 666: select t1.*, t2.*, unnamed_join.* from (select (fields->>'a')::int a, (fields->>'b')::int b from t1) t1 join (select (fields->>'a')::int a, (fields->>'b')::int b from t2) t2 on (t1.a::int = t2.a::int), t3 as unnamed_join for update of unnamed_join; @@ -2441,29 +2920,60 @@ select t1.*, t2.*, unnamed_join.* from ---+---+---+---+--------+------ (0 rows) +--Testcase 667: +select foo.*, unnamed_join.* from + (select (fields->>'a')::int a, (fields->>'b')::int b from t1) t1 join (select (fields->>'a')::int a, (fields->>'b')::int b from t2) t2 using (a) as foo, t3 as unnamed_join + for update of unnamed_join; + a | fields | time +---+--------+------ +(0 rows) + +--Testcase 668: +select foo.*, unnamed_join.* from + (select (fields->>'a')::int a, (fields->>'b')::int b from t1) t1 join (select (fields->>'a')::int a, (fields->>'b')::int b from t2) t2 using (a) as foo, t3 as unnamed_join + for update of foo; +ERROR: FOR UPDATE cannot be applied to a join +LINE 3: for update of foo; + ^ +--Testcase 669: +select bar.*, unnamed_join.* from + ((select (fields->>'a')::int a, (fields->>'b')::int b from t1) t1 join (select (fields->>'a')::int a, (fields->>'b')::int b from t2) t2 using (a) as foo) as bar, t3 as unnamed_join + for update of foo; +ERROR: relation "foo" in FOR UPDATE clause not found in FROM clause +LINE 3: for update of foo; + ^ +--Testcase 670: +select bar.*, unnamed_join.* from + ((select (fields->>'a')::int a, (fields->>'b')::int b from t1) t1 join (select (fields->>'a')::int a, (fields->>'b')::int b from t2) t2 using (a) as foo) as bar, t3 as unnamed_join + for update of bar; +ERROR: FOR UPDATE cannot be applied to a join +LINE 3: for update of bar; + ^ -- -- regression test for 8.1 merge right join bug -- ---Testcase 159: +--Testcase 169: CREATE FOREIGN TABLE tt1 ( fields jsonb OPTIONS (fields 'true') ) SERVER influxdb_svr OPTIONS(schemaless 'true'); +--Testcase 596: CREATE FOREIGN TABLE tt1_nsc ( tt1_id int4, joincol int4 ) SERVER influxdb_svr OPTIONS (table 'tt1'); ---Testcase 160: +--Testcase 170: INSERT INTO tt1_nsc VALUES (1, 11); ---Testcase 161: +--Testcase 171: INSERT INTO tt1_nsc VALUES (2, NULL); ---Testcase 162: +--Testcase 172: CREATE FOREIGN TABLE tt2 ( fields jsonb OPTIONS (fields 'true') ) SERVER influxdb_svr OPTIONS(schemaless 'true'); +--Testcase 597: CREATE FOREIGN TABLE tt2_nsc ( tt2_id int4, joincol int4 ) SERVER influxdb_svr OPTIONS (table 'tt2'); ---Testcase 163: +--Testcase 173: INSERT INTO tt2_nsc VALUES (21, 11); ---Testcase 164: +--Testcase 174: INSERT INTO tt2_nsc VALUES (22, 11); ---Testcase 165: +--Testcase 175: set enable_hashjoin to off; ---Testcase 166: +--Testcase 176: set enable_nestloop to off; -- these should give the same results ---Testcase 167: +--Testcase 177: select tt1.*, tt2.* from (select (fields->>'tt1_id')::int4 tt1_id, (fields->>'joincol')::int4 joincol from tt1) tt1 left join (select (fields->>'tt2_id')::int4 tt2_id, (fields->>'joincol')::int4 joincol from tt2) tt2 on tt1.joincol::int4 = tt2.joincol::int4; tt1_id | joincol | tt2_id | joincol --------+---------+--------+--------- @@ -2472,7 +2982,7 @@ select tt1.*, tt2.* from (select (fields->>'tt1_id')::int4 tt1_id, (fields->>'jo 2 | | | (3 rows) ---Testcase 168: +--Testcase 178: select tt1.*, tt2.* from (select (fields->>'tt2_id')::int4 tt2_id, (fields->>'joincol')::int4 joincol from tt2) tt2 right join (select (fields->>'tt1_id')::int4 tt1_id, (fields->>'joincol')::int4 joincol from tt1) tt1 on tt1.joincol::int4 = tt2.joincol::int4; tt1_id | joincol | tt2_id | joincol --------+---------+--------+--------- @@ -2481,18 +2991,20 @@ select tt1.*, tt2.* from (select (fields->>'tt2_id')::int4 tt2_id, (fields->>'jo 2 | | | (3 rows) ---Testcase 169: +--Testcase 179: reset enable_hashjoin; ---Testcase 170: +--Testcase 180: reset enable_nestloop; -- -- regression test for bug #13908 (hash join with skew tuples & nbatch increase) -- ---Testcase 171: +--Testcase 181: set work_mem to '64kB'; ---Testcase 172: +--Testcase 182: set enable_mergejoin to off; ---Testcase 173: +--Testcase 183: +set enable_memoize to off; +--Testcase 184: explain (costs off) select count(*) from tenk1 a, tenk1 b where ((a.fields->>'hundred')::int4 = (b.fields->>'thousand')::int4) and ((b.fields->>'fivethous')::int4 % 10) < 10; @@ -2506,7 +3018,7 @@ select count(*) from tenk1 a, tenk1 b -> Foreign Scan on tenk1 b (6 rows) ---Testcase 174: +--Testcase 185: select count(*) from tenk1 a, tenk1 b where ((a.fields->>'hundred')::int4 = (b.fields->>'thousand')::int4) and ((b.fields->>'fivethous')::int4 % 10) < 10; count @@ -2514,32 +3026,67 @@ select count(*) from tenk1 a, tenk1 b 100000 (1 row) ---Testcase 175: +--Testcase 186: reset work_mem; ---Testcase 176: +--Testcase 187: reset enable_mergejoin; +--Testcase 188: +reset enable_memoize; -- -- regression test for 8.2 bug with improper re-ordering of left joins -- ---Testcase 177: +--Testcase 189: create foreign table tt3(fields jsonb OPTIONS (fields 'true')) server influxdb_svr OPTIONS(schemaless 'true'); +--Testcase 598: create foreign table tt3_nsc(f1 int, f2 text) server influxdb_svr OPTIONS (table 'tt3'); ---Testcase 178: +--Testcase 190: insert into tt3_nsc select x, repeat('xyzzy', 100) from generate_series(1,10000) x; ---Testcase 179: +--Testcase 191: create foreign table tt4(fields jsonb OPTIONS (fields 'true')) server influxdb_svr OPTIONS(schemaless 'true'); +--Testcase 599: create foreign table tt4_nsc(f1 int) server influxdb_svr OPTIONS (table 'tt4'); ---Testcase 180: +--Testcase 192: insert into tt4_nsc values (0),(1),(9999); ---Testcase 181: -SELECT (a.fields->>'f1')::int f1 +set enable_nestloop to off; +EXPLAIN (COSTS OFF) +SELECT (a.fields->>'f1')::int4 as f1 FROM tt4 a LEFT JOIN ( - SELECT (b.fields->>'f1')::int f1 - FROM tt3 b LEFT JOIN tt3 c ON ((b.fields->>'f1')::int = (c.fields->>'f1')::int) - WHERE c.fields->>'f1' IS NULL -) AS d ON ((a.fields->>'f1')::int = (d.f1)::int) -WHERE d.f1 IS NULL; + SELECT (b.fields->>'f1')::int4 as f1 + FROM tt3 b LEFT JOIN tt3 c ON ((b.fields->>'f1')::int4 = (c.fields->>'f1')::int4) + WHERE COALESCE((c.fields->>'f1')::int4, 0) = 0 +) AS d ON ((a.fields->>'f1')::int4 = d.f1) +WHERE COALESCE(d.f1, 0) = 0 +ORDER BY 1; + QUERY PLAN +------------------------------------------------------------------------------------------------------------- + Merge Left Join + Merge Cond: ((((a.fields ->> 'f1'::text))::integer) = ((b.fields ->> 'f1'::text))::integer) + Filter: (COALESCE((((b.fields ->> 'f1'::text))::integer), 0) = 0) + -> Sort + Sort Key: (((a.fields ->> 'f1'::text))::integer) + -> Foreign Scan on tt4 a + -> Materialize + -> Merge Left Join + Merge Cond: ((((b.fields ->> 'f1'::text))::integer) = (((c.fields ->> 'f1'::text))::integer)) + Filter: (COALESCE(((c.fields ->> 'f1'::text))::integer, 0) = 0) + -> Sort + Sort Key: (((b.fields ->> 'f1'::text))::integer) + -> Foreign Scan on tt3 b + -> Sort + Sort Key: (((c.fields ->> 'f1'::text))::integer) + -> Foreign Scan on tt3 c +(16 rows) + +SELECT (a.fields->>'f1')::int4 as f1 +FROM tt4 a +LEFT JOIN ( + SELECT (b.fields->>'f1')::int4 as f1 + FROM tt3 b LEFT JOIN tt3 c ON ((b.fields->>'f1')::int4 = (c.fields->>'f1')::int4) + WHERE COALESCE((c.fields->>'f1')::int4, 0) = 0 +) AS d ON ((a.fields->>'f1')::int4 = d.f1) +WHERE COALESCE(d.f1, 0) = 0 +ORDER BY 1; f1 ------ 0 @@ -2547,12 +3094,84 @@ WHERE d.f1 IS NULL; 9999 (3 rows) +reset enable_nestloop; +-- +-- basic semijoin and antijoin recognition tests +-- +explain (costs off) +select a.* from tenk1 a +where (a.fields->>'unique1')::int4 in (select (b.fields->>'unique2')::int4 from tenk1 b); + QUERY PLAN +------------------------------------------------------------------------------------------------------ + Hash Join + Hash Cond: (((a.fields ->> 'unique1'::text))::integer = ((b.fields ->> 'unique2'::text))::integer) + -> Foreign Scan on tenk1 a + -> Hash + -> HashAggregate + Group Key: ((b.fields ->> 'unique2'::text))::integer + -> Foreign Scan on tenk1 b +(7 rows) + +-- sadly, this is not an antijoin +explain (costs off) +select a.* from tenk1 a +where (a.fields->>'unique1')::int4 not in (select (b.fields->>'unique2')::int4 from tenk1 b); + QUERY PLAN +------------------------------------ + Foreign Scan on tenk1 a + Filter: (NOT (hashed SubPlan 1)) + SubPlan 1 + -> Foreign Scan on tenk1 b +(4 rows) + +explain (costs off) +select a.* from tenk1 a +where exists (select 1 from tenk1 b where (a.fields->>'unique1')::int4 = (b.fields->>'unique2')::int4); + QUERY PLAN +------------------------------------------------------------------------------------------------------ + Hash Join + Hash Cond: (((a.fields ->> 'unique1'::text))::integer = ((b.fields ->> 'unique2'::text))::integer) + -> Foreign Scan on tenk1 a + -> Hash + -> HashAggregate + Group Key: ((b.fields ->> 'unique2'::text))::integer + -> Foreign Scan on tenk1 b +(7 rows) + +explain (costs off) +select a.* from tenk1 a +where not exists (select 1 from tenk1 b where (a.fields->>'unique1')::int4 = (b.fields->>'unique2')::int4); + QUERY PLAN +------------------------------------------------------------------------------------------------------ + Hash Anti Join + Hash Cond: (((a.fields ->> 'unique1'::text))::integer = ((b.fields ->> 'unique2'::text))::integer) + -> Foreign Scan on tenk1 a + -> Hash + -> Foreign Scan on tenk1 b +(5 rows) + +explain (costs off) +select a.* from tenk1 a left join tenk1 b on (a.fields->>'unique1')::int4 = (b.fields->>'unique2')::int4 +where (b.fields->>'unique2')::int4 is null; + QUERY PLAN +----------------------------------------------------------------------------------------------------------- + Merge Left Join + Merge Cond: ((((a.fields ->> 'unique1'::text))::integer) = (((b.fields ->> 'unique2'::text))::integer)) + Filter: (((b.fields ->> 'unique2'::text))::integer IS NULL) + -> Sort + Sort Key: (((a.fields ->> 'unique1'::text))::integer) + -> Foreign Scan on tenk1 a + -> Sort + Sort Key: (((b.fields ->> 'unique2'::text))::integer) + -> Foreign Scan on tenk1 b +(9 rows) + -- -- regression test for proper handling of outer joins within antijoins -- ---Testcase 182: +--Testcase 194: create foreign table tt4x(fields jsonb OPTIONS (fields 'true')) server influxdb_svr OPTIONS(schemaless 'true'); ---Testcase 183: +--Testcase 195: explain (costs off) select * from tt4x t1 where not exists ( @@ -2594,23 +3213,25 @@ where not exists ( -- -- regression test for problems of the sort depicted in bug #3494 -- ---Testcase 184: +--Testcase 196: create foreign table tt5(fields jsonb OPTIONS (fields 'true')) server influxdb_svr OPTIONS(schemaless 'true'); +--Testcase 600: create foreign table tt5_nsc(f1 int, f2 int) server influxdb_svr OPTIONS (table 'tt5'); ---Testcase 185: +--Testcase 197: create foreign table tt6(fields jsonb OPTIONS (fields 'true')) server influxdb_svr OPTIONS(schemaless 'true'); +--Testcase 601: create foreign table tt6_nsc(f1 int, f2 int) server influxdb_svr OPTIONS (table 'tt6'); ---Testcase 186: +--Testcase 198: insert into tt5_nsc values(1, 10); ---Testcase 187: +--Testcase 199: insert into tt5_nsc values(1, 11); ---Testcase 188: +--Testcase 200: insert into tt6_nsc values(1, 9); ---Testcase 189: +--Testcase 201: insert into tt6_nsc values(1, 2); ---Testcase 190: +--Testcase 202: insert into tt6_nsc values(2, 9); ---Testcase 191: +--Testcase 203: select * from (select (fields->>'f1')::int f1, (fields->>'f2')::int f2 from tt5) tt5,(select (fields->>'f1')::int f1, (fields->>'f2')::int f2 from tt6) tt6 where (tt5.f1)::int = (tt6.f1)::int and (tt5.f1)::int = (tt5.f2)::int - (tt6.f2)::int; f1 | f2 | f1 | f2 ----+----+----+---- @@ -2620,25 +3241,27 @@ select * from (select (fields->>'f1')::int f1, (fields->>'f2')::int f2 from tt5) -- -- regression test for problems of the sort depicted in bug #3588 -- ---Testcase 192: +--Testcase 204: create foreign table xx (fields jsonb OPTIONS (fields 'true')) server influxdb_svr OPTIONS(schemaless 'true'); +--Testcase 602: create foreign table xx_nsc (pkxx int) server influxdb_svr OPTIONS (table 'xx'); ---Testcase 193: +--Testcase 205: create foreign table yy (fields jsonb OPTIONS (fields 'true')) server influxdb_svr OPTIONS(schemaless 'true'); +--Testcase 603: create foreign table yy_nsc (pkyy int, pkxx int) server influxdb_svr OPTIONS (table 'yy'); ---Testcase 194: +--Testcase 206: insert into xx_nsc values (1); ---Testcase 195: +--Testcase 207: insert into xx_nsc values (2); ---Testcase 196: +--Testcase 208: insert into xx_nsc values (3); ---Testcase 197: +--Testcase 209: insert into yy_nsc values (101, 1); ---Testcase 198: +--Testcase 210: insert into yy_nsc values (201, 2); ---Testcase 199: +--Testcase 211: insert into yy_nsc values (301, NULL); ---Testcase 200: +--Testcase 212: select (yy.fields->>'pkyy')::int as yy_pkyy, (yy.fields->>'pkxx')::int as yy_pkxx, (yya.fields->>'pkyy')::int as yya_pkyy, (xxa.fields->>'pkxx')::int as xxa_pkxx, (xxb.fields->>'pkxx')::int as xxb_pkxx from yy @@ -2656,19 +3279,21 @@ from yy -- regression test for improper pushing of constants across outer-join clauses -- (as seen in early 8.2.x releases) -- ---Testcase 201: +--Testcase 213: create foreign table zt1 (fields jsonb OPTIONS (fields 'true')) server influxdb_svr OPTIONS(schemaless 'true'); +--Testcase 604: create foreign table zt1_nsc (f1 int) server influxdb_svr OPTIONS (table 'zt1'); ---Testcase 202: +--Testcase 214: create foreign table zt2 (fields jsonb OPTIONS (fields 'true')) server influxdb_svr OPTIONS(schemaless 'true'); +--Testcase 605: create foreign table zt2_nsc (f2 int) server influxdb_svr OPTIONS (table 'zt2'); ---Testcase 203: +--Testcase 215: create foreign table zt3 (fields jsonb OPTIONS (fields 'true')) server influxdb_svr OPTIONS(schemaless 'true'); ---Testcase 204: +--Testcase 216: insert into zt1_nsc values(53); ---Testcase 205: +--Testcase 217: insert into zt2_nsc values(53); ---Testcase 206: +--Testcase 218: select * from (select (fields->>'f2')::int f2 from zt2) zt2 left join (select (fields->>'f3')::int f3 from zt3) zt3 on (f2::int = f3::int) left join (select (fields->>'f1')::int f1 from zt1) zt1 on (f3::int = f1::int) @@ -2678,9 +3303,9 @@ where (f2)::int = 53; 53 | | (1 row) ---Testcase 207: +--Testcase 219: create temp view zv1 as select *,'dummy'::text AS junk from zt1; ---Testcase 208: +--Testcase 220: select * from (select (fields->>'f2')::int f2 from zt2) zt2 left join (select (fields->>'f3')::int f3 from zt3) zt3 on (f2::int = f3::int) left join zv1 on (f3::int = (zv1.fields->>'f1')::int) @@ -2694,7 +3319,7 @@ where (f2)::int = 53; -- regression test for improper extraction of OR indexqual conditions -- (as seen in early 8.3.x releases) -- ---Testcase 209: +--Testcase 221: select a.unique2, a.ten, b.tenthous, b.unique2, b.hundred from (select (fields->>'unique1')::int4 unique1, (fields->>'unique2')::int4 unique2, (fields->>'two')::int4 two, (fields->>'four')::int4 four, (fields->>'ten')::int4 ten, (fields->>'twenty')::int4 twenty, (fields->>'hundred')::int4 hundred, (fields->>'thousand')::int4 thousand, (fields->>'twothousand')::int4 twothousand, (fields->>'fivethous')::int4 fivethous, (fields->>'tenthous')::int4 tenthous, (fields->>'odd')::int4 odd, (fields->>'even')::int4 even, (fields->>'stringu1')::name stringu1, (fields->>'stringu2')::name stringu2, (fields->>'string4')::name string4 from tenk1) a left join (select (fields->>'unique1')::int4 unique1, (fields->>'unique2')::int4 unique2, (fields->>'two')::int4 two, (fields->>'four')::int4 four, (fields->>'ten')::int4 ten, (fields->>'twenty')::int4 twenty, (fields->>'hundred')::int4 hundred, (fields->>'thousand')::int4 thousand, (fields->>'twothousand')::int4 twothousand, (fields->>'fivethous')::int4 fivethous, (fields->>'tenthous')::int4 tenthous, (fields->>'odd')::int4 odd, (fields->>'even')::int4 even, (fields->>'stringu1')::name stringu1, (fields->>'stringu2')::name stringu2, (fields->>'string4')::name string4 from tenk1) b on a.unique2 = b.tenthous where (a.unique1)::int4 = 42 and @@ -2706,19 +3331,19 @@ where (a.unique1)::int4 = 42 and -- -- test proper positioning of one-time quals in EXISTS (8.4devel bug) -- ---Testcase 210: +--Testcase 222: prepare foo(bool) as select count(*) from (select (fields->>'unique1')::int4 unique1, (fields->>'unique2')::int4 unique2, (fields->>'two')::int4 two, (fields->>'four')::int4 four, (fields->>'ten')::int4 ten, (fields->>'twenty')::int4 twenty, (fields->>'hundred')::int4 hundred, (fields->>'thousand')::int4 thousand, (fields->>'twothousand')::int4 twothousand, (fields->>'fivethous')::int4 fivethous, (fields->>'tenthous')::int4 tenthous, (fields->>'odd')::int4 odd, (fields->>'even')::int4 even, (fields->>'stringu1')::name stringu1, (fields->>'stringu2')::name stringu2, (fields->>'string4')::name string4 from tenk1) a left join (select (fields->>'unique1')::int4 unique1, (fields->>'unique2')::int4 unique2, (fields->>'two')::int4 two, (fields->>'four')::int4 four, (fields->>'ten')::int4 ten, (fields->>'twenty')::int4 twenty, (fields->>'hundred')::int4 hundred, (fields->>'thousand')::int4 thousand, (fields->>'twothousand')::int4 twothousand, (fields->>'fivethous')::int4 fivethous, (fields->>'tenthous')::int4 tenthous, (fields->>'odd')::int4 odd, (fields->>'even')::int4 even, (fields->>'stringu1')::name stringu1, (fields->>'stringu2')::name stringu2, (fields->>'string4')::name string4 from tenk1) b on ((a.unique2)::int4 = (b.unique1)::int4 and exists (select 1 from (select (fields->>'unique1')::int4 unique1, (fields->>'unique2')::int4 unique2, (fields->>'two')::int4 two, (fields->>'four')::int4 four, (fields->>'ten')::int4 ten, (fields->>'twenty')::int4 twenty, (fields->>'hundred')::int4 hundred, (fields->>'thousand')::int4 thousand, (fields->>'twothousand')::int4 twothousand, (fields->>'fivethous')::int4 fivethous, (fields->>'tenthous')::int4 tenthous, (fields->>'odd')::int4 odd, (fields->>'even')::int4 even, (fields->>'stringu1')::name stringu1, (fields->>'stringu2')::name stringu2, (fields->>'string4')::name string4 from tenk1) c where (c.thousand)::int4 = (b.unique2)::int4 and $1)); ---Testcase 211: +--Testcase 223: execute foo(true); count ------- 10000 (1 row) ---Testcase 212: +--Testcase 224: execute foo(false); count ------- @@ -2729,38 +3354,38 @@ execute foo(false); -- test for sane behavior with noncanonical merge clauses, per bug #4926 -- begin; ---Testcase 213: +--Testcase 225: set enable_mergejoin = 1; ---Testcase 214: +--Testcase 226: set enable_hashjoin = 0; ---Testcase 215: +--Testcase 227: set enable_nestloop = 0; ---Testcase 216: +--Testcase 228: create foreign table a (fields jsonb OPTIONS (fields 'true')) server influxdb_svr OPTIONS(schemaless 'true'); ---Testcase 217: +--Testcase 229: create foreign table b (fields jsonb OPTIONS (fields 'true')) server influxdb_svr OPTIONS(schemaless 'true'); ---Testcase 218: +--Testcase 230: select * from (select (fields->>'i')::int i from a) a left join (select (fields->>'x')::int x, (fields->>'y')::int y from b) b on i::int = x::int and i::int = y::int and x::int = i::int; i | x | y ---+---+--- (0 rows) ---Testcase 219: +--Testcase 231: DROP FOREIGN TABLE a; ---Testcase 220: +--Testcase 232: DROP FOREIGN TABLE b; rollback; -- -- test handling of merge clauses using record_ops -- begin; ---Testcase 221: +--Testcase 233: create type mycomptype as (id int, v bigint); ---Testcase 222: +--Testcase 234: create temp table tidv (idv mycomptype); ---Testcase 223: +--Testcase 235: create index on tidv (idv); ---Testcase 224: +--Testcase 236: explain (costs off) select a.idv, b.idv from tidv a, tidv b where a.idv = b.idv; QUERY PLAN @@ -2772,11 +3397,11 @@ select a.idv, b.idv from tidv a, tidv b where a.idv = b.idv; -> Index Only Scan using tidv_idv_idx on tidv b (5 rows) ---Testcase 225: +--Testcase 237: set enable_mergejoin = 0; ---Testcase 226: +--Testcase 238: set enable_hashjoin = 0; ---Testcase 227: +--Testcase 239: explain (costs off) select a.idv, b.idv from tidv a, tidv b where a.idv = b.idv; QUERY PLAN @@ -2791,7 +3416,7 @@ rollback; -- -- test NULL behavior of whole-row Vars, per bug #5025 -- ---Testcase 228: +--Testcase 240: select t1.q2, count(t2.*) from (select (fields->>'q1')::int8 q1, (fields->>'q2')::int8 q2 from INT8_TBL) t1 left join (select (fields->>'q1')::int8 q1, (fields->>'q2')::int8 q2 from INT8_TBL) t2 on (t1.q2 = t2.q1) group by t1.q2 order by 1; @@ -2803,7 +3428,7 @@ group by t1.q2 order by 1; 4567890123456789 | 6 (4 rows) ---Testcase 229: +--Testcase 241: select (t1.fields->>'q2')::int8 q2, count(t2.*) from int8_tbl t1 left join (select * from int8_tbl) t2 on ((t1.fields->>'q2')::int8 = (t2.fields->>'q1')::int8) group by t1.fields->>'q2' order by 1; @@ -2815,7 +3440,7 @@ group by t1.fields->>'q2' order by 1; 4567890123456789 | 6 (4 rows) ---Testcase 230: +--Testcase 242: select (t1.fields->>'q2')::int8 q2, count(t2.*) from int8_tbl t1 left join (select * from int8_tbl offset 0) t2 on ((t1.fields->>'q2')::int8 = (t2.fields->>'q1')::int8) group by t1.fields->>'q2' order by 1; @@ -2827,7 +3452,7 @@ group by t1.fields->>'q2' order by 1; 4567890123456789 | 6 (4 rows) ---Testcase 231: +--Testcase 243: select (t1.fields->>'q2')::int8 q2, count(t2.*) from int8_tbl t1 left join (select (fields->>'q1')::int8 q1, case when (fields->>'q2')::int8=1 then 1 else (fields->>'q2')::int8 end as q2 from int8_tbl) t2 @@ -2845,44 +3470,47 @@ group by t1.fields->>'q2' order by 1; -- test incorrect failure to NULL pulled-up subexpressions -- begin; ---Testcase 232: +--Testcase 244: create foreign table a ( fields jsonb OPTIONS (fields 'true') ) server influxdb_svr OPTIONS(schemaless 'true'); +--Testcase 606: create foreign table a_nsc ( code char ) server influxdb_svr OPTIONS (table 'a'); ---Testcase 233: +--Testcase 245: create foreign table b ( fields jsonb OPTIONS (fields 'true') ) server influxdb_svr OPTIONS(schemaless 'true'); +--Testcase 607: create foreign table b_nsc ( a char, num integer ) server influxdb_svr OPTIONS (table 'b'); ---Testcase 234: +--Testcase 246: create foreign table c ( fields jsonb OPTIONS (fields 'true') ) server influxdb_svr OPTIONS(schemaless 'true'); +--Testcase 608: create foreign table c_nsc ( name char, a char ) server influxdb_svr OPTIONS (table 'c'); ---Testcase 235: +--Testcase 247: insert into a_nsc (code) values ('p'); ---Testcase 236: +--Testcase 248: insert into a_nsc (code) values ('q'); ---Testcase 237: +--Testcase 249: insert into b_nsc (a, num) values ('p', 1); ---Testcase 238: +--Testcase 250: insert into b_nsc (a, num) values ('p', 2); ---Testcase 239: +--Testcase 251: insert into c_nsc (name, a) values ('A', 'p'); ---Testcase 240: +--Testcase 252: insert into c_nsc (name, a) values ('B', 'q'); ---Testcase 241: +--Testcase 253: insert into c_nsc (name, a) values ('C', null); ---Testcase 242: +--Testcase 254: select c.name, ss.code, ss.b_cnt, ss.const from (select fields->>'name' "name", fields->>'a' a from c) c left join (select a.code, coalesce(b_grp.cnt, 0) as b_cnt, -1 as const @@ -2899,27 +3527,30 @@ order by c.name; C | | | (3 rows) ---Testcase 243: +--Testcase 255: DELETE FROM a_nsc; ---Testcase 244: +--Testcase 256: DELETE FROM b_nsc; ---Testcase 245: +--Testcase 257: DELETE FROM c_nsc; ---Testcase 246: +--Testcase 258: DROP FOREIGN TABLE a; +--Testcase 609: DROP FOREIGN TABLE a_nsc; ---Testcase 247: +--Testcase 259: DROP FOREIGN TABLE b; +--Testcase 610: DROP FOREIGN TABLE b_nsc; ---Testcase 248: +--Testcase 260: DROP FOREIGN TABLE c; +--Testcase 611: DROP FOREIGN TABLE c_nsc; rollback; -- -- test incorrect handling of placeholders that only appear in targetlists, -- per bug #6154 -- ---Testcase 249: +--Testcase 261: SELECT * FROM ( SELECT 1 as key1 ) sub1 LEFT JOIN @@ -2941,7 +3572,7 @@ ON sub1.key1 = sub2.key3; (1 row) -- test the path using join aliases, too ---Testcase 250: +--Testcase 262: SELECT * FROM ( SELECT 1 as key1 ) sub1 LEFT JOIN @@ -2965,7 +3596,7 @@ ON sub1.key1 = sub2.key3; -- -- test case where a PlaceHolderVar is used as a nestloop parameter -- ---Testcase 251: +--Testcase 263: EXPLAIN (COSTS OFF) SELECT qq, (fields->>'unique1')::int4 unique1 FROM @@ -2993,7 +3624,7 @@ SELECT qq, (fields->>'unique1')::int4 unique1 -> Foreign Scan on int8_tbl b (15 rows) ---Testcase 252: +--Testcase 264: SELECT qq, (fields->>'unique1')::int4 unique1 FROM ( SELECT COALESCE((fields->>'q1')::int8, 0) AS qq FROM int8_tbl a ) AS ss1 @@ -3011,53 +3642,56 @@ SELECT qq, (fields->>'unique1')::int4 unique1 -- -- nested nestloops can require nested PlaceHolderVars -- ---Testcase 253: +--Testcase 265: create foreign table nt1 ( fields jsonb OPTIONS (fields 'true') ) server influxdb_svr OPTIONS(schemaless 'true'); +--Testcase 612: create foreign table nt1_nsc ( id int, a1 boolean, a2 boolean ) server influxdb_svr OPTIONS (table 'nt1'); ---Testcase 254: +--Testcase 266: create foreign table nt2 ( fields jsonb OPTIONS (fields 'true') ) server influxdb_svr OPTIONS(schemaless 'true'); +--Testcase 613: create foreign table nt2_nsc ( id int, nt1_id int, b1 boolean, b2 boolean ) server influxdb_svr OPTIONS (table 'nt2'); ---Testcase 255: +--Testcase 267: create foreign table nt3 ( fields jsonb OPTIONS (fields 'true') ) server influxdb_svr OPTIONS(schemaless 'true'); +--Testcase 614: create foreign table nt3_nsc ( id int, nt2_id int, c1 boolean ) server influxdb_svr OPTIONS (table 'nt3'); ---Testcase 256: +--Testcase 268: insert into nt1_nsc values (1,true,true); ---Testcase 257: +--Testcase 269: insert into nt1_nsc values (2,true,false); ---Testcase 258: +--Testcase 270: insert into nt1_nsc values (3,false,false); ---Testcase 259: +--Testcase 271: insert into nt2_nsc values (1,1,true,true); ---Testcase 260: +--Testcase 272: insert into nt2_nsc values (2,2,true,false); ---Testcase 261: +--Testcase 273: insert into nt2_nsc values (3,3,false,false); ---Testcase 262: +--Testcase 274: insert into nt3_nsc values (1,1,true); ---Testcase 263: +--Testcase 275: insert into nt3_nsc values (2,2,false); ---Testcase 264: +--Testcase 276: insert into nt3_nsc values (3,3,true); ---Testcase 265: +--Testcase 277: explain (costs off) select (nt3.fields->>'id')::int id from nt3 as nt3 @@ -3084,7 +3718,7 @@ where (nt3.fields->>'id')::int = 1 and ss2.b3; -> Foreign Scan on nt1 (10 rows) ---Testcase 266: +--Testcase 278: select (nt3.fields->>'id')::int id from nt3 as nt3 left join @@ -3104,7 +3738,7 @@ where (nt3.fields->>'id')::int = 1 and ss2.b3; -- -- test case where a PlaceHolderVar is propagated into a subquery -- ---Testcase 267: +--Testcase 279: explain (costs off) select * from (select (fields->>'q1')::int8 q1, (fields->>'q2')::int8 q2 from INT8_TBL t1) t1 left join @@ -3133,7 +3767,7 @@ order by 1,2; -> Foreign Scan on int8_tbl t3 (16 rows) ---Testcase 268: +--Testcase 280: select * from (select (fields->>'q1')::int8 q1, (fields->>'q2')::int8 q2 from INT8_TBL t1) t1 left join (select q1 as x, 42 as y from (select (fields->>'q1')::int8 q1, (fields->>'q2')::int8 q2 from INT8_TBL t2) t2) ss @@ -3156,7 +3790,7 @@ order by 1,2; -- -- variant where a PlaceHolderVar is needed at a join, but not above the join -- ---Testcase 269: +--Testcase 281: explain (costs off) select * from (select (fields->>'f1')::int4 f1 from INT4_TBL i41) as i41, @@ -3168,13 +3802,13 @@ select * from right join (select (fields->>'f1')::int4 f1 from INT4_TBL i43) as i43 on (i43.f1 > 1) where ss1.loc = ss1.lat) as ss2 where i41.f1 > 0; - QUERY PLAN --------------------------------------------------------------------------------------------------------------- + QUERY PLAN +---------------------------------------------------------------------------------------------------------------- Nested Loop -> Nested Loop -> Foreign Scan on int4_tbl i41 -> Nested Loop - Join Filter: (((i41.fields ->> 'f1'::text))::integer = ((i42.fields ->> 'f1'::text))::integer) + Join Filter: ((((i42.fields ->> 'f1'::text))::integer) = ((i41.fields ->> 'f1'::text))::integer) -> Foreign Scan on int8_tbl i81 -> Materialize -> Foreign Scan on int4_tbl i42 @@ -3182,7 +3816,7 @@ where i41.f1 > 0; -> Foreign Scan on int4_tbl i43 (10 rows) ---Testcase 270: +--Testcase 282: select * from (select (fields->>'f1')::int4 f1 from INT4_TBL i41) as i41, lateral @@ -3220,7 +3854,7 @@ where i41.f1 > 0; -- -- test the corner cases FULL JOIN ON TRUE and FULL JOIN ON FALSE -- ---Testcase 271: +--Testcase 283: select * from (select (fields->>'f1')::int4 f1 from INT4_TBL) a full join (select (fields->>'f1')::int4 f1 from INT4_TBL) b on true; f1 | f1 -------------+------------- @@ -3251,7 +3885,7 @@ select * from (select (fields->>'f1')::int4 f1 from INT4_TBL) a full join (selec -2147483647 | -2147483647 (25 rows) ---Testcase 272: +--Testcase 284: select * from (select (fields->>'f1')::int4 f1 from INT4_TBL) a full join (select (fields->>'f1')::int4 f1 from INT4_TBL) b on false; f1 | f1 -------------+------------- @@ -3270,11 +3904,11 @@ select * from (select (fields->>'f1')::int4 f1 from INT4_TBL) a full join (selec -- -- test for ability to use a cartesian join when necessary -- ---Testcase 273: +--Testcase 285: create foreign table q1 (fields jsonb OPTIONS (fields 'true')) server influxdb_svr OPTIONS(schemaless 'true'); ---Testcase 274: +--Testcase 286: create foreign table q2 (fields jsonb OPTIONS (fields 'true')) server influxdb_svr OPTIONS(schemaless 'true'); ---Testcase 275: +--Testcase 287: explain (costs off) select * from (select (fields->>'unique1')::int4 unique1, (fields->>'unique2')::int4 unique2, (fields->>'two')::int4 two, (fields->>'four')::int4 four, (fields->>'ten')::int4 ten, (fields->>'twenty')::int4 twenty, (fields->>'hundred')::int4 hundred, (fields->>'thousand')::int4 thousand, (fields->>'twothousand')::int4 twothousand, (fields->>'fivethous')::int4 fivethous, (fields->>'tenthous')::int4 tenthous, (fields->>'odd')::int4 odd, (fields->>'even')::int4 even, (fields->>'stringu1')::name stringu1, (fields->>'stringu2')::name stringu2, (fields->>'string4')::name string4 from tenk1) tenk1 join (select (fields->>'f1')::int4 f1 from INT4_TBL) INT4_TBL on (f1)::int = (twothousand)::int, @@ -3300,7 +3934,7 @@ where (q1)::int = thousand::int or (q2)::int = thousand::int; -> Foreign Scan on q2 (16 rows) ---Testcase 276: +--Testcase 288: explain (costs off) select * from (select (fields->>'unique1')::int4 unique1, (fields->>'unique2')::int4 unique2, (fields->>'two')::int4 two, (fields->>'four')::int4 four, (fields->>'ten')::int4 ten, (fields->>'twenty')::int4 twenty, (fields->>'hundred')::int4 hundred, (fields->>'thousand')::int4 thousand, (fields->>'twothousand')::int4 twothousand, (fields->>'fivethous')::int4 fivethous, (fields->>'tenthous')::int4 tenthous, (fields->>'odd')::int4 odd, (fields->>'even')::int4 even, (fields->>'stringu1')::name stringu1, (fields->>'stringu2')::name stringu2, (fields->>'string4')::name string4 from tenk1) tenk1 join (select (fields->>'f1')::int4 f1 from INT4_TBL) INT4_TBL on (f1)::int = (twothousand)::int, @@ -3332,7 +3966,7 @@ where (thousand)::int = ((q1)::int + (q2)::int); -- -- test ability to generate a suitable plan for a star-schema query -- ---Testcase 277: +--Testcase 289: explain (costs off) select * from (select (fields->>'unique1')::int4 unique1, (fields->>'unique2')::int4 unique2, (fields->>'two')::int4 two, (fields->>'four')::int4 four, (fields->>'ten')::int4 ten, (fields->>'twenty')::int4 twenty, (fields->>'hundred')::int4 hundred, (fields->>'thousand')::int4 thousand, (fields->>'twothousand')::int4 twothousand, (fields->>'fivethous')::int4 fivethous, (fields->>'tenthous')::int4 tenthous, (fields->>'odd')::int4 odd, (fields->>'even')::int4 even, (fields->>'stringu1')::name stringu1, (fields->>'stringu2')::name stringu2, (fields->>'string4')::name string4 from tenk1 tenk1) tenk1, (select (fields->>'q1')::int8 q1, (fields->>'q2')::int8 q2 from INT8_TBL a) a, (select (fields->>'q1')::int8 q1, (fields->>'q2')::int8 q2 from INT8_TBL b) b @@ -3353,7 +3987,7 @@ where thousand::int4 = a.q1::int8 and tenthous::int4 = b.q1::int8 and a.q2::int8 -- -- test a corner case in which we shouldn't apply the star-schema optimization -- ---Testcase 278: +--Testcase 290: explain (costs off) select (t1.fields->>'unique2')::int4 unique2, (t1.fields->>'stringu1')::name stringu1, (t2.fields->>'unique1')::int4 unique1, (t2.fields->>'stringu2')::name stringu2 from tenk1 t1 @@ -3367,33 +4001,26 @@ select (t1.fields->>'unique2')::int4 unique2, (t1.fields->>'stringu1')::name str left join tenk1 t2 on ((subq1.y1)::int4 = (t2.fields->>'unique1')::int4) where (t1.fields->>'unique2')::int4 < 42 and (t1.fields->>'stringu1')::name > t2.fields->>'stringu2'; - QUERY PLAN ------------------------------------------------------------------------------------------------------- - Merge Join - Merge Cond: ((((t2.fields ->> 'unique1'::text))::integer) = (3)) - Join Filter: ((((t1.fields ->> 'stringu1'::text))::name)::text > (t2.fields ->> 'stringu2'::text)) - -> Sort - Sort Key: (((t2.fields ->> 'unique1'::text))::integer) - -> Foreign Scan on tenk1 t2 - -> Sort - Sort Key: (3) - -> Merge Join - Merge Cond: ((((t1.fields ->> 'unique2'::text))::integer) = (11)) - -> Sort - Sort Key: (((t1.fields ->> 'unique2'::text))::integer) + QUERY PLAN +---------------------------------------------------------------------------------------------------------- + Nested Loop + -> Foreign Scan on int4_tbl i1 + -> Materialize + -> Hash Join + Hash Cond: ((11) = ((t1.fields ->> 'unique2'::text))::integer) + Join Filter: (((t1.fields ->> 'stringu1'::text))::name > (t2.fields ->> 'stringu2'::text)) + -> Nested Loop + -> Seq Scan on onerow + -> Hash Join + Hash Cond: (((t2.fields ->> 'unique1'::text))::integer = (3)) + -> Foreign Scan on tenk1 t2 + -> Hash + -> Seq Scan on onerow onerow_1 + -> Hash -> Foreign Scan on tenk1 t1 - -> Sort - Sort Key: (11) - -> Nested Loop Left Join - Join Filter: (((i1.fields ->> 'f1'::text))::integer = 0) - -> Foreign Scan on int4_tbl i1 - -> Materialize - -> Nested Loop Left Join - -> Seq Scan on onerow - -> Seq Scan on onerow onerow_1 -(22 rows) +(15 rows) ---Testcase 279: +--Testcase 291: select (t1.fields->>'unique2')::int4 unique2, (t1.fields->>'stringu1')::name stringu1, (t2.fields->>'unique1')::int4 unique1, (t2.fields->>'stringu2')::name stringu2 from tenk1 t1 inner join int4_tbl i1 @@ -3412,7 +4039,7 @@ where (t1.fields->>'unique2')::int4 < 42 and (t1.fields->>'stringu1')::name > t2 (1 row) -- variant that isn't quite a star-schema case ---Testcase 280: +--Testcase 292: select ss1.d1 from tenk1 as t1 inner join tenk1 as t2 @@ -3433,7 +4060,7 @@ where (t1.fields->>'unique1')::int4 < (i4.fields->>'f1')::int4; (0 rows) -- this variant is foldable by the remove-useless-RESULT-RTEs code ---Testcase 281: +--Testcase 293: explain (costs off) select (t1.fields->>'unique2')::int4 unique2, (t1.fields->>'stringu1')::name stringu1, (t2.fields->>'unique1')::int4 unique1, (t2.fields->>'stringu2')::name stringu2 from tenk1 t1 @@ -3450,27 +4077,18 @@ where (t1.fields->>'unique2')::int4 < 42 and (t1.fields->>'stringu1')::name > (t QUERY PLAN ------------------------------------------------------------------------------------------------------ Hash Join - Hash Cond: ((11) = ((t1.fields ->> 'unique2'::text))::integer) + Hash Cond: (((t2.fields ->> 'unique1'::text))::integer = (3)) Join Filter: (((t1.fields ->> 'stringu1'::text))::name > ((t2.fields ->> 'stringu2'::text))::name) - -> Nested Loop - Join Filter: ((1) = v2.y2) + -> Foreign Scan on tenk1 t2 + -> Hash -> Hash Join - Hash Cond: (((i1.fields ->> 'f1'::text))::integer = (0)) - -> Foreign Scan on int4_tbl i1 + Hash Cond: (((t1.fields ->> 'unique2'::text))::integer = (11)) + -> Foreign Scan on tenk1 t1 -> Hash - -> Result - -> Materialize - -> Hash Join - Hash Cond: (((t2.fields ->> 'unique1'::text))::integer = v2.y1) - -> Foreign Scan on tenk1 t2 - -> Hash - -> Subquery Scan on v2 - -> Result - -> Hash - -> Foreign Scan on tenk1 t1 -(19 rows) + -> Foreign Scan on int4_tbl i1 +(10 rows) ---Testcase 282: +--Testcase 294: select (t1.fields->>'unique2')::int4 unique2, (t1.fields->>'stringu1')::name stringu1, (t2.fields->>'unique1')::int4 unique1, (t2.fields->>'stringu2')::name stringu2 from tenk1 t1 inner join int4_tbl i1 @@ -3490,28 +4108,24 @@ where (t1.fields->>'unique2')::int4 < 42 and (t1.fields->>'stringu1')::name > (t -- Here's a variant that we can't fold too aggressively, though, -- or we end up with noplace to evaluate the lateral PHV ---Testcase 283: +--Testcase 295: explain (verbose, costs off) select * from (select 1 as x) ss1 left join (select 2 as y) ss2 on (true), lateral (select ss2.y as z limit 1) ss3; - QUERY PLAN ------------------------------ + QUERY PLAN +--------------------------- Nested Loop - Output: (1), (2), ((2)) - -> Nested Loop Left Join - Output: (1), (2) - -> Result - Output: 1 - -> Result - Output: 2 + Output: 1, (2), ((2)) + -> Result + Output: 2 -> Limit Output: ((2)) -> Result Output: (2) -(12 rows) +(8 rows) ---Testcase 284: +--Testcase 296: 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; @@ -3521,7 +4135,7 @@ select * from (1 row) -- Test proper handling of appendrel PHVs during useless-RTE removal ---Testcase 285: +--Testcase 297: explain (costs off) select * from (select 0 as z) as t1 @@ -3535,16 +4149,14 @@ where b; QUERY PLAN --------------------------------------- Nested Loop - -> Nested Loop Left Join - -> Result - -> Result + -> Result -> Append -> Result -> Result One-Time Filter: (true) -(8 rows) +(6 rows) ---Testcase 286: +--Testcase 298: select * from (select 0 as z) as t1 left join @@ -3560,27 +4172,80 @@ where b; 0 | t | t (2 rows) +-- 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 ); + QUERY PLAN +---------------------------- + Result + Output: 1 + One-Time Filter: (1 = 1) +(3 rows) + +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 ); + f1 +---- + 1 +(1 row) + +-- 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; + QUERY PLAN +------------------------------------------------------------------------------------------------------------------- + Result + Output: (current_database())::information_schema.sql_identifier, (c.relname)::information_schema.sql_identifier + One-Time Filter: false +(3 rows) + +-- 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; + QUERY PLAN +-------------------------------------------------- + Nested Loop Left Join + Output: int4_tbl.fields, ('foo'::text) + Filter: (('foo'::text) IS NULL) + -> Foreign Scan on public.int4_tbl + Output: int4_tbl.fields + InfluxDB query: SELECT * FROM "int4_tbl" + -> Materialize + Output: ('foo'::text) + -> Append + -> Result + Output: 'foo'::text + -> Result + Output: 'bar'::text +(13 rows) + -- -- test inlining of immutable functions -- ---Testcase 287: +--Testcase 299: create function f_immutable_int4(i integer) returns integer as $$ begin return i; end; $$ language plpgsql immutable; -- check optimization of function scan with join ---Testcase 288: +--Testcase 300: explain (costs off) select (fields->>'unique1')::int4 unique1 from tenk1, (select * from f_immutable_int4(1) x) x where x = (fields->>'unique1')::int4; - QUERY PLAN --------------------------------------------------------------------- - Hash Join - Hash Cond: (((tenk1.fields ->> 'unique1'::text))::integer = x.x) - -> Foreign Scan on tenk1 - -> Hash - -> Function Scan on x -(5 rows) + QUERY PLAN +----------------------- + Foreign Scan on tenk1 +(1 row) ---Testcase 289: +--Testcase 301: explain (verbose, costs off) select (fields->>'unique1')::int4 unique1, x.* from tenk1, (select *, random() from f_immutable_int4(1) x) x @@ -3588,104 +4253,96 @@ where x = (fields->>'unique1')::int4; QUERY PLAN -------------------------------------------------------------------------- Hash Join - Output: ((tenk1.fields ->> 'unique1'::text))::integer, x.x, (random()) - Hash Cond: (((tenk1.fields ->> 'unique1'::text))::integer = x.x) + Output: ((tenk1.fields ->> 'unique1'::text))::integer, (1), (random()) + Hash Cond: (((tenk1.fields ->> 'unique1'::text))::integer = (1)) -> Foreign Scan on public.tenk1 Output: tenk1.fields InfluxDB query: SELECT * FROM "tenk" -> Hash - Output: x.x, (random()) - -> Function Scan on x - Output: x.x, random() - Function Call: 1 -(11 rows) + Output: (1), (random()) + -> Result + Output: 1, random() +(10 rows) ---Testcase 290: +--Testcase 302: explain (costs off) select (fields->>'unique1')::int4 unique1 from tenk1, f_immutable_int4(1) x where x = (fields->>'unique1')::int4; - QUERY PLAN --------------------------------------------------------------------- - Hash Join - Hash Cond: (((tenk1.fields ->> 'unique1'::text))::integer = x.x) - -> Foreign Scan on tenk1 - -> Hash - -> Function Scan on x -(5 rows) + QUERY PLAN +----------------------- + Foreign Scan on tenk1 +(1 row) ---Testcase 291: +--Testcase 303: explain (costs off) select (fields->>'unique1')::int4 unique1 from tenk1, lateral f_immutable_int4(1) x where x = (fields->>'unique1')::int4; - QUERY PLAN --------------------------------------------------------------------- - Hash Join - Hash Cond: (((tenk1.fields ->> 'unique1'::text))::integer = x.x) - -> Foreign Scan on tenk1 - -> Hash - -> Function Scan on x -(5 rows) + QUERY PLAN +----------------------- + Foreign Scan on tenk1 +(1 row) ---Testcase 292: +--Testcase 569: +explain (costs off) +select (fields->>'unique1')::int4 unique1 from tenk1, lateral f_immutable_int4(1) x where x in (select 17); + QUERY PLAN +-------------------------- + Result + One-Time Filter: false +(2 rows) + +--Testcase 304: explain (costs off) select (fields->>'unique1')::int4 unique1, x from tenk1 join f_immutable_int4(1) x on (fields->>'unique1')::int4 = x; - QUERY PLAN --------------------------------------------------------------------- - Hash Join - Hash Cond: (((tenk1.fields ->> 'unique1'::text))::integer = x.x) - -> Foreign Scan on tenk1 - -> Hash - -> Function Scan on x -(5 rows) + QUERY PLAN +----------------------- + Foreign Scan on tenk1 +(1 row) ---Testcase 293: +--Testcase 305: explain (costs off) select (fields->>'unique1')::int4 unique1, x from tenk1 left join f_immutable_int4(1) x on (fields->>'unique1')::int4 = x; QUERY PLAN -------------------------------------------------------------------- - Hash Left Join - Hash Cond: (((tenk1.fields ->> 'unique1'::text))::integer = x.x) + Nested Loop Left Join + Join Filter: (((tenk1.fields ->> 'unique1'::text))::integer = 1) -> Foreign Scan on tenk1 - -> Hash - -> Function Scan on x + -> Materialize + -> Result (5 rows) ---Testcase 294: +--Testcase 306: explain (costs off) select (fields->>'unique1')::int4 unique1, x from tenk1 right join f_immutable_int4(1) x on (fields->>'unique1')::int4 = x; - QUERY PLAN --------------------------------------------------------------------- - Hash Right Join - Hash Cond: (((tenk1.fields ->> 'unique1'::text))::integer = x.x) + QUERY PLAN +----------------------------- + Nested Loop Left Join + -> Result -> Foreign Scan on tenk1 - -> Hash - -> Function Scan on x -(5 rows) +(3 rows) ---Testcase 295: +--Testcase 307: explain (costs off) select (fields->>'unique1')::int4 unique1, x from tenk1 full join f_immutable_int4(1) x on (fields->>'unique1')::int4 = x; QUERY PLAN -------------------------------------------------------------------- Hash Full Join - Hash Cond: (((tenk1.fields ->> 'unique1'::text))::integer = x.x) + Hash Cond: (((tenk1.fields ->> 'unique1'::text))::integer = (1)) -> Foreign Scan on tenk1 -> Hash - -> Function Scan on x + -> Result (5 rows) -- check that pullup of a const function allows further const-folding ---Testcase 296: +--Testcase 308: explain (costs off) select (fields->>'unique1')::int4 unique1 from tenk1, f_immutable_int4(1) x where x = 42; - QUERY PLAN ------------------------------ - Nested Loop - -> Function Scan on x - Filter: (x = 42) - -> Foreign Scan on tenk1 -(4 rows) + QUERY PLAN +-------------------------- + Result + One-Time Filter: false +(2 rows) -- test inlining of immutable functions with PlaceHolderVars ---Testcase 297: +--Testcase 309: explain (costs off) select (nt3.fields->>'id')::int id from nt3 as nt3 @@ -3702,26 +4359,26 @@ where (nt3.fields->>'id')::int = 1 and (ss2.b3)::boolean; ---------------------------------------------------------------------------------------------------- Hash Right Join Hash Cond: (((nt2.fields ->> 'id'::text))::integer = ((nt3.fields ->> 'nt2_id'::text))::integer) - Filter: ((((nt2.fields ->> 'b1'::text))::boolean OR (i4.i4 = 42))) - -> Hash Left Join - Hash Cond: (((nt2.fields ->> 'nt1_id'::text))::integer = i4.i4) + Filter: ((((nt2.fields ->> 'b1'::text))::boolean OR ((0) = 42))) + -> Nested Loop Left Join + Join Filter: (0 = ((nt2.fields ->> 'nt1_id'::text))::integer) -> Foreign Scan on nt2 - -> Hash - -> Function Scan on i4 + -> Materialize + -> Result -> Hash -> Foreign Scan on nt3 (10 rows) ---Testcase 298: +--Testcase 310: drop function f_immutable_int4(int); -- test inlining when function returns composite ---Testcase 299: +--Testcase 311: create function mki8(bigint, bigint) returns int8_tbl as $$select row('{"q1" : ' || cast($1 as text) || ', "q2" : ' || cast($2 as text) || '}')::int8_tbl$$ language sql; ---Testcase 300: +--Testcase 312: create function mki4(int) returns int4_tbl as $$select row('{"f1" : ' || cast($1 as text) || '}')::int4_tbl$$ language sql; ---Testcase 301: +--Testcase 313: explain (verbose, costs off) select * from mki8(1, 2); QUERY PLAN @@ -3731,14 +4388,14 @@ select * from mki8(1, 2); Function Call: '("{""q1"": 1, ""q2"": 2}")'::int8_tbl (3 rows) ---Testcase 302: +--Testcase 314: select * from mki8(1, 2); fields -------------------- {"q1": 1, "q2": 2} (1 row) ---Testcase 303: +--Testcase 315: explain (verbose, costs off) select * from mki4(42); QUERY PLAN @@ -3748,22 +4405,22 @@ select * from mki4(42); Function Call: '("{""f1"": 42}")'::int4_tbl (3 rows) ---Testcase 304: +--Testcase 316: select * from mki4(42); fields ------------ {"f1": 42} (1 row) ---Testcase 305: +--Testcase 317: drop function mki8(bigint, bigint); ---Testcase 306: +--Testcase 318: drop function mki4(int); -- -- test extraction of restriction OR clauses from join OR clause -- (we used to only do this for indexable clauses) -- ---Testcase 307: +--Testcase 319: explain (costs off) select * from (select (fields->>'unique1')::int4 unique1, (fields->>'unique2')::int4 unique2, (fields->>'two')::int4 two, (fields->>'four')::int4 four, (fields->>'ten')::int4 ten, (fields->>'twenty')::int4 twenty, (fields->>'hundred')::int4 hundred, (fields->>'thousand')::int4 thousand, (fields->>'twothousand')::int4 twothousand, (fields->>'fivethous')::int4 fivethous, (fields->>'tenthous')::int4 tenthous, (fields->>'odd')::int4 odd, (fields->>'even')::int4 even, (fields->>'stringu1')::name stringu1, (fields->>'stringu2')::name stringu2, (fields->>'string4')::name string4 from tenk1 a) a join (select (fields->>'unique1')::int4 unique1, (fields->>'unique2')::int4 unique2, (fields->>'two')::int4 two, (fields->>'four')::int4 four, (fields->>'ten')::int4 ten, (fields->>'twenty')::int4 twenty, (fields->>'hundred')::int4 hundred, (fields->>'thousand')::int4 thousand, (fields->>'twothousand')::int4 twothousand, (fields->>'fivethous')::int4 fivethous, (fields->>'tenthous')::int4 tenthous, (fields->>'odd')::int4 odd, (fields->>'even')::int4 even, (fields->>'stringu1')::name stringu1, (fields->>'stringu2')::name stringu2, (fields->>'string4')::name string4 from tenk1 b) b on ((a.unique1)::int4 = 1 and (b.unique1)::int4 = 2) or ((a.unique2)::int4 = 3 and (b.hundred)::int4 = 4); @@ -3776,7 +4433,7 @@ select * from (select (fields->>'unique1')::int4 unique1, (fields->>'unique2'):: -> Foreign Scan on tenk1 b (5 rows) ---Testcase 308: +--Testcase 320: explain (costs off) select * from (select (fields->>'unique1')::int4 unique1, (fields->>'unique2')::int4 unique2, (fields->>'two')::int4 two, (fields->>'four')::int4 four, (fields->>'ten')::int4 ten, (fields->>'twenty')::int4 twenty, (fields->>'hundred')::int4 hundred, (fields->>'thousand')::int4 thousand, (fields->>'twothousand')::int4 twothousand, (fields->>'fivethous')::int4 fivethous, (fields->>'tenthous')::int4 tenthous, (fields->>'odd')::int4 odd, (fields->>'even')::int4 even, (fields->>'stringu1')::name stringu1, (fields->>'stringu2')::name stringu2, (fields->>'string4')::name string4 from tenk1 a) a join (select (fields->>'unique1')::int4 unique1, (fields->>'unique2')::int4 unique2, (fields->>'two')::int4 two, (fields->>'four')::int4 four, (fields->>'ten')::int4 ten, (fields->>'twenty')::int4 twenty, (fields->>'hundred')::int4 hundred, (fields->>'thousand')::int4 thousand, (fields->>'twothousand')::int4 twothousand, (fields->>'fivethous')::int4 fivethous, (fields->>'tenthous')::int4 tenthous, (fields->>'odd')::int4 odd, (fields->>'even')::int4 even, (fields->>'stringu1')::name stringu1, (fields->>'stringu2')::name stringu2, (fields->>'string4')::name string4 from tenk1 b) b on ((a.unique1)::int4 = 1 and (b.unique1)::int4 = 2) or ((a.unique2)::int4 = 3 and (b.ten)::int4 = 4); @@ -3789,7 +4446,7 @@ select * from (select (fields->>'unique1')::int4 unique1, (fields->>'unique2'):: -> Foreign Scan on tenk1 b (5 rows) ---Testcase 309: +--Testcase 321: explain (costs off) select * from (select (fields->>'unique1')::int4 unique1, (fields->>'unique2')::int4 unique2, (fields->>'two')::int4 two, (fields->>'four')::int4 four, (fields->>'ten')::int4 ten, (fields->>'twenty')::int4 twenty, (fields->>'hundred')::int4 hundred, (fields->>'thousand')::int4 thousand, (fields->>'twothousand')::int4 twothousand, (fields->>'fivethous')::int4 fivethous, (fields->>'tenthous')::int4 tenthous, (fields->>'odd')::int4 odd, (fields->>'even')::int4 even, (fields->>'stringu1')::name stringu1, (fields->>'stringu2')::name stringu2, (fields->>'string4')::name string4 from tenk1 a) a join (select (fields->>'unique1')::int4 unique1, (fields->>'unique2')::int4 unique2, (fields->>'two')::int4 two, (fields->>'four')::int4 four, (fields->>'ten')::int4 ten, (fields->>'twenty')::int4 twenty, (fields->>'hundred')::int4 hundred, (fields->>'thousand')::int4 thousand, (fields->>'twothousand')::int4 twothousand, (fields->>'fivethous')::int4 fivethous, (fields->>'tenthous')::int4 tenthous, (fields->>'odd')::int4 odd, (fields->>'even')::int4 even, (fields->>'stringu1')::name stringu1, (fields->>'stringu2')::name stringu2, (fields->>'string4')::name string4 from tenk1 b) b on ((a.unique1)::int4 = 1 and (b.unique1)::int4 = 2) or @@ -3806,7 +4463,7 @@ select * from (select (fields->>'unique1')::int4 unique1, (fields->>'unique2'):: -- -- test placement of movable quals in a parameterized join tree -- ---Testcase 310: +--Testcase 322: explain (costs off) select * from (select (fields->>'unique1')::int4 unique1, (fields->>'unique2')::int4 unique2, (fields->>'two')::int4 two, (fields->>'four')::int4 four, (fields->>'ten')::int4 ten, (fields->>'twenty')::int4 twenty, (fields->>'hundred')::int4 hundred, (fields->>'thousand')::int4 thousand, (fields->>'twothousand')::int4 twothousand, (fields->>'fivethous')::int4 fivethous, (fields->>'tenthous')::int4 tenthous, (fields->>'odd')::int4 odd, (fields->>'even')::int4 even, (fields->>'stringu1')::name stringu1, (fields->>'stringu2')::name stringu2, (fields->>'string4')::name string4 from tenk1 t1) t1 left join ((select (fields->>'unique1')::int4 unique1, (fields->>'unique2')::int4 unique2, (fields->>'two')::int4 two, (fields->>'four')::int4 four, (fields->>'ten')::int4 ten, (fields->>'twenty')::int4 twenty, (fields->>'hundred')::int4 hundred, (fields->>'thousand')::int4 thousand, (fields->>'twothousand')::int4 twothousand, (fields->>'fivethous')::int4 fivethous, (fields->>'tenthous')::int4 tenthous, (fields->>'odd')::int4 odd, (fields->>'even')::int4 even, (fields->>'stringu1')::name stringu1, (fields->>'stringu2')::name stringu2, (fields->>'string4')::name string4 from tenk1 t2) t2 join (select (fields->>'unique1')::int4 unique1, (fields->>'unique2')::int4 unique2, (fields->>'two')::int4 two, (fields->>'four')::int4 four, (fields->>'ten')::int4 ten, (fields->>'twenty')::int4 twenty, (fields->>'hundred')::int4 hundred, (fields->>'thousand')::int4 thousand, (fields->>'twothousand')::int4 twothousand, (fields->>'fivethous')::int4 fivethous, (fields->>'tenthous')::int4 tenthous, (fields->>'odd')::int4 odd, (fields->>'even')::int4 even, (fields->>'stringu1')::name stringu1, (fields->>'stringu2')::name stringu2, (fields->>'string4')::name string4 from tenk1 t3) t3 on (t2.thousand)::int4 = (t3.unique2)::int4) @@ -3828,7 +4485,7 @@ where (t1.unique1)::int4 = 1; -> Foreign Scan on tenk1 t1 (12 rows) ---Testcase 311: +--Testcase 323: explain (costs off) select * from (select (fields->>'unique1')::int4 unique1, (fields->>'unique2')::int4 unique2, (fields->>'two')::int4 two, (fields->>'four')::int4 four, (fields->>'ten')::int4 ten, (fields->>'twenty')::int4 twenty, (fields->>'hundred')::int4 hundred, (fields->>'thousand')::int4 thousand, (fields->>'twothousand')::int4 twothousand, (fields->>'fivethous')::int4 fivethous, (fields->>'tenthous')::int4 tenthous, (fields->>'odd')::int4 odd, (fields->>'even')::int4 even, (fields->>'stringu1')::name stringu1, (fields->>'stringu2')::name stringu2, (fields->>'string4')::name string4 from tenk1 t1) t1 left join ((select (fields->>'unique1')::int4 unique1, (fields->>'unique2')::int4 unique2, (fields->>'two')::int4 two, (fields->>'four')::int4 four, (fields->>'ten')::int4 ten, (fields->>'twenty')::int4 twenty, (fields->>'hundred')::int4 hundred, (fields->>'thousand')::int4 thousand, (fields->>'twothousand')::int4 twothousand, (fields->>'fivethous')::int4 fivethous, (fields->>'tenthous')::int4 tenthous, (fields->>'odd')::int4 odd, (fields->>'even')::int4 even, (fields->>'stringu1')::name stringu1, (fields->>'stringu2')::name stringu2, (fields->>'string4')::name string4 from tenk1 t2) t2 join (select (fields->>'unique1')::int4 unique1, (fields->>'unique2')::int4 unique2, (fields->>'two')::int4 two, (fields->>'four')::int4 four, (fields->>'ten')::int4 ten, (fields->>'twenty')::int4 twenty, (fields->>'hundred')::int4 hundred, (fields->>'thousand')::int4 thousand, (fields->>'twothousand')::int4 twothousand, (fields->>'fivethous')::int4 fivethous, (fields->>'tenthous')::int4 tenthous, (fields->>'odd')::int4 odd, (fields->>'even')::int4 even, (fields->>'stringu1')::name stringu1, (fields->>'stringu2')::name stringu2, (fields->>'string4')::name string4 from tenk1 t3) t3 on (t2.thousand)::int4 = (t3.unique2)::int4) @@ -3851,7 +4508,7 @@ where (t1.unique1)::int4 = 1; -> Foreign Scan on tenk1 t1 (13 rows) ---Testcase 312: +--Testcase 324: explain (costs off) select count(*) from (select (fields->>'unique1')::int4 unique1, (fields->>'unique2')::int4 unique2, (fields->>'two')::int4 two, (fields->>'four')::int4 four, (fields->>'ten')::int4 ten, (fields->>'twenty')::int4 twenty, (fields->>'hundred')::int4 hundred, (fields->>'thousand')::int4 thousand, (fields->>'twothousand')::int4 twothousand, (fields->>'fivethous')::int4 fivethous, (fields->>'tenthous')::int4 tenthous, (fields->>'odd')::int4 odd, (fields->>'even')::int4 even, (fields->>'stringu1')::name stringu1, (fields->>'stringu2')::name stringu2, (fields->>'string4')::name string4 from tenk1 a) a join (select (fields->>'unique1')::int4 unique1, (fields->>'unique2')::int4 unique2, (fields->>'two')::int4 two, (fields->>'four')::int4 four, (fields->>'ten')::int4 ten, (fields->>'twenty')::int4 twenty, (fields->>'hundred')::int4 hundred, (fields->>'thousand')::int4 thousand, (fields->>'twothousand')::int4 twothousand, (fields->>'fivethous')::int4 fivethous, (fields->>'tenthous')::int4 tenthous, (fields->>'odd')::int4 odd, (fields->>'even')::int4 even, (fields->>'stringu1')::name stringu1, (fields->>'stringu2')::name stringu2, (fields->>'string4')::name string4 from tenk1 b) b on (a.unique1)::int4 = (b.unique2)::int4 @@ -3885,7 +4542,7 @@ select count(*) from -> Foreign Scan on tenk1 c (24 rows) ---Testcase 313: +--Testcase 325: select count(*) from (select (fields->>'unique1')::int4 unique1, (fields->>'unique2')::int4 unique2, (fields->>'two')::int4 two, (fields->>'four')::int4 four, (fields->>'ten')::int4 ten, (fields->>'twenty')::int4 twenty, (fields->>'hundred')::int4 hundred, (fields->>'thousand')::int4 thousand, (fields->>'twothousand')::int4 twothousand, (fields->>'fivethous')::int4 fivethous, (fields->>'tenthous')::int4 tenthous, (fields->>'odd')::int4 odd, (fields->>'even')::int4 even, (fields->>'stringu1')::name stringu1, (fields->>'stringu2')::name stringu2, (fields->>'string4')::name string4 from tenk1 a) a join (select (fields->>'unique1')::int4 unique1, (fields->>'unique2')::int4 unique2, (fields->>'two')::int4 two, (fields->>'four')::int4 four, (fields->>'ten')::int4 ten, (fields->>'twenty')::int4 twenty, (fields->>'hundred')::int4 hundred, (fields->>'thousand')::int4 thousand, (fields->>'twothousand')::int4 twothousand, (fields->>'fivethous')::int4 fivethous, (fields->>'tenthous')::int4 tenthous, (fields->>'odd')::int4 odd, (fields->>'even')::int4 even, (fields->>'stringu1')::name stringu1, (fields->>'stringu2')::name stringu2, (fields->>'string4')::name string4 from tenk1 b) b on (a.unique1)::int4 = (b.unique2)::int4 left join (select (fields->>'unique1')::int4 unique1, (fields->>'unique2')::int4 unique2, (fields->>'two')::int4 two, (fields->>'four')::int4 four, (fields->>'ten')::int4 ten, (fields->>'twenty')::int4 twenty, (fields->>'hundred')::int4 hundred, (fields->>'thousand')::int4 thousand, (fields->>'twothousand')::int4 twothousand, (fields->>'fivethous')::int4 fivethous, (fields->>'tenthous')::int4 tenthous, (fields->>'odd')::int4 odd, (fields->>'even')::int4 even, (fields->>'stringu1')::name stringu1, (fields->>'stringu2')::name stringu2, (fields->>'string4')::name string4 from tenk1 c) c on (a.unique2)::int4 = (b.unique1)::int4 and (c.thousand)::int4 = (a.thousand)::int4 @@ -3895,7 +4552,7 @@ select count(*) from 10 (1 row) ---Testcase 314: +--Testcase 326: explain (costs off) select (b.fields->>'unique1')::int4 unique1 from tenk1 a join tenk1 b on (a.fields->>'unique1')::int4 = (b.fields->>'unique2')::int4 @@ -3940,7 +4597,7 @@ select (b.fields->>'unique1')::int4 unique1 from -> Foreign Scan on tenk1 c (33 rows) ---Testcase 315: +--Testcase 327: select (b.fields->>'unique1')::int4 unique1 from tenk1 a join tenk1 b on (a.fields->>'unique1')::int4 = (b.fields->>'unique2')::int4 left join tenk1 c on (b.fields->>'unique1')::int4 = 42 and (c.fields->>'thousand')::int4 = (a.fields->>'thousand')::int4 @@ -3956,7 +4613,7 @@ select (b.fields->>'unique1')::int4 unique1 from (5 rows) ---Testcase 316: +--Testcase 328: explain (costs off) select * from ( @@ -3965,20 +4622,20 @@ select * from ) ss where fault = 122 order by fault; - QUERY PLAN ------------------------------------------------------------------------------------------------------------------------------------------ - Merge Left Join - Merge Cond: ((((int8_tbl.fields ->> 'q2'::text))::bigint) = (((tenk1.fields ->> 'unique2'::text))::integer)) - Filter: ((COALESCE(((tenk1.fields ->> 'unique1'::text))::integer, '-1'::integer) + ((int8_tbl.fields ->> 'q1'::text))::bigint) = 122) - -> Sort - Sort Key: (((int8_tbl.fields ->> 'q2'::text))::bigint) - -> Foreign Scan on int8_tbl + QUERY PLAN +------------------------------------------------------------------------------------------------------------------------------------------- + Merge Right Join + Merge Cond: ((((tenk1.fields ->> 'unique2'::text))::integer) = (((int8_tbl.fields ->> 'q2'::text))::bigint)) + Filter: ((COALESCE((((tenk1.fields ->> 'unique1'::text))::integer), '-1'::integer) + ((int8_tbl.fields ->> 'q1'::text))::bigint) = 122) -> Sort Sort Key: (((tenk1.fields ->> 'unique2'::text))::integer) -> Foreign Scan on tenk1 + -> Sort + Sort Key: (((int8_tbl.fields ->> 'q2'::text))::bigint) + -> Foreign Scan on int8_tbl (9 rows) ---Testcase 317: +--Testcase 329: select * from ( select unique1, q1, coalesce((unique1)::int4, -1) + (q1)::int8 as fault @@ -3991,7 +4648,7 @@ order by fault; | 123 | 122 (1 row) ---Testcase 318: +--Testcase 330: explain (costs off) select * from (values (1, array[10,20]), (2, array[20,30])) as v1(v1x,v1ys) @@ -4009,7 +4666,7 @@ left join unnest(v1ys) as u1(u1y) on u1y = v2y; -> Values Scan on "*VALUES*_1" (8 rows) ---Testcase 319: +--Testcase 331: 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 @@ -4023,25 +4680,25 @@ left join unnest(v1ys) as u1(u1y) on u1y = v2y; -- -- test handling of potential equivalence clauses above outer joins -- ---Testcase 320: +--Testcase 332: explain (costs off) select q1, unique2, thousand, hundred from (select (fields->>'q1')::int8 q1, (fields->>'q2')::int8 q2 from INT8_TBL a) a left join (select (fields->>'unique1')::int4 unique1, (fields->>'unique2')::int4 unique2, (fields->>'two')::int4 two, (fields->>'four')::int4 four, (fields->>'ten')::int4 ten, (fields->>'twenty')::int4 twenty, (fields->>'hundred')::int4 hundred, (fields->>'thousand')::int4 thousand, (fields->>'twothousand')::int4 twothousand, (fields->>'fivethous')::int4 fivethous, (fields->>'tenthous')::int4 tenthous, (fields->>'odd')::int4 odd, (fields->>'even')::int4 even, (fields->>'stringu1')::name stringu1, (fields->>'stringu2')::name stringu2, (fields->>'string4')::name string4 from tenk1 b) b on (q1)::int8 = (unique2)::int4 where coalesce((thousand)::int4,123) = (q1)::int8 and (q1)::int8 = coalesce((hundred)::int4,123); - QUERY PLAN ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- - Merge Left Join - Merge Cond: ((((a.fields ->> 'q1'::text))::bigint) = (((b.fields ->> 'unique2'::text))::integer)) - Filter: ((COALESCE(((b.fields ->> 'thousand'::text))::integer, 123) = (((a.fields ->> 'q1'::text))::bigint)) AND ((((a.fields ->> 'q1'::text))::bigint) = COALESCE(((b.fields ->> 'hundred'::text))::integer, 123))) - -> Sort - Sort Key: (((a.fields ->> 'q1'::text))::bigint) - -> Foreign Scan on int8_tbl a + QUERY PLAN +------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- + Merge Right Join + Merge Cond: ((((b.fields ->> 'unique2'::text))::integer) = (((a.fields ->> 'q1'::text))::bigint)) + Filter: ((COALESCE((((b.fields ->> 'thousand'::text))::integer), 123) = COALESCE((((b.fields ->> 'hundred'::text))::integer), 123)) AND ((((a.fields ->> 'q1'::text))::bigint) = COALESCE((((b.fields ->> 'hundred'::text))::integer), 123))) -> Sort Sort Key: (((b.fields ->> 'unique2'::text))::integer) -> Foreign Scan on tenk1 b + -> Sort + Sort Key: (((a.fields ->> 'q1'::text))::bigint) + -> Foreign Scan on int8_tbl a (9 rows) ---Testcase 321: +--Testcase 333: select q1, unique2, thousand, hundred from (select (fields->>'q1')::int8 q1, (fields->>'q2')::int8 q2 from INT8_TBL a) a left join (select (fields->>'unique1')::int4 unique1, (fields->>'unique2')::int4 unique2, (fields->>'two')::int4 two, (fields->>'four')::int4 four, (fields->>'ten')::int4 ten, (fields->>'twenty')::int4 twenty, (fields->>'hundred')::int4 hundred, (fields->>'thousand')::int4 thousand, (fields->>'twothousand')::int4 twothousand, (fields->>'fivethous')::int4 fivethous, (fields->>'tenthous')::int4 tenthous, (fields->>'odd')::int4 odd, (fields->>'even')::int4 even, (fields->>'stringu1')::name stringu1, (fields->>'stringu2')::name stringu2, (fields->>'string4')::name string4 from tenk1 b) b on (q1)::int8 = (unique2)::int4 where coalesce((thousand)::int4,123) = (q1)::int8 and (q1)::int8 = coalesce((hundred)::int4,123); @@ -4049,25 +4706,25 @@ select q1, unique2, thousand, hundred ----+---------+----------+--------- (0 rows) ---Testcase 322: +--Testcase 334: explain (costs off) select f1, unique2, case when (unique2)::int4 is null then (f1)::int4 else 0 end from (select (fields->>'f1')::int4 f1 from INT4_TBL a) a left join (select (fields->>'unique1')::int4 unique1, (fields->>'unique2')::int4 unique2, (fields->>'two')::int4 two, (fields->>'four')::int4 four, (fields->>'ten')::int4 ten, (fields->>'twenty')::int4 twenty, (fields->>'hundred')::int4 hundred, (fields->>'thousand')::int4 thousand, (fields->>'twothousand')::int4 twothousand, (fields->>'fivethous')::int4 fivethous, (fields->>'tenthous')::int4 tenthous, (fields->>'odd')::int4 odd, (fields->>'even')::int4 even, (fields->>'stringu1')::name stringu1, (fields->>'stringu2')::name stringu2, (fields->>'string4')::name string4 from tenk1 b) b on (f1)::int4 = (unique2)::int4 where (case when (unique2)::int4 is null then (f1)::int4 else 0 end) = 0; - QUERY PLAN --------------------------------------------------------------------------------------------------------------------------------------- - Merge Left Join - Merge Cond: ((((a.fields ->> 'f1'::text))::integer) = (((b.fields ->> 'unique2'::text))::integer)) - Filter: (CASE WHEN (((b.fields ->> 'unique2'::text))::integer IS NULL) THEN (((a.fields ->> 'f1'::text))::integer) ELSE 0 END = 0) - -> Sort - Sort Key: (((a.fields ->> 'f1'::text))::integer) - -> Foreign Scan on int4_tbl a + QUERY PLAN +---------------------------------------------------------------------------------------------------------------------------------------- + Merge Right Join + Merge Cond: ((((b.fields ->> 'unique2'::text))::integer) = (((a.fields ->> 'f1'::text))::integer)) + Filter: (CASE WHEN ((((b.fields ->> 'unique2'::text))::integer) IS NULL) THEN (((a.fields ->> 'f1'::text))::integer) ELSE 0 END = 0) -> Sort Sort Key: (((b.fields ->> 'unique2'::text))::integer) -> Foreign Scan on tenk1 b + -> Sort + Sort Key: (((a.fields ->> 'f1'::text))::integer) + -> Foreign Scan on int4_tbl a (9 rows) ---Testcase 323: +--Testcase 335: select f1, unique2, case when (unique2)::int4 is null then (f1)::int4 else 0 end from (select (fields->>'f1')::int4 f1 from INT4_TBL a) a left join (select (fields->>'unique1')::int4 unique1, (fields->>'unique2')::int4 unique2, (fields->>'two')::int4 two, (fields->>'four')::int4 four, (fields->>'ten')::int4 ten, (fields->>'twenty')::int4 twenty, (fields->>'hundred')::int4 hundred, (fields->>'thousand')::int4 thousand, (fields->>'twothousand')::int4 twothousand, (fields->>'fivethous')::int4 fivethous, (fields->>'tenthous')::int4 tenthous, (fields->>'odd')::int4 odd, (fields->>'even')::int4 even, (fields->>'stringu1')::name stringu1, (fields->>'stringu2')::name stringu2, (fields->>'string4')::name string4 from tenk1 b) b on (f1)::int4 = (unique2)::int4 where (case when (unique2)::int4 is null then (f1)::int4 else 0 end) = 0; @@ -4079,15 +4736,14 @@ select f1, unique2, case when (unique2)::int4 is null then (f1)::int4 else 0 end -- -- another case with equivalence clauses above outer joins (bug #8591) -- ---Testcase 324: +--Testcase 336: explain (costs off) select (a.fields->>'unique1')::int4 unique1, (b.fields->>'unique1')::int4 unique1, (c.fields->>'unique1')::int4 unique1, coalesce((b.fields->>'twothousand')::int4, (a.fields->>'twothousand')::int4) from tenk1 a left join tenk1 b on (b.fields->>'thousand')::int4 = (a.fields->>'unique1')::int4 left join tenk1 c on (c.fields->>'unique2')::int4 = coalesce((b.fields->>'twothousand')::int4, (a.fields->>'twothousand')::int4) where (a.fields->>'unique2')::int4 < 10 and coalesce((b.fields->>'twothousand')::int4, (a.fields->>'twothousand')::int4) = 44; - QUERY PLAN -------------------------------------------------------------------------------------------------------------------------------------------------------------------- - Hash Left Join - Hash Cond: (COALESCE(((b.fields ->> 'twothousand'::text))::integer, ((a.fields ->> 'twothousand'::text))::integer) = ((c.fields ->> 'unique2'::text))::integer) + QUERY PLAN +------------------------------------------------------------------------------------------------------------------------------- + Nested Loop Left Join -> Merge Left Join Merge Cond: ((((a.fields ->> 'unique1'::text))::integer) = (((b.fields ->> 'thousand'::text))::integer)) Filter: (COALESCE(((b.fields ->> 'twothousand'::text))::integer, ((a.fields ->> 'twothousand'::text))::integer) = 44) @@ -4097,11 +4753,11 @@ select (a.fields->>'unique1')::int4 unique1, (b.fields->>'unique1')::int4 unique -> Sort Sort Key: (((b.fields ->> 'thousand'::text))::integer) -> Foreign Scan on tenk1 b - -> Hash + -> Materialize -> Foreign Scan on tenk1 c -(13 rows) +(12 rows) ---Testcase 325: +--Testcase 337: select (a.fields->>'unique1')::int4 unique1, (b.fields->>'unique1')::int4 unique1, (c.fields->>'unique1')::int4 unique1, coalesce((b.fields->>'twothousand')::int4, (a.fields->>'twothousand')::int4) from tenk1 a left join tenk1 b on (b.fields->>'thousand')::int4 = (a.fields->>'unique1')::int4 left join tenk1 c on (c.fields->>'unique2')::int4 = coalesce((b.fields->>'twothousand')::int4, (a.fields->>'twothousand')::int4) where (a.fields->>'unique2')::int4 < 10 and coalesce((b.fields->>'twothousand')::int4, (a.fields->>'twothousand')::int4) = 44; @@ -4109,10 +4765,46 @@ select (a.fields->>'unique1')::int4 unique1, (b.fields->>'unique1')::int4 unique ---------+---------+---------+---------- (0 rows) +-- related case +explain (costs off) +select * from int8_tbl t1 left join int8_tbl t2 on (t1.fields->>'q2')::int8 = (t2.fields->>'q1')::int8, + lateral (select * from int8_tbl t3 where (t2.fields->>'q1')::int8 = (t2.fields->>'q2')::int8) ss; + QUERY PLAN +------------------------------------------------------------------------------------------------------------- + Nested Loop + -> Foreign Scan on int8_tbl t3 + -> Materialize + -> Merge Left Join + Merge Cond: ((((t1.fields ->> 'q2'::text))::bigint) = (((t2.fields ->> 'q1'::text))::bigint)) + Filter: (((t2.fields ->> 'q1'::text))::bigint = ((t2.fields ->> 'q2'::text))::bigint) + -> Sort + Sort Key: (((t1.fields ->> 'q2'::text))::bigint) + -> Foreign Scan on int8_tbl t1 + -> Sort + Sort Key: (((t2.fields ->> 'q1'::text))::bigint) + -> Foreign Scan on int8_tbl t2 +(12 rows) + +select * from int8_tbl t1 left join int8_tbl t2 on (t1.fields->>'q2')::int8 = (t2.fields->>'q1')::int8, + lateral (select * from int8_tbl t3 where (t2.fields->>'q1')::int8 = (t2.fields->>'q2')::int8) ss; + fields | fields | fields +------------------------------------------------------+------------------------------------------------------+------------------------------------------------------- + {"q1": "123", "q2": "4567890123456789"} | {"q1": "4567890123456789", "q2": "4567890123456789"} | {"q1": "123", "q2": "456"} + {"q1": "4567890123456789", "q2": "4567890123456789"} | {"q1": "4567890123456789", "q2": "4567890123456789"} | {"q1": "123", "q2": "456"} + {"q1": "123", "q2": "4567890123456789"} | {"q1": "4567890123456789", "q2": "4567890123456789"} | {"q1": "123", "q2": "4567890123456789"} + {"q1": "4567890123456789", "q2": "4567890123456789"} | {"q1": "4567890123456789", "q2": "4567890123456789"} | {"q1": "123", "q2": "4567890123456789"} + {"q1": "123", "q2": "4567890123456789"} | {"q1": "4567890123456789", "q2": "4567890123456789"} | {"q1": "4567890123456789", "q2": "123"} + {"q1": "4567890123456789", "q2": "4567890123456789"} | {"q1": "4567890123456789", "q2": "4567890123456789"} | {"q1": "4567890123456789", "q2": "123"} + {"q1": "123", "q2": "4567890123456789"} | {"q1": "4567890123456789", "q2": "4567890123456789"} | {"q1": "4567890123456789", "q2": "4567890123456789"} + {"q1": "4567890123456789", "q2": "4567890123456789"} | {"q1": "4567890123456789", "q2": "4567890123456789"} | {"q1": "4567890123456789", "q2": "4567890123456789"} + {"q1": "123", "q2": "4567890123456789"} | {"q1": "4567890123456789", "q2": "4567890123456789"} | {"q1": "4567890123456789", "q2": "-4567890123456789"} + {"q1": "4567890123456789", "q2": "4567890123456789"} | {"q1": "4567890123456789", "q2": "4567890123456789"} | {"q1": "4567890123456789", "q2": "-4567890123456789"} +(10 rows) + -- -- check handling of join aliases when flattening multiple levels of subquery -- ---Testcase 326: +--Testcase 338: 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) @@ -4126,19 +4818,19 @@ left join using (join_key) ) foo3 using (join_key); - QUERY PLAN --------------------------------------------------------------------------------------------------------------- + QUERY PLAN +--------------------------------------------------------------------------------------------------------------------- Hash Right Join - Output: "*VALUES*".column1, ((i1.fields ->> 'f1'::text))::integer, (666) + Output: "*VALUES*".column1, (((i1.fields ->> 'f1'::text))::integer), (666) Hash Cond: (((i1.fields ->> 'f1'::text))::integer = "*VALUES*".column1) -> Merge Left Join - Output: i1.fields, 666 + Output: i1.fields, (((i1.fields ->> 'f1'::text))::integer), 666 Merge Cond: ((((i1.fields ->> 'f1'::text))::integer) = (((i2.fields ->> 'unique2'::text))::integer)) -> Sort - Output: i1.fields, (((i1.fields ->> 'f1'::text))::integer) + Output: i1.fields, (((i1.fields ->> 'f1'::text))::integer), (((i1.fields ->> 'f1'::text))::integer) Sort Key: (((i1.fields ->> 'f1'::text))::integer) -> Foreign Scan on public.int4_tbl i1 - Output: i1.fields, ((i1.fields ->> 'f1'::text))::integer + Output: i1.fields, ((i1.fields ->> 'f1'::text))::integer, ((i1.fields ->> 'f1'::text))::integer InfluxDB query: SELECT * FROM "int4_tbl" -> Sort Output: i2.fields, (((i2.fields ->> 'unique2'::text))::integer) @@ -4152,7 +4844,7 @@ using (join_key); Output: "*VALUES*".column1 (22 rows) ---Testcase 327: +--Testcase 339: select foo1.join_key as foo1_id, foo3.join_key AS foo3_id, bug_field from (values (0),(1)) foo1(join_key) left join @@ -4171,12 +4863,73 @@ using (join_key); 1 | | (2 rows) +-- +-- check handling of a variable-free join alias +-- +explain (verbose, costs off) +select * from +int4_tbl i0 left join +( (select (fields->>'f1')::int4 f1, 123 as x from int4_tbl i1) ss1 + left join + (select (fields->>'q1') q1, (fields->>'q2') q2, (fields->>'q2')::int4 as x from int8_tbl i2) ss2 + using (x) +) ss0 +on ((i0.fields->>'f1')::int4 = ss0.f1) +order by (i0.fields->>'f1')::int4, x; + QUERY PLAN +------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ + Incremental Sort + Output: i0.fields, (123), (((i1.fields ->> 'f1'::text))::integer), ((i2.fields ->> 'q1'::text)), ((i2.fields ->> 'q2'::text)), (((i0.fields ->> 'f1'::text))::integer) + Sort Key: (((i0.fields ->> 'f1'::text))::integer), (123) + Presorted Key: (((i0.fields ->> 'f1'::text))::integer) + -> Merge Left Join + Output: i0.fields, (123), (((i1.fields ->> 'f1'::text))::integer), ((i2.fields ->> 'q1'::text)), ((i2.fields ->> 'q2'::text)), (((i0.fields ->> 'f1'::text))::integer) + Merge Cond: ((((i0.fields ->> 'f1'::text))::integer) = (((i1.fields ->> 'f1'::text))::integer)) + -> Sort + Output: i0.fields, (((i0.fields ->> 'f1'::text))::integer) + Sort Key: (((i0.fields ->> 'f1'::text))::integer) + -> Foreign Scan on public.int4_tbl i0 + Output: i0.fields, ((i0.fields ->> 'f1'::text))::integer + InfluxDB query: SELECT * FROM "int4_tbl" + -> Sort + Output: i1.fields, (123), (((i1.fields ->> 'f1'::text))::integer), ((i2.fields ->> 'q1'::text)), ((i2.fields ->> 'q2'::text)), (((i1.fields ->> 'f1'::text))::integer) + Sort Key: (((i1.fields ->> 'f1'::text))::integer) + -> Nested Loop Left Join + Output: i1.fields, (123), (((i1.fields ->> 'f1'::text))::integer), ((i2.fields ->> 'q1'::text)), ((i2.fields ->> 'q2'::text)), ((i1.fields ->> 'f1'::text))::integer + -> Foreign Scan on public.int4_tbl i1 + Output: i1.fields, 123, ((i1.fields ->> 'f1'::text))::integer + InfluxDB query: SELECT * FROM "int4_tbl" + -> Materialize + Output: ((i2.fields ->> 'q1'::text)), ((i2.fields ->> 'q2'::text)) + -> Foreign Scan on public.int8_tbl i2 + Output: (i2.fields ->> 'q1'::text), (i2.fields ->> 'q2'::text) + InfluxDB query: SELECT "q1", "q2" FROM "int8_tbl" WHERE ((123 = "q2")) +(26 rows) + +select * from +int4_tbl i0 left join +( (select (fields->>'f1')::int4 f1, 123 as x from int4_tbl i1) ss1 + left join + (select (fields->>'q1') q1, (fields->>'q2') q2, (fields->>'q2')::int4 as x from int8_tbl i2) ss2 + using (x) +) ss0 +on ((i0.fields->>'f1')::int4 = ss0.f1) +order by (i0.fields->>'f1')::int4, x; + fields | x | f1 | q1 | q2 +-----------------------+-----+-------------+------------------+----- + {"f1": "-2147483647"} | 123 | -2147483647 | 4567890123456789 | 123 + {"f1": "-123456"} | 123 | -123456 | 4567890123456789 | 123 + {"f1": "0"} | 123 | 0 | 4567890123456789 | 123 + {"f1": "123456"} | 123 | 123456 | 4567890123456789 | 123 + {"f1": "2147483647"} | 123 | 2147483647 | 4567890123456789 | 123 +(5 rows) + -- -- test successful handling of nested outer joins with degenerate join quals -- ---Testcase 328: +--Testcase 340: create foreign table text_tbl(fields jsonb OPTIONS (fields 'true')) server influxdb_svr OPTIONS(schemaless 'true'); ---Testcase 329: +--Testcase 341: explain (verbose, costs off) select t1.* from (select fields->>'f1' f1 from text_tbl t1) t1 @@ -4224,7 +4977,7 @@ select t1.* from -> Sort Output: i8.fields, (NULL::integer), (((NULL::integer))::bigint) Sort Key: (((NULL::integer))::bigint) - -> Merge Right Join + -> Merge Join Output: i8.fields, (NULL::integer), ((NULL::integer))::bigint Merge Cond: ((((i8b2.fields ->> 'q1'::text))::bigint) = (((i8.fields ->> 'q1'::text))::bigint)) -> Sort @@ -4241,7 +4994,7 @@ select t1.* from InfluxDB query: SELECT * FROM "int8_tbl" (49 rows) ---Testcase 330: +--Testcase 342: select t1.* from (select fields->>'f1' f1 from text_tbl t1) t1 left join (select *, '***'::text as d1 from int8_tbl i8b1) b1 @@ -4258,11 +5011,11 @@ select t1.* from hi de ho neighbor (2 rows) ---Testcase 331: +--Testcase 343: explain (verbose, costs off) select t1.* from (select fields->>'f1' f1 from text_tbl t1) t1 - left join (select *, '***'::text as d1 from (select (fields->>'q1')::int8 q1, (fields->>'q2')::int8 q2 from INT8_TBL i8b1) i8b1) b1 + left join (select *, '***'::text as d1 from (select (fields->>'q1')::int8 q1, (fields->>'q2')::int8 q2 from INT8_TBL i8b1) i8b1 ) b1 left join (select (fields->>'q1')::int8 q1, (fields->>'q2')::int8 q2 from INT8_TBL i8) i8 left join (select *, null::int as d2 from (select (fields->>'q1')::int8 q1, (fields->>'q2')::int8 q2 from INT8_TBL i8b2) i8b2, (select (fields->>'f1')::int4 f1 from INT4_TBL i4b2) i4b2) b2 on ((i8.q1)::int8 = (b2.q1)::int8) @@ -4270,8 +5023,8 @@ select t1.* from on (t1.f1 = b1.d1) left join (select (fields->>'f1')::int4 f1 from INT4_TBL i4) i4 on ((i8.q2)::int8 = (i4.f1)::int4); - QUERY PLAN ---------------------------------------------------------------------------------------------------------------------------------------------------- + QUERY PLAN +------------------------------------------------------------------------------------------------------------------------------------------------------------- Merge Right Join Output: (t1.fields ->> 'f1'::text) Merge Cond: ((((i4.fields ->> 'f1'::text))::integer) = (((i8.fields ->> 'q2'::text))::bigint)) @@ -4282,20 +5035,20 @@ select t1.* from Output: i4.fields, ((i4.fields ->> 'f1'::text))::integer InfluxDB query: SELECT * FROM "int4_tbl" -> Materialize - Output: t1.fields, i8.fields, (((i8.fields ->> 'q2'::text))::bigint) + Output: t1.fields, (((i8.fields ->> 'q2'::text))::bigint) -> Sort - Output: t1.fields, i8.fields, (((i8.fields ->> 'q2'::text))::bigint) + Output: t1.fields, (((i8.fields ->> 'q2'::text))::bigint) Sort Key: (((i8.fields ->> 'q2'::text))::bigint) -> Nested Loop Left Join - Output: t1.fields, i8.fields, ((i8.fields ->> 'q2'::text))::bigint + Output: t1.fields, (((i8.fields ->> 'q2'::text))::bigint) Join Filter: ((t1.fields ->> 'f1'::text) = '***'::text) -> Foreign Scan on public.text_tbl t1 Output: t1.fields InfluxDB query: SELECT * FROM "text_tbl" -> Materialize - Output: i8.fields + Output: (((i8.fields ->> 'q2'::text))::bigint) -> Merge Left Join - Output: i8.fields + Output: (((i8.fields ->> 'q2'::text))::bigint) Merge Cond: ((((i8b1.fields ->> 'q2'::text))::bigint) = (((NULL::integer))::bigint)) -> Sort Output: i8b1.fields, (((i8b1.fields ->> 'q2'::text))::bigint) @@ -4304,18 +5057,18 @@ select t1.* from Output: i8b1.fields, ((i8b1.fields ->> 'q2'::text))::bigint InfluxDB query: SELECT * FROM "int8_tbl" -> Materialize - Output: i8.fields, (NULL::integer), (((NULL::integer))::bigint) + Output: (((i8.fields ->> 'q2'::text))::bigint), (NULL::integer), (((NULL::integer))::bigint) -> Sort - Output: i8.fields, (NULL::integer), (((NULL::integer))::bigint) + Output: (((i8.fields ->> 'q2'::text))::bigint), (NULL::integer), (((NULL::integer))::bigint) Sort Key: (((NULL::integer))::bigint) -> Merge Left Join - Output: i8.fields, (NULL::integer), ((NULL::integer))::bigint + Output: (((i8.fields ->> 'q2'::text))::bigint), (NULL::integer), ((NULL::integer))::bigint Merge Cond: ((((i8.fields ->> 'q1'::text))::bigint) = (((i8b2.fields ->> 'q1'::text))::bigint)) -> Sort - Output: i8.fields, (((i8.fields ->> 'q1'::text))::bigint) + Output: i8.fields, (((i8.fields ->> 'q2'::text))::bigint), (((i8.fields ->> 'q1'::text))::bigint) Sort Key: (((i8.fields ->> 'q1'::text))::bigint) -> Foreign Scan on public.int8_tbl i8 - Output: i8.fields, ((i8.fields ->> 'q1'::text))::bigint + Output: i8.fields, ((i8.fields ->> 'q2'::text))::bigint, ((i8.fields ->> 'q1'::text))::bigint InfluxDB query: SELECT * FROM "int8_tbl" -> Materialize Output: i8b2.fields, (NULL::integer), (((i8b2.fields ->> 'q1'::text))::bigint) @@ -4334,7 +5087,7 @@ select t1.* from InfluxDB query: SELECT * FROM "int8_tbl" (60 rows) ---Testcase 332: +--Testcase 344: select t1.* from (select fields->>'f1' f1 from text_tbl t1) t1 left join (select *, '***'::text as d1 from (select (fields->>'q1')::int8 q1, (fields->>'q2')::int8 q2 from INT8_TBL i8b1) i8b1) b1 @@ -4351,7 +5104,7 @@ select t1.* from hi de ho neighbor (2 rows) ---Testcase 333: +--Testcase 345: explain (verbose, costs off) select t1.* from (select fields->>'f1' f1 from text_tbl t1) t1 @@ -4364,8 +5117,8 @@ select t1.* from on (t1.f1 = b1.d1) left join (select (fields->>'f1')::int4 f1 from INT4_TBL i4) i4 on ((i8.q2)::int8 = (i4.f1)::int4); - QUERY PLAN ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------- + QUERY PLAN +---------------------------------------------------------------------------------------------------------------------------------------------------------------------- Merge Right Join Output: (t1.fields ->> 'f1'::text) Merge Cond: ((((i4.fields ->> 'f1'::text))::integer) = (((i8.fields ->> 'q2'::text))::bigint)) @@ -4376,20 +5129,20 @@ select t1.* from Output: i4.fields, ((i4.fields ->> 'f1'::text))::integer InfluxDB query: SELECT * FROM "int4_tbl" -> Materialize - Output: t1.fields, i8.fields, (((i8.fields ->> 'q2'::text))::bigint) + Output: t1.fields, (((i8.fields ->> 'q2'::text))::bigint) -> Sort - Output: t1.fields, i8.fields, (((i8.fields ->> 'q2'::text))::bigint) + Output: t1.fields, (((i8.fields ->> 'q2'::text))::bigint) Sort Key: (((i8.fields ->> 'q2'::text))::bigint) -> Nested Loop Left Join - Output: t1.fields, i8.fields, ((i8.fields ->> 'q2'::text))::bigint + Output: t1.fields, (((i8.fields ->> 'q2'::text))::bigint) Join Filter: ((t1.fields ->> 'f1'::text) = '***'::text) -> Foreign Scan on public.text_tbl t1 Output: t1.fields InfluxDB query: SELECT * FROM "text_tbl" -> Materialize - Output: i8.fields + Output: (((i8.fields ->> 'q2'::text))::bigint) -> Merge Left Join - Output: i8.fields + Output: (((i8.fields ->> 'q2'::text))::bigint) Merge Cond: ((((i8b1.fields ->> 'q2'::text))::bigint) = (((NULL::integer))::bigint)) -> Sort Output: i8b1.fields, (((i8b1.fields ->> 'q2'::text))::bigint) @@ -4397,40 +5150,38 @@ select t1.* from -> Foreign Scan on public.int8_tbl i8b1 Output: i8b1.fields, ((i8b1.fields ->> 'q2'::text))::bigint InfluxDB query: SELECT * FROM "int8_tbl" - -> Materialize - Output: i8.fields, (NULL::integer), (((NULL::integer))::bigint) - -> Sort - Output: i8.fields, (NULL::integer), (((NULL::integer))::bigint) - Sort Key: (((NULL::integer))::bigint) - -> Merge Left Join - Output: i8.fields, (NULL::integer), ((NULL::integer))::bigint - Merge Cond: ((((i8.fields ->> 'q1'::text))::bigint) = ((i8b2.fields ->> 'q1'::text))::bigint) - -> Sort - Output: i8.fields, (((i8.fields ->> 'q1'::text))::bigint) - Sort Key: (((i8.fields ->> 'q1'::text))::bigint) - -> Foreign Scan on public.int8_tbl i8 - Output: i8.fields, ((i8.fields ->> 'q1'::text))::bigint - InfluxDB query: SELECT * FROM "int8_tbl" - -> Materialize - Output: i8b2.fields, (NULL::integer) - -> Merge Join - Output: i8b2.fields, NULL::integer - Merge Cond: ((((i8b2.fields ->> 'q1'::text))::bigint) = ((((i4b2.fields ->> 'f1'::text))::integer)::bigint)) - -> Sort - Output: i8b2.fields, (((i8b2.fields ->> 'q1'::text))::bigint) - Sort Key: (((i8b2.fields ->> 'q1'::text))::bigint) - -> Foreign Scan on public.int8_tbl i8b2 - Output: i8b2.fields, ((i8b2.fields ->> 'q1'::text))::bigint - InfluxDB query: SELECT * FROM "int8_tbl" - -> Sort - Output: i4b2.fields, ((((i4b2.fields ->> 'f1'::text))::integer)::bigint) - Sort Key: ((((i4b2.fields ->> 'f1'::text))::integer)::bigint) - -> Foreign Scan on public.int4_tbl i4b2 - Output: i4b2.fields, (((i4b2.fields ->> 'f1'::text))::integer)::bigint - InfluxDB query: SELECT * FROM "int4_tbl" -(62 rows) + -> Sort + Output: (((i8.fields ->> 'q2'::text))::bigint), (NULL::integer), (((NULL::integer))::bigint) + Sort Key: (((NULL::integer))::bigint) + -> Merge Left Join + Output: (((i8.fields ->> 'q2'::text))::bigint), (NULL::integer), ((NULL::integer))::bigint + Merge Cond: ((((i8.fields ->> 'q1'::text))::bigint) = ((i8b2.fields ->> 'q1'::text))::bigint) + -> Sort + Output: i8.fields, (((i8.fields ->> 'q2'::text))::bigint), (((i8.fields ->> 'q1'::text))::bigint) + Sort Key: (((i8.fields ->> 'q1'::text))::bigint) + -> Foreign Scan on public.int8_tbl i8 + Output: i8.fields, ((i8.fields ->> 'q2'::text))::bigint, ((i8.fields ->> 'q1'::text))::bigint + InfluxDB query: SELECT * FROM "int8_tbl" + -> Materialize + Output: i8b2.fields, (NULL::integer) + -> Merge Join + Output: i8b2.fields, NULL::integer + Merge Cond: ((((i8b2.fields ->> 'q1'::text))::bigint) = ((((i4b2.fields ->> 'f1'::text))::integer)::bigint)) + -> Sort + Output: i8b2.fields, (((i8b2.fields ->> 'q1'::text))::bigint) + Sort Key: (((i8b2.fields ->> 'q1'::text))::bigint) + -> Foreign Scan on public.int8_tbl i8b2 + Output: i8b2.fields, ((i8b2.fields ->> 'q1'::text))::bigint + InfluxDB query: SELECT * FROM "int8_tbl" + -> Sort + Output: i4b2.fields, ((((i4b2.fields ->> 'f1'::text))::integer)::bigint) + Sort Key: ((((i4b2.fields ->> 'f1'::text))::integer)::bigint) + -> Foreign Scan on public.int4_tbl i4b2 + Output: i4b2.fields, (((i4b2.fields ->> 'f1'::text))::integer)::bigint + InfluxDB query: SELECT * FROM "int4_tbl" +(60 rows) ---Testcase 334: +--Testcase 346: select t1.* from (select fields->>'f1' f1 from text_tbl t1) t1 left join (select *, '***'::text as d1 from (select (fields->>'q1')::int8 q1, (fields->>'q2')::int8 q2 from INT8_TBL i8b1) i8b1) b1 @@ -4448,7 +5199,7 @@ select t1.* from hi de ho neighbor (2 rows) ---Testcase 335: +--Testcase 347: explain (verbose, costs off) select * from (select fields->>'f1' f1 from text_tbl t1) t1 @@ -4458,36 +5209,36 @@ select * from on t1.f1 = 'doh!' left join (select (fields->>'f1')::int4 f1 from INT4_TBL i4) i4 on i8.q1 = i4.f1; - QUERY PLAN ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------- + QUERY PLAN +----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- Nested Loop Left Join - Output: (t1.fields ->> 'f1'::text), ((i8.fields ->> 'q1'::text))::bigint, (i8.fields ->> 'q2'::text), (t2.fields ->> 'f1'::text), ((i4.fields ->> 'f1'::text))::integer + Output: ((t1.fields ->> 'f1'::text)), (((i8.fields ->> 'q1'::text))::bigint), ((i8.fields ->> 'q2'::text)), (t2.fields ->> 'f1'::text), (((i4.fields ->> 'f1'::text))::integer) -> Foreign Scan on public.text_tbl t2 Output: t2.fields InfluxDB query: SELECT * FROM "text_tbl" -> Materialize - Output: i8.fields, i4.fields, t1.fields + Output: (((i8.fields ->> 'q1'::text))::bigint), ((i8.fields ->> 'q2'::text)), (((i4.fields ->> 'f1'::text))::integer), ((t1.fields ->> 'f1'::text)) -> Nested Loop - Output: i8.fields, i4.fields, t1.fields + Output: (((i8.fields ->> 'q1'::text))::bigint), ((i8.fields ->> 'q2'::text)), (((i4.fields ->> 'f1'::text))::integer), ((t1.fields ->> 'f1'::text)) -> Hash Right Join - Output: i8.fields, i4.fields - Hash Cond: (((i4.fields ->> 'f1'::text))::integer = ((i8.fields ->> 'q1'::text))::bigint) + Output: (((i8.fields ->> 'q1'::text))::bigint), ((i8.fields ->> 'q2'::text)), (((i4.fields ->> 'f1'::text))::integer) + Hash Cond: (((i4.fields ->> 'f1'::text))::integer = (((i8.fields ->> 'q1'::text))::bigint)) -> Foreign Scan on public.int4_tbl i4 - Output: i4.fields + Output: i4.fields, ((i4.fields ->> 'f1'::text))::integer InfluxDB query: SELECT * FROM "int4_tbl" -> Hash - Output: i8.fields + Output: (((i8.fields ->> 'q1'::text))::bigint), ((i8.fields ->> 'q2'::text)) -> Foreign Scan on public.int8_tbl i8 - Output: i8.fields - InfluxDB query: SELECT * FROM "int8_tbl" WHERE (("q2" = 456)) + Output: ((i8.fields ->> 'q1'::text))::bigint, (i8.fields ->> 'q2'::text) + InfluxDB query: SELECT "q1", "q2" FROM "int8_tbl" WHERE (("q2" = 456)) -> Materialize - Output: t1.fields + Output: ((t1.fields ->> 'f1'::text)) -> Foreign Scan on public.text_tbl t1 - Output: t1.fields - InfluxDB query: SELECT * FROM "text_tbl" WHERE (("f1" = 'doh!')) + Output: (t1.fields ->> 'f1'::text) + InfluxDB query: SELECT "f1" FROM "text_tbl" WHERE (("f1" = 'doh!')) (25 rows) ---Testcase 336: +--Testcase 348: select * from (select fields->>'f1' f1 from text_tbl t1) t1 inner join (select (fields->>'q1')::int8 q1, fields->>'q2' q2 from INT8_TBL i8) i8 @@ -4502,10 +5253,57 @@ select * from doh! | 123 | 456 | hi de ho neighbor | (2 rows) +-- 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; + QUERY PLAN +-------------------------------- + Nested Loop Left Join + Join Filter: false + -> Result + -> Result + One-Time Filter: false +(5 rows) + +-- 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.fields->>'f1')::int4 is not null + left join (select 1 as a) ss1 on null + join int4_tbl i42 on ss1.a is null or (i8.fields->>'q1')::int8 <> (i8.fields->>'q2')::int8 + right join (select 2 as b) ss2 + on ss2.b < (i4.fields->>'f1')::int4; + QUERY PLAN +------------------------------------------------------------------------------------------------------------------------- + Nested Loop Left Join + -> Result + -> Nested Loop + -> Nested Loop Left Join + Join Filter: NULL::boolean + Filter: (((1) IS NULL) OR (((i8.fields ->> 'q1'::text))::bigint <> ((i8.fields ->> 'q2'::text))::bigint)) + -> Nested Loop Left Join + Join Filter: (((i4.fields ->> 'f1'::text))::integer IS NOT NULL) + -> Foreign Scan on int4_tbl i4 + -> Materialize + -> Foreign Scan on int8_tbl i8 + -> Result + One-Time Filter: false + -> Materialize + -> Foreign Scan on int4_tbl i42 +(15 rows) + -- -- test for appropriate join order in the presence of lateral references -- ---Testcase 337: +--Testcase 349: explain (verbose, costs off) select * from (select fields->>'f1' f1 from text_tbl t1) t1 @@ -4513,29 +5311,27 @@ select * from on (i8.q2)::int8 = 123, lateral (select i8.q1, t2.fields->>'f1' f1 from text_tbl t2 limit 1) as ss where t1.f1 = ss.f1; - QUERY PLAN ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- + QUERY PLAN +---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- Nested Loop - Output: (t1.fields ->> 'f1'::text), ((i8.fields ->> 'q1'::text))::bigint, ((i8.fields ->> 'q2'::text))::bigint, (((i8.fields ->> 'q1'::text))::bigint), ((t2.fields ->> 'f1'::text)) + Output: (t1.fields ->> 'f1'::text), (((i8.fields ->> 'q1'::text))::bigint), (((i8.fields ->> 'q2'::text))::bigint), ((((i8.fields ->> 'q1'::text))::bigint)), ((t2.fields ->> 'f1'::text)) Join Filter: ((t1.fields ->> 'f1'::text) = ((t2.fields ->> 'f1'::text))) -> Nested Loop Left Join - Output: t1.fields, i8.fields + Output: t1.fields, (((i8.fields ->> 'q1'::text))::bigint), (((i8.fields ->> 'q2'::text))::bigint) -> Foreign Scan on public.text_tbl t1 Output: t1.fields InfluxDB query: SELECT * FROM "text_tbl" -> Materialize - Output: i8.fields + Output: (((i8.fields ->> 'q1'::text))::bigint), (((i8.fields ->> 'q2'::text))::bigint) -> Foreign Scan on public.int8_tbl i8 - Output: i8.fields - InfluxDB query: SELECT * FROM "int8_tbl" WHERE (("q2" = 123)) - -> Limit - Output: (((i8.fields ->> 'q1'::text))::bigint), ((t2.fields ->> 'f1'::text)) - -> Foreign Scan on public.text_tbl t2 - Output: ((i8.fields ->> 'q1'::text))::bigint, (t2.fields ->> 'f1'::text) - InfluxDB query: SELECT "f1" FROM "text_tbl" -(18 rows) + Output: ((i8.fields ->> 'q1'::text))::bigint, ((i8.fields ->> 'q2'::text))::bigint + InfluxDB query: SELECT "q1", "q2" FROM "int8_tbl" WHERE (("q2" = 123)) + -> Foreign Scan on public.text_tbl t2 + Output: (((i8.fields ->> 'q1'::text))::bigint), (t2.fields ->> 'f1'::text) + InfluxDB query: SELECT "f1" FROM "text_tbl" LIMIT 1 +(16 rows) ---Testcase 338: +--Testcase 350: select * from (select fields->>'f1' f1 from text_tbl t1) t1 left join (select (fields->>'q1')::int8 q1, (fields->>'q2')::int8 q2 from INT8_TBL i8) i8 @@ -4547,7 +5343,7 @@ where t1.f1 = ss.f1; doh! | 4567890123456789 | 123 | 4567890123456789 | doh! (1 row) ---Testcase 339: +--Testcase 351: explain (verbose, costs off) select * from (select fields->>'f1' f1 from text_tbl t1) t1 @@ -4556,36 +5352,32 @@ select * from lateral (select i8.q1, t2.fields->>'f1' f1 from text_tbl t2 limit 1) as ss1, lateral (select ss1.* from text_tbl t3 limit 1) as ss2 where t1.f1 = ss2.f1; - QUERY PLAN ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- + QUERY PLAN +-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- Nested Loop - Output: (t1.fields ->> 'f1'::text), ((i8.fields ->> 'q1'::text))::bigint, ((i8.fields ->> 'q2'::text))::bigint, (((i8.fields ->> 'q1'::text))::bigint), ((t2.fields ->> 'f1'::text)), ((((i8.fields ->> 'q1'::text))::bigint)), (((t2.fields ->> 'f1'::text))) + Output: (t1.fields ->> 'f1'::text), (((i8.fields ->> 'q1'::text))::bigint), (((i8.fields ->> 'q2'::text))::bigint), ((((i8.fields ->> 'q1'::text))::bigint)), ((t2.fields ->> 'f1'::text)), (((((i8.fields ->> 'q1'::text))::bigint))), (((t2.fields ->> 'f1'::text))) Join Filter: ((t1.fields ->> 'f1'::text) = (((t2.fields ->> 'f1'::text)))) -> Nested Loop - Output: t1.fields, i8.fields, (((i8.fields ->> 'q1'::text))::bigint), ((t2.fields ->> 'f1'::text)) + Output: t1.fields, (((i8.fields ->> 'q1'::text))::bigint), (((i8.fields ->> 'q2'::text))::bigint), ((((i8.fields ->> 'q1'::text))::bigint)), ((t2.fields ->> 'f1'::text)) -> Nested Loop Left Join - Output: t1.fields, i8.fields + Output: t1.fields, (((i8.fields ->> 'q1'::text))::bigint), (((i8.fields ->> 'q2'::text))::bigint) -> Foreign Scan on public.text_tbl t1 Output: t1.fields InfluxDB query: SELECT * FROM "text_tbl" -> Materialize - Output: i8.fields + Output: (((i8.fields ->> 'q1'::text))::bigint), (((i8.fields ->> 'q2'::text))::bigint) -> Foreign Scan on public.int8_tbl i8 - Output: i8.fields - InfluxDB query: SELECT * FROM "int8_tbl" WHERE (("q2" = 123)) - -> Limit - Output: (((i8.fields ->> 'q1'::text))::bigint), ((t2.fields ->> 'f1'::text)) - -> Foreign Scan on public.text_tbl t2 - Output: ((i8.fields ->> 'q1'::text))::bigint, (t2.fields ->> 'f1'::text) - InfluxDB query: SELECT "f1" FROM "text_tbl" - -> Limit - Output: ((((i8.fields ->> 'q1'::text))::bigint)), (((t2.fields ->> 'f1'::text))) - -> Foreign Scan on public.text_tbl t3 - Output: (((i8.fields ->> 'q1'::text))::bigint), ((t2.fields ->> 'f1'::text)) - InfluxDB query: SELECT * FROM "text_tbl" -(25 rows) + Output: ((i8.fields ->> 'q1'::text))::bigint, ((i8.fields ->> 'q2'::text))::bigint + InfluxDB query: SELECT "q1", "q2" FROM "int8_tbl" WHERE (("q2" = 123)) + -> Foreign Scan on public.text_tbl t2 + Output: (((i8.fields ->> 'q1'::text))::bigint), (t2.fields ->> 'f1'::text) + InfluxDB query: SELECT "f1" FROM "text_tbl" LIMIT 1 + -> Foreign Scan on public.text_tbl t3 + Output: ((((i8.fields ->> 'q1'::text))::bigint)), ((t2.fields ->> 'f1'::text)) + InfluxDB query: SELECT * FROM "text_tbl" LIMIT 1 +(21 rows) ---Testcase 340: +--Testcase 352: select * from (select fields->>'f1' f1 from text_tbl t1) t1 left join (select (fields->>'q1')::int8 q1, (fields->>'q2')::int8 q2 from INT8_TBL i8) i8 @@ -4598,7 +5390,7 @@ where t1.f1 = ss2.f1; doh! | 4567890123456789 | 123 | 4567890123456789 | doh! | 4567890123456789 | doh! (1 row) ---Testcase 341: +--Testcase 353: explain (verbose, costs off) select 1 from text_tbl as tt1 @@ -4607,44 +5399,44 @@ select 1 from left join text_tbl as tt4 on (tt3.fields->>'f1' = tt4.fields->>'f1'), lateral (select tt4.fields->>'f1' as c0 from text_tbl as tt5 limit 1) as ss1 where tt1.fields->>'f1' = ss1.c0; - QUERY PLAN -------------------------------------------------------------------------------------------- + QUERY PLAN +------------------------------------------------------------------------------------------------- Nested Loop Output: 1 - -> Nested Loop Left Join + -> Hash Left Join Output: tt1.fields, tt4.fields - -> Nested Loop - Output: tt1.fields - -> Foreign Scan on public.text_tbl tt2 - Output: tt2.fields - InfluxDB query: SELECT * FROM "text_tbl" - -> Materialize + Hash Cond: ((tt3.fields ->> 'f1'::text) = (tt4.fields ->> 'f1'::text)) + -> Nested Loop Left Join + Output: tt1.fields, tt3.fields + -> Nested Loop Output: tt1.fields - -> Foreign Scan on public.text_tbl tt1 + -> Foreign Scan on public.text_tbl tt2 + Output: tt2.fields + InfluxDB query: SELECT * FROM "text_tbl" + -> Materialize Output: tt1.fields + -> Foreign Scan on public.text_tbl tt1 + Output: tt1.fields + InfluxDB query: SELECT * FROM "text_tbl" WHERE (("f1" = 'foo')) + -> Materialize + Output: tt3.fields + -> Foreign Scan on public.text_tbl tt3 + Output: tt3.fields InfluxDB query: SELECT * FROM "text_tbl" WHERE (("f1" = 'foo')) - -> Hash Left Join + -> Hash Output: tt4.fields - Hash Cond: ((tt3.fields ->> 'f1'::text) = (tt4.fields ->> 'f1'::text)) - -> Foreign Scan on public.text_tbl tt3 - Output: tt3.fields - InfluxDB query: SELECT * FROM "text_tbl" WHERE (("f1" = 'foo')) - -> Hash + -> Foreign Scan on public.text_tbl tt4 Output: tt4.fields - -> Foreign Scan on public.text_tbl tt4 - Output: tt4.fields - InfluxDB query: SELECT * FROM "text_tbl" WHERE (("f1" = 'foo')) + InfluxDB query: SELECT * FROM "text_tbl" WHERE (("f1" = 'foo')) -> Subquery Scan on ss1 Output: ss1.c0 Filter: (ss1.c0 = 'foo'::text) - -> Limit - Output: ((tt4.fields ->> 'f1'::text)) - -> Foreign Scan on public.text_tbl tt5 - Output: (tt4.fields ->> 'f1'::text) - InfluxDB query: SELECT * FROM "text_tbl" + -> Foreign Scan on public.text_tbl tt5 + Output: (tt4.fields ->> 'f1'::text) + InfluxDB query: SELECT * FROM "text_tbl" LIMIT 1 (33 rows) ---Testcase 342: +--Testcase 354: select 1 from text_tbl as tt1 inner join text_tbl as tt2 on (tt1.fields->>'f1' = 'foo') @@ -4656,10 +5448,59 @@ where tt1.fields->>'f1' = ss1.c0; ---------- (0 rows) +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 (x1.fields->>'f1')::int4 = (x2.fields->>'q1')::int8) as ss1 + right join (select 1 as z) as ss2 on true) + on false, + lateral (select (i4.fields->>'f1')::int4 f1, ss1.n from int8_tbl as i8 limit 1) as ss3; + QUERY PLAN +-------------------------- + Result + Output: 1 + One-Time Filter: false +(3 rows) + +select 1 from + int4_tbl as i4 + inner join + ((select 42 as n from int4_tbl x1 left join int8_tbl x2 on (x1.fields->>'f1')::int4 = (x2.fields->>'q1')::int8) as ss1 + right join (select 1 as z) as ss2 on true) + on false, + lateral (select (i4.fields->>'f1')::int4 f1, ss1.n from int8_tbl as i8 limit 1) as ss3; + ?column? +---------- +(0 rows) + +-- +-- check a case where we formerly generated invalid parameterized paths +-- +begin; +CREATE FOREIGN TABLE temp_t (fields jsonb OPTIONS (fields 'true')) SERVER influxdb_svr OPTIONS(schemaless 'true'); +explain (costs off) +select 1 from (select (temp_t.fields->>'a')::int4 a FROM temp_t) t1 + join lateral (select t1.a from (select 1) foo offset 0) as s1 on true + join + (select 1 from (select (temp_t.fields->>'a')::int4 a FROM temp_t) t2 + inner join ((select (temp_t.fields->>'a')::int4 a FROM temp_t) t3 + left join ((select (temp_t.fields->>'a')::int4 a FROM temp_t) t4 left join (select (temp_t.fields->>'a')::int4 a FROM temp_t) t5 on t4.a = 1) + on t3.a = t4.a) + on false + where t3.a = coalesce(t5.a,1)) as s2 + on true; + QUERY PLAN +-------------------------- + Result + One-Time Filter: false +(2 rows) + +rollback; -- -- check a case in which a PlaceHolderVar forces join order -- ---Testcase 343: +--Testcase 355: explain (verbose, costs off) select ss2.* from (select (fields->>'f1')::int4 f1 from INT4_TBL) i41 @@ -4670,47 +5511,47 @@ select ss2.* from on (i41.f1)::int4 = (ss1.c1)::int4, lateral (select i41.*, i8.*, ss1.* from text_tbl limit 1) ss2 where (ss1.c2)::int8 = 0; - QUERY PLAN ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- + QUERY PLAN +---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- Nested Loop - Output: (((int4_tbl.fields ->> 'f1'::text))::integer), (((int8_tbl.fields ->> 'q1'::text))::bigint), (((int8_tbl.fields ->> 'q2'::text))::bigint), ((i42.fields ->> 'f1'::text)), ((i43.fields ->> 'f1'::text)), ((42)) - -> Nested Loop - Output: int4_tbl.fields, i42.fields, int8_tbl.fields, i43.fields, 42 - -> Nested Loop - Output: int4_tbl.fields, i42.fields, int8_tbl.fields - -> Merge Join - Output: int4_tbl.fields, i42.fields - Merge Cond: ((((int4_tbl.fields ->> 'f1'::text))::integer) = (((i42.fields ->> 'f1'::text))::integer)) - -> Sort - Output: int4_tbl.fields, (((int4_tbl.fields ->> 'f1'::text))::integer) - Sort Key: (((int4_tbl.fields ->> 'f1'::text))::integer) - -> Foreign Scan on public.int4_tbl - Output: int4_tbl.fields, ((int4_tbl.fields ->> 'f1'::text))::integer - InfluxDB query: SELECT * FROM "int4_tbl" - -> Sort - Output: i42.fields, (((i42.fields ->> 'f1'::text))::integer) - Sort Key: (((i42.fields ->> 'f1'::text))::integer) - -> Foreign Scan on public.int4_tbl i42 - Output: i42.fields, ((i42.fields ->> 'f1'::text))::integer - InfluxDB query: SELECT * FROM "int4_tbl" - -> Materialize - Output: int8_tbl.fields - -> Foreign Scan on public.int8_tbl - Output: int8_tbl.fields - InfluxDB query: SELECT * FROM "int8_tbl" WHERE (("q1" = 0)) - -> Materialize - Output: i43.fields - -> Foreign Scan on public.int4_tbl i43 - Output: i43.fields - InfluxDB query: SELECT * FROM "int4_tbl" WHERE (("f1" = 0)) - -> Limit - Output: (((int4_tbl.fields ->> 'f1'::text))::integer), (((int8_tbl.fields ->> 'q1'::text))::bigint), (((int8_tbl.fields ->> 'q2'::text))::bigint), ((i42.fields ->> 'f1'::text)), ((i43.fields ->> 'f1'::text)), ((42)) - -> Foreign Scan on public.text_tbl - Output: ((int4_tbl.fields ->> 'f1'::text))::integer, ((int8_tbl.fields ->> 'q1'::text))::bigint, ((int8_tbl.fields ->> 'q2'::text))::bigint, (i42.fields ->> 'f1'::text), (i43.fields ->> 'f1'::text), (42) - InfluxDB query: SELECT * FROM "text_tbl" + Output: (((int4_tbl.fields ->> 'f1'::text))::integer), ((((int8_tbl.fields ->> 'q1'::text))::bigint)), ((((int8_tbl.fields ->> 'q2'::text))::bigint)), (((i42.fields ->> 'f1'::text))), (((i43.fields ->> 'f1'::text))), ((42)) + -> Merge Join + Output: int4_tbl.fields, ((i42.fields ->> 'f1'::text)), (((int8_tbl.fields ->> 'q1'::text))::bigint), (((int8_tbl.fields ->> 'q2'::text))::bigint), ((i43.fields ->> 'f1'::text)), (42) + Merge Cond: ((((int4_tbl.fields ->> 'f1'::text))::integer) = (((i42.fields ->> 'f1'::text))::integer)) + -> Sort + Output: int4_tbl.fields, (((int4_tbl.fields ->> 'f1'::text))::integer) + Sort Key: (((int4_tbl.fields ->> 'f1'::text))::integer) + -> Foreign Scan on public.int4_tbl + Output: int4_tbl.fields, ((int4_tbl.fields ->> 'f1'::text))::integer + InfluxDB query: SELECT * FROM "int4_tbl" + -> Sort + Output: (((int8_tbl.fields ->> 'q1'::text))::bigint), (((int8_tbl.fields ->> 'q2'::text))::bigint), ((i43.fields ->> 'f1'::text)), i42.fields, ((i42.fields ->> 'f1'::text)), (42), (((i42.fields ->> 'f1'::text))::integer) + Sort Key: (((i42.fields ->> 'f1'::text))::integer) + -> Nested Loop + Output: (((int8_tbl.fields ->> 'q1'::text))::bigint), (((int8_tbl.fields ->> 'q2'::text))::bigint), ((i43.fields ->> 'f1'::text)), i42.fields, ((i42.fields ->> 'f1'::text)), 42, ((i42.fields ->> 'f1'::text))::integer + -> Foreign Scan on public.int4_tbl i42 + Output: i42.fields, (i42.fields ->> 'f1'::text) + InfluxDB query: SELECT * FROM "int4_tbl" + -> Materialize + Output: (((int8_tbl.fields ->> 'q1'::text))::bigint), (((int8_tbl.fields ->> 'q2'::text))::bigint), ((i43.fields ->> 'f1'::text)) + -> Hash Join + Output: (((int8_tbl.fields ->> 'q1'::text))::bigint), (((int8_tbl.fields ->> 'q2'::text))::bigint), ((i43.fields ->> 'f1'::text)) + Hash Cond: (((int8_tbl.fields ->> 'q1'::text))::bigint = ((i43.fields ->> 'f1'::text))::bigint) + -> Foreign Scan on public.int8_tbl + Output: int8_tbl.fields, ((int8_tbl.fields ->> 'q1'::text))::bigint, ((int8_tbl.fields ->> 'q2'::text))::bigint + InfluxDB query: SELECT * FROM "int8_tbl" + -> Hash + Output: i43.fields, ((i43.fields ->> 'f1'::text)) + -> Foreign Scan on public.int4_tbl i43 + Output: i43.fields, (i43.fields ->> 'f1'::text) + Filter: (((i43.fields ->> 'f1'::text))::bigint = 0) + InfluxDB query: SELECT * FROM "int4_tbl" + -> Foreign Scan on public.text_tbl + Output: ((int4_tbl.fields ->> 'f1'::text))::integer, (((int8_tbl.fields ->> 'q1'::text))::bigint), (((int8_tbl.fields ->> 'q2'::text))::bigint), ((i42.fields ->> 'f1'::text)), ((i43.fields ->> 'f1'::text)), (42) + InfluxDB query: SELECT * FROM "text_tbl" LIMIT 1 (36 rows) ---Testcase 344: +--Testcase 356: select ss2.* from (select (fields->>'f1')::int4 f1 from INT4_TBL) i41 left join (select (fields->>'q1')::int8 q1, (fields->>'q2')::int8 q2 from INT8_TBL) i8 @@ -4727,26 +5568,26 @@ where (ss1.c2)::int8 = 0; -- -- test successful handling of full join underneath left join (bug #14105) -- ---Testcase 345: +--Testcase 357: explain (costs off) select * from (select 1 as id) as xx left join ((select (fields->>'unique1')::int4 unique1, (fields->>'unique2')::int4 unique2, (fields->>'two')::int4 two, (fields->>'four')::int4 four, (fields->>'ten')::int4 ten, (fields->>'twenty')::int4 twenty, (fields->>'hundred')::int4 hundred, (fields->>'thousand')::int4 thousand, (fields->>'twothousand')::int4 twothousand, (fields->>'fivethous')::int4 fivethous, (fields->>'tenthous')::int4 tenthous, (fields->>'odd')::int4 odd, (fields->>'even')::int4 even, (fields->>'stringu1')::name stringu1, (fields->>'stringu2')::name stringu2, (fields->>'string4')::name string4 from tenk1 a1) as a1 full join (select 1 as id) as yy on ((a1.unique1)::int4 = yy.id)) on (xx.id = coalesce(yy.id)); - QUERY PLAN ------------------------------------------------------------------------ + QUERY PLAN +------------------------------------------------------------------------- Nested Loop Left Join - Join Filter: ((1) = COALESCE((1))) -> Result -> Hash Full Join - Hash Cond: (((a1.fields ->> 'unique1'::text))::integer = (1)) + Hash Cond: ((((a1.fields ->> 'unique1'::text))::integer) = (1)) + Filter: (1 = COALESCE((1))) -> Foreign Scan on tenk1 a1 -> Hash -> Result (8 rows) ---Testcase 346: +--Testcase 358: select * from (select 1 as id) as xx left join @@ -4760,40 +5601,40 @@ select * from -- -- test ability to push constants through outer join clauses -- ---Testcase 347: +--Testcase 359: explain (costs off) select * from (select (fields->>'f1')::int4 f1 from INT4_TBL a) a left join (select (fields->>'unique1')::int4 unique1, (fields->>'unique2')::int4 unique2, (fields->>'two')::int4 two, (fields->>'four')::int4 four, (fields->>'ten')::int4 ten, (fields->>'twenty')::int4 twenty, (fields->>'hundred')::int4 hundred, (fields->>'thousand')::int4 thousand, (fields->>'twothousand')::int4 twothousand, (fields->>'fivethous')::int4 fivethous, (fields->>'tenthous')::int4 tenthous, (fields->>'odd')::int4 odd, (fields->>'even')::int4 even, (fields->>'stringu1')::name stringu1, (fields->>'stringu2')::name stringu2, (fields->>'string4')::name string4 from tenk1 b) b on (f1)::int4 = (unique2)::int4 where (f1)::int4 = 0; - QUERY PLAN -------------------------------------------------------------------------------------------------- - Hash Left Join - Hash Cond: (((a.fields ->> 'f1'::text))::integer = ((b.fields ->> 'unique2'::text))::integer) + QUERY PLAN +------------------------------------- + Nested Loop Left Join -> Foreign Scan on int4_tbl a - -> Hash + -> Materialize -> Foreign Scan on tenk1 b -(5 rows) +(4 rows) ---Testcase 348: +--Testcase 360: explain (costs off) select * from (select (fields->>'unique1')::int4 unique1, (fields->>'unique2')::int4 unique2, (fields->>'two')::int4 two, (fields->>'four')::int4 four, (fields->>'ten')::int4 ten, (fields->>'twenty')::int4 twenty, (fields->>'hundred')::int4 hundred, (fields->>'thousand')::int4 thousand, (fields->>'twothousand')::int4 twothousand, (fields->>'fivethous')::int4 fivethous, (fields->>'tenthous')::int4 tenthous, (fields->>'odd')::int4 odd, (fields->>'even')::int4 even, (fields->>'stringu1')::name stringu1, (fields->>'stringu2')::name stringu2, (fields->>'string4')::name string4 from tenk1 a) a full join (select (fields->>'unique1')::int4 unique1, (fields->>'unique2')::int4 unique2, (fields->>'two')::int4 two, (fields->>'four')::int4 four, (fields->>'ten')::int4 ten, (fields->>'twenty')::int4 twenty, (fields->>'hundred')::int4 hundred, (fields->>'thousand')::int4 thousand, (fields->>'twothousand')::int4 twothousand, (fields->>'fivethous')::int4 fivethous, (fields->>'tenthous')::int4 tenthous, (fields->>'odd')::int4 odd, (fields->>'even')::int4 even, (fields->>'stringu1')::name stringu1, (fields->>'stringu2')::name stringu2, (fields->>'string4')::name string4 from tenk1 b) b using(unique2) where (unique2)::int4 = 42; - QUERY PLAN ------------------------------------------------------------------------------------------------------- - Hash Full Join - Hash Cond: (((a.fields ->> 'unique2'::text))::integer = ((b.fields ->> 'unique2'::text))::integer) + QUERY PLAN +---------------------------------------------------------------------- + Merge Full Join -> Foreign Scan on tenk1 a - -> Hash + Filter: (((fields ->> 'unique2'::text))::integer = 42) + -> Materialize -> Foreign Scan on tenk1 b -(5 rows) + Filter: (((fields ->> 'unique2'::text))::integer = 42) +(6 rows) -- -- test that quals attached to an outer join have correct semantics, -- specifically that they don't re-use expressions computed below the join; -- we force a mergejoin so that coalesce(b.q1, 1) appears as a join input -- ---Testcase 349: +--Testcase 361: set enable_hashjoin to off; ---Testcase 350: +--Testcase 362: set enable_nestloop to off; ---Testcase 351: +--Testcase 363: explain (verbose, costs off) select (a.fields->>'q2')::int8 q2, (b.fields->>'q1')::int8 q1 from int8_tbl a left join int8_tbl b on (a.fields->>'q2')::int8 = coalesce((b.fields->>'q1')::int8, 1) @@ -4818,7 +5659,7 @@ explain (verbose, costs off) InfluxDB query: SELECT * FROM "int8_tbl" (16 rows) ---Testcase 352: +--Testcase 364: select (a.fields->>'q2')::int8 q2, (b.fields->>'q1')::int8 q1 from int8_tbl a left join int8_tbl b on (a.fields->>'q2')::int8 = coalesce((b.fields->>'q1')::int8, 1) where coalesce((b.fields->>'q1')::int8, 1) > 0; @@ -4836,36 +5677,160 @@ select (a.fields->>'q2')::int8 q2, (b.fields->>'q1')::int8 q1 4567890123456789 | 4567890123456789 (10 rows) ---Testcase 353: -reset enable_hashjoin; ---Testcase 354: -reset enable_nestloop; +--Testcase 365: +reset enable_hashjoin; +--Testcase 366: +reset enable_nestloop; +-- +-- test join strength reduction with a SubPlan providing the proof +-- +explain (costs off) +select (a.fields->>'unique1') unique1, (b.fields->>'unique2') unique2 + from onek a left join onek b on (a.fields->>'unique1')::int4 = (b.fields->>'unique2')::int4 + where (b.fields->>'unique2')::int4 = any (select (fields->>'q1')::int8 from int8_tbl c where (c.fields->>'q1')::int8 < (b.fields->>'unique1')::int4); + QUERY PLAN +----------------------------------------------------------------------------------------------------------- + Merge Join + Merge Cond: ((((b.fields ->> 'unique2'::text))::integer) = (((a.fields ->> 'unique1'::text))::integer)) + -> Sort + Sort Key: (((b.fields ->> 'unique2'::text))::integer) + -> Foreign Scan on onek b + Filter: (SubPlan 1) + SubPlan 1 + -> Foreign Scan on int8_tbl c + -> Sort + Sort Key: (((a.fields ->> 'unique1'::text))::integer) + -> Foreign Scan on onek a +(11 rows) + +select (a.fields->>'unique1') unique1, (b.fields->>'unique2') unique2 + from onek a left join onek b on (a.fields->>'unique1')::int4 = (b.fields->>'unique2')::int4 + where (b.fields->>'unique2')::int4 = any (select (fields->>'q1')::int8 from int8_tbl c where (c.fields->>'q1')::int8 < (b.fields->>'unique1')::int4); + unique1 | unique2 +---------+--------- + 123 | 123 +(1 row) + +-- +-- test full-join strength reduction +-- +explain (costs off) +select a.fields->>'unique1' unique1, b.fields->>'unique2' unique2 + from onek a full join onek b on (a.fields->>'unique1')::int4 = (b.fields->>'unique2')::int4 + where (a.fields->>'unique1')::int4 = 42; + QUERY PLAN +------------------------------------ + Nested Loop Left Join + -> Foreign Scan on onek a + -> Materialize + -> Foreign Scan on onek b +(4 rows) + +select a.fields->>'unique1' unique1, b.fields->>'unique2' unique2 + from onek a full join onek b on (a.fields->>'unique1')::int4 = (b.fields->>'unique2')::int4 + where (a.fields->>'unique1')::int4 = 42; + unique1 | unique2 +---------+--------- + 42 | 42 +(1 row) + +explain (costs off) +select a.fields->>'unique1' unique1, b.fields->>'unique2' unique2 + from onek a full join onek b on (a.fields->>'unique1')::int4 = (b.fields->>'unique2')::int4 + where (b.fields->>'unique2')::int4 = 43; + QUERY PLAN +------------------------------------ + Nested Loop Left Join + -> Foreign Scan on onek b + -> Materialize + -> Foreign Scan on onek a +(4 rows) + +select a.fields->>'unique1' unique1, b.fields->>'unique2' unique2 + from onek a full join onek b on (a.fields->>'unique1')::int4 = (b.fields->>'unique2')::int4 + where (b.fields->>'unique2')::int4 = 43; + unique1 | unique2 +---------+--------- + 43 | 43 +(1 row) + +explain (costs off) +select a.fields->>'unique1', b.fields->>'unique2' + from onek a full join onek b on (a.fields->>'unique1')::int4 = (b.fields->>'unique2')::int4 + where (a.fields->>'unique1')::int4 = 42 and (b.fields->>'unique2')::int4 = 42; + QUERY PLAN +------------------------------------ + Nested Loop + -> Foreign Scan on onek a + -> Materialize + -> Foreign Scan on onek b +(4 rows) + +select a.fields->>'unique1', b.fields->>'unique2' + from onek a full join onek b on (a.fields->>'unique1')::int4 = (b.fields->>'unique2')::int4 + where (a.fields->>'unique1')::int4 = 42 and (b.fields->>'unique2')::int4 = 42; + ?column? | ?column? +----------+---------- + 42 | 42 +(1 row) + +-- +-- 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 (i81.fields->>'q2')::int8=v1) ss1 +full join + (select * from (values(456,2)) w(v1,v2) join int8_tbl i82 on (i82.fields->>'q2')::int8=v1) ss2 +on true; + QUERY PLAN +------------------------------------------ + Merge Full Join + -> Foreign Scan on int8_tbl i81 + -> Materialize + -> Foreign Scan on int8_tbl i82 +(4 rows) + +select * from + (select * from int8_tbl i81 join (values(123,2)) v(v1,v2) on (i81.fields->>'q2')::int8=v1) ss1 +full join + (select * from (values(456,2)) w(v1,v2) join int8_tbl i82 on (i82.fields->>'q2')::int8=v1) ss2 +on true; + fields | v1 | v2 | v1 | v2 | fields +-----------------------------------------+-----+----+-----+----+---------------------------- + {"q1": "4567890123456789", "q2": "123"} | 123 | 2 | 456 | 2 | {"q1": "123", "q2": "456"} +(1 row) + -- -- test join removal -- begin; ---Testcase 355: +--Testcase 367: CREATE FOREIGN TABLE a (fields jsonb OPTIONS (fields 'true')) SERVER influxdb_svr OPTIONS(schemaless 'true'); +--Testcase 615: CREATE FOREIGN TABLE a_nsc (id int, b_id int) SERVER influxdb_svr OPTIONS (table 'a'); ---Testcase 356: +--Testcase 368: CREATE FOREIGN TABLE b (fields jsonb OPTIONS (fields 'true')) SERVER influxdb_svr OPTIONS(schemaless 'true'); +--Testcase 616: CREATE FOREIGN TABLE b_nsc (id int, c_id int) SERVER influxdb_svr OPTIONS (table 'b'); ---Testcase 357: +--Testcase 369: CREATE FOREIGN TABLE c (fields jsonb OPTIONS (fields 'true')) SERVER influxdb_svr OPTIONS(schemaless 'true'); +--Testcase 617: CREATE FOREIGN TABLE c_nsc (id int) SERVER influxdb_svr OPTIONS (table 'c'); ---Testcase 358: +--Testcase 370: CREATE FOREIGN TABLE d (fields jsonb OPTIONS (fields 'true')) SERVER influxdb_svr OPTIONS(schemaless 'true'); +--Testcase 618: CREATE FOREIGN TABLE d_nsc (a int, b int) SERVER influxdb_svr OPTIONS (table 'd'); ---Testcase 359: +--Testcase 371: INSERT INTO a_nsc VALUES (0, 0), (1, NULL); ---Testcase 360: +--Testcase 372: INSERT INTO b_nsc VALUES (0, 0), (1, NULL); ---Testcase 361: +--Testcase 373: INSERT INTO c_nsc VALUES (0), (1); ---Testcase 362: +--Testcase 374: INSERT INTO d_nsc VALUES (1,3), (2,2), (3,1); -- all three cases should be optimizable into a simple seqscan ---Testcase 363: +--Testcase 375: explain (costs off) SELECT a.* FROM (select (fields->>'id')::int id, (fields->>'b_id')::int b_id from a) a LEFT JOIN (select (fields->>'id')::int id, (fields->>'c_id')::int c_id from b) b ON a.b_id = b.id; QUERY PLAN --------------------------------------------------------------------------------------------------- @@ -4879,7 +5844,7 @@ explain (costs off) SELECT a.* FROM (select (fields->>'id')::int id, (fields->>' -> Foreign Scan on b (8 rows) ---Testcase 364: +--Testcase 376: explain (costs off) SELECT b.* FROM (select (fields->>'id')::int id, (fields->>'c_id')::int c_id from b) b LEFT JOIN (select (fields->>'id')::int id from c) c ON b.c_id = c.id; QUERY PLAN --------------------------------------------------------------------------------------------------- @@ -4893,7 +5858,7 @@ explain (costs off) SELECT b.* FROM (select (fields->>'id')::int id, (fields->>' -> Foreign Scan on c (8 rows) ---Testcase 365: +--Testcase 377: explain (costs off) SELECT a.* FROM (select (fields->>'id')::int id, (fields->>'b_id')::int b_id from a) a LEFT JOIN ((select (fields->>'id')::int id, (fields->>'c_id')::int c_id from b) b left join (select (fields->>'id')::int id from c) c on b.c_id = c.id) ON (a.b_id = b.id); @@ -4917,7 +5882,7 @@ explain (costs off) (15 rows) -- check optimization of outer join within another special join ---Testcase 366: +--Testcase 378: explain (costs off) select (fields->>'id')::int id from a where (fields->>'id')::int in ( select (b.fields->>'id')::int from b left join c on (b.fields->>'id')::int = (c.fields->>'id')::int @@ -4940,9 +5905,248 @@ select (fields->>'id')::int id from a where (fields->>'id')::int in ( -> Foreign Scan on c (14 rows) +-- check optimization with oddly-nested outer joins +explain (costs off) +select a1.fields->>'id' id from + (a a1 left join a a2 on true) + left join + (a a3 left join a a4 on (a3.fields->>'id')::int = (a4.fields->>'id')::int) + on (a2.fields->>'id')::int = (a3.fields->>'id')::int; + QUERY PLAN +--------------------------------------------------------------------------------------------------------------------------- + Nested Loop Left Join + -> Foreign Scan on a a1 + -> Materialize + -> Merge Left Join + Merge Cond: ((((a2.fields ->> 'id'::text))::integer) = ((a3.fields ->> 'id'::text))::integer) + -> Sort + Sort Key: (((a2.fields ->> 'id'::text))::integer) + -> Foreign Scan on a a2 + -> Materialize + -> Merge Left Join + Merge Cond: ((((a3.fields ->> 'id'::text))::integer) = (((a4.fields ->> 'id'::text))::integer)) + -> Sort + Sort Key: (((a3.fields ->> 'id'::text))::integer) + -> Foreign Scan on a a3 + -> Sort + Sort Key: (((a4.fields ->> 'id'::text))::integer) + -> Foreign Scan on a a4 +(17 rows) + +explain (costs off) +select a1.fields->>'id' id from + (a a1 left join a a2 on (a1.fields->>'id')::int = (a2.fields->>'id')::int) + left join + (a a3 left join a a4 on (a3.fields->>'id')::int = (a4.fields->>'id')::int) + on (a2.fields->>'id')::int = (a3.fields->>'id')::int; + QUERY PLAN +--------------------------------------------------------------------------------------------------------------- + Merge Right Join + Merge Cond: (((a3.fields ->> 'id'::text))::integer = (((a2.fields ->> 'id'::text))::integer)) + -> Merge Left Join + Merge Cond: ((((a3.fields ->> 'id'::text))::integer) = (((a4.fields ->> 'id'::text))::integer)) + -> Sort + Sort Key: (((a3.fields ->> 'id'::text))::integer) + -> Foreign Scan on a a3 + -> Sort + Sort Key: (((a4.fields ->> 'id'::text))::integer) + -> Foreign Scan on a a4 + -> Sort + Sort Key: (((a2.fields ->> 'id'::text))::integer) + -> Merge Left Join + Merge Cond: ((((a1.fields ->> 'id'::text))::integer) = (((a2.fields ->> 'id'::text))::integer)) + -> Sort + Sort Key: (((a1.fields ->> 'id'::text))::integer) + -> Foreign Scan on a a1 + -> Sort + Sort Key: (((a2.fields ->> 'id'::text))::integer) + -> Foreign Scan on a a2 +(20 rows) + +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.fields->>'id')::int = (t4.fields->>'id')::int and (t2.fields->>'id')::int = (t3.fields->>'id')::int; + QUERY PLAN +--------------------------------------------------------------------------------------------------- + Merge Left Join + Merge Cond: ((((t2.fields ->> 'id'::text))::integer) = (((t4.fields ->> 'id'::text))::integer)) + Join Filter: ((((t2.fields ->> 'id'::text))::integer) = ((t3.fields ->> 'id'::text))::integer) + -> Sort + Sort Key: (((t2.fields ->> 'id'::text))::integer) + -> Nested Loop + -> Nested Loop Left Join + -> Foreign Scan on a t1 + -> Materialize + -> Foreign Scan on a t2 + -> Materialize + -> Foreign Scan on a t3 + -> Sort + Sort Key: (((t4.fields ->> 'id'::text))::integer) + -> Foreign Scan on a t4 +(15 rows) + +-- 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.fields->>'f1')::int = (t4.fields->>'f1')::int + left join ((select null as f1 from int4_tbl as t6) as ss1 + inner join int8_tbl as t7 on null) + on (t5.fields->>'q1')::int = (t7.fields->>'q2')::int) + on false; + QUERY PLAN +----------------------------------- + Nested Loop Left Join + Join Filter: false + -> Foreign Scan on int4_tbl t1 + -> Result + One-Time Filter: false +(5 rows) + +-- 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.fields->>'f1')::int = (t4.fields->>'f1')::int + left join ((select t6.fields->>'f1' f1 from int4_tbl as t6) as ss1 + inner join int8_tbl as t7 on null) + on (t5.fields->>'q1')::int = (t7.fields->>'q2')::int) + on false; + QUERY PLAN +----------------------------------- + Nested Loop Left Join + Join Filter: false + -> Foreign Scan on int4_tbl t1 + -> Result + One-Time Filter: false +(5 rows) + +-- per further discussion of bug #17781 +explain (costs off) +select ss1.x +from (select (i4.fields->>'f1')::int4/2 as x from int4_tbl i4 left join a on (a.fields->>'id')::int4 = (i4.fields->>'f1')::int4) ss1 + right join int8_tbl i8 on true +where current_user is not null; -- this is to add a Result node + QUERY PLAN +-------------------------------------------------------------------------------------------------------------------- + Result + One-Time Filter: (CURRENT_USER IS NOT NULL) + -> Nested Loop Left Join + -> Foreign Scan on int8_tbl i8 + -> Materialize + -> Merge Left Join + Merge Cond: ((((i4.fields ->> 'f1'::text))::integer) = (((a.fields ->> 'id'::text))::integer)) + -> Sort + Sort Key: (((i4.fields ->> 'f1'::text))::integer) + -> Foreign Scan on int4_tbl i4 + -> Sort + Sort Key: (((a.fields ->> 'id'::text))::integer) + -> Foreign Scan on a +(13 rows) + +-- 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.fields->>'q1')::int8 > (t3.fields->>'unique1')::int8) + on (t1.fields->>'q2')::int8 = (t2.fields->>'q2')::int8 + left join onek t4 + on (t2.fields->>'q2')::int8 < (t3.fields->>'unique2')::int8; + QUERY PLAN +--------------------------------------------------------------------------------------------------------------------------- + Nested Loop Left Join + Join Filter: (((t2.fields ->> 'q2'::text))::bigint < ((t3.fields ->> 'unique2'::text))::bigint) + -> Merge Left Join + Merge Cond: ((((t1.fields ->> 'q2'::text))::bigint) = (((t2.fields ->> 'q2'::text))::bigint)) + -> Sort + Sort Key: (((t1.fields ->> 'q2'::text))::bigint) + -> Foreign Scan on int8_tbl t1 + -> Materialize + -> Sort + Sort Key: (((t2.fields ->> 'q2'::text))::bigint) + -> Nested Loop Left Join + Join Filter: (((t2.fields ->> 'q1'::text))::bigint > ((t3.fields ->> 'unique1'::text))::bigint) + -> Foreign Scan on int8_tbl t2 + -> Materialize + -> Foreign Scan on onek t3 + -> Materialize + -> Foreign Scan on onek t4 +(17 rows) + +-- 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.fields->>'q2')::int8 = (t4.fields->>'q2')::int8) +on (t1.fields->>'q1')::int8 = (t2.fields->>'q1')::int8; + QUERY PLAN +----------------------------------------------------------------------------------------- + Hash Left Join + Hash Cond: (((t1.fields ->> 'q1'::text))::bigint = ((fields ->> 'q1'::text))::bigint) + -> Foreign Scan on int8_tbl t1 + -> Hash + -> Result + One-Time Filter: false +(6 rows) + +-- 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.fields->>'q1')::int8-(t3.fields->>'q2')::int8) = 0 and ((t2.fields->>'q1')::int8-(t3.fields->>'q2')::int8) = 1 + left join int8_tbl t4 on (t2.fields->>'q2')::int8 = (t4.fields->>'q2')::int8) +on (t1.fields->>'q1')::int8 = (t2.fields->>'q1')::int8; + QUERY PLAN +----------------------------------------------------------------------------------------- + Hash Left Join + Hash Cond: (((t1.fields ->> 'q1'::text))::bigint = ((fields ->> 'q1'::text))::bigint) + -> Foreign Scan on int8_tbl t1 + -> Hash + -> Result + One-Time Filter: false +(6 rows) + +-- 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.fields->>'f1')::int4 = 1 + left join int8_tbl t4 on (t2.fields->>'q2')::int8 = (t4.fields->>'q2')::int8) + on (t1.fields->>'q1')::int8 = (t2.fields->>'q1')::int8 +) from int4_tbl x0; + QUERY PLAN +------------------------------------------------------------------------------------------------------------ + Foreign Scan on int4_tbl x0 + SubPlan 1 + -> Nested Loop Left Join + Join Filter: (((t2.fields ->> 'q2'::text))::bigint = ((t4.fields ->> 'q2'::text))::bigint) + -> Nested Loop Left Join + Join Filter: (((t1.fields ->> 'q1'::text))::bigint = ((t2.fields ->> 'q1'::text))::bigint) + -> Foreign Scan on int8_tbl t1 + -> Materialize + -> Result + One-Time Filter: (((x0.fields ->> 'f1'::text))::integer = 1) + -> Nested Loop + -> Foreign Scan on int8_tbl t3 + -> Materialize + -> Foreign Scan on int8_tbl t2 + -> Materialize + -> Foreign Scan on int8_tbl t4 +(16 rows) + -- check that join removal works for a left join when joining a subquery -- that is guaranteed to be unique by its GROUP BY clause ---Testcase 367: +--Testcase 379: explain (costs off) select d.* from (select (fields->>'a')::int a, (fields->>'b')::int b from d) d left join (select * from (select (fields->>'id')::int id, (fields->>'c_id')::int c_id from b) b group by b.id, b.c_id) s on (d.a)::int = (s.id)::int and (d.b)::int = (s.c_id)::int; @@ -4952,7 +6156,7 @@ select d.* from (select (fields->>'a')::int a, (fields->>'b')::int b from d) d l (1 row) -- similarly, but keying off a DISTINCT clause ---Testcase 368: +--Testcase 380: explain (costs off) select d.* from (select (fields->>'a')::int a, (fields->>'b')::int b from d) d left join (select distinct * from (select (fields->>'id')::int id, (fields->>'c_id')::int c_id from b) b) s on (d.a)::int = (s.id)::int and (d.b)::int = (s.c_id)::int; @@ -4965,7 +6169,7 @@ select d.* from (select (fields->>'a')::int a, (fields->>'b')::int b from d) d l -- 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.) ---Testcase 369: +--Testcase 381: explain (costs off) select d.* from (select (fields->>'a')::int a, (fields->>'b')::int b from d) d left join (select * from (select (fields->>'id')::int id, (fields->>'c_id')::int c_id from b) b group by b.id, b.c_id) s on (d.a)::int = (s.id)::int; @@ -4985,7 +6189,7 @@ select d.* from (select (fields->>'a')::int a, (fields->>'b')::int b from d) d l (11 rows) -- similarly, but keying off a DISTINCT clause ---Testcase 370: +--Testcase 382: explain (costs off) select d.* from (select (fields->>'a')::int a, (fields->>'b')::int b from d) d left join (select distinct * from (select (fields->>'id')::int id, (fields->>'c_id')::int c_id from b) b) s on (d.a)::int = (s.id)::int; @@ -5004,9 +6208,25 @@ select d.* from (select (fields->>'a')::int a, (fields->>'b')::int b from d) d l -> Foreign Scan on d (11 rows) +-- join removal is not possible here +explain (costs off) +select 1 from a t1 + left join (a t2 left join a t3 on (t2.fields->>'id')::int = 1) on (t2.fields->>'id')::int = 1; + QUERY PLAN +------------------------------------------------------------------------ + Nested Loop Left Join + -> Foreign Scan on a t1 + -> Materialize + -> Nested Loop Left Join + Join Filter: (((t2.fields ->> 'id'::text))::integer = 1) + -> Foreign Scan on a t2 + -> Materialize + -> Foreign Scan on a t3 +(8 rows) + -- check join removal works when uniqueness of the join condition is enforced -- by a UNION ---Testcase 371: +--Testcase 383: explain (costs off) select d.* from (select (fields->>'a')::int a, (fields->>'b')::int b from d) d left join (select (fields->>'id')::int id from a union select (fields->>'id')::int id from b) s on (d.a)::int = (s.id)::int; @@ -5016,7 +6236,7 @@ select d.* from (select (fields->>'a')::int a, (fields->>'b')::int b from d) d l (1 row) -- check join removal with a cross-type comparison operator ---Testcase 372: +--Testcase 384: explain (costs off) select i8.* from (select (fields->>'q1')::int8 q1, (fields->>'q2')::int8 q2 from INT8_TBL i8) i8 left join (select (fields->>'f1')::int f1 from int4_tbl group by (fields->>'f1')::int) i4 on (i8.q1)::int8 = (i4.f1)::int4; @@ -5026,7 +6246,7 @@ select i8.* from (select (fields->>'q1')::int8 q1, (fields->>'q2')::int8 q2 from (1 row) -- check join removal with lateral references ---Testcase 373: +--Testcase 385: explain (costs off) select 1 from (select (a.fields->>'id')::int id FROM a left join b on (a.fields->>'b_id')::int = (b.fields->>'id')::int) q, lateral generate_series(1, (q.id)::int) gs(i) where (q.id)::int = (gs.i)::int; @@ -5045,39 +6265,80 @@ select 1 from (select (a.fields->>'id')::int id FROM a left join b on (a.fields- Filter: (((a.fields ->> 'id'::text))::integer = i) (11 rows) ---Testcase 374: +-- check join removal within RHS of an outer join +explain (costs off) +select c.fields->>'id', ss.a from c + left join (select d.fields->>'a' a from onerow, d left join b on (d.fields->>'a')::int = (b.fields->>'id')::int) ss + on (c.fields->>'id')::int = ss.a::int; + QUERY PLAN +------------------------------------------------------------------------------------------------------------ + Merge Left Join + Merge Cond: ((((c.fields ->> 'id'::text))::integer) = ((d.fields ->> 'a'::text))::integer) + -> Sort + Sort Key: (((c.fields ->> 'id'::text))::integer) + -> Foreign Scan on c + -> Materialize + -> Merge Left Join + Merge Cond: ((((d.fields ->> 'a'::text))::integer) = (((b.fields ->> 'id'::text))::integer)) + -> Sort + Sort Key: (((d.fields ->> 'a'::text))::integer) + -> Nested Loop + -> Seq Scan on onerow + -> Foreign Scan on d + -> Sort + Sort Key: (((b.fields ->> 'id'::text))::integer) + -> Foreign Scan on b +(16 rows) + +CREATE TEMP TABLE parted_b (id int PRIMARY KEY) partition by range(id); +CREATE TEMP TABLE parted_b1 partition of parted_b for values from (0) to (10); +-- test join removals on a partitioned table +explain (costs off) +select a.* from a left join parted_b pb on (a.fields->>'b_id')::int = pb.id; + QUERY PLAN +------------------- + Foreign Scan on a +(1 row) + +--Testcase 386: DELETE FROM a_nsc; ---Testcase 375: +--Testcase 387: DELETE FROM b_nsc; ---Testcase 376: +--Testcase 388: DELETE FROM c_nsc; ---Testcase 377: +--Testcase 389: DELETE FROM d_nsc; ---Testcase 378: +--Testcase 390: DROP FOREIGN TABLE a; +--Testcase 619: DROP FOREIGN TABLE a_nsc; ---Testcase 379: +--Testcase 391: DROP FOREIGN TABLE b; +--Testcase 620: DROP FOREIGN TABLE b_nsc; ---Testcase 380: +--Testcase 392: DROP FOREIGN TABLE c; +--Testcase 621: DROP FOREIGN TABLE c_nsc; ---Testcase 381: +--Testcase 393: DROP FOREIGN TABLE d; +--Testcase 622: DROP FOREIGN TABLE d_nsc; rollback; ---Testcase 382: +--Testcase 394: create foreign table parent (fields jsonb OPTIONS (fields 'true')) server influxdb_svr OPTIONS(schemaless 'true'); +--Testcase 623: create foreign table parent_nsc (k int, pd int) server influxdb_svr OPTIONS (table 'parent'); ---Testcase 383: +--Testcase 395: create foreign table child (fields jsonb OPTIONS (fields 'true')) server influxdb_svr OPTIONS(schemaless 'true'); +--Testcase 624: create foreign table child_nsc (k int, cd int) server influxdb_svr OPTIONS (table 'child'); ---Testcase 384: +--Testcase 396: insert into parent_nsc values (1, 10), (2, 20), (3, 30); ---Testcase 385: +--Testcase 397: insert into child_nsc values (1, 100), (4, 400); -- this case is optimizable ---Testcase 386: +--Testcase 398: select p.* from (select (fields->>'k')::int k, (fields->>'pd')::int pd from parent p) p left join (select (fields->>'k')::int k, (fields->>'cd')::int cd from child c) c on ((p.k)::int = (c.k)::int); k | pd ---+---- @@ -5086,7 +6347,7 @@ select p.* from (select (fields->>'k')::int k, (fields->>'pd')::int pd from pare 3 | 30 (3 rows) ---Testcase 387: +--Testcase 399: explain (costs off) select p.* from (select (fields->>'k')::int k, (fields->>'pd')::int pd from parent p) p left join (select (fields->>'k')::int k, (fields->>'cd')::int cd from child c) c on ((p.k)::int = (c.k)::int); QUERY PLAN @@ -5102,7 +6363,7 @@ explain (costs off) (8 rows) -- this case is not ---Testcase 388: +--Testcase 400: select p.*, linked from (select (fields->>'k')::int k, (fields->>'pd')::int pd from parent p) p left join (select c.*, true as linked from (select (fields->>'k')::int k, (fields->>'cd')::int cd from child c) c) as ss on (p.k = ss.k); @@ -5113,7 +6374,7 @@ select p.*, linked from (select (fields->>'k')::int k, (fields->>'pd')::int pd f 3 | 30 | (3 rows) ---Testcase 389: +--Testcase 401: explain (costs off) select p.*, linked from (select (fields->>'k')::int k, (fields->>'pd')::int pd from parent p) p left join (select c.*, true as linked from (select (fields->>'k')::int k, (fields->>'cd')::int cd from child c) c) as ss @@ -5131,7 +6392,7 @@ explain (costs off) (8 rows) -- check for a 9.0rc1 bug: join removal breaks pseudoconstant qual handling ---Testcase 390: +--Testcase 402: select p.* from (select (fields->>'k')::int k, (fields->>'pd')::int pd from parent) p left join (select (fields->>'k')::int k, (fields->>'cd')::int cd from child) c on ((p.k)::int = (c.k)::int) where (p.k)::int = 1 and (p.k)::int = 2; @@ -5139,7 +6400,7 @@ select p.* from ---+---- (0 rows) ---Testcase 391: +--Testcase 403: explain (costs off) select p.* from (select (fields->>'k')::int k, (fields->>'pd')::int pd from parent) p left join (select (fields->>'k')::int k, (fields->>'cd')::int cd from child) c on ((p.k)::int = (c.k)::int) @@ -5150,7 +6411,7 @@ select p.* from One-Time Filter: false (2 rows) ---Testcase 392: +--Testcase 404: select p.* from ((select (fields->>'k')::int k, (fields->>'pd')::int pd from parent) p left join (select (fields->>'k')::int k, (fields->>'cd')::int cd from child) c on ((p.k)::int = (c.k)::int)) join (select (fields->>'k')::int k, (fields->>'pd')::int pd from parent) x on (p.k)::int = (x.k)::int where (p.k)::int = 1 and (p.k)::int = 2; @@ -5158,7 +6419,7 @@ select p.* from ---+---- (0 rows) ---Testcase 393: +--Testcase 405: explain (costs off) select p.* from ((select (fields->>'k')::int k, (fields->>'pd')::int pd from parent) p left join (select (fields->>'k')::int k, (fields->>'cd')::int cd from child) c on ((p.k)::int = (c.k)::int)) join (select (fields->>'k')::int k, (fields->>'pd')::int pd from parent) x on (p.k)::int = (x.k)::int @@ -5171,49 +6432,54 @@ select p.* from -- bug 5255: this is not optimizable by join removal begin; ---Testcase 394: +--Testcase 406: CREATE FOREIGN TABLE a (fields jsonb OPTIONS (fields 'true')) SERVER influxdb_svr OPTIONS(schemaless 'true'); +--Testcase 625: CREATE FOREIGN TABLE a_nsc (id int) SERVER influxdb_svr OPTIONS (table 'a'); ---Testcase 395: +--Testcase 407: CREATE FOREIGN TABLE b (fields jsonb OPTIONS (fields 'true')) SERVER influxdb_svr OPTIONS(schemaless 'true'); +--Testcase 626: CREATE FOREIGN TABLE b_nsc (id int, a_id int) SERVER influxdb_svr OPTIONS (table 'b'); ---Testcase 396: +--Testcase 408: INSERT INTO a_nsc VALUES (0), (1); ---Testcase 397: +--Testcase 409: INSERT INTO b_nsc VALUES (0, 0), (1, NULL); ---Testcase 398: +--Testcase 410: SELECT * FROM (select (fields->>'id')::int id, (fields->>'a_id')::int a_id from b) b LEFT JOIN (select (fields->>'id')::int id from a) a ON ((b.a_id)::int = (a.id)::int) WHERE ((a.id)::int IS NULL OR (a.id)::int > 0); id | a_id | id ----+------+---- 1 | | (1 row) ---Testcase 399: +--Testcase 411: SELECT b.* FROM (select (fields->>'id')::int id, (fields->>'a_id')::int a_id from b) b LEFT JOIN (select (fields->>'id')::int id from a) a ON ((b.a_id)::int = (a.id)::int) WHERE ((a.id)::int IS NULL OR (a.id)::int > 0); id | a_id ----+------ 1 | (1 row) ---Testcase 400: +--Testcase 412: DELETE FROM a_nsc; ---Testcase 401: +--Testcase 413: DELETE FROM b_nsc; ---Testcase 402: +--Testcase 414: DROP FOREIGN TABLE a; +--Testcase 627: DROP FOREIGN TABLE a_nsc; ---Testcase 403: +--Testcase 415: DROP FOREIGN TABLE b; +--Testcase 628: DROP FOREIGN TABLE b_nsc; rollback; -- another join removal bug: this is not optimizable, either begin; ---Testcase 404: +--Testcase 416: create foreign table innertab (fields jsonb OPTIONS (fields 'true')) server influxdb_svr OPTIONS(schemaless 'true'); +--Testcase 629: create foreign table innertab_nsc (id int8, dat1 int8) server influxdb_svr OPTIONS (table 'innertab'); ---Testcase 405: +--Testcase 417: insert into innertab_nsc values(123, 42); ---Testcase 406: +--Testcase 418: SELECT * FROM (SELECT 1 AS x) ss1 LEFT JOIN @@ -5229,16 +6495,79 @@ SELECT * FROM 1 | 4567890123456789 | 4567890123456789 | 4567890123456789 (5 rows) +-- join removal bug #17769: can't remove if there's a pushed-down reference +EXPLAIN (COSTS OFF) +SELECT q2 FROM + (SELECT (int8_tbl.fields->>'q1')::int8 q1, (int8_tbl.fields->>'q2')::int8 q2, (innertab.fields->>'id')::int id, (innertab.fields->>'dat1')::int dat1 + FROM int8_tbl LEFT JOIN innertab ON (int8_tbl.fields->>'q2')::int8 = (innertab.fields->>'id')::int) ss + WHERE COALESCE(dat1, 0) = q1; + QUERY PLAN +--------------------------------------------------------------------------------------------------------------------- + Merge Left Join + Merge Cond: ((((int8_tbl.fields ->> 'q2'::text))::bigint) = (((innertab.fields ->> 'id'::text))::integer)) + Filter: (COALESCE(((innertab.fields ->> 'dat1'::text))::integer, 0) = ((int8_tbl.fields ->> 'q1'::text))::bigint) + -> Sort + Sort Key: (((int8_tbl.fields ->> 'q2'::text))::bigint) + -> Foreign Scan on int8_tbl + -> Sort + Sort Key: (((innertab.fields ->> 'id'::text))::integer) + -> Foreign Scan on innertab +(9 rows) + +-- join removal bug #17773: otherwise-removable PHV appears in a qual condition +EXPLAIN (VERBOSE, COSTS OFF) +SELECT q2 FROM + (SELECT (int8_tbl.fields->>'q2')::int8 q2, 'constant'::text AS x + FROM int8_tbl LEFT JOIN innertab ON (int8_tbl.fields->>'q2')::int8 = (innertab.fields->>'id')::int) ss + RIGHT JOIN int4_tbl ON NULL + WHERE x >= x; + QUERY PLAN +--------------------------------------------------------------------- + Nested Loop Left Join + Output: (((fields ->> 'q2'::text))::bigint) + Join Filter: NULL::boolean + Filter: (('constant'::text) >= ('constant'::text)) + -> Foreign Scan on public.int4_tbl + Output: int4_tbl.fields + InfluxDB query: SELECT * FROM "int4_tbl" + -> Result + Output: ((fields ->> 'q2'::text))::bigint, 'constant'::text + One-Time Filter: false +(10 rows) + +-- join removal bug #17786: check that OR conditions are cleaned up +EXPLAIN (COSTS OFF) +SELECT (int4_tbl.fields->>'f1'), x +FROM int4_tbl + JOIN ((SELECT 42 AS x FROM int8_tbl LEFT JOIN innertab ON (int8_tbl.fields->>'q1')::int8 = (innertab.fields->>'id')::int) AS ss1 + RIGHT JOIN tenk1 ON NULL) + ON (tenk1.fields->>'unique1')::int = ss1.x OR (tenk1.fields->>'unique2')::int = ss1.x; + QUERY PLAN +------------------------------------------------------------------------------------------------------------------------------------------ + Nested Loop + -> Foreign Scan on int4_tbl + -> Materialize + -> Nested Loop Left Join + Join Filter: NULL::boolean + Filter: ((((tenk1.fields ->> 'unique1'::text))::integer = (42)) OR (((tenk1.fields ->> 'unique2'::text))::integer = (42))) + -> Foreign Scan on tenk1 + -> Result + One-Time Filter: false +(9 rows) + -- Clean up +--Testcase 630: DELETE FROM innertab_nsc; +--Testcase 631: DROP FOREIGN TABLE innertab; +--Testcase 632: DROP FOREIGN TABLE innertab_nsc; rollback; -- another join removal bug: we must clean up correctly when removing a PHV begin; ---Testcase 407: +--Testcase 419: create foreign table uniquetbl (fields jsonb OPTIONS (fields 'true')) server influxdb_svr OPTIONS(schemaless 'true'); ---Testcase 408: +--Testcase 420: explain (costs off) select t1.* from (select fields->>'f1' f1 from uniquetbl t1) as t1 @@ -5265,7 +6594,7 @@ select t1.* from -> Foreign Scan on uniquetbl t1 (15 rows) ---Testcase 409: +--Testcase 421: explain (costs off) select t0.* from @@ -5280,21 +6609,21 @@ from where ss.stringu2 !~* ss.case1; QUERY PLAN ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- - Merge Join - Merge Cond: (((t0.fields ->> 'f1'::text)) = (CASE ((t1.fields ->> 'ten'::text))::integer WHEN 0 THEN 'doh!'::text ELSE NULL::text END)) + Merge Right Join + Merge Cond: (((u1.fields ->> 'f1'::text)) = (((t1.fields ->> 'string4'::text))::name)) -> Sort - Sort Key: ((t0.fields ->> 'f1'::text)) - -> Foreign Scan on text_tbl t0 + Sort Key: ((u1.fields ->> 'f1'::text)) + -> Foreign Scan on uniquetbl u1 -> Materialize -> Sort - Sort Key: (CASE ((t1.fields ->> 'ten'::text))::integer WHEN 0 THEN 'doh!'::text ELSE NULL::text END) - -> Merge Right Join - Merge Cond: (((u1.fields ->> 'f1'::text)) = ((((t1.fields ->> 'string4'::text))::name)::text)) + Sort Key: (((t1.fields ->> 'string4'::text))::name) COLLATE "default" + -> Merge Join + Merge Cond: (((t0.fields ->> 'f1'::text)) = (CASE ((t1.fields ->> 'ten'::text))::integer WHEN 0 THEN 'doh!'::text ELSE NULL::text END)) -> Sort - Sort Key: ((u1.fields ->> 'f1'::text)) - -> Foreign Scan on uniquetbl u1 + Sort Key: ((t0.fields ->> 'f1'::text)) + -> Foreign Scan on text_tbl t0 -> Sort - Sort Key: ((((t1.fields ->> 'string4'::text))::name)::text) + Sort Key: (CASE ((t1.fields ->> 'ten'::text))::integer WHEN 0 THEN 'doh!'::text ELSE NULL::text END) -> Merge Join Merge Cond: ((((t1.fields ->> 'unique2'::text))::integer) = (((i4.fields ->> 'f1'::text))::integer)) -> Sort @@ -5306,7 +6635,7 @@ where ss.stringu2 !~* ss.case1; -> Foreign Scan on int4_tbl i4 (24 rows) ---Testcase 410: +--Testcase 422: select t0.* from (select fields->>'f1' f1 from text_tbl t0) t0 @@ -5323,9 +6652,120 @@ where ss.stringu2 !~* ss.case1; doh! (1 row) +rollback; +-- another join removal bug: we must clean up EquivalenceClasses too +begin; +create foreign table t (fields jsonb OPTIONS (fields 'true')) server influxdb_svr OPTIONS (table 't1_eq_class', schemaless 'true'); +create foreign table t_tmp (a int) server influxdb_svr OPTIONS (table 't1_eq_class'); +insert into t_tmp values (1); +explain (costs off) +select 1 +from (select (fields->>'a')::int as a from t) t1 + left join (select 2 as c + from (select (fields->>'a')::int as a from t) t2 left join (select (fields->>'a')::int as a from t) t3 on t2.a = t3.a) s + on true +where t1.a = s.c; + QUERY PLAN +--------------------------------------------------------------------------------------------------------------- + Nested Loop Left Join + Filter: (((t.fields ->> 'a'::text))::integer = (2)) + -> Foreign Scan on t + -> Materialize + -> Merge Left Join + Merge Cond: ((((t_1.fields ->> 'a'::text))::integer) = (((t_2.fields ->> 'a'::text))::integer)) + -> Sort + Sort Key: (((t_1.fields ->> 'a'::text))::integer) + -> Foreign Scan on t t_1 + -> Sort + Sort Key: (((t_2.fields ->> 'a'::text))::integer) + -> Foreign Scan on t t_2 +(12 rows) + +select 1 +from (select (fields->>'a')::int as a from t) t1 + left join (select 2 as c + from (select (fields->>'a')::int as a from t) t2 left join (select (fields->>'a')::int as a from t) t3 on t2.a = t3.a) s + on true +where t1.a = s.c; + ?column? +---------- +(0 rows) + +rollback; +-- test cases where we can remove a join, but not a PHV computed at it +begin; +create foreign table t (fields jsonb OPTIONS (fields 'true')) server influxdb_svr OPTIONS (table 't2_eq_class', schemaless 'true'); +create foreign table t_tmp (a int, b int) server influxdb_svr OPTIONS (table 't2_eq_class'); +insert into t_tmp values (1,1), (2,2); +explain (costs off) +select 1 +from (select (fields->>'a')::int as a, (fields->>'b')::int as b from t) t1 + left join (select t2.a, 1 as c + from (select (fields->>'a')::int as a, (fields->>'b')::int as b from t) t2 left join (select (fields->>'a')::int as a, (fields->>'b')::int as b from t) t3 on t2.a = t3.a) s + on true + left join (select (fields->>'a')::int as a, (fields->>'b')::int as b from t) t4 on true +where s.a < s.c; + QUERY PLAN +--------------------------------------------------------------------------------------------------------------------- + Nested Loop Left Join + -> Nested Loop + -> Foreign Scan on t + -> Materialize + -> Merge Left Join + Merge Cond: ((((t_1.fields ->> 'a'::text))::integer) = (((t_2.fields ->> 'a'::text))::integer)) + Filter: ((((t_1.fields ->> 'a'::text))::integer) < 1) + -> Sort + Sort Key: (((t_1.fields ->> 'a'::text))::integer) + -> Foreign Scan on t t_1 + -> Sort + Sort Key: (((t_2.fields ->> 'a'::text))::integer) + -> Foreign Scan on t t_2 + -> Materialize + -> Foreign Scan on t t_3 +(15 rows) + +explain (costs off) +select t1.a, s.* +from (select (fields->>'a')::int as a, (fields->>'b')::int as b from t) t1 + left join lateral (select t2.a, coalesce(t1.a, 1) as c + from (select (fields->>'a')::int as a, (fields->>'b')::int as b from t) t2 left join (select (fields->>'a')::int as a, (fields->>'b')::int as b from t) t3 on t2.a = t3.a) s + on true + left join (select (fields->>'a')::int as a, (fields->>'b')::int as b from t) t4 on true +where s.a < s.c; + QUERY PLAN +-------------------------------------------------------------------------------------------------------------------- + Nested Loop Left Join + -> Nested Loop + -> Foreign Scan on t + -> Merge Left Join + Merge Cond: ((((t_1.fields ->> 'a'::text))::integer) = (((t_2.fields ->> 'a'::text))::integer)) + Filter: ((((t_1.fields ->> 'a'::text))::integer) < COALESCE(((t.fields ->> 'a'::text))::integer, 1)) + -> Sort + Sort Key: (((t_1.fields ->> 'a'::text))::integer) + -> Foreign Scan on t t_1 + -> Sort + Sort Key: (((t_2.fields ->> 'a'::text))::integer) + -> Foreign Scan on t t_2 + -> Materialize + -> Foreign Scan on t t_3 +(14 rows) + +select t1.a, s.* +from (select (fields->>'a')::int as a, (fields->>'b')::int as b from t) t1 + left join lateral (select t2.a, coalesce(t1.a, 1) as c + from (select (fields->>'a')::int as a, (fields->>'b')::int as b from t) t2 left join (select (fields->>'a')::int as a, (fields->>'b')::int as b from t) t3 on t2.a = t3.a) s + on true + left join (select (fields->>'a')::int as a, (fields->>'b')::int as b from t) t4 on true +where s.a < s.c; + a | a | c +---+---+--- + 2 | 1 | 2 + 2 | 1 | 2 +(2 rows) + rollback; -- test case to expose miscomputation of required relid set for a PHV ---Testcase 411: +--Testcase 423: explain (verbose, costs off) select i8.*, ss.v, (t.fields->>'unique2')::int4 unique2 from (select (fields->>'q1')::int8 q1, (fields->>'q2')::int8 q2 from INT8_TBL i8) i8 @@ -5335,13 +6775,16 @@ select i8.*, ss.v, (t.fields->>'unique2')::int4 unique2 where q2::int8 = 456; QUERY PLAN -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- - Hash Left Join + Hash Right Join Output: ((i8.fields ->> 'q1'::text))::bigint, ((i8.fields ->> 'q2'::text))::bigint, ((((i4.fields ->> 'f1'::text))::integer + 1)), ((t.fields ->> 'unique2'::text))::integer - Hash Cond: (((((i4.fields ->> 'f1'::text))::integer + 1)) = ((t.fields ->> 'unique2'::text))::integer) - -> Nested Loop Left Join + Hash Cond: (((t.fields ->> 'unique2'::text))::integer = ((((i4.fields ->> 'f1'::text))::integer + 1))) + -> Foreign Scan on public.tenk1 t + Output: t.fields + InfluxDB query: SELECT * FROM "tenk" + -> Hash Output: i8.fields, ((((i4.fields ->> 'f1'::text))::integer + 1)) -> Nested Loop Left Join - Output: i8.fields, i4.fields + Output: i8.fields, (((i4.fields ->> 'f1'::text))::integer + 1) -> Foreign Scan on public.int8_tbl i8 Output: i8.fields InfluxDB query: SELECT * FROM "int8_tbl" WHERE (("q2" = 456)) @@ -5350,16 +6793,9 @@ where q2::int8 = 456; -> Foreign Scan on public.int4_tbl i4 Output: i4.fields InfluxDB query: SELECT * FROM "int4_tbl" WHERE (("f1" = 1)) - -> Result - Output: (((i4.fields ->> 'f1'::text))::integer + 1) - -> Hash - Output: t.fields - -> Foreign Scan on public.tenk1 t - Output: t.fields - InfluxDB query: SELECT * FROM "tenk" -(22 rows) +(18 rows) ---Testcase 412: +--Testcase 424: select i8.*, ss.v, (t.fields->>'unique2')::int4 unique2 from (select (fields->>'q1')::int8 q1, (fields->>'q2')::int8 q2 from INT8_TBL i8) i8 left join int4_tbl i4 on (i4.fields->>'f1')::int4 = 1 @@ -5371,21 +6807,55 @@ where q2::int8 = 456; 123 | 456 | | (1 row) +-- InfluxDB does not support partition table, create local table for test +-- and check a related issue where we miscompute required relids for +-- a PHV that's been translated to a child rel +--Testcase 570: +create temp table parttbl (a integer primary key) partition by range (a); +--Testcase 571: +create temp table parttbl1 partition of parttbl for values from (1) to (100); +--Testcase 572: +insert into parttbl values (11), (12); +--Testcase 573: +explain (costs off) +select * from + (select *, 12 as phv from parttbl) as ss + right join (select (fields->>'f1')::int4 f1 from int4_tbl) int4_tbl on true +where ss.a = ss.phv and f1 = 0; + QUERY PLAN +-------------------------------------- + Nested Loop + -> Seq Scan on parttbl1 parttbl + Filter: (a = 12) + -> Materialize + -> Foreign Scan on int4_tbl +(5 rows) + +--Testcase 574: +select * from + (select *, 12 as phv from parttbl) as ss + right join (select (fields->>'f1')::int4 f1 from int4_tbl) int4_tbl on true +where ss.a = ss.phv and f1 = 0; + a | phv | f1 +----+-----+---- + 12 | 12 | 0 +(1 row) + -- bug #8444: we've historically allowed duplicate aliases within aliased JOINs ---Testcase 413: +--Testcase 425: select * from (select (fields->>'q1')::int8 q1, (fields->>'q2')::int8 q2 from INT8_TBL) x join ((select (fields->>'f1')::int4 f1 from INT4_TBL) x cross join (select (fields->>'f1')::int4 f1 from INT4_TBL) y) j on q1 = f1; -- error ERROR: column reference "f1" is ambiguous LINE 2: ...ct (fields->>'f1')::int4 f1 from INT4_TBL) y) j on q1 = f1; ^ ---Testcase 414: +--Testcase 426: select * from (select (fields->>'q1')::int8 q1, (fields->>'q2')::int8 q2 from INT8_TBL) x join ((select (fields->>'f1')::int4 f1 from INT4_TBL) x cross join (select (fields->>'f1')::int4 f1 from INT4_TBL) y) j on q1 = y.f1; -- error ERROR: invalid reference to FROM-clause entry for table "y" LINE 2: ...t (fields->>'f1')::int4 f1 from INT4_TBL) y) j on q1 = y.f1; ^ -HINT: There is an entry for table "y", but it cannot be referenced from this part of the query. ---Testcase 415: +DETAIL: There is an entry for table "y", but it cannot be referenced from this part of the query. +--Testcase 427: select * from (select (fields->>'q1')::int8 q1, (fields->>'q2')::int8 q2 from INT8_TBL) x join ((select (fields->>'f1')::int4 f1 from INT4_TBL) x cross join (select (fields->>'f1')::int4 f1 from INT4_TBL) y(ff)) j on q1 = f1; -- ok q1 | q2 | f1 | ff @@ -5395,31 +6865,37 @@ select * from -- -- Test hints given on incorrect column references are useful -- ---Testcase 416: -select( t1.ffields->>'unique1')::int4 unique1 from +--Testcase 428: +select (t1.ffields->>'unique1')::int4 unique1 from tenk1 t1 join tenk2 t2 on (t1.fields->>'two')::int4 = (t2.fields->>'two')::int4; -- error, prefer "t1" suggestion ERROR: column t1.ffields does not exist -LINE 1: select( t1.ffields->>'unique1')::int4 unique1 from +LINE 1: select (t1.ffields->>'unique1')::int4 unique1 from ^ HINT: Perhaps you meant to reference the column "t1.fields". ---Testcase 417: +--Testcase 429: select (t2.ffields->>'unique1')::int4 unique1 from tenk1 t1 join tenk2 t2 on (t1.fields->>'two')::int4 = (t2.fields->>'two')::int4; -- error, prefer "t2" suggestion ERROR: column t2.ffields does not exist LINE 1: select (t2.ffields->>'unique1')::int4 unique1 from ^ HINT: Perhaps you meant to reference the column "t2.fields". ---Testcase 418: +--Testcase 430: select (ffields->>'unique1')::int4 unique1 from tenk1 t1 join tenk2 t2 on (t1.fields->>'two')::int4 = (t2.fields->>'two')::int4; -- error, suggest both at once ERROR: column "ffields" does not exist LINE 1: select (ffields->>'unique1')::int4 unique1 from ^ HINT: Perhaps you meant to reference the column "t1.fields" or the column "t2.fields". +select (ffields->>'ctid')::int4 ctid from + tenk1 t1 join tenk2 t2 on (t1.fields->>'two')::int4 = (t2.fields->>'two')::int4; -- error, need qualification +ERROR: column "ffields" does not exist +LINE 1: select (ffields->>'ctid')::int4 ctid from + ^ +HINT: Perhaps you meant to reference the column "t1.fields" or the column "t2.fields". -- -- Take care to reference the correct RTE -- ---Testcase 556: +--Testcase 431: 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, @@ -5428,10 +6904,22 @@ select atts.relid::regclass, s.* from pg_stats s join ERROR: column atts.relid does not exist LINE 1: select atts.relid::regclass, s.* from pg_stats s join ^ +-- Test bug in rangetable flattening +explain (verbose, costs off) +select 1 from + (select * from int8_tbl where (int8_tbl.fields->>'q1')::int8 <> (select 42) offset 0) ss +where false; + QUERY PLAN +-------------------------- + Result + Output: 1 + One-Time Filter: false +(3 rows) + -- -- Test LATERAL -- ---Testcase 419: +--Testcase 432: select unique2, x.* from (select (fields->>'unique1')::int4 unique1, (fields->>'unique2')::int4 unique2, fields->>'two' two, fields->>'four' four, fields->>'ten' ten, fields->>'twenty' twenty, fields->>'hundred' hundred, fields->>'thousand' thousand, fields->>'twothousand' twothousand, fields->>'fivethous' fivethous, fields->>'tenthous' tenthous, fields->>'odd' odd, fields->>'even' even, fields->>'stringu1' stringu1, fields->>'stringu2' stringu2, fields->>'string4' string4 from tenk1 a) a, lateral (select * from (select (fields->>'f1')::int4 f1 from INT4_TBL b) b where f1 = a.unique1) x; unique2 | f1 @@ -5439,7 +6927,7 @@ from (select (fields->>'unique1')::int4 unique1, (fields->>'unique2')::int4 uniq 9998 | 0 (1 row) ---Testcase 420: +--Testcase 433: explain (costs off) select unique2, x.* from (select (fields->>'unique1')::int4 unique1, (fields->>'unique2')::int4 unique2, fields->>'two' two, fields->>'four' four, fields->>'ten' ten, fields->>'twenty' twenty, fields->>'hundred' hundred, fields->>'thousand' thousand, fields->>'twothousand' twothousand, fields->>'fivethous' fivethous, fields->>'tenthous' tenthous, fields->>'odd' odd, fields->>'even' even, fields->>'stringu1' stringu1, fields->>'stringu2' stringu2, fields->>'string4' string4 from tenk1 a) a, lateral (select * from (select (fields->>'f1')::int4 f1 from INT4_TBL b) b where f1 = a.unique1) x; @@ -5455,7 +6943,7 @@ explain (costs off) -> Foreign Scan on int4_tbl b (8 rows) ---Testcase 421: +--Testcase 434: select unique2, x.* from (select (fields->>'f1')::int4 f1 from INT4_TBL x) x, lateral (select (fields->>'unique2')::int4 unique2 from tenk1 where f1 = (fields->>'unique1')::int4) ss; unique2 | f1 @@ -5463,7 +6951,7 @@ from (select (fields->>'f1')::int4 f1 from INT4_TBL x) x, lateral (select (field 9998 | 0 (1 row) ---Testcase 422: +--Testcase 435: explain (costs off) select unique2, x.* from (select (fields->>'f1')::int4 f1 from INT4_TBL x) x, lateral (select (fields->>'unique2')::int4 unique2 from tenk1 where f1 = (fields->>'unique1')::int4) ss; @@ -5479,7 +6967,7 @@ explain (costs off) -> Foreign Scan on tenk1 (8 rows) ---Testcase 423: +--Testcase 436: explain (costs off) select unique2, x.* from (select (fields->>'f1')::int4 f1 from INT4_TBL x) x cross join lateral (select (fields->>'unique2')::int4 unique2 from tenk1 where f1 = (fields->>'unique1')::int4) ss; @@ -5495,7 +6983,7 @@ explain (costs off) -> Foreign Scan on tenk1 (8 rows) ---Testcase 424: +--Testcase 437: select unique2, x.* from (select (fields->>'f1')::int4 f1 from INT4_TBL x) x left join lateral (select (fields->>'unique1')::int4 unique1, (fields->>'unique2')::int4 unique2 from tenk1 where f1 = (fields->>'unique1')::int4) ss on true; unique2 | f1 @@ -5507,25 +6995,25 @@ from (select (fields->>'f1')::int4 f1 from INT4_TBL x) x left join lateral (sele | 2147483647 (5 rows) ---Testcase 425: +--Testcase 438: explain (costs off) select unique2, x.* from (select (fields->>'f1')::int4 f1 from INT4_TBL x) x left join lateral (select (fields->>'unique1')::int4 unique1, (fields->>'unique2')::int4 unique2 from tenk1 where f1 = (fields->>'unique1')::int4) ss on true; QUERY PLAN ---------------------------------------------------------------------------------------------------------- - Merge Left Join - Merge Cond: ((((x.fields ->> 'f1'::text))::integer) = (((tenk1.fields ->> 'unique1'::text))::integer)) - -> Sort - Sort Key: (((x.fields ->> 'f1'::text))::integer) - -> Foreign Scan on int4_tbl x + Merge Right Join + Merge Cond: ((((tenk1.fields ->> 'unique1'::text))::integer) = (((x.fields ->> 'f1'::text))::integer)) -> Sort Sort Key: (((tenk1.fields ->> 'unique1'::text))::integer) -> Foreign Scan on tenk1 + -> Sort + Sort Key: (((x.fields ->> 'f1'::text))::integer) + -> Foreign Scan on int4_tbl x (8 rows) -- check scoping of lateral versus parent references -- the first of these should return int8_tbl.q2, the second int8_tbl.q1 ---Testcase 426: +--Testcase 439: select *, (select r from (select q1 as q2) x, (select q2 as r) y) from (select (fields->>'q1')::int8 q1, (fields->>'q2')::int8 q2 from INT8_TBL) int8_tbl; q1 | q2 | r ------------------+-------------------+------------------- @@ -5536,7 +7024,7 @@ select *, (select r from (select q1 as q2) x, (select q2 as r) y) from (select ( 4567890123456789 | -4567890123456789 | -4567890123456789 (5 rows) ---Testcase 427: +--Testcase 440: select *, (select r from (select q1 as q2) x, lateral (select q2 as r) y) from (select (fields->>'q1')::int8 q1, (fields->>'q2')::int8 q2 from INT8_TBL) int8_tbl; q1 | q2 | r ------------------+-------------------+------------------ @@ -5548,14 +7036,14 @@ select *, (select r from (select q1 as q2) x, lateral (select q2 as r) y) from ( (5 rows) -- lateral with function in FROM ---Testcase 428: +--Testcase 441: select count(*) from tenk1 a, lateral generate_series(1, (fields->>'two')::int4) g; count ------- 5000 (1 row) ---Testcase 429: +--Testcase 442: explain (costs off) select count(*) from tenk1 a, lateral generate_series(1, (fields->>'two')::int4) g; QUERY PLAN @@ -5566,7 +7054,7 @@ explain (costs off) -> Function Scan on generate_series g (4 rows) ---Testcase 430: +--Testcase 443: explain (costs off) select count(*) from tenk1 a cross join lateral generate_series(1,(fields->>'two')::int4) g; QUERY PLAN @@ -5578,7 +7066,7 @@ explain (costs off) (4 rows) -- don't need the explicit LATERAL keyword for functions ---Testcase 431: +--Testcase 444: explain (costs off) select count(*) from tenk1 a, generate_series(1,(fields->>'two')::int4) g; QUERY PLAN @@ -5590,7 +7078,7 @@ explain (costs off) (4 rows) -- lateral with UNION ALL subselect ---Testcase 432: +--Testcase 445: explain (costs off) select * from generate_series(100,200) g, lateral (select * from (select (fields->>'q1')::int8 q1, (fields->>'q2')::int8 q2 from INT8_TBL a) a where g = (q1)::int8 union all @@ -5604,7 +7092,7 @@ explain (costs off) -> Foreign Scan on int8_tbl b (5 rows) ---Testcase 433: +--Testcase 446: select * from generate_series(100,200) g, lateral (select * from (select (fields->>'q1')::int8 q1, (fields->>'q2')::int8 q2 from INT8_TBL a) a where g = (q1)::int8 union all select * from (select (fields->>'q1')::int8 q1, (fields->>'q2')::int8 q2 from INT8_TBL b) b where g = (q2)::int8) ss; @@ -5616,7 +7104,7 @@ select * from generate_series(100,200) g, (3 rows) -- lateral with VALUES ---Testcase 434: +--Testcase 447: explain (costs off) select count(*) from tenk1 a, tenk1 b join lateral (values(a.fields->>'unique1')) ss(x) on b.fields->>'unique2' = ss.x; @@ -5633,7 +7121,7 @@ explain (costs off) -> Foreign Scan on tenk1 b (9 rows) ---Testcase 435: +--Testcase 448: select count(*) from tenk1 a, tenk1 b join lateral (values(a.fields->>'unique1')) ss(x) on b.fields->>'unique2' = ss.x; count @@ -5642,7 +7130,7 @@ select count(*) from tenk1 a, (1 row) -- lateral with VALUES, no flattening possible ---Testcase 436: +--Testcase 449: explain (costs off) select count(*) from tenk1 a, tenk1 b join lateral (values((a.fields->>'unique1')::int4),(-1)) ss(x) on (b.fields->>'unique2')::int4 = (ss.x)::int; @@ -5661,7 +7149,7 @@ explain (costs off) -> Values Scan on "*VALUES*" (11 rows) ---Testcase 437: +--Testcase 450: select count(*) from tenk1 a, tenk1 b join lateral (values((a.fields->>'unique1')::int4),(-1)) ss(x) on (b.fields->>'unique2')::int4 = (ss.x)::int; count @@ -5670,7 +7158,7 @@ select count(*) from tenk1 a, (1 row) -- lateral injecting a strange outer join condition ---Testcase 438: +--Testcase 451: explain (costs off) select * from (select (fields->>'q1')::int8 q1, (fields->>'q2')::int8 q2 from INT8_TBL a) a, (select (fields->>'q1')::int8 q1, (fields->>'q2')::int8 q2 from INT8_TBL x) x left join lateral (select a.q1 from (select (fields->>'f1')::int4 f1 from INT4_TBL y) y) ss(z) @@ -5692,7 +7180,7 @@ explain (costs off) -> Foreign Scan on int4_tbl y (12 rows) ---Testcase 439: +--Testcase 452: select * from (select (fields->>'q1')::int8 q1, (fields->>'q2')::int8 q2 from INT8_TBL a) a, (select (fields->>'q1')::int8 q1, (fields->>'q2')::int8 q2 from INT8_TBL x) x left join lateral (select a.q1 from (select (fields->>'f1')::int4 f1 from INT4_TBL y) y) ss(z) on x.q2 = ss.z @@ -5759,7 +7247,7 @@ select * from (select (fields->>'q1')::int8 q1, (fields->>'q2')::int8 q2 from IN (57 rows) -- lateral reference to a join alias variable ---Testcase 440: +--Testcase 453: select * from (select (fields->>'f1')::int4/2 as x from int4_tbl) ss1 join (select (fields->>'f1')::int4 f1 from INT4_TBL) i4 on x::int4 = (f1)::int4, lateral (select x) ss2(y); x | f1 | y @@ -5767,7 +7255,7 @@ select * from (select (fields->>'f1')::int4/2 as x from int4_tbl) ss1 join (sele 0 | 0 | 0 (1 row) ---Testcase 441: +--Testcase 454: select * from (select (fields->>'f1')::int4 as x from int4_tbl) ss1 join (select (fields->>'f1')::int4 f1 from INT4_TBL) i4 on x::int4 = (f1)::int4, lateral (values(x)) ss2(y); x | f1 | y @@ -5779,7 +7267,7 @@ select * from (select (fields->>'f1')::int4 as x from int4_tbl) ss1 join (select 2147483647 | 2147483647 | 2147483647 (5 rows) ---Testcase 442: +--Testcase 455: select * from ((select (fields->>'f1')::int4/2 as x from int4_tbl) ss1 join (select (fields->>'f1')::int4 f1 from INT4_TBL) i4 on x::int4 = (f1)::int4) j, lateral (select x) ss2(y); x | f1 | y @@ -5788,7 +7276,7 @@ select * from ((select (fields->>'f1')::int4/2 as x from int4_tbl) ss1 join (sel (1 row) -- lateral references requiring pullup ---Testcase 443: +--Testcase 456: select * from (values(1)) x(lb), lateral generate_series(lb,4) x4; lb | x4 @@ -5799,7 +7287,7 @@ select * from (values(1)) x(lb), 1 | 4 (4 rows) ---Testcase 444: +--Testcase 457: select * from (select (fields->>'f1')::int4/1000000000 from int4_tbl) x(lb), lateral generate_series(lb,4) x4; lb | x4 @@ -5831,7 +7319,7 @@ select * from (select (fields->>'f1')::int4/1000000000 from int4_tbl) x(lb), -2 | 4 (25 rows) ---Testcase 445: +--Testcase 458: select * from (values(1)) x(lb), lateral (values(lb)) y(lbcopy); lb | lbcopy @@ -5839,7 +7327,7 @@ select * from (values(1)) x(lb), 1 | 1 (1 row) ---Testcase 446: +--Testcase 459: select * from (values(1)) x(lb), lateral (select lb from int4_tbl) y(lbcopy); lb | lbcopy @@ -5851,7 +7339,7 @@ select * from (values(1)) x(lb), 1 | 1 (5 rows) ---Testcase 447: +--Testcase 460: select * from (select (fields->>'q1')::int8 q1, (fields->>'q2')::int8 q2 from INT8_TBL) x left join (select (fields->>'q1')::int8 q1,coalesce((fields->>'q2')::int8,0) q2 from int8_tbl) y on x.q2 = y.q1, lateral (values(x.q1,y.q1,y.q2)) v(xq1,yq1,yq2) ORDER BY xq1, yq1, yq2; @@ -5869,7 +7357,7 @@ select * from 4567890123456789 | -4567890123456789 | | | 4567890123456789 | | (10 rows) ---Testcase 448: +--Testcase 461: select * from (select (fields->>'q1')::int8 q1, (fields->>'q2')::int8 q2 from INT8_TBL) x left join (select (fields->>'q1')::int8 q1,coalesce((fields->>'q2')::int8,0) q2 from int8_tbl) y on x.q2 = y.q1, lateral (select x.q1,y.q1,y.q2) v(xq1,yq1,yq2) ORDER BY xq1, yq1, yq2; @@ -5887,7 +7375,7 @@ select * from 4567890123456789 | -4567890123456789 | | | 4567890123456789 | | (10 rows) ---Testcase 449: +--Testcase 462: select x.* from (select (fields->>'q1')::int8 q1, (fields->>'q2')::int8 q2 from INT8_TBL) x left join (select (fields->>'q1')::int8 q1,coalesce((fields->>'q2')::int8,0) q2 from int8_tbl) y on x.q2 = y.q1, lateral (select x.q1,y.q1,y.q2) v(xq1,yq1,yq2) ORDER BY xq1, yq1, yq2; @@ -5905,7 +7393,7 @@ select x.* from 4567890123456789 | -4567890123456789 (10 rows) ---Testcase 450: +--Testcase 463: select v.* from (int8_tbl x left join (select (fields->>'q1')::int8 q1,coalesce((fields->>'q2')::int8,0) q2 from int8_tbl) y on (x.fields->>'q2')::int8 = y.q1) left join int4_tbl z on (z.fields->>'f1')::int8 = (x.fields->>'q2')::int8, @@ -5934,7 +7422,7 @@ select v.* from 4567890123456789 | -4567890123456789 (20 rows) ---Testcase 451: +--Testcase 464: select v.* from (int8_tbl x left join (select (fields->>'q1')::int8 q1,(select coalesce((fields->>'q2')::int8,0)) q2 from int8_tbl) y on (x.fields->>'q2')::int8 = y.q1) left join int4_tbl z on (z.fields->>'f1')::int8 = (x.fields->>'q2')::int8, @@ -5963,11 +7451,11 @@ select v.* from 4567890123456789 | -4567890123456789 (20 rows) ---Testcase 452: +--Testcase 465: select v.* from (int8_tbl x left join (select (fields->>'q1')::int8 q1,(select coalesce((fields->>'q2')::int8,0)) q2 from int8_tbl) y on (x.fields->>'q2')::int8 = y.q1) left join int4_tbl z on (z.fields->>'f1')::int8 = (x.fields->>'q2')::int8, - lateral (select (x.fields->>'q1')::int8,(y.q1)::int8 from onerow union all select (x.fields->>'q2')::int8,(y.q2)::int8 from onerow) v(vx,vy); + lateral (select (x.fields->>'q1')::int8,(y.q1)::int8 from onerow union all select (x.fields->>'q2')::int8,(y.q2)::int8 from onerow) v(vx,vy); vx | vy -------------------+------------------- 4567890123456789 | @@ -5992,24 +7480,24 @@ select v.* from 4567890123456789 | -4567890123456789 (20 rows) ---Testcase 453: +--Testcase 466: explain (verbose, costs off) select * from (select (fields->>'q1')::int8 q1, (fields->>'q2')::int8 q2 from INT8_TBL a) a left join lateral (select *, a.q2 as x from (select (fields->>'q1')::int8 q1, (fields->>'q2')::int8 q2 from INT8_TBL b) b) ss on a.q2 = ss.q1; - QUERY PLAN ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ + QUERY PLAN +--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- Nested Loop Left Join - Output: ((a.fields ->> 'q1'::text))::bigint, ((a.fields ->> 'q2'::text))::bigint, ((b.fields ->> 'q1'::text))::bigint, ((b.fields ->> 'q2'::text))::bigint, (((a.fields ->> 'q2'::text))::bigint) + Output: ((a.fields ->> 'q1'::text))::bigint, ((a.fields ->> 'q2'::text))::bigint, (((b.fields ->> 'q1'::text))::bigint), (((b.fields ->> 'q2'::text))::bigint), (((a.fields ->> 'q2'::text))::bigint) -> Foreign Scan on public.int8_tbl a Output: a.fields InfluxDB query: SELECT * FROM "int8_tbl" -> Foreign Scan on public.int8_tbl b - Output: b.fields, ((a.fields ->> 'q2'::text))::bigint + Output: b.fields, ((b.fields ->> 'q1'::text))::bigint, ((b.fields ->> 'q2'::text))::bigint, ((a.fields ->> 'q2'::text))::bigint InfluxDB query: SELECT * FROM "int8_tbl" WHERE (($1 = "q1")) (8 rows) ---Testcase 454: +--Testcase 467: select * from (select (fields->>'q1')::int8 q1, (fields->>'q2')::int8 q2 from INT8_TBL a) a left join lateral (select *, a.q2 as x from (select (fields->>'q1')::int8 q1, (fields->>'q2')::int8 q2 from INT8_TBL b) b) ss on a.q2 = ss.q1; @@ -6027,24 +7515,24 @@ select * from 4567890123456789 | -4567890123456789 | | | (10 rows) ---Testcase 455: +--Testcase 468: explain (verbose, costs off) select * from (select (fields->>'q1')::int8 q1, (fields->>'q2')::int8 q2 from INT8_TBL a) a left join lateral (select *, coalesce((a.q2)::int8, 42) as x from (select (fields->>'q1')::int8 q1, (fields->>'q2')::int8 q2 from INT8_TBL b) b) ss on a.q2 = ss.q1; - QUERY PLAN ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ + QUERY PLAN +--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- Nested Loop Left Join - Output: ((a.fields ->> 'q1'::text))::bigint, ((a.fields ->> 'q2'::text))::bigint, ((b.fields ->> 'q1'::text))::bigint, ((b.fields ->> 'q2'::text))::bigint, (COALESCE(((a.fields ->> 'q2'::text))::bigint, '42'::bigint)) + Output: ((a.fields ->> 'q1'::text))::bigint, ((a.fields ->> 'q2'::text))::bigint, (((b.fields ->> 'q1'::text))::bigint), (((b.fields ->> 'q2'::text))::bigint), (COALESCE(((a.fields ->> 'q2'::text))::bigint, '42'::bigint)) -> Foreign Scan on public.int8_tbl a Output: a.fields InfluxDB query: SELECT * FROM "int8_tbl" -> Foreign Scan on public.int8_tbl b - Output: b.fields, COALESCE(((a.fields ->> 'q2'::text))::bigint, '42'::bigint) + Output: b.fields, ((b.fields ->> 'q1'::text))::bigint, ((b.fields ->> 'q2'::text))::bigint, COALESCE(((a.fields ->> 'q2'::text))::bigint, '42'::bigint) InfluxDB query: SELECT * FROM "int8_tbl" WHERE (($1 = "q1")) (8 rows) ---Testcase 456: +--Testcase 469: select * from (select (fields->>'q1')::int8 q1, (fields->>'q2')::int8 q2 from INT8_TBL a) a left join lateral (select *, coalesce((a.q2)::int8, 42) as x from (select (fields->>'q1')::int8 q1, (fields->>'q2')::int8 q2 from INT8_TBL b) b) ss on a.q2 = ss.q1; @@ -6064,30 +7552,30 @@ select * from -- lateral can result in join conditions appearing below their -- real semantic level ---Testcase 457: +--Testcase 470: explain (verbose, costs off) select * from (select (fields->>'f1')::int4 f1 from INT4_TBL i) i left join lateral (select * from (select (fields->>'f1')::int2 f1 from INT2_TBL j) j where i.f1 = j.f1) k on true; - QUERY PLAN --------------------------------------------------------------------------------------------------- - Merge Left Join - Output: (((i.fields ->> 'f1'::text))::integer), ((j.fields ->> 'f1'::text))::smallint - Merge Cond: ((((i.fields ->> 'f1'::text))::integer) = (((j.fields ->> 'f1'::text))::smallint)) + QUERY PLAN +-------------------------------------------------------------------------------------------------------------- + Merge Right Join + Output: (((i.fields ->> 'f1'::text))::integer), (((j.fields ->> 'f1'::text))::smallint) + Merge Cond: ((((j.fields ->> 'f1'::text))::smallint) = (((i.fields ->> 'f1'::text))::integer)) + -> Sort + Output: j.fields, (((j.fields ->> 'f1'::text))::smallint), (((j.fields ->> 'f1'::text))::smallint) + Sort Key: (((j.fields ->> 'f1'::text))::smallint) + -> Foreign Scan on public.int2_tbl j + Output: j.fields, ((j.fields ->> 'f1'::text))::smallint, ((j.fields ->> 'f1'::text))::smallint + InfluxDB query: SELECT * FROM "int2_tbl" -> Sort Output: i.fields, (((i.fields ->> 'f1'::text))::integer) Sort Key: (((i.fields ->> 'f1'::text))::integer) -> Foreign Scan on public.int4_tbl i Output: i.fields, ((i.fields ->> 'f1'::text))::integer InfluxDB query: SELECT * FROM "int4_tbl" - -> Sort - Output: j.fields, (((j.fields ->> 'f1'::text))::smallint) - Sort Key: (((j.fields ->> 'f1'::text))::smallint) - -> Foreign Scan on public.int2_tbl j - Output: j.fields, ((j.fields ->> 'f1'::text))::smallint - InfluxDB query: SELECT * FROM "int2_tbl" (15 rows) ---Testcase 458: +--Testcase 471: select * from (select (fields->>'f1')::int4 f1 from INT4_TBL i) i left join lateral (select * from (select (fields->>'f1')::int2 f1 from INT2_TBL j) j where i.f1 = j.f1) k on true; f1 | f1 @@ -6099,7 +7587,7 @@ select * from (select (fields->>'f1')::int4 f1 from INT4_TBL i) i left join 2147483647 | (5 rows) ---Testcase 459: +--Testcase 472: explain (verbose, costs off) select * from (select (fields->>'f1')::int4 f1 from INT4_TBL i) i left join lateral (select coalesce(i) from (select (fields->>'f1')::int2 f1 from INT2_TBL j) j where i.f1 = j.f1) k on true; @@ -6115,7 +7603,7 @@ select * from (select (fields->>'f1')::int4 f1 from INT4_TBL i) i left join InfluxDB query: SELECT * FROM "int2_tbl" WHERE (($1 = "f1")) (8 rows) ---Testcase 460: +--Testcase 473: select * from (select (fields->>'f1')::int4 f1 from INT4_TBL i) i left join lateral (select coalesce(i) from (select (fields->>'f1')::int2 f1 from INT2_TBL j) j where i.f1 = j.f1) k on true; f1 | coalesce @@ -6127,7 +7615,7 @@ select * from (select (fields->>'f1')::int4 f1 from INT4_TBL i) i left join -2147483647 | (5 rows) ---Testcase 461: +--Testcase 474: explain (verbose, costs off) select * from (select (fields->>'f1')::int4 f1 from INT4_TBL a) a, lateral ( @@ -6141,19 +7629,19 @@ select * from (select (fields->>'f1')::int4 f1 from INT4_TBL a) a, Output: a.fields InfluxDB query: SELECT * FROM "int4_tbl" -> Hash Left Join - Output: ((b.fields ->> 'f1'::text))::integer, ((c.fields ->> 'q1'::text))::bigint, ((c.fields ->> 'q2'::text))::bigint + Output: ((b.fields ->> 'f1'::text))::integer, (((c.fields ->> 'q1'::text))::bigint), (((c.fields ->> 'q2'::text))::bigint) Hash Cond: (((b.fields ->> 'f1'::text))::integer = ((c.fields ->> 'q1'::text))::bigint) -> Foreign Scan on public.int4_tbl b Output: b.fields InfluxDB query: SELECT * FROM "int4_tbl" -> Hash - Output: c.fields + Output: c.fields, (((c.fields ->> 'q1'::text))::bigint), (((c.fields ->> 'q2'::text))::bigint) -> Foreign Scan on public.int8_tbl c - Output: c.fields + Output: c.fields, ((c.fields ->> 'q1'::text))::bigint, ((c.fields ->> 'q2'::text))::bigint InfluxDB query: SELECT * FROM "int8_tbl" WHERE (($1 = "q2")) (16 rows) ---Testcase 462: +--Testcase 475: select * from (select (fields->>'f1')::int4 f1 from INT4_TBL a) a, lateral ( select * from (select (fields->>'f1')::int4 f1 from INT4_TBL b) b left join (select (fields->>'q1')::int8 q1, (fields->>'q2')::int8 q2 from INT8_TBL c) c on (b.f1 = q1 and a.f1 = q2) @@ -6188,35 +7676,35 @@ select * from (select (fields->>'f1')::int4 f1 from INT4_TBL a) a, (25 rows) -- lateral reference in a PlaceHolderVar evaluated at join level ---Testcase 463: +--Testcase 476: explain (verbose, costs off) select * from - (select (fields->>'q1')::int8 q1, (fields->>'q2')::int8 q2 from INT8_TBL a) a left join lateral - (select (b.fields->>'q1')::int8 as bq1, (c.fields->>'q1')::int8 as cq1, least(a.q1,(b.fields->>'q1')::int8,(c.fields->>'q1')::int8) from + (select (fields->>'q1')::int8 q1, (fields->>'q2')::int8 q2 from INT8_TBL) a left join lateral + (select (b.fields->>'q1')::int8 as bq1, (c.fields->>'q1')::int8 as cq1, least(a.q1,(b.fields->>'q1')::int8,(c.fields->>'q1')::int8) from int8_tbl b cross join int8_tbl c) ss on a.q2 = ss.bq1; - QUERY PLAN --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- + QUERY PLAN +--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- Nested Loop Left Join - Output: ((a.fields ->> 'q1'::text))::bigint, ((a.fields ->> 'q2'::text))::bigint, ((b.fields ->> 'q1'::text))::bigint, ((c.fields ->> 'q1'::text))::bigint, (LEAST(((a.fields ->> 'q1'::text))::bigint, ((b.fields ->> 'q1'::text))::bigint, ((c.fields ->> 'q1'::text))::bigint)) - -> Foreign Scan on public.int8_tbl a - Output: a.fields + Output: ((int8_tbl.fields ->> 'q1'::text))::bigint, ((int8_tbl.fields ->> 'q2'::text))::bigint, (((b.fields ->> 'q1'::text))::bigint), (((c.fields ->> 'q1'::text))::bigint), (LEAST(((int8_tbl.fields ->> 'q1'::text))::bigint, ((b.fields ->> 'q1'::text))::bigint, ((c.fields ->> 'q1'::text))::bigint)) + -> Foreign Scan on public.int8_tbl + Output: int8_tbl.fields InfluxDB query: SELECT * FROM "int8_tbl" -> Nested Loop - Output: b.fields, c.fields, LEAST(((a.fields ->> 'q1'::text))::bigint, ((b.fields ->> 'q1'::text))::bigint, ((c.fields ->> 'q1'::text))::bigint) + Output: b.fields, (((b.fields ->> 'q1'::text))::bigint), (((c.fields ->> 'q1'::text))::bigint), LEAST(((int8_tbl.fields ->> 'q1'::text))::bigint, ((b.fields ->> 'q1'::text))::bigint, ((c.fields ->> 'q1'::text))::bigint) -> Foreign Scan on public.int8_tbl b - Output: b.fields + Output: b.fields, ((b.fields ->> 'q1'::text))::bigint InfluxDB query: SELECT * FROM "int8_tbl" WHERE (($1 = "q1")) -> Materialize - Output: c.fields + Output: c.fields, (((c.fields ->> 'q1'::text))::bigint) -> Foreign Scan on public.int8_tbl c - Output: c.fields + Output: c.fields, ((c.fields ->> 'q1'::text))::bigint InfluxDB query: SELECT * FROM "int8_tbl" (15 rows) ---Testcase 464: +--Testcase 477: select * from - (select (fields->>'q1')::int8 q1, (fields->>'q2')::int8 q2 from INT8_TBL a) a left join lateral + (select (fields->>'q1')::int8 q1, (fields->>'q2')::int8 q2 from INT8_TBL) a left join lateral (select (b.fields->>'q1')::int8 as bq1, (c.fields->>'q1')::int8 as cq1, least(a.q1,(b.fields->>'q1')::int8,(c.fields->>'q1')::int8) from int8_tbl b cross join int8_tbl c) ss on a.q2 = ss.bq1; @@ -6267,7 +7755,7 @@ select * from (42 rows) -- case requiring nested PlaceHolderVars ---Testcase 465: +--Testcase 478: explain (verbose, costs off) select * from (select (fields->>'q1')::int8 q1, (fields->>'q2')::int8 q2 from INT8_TBL c) c left join ( @@ -6277,12 +7765,12 @@ select * from lateral (select (fields->>'q1')::int8 q1, coalesce(ss1.x,(fields->>'q2')::int8) as y from int8_tbl d) ss2 ) on c.q2 = ss2.q1, lateral (select ss2.y offset 0) ss3; - QUERY PLAN ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ + QUERY PLAN +------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- Nested Loop - Output: ((c.fields ->> 'q1'::text))::bigint, ((c.fields ->> 'q2'::text))::bigint, ((a.fields ->> 'q1'::text))::bigint, ((a.fields ->> 'q2'::text))::bigint, ((b.fields ->> 'q1'::text))::bigint, (COALESCE(((b.fields ->> 'q2'::text))::bigint, '42'::bigint)), ((d.fields ->> 'q1'::text))::bigint, (COALESCE((COALESCE(((b.fields ->> 'q2'::text))::bigint, '42'::bigint)), ((d.fields ->> 'q2'::text))::bigint)), ((COALESCE((COALESCE(((b.fields ->> 'q2'::text))::bigint, '42'::bigint)), ((d.fields ->> 'q2'::text))::bigint))) + Output: ((c.fields ->> 'q1'::text))::bigint, ((c.fields ->> 'q2'::text))::bigint, (((a.fields ->> 'q1'::text))::bigint), (((a.fields ->> 'q2'::text))::bigint), (((b.fields ->> 'q1'::text))::bigint), (COALESCE(((b.fields ->> 'q2'::text))::bigint, '42'::bigint)), (((d.fields ->> 'q1'::text))::bigint), (COALESCE((COALESCE(((b.fields ->> 'q2'::text))::bigint, '42'::bigint)), ((d.fields ->> 'q2'::text))::bigint)), ((COALESCE((COALESCE(((b.fields ->> 'q2'::text))::bigint, '42'::bigint)), ((d.fields ->> 'q2'::text))::bigint))) -> Merge Left Join - Output: c.fields, a.fields, b.fields, d.fields, (COALESCE(((b.fields ->> 'q2'::text))::bigint, '42'::bigint)), (COALESCE((COALESCE(((b.fields ->> 'q2'::text))::bigint, '42'::bigint)), ((d.fields ->> 'q2'::text))::bigint)) + Output: c.fields, (((a.fields ->> 'q1'::text))::bigint), (((a.fields ->> 'q2'::text))::bigint), (((b.fields ->> 'q1'::text))::bigint), (COALESCE(((b.fields ->> 'q2'::text))::bigint, '42'::bigint)), (((d.fields ->> 'q1'::text))::bigint), (COALESCE((COALESCE(((b.fields ->> 'q2'::text))::bigint, '42'::bigint)), ((d.fields ->> 'q2'::text))::bigint)) Merge Cond: ((((c.fields ->> 'q2'::text))::bigint) = (((d.fields ->> 'q1'::text))::bigint)) -> Sort Output: c.fields, (((c.fields ->> 'q2'::text))::bigint) @@ -6291,36 +7779,36 @@ select * from Output: c.fields, ((c.fields ->> 'q2'::text))::bigint InfluxDB query: SELECT * FROM "int8_tbl" -> Materialize - Output: a.fields, b.fields, d.fields, (COALESCE(((b.fields ->> 'q2'::text))::bigint, '42'::bigint)), (COALESCE((COALESCE(((b.fields ->> 'q2'::text))::bigint, '42'::bigint)), ((d.fields ->> 'q2'::text))::bigint)), (((d.fields ->> 'q1'::text))::bigint) + Output: (((a.fields ->> 'q1'::text))::bigint), (((a.fields ->> 'q2'::text))::bigint), (((b.fields ->> 'q1'::text))::bigint), (COALESCE(((b.fields ->> 'q2'::text))::bigint, '42'::bigint)), d.fields, (((d.fields ->> 'q1'::text))::bigint), (COALESCE((COALESCE(((b.fields ->> 'q2'::text))::bigint, '42'::bigint)), ((d.fields ->> 'q2'::text))::bigint)), (((d.fields ->> 'q1'::text))::bigint) -> Sort - Output: a.fields, b.fields, d.fields, (COALESCE(((b.fields ->> 'q2'::text))::bigint, '42'::bigint)), (COALESCE((COALESCE(((b.fields ->> 'q2'::text))::bigint, '42'::bigint)), ((d.fields ->> 'q2'::text))::bigint)), (((d.fields ->> 'q1'::text))::bigint) + Output: (((a.fields ->> 'q1'::text))::bigint), (((a.fields ->> 'q2'::text))::bigint), (((b.fields ->> 'q1'::text))::bigint), (COALESCE(((b.fields ->> 'q2'::text))::bigint, '42'::bigint)), d.fields, (((d.fields ->> 'q1'::text))::bigint), (COALESCE((COALESCE(((b.fields ->> 'q2'::text))::bigint, '42'::bigint)), ((d.fields ->> 'q2'::text))::bigint)), (((d.fields ->> 'q1'::text))::bigint) Sort Key: (((d.fields ->> 'q1'::text))::bigint) -> Nested Loop - Output: a.fields, b.fields, d.fields, (COALESCE(((b.fields ->> 'q2'::text))::bigint, '42'::bigint)), (COALESCE((COALESCE(((b.fields ->> 'q2'::text))::bigint, '42'::bigint)), ((d.fields ->> 'q2'::text))::bigint)), ((d.fields ->> 'q1'::text))::bigint - -> Merge Right Join - Output: a.fields, b.fields, (COALESCE(((b.fields ->> 'q2'::text))::bigint, '42'::bigint)) - Merge Cond: ((((b.fields ->> 'q1'::text))::bigint) = (((a.fields ->> 'q2'::text))::bigint)) - -> Sort - Output: b.fields, (COALESCE(((b.fields ->> 'q2'::text))::bigint, '42'::bigint)), (((b.fields ->> 'q1'::text))::bigint) - Sort Key: (((b.fields ->> 'q1'::text))::bigint) - -> Foreign Scan on public.int8_tbl b - Output: b.fields, COALESCE(((b.fields ->> 'q2'::text))::bigint, '42'::bigint), ((b.fields ->> 'q1'::text))::bigint - InfluxDB query: SELECT * FROM "int8_tbl" + Output: (((a.fields ->> 'q1'::text))::bigint), (((a.fields ->> 'q2'::text))::bigint), (((b.fields ->> 'q1'::text))::bigint), (COALESCE(((b.fields ->> 'q2'::text))::bigint, '42'::bigint)), d.fields, (((d.fields ->> 'q1'::text))::bigint), (COALESCE((COALESCE(((b.fields ->> 'q2'::text))::bigint, '42'::bigint)), ((d.fields ->> 'q2'::text))::bigint)), ((d.fields ->> 'q1'::text))::bigint + -> Merge Left Join + Output: (((a.fields ->> 'q1'::text))::bigint), (((a.fields ->> 'q2'::text))::bigint), (((b.fields ->> 'q1'::text))::bigint), (COALESCE(((b.fields ->> 'q2'::text))::bigint, '42'::bigint)) + Merge Cond: ((((a.fields ->> 'q2'::text))::bigint) = (((b.fields ->> 'q1'::text))::bigint)) -> Sort - Output: a.fields, (((a.fields ->> 'q2'::text))::bigint) + Output: a.fields, (((a.fields ->> 'q1'::text))::bigint), (((a.fields ->> 'q2'::text))::bigint), (((a.fields ->> 'q2'::text))::bigint) Sort Key: (((a.fields ->> 'q2'::text))::bigint) -> Foreign Scan on public.int8_tbl a - Output: a.fields, ((a.fields ->> 'q2'::text))::bigint + Output: a.fields, ((a.fields ->> 'q1'::text))::bigint, ((a.fields ->> 'q2'::text))::bigint, ((a.fields ->> 'q2'::text))::bigint + InfluxDB query: SELECT * FROM "int8_tbl" + -> Sort + Output: b.fields, (((b.fields ->> 'q1'::text))::bigint), (COALESCE(((b.fields ->> 'q2'::text))::bigint, '42'::bigint)), (((b.fields ->> 'q1'::text))::bigint) + Sort Key: (((b.fields ->> 'q1'::text))::bigint) + -> Foreign Scan on public.int8_tbl b + Output: b.fields, ((b.fields ->> 'q1'::text))::bigint, COALESCE(((b.fields ->> 'q2'::text))::bigint, '42'::bigint), ((b.fields ->> 'q1'::text))::bigint InfluxDB query: SELECT * FROM "int8_tbl" -> Foreign Scan on public.int8_tbl d - Output: d.fields, COALESCE((COALESCE(((b.fields ->> 'q2'::text))::bigint, '42'::bigint)), ((d.fields ->> 'q2'::text))::bigint) + Output: d.fields, ((d.fields ->> 'q1'::text))::bigint, COALESCE((COALESCE(((b.fields ->> 'q2'::text))::bigint, '42'::bigint)), ((d.fields ->> 'q2'::text))::bigint) InfluxDB query: SELECT * FROM "int8_tbl" -> Result Output: (COALESCE((COALESCE(((b.fields ->> 'q2'::text))::bigint, '42'::bigint)), ((d.fields ->> 'q2'::text))::bigint)) (38 rows) -- case that breaks the old ph_may_need optimization ---Testcase 466: +--Testcase 479: explain (verbose, costs off) select c.*,a.*,ss1.q1,ss2.q1,ss3.* from (select (fields->>'q1')::int8 q1, (fields->>'q2')::int8 q2 from INT8_TBL c) c left join ( @@ -6332,13 +7820,13 @@ select c.*,a.*,ss1.q1,ss2.q1,ss3.* from lateral (select (fields->>'q1')::int8 q1, coalesce(ss1.x,(fields->>'q2')::int8) as y from int8_tbl d) ss2 ) on c.q2 = ss2.q1, lateral (select * from (select (fields->>'f1')::int4 f1 from INT4_TBL i) i where (ss2.y)::int8 > (f1)::int4) ss3; - QUERY PLAN ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- + QUERY PLAN +------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ Nested Loop - Output: ((c.fields ->> 'q1'::text))::bigint, ((c.fields ->> 'q2'::text))::bigint, ((a.fields ->> 'q1'::text))::bigint, ((a.fields ->> 'q2'::text))::bigint, ((b.fields ->> 'q1'::text))::bigint, ((d.fields ->> 'q1'::text))::bigint, ((i.fields ->> 'f1'::text))::integer + Output: ((c.fields ->> 'q1'::text))::bigint, ((c.fields ->> 'q2'::text))::bigint, (((a.fields ->> 'q1'::text))::bigint), (((a.fields ->> 'q2'::text))::bigint), (((b.fields ->> 'q1'::text))::bigint), (((d.fields ->> 'q1'::text))::bigint), ((i.fields ->> 'f1'::text))::integer Join Filter: ((COALESCE((COALESCE(((b.fields ->> 'q2'::text))::bigint, (((b2.fields ->> 'f1'::text))::integer)::bigint)), ((d.fields ->> 'q2'::text))::bigint)) > ((i.fields ->> 'f1'::text))::integer) -> Merge Left Join - Output: c.fields, a.fields, b.fields, d.fields, (COALESCE((COALESCE(((b.fields ->> 'q2'::text))::bigint, (((b2.fields ->> 'f1'::text))::integer)::bigint)), ((d.fields ->> 'q2'::text))::bigint)) + Output: c.fields, (((a.fields ->> 'q1'::text))::bigint), (((a.fields ->> 'q2'::text))::bigint), (((b.fields ->> 'q1'::text))::bigint), (((d.fields ->> 'q1'::text))::bigint), (COALESCE((COALESCE(((b.fields ->> 'q2'::text))::bigint, (((b2.fields ->> 'f1'::text))::integer)::bigint)), ((d.fields ->> 'q2'::text))::bigint)) Merge Cond: ((((c.fields ->> 'q2'::text))::bigint) = (((d.fields ->> 'q1'::text))::bigint)) -> Sort Output: c.fields, (((c.fields ->> 'q2'::text))::bigint) @@ -6347,39 +7835,39 @@ select c.*,a.*,ss1.q1,ss2.q1,ss3.* from Output: c.fields, ((c.fields ->> 'q2'::text))::bigint InfluxDB query: SELECT * FROM "int8_tbl" -> Materialize - Output: a.fields, b.fields, d.fields, (COALESCE((COALESCE(((b.fields ->> 'q2'::text))::bigint, (((b2.fields ->> 'f1'::text))::integer)::bigint)), ((d.fields ->> 'q2'::text))::bigint)), (((d.fields ->> 'q1'::text))::bigint) + Output: (((a.fields ->> 'q1'::text))::bigint), (((a.fields ->> 'q2'::text))::bigint), (((b.fields ->> 'q1'::text))::bigint), d.fields, (((d.fields ->> 'q1'::text))::bigint), (COALESCE((COALESCE(((b.fields ->> 'q2'::text))::bigint, (((b2.fields ->> 'f1'::text))::integer)::bigint)), ((d.fields ->> 'q2'::text))::bigint)), (((d.fields ->> 'q1'::text))::bigint) -> Sort - Output: a.fields, b.fields, d.fields, (COALESCE((COALESCE(((b.fields ->> 'q2'::text))::bigint, (((b2.fields ->> 'f1'::text))::integer)::bigint)), ((d.fields ->> 'q2'::text))::bigint)), (((d.fields ->> 'q1'::text))::bigint) + Output: (((a.fields ->> 'q1'::text))::bigint), (((a.fields ->> 'q2'::text))::bigint), (((b.fields ->> 'q1'::text))::bigint), d.fields, (((d.fields ->> 'q1'::text))::bigint), (COALESCE((COALESCE(((b.fields ->> 'q2'::text))::bigint, (((b2.fields ->> 'f1'::text))::integer)::bigint)), ((d.fields ->> 'q2'::text))::bigint)), (((d.fields ->> 'q1'::text))::bigint) Sort Key: (((d.fields ->> 'q1'::text))::bigint) -> Nested Loop - Output: a.fields, b.fields, d.fields, (COALESCE((COALESCE(((b.fields ->> 'q2'::text))::bigint, (((b2.fields ->> 'f1'::text))::integer)::bigint)), ((d.fields ->> 'q2'::text))::bigint)), ((d.fields ->> 'q1'::text))::bigint + Output: (((a.fields ->> 'q1'::text))::bigint), (((a.fields ->> 'q2'::text))::bigint), (((b.fields ->> 'q1'::text))::bigint), d.fields, (((d.fields ->> 'q1'::text))::bigint), (COALESCE((COALESCE(((b.fields ->> 'q2'::text))::bigint, (((b2.fields ->> 'f1'::text))::integer)::bigint)), ((d.fields ->> 'q2'::text))::bigint)), ((d.fields ->> 'q1'::text))::bigint -> Merge Left Join - Output: a.fields, b.fields, (COALESCE(((b.fields ->> 'q2'::text))::bigint, (((b2.fields ->> 'f1'::text))::integer)::bigint)) + Output: (((a.fields ->> 'q1'::text))::bigint), (((a.fields ->> 'q2'::text))::bigint), (((b.fields ->> 'q1'::text))::bigint), (COALESCE(((b.fields ->> 'q2'::text))::bigint, (((b2.fields ->> 'f1'::text))::integer)::bigint)) Merge Cond: ((((a.fields ->> 'q2'::text))::bigint) = (((b.fields ->> 'q1'::text))::bigint)) -> Sort - Output: a.fields, (((a.fields ->> 'q2'::text))::bigint) + Output: a.fields, (((a.fields ->> 'q1'::text))::bigint), (((a.fields ->> 'q2'::text))::bigint), (((a.fields ->> 'q2'::text))::bigint) Sort Key: (((a.fields ->> 'q2'::text))::bigint) -> Foreign Scan on public.int8_tbl a - Output: a.fields, ((a.fields ->> 'q2'::text))::bigint + Output: a.fields, ((a.fields ->> 'q1'::text))::bigint, ((a.fields ->> 'q2'::text))::bigint, ((a.fields ->> 'q2'::text))::bigint InfluxDB query: SELECT * FROM "int8_tbl" -> Materialize - Output: b.fields, (COALESCE(((b.fields ->> 'q2'::text))::bigint, (((b2.fields ->> 'f1'::text))::integer)::bigint)), (((b.fields ->> 'q1'::text))::bigint) + Output: b.fields, (((b.fields ->> 'q1'::text))::bigint), (COALESCE(((b.fields ->> 'q2'::text))::bigint, (((b2.fields ->> 'f1'::text))::integer)::bigint)), (((b.fields ->> 'q1'::text))::bigint) -> Sort - Output: b.fields, (COALESCE(((b.fields ->> 'q2'::text))::bigint, (((b2.fields ->> 'f1'::text))::integer)::bigint)), (((b.fields ->> 'q1'::text))::bigint) + Output: b.fields, (((b.fields ->> 'q1'::text))::bigint), (COALESCE(((b.fields ->> 'q2'::text))::bigint, (((b2.fields ->> 'f1'::text))::integer)::bigint)), (((b.fields ->> 'q1'::text))::bigint) Sort Key: (((b.fields ->> 'q1'::text))::bigint) -> Nested Loop - Output: b.fields, COALESCE(((b.fields ->> 'q2'::text))::bigint, (((b2.fields ->> 'f1'::text))::integer)::bigint), ((b.fields ->> 'q1'::text))::bigint + Output: b.fields, (((b.fields ->> 'q1'::text))::bigint), COALESCE(((b.fields ->> 'q2'::text))::bigint, (((b2.fields ->> 'f1'::text))::integer)::bigint), ((b.fields ->> 'q1'::text))::bigint Join Filter: (((b.fields ->> 'q1'::text))::bigint < ((b2.fields ->> 'f1'::text))::integer) - -> Foreign Scan on public.int8_tbl b - Output: b.fields - InfluxDB query: SELECT * FROM "int8_tbl" - -> Materialize + -> Foreign Scan on public.int4_tbl b2 Output: b2.fields - -> Foreign Scan on public.int4_tbl b2 - Output: b2.fields - InfluxDB query: SELECT * FROM "int4_tbl" + InfluxDB query: SELECT * FROM "int4_tbl" + -> Materialize + Output: b.fields, (((b.fields ->> 'q1'::text))::bigint) + -> Foreign Scan on public.int8_tbl b + Output: b.fields, ((b.fields ->> 'q1'::text))::bigint + InfluxDB query: SELECT * FROM "int8_tbl" -> Foreign Scan on public.int8_tbl d - Output: d.fields, COALESCE((COALESCE(((b.fields ->> 'q2'::text))::bigint, (((b2.fields ->> 'f1'::text))::integer)::bigint)), ((d.fields ->> 'q2'::text))::bigint) + Output: d.fields, ((d.fields ->> 'q1'::text))::bigint, COALESCE((COALESCE(((b.fields ->> 'q2'::text))::bigint, (((b2.fields ->> 'f1'::text))::integer)::bigint)), ((d.fields ->> 'q2'::text))::bigint) InfluxDB query: SELECT * FROM "int8_tbl" -> Materialize Output: i.fields @@ -6389,7 +7877,7 @@ select c.*,a.*,ss1.q1,ss2.q1,ss3.* from (52 rows) -- check processing of postponed quals (bug #9041) ---Testcase 467: +--Testcase 480: explain (verbose, costs off) select * from (select 1 as x offset 0) x cross join (select 2 as y offset 0) y @@ -6411,41 +7899,64 @@ select * from Output: 3 (11 rows) +-- 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.fields->>'f1')::int = 1 + inner join (int4_tbl t4 left join int4_tbl t5 on true) on true) ss; + QUERY PLAN +----------------------------------------------------------- + Nested Loop Left Join + -> Nested Loop + -> Nested Loop + -> Nested Loop + -> Foreign Scan on int4_tbl t2 + -> Materialize + -> Foreign Scan on int4_tbl t1 + -> Materialize + -> Foreign Scan on int4_tbl t3 + -> Materialize + -> Foreign Scan on int4_tbl t4 + -> Materialize + -> Foreign Scan on int4_tbl t5 +(13 rows) + -- check dummy rels with lateral references (bug #15694) ---Testcase 468: +--Testcase 481: explain (verbose, costs off) select * from (select (fields->>'q1')::int8 q1, (fields->>'q2')::int8 q2 from INT8_TBL i8) i8 left join lateral (select *, i8.q2 from (select (fields->>'f1')::int4 f1 from INT4_TBL int4_tbl) int4_tbl where false) ss on true; - QUERY PLAN ------------------------------------------------------------------------------------------------------------------------------------------------------------------- + QUERY PLAN +-------------------------------------------------------------------------------------------------------------------------------------------------------------------- Nested Loop Left Join - Output: ((i8.fields ->> 'q1'::text))::bigint, ((i8.fields ->> 'q2'::text))::bigint, ((fields ->> 'f1'::text))::integer, (((i8.fields ->> 'q2'::text))::bigint) + Output: ((i8.fields ->> 'q1'::text))::bigint, ((i8.fields ->> 'q2'::text))::bigint, (((fields ->> 'f1'::text))::integer), (((i8.fields ->> 'q2'::text))::bigint) + Join Filter: false -> Foreign Scan on public.int8_tbl i8 Output: i8.fields InfluxDB query: SELECT * FROM "int8_tbl" -> Result - Output: fields, ((i8.fields ->> 'q2'::text))::bigint + Output: ((fields ->> 'f1'::text))::integer, ((i8.fields ->> 'q2'::text))::bigint One-Time Filter: false -(8 rows) +(9 rows) ---Testcase 469: +--Testcase 482: explain (verbose, costs off) select * from (select (fields->>'q1')::int8 q1, (fields->>'q2')::int8 q2 from INT8_TBL i8) i8 left join lateral (select *, i8.q2 from (select (fields->>'f1')::int4 f1 from INT4_TBL i1) i1, (select (fields->>'f1')::int4 f1 from INT4_TBL i2) i2 where false) ss on true; - QUERY PLAN ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- + QUERY PLAN +---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- Nested Loop Left Join - Output: ((i8.fields ->> 'q1'::text))::bigint, ((i8.fields ->> 'q2'::text))::bigint, ((fields ->> 'f1'::text))::integer, ((fields ->> 'f1'::text))::integer, (((i8.fields ->> 'q2'::text))::bigint) + Output: ((i8.fields ->> 'q1'::text))::bigint, ((i8.fields ->> 'q2'::text))::bigint, (((fields ->> 'f1'::text))::integer), (((fields ->> 'f1'::text))::integer), (((i8.fields ->> 'q2'::text))::bigint) -> Foreign Scan on public.int8_tbl i8 Output: i8.fields InfluxDB query: SELECT * FROM "int8_tbl" -> Result - Output: fields, fields, ((i8.fields ->> 'q2'::text))::bigint + Output: ((fields ->> 'f1'::text))::integer, ((fields ->> 'f1'::text))::integer, ((i8.fields ->> 'q2'::text))::bigint One-Time Filter: false (8 rows) -- check handling of nested appendrels inside LATERAL ---Testcase 470: +--Testcase 483: select * from ((select 2 as v) union all (select 3 as v)) as q1 cross join lateral @@ -6465,10 +7976,11 @@ select * from (6 rows) -- check the number of columns specified +--Testcase 665: SELECT * FROM ((SELECT fields->>'q1', fields->>'q2' FROM int8_tbl) i cross join (SELECT fields->>'f1' FROM int4_tbl) j) ss(a,b,c,d); ERROR: join expression "ss" has 3 columns available but 4 columns specified -- check we don't try to do a unique-ified semijoin with LATERAL ---Testcase 471: +--Testcase 484: explain (verbose, costs off) select * from (values (0,9998), (1,1000)) v(id,x), @@ -6494,7 +8006,7 @@ select * from InfluxDB query: SELECT "unique1" FROM "tenk" WHERE (("unique2" = $1)) (15 rows) ---Testcase 472: +--Testcase 485: select * from (values (0,9998), (1,1000)) v(id,x), lateral (select (fields->>'f1')::int4 f1 from INT4_TBL @@ -6507,7 +8019,7 @@ select * from -- check proper extParam/allParam handling (this isn't exactly a LATERAL issue, -- but we can make the test case much more compact with LATERAL) ---Testcase 473: +--Testcase 486: explain (verbose, costs off) select * from (values (0), (1)) v(id), lateral (select * from (select (fields->>'q1')::int8 q1, (fields->>'q2')::int8 q2 from INT8_TBL) t1, @@ -6517,8 +8029,8 @@ lateral (select * from (select (fields->>'q1')::int8 q1, (fields->>'q2')::int8 q where (fields->>'q2')::int8 = (select greatest(t1.q1,t2.q2)) and (select v.id=0)) offset 0) ss2) ss where (t1.q1)::int8 = (ss.q2)::int8) ss0; - QUERY PLAN --------------------------------------------------------------------------------------------------------------------------------------- + QUERY PLAN +------------------------------------------------------------------------------------------------------------------------------------------------ Nested Loop Output: "*VALUES*".column1, ((int8_tbl.fields ->> 'q1'::text))::bigint, ((int8_tbl.fields ->> 'q2'::text))::bigint, ss2.q1, ss2.q2 -> Foreign Scan on public.int8_tbl @@ -6541,16 +8053,16 @@ lateral (select * from (select (fields->>'q1')::int8 q1, (fields->>'q2')::int8 q One-Time Filter: $4 InitPlan 1 (returns $2) -> Result - Output: GREATEST((($0 ->> 'q1'::text))::bigint, ((int8_tbl_1.fields ->> 'q2'::text))::bigint) + Output: GREATEST(((int8_tbl.fields ->> 'q1'::text))::bigint, ((int8_tbl_1.fields ->> 'q2'::text))::bigint) InitPlan 2 (returns $4) -> Result - Output: ($3 = 0) + Output: ("*VALUES*".column1 = 0) -> Foreign Scan on public.int8_tbl t3 Output: t3.fields InfluxDB query: SELECT * FROM "int8_tbl" WHERE (("q2" = $1)) (29 rows) ---Testcase 474: +--Testcase 487: select * from (values (0), (1)) v(id), lateral (select * from (select (fields->>'q1')::int8 q1, (fields->>'q2')::int8 q2 from INT8_TBL) t1, lateral (select * from @@ -6567,97 +8079,101 @@ lateral (select * from (select (fields->>'q1')::int8 q1, (fields->>'q2')::int8 q (3 rows) -- test some error cases where LATERAL should have been used but wasn't ---Testcase 475: +--Testcase 488: select (fields->>'f1')::int4 f1,(fields->>'g')::int4 g from int4_tbl a, (select fields->>'f1' as g) ss; ERROR: column "fields" does not exist LINE 1: ...1,(fields->>'g')::int4 g from int4_tbl a, (select fields->>'... ^ -HINT: There is a column named "fields" in table "a", but it cannot be referenced from this part of the query. ---Testcase 476: +DETAIL: There is a column named "fields" in table "a", but it cannot be referenced from this part of the query. +HINT: To reference that column, you must mark this subquery with LATERAL. +--Testcase 489: select (fields->>'f1')::int4 f1,(fields->>'g')::int4 g from int4_tbl a, (select a.fields->>'f1' as g) ss; ERROR: invalid reference to FROM-clause entry for table "a" LINE 1: ...1,(fields->>'g')::int4 g from int4_tbl a, (select a.fields->... ^ -HINT: There is an entry for table "a", but it cannot be referenced from this part of the query. ---Testcase 477: +DETAIL: There is an entry for table "a", but it cannot be referenced from this part of the query. +HINT: To reference that table, you must mark this subquery with LATERAL. +--Testcase 490: select (fields->>'f1')::int4 f1,(fields->>'g')::int4 g from int4_tbl a cross join (select fields->>'f1' as g) ss; ERROR: column "fields" does not exist LINE 1: ...>>'g')::int4 g from int4_tbl a cross join (select fields->>'... ^ -HINT: There is a column named "fields" in table "a", but it cannot be referenced from this part of the query. ---Testcase 478: +DETAIL: There is a column named "fields" in table "a", but it cannot be referenced from this part of the query. +HINT: To reference that column, you must mark this subquery with LATERAL. +--Testcase 491: select (fields->>'f1')::int4 f1,(fields->>'g')::int4 g from int4_tbl a cross join (select a.fields->>'f1' as g) ss; ERROR: invalid reference to FROM-clause entry for table "a" LINE 1: ...>>'g')::int4 g from int4_tbl a cross join (select a.fields->... ^ -HINT: There is an entry for table "a", but it cannot be referenced from this part of the query. +DETAIL: There is an entry for table "a", but it cannot be referenced from this part of the query. +HINT: To reference that table, you must mark this subquery with LATERAL. -- SQL:2008 says the left table is in scope but illegal to access here ---Testcase 479: +--Testcase 492: select (fields->>'f1')::int4 f1,(fields->>'g')::int4 g from int4_tbl a right join lateral generate_series(0, (a.fields->>'f1')::int4) g on true; ERROR: invalid reference to FROM-clause entry for table "a" LINE 1: ...int4_tbl a right join lateral generate_series(0, (a.fields->... ^ DETAIL: The combining JOIN type must be INNER or LEFT for a LATERAL reference. ---Testcase 480: +--Testcase 493: select (fields->>'f1')::int4 f1,(fields->>'g')::int4 g from int4_tbl a full join lateral generate_series(0, (a.fields->>'f1')::int4) g on true; ERROR: invalid reference to FROM-clause entry for table "a" LINE 1: ... int4_tbl a full join lateral generate_series(0, (a.fields->... ^ DETAIL: The combining JOIN type must be INNER or LEFT for a LATERAL reference. -- check we complain about ambiguous table references ---Testcase 481: +--Testcase 494: select * from (select (fields->>'q1')::int8 q1, (fields->>'q2')::int8 q2 from INT8_TBL) x cross join ((select (fields->>'f1')::int4 f1 from INT4_TBL) x cross join lateral (select x.f1) ss); ERROR: table reference "x" is ambiguous LINE 2: ...t4 f1 from INT4_TBL) x cross join lateral (select x.f1) ss); ^ -- LATERAL can be used to put an aggregate into the FROM clause of its query ---Testcase 482: +--Testcase 495: select 1 from tenk1 a, lateral (select max((a.fields->>'unique1')::int4) from int4_tbl b) ss; ERROR: aggregate functions are not allowed in FROM clause of their own query level LINE 1: select 1 from tenk1 a, lateral (select max((a.fields->>'uniq... ^ -- check behavior of LATERAL in UPDATE/DELETE ---Testcase 483: +--Testcase 496: create temp table xx1 as select fields->>'f1' as x1, -(fields->>'f1')::int4 as x2 from int4_tbl; -- error, can't do this: ---Testcase 484: +--Testcase 497: update xx1 set x2 = f1 from (select * from (select (fields->>'f1')::int4 f1 from INT4_TBL) int4_tbl where f1 = x1) ss; ERROR: column "x1" does not exist LINE 1: ...->>'f1')::int4 f1 from INT4_TBL) int4_tbl where f1 = x1) ss; ^ -HINT: There is a column named "x1" in table "xx1", but it cannot be referenced from this part of the query. ---Testcase 485: +DETAIL: There is a column named "x1" in table "xx1", but it cannot be referenced from this part of the query. +--Testcase 498: update xx1 set x2 = f1 from (select * from (select (fields->>'f1')::int4 f1 from INT4_TBL) int4_tbl where f1 = xx1.x1) ss; ERROR: invalid reference to FROM-clause entry for table "xx1" LINE 1: ...'f1')::int4 f1 from INT4_TBL) int4_tbl where f1 = xx1.x1) ss... ^ -HINT: There is an entry for table "xx1", but it cannot be referenced from this part of the query. +DETAIL: There is an entry for table "xx1", but it cannot be referenced from this part of the query. -- can't do it even with LATERAL: ---Testcase 486: +--Testcase 499: update xx1 set x2 = f1 from lateral (select * from (select (fields->>'f1')::int4 f1 from INT4_TBL) int4_tbl where f1 = x1) ss; ERROR: invalid reference to FROM-clause entry for table "xx1" LINE 1: ...->>'f1')::int4 f1 from INT4_TBL) int4_tbl where f1 = x1) ss; ^ HINT: There is an entry for table "xx1", but it cannot be referenced from this part of the query. -- we might in future allow something like this, but for now it's an error: ---Testcase 487: +--Testcase 500: update xx1 set x2 = f1 from xx1, lateral (select * from (select (fields->>'f1')::int4 f1 from INT4_TBL) int4_tbl where f1 = x1) ss; ERROR: table name "xx1" specified more than once -- also errors: ---Testcase 488: +--Testcase 501: delete from xx1 using (select * from (select (fields->>'f1')::int4 f1 from INT4_TBL) int4_tbl where f1 = x1) ss; ERROR: column "x1" does not exist LINE 1: ...->>'f1')::int4 f1 from INT4_TBL) int4_tbl where f1 = x1) ss; ^ -HINT: There is a column named "x1" in table "xx1", but it cannot be referenced from this part of the query. ---Testcase 489: +DETAIL: There is a column named "x1" in table "xx1", but it cannot be referenced from this part of the query. +--Testcase 502: delete from xx1 using (select * from (select (fields->>'f1')::int4 f1 from INT4_TBL) int4_tbl where f1 = xx1.x1) ss; ERROR: invalid reference to FROM-clause entry for table "xx1" LINE 1: ...'f1')::int4 f1 from INT4_TBL) int4_tbl where f1 = xx1.x1) ss... ^ -HINT: There is an entry for table "xx1", but it cannot be referenced from this part of the query. ---Testcase 490: +DETAIL: There is an entry for table "xx1", but it cannot be referenced from this part of the query. +--Testcase 503: delete from xx1 using lateral (select * from (select (fields->>'f1')::int4 f1 from INT4_TBL) int4_tbl where f1 = x1) ss; ERROR: invalid reference to FROM-clause entry for table "xx1" LINE 1: ...->>'f1')::int4 f1 from INT4_TBL) int4_tbl where f1 = x1) ss; @@ -6721,17 +8237,19 @@ rollback; -- test that foreign key join estimation performs sanely for outer joins -- begin; ---Testcase 491: +--Testcase 504: create foreign table fkest (fields jsonb OPTIONS (fields 'true')) server influxdb_svr OPTIONS(schemaless 'true'); +--Testcase 633: create foreign table fkest_nsc (a int, b int, c int) server influxdb_svr OPTIONS (table 'fkest'); ---Testcase 492: +--Testcase 505: create foreign table fkest1 (fields jsonb OPTIONS (fields 'true')) server influxdb_svr OPTIONS(schemaless 'true'); +--Testcase 634: create foreign table fkest1_nsc (a int, b int) server influxdb_svr OPTIONS (table 'fkest1'); ---Testcase 493: +--Testcase 506: insert into fkest_nsc select x/10, x%10, x from generate_series(1,1000) x; ---Testcase 494: +--Testcase 507: insert into fkest1_nsc select x/10, x%10 from generate_series(1,1000) x; ---Testcase 495: +--Testcase 508: explain (costs off) select * from (select (fields->>'a')::int a, (fields->>'b')::int b, (fields->>'c')::int c from fkest f) f @@ -6761,23 +8279,26 @@ rollback; -- -- test planner's ability to mark joins as unique -- ---Testcase 496: +--Testcase 509: create foreign table j1 (fields jsonb OPTIONS (fields 'true')) server influxdb_svr OPTIONS(schemaless 'true'); +--Testcase 635: create foreign table j1_nsc (id int) server influxdb_svr OPTIONS (table 'j1'); ---Testcase 497: +--Testcase 510: create foreign table j2 (fields jsonb OPTIONS (fields 'true')) server influxdb_svr OPTIONS(schemaless 'true'); +--Testcase 636: create foreign table j2_nsc (id int) server influxdb_svr OPTIONS (table 'j2'); ---Testcase 498: +--Testcase 511: create foreign table j3 (fields jsonb OPTIONS (fields 'true')) server influxdb_svr OPTIONS(schemaless 'true'); +--Testcase 637: create foreign table j3_nsc (id int) server influxdb_svr OPTIONS (table 'j3'); ---Testcase 499: +--Testcase 512: insert into j1_nsc values(1),(2),(3); ---Testcase 500: +--Testcase 513: insert into j2_nsc values(1),(2),(3); ---Testcase 501: +--Testcase 514: insert into j3_nsc values(1),(1); -- ensure join is properly marked as unique ---Testcase 502: +--Testcase 515: explain (verbose, costs off) select * from (select (fields->>'id')::int id from j1) j1 inner join (select (fields->>'id')::int id from j2) j2 on (j1.id)::int = (j2.id)::int; QUERY PLAN @@ -6800,7 +8321,7 @@ select * from (select (fields->>'id')::int id from j1) j1 inner join (select (fi (15 rows) -- ensure join is not unique when not an equi-join ---Testcase 503: +--Testcase 516: explain (verbose, costs off) select * from (select (fields->>'id')::int id from j1) j1 inner join (select (fields->>'id')::int id from j2) j2 on (j1.id)::int > (j2.id)::int; QUERY PLAN @@ -6819,7 +8340,7 @@ select * from (select (fields->>'id')::int id from j1) j1 inner join (select (fi (11 rows) -- ensure non-unique rel is not chosen as inner ---Testcase 504: +--Testcase 517: explain (verbose, costs off) select * from (select (fields->>'id')::int id from j1) j1 inner join (select (fields->>'id')::int id from j3) j3 on (j1.id)::int = (j3.id)::int; QUERY PLAN @@ -6842,76 +8363,76 @@ select * from (select (fields->>'id')::int id from j1) j1 inner join (select (fi (15 rows) -- ensure left join is marked as unique ---Testcase 505: +--Testcase 518: explain (verbose, costs off) select * from (select (fields->>'id')::int id from j1) j1 left join (select (fields->>'id')::int id from j2) j2 on (j1.id)::int = (j2.id)::int; - QUERY PLAN ---------------------------------------------------------------------------------------------------- - Merge Left Join - Output: (((j1.fields ->> 'id'::text))::integer), ((j2.fields ->> 'id'::text))::integer - Merge Cond: ((((j1.fields ->> 'id'::text))::integer) = (((j2.fields ->> 'id'::text))::integer)) + QUERY PLAN +--------------------------------------------------------------------------------------------------------------- + Merge Right Join + Output: (((j1.fields ->> 'id'::text))::integer), (((j2.fields ->> 'id'::text))::integer) + Merge Cond: ((((j2.fields ->> 'id'::text))::integer) = (((j1.fields ->> 'id'::text))::integer)) + -> Sort + Output: j2.fields, (((j2.fields ->> 'id'::text))::integer), (((j2.fields ->> 'id'::text))::integer) + Sort Key: (((j2.fields ->> 'id'::text))::integer) + -> Foreign Scan on public.j2 + Output: j2.fields, ((j2.fields ->> 'id'::text))::integer, ((j2.fields ->> 'id'::text))::integer + InfluxDB query: SELECT * FROM "j2" -> Sort Output: j1.fields, (((j1.fields ->> 'id'::text))::integer) Sort Key: (((j1.fields ->> 'id'::text))::integer) -> Foreign Scan on public.j1 Output: j1.fields, ((j1.fields ->> 'id'::text))::integer InfluxDB query: SELECT * FROM "j1" - -> Sort - Output: j2.fields, (((j2.fields ->> 'id'::text))::integer) - Sort Key: (((j2.fields ->> 'id'::text))::integer) - -> Foreign Scan on public.j2 - Output: j2.fields, ((j2.fields ->> 'id'::text))::integer - InfluxDB query: SELECT * FROM "j2" (15 rows) -- ensure right join is marked as unique ---Testcase 506: +--Testcase 519: explain (verbose, costs off) select * from (select (fields->>'id')::int id from j1) j1 right join (select (fields->>'id')::int id from j2) j2 on (j1.id)::int = (j2.id)::int; - QUERY PLAN ---------------------------------------------------------------------------------------------------- - Merge Left Join - Output: ((j1.fields ->> 'id'::text))::integer, (((j2.fields ->> 'id'::text))::integer) - Merge Cond: ((((j2.fields ->> 'id'::text))::integer) = (((j1.fields ->> 'id'::text))::integer)) + QUERY PLAN +--------------------------------------------------------------------------------------------------------------- + Merge Right Join + Output: (((j1.fields ->> 'id'::text))::integer), (((j2.fields ->> 'id'::text))::integer) + Merge Cond: ((((j1.fields ->> 'id'::text))::integer) = (((j2.fields ->> 'id'::text))::integer)) + -> Sort + Output: j1.fields, (((j1.fields ->> 'id'::text))::integer), (((j1.fields ->> 'id'::text))::integer) + Sort Key: (((j1.fields ->> 'id'::text))::integer) + -> Foreign Scan on public.j1 + Output: j1.fields, ((j1.fields ->> 'id'::text))::integer, ((j1.fields ->> 'id'::text))::integer + InfluxDB query: SELECT * FROM "j1" -> Sort Output: j2.fields, (((j2.fields ->> 'id'::text))::integer) Sort Key: (((j2.fields ->> 'id'::text))::integer) -> Foreign Scan on public.j2 Output: j2.fields, ((j2.fields ->> 'id'::text))::integer InfluxDB query: SELECT * FROM "j2" - -> Sort - Output: j1.fields, (((j1.fields ->> 'id'::text))::integer) - Sort Key: (((j1.fields ->> 'id'::text))::integer) - -> Foreign Scan on public.j1 - Output: j1.fields, ((j1.fields ->> 'id'::text))::integer - InfluxDB query: SELECT * FROM "j1" (15 rows) -- ensure full join is marked as unique ---Testcase 507: +--Testcase 520: explain (verbose, costs off) select * from (select (fields->>'id')::int id from j1) j1 full join (select (fields->>'id')::int id from j2) j2 on (j1.id)::int = (j2.id)::int; QUERY PLAN --------------------------------------------------------------------------------------------------- Merge Full Join - Output: ((j1.fields ->> 'id'::text))::integer, ((j2.fields ->> 'id'::text))::integer + Output: (((j1.fields ->> 'id'::text))::integer), (((j2.fields ->> 'id'::text))::integer) Merge Cond: ((((j1.fields ->> 'id'::text))::integer) = (((j2.fields ->> 'id'::text))::integer)) -> Sort - Output: j1.fields, (((j1.fields ->> 'id'::text))::integer) + Output: (((j1.fields ->> 'id'::text))::integer) Sort Key: (((j1.fields ->> 'id'::text))::integer) -> Foreign Scan on public.j1 - Output: j1.fields, ((j1.fields ->> 'id'::text))::integer - InfluxDB query: SELECT * FROM "j1" + Output: ((j1.fields ->> 'id'::text))::integer + InfluxDB query: SELECT "id" FROM "j1" -> Sort - Output: j2.fields, (((j2.fields ->> 'id'::text))::integer) + Output: (((j2.fields ->> 'id'::text))::integer) Sort Key: (((j2.fields ->> 'id'::text))::integer) -> Foreign Scan on public.j2 - Output: j2.fields, ((j2.fields ->> 'id'::text))::integer - InfluxDB query: SELECT * FROM "j2" + Output: ((j2.fields ->> 'id'::text))::integer + InfluxDB query: SELECT "id" FROM "j2" (15 rows) -- a clauseless (cross) join can't be unique ---Testcase 508: +--Testcase 521: explain (verbose, costs off) select * from (select (fields->>'id')::int id from j1) j1 cross join (select (fields->>'id')::int id from j2) j2; QUERY PLAN @@ -6929,7 +8450,7 @@ select * from (select (fields->>'id')::int id from j1) j1 cross join (select (fi (10 rows) -- ensure a natural join is marked as unique ---Testcase 509: +--Testcase 522: explain (verbose, costs off) select * from (select (fields->>'id')::int id from j1) j1 natural join (select (fields->>'id')::int id from j2) j2; QUERY PLAN @@ -6952,7 +8473,7 @@ select * from (select (fields->>'id')::int id from j1) j1 natural join (select ( (15 rows) -- ensure a distinct clause allows the inner to become unique ---Testcase 510: +--Testcase 523: explain (verbose, costs off) select * from (select (fields->>'id')::int id from j1 j1) j1 inner join (select distinct (fields->>'id')::int id from j3 j3) j3 on (j1.id)::int = (j3.id)::int; @@ -6976,7 +8497,7 @@ inner join (select distinct (fields->>'id')::int id from j3 j3) j3 on (j1.id)::i (15 rows) -- ensure group by clause allows the inner to become unique ---Testcase 511: +--Testcase 524: explain (verbose, costs off) select * from (select (fields->>'id')::int id from j1 j1) j1 inner join (select (fields->>'id')::int id from j3 j3 group by fields->>'id') j3 on (j1.id)::int = (j3.id)::int; @@ -7004,40 +8525,46 @@ inner join (select (fields->>'id')::int id from j3 j3 group by fields->>'id') j3 InfluxDB query: SELECT * FROM "j1" (20 rows) ---Testcase 512: +--Testcase 525: delete from j1_nsc; ---Testcase 513: +--Testcase 526: delete from j2_nsc; ---Testcase 514: +--Testcase 527: delete from j3_nsc; ---Testcase 515: +--Testcase 528: drop foreign table j1; +--Testcase 638: drop foreign table j1_nsc; ---Testcase 516: +--Testcase 529: drop foreign table j2; +--Testcase 639: drop foreign table j2_nsc; ---Testcase 517: +--Testcase 530: drop foreign table j3; +--Testcase 640: drop foreign table j3_nsc; -- test more complex permutations of unique joins ---Testcase 518: +--Testcase 531: create foreign table j1 (fields jsonb OPTIONS (fields 'true')) server influxdb_svr OPTIONS(schemaless 'true'); +--Testcase 641: create foreign table j1_nsc (id1 int, id2 int) server influxdb_svr OPTIONS (table 'j1'); ---Testcase 519: +--Testcase 532: create foreign table j2 (fields jsonb OPTIONS (fields 'true')) server influxdb_svr OPTIONS(schemaless 'true'); +--Testcase 642: create foreign table j2_nsc (id1 int, id2 int) server influxdb_svr OPTIONS (table 'j2'); ---Testcase 520: +--Testcase 533: create foreign table j3 (fields jsonb OPTIONS (fields 'true')) server influxdb_svr OPTIONS(schemaless 'true'); +--Testcase 643: create foreign table j3_nsc (id1 int, id2 int) server influxdb_svr OPTIONS (table 'j3'); ---Testcase 521: +--Testcase 534: insert into j1_nsc values(1,1),(1,2); ---Testcase 522: +--Testcase 535: insert into j2_nsc values(1,1); ---Testcase 523: +--Testcase 536: insert into j3_nsc values(1,1); -- ensure there's no unique join when not all columns which are part of the -- unique index are seen in the join clause ---Testcase 524: +--Testcase 537: explain (verbose, costs off) select * from (select (fields->>'id1')::int id1, (fields->>'id2')::int id2 from j1) j1 inner join (select (fields->>'id1')::int id1, (fields->>'id2')::int id2 from j2) j2 on (j1.id1)::int = (j2.id1)::int; @@ -7061,7 +8588,7 @@ inner join (select (fields->>'id1')::int id1, (fields->>'id2')::int id2 from j2) (15 rows) -- ensure proper unique detection with multiple join quals ---Testcase 525: +--Testcase 538: explain (verbose, costs off) select * from (select (fields->>'id1')::int id1, (fields->>'id2')::int id2 from j1) j1 inner join (select (fields->>'id1')::int id1, (fields->>'id2')::int id2 from j2) j2 on (j1.id1)::int = (j2.id1)::int and (j1.id2)::int = (j2.id2)::int; @@ -7086,7 +8613,7 @@ inner join (select (fields->>'id1')::int id1, (fields->>'id2')::int id2 from j2) -- ensure we don't detect the join to be unique when quals are not part of the -- join condition ---Testcase 526: +--Testcase 539: explain (verbose, costs off) select * from (select (fields->>'id1')::int id1, (fields->>'id2')::int id2 from j1) j1 inner join (select (fields->>'id1')::int id1, (fields->>'id2')::int id2 from j2) j2 on (j1.id1)::int = (j2.id1)::int where (j1.id2)::int = 1; @@ -7106,17 +8633,17 @@ inner join (select (fields->>'id1')::int id1, (fields->>'id2')::int id2 from j2) (11 rows) -- as above, but for left joins. ---Testcase 527: +--Testcase 540: explain (verbose, costs off) select * from (select (fields->>'id1')::int id1, (fields->>'id2')::int id2 from j1) j1 left join (select (fields->>'id1')::int id1, (fields->>'id2')::int id2 from j2) j2 on (j1.id1)::int = (j2.id1)::int where (j1.id2)::int = 1; - QUERY PLAN --------------------------------------------------------------------------------------------------------------------------------------------------------------------------- + QUERY PLAN +------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ Hash Right Join - Output: ((j1.fields ->> 'id1'::text))::integer, ((j1.fields ->> 'id2'::text))::integer, ((j2.fields ->> 'id1'::text))::integer, ((j2.fields ->> 'id2'::text))::integer + Output: ((j1.fields ->> 'id1'::text))::integer, ((j1.fields ->> 'id2'::text))::integer, (((j2.fields ->> 'id1'::text))::integer), (((j2.fields ->> 'id2'::text))::integer) Hash Cond: (((j2.fields ->> 'id1'::text))::integer = ((j1.fields ->> 'id1'::text))::integer) -> Foreign Scan on public.j2 - Output: j2.fields + Output: j2.fields, ((j2.fields ->> 'id1'::text))::integer, ((j2.fields ->> 'id2'::text))::integer InfluxDB query: SELECT * FROM "j2" -> Hash Output: j1.fields @@ -7125,23 +8652,48 @@ left join (select (fields->>'id1')::int id1, (fields->>'id2')::int id2 from j2) InfluxDB query: SELECT * FROM "j1" WHERE (("id2" = 1)) (11 rows) +-- create unique index j1_id2_idx on j1(id2) where id2 is not null; +-- ensure we don't use a partial unique index as unique proofs +explain (verbose, costs off) +select * from (select (fields->>'id2')::int id2 from j1) j1 +inner join (select (fields->>'id2')::int id2 from j2) j2 on (j1.id2)::int = (j2.id2)::int; + QUERY PLAN +----------------------------------------------------------------------------------------------------- + Merge Join + Output: (((j1.fields ->> 'id2'::text))::integer), (((j2.fields ->> 'id2'::text))::integer) + Merge Cond: ((((j1.fields ->> 'id2'::text))::integer) = (((j2.fields ->> 'id2'::text))::integer)) + -> Sort + Output: j1.fields, (((j1.fields ->> 'id2'::text))::integer) + Sort Key: (((j1.fields ->> 'id2'::text))::integer) + -> Foreign Scan on public.j1 + Output: j1.fields, ((j1.fields ->> 'id2'::text))::integer + InfluxDB query: SELECT * FROM "j1" + -> Sort + Output: j2.fields, (((j2.fields ->> 'id2'::text))::integer) + Sort Key: (((j2.fields ->> 'id2'::text))::integer) + -> Foreign Scan on public.j2 + Output: j2.fields, ((j2.fields ->> 'id2'::text))::integer + InfluxDB query: SELECT * FROM "j2" +(15 rows) + +-- drop index j1_id2_idx; -- 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. ---Testcase 528: +--Testcase 541: set enable_nestloop to 0; ---Testcase 529: +--Testcase 542: set enable_hashjoin to 0; ---Testcase 530: +--Testcase 543: set enable_sort to 0; -- create indexes that will be preferred over the PKs to perform the join --create index j1_id1_idx on j1 (id1) where id1 % 1000 = 1; --create index j2_id1_idx on j2 (id1) where id1 % 1000 = 1; -- need an additional row in j2, if we want j2_id1_idx to be preferred ---Testcase 531: +--Testcase 544: insert into j2_nsc values(1,2); --analyze j2; ---Testcase 532: +--Testcase 545: explain (costs off) select * from (select (fields->>'id1')::int id1, (fields->>'id2')::int id2 from j1) j1 inner join (select (fields->>'id1')::int id1, (fields->>'id2')::int id2 from j2) j2 on j1.id1 = j2.id1 and j1.id2 = j2.id2 where (j1.id1)::int % 1000 = 1 and (j2.id1)::int % 1000 = 1; @@ -7154,7 +8706,7 @@ where (j1.id1)::int % 1000 = 1 and (j2.id1)::int % 1000 = 1; -> Foreign Scan on j2 (5 rows) ---Testcase 533: +--Testcase 546: select * from (select (fields->>'id1')::int id1, (fields->>'id2')::int id2 from j1) j1 inner join (select (fields->>'id1')::int id1, (fields->>'id2')::int id2 from j2) j2 on j1.id1 = j2.id1 and j1.id2 = j2.id2 where (j1.id1)::int % 1000 = 1 and (j2.id1)::int % 1000 = 1; @@ -7165,7 +8717,7 @@ where (j1.id1)::int % 1000 = 1 and (j2.id1)::int % 1000 = 1; (2 rows) -- Exercise array keys mark/restore B-Tree code ---Testcase 534: +--Testcase 547: explain (costs off) select * from (select (fields->>'id1')::int id1, (fields->>'id2')::int id2 from j1) j1 inner join (select (fields->>'id1')::int id1, (fields->>'id2')::int id2 from j2) j2 on j1.id1 = j2.id1 and j1.id2 = j2.id2 where (j1.id1)::int % 1000 = 1 and (j2.id1)::int % 1000 = 1 and (j2.id1)::int = any (array[1]); @@ -7178,7 +8730,7 @@ where (j1.id1)::int % 1000 = 1 and (j2.id1)::int % 1000 = 1 and (j2.id1)::int = -> Foreign Scan on j2 (5 rows) ---Testcase 535: +--Testcase 548: select * from (select (fields->>'id1')::int id1, (fields->>'id2')::int id2 from j1) j1 inner join (select (fields->>'id1')::int id1, (fields->>'id2')::int id2 from j2) j2 on j1.id1 = j2.id1 and j1.id2 = j2.id2 where (j1.id1)::int % 1000 = 1 and (j2.id1)::int % 1000 = 1 and (j2.id1)::int = any (array[1]); @@ -7189,7 +8741,7 @@ where (j1.id1)::int % 1000 = 1 and (j2.id1)::int % 1000 = 1 and (j2.id1)::int = (2 rows) -- Exercise array keys "find extreme element" B-Tree code ---Testcase 536: +--Testcase 549: explain (costs off) select * from (select (fields->>'id1')::int id1, (fields->>'id2')::int id2 from j1) j1 inner join (select (fields->>'id1')::int id1, (fields->>'id2')::int id2 from j2) j2 on j1.id1 = j2.id1 and j1.id2 = j2.id2 where (j1.id1)::int % 1000 = 1 and (j2.id1)::int % 1000 = 1 and (j2.id1)::int >= any (array[1,5]); @@ -7202,7 +8754,7 @@ where (j1.id1)::int % 1000 = 1 and (j2.id1)::int % 1000 = 1 and (j2.id1)::int >= -> Foreign Scan on j2 (5 rows) ---Testcase 537: +--Testcase 550: select * from (select (fields->>'id1')::int id1, (fields->>'id2')::int id2 from j1) j1 inner join (select (fields->>'id1')::int id1, (fields->>'id2')::int id2 from j2) j2 on j1.id1 = j2.id1 and j1.id2 = j2.id2 where (j1.id1)::int % 1000 = 1 and (j2.id1)::int % 1000 = 1 and (j2.id1)::int >= any (array[1,5]); @@ -7212,34 +8764,32 @@ where (j1.id1)::int % 1000 = 1 and (j2.id1)::int % 1000 = 1 and (j2.id1)::int >= 1 | 2 | 1 | 2 (2 rows) ---Testcase 538: +--Testcase 551: reset enable_nestloop; ---Testcase 539: +--Testcase 552: reset enable_hashjoin; ---Testcase 540: +--Testcase 553: reset enable_sort; ---Testcase 541: +--Testcase 554: delete from j1_nsc; ---Testcase 542: +--Testcase 555: delete from j2_nsc; ---Testcase 543: +--Testcase 556: delete from j3_nsc; ---Testcase 544: +--Testcase 557: drop foreign table j1; +--Testcase 644: drop foreign table j1_nsc; ---Testcase 545: +--Testcase 558: drop foreign table j2; +--Testcase 645: drop foreign table j2_nsc; ---Testcase 546: +--Testcase 559: drop foreign table j3; +--Testcase 646: drop foreign table j3_nsc; -- check that semijoin inner is not seen as unique for a portion of the outerrel ---Testcase 547: -CREATE FOREIGN TABLE onek ( - fields jsonb OPTIONS (fields 'true') -) SERVER influxdb_svr OPTIONS(schemaless 'true'); --- check that semijoin inner is not seen as unique for a portion of the outerrel ---Testcase 548: +--Testcase 561: explain (verbose, costs off) select (t1.fields->>'unique1')::int4 unique1, (t2.fields->>'hundred')::int4 hundred from onek t1, tenk1 t2 @@ -7277,12 +8827,12 @@ where exists (select 1 from tenk1 t3 (26 rows) -- ... unless it actually is unique ---Testcase 549: +--Testcase 562: create table j3 as select (fields->>'unique1')::int4 unique1, (fields->>'tenthous')::int4 tenthous from onek; vacuum analyze j3; ---Testcase 550: +--Testcase 563: create unique index on j3(unique1, tenthous); ---Testcase 551: +--Testcase 564: explain (verbose, costs off) select (t1.fields->>'unique1')::int4 unique1, (t2.fields->>'hundred')::int4 hundred from onek t1, tenk1 t2 @@ -7311,26 +8861,44 @@ where exists (select 1 from j3 Output: j3.unique1, j3.tenthous (18 rows) ---Testcase 552: +--Testcase 565: drop table j3; -- Clean up +--Testcase 647: DELETE FROM t1_nsc; +--Testcase 648: DELETE FROM t2_nsc; +--Testcase 649: DELETE FROM t3_nsc; +--Testcase 650: DELETE FROM tt1_nsc; +--Testcase 651: DELETE FROM tt2_nsc; +--Testcase 652: DELETE FROM tt3_nsc; +--Testcase 653: DELETE FROM tt4_nsc; +--Testcase 654: DELETE FROM tt5_nsc; +--Testcase 655: DELETE FROM tt6_nsc; +--Testcase 656: DELETE FROM xx_nsc; +--Testcase 657: DELETE FROM yy_nsc; +--Testcase 658: DELETE FROM zt1_nsc; +--Testcase 659: DELETE FROM zt2_nsc; +--Testcase 660: DELETE FROM nt1_nsc; +--Testcase 661: DELETE FROM nt2_nsc; +--Testcase 662: DELETE FROM nt3_nsc; +--Testcase 663: DELETE FROM parent_nsc; +--Testcase 664: DELETE FROM child_nsc; DO $d$ declare @@ -7344,9 +8912,9 @@ end; $d$; NOTICE: drop cascades to table t2a NOTICE: drop cascades to view zv1 ---Testcase 553: +--Testcase 566: DROP USER MAPPING FOR CURRENT_USER SERVER influxdb_svr; ---Testcase 554: +--Testcase 567: DROP SERVER influxdb_svr CASCADE; ---Testcase 555: +--Testcase 568: DROP EXTENSION influxdb_fdw; diff --git a/expected/12.12/schemaless/extra/limit.out b/expected/16.0/schemaless/extra/limit.out similarity index 89% rename from expected/12.12/schemaless/extra/limit.out rename to expected/16.0/schemaless/extra/limit.out index 0fe9859..2d5bea1 100644 --- a/expected/12.12/schemaless/extra/limit.out +++ b/expected/16.0/schemaless/extra/limit.out @@ -1,28 +1,26 @@ \set ECHO none ---Testcase 51: +--Testcase 1: CREATE EXTENSION influxdb_fdw; ---Testcase 52: +--Testcase 2: CREATE SERVER influxdb_svr FOREIGN DATA WRAPPER influxdb_fdw OPTIONS (dbname 'coredb', :SERVER); ---Testcase 53: +--Testcase 3: CREATE USER MAPPING FOR CURRENT_USER SERVER influxdb_svr OPTIONS (:AUTHENTICATION); --- import time column as timestamp and text type --- IMPORT FOREIGN SCHEMA influxdb_schema FROM SERVER influxdb_svr INTO public; -- -- LIMIT -- Check the LIMIT/OFFSET feature of SELECT -- ---Testcase 54: +--Testcase 4: CREATE FOREIGN TABLE onek ( fields jsonb OPTIONS (fields 'true') ) SERVER influxdb_svr OPTIONS (schemaless 'true'); ---Testcase 55: +--Testcase 5: CREATE FOREIGN TABLE int8_tbl(fields jsonb OPTIONS (fields 'true')) SERVER influxdb_svr OPTIONS (schemaless 'true'); ---Testcase 56: +--Testcase 6: CREATE FOREIGN TABLE tenk1 ( fields jsonb OPTIONS (fields 'true') ) SERVER influxdb_svr OPTIONS (table 'tenk', schemaless 'true'); ---Testcase 1: +--Testcase 7: SELECT ''::text AS two, (fields->>'unique1')::int4 unique1, (fields->>'unique2')::int4 unique2, (fields->>'stringu1')::name stringu1 FROM onek WHERE (fields->>'unique1')::int4 > 50 ORDER BY (fields->>'unique1')::int4 LIMIT 2; @@ -32,7 +30,7 @@ SELECT ''::text AS two, (fields->>'unique1')::int4 unique1, (fields->>'unique2') | 52 | 985 | ACAAAA (2 rows) ---Testcase 2: +--Testcase 8: SELECT ''::text AS five, (fields->>'unique1')::int4 unique1, (fields->>'unique2')::int4 unique2, (fields->>'stringu1')::name stringu1 FROM onek WHERE (fields->>'unique1')::int4 > 60 ORDER BY (fields->>'unique1')::int4 LIMIT 5; @@ -45,7 +43,7 @@ SELECT ''::text AS five, (fields->>'unique1')::int4 unique1, (fields->>'unique2' | 65 | 64 | NCAAAA (5 rows) ---Testcase 3: +--Testcase 9: SELECT ''::text AS two, (fields->>'unique1')::int4 unique1, (fields->>'unique2')::int4 unique2, (fields->>'stringu1')::name stringu1 FROM onek WHERE (fields->>'unique1')::int4 > 60 AND (fields->>'unique1')::int4 < 63 ORDER BY (fields->>'unique1')::int4 LIMIT 5; @@ -55,7 +53,7 @@ SELECT ''::text AS two, (fields->>'unique1')::int4 unique1, (fields->>'unique2') | 62 | 633 | KCAAAA (2 rows) ---Testcase 4: +--Testcase 10: SELECT ''::text AS three, (fields->>'unique1')::int4 unique1, (fields->>'unique2')::int4 unique2, (fields->>'stringu1')::name stringu1 FROM onek WHERE (fields->>'unique1')::int4 > 100 ORDER BY (fields->>'unique1')::int4 LIMIT 3 OFFSET 20; @@ -66,7 +64,7 @@ SELECT ''::text AS three, (fields->>'unique1')::int4 unique1, (fields->>'unique2 | 123 | 777 | TEAAAA (3 rows) ---Testcase 5: +--Testcase 11: SELECT ''::text AS zero, (fields->>'unique1')::int4 unique1, (fields->>'unique2')::int4 unique2, (fields->>'stringu1')::name stringu1 FROM onek WHERE (fields->>'unique1')::int4 < 50 ORDER BY (fields->>'unique1')::int4 DESC LIMIT 8 OFFSET 99; @@ -74,7 +72,7 @@ SELECT ''::text AS zero, (fields->>'unique1')::int4 unique1, (fields->>'unique2' ------+---------+---------+---------- (0 rows) ---Testcase 6: +--Testcase 12: SELECT ''::text AS eleven, (fields->>'unique1')::int4 unique1, (fields->>'unique2')::int4 unique2, (fields->>'stringu1')::name stringu1 FROM onek WHERE (fields->>'unique1')::int4 < 50 ORDER BY (fields->>'unique1')::int4 DESC LIMIT 20 OFFSET 39; @@ -93,7 +91,7 @@ SELECT ''::text AS eleven, (fields->>'unique1')::int4 unique1, (fields->>'unique | 0 | 998 | AAAAAA (11 rows) ---Testcase 7: +--Testcase 13: SELECT ''::text AS ten, (fields->>'unique1')::int4 unique1, (fields->>'unique2')::int4 unique2, (fields->>'stringu1')::name stringu1 FROM onek ORDER BY (fields->>'unique1')::int4 OFFSET 990; @@ -111,7 +109,7 @@ SELECT ''::text AS ten, (fields->>'unique1')::int4 unique1, (fields->>'unique2') | 999 | 152 | LMAAAA (10 rows) ---Testcase 8: +--Testcase 14: SELECT ''::text AS five, (fields->>'unique1')::int4 unique1, (fields->>'unique2')::int4 unique2, (fields->>'stringu1')::name stringu1 FROM onek ORDER BY (fields->>'unique1')::int4 OFFSET 990 LIMIT 5; @@ -124,7 +122,7 @@ SELECT ''::text AS five, (fields->>'unique1')::int4 unique1, (fields->>'unique2' | 994 | 695 | GMAAAA (5 rows) ---Testcase 9: +--Testcase 15: SELECT ''::text AS five, (fields->>'unique1')::int4 unique1, (fields->>'unique2')::int4 unique2, (fields->>'stringu1')::name stringu1 FROM onek ORDER BY (fields->>'unique1')::int4 LIMIT 5 OFFSET 900; @@ -139,7 +137,7 @@ SELECT ''::text AS five, (fields->>'unique1')::int4 unique1, (fields->>'unique2' -- Test null limit and offset. The planner would discard a simple null -- constant, so to ensure executor is exercised, do this: ---Testcase 10: +--Testcase 16: select * from int8_tbl limit (case when random() < 0.5 then null::bigint end); fields ------------------------------------------------------- @@ -150,7 +148,7 @@ select * from int8_tbl limit (case when random() < 0.5 then null::bigint end); {"q1": "4567890123456789", "q2": "-4567890123456789"} (5 rows) ---Testcase 11: +--Testcase 17: select * from int8_tbl offset (case when random() < 0.5 then null::bigint end); fields ------------------------------------------------------- @@ -164,7 +162,7 @@ select * from int8_tbl offset (case when random() < 0.5 then null::bigint end); -- Test assorted cases involving backwards fetch from a LIMIT plan node begin; declare c1 scroll cursor for select * from int8_tbl limit 10; ---Testcase 12: +--Testcase 18: fetch all in c1; fields ------------------------------------------------------- @@ -175,20 +173,20 @@ fetch all in c1; {"q1": "4567890123456789", "q2": "-4567890123456789"} (5 rows) ---Testcase 13: +--Testcase 19: fetch 1 in c1; fields -------- (0 rows) ---Testcase 14: +--Testcase 20: fetch backward 1 in c1; fields ------------------------------------------------------- {"q1": "4567890123456789", "q2": "-4567890123456789"} (1 row) ---Testcase 15: +--Testcase 21: fetch backward all in c1; fields ------------------------------------------------------ @@ -198,13 +196,13 @@ fetch backward all in c1; {"q1": "123", "q2": "456"} (4 rows) ---Testcase 16: +--Testcase 22: fetch backward 1 in c1; fields -------- (0 rows) ---Testcase 17: +--Testcase 23: fetch all in c1; fields ------------------------------------------------------- @@ -216,7 +214,7 @@ fetch all in c1; (5 rows) declare c2 scroll cursor for select * from int8_tbl limit 3; ---Testcase 18: +--Testcase 24: fetch all in c2; fields ----------------------------------------- @@ -225,20 +223,20 @@ fetch all in c2; {"q1": "4567890123456789", "q2": "123"} (3 rows) ---Testcase 19: +--Testcase 25: fetch 1 in c2; fields -------- (0 rows) ---Testcase 20: +--Testcase 26: fetch backward 1 in c2; fields ----------------------------------------- {"q1": "4567890123456789", "q2": "123"} (1 row) ---Testcase 21: +--Testcase 27: fetch backward all in c2; fields ----------------------------------------- @@ -246,13 +244,13 @@ fetch backward all in c2; {"q1": "123", "q2": "456"} (2 rows) ---Testcase 22: +--Testcase 28: fetch backward 1 in c2; fields -------- (0 rows) ---Testcase 23: +--Testcase 29: fetch all in c2; fields ----------------------------------------- @@ -262,7 +260,7 @@ fetch all in c2; (3 rows) declare c3 scroll cursor for select * from int8_tbl offset 3; ---Testcase 24: +--Testcase 30: fetch all in c3; fields ------------------------------------------------------- @@ -270,33 +268,33 @@ fetch all in c3; {"q1": "4567890123456789", "q2": "-4567890123456789"} (2 rows) ---Testcase 25: +--Testcase 31: fetch 1 in c3; fields -------- (0 rows) ---Testcase 26: +--Testcase 32: fetch backward 1 in c3; fields ------------------------------------------------------- {"q1": "4567890123456789", "q2": "-4567890123456789"} (1 row) ---Testcase 27: +--Testcase 33: fetch backward all in c3; fields ------------------------------------------------------ {"q1": "4567890123456789", "q2": "4567890123456789"} (1 row) ---Testcase 28: +--Testcase 34: fetch backward 1 in c3; fields -------- (0 rows) ---Testcase 29: +--Testcase 35: fetch all in c3; fields ------------------------------------------------------- @@ -305,75 +303,107 @@ fetch all in c3; (2 rows) declare c4 scroll cursor for select * from int8_tbl offset 10; ---Testcase 30: +--Testcase 36: fetch all in c4; fields -------- (0 rows) ---Testcase 31: +--Testcase 37: fetch 1 in c4; fields -------- (0 rows) ---Testcase 32: +--Testcase 38: fetch backward 1 in c4; fields -------- (0 rows) ---Testcase 33: +--Testcase 39: fetch backward all in c4; fields -------- (0 rows) ---Testcase 34: +--Testcase 40: fetch backward 1 in c4; fields -------- (0 rows) ---Testcase 35: +--Testcase 41: fetch all in c4; fields -------- (0 rows) declare c5 scroll cursor for select * from int8_tbl order by (fields->>'q1')::int8 fetch first 2 rows with ties; -ERROR: syntax error at or near "with" -LINE 1: ...order by (fields->>'q1')::int8 fetch first 2 rows with ties; - ^ ---Testcase 57: +--Testcase 42: fetch all in c5; -ERROR: current transaction is aborted, commands ignored until end of transaction block ---Testcase 58: + fields +----------------------------------------- + {"q1": "123", "q2": "456"} + {"q1": "123", "q2": "4567890123456789"} +(2 rows) + +--Testcase 43: fetch 1 in c5; -ERROR: current transaction is aborted, commands ignored until end of transaction block ---Testcase 59: + fields +-------- +(0 rows) + +--Testcase 44: fetch backward 1 in c5; -ERROR: current transaction is aborted, commands ignored until end of transaction block ---Testcase 60: + fields +----------------------------------------- + {"q1": "123", "q2": "4567890123456789"} +(1 row) + +--Testcase 45: fetch backward 1 in c5; -ERROR: current transaction is aborted, commands ignored until end of transaction block ---Testcase 61: + fields +---------------------------- + {"q1": "123", "q2": "456"} +(1 row) + +--Testcase 46: fetch all in c5; -ERROR: current transaction is aborted, commands ignored until end of transaction block ---Testcase 62: + fields +----------------------------------------- + {"q1": "123", "q2": "4567890123456789"} +(1 row) + +--Testcase 47: fetch backward all in c5; -ERROR: current transaction is aborted, commands ignored until end of transaction block ---Testcase 63: + fields +----------------------------------------- + {"q1": "123", "q2": "4567890123456789"} + {"q1": "123", "q2": "456"} +(2 rows) + +--Testcase 48: fetch all in c5; -ERROR: current transaction is aborted, commands ignored until end of transaction block ---Testcase 64: + fields +----------------------------------------- + {"q1": "123", "q2": "456"} + {"q1": "123", "q2": "4567890123456789"} +(2 rows) + +--Testcase 49: fetch backward all in c5; -ERROR: current transaction is aborted, commands ignored until end of transaction block + fields +----------------------------------------- + {"q1": "123", "q2": "4567890123456789"} + {"q1": "123", "q2": "456"} +(2 rows) + rollback; -- Stress test for variable LIMIT in conjunction with bounded-heap sorting ---Testcase 65: +--Testcase 50: CREATE FOREIGN TABLE generate_series4(fields jsonb OPTIONS (fields 'true')) SERVER influxdb_svr OPTIONS (schemaless 'true'); ---Testcase 36: +--Testcase 51: SELECT (SELECT (fields->>'a')::int a FROM (VALUES (1)) AS x, @@ -398,9 +428,9 @@ SELECT -- Test behavior of volatile and set-returning functions in conjunction -- with ORDER BY and LIMIT. -- ---Testcase 66: +--Testcase 52: create temp sequence testseq; ---Testcase 37: +--Testcase 53: explain (verbose, costs off) select (fields->>'unique1')::int4 unique1, (fields->>'unique2')::int4 unique2, nextval('testseq') from tenk1 order by (fields->>'unique2')::int4 limit 10; @@ -418,7 +448,7 @@ select (fields->>'unique1')::int4 unique1, (fields->>'unique2')::int4 unique2, n InfluxDB query: SELECT "unique1", "unique2" FROM "tenk" (10 rows) ---Testcase 38: +--Testcase 54: select (fields->>'unique1')::int4 unique1, (fields->>'unique2')::int4 unique2, nextval('testseq') from tenk1 order by (fields->>'unique2')::int4 limit 10; unique1 | unique2 | nextval @@ -435,14 +465,14 @@ select (fields->>'unique1')::int4 unique1, (fields->>'unique2')::int4 unique2, n 3043 | 9 | 10 (10 rows) ---Testcase 39: +--Testcase 55: select currval('testseq'); currval --------- 10 (1 row) ---Testcase 40: +--Testcase 56: explain (verbose, costs off) select (fields->>'unique1')::int4 unique1, (fields->>'unique2')::int4 unique2, nextval('testseq') from tenk1 order by (fields->>'tenthous')::int4 limit 10; @@ -460,7 +490,7 @@ select (fields->>'unique1')::int4 unique1, (fields->>'unique2')::int4 unique2, n InfluxDB query: SELECT "unique1", "unique2", "tenthous" FROM "tenk" (10 rows) ---Testcase 41: +--Testcase 57: select(fields->>'unique1')::int4 unique1, (fields->>'unique2')::int4 unique2, nextval('testseq') from tenk1 order by (fields->>'tenthous')::int4 limit 10; unique1 | unique2 | nextval @@ -477,14 +507,14 @@ select(fields->>'unique1')::int4 unique1, (fields->>'unique2')::int4 unique2, ne 9 | 4463 | 20 (10 rows) ---Testcase 42: +--Testcase 58: select currval('testseq'); currval --------- 20 (1 row) ---Testcase 43: +--Testcase 59: explain (verbose, costs off) select (fields->>'unique1')::int4 unique1, (fields->>'unique2')::int4 unique2, generate_series(1,10) from tenk1 order by (fields->>'unique2')::int4 limit 7; @@ -502,7 +532,7 @@ select (fields->>'unique1')::int4 unique1, (fields->>'unique2')::int4 unique2, g InfluxDB query: SELECT "unique1", "unique2" FROM "tenk" (10 rows) ---Testcase 44: +--Testcase 60: select (fields->>'unique1')::int4 unique1, (fields->>'unique2')::int4 unique2, generate_series(1,10) from tenk1 order by (fields->>'unique2')::int4 limit 7; unique1 | unique2 | generate_series @@ -516,7 +546,7 @@ select (fields->>'unique1')::int4 unique1, (fields->>'unique2')::int4 unique2, g 8800 | 0 | 7 (7 rows) ---Testcase 45: +--Testcase 61: explain (verbose, costs off) select (fields->>'unique1')::int4 unique1, (fields->>'unique2')::int4 unique2, generate_series(1,10) from tenk1 order by (fields->>'tenthous')::int4 limit 7; @@ -534,7 +564,7 @@ select (fields->>'unique1')::int4 unique1, (fields->>'unique2')::int4 unique2, g InfluxDB query: SELECT "unique1", "unique2", "tenthous" FROM "tenk" (10 rows) ---Testcase 46: +--Testcase 62: select (fields->>'unique1')::int4 unique1, (fields->>'unique2')::int4 unique2, generate_series(1,10) from tenk1 order by (fields->>'tenthous')::int4 limit 7; unique1 | unique2 | generate_series @@ -549,7 +579,7 @@ select (fields->>'unique1')::int4 unique1, (fields->>'unique2')::int4 unique2, g (7 rows) -- use of random() is to keep planner from folding the expressions together ---Testcase 47: +--Testcase 63: explain (verbose, costs off) select generate_series(0,2) as s1, generate_series((random()*.1)::int,2) as s2; QUERY PLAN @@ -559,7 +589,7 @@ select generate_series(0,2) as s1, generate_series((random()*.1)::int,2) as s2; -> Result (3 rows) ---Testcase 48: +--Testcase 64: select generate_series(0,2) as s1, generate_series((random()*.1)::int,2) as s2; s1 | s2 ----+---- @@ -568,7 +598,7 @@ select generate_series(0,2) as s1, generate_series((random()*.1)::int,2) as s2; 2 | 2 (3 rows) ---Testcase 49: +--Testcase 65: explain (verbose, costs off) select generate_series(0,2) as s1, generate_series((random()*.1)::int,2) as s2 order by s2 desc; @@ -582,7 +612,7 @@ order by s2 desc; -> Result (6 rows) ---Testcase 50: +--Testcase 66: select generate_series(0,2) as s1, generate_series((random()*.1)::int,2) as s2 order by s2 desc; s1 | s2 @@ -632,23 +662,56 @@ select sum((fields->>'tenthous')::int4) as s1, sum((fields->>'tenthous')::int4) SELECT (fields->>'thousand')::int4 thousand FROM onek WHERE (fields->>'thousand')::int4 < 5 ORDER BY (fields->>'thousand')::int4 FETCH FIRST 2 ROW WITH TIES; -ERROR: syntax error at or near "WITH" -LINE 3: ... BY (fields->>'thousand')::int4 FETCH FIRST 2 ROW WITH TIES; - ^ + thousand +---------- + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 +(10 rows) + --Testcase 70: SELECT (fields->>'thousand')::int4 thousand FROM onek WHERE (fields->>'thousand')::int4 < 5 ORDER BY (fields->>'thousand')::int4 FETCH FIRST ROWS WITH TIES; -ERROR: syntax error at or near "WITH" -LINE 3: ...R BY (fields->>'thousand')::int4 FETCH FIRST ROWS WITH TIES; - ^ + thousand +---------- + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 +(10 rows) + --Testcase 71: SELECT (fields->>'thousand')::int4 thousand FROM onek WHERE (fields->>'thousand')::int4 < 5 ORDER BY (fields->>'thousand')::int4 FETCH FIRST 1 ROW WITH TIES; -ERROR: syntax error at or near "WITH" -LINE 3: ... BY (fields->>'thousand')::int4 FETCH FIRST 1 ROW WITH TIES; - ^ + thousand +---------- + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 +(10 rows) + --Testcase 72: SELECT (fields->>'thousand')::int4 thousand FROM onek WHERE (fields->>'thousand')::int4 < 5 @@ -659,23 +722,36 @@ SELECT (fields->>'thousand')::int4 thousand 0 (2 rows) +-- SKIP LOCKED and WITH TIES are incompatible +--Testcase 90: +SELECT (fields->>'thousand')::int4 thousand + FROM onek WHERE (fields->>'thousand')::int4 < 5 + ORDER BY (fields->>'thousand')::int4 FETCH FIRST 1 ROW WITH TIES FOR UPDATE SKIP LOCKED; +ERROR: SKIP LOCKED and WITH TIES options cannot be used together -- should fail --Testcase 73: SELECT ''::text AS two, (fields->>'unique1')::int4 unique1, (fields->>'unique2')::int4 unique2, (fields->>'stringu1')::name stringu1 FROM onek WHERE (fields->>'unique1')::int4 > 50 FETCH FIRST 2 ROW WITH TIES; -ERROR: syntax error at or near "WITH" -LINE 3: FETCH FIRST 2 ROW WITH TIES; - ^ +ERROR: WITH TIES cannot be specified without ORDER BY clause -- test ruleutils --Testcase 74: CREATE VIEW limit_thousand_v_1 AS SELECT (fields->>'thousand')::int4 thousand FROM onek WHERE (fields->>'thousand')::int4 < 995 ORDER BY (fields->>'thousand')::int4 FETCH FIRST 5 ROWS WITH TIES OFFSET 10; -ERROR: syntax error at or near "WITH" -LINE 2: ...BY (fields->>'thousand')::int4 FETCH FIRST 5 ROWS WITH TIES ... - ^ --Testcase 75: \d+ limit_thousand_v_1 + View "public.limit_thousand_v_1" + Column | Type | Collation | Nullable | Default | Storage | Description +----------+---------+-----------+----------+---------+---------+------------- + thousand | integer | | | | plain | +View definition: + SELECT (fields ->> 'thousand'::text)::integer AS thousand + FROM onek + WHERE ((fields ->> 'thousand'::text)::integer) < 995 + ORDER BY ((fields ->> 'thousand'::text)::integer) + OFFSET 10 + FETCH FIRST 5 ROWS WITH TIES; + --Testcase 76: CREATE VIEW limit_thousand_v_2 AS SELECT (fields->>'thousand')::int4 thousand FROM onek WHERE (fields->>'thousand')::int4 < 995 ORDER BY (fields->>'thousand')::int4 OFFSET 10 FETCH FIRST 5 ROWS ONLY; @@ -686,27 +762,33 @@ CREATE VIEW limit_thousand_v_2 AS SELECT (fields->>'thousand')::int4 thousand FR ----------+---------+-----------+----------+---------+---------+------------- thousand | integer | | | | plain | View definition: - SELECT (onek.fields ->> 'thousand'::text)::integer AS thousand + SELECT (fields ->> 'thousand'::text)::integer AS thousand FROM onek - WHERE ((onek.fields ->> 'thousand'::text)::integer) < 995 - ORDER BY ((onek.fields ->> 'thousand'::text)::integer) + WHERE ((fields ->> 'thousand'::text)::integer) < 995 + ORDER BY ((fields ->> 'thousand'::text)::integer) OFFSET 10 LIMIT 5; --Testcase 78: CREATE VIEW limit_thousand_v_3 AS SELECT (fields->>'thousand')::int4 thousand FROM onek WHERE (fields->>'thousand')::int4 < 995 ORDER BY (fields->>'thousand')::int4 FETCH FIRST NULL ROWS WITH TIES; -- fails -ERROR: syntax error at or near "WITH" -LINE 2: ...(fields->>'thousand')::int4 FETCH FIRST NULL ROWS WITH TIES; - ^ +ERROR: row count cannot be null in FETCH FIRST ... WITH TIES clause --Testcase 79: CREATE VIEW limit_thousand_v_3 AS SELECT (fields->>'thousand')::int4 thousand FROM onek WHERE (fields->>'thousand')::int4 < 995 ORDER BY (fields->>'thousand')::int4 FETCH FIRST (NULL+1) ROWS WITH TIES; -ERROR: syntax error at or near "WITH" -LINE 2: ...lds->>'thousand')::int4 FETCH FIRST (NULL+1) ROWS WITH TIES; - ^ --Testcase 80: \d+ limit_thousand_v_3 + View "public.limit_thousand_v_3" + Column | Type | Collation | Nullable | Default | Storage | Description +----------+---------+-----------+----------+---------+---------+------------- + thousand | integer | | | | plain | +View definition: + SELECT (fields ->> 'thousand'::text)::integer AS thousand + FROM onek + WHERE ((fields ->> 'thousand'::text)::integer) < 995 + ORDER BY ((fields ->> 'thousand'::text)::integer) + FETCH FIRST (NULL::integer + 1) ROWS WITH TIES; + --Testcase 81: CREATE VIEW limit_thousand_v_4 AS SELECT (fields->>'thousand')::int4 thousand FROM onek WHERE (fields->>'thousand')::int4 < 995 ORDER BY (fields->>'thousand')::int4 FETCH FIRST NULL ROWS ONLY; @@ -717,21 +799,19 @@ CREATE VIEW limit_thousand_v_4 AS SELECT (fields->>'thousand')::int4 thousand FR ----------+---------+-----------+----------+---------+---------+------------- thousand | integer | | | | plain | View definition: - SELECT (onek.fields ->> 'thousand'::text)::integer AS thousand + SELECT (fields ->> 'thousand'::text)::integer AS thousand FROM onek - WHERE ((onek.fields ->> 'thousand'::text)::integer) < 995 - ORDER BY ((onek.fields ->> 'thousand'::text)::integer) + WHERE ((fields ->> 'thousand'::text)::integer) < 995 + ORDER BY ((fields ->> 'thousand'::text)::integer) LIMIT ALL; -- leave these views --Testcase 83: DROP VIEW limit_thousand_v_1; -ERROR: view "limit_thousand_v_1" does not exist --Testcase 84: DROP VIEW limit_thousand_v_2; --Testcase 85: DROP VIEW limit_thousand_v_3; -ERROR: view "limit_thousand_v_3" does not exist --Testcase 86: DROP VIEW limit_thousand_v_4; -- Clean up diff --git a/expected/12.12/schemaless/extra/prepare.out b/expected/16.0/schemaless/extra/prepare.out similarity index 87% rename from expected/12.12/schemaless/extra/prepare.out rename to expected/16.0/schemaless/extra/prepare.out index 13104ac..b0218df 100644 --- a/expected/12.12/schemaless/extra/prepare.out +++ b/expected/16.0/schemaless/extra/prepare.out @@ -2,107 +2,107 @@ -- of the pg_prepared_statements view as prepared statements are -- created and removed. \set ECHO none ---Testcase 27: +--Testcase 1: CREATE EXTENSION influxdb_fdw; ---Testcase 28: +--Testcase 2: CREATE SERVER influxdb_svr FOREIGN DATA WRAPPER influxdb_fdw OPTIONS (dbname 'coredb', :SERVER); ---Testcase 29: +--Testcase 3: CREATE USER MAPPING FOR CURRENT_USER SERVER influxdb_svr OPTIONS (:AUTHENTICATION); ---Testcase 30: +--Testcase 4: CREATE FOREIGN TABLE tenk1 ( fields jsonb OPTIONS (fields 'true') ) SERVER influxdb_svr OPTIONS (table 'tenk', schemaless 'true'); -- Does not support this command -- ALTER TABLE tenk1 SET WITH OIDS; ---Testcase 31: +--Testcase 5: CREATE FOREIGN TABLE road ( fields jsonb OPTIONS (fields 'true') ) SERVER influxdb_svr OPTIONS (schemaless 'true'); ---Testcase 32: +--Testcase 6: CREATE FOREIGN TABLE road_tmp (fields jsonb OPTIONS (fields 'true')) SERVER influxdb_svr OPTIONS (schemaless 'true'); ---Testcase 1: -SELECT name, statement, parameter_types FROM pg_prepared_statements; - name | statement | parameter_types -------+-----------+----------------- +--Testcase 7: +SELECT name, statement, parameter_types, result_types FROM pg_prepared_statements; + name | statement | parameter_types | result_types +------+-----------+-----------------+-------------- (0 rows) ---Testcase 2: +--Testcase 8: PREPARE q1 AS SELECT (fields->>'a')::int AS a FROM road_tmp; ---Testcase 3: +--Testcase 9: EXECUTE q1; a --- 1 (1 row) ---Testcase 4: -SELECT name, statement, parameter_types FROM pg_prepared_statements; - name | statement | parameter_types -------+--------------------------------------------------------------+----------------- - q1 | PREPARE q1 AS SELECT (fields->>'a')::int AS a FROM road_tmp; | {} +--Testcase 10: +SELECT name, statement, parameter_types, result_types FROM pg_prepared_statements; + name | statement | parameter_types | result_types +------+--------------------------------------------------------------+-----------------+-------------- + q1 | PREPARE q1 AS SELECT (fields->>'a')::int AS a FROM road_tmp; | {} | {integer} (1 row) -- should fail ---Testcase 5: +--Testcase 11: PREPARE q1 AS SELECT (fields->>'b')::int b FROM road_tmp; ERROR: prepared statement "q1" already exists -- should succeed DEALLOCATE q1; ---Testcase 6: +--Testcase 12: PREPARE q1 AS SELECT (fields->>'b')::int b FROM road_tmp; ---Testcase 7: +--Testcase 13: EXECUTE q1; b --- 2 (1 row) ---Testcase 8: +--Testcase 14: PREPARE q2 AS SELECT (fields->>'b')::int AS b FROM road_tmp; ---Testcase 9: -SELECT name, statement, parameter_types FROM pg_prepared_statements; - name | statement | parameter_types -------+--------------------------------------------------------------+----------------- - q1 | PREPARE q1 AS SELECT (fields->>'b')::int b FROM road_tmp; | {} - q2 | PREPARE q2 AS SELECT (fields->>'b')::int AS b FROM road_tmp; | {} +--Testcase 15: +SELECT name, statement, parameter_types, result_types FROM pg_prepared_statements; + name | statement | parameter_types | result_types +------+--------------------------------------------------------------+-----------------+-------------- + q1 | PREPARE q1 AS SELECT (fields->>'b')::int b FROM road_tmp; | {} | {integer} + q2 | PREPARE q2 AS SELECT (fields->>'b')::int AS b FROM road_tmp; | {} | {integer} (2 rows) -- sql92 syntax DEALLOCATE PREPARE q1; ---Testcase 10: -SELECT name, statement, parameter_types FROM pg_prepared_statements; - name | statement | parameter_types -------+--------------------------------------------------------------+----------------- - q2 | PREPARE q2 AS SELECT (fields->>'b')::int AS b FROM road_tmp; | {} +--Testcase 16: +SELECT name, statement, parameter_types, result_types FROM pg_prepared_statements; + name | statement | parameter_types | result_types +------+--------------------------------------------------------------+-----------------+-------------- + q2 | PREPARE q2 AS SELECT (fields->>'b')::int AS b FROM road_tmp; | {} | {integer} (1 row) DEALLOCATE PREPARE q2; -- the view should return the empty set again ---Testcase 11: -SELECT name, statement, parameter_types FROM pg_prepared_statements; - name | statement | parameter_types -------+-----------+----------------- +--Testcase 17: +SELECT name, statement, parameter_types, result_types FROM pg_prepared_statements; + name | statement | parameter_types | result_types +------+-----------+-----------------+-------------- (0 rows) -- parameterized queries ---Testcase 12: +--Testcase 18: PREPARE q2(text) AS SELECT datname, datistemplate, datallowconn FROM pg_database WHERE datname = $1; ---Testcase 13: +--Testcase 19: EXECUTE q2('postgres'); datname | datistemplate | datallowconn ----------+---------------+-------------- postgres | f | t (1 row) ---Testcase 14: +--Testcase 20: PREPARE q3(text, int, float, boolean, smallint) AS SELECT * FROM tenk1 WHERE fields->>'string4' = $1 AND ((fields->>'four')::int = $2 OR (fields->>'ten')::int = $3::bigint OR true = $4 OR (fields->>'odd')::int = $5::int) ORDER BY (fields->>'unique1')::int; ---Testcase 15: +--Testcase 21: EXECUTE q3('AAAAxx', 5::smallint, 10.5::float, false, 4::bigint); fields ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- @@ -138,34 +138,36 @@ EXECUTE q3('AAAAxx', 5::smallint, 10.5::float, false, 4::bigint); (29 rows) -- too few params ---Testcase 16: +--Testcase 22: EXECUTE q3('bool'); ERROR: wrong number of parameters for prepared statement "q3" DETAIL: Expected 5 parameters but got 1. -- too many params ---Testcase 17: +--Testcase 23: EXECUTE q3('bytea', 5::smallint, 10.5::float, false, 4::bigint, true); ERROR: wrong number of parameters for prepared statement "q3" DETAIL: Expected 5 parameters but got 6. -- wrong param types ---Testcase 18: +--Testcase 24: EXECUTE q3(5::smallint, 10.5::float, false, 4::bigint, 'bytea'); ERROR: parameter $3 of type boolean cannot be coerced to the expected type double precision +LINE 1: EXECUTE q3(5::smallint, 10.5::float, false, 4::bigint, 'byte... + ^ HINT: You will need to rewrite or cast the expression. -- invalid type ---Testcase 19: +--Testcase 25: PREPARE q4(nonexistenttype) AS SELECT $1; ERROR: type "nonexistenttype" does not exist LINE 1: PREPARE q4(nonexistenttype) AS SELECT $1; ^ -- create table as execute ---Testcase 20: +--Testcase 26: PREPARE q5(int, text) AS SELECT * FROM tenk1 WHERE (fields->>'unique1')::int = $1 OR fields->>'stringu1' = $2 ORDER BY (fields->>'unique1')::int; ---Testcase 33: +--Testcase 27: CREATE TEMPORARY TABLE q5_prep_results AS EXECUTE q5(200, 'DTAAAA'); ---Testcase 21: +--Testcase 28: SELECT * FROM q5_prep_results; fields ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- @@ -187,46 +189,50 @@ SELECT * FROM q5_prep_results; {"odd": "122", "ten": "1", "two": "1", "even": "123", "four": "1", "twenty": "1", "hundred": "61", "string4": "OOOOxx", "unique1": "9961", "unique2": "2058", "stringu1": "DTAAAA", "stringu2": "EBDAAA", "tenthous": "9961", "thousand": "961", "fivethous": "4961", "twothousand": "1961"} (16 rows) ---Testcase 34: +--Testcase 29: CREATE TEMPORARY TABLE q5_prep_nodata AS EXECUTE q5(200, 'DTAAAA') WITH NO DATA; ---Testcase 22: +--Testcase 30: SELECT * FROM q5_prep_nodata; fields -------- (0 rows) -- unknown or unspecified parameter types: should succeed ---Testcase 23: +--Testcase 31: PREPARE q6 AS SELECT * FROM tenk1 WHERE (fields->>'unique1')::int = $1 AND fields->>'stringu1' = $2; ---Testcase 24: +--Testcase 32: PREPARE q7(unknown) AS SELECT * FROM road WHERE fields->>'thepath' = $1; ---Testcase 25: -SELECT name, statement, parameter_types FROM pg_prepared_statements +-- influxdb does not update +-- DML statements +-- PREPARE q8 AS +-- UPDATE tenk1 SET fields->>'stringu1' = $2 WHERE fields->>'unique1' = $1; +--Testcase 33: +SELECT name, statement, parameter_types, result_types FROM pg_prepared_statements ORDER BY name; - name | statement | parameter_types -------+-----------------------------------------------------------------------------------------------+---------------------------------------------------- - q2 | PREPARE q2(text) AS +| {text} - | SELECT datname, datistemplate, datallowconn +| - | FROM pg_database WHERE datname = $1; | - q3 | PREPARE q3(text, int, float, boolean, smallint) AS +| {text,integer,"double precision",boolean,smallint} - | SELECT * FROM tenk1 WHERE fields->>'string4' = $1 AND ((fields->>'four')::int = $2 OR+| - | (fields->>'ten')::int = $3::bigint OR true = $4 OR (fields->>'odd')::int = $5::int) +| - | ORDER BY (fields->>'unique1')::int; | - q5 | PREPARE q5(int, text) AS +| {integer,text} - | SELECT * FROM tenk1 WHERE (fields->>'unique1')::int = $1 OR fields->>'stringu1' = $2 +| - | ORDER BY (fields->>'unique1')::int; | - q6 | PREPARE q6 AS +| {integer,text} - | SELECT * FROM tenk1 WHERE (fields->>'unique1')::int = $1 AND fields->>'stringu1' = $2; | - q7 | PREPARE q7(unknown) AS +| {text} - | SELECT * FROM road WHERE fields->>'thepath' = $1; | + name | statement | parameter_types | result_types +------+-----------------------------------------------------------------------------------------------+----------------------------------------------------+------------------------ + q2 | PREPARE q2(text) AS +| {text} | {name,boolean,boolean} + | SELECT datname, datistemplate, datallowconn +| | + | FROM pg_database WHERE datname = $1; | | + q3 | PREPARE q3(text, int, float, boolean, smallint) AS +| {text,integer,"double precision",boolean,smallint} | {jsonb} + | SELECT * FROM tenk1 WHERE fields->>'string4' = $1 AND ((fields->>'four')::int = $2 OR+| | + | (fields->>'ten')::int = $3::bigint OR true = $4 OR (fields->>'odd')::int = $5::int) +| | + | ORDER BY (fields->>'unique1')::int; | | + q5 | PREPARE q5(int, text) AS +| {integer,text} | {jsonb} + | SELECT * FROM tenk1 WHERE (fields->>'unique1')::int = $1 OR fields->>'stringu1' = $2 +| | + | ORDER BY (fields->>'unique1')::int; | | + q6 | PREPARE q6 AS +| {integer,text} | {jsonb} + | SELECT * FROM tenk1 WHERE (fields->>'unique1')::int = $1 AND fields->>'stringu1' = $2; | | + q7 | PREPARE q7(unknown) AS +| {text} | {jsonb} + | SELECT * FROM road WHERE fields->>'thepath' = $1; | | (5 rows) -- test DEALLOCATE ALL; DEALLOCATE ALL; ---Testcase 26: +--Testcase 34: SELECT name, statement, parameter_types FROM pg_prepared_statements ORDER BY name; name | statement | parameter_types diff --git a/expected/13.8/schemaless/extra/select.out b/expected/16.0/schemaless/extra/select.out similarity index 98% rename from expected/13.8/schemaless/extra/select.out rename to expected/16.0/schemaless/extra/select.out index 84f52d3..7df5b87 100644 --- a/expected/13.8/schemaless/extra/select.out +++ b/expected/16.0/schemaless/extra/select.out @@ -2,40 +2,40 @@ -- SELECT -- \set ECHO none ---Testcase 52: +--Testcase 1: CREATE EXTENSION influxdb_fdw; ---Testcase 53: +--Testcase 2: CREATE SERVER influxdb_svr FOREIGN DATA WRAPPER influxdb_fdw OPTIONS (dbname 'coredb', :SERVER); ---Testcase 54: +--Testcase 3: CREATE USER MAPPING FOR CURRENT_USER SERVER influxdb_svr OPTIONS (:AUTHENTICATION); ---Testcase 55: +--Testcase 4: CREATE FOREIGN TABLE onek ( fields jsonb OPTIONS (fields 'true') ) SERVER influxdb_svr OPTIONS (schemaless 'true'); ---Testcase 56: +--Testcase 5: CREATE FOREIGN TABLE onek2 ( fields jsonb OPTIONS (fields 'true') ) SERVER influxdb_svr OPTIONS (table 'onek', schemaless 'true'); ---Testcase 57: +--Testcase 6: CREATE FOREIGN TABLE INT8_TBL ( fields jsonb OPTIONS (fields 'true') ) SERVER influxdb_svr OPTIONS (schemaless 'true'); ---Testcase 58: +--Testcase 7: CREATE FOREIGN TABLE person ( fields jsonb OPTIONS (fields 'true') ) SERVER influxdb_svr OPTIONS (schemaless 'true'); ---Testcase 59: +--Testcase 8: CREATE FOREIGN TABLE emp ( fields jsonb OPTIONS (fields 'true') ) INHERITS (person) SERVER influxdb_svr OPTIONS (schemaless 'true'); NOTICE: merging column "fields" with inherited definition ---Testcase 60: +--Testcase 9: CREATE FOREIGN TABLE student ( fields jsonb OPTIONS (fields 'true') ) INHERITS (person) SERVER influxdb_svr OPTIONS (schemaless 'true'); NOTICE: merging column "fields" with inherited definition ---Testcase 61: +--Testcase 10: CREATE FOREIGN TABLE stud_emp ( fields jsonb OPTIONS (fields 'true') ) INHERITS (emp, student) SERVER influxdb_svr OPTIONS (schemaless 'true'); @@ -44,7 +44,7 @@ NOTICE: merging column "fields" with inherited definition -- btree index -- awk '{if($1<10){print;}else{next;}}' onek.data | sort +0n -1 -- ---Testcase 1: +--Testcase 11: SELECT * FROM onek WHERE (onek.fields->>'unique1')::int4 < 10 ORDER BY (onek.fields->>'unique1')::int4; @@ -65,7 +65,7 @@ SELECT * FROM onek -- -- awk '{if($1<20){print $1,$14;}else{next;}}' onek.data | sort +0nr -1 -- ---Testcase 2: +--Testcase 12: SELECT (onek.fields->>'unique1')::int4 unique1, (onek.fields->>'stringu1')::name stringu1 FROM onek WHERE (onek.fields->>'unique1')::int4 < 20 ORDER BY (onek.fields->>'unique1')::int4 using >; @@ -96,7 +96,7 @@ SELECT (onek.fields->>'unique1')::int4 unique1, (onek.fields->>'stringu1')::name -- -- awk '{if($1>980){print $1,$14;}else{next;}}' onek.data | sort +1d -2 -- ---Testcase 3: +--Testcase 13: SELECT (onek.fields->>'unique1')::int4 unique1, (onek.fields->>'stringu1')::name stringu1 FROM onek WHERE (onek.fields->>'unique1')::int4 > 980 ORDER BY (fields->>'stringu1')::name using <; @@ -127,7 +127,7 @@ SELECT (onek.fields->>'unique1')::int4 unique1, (onek.fields->>'stringu1')::name -- awk '{if($1>980){print $1,$16;}else{next;}}' onek.data | -- sort +1d -2 +0nr -1 -- ---Testcase 4: +--Testcase 14: SELECT (onek.fields->>'unique1')::int4 unique1, (onek.fields->>'string4')::name string4 FROM onek WHERE (onek.fields->>'unique1')::int4 > 980 ORDER BY (fields->>'string4')::name using <, (fields->>'unique1')::int4 using >; @@ -158,7 +158,7 @@ SELECT (onek.fields->>'unique1')::int4 unique1, (onek.fields->>'string4')::name -- awk '{if($1>980){print $1,$16;}else{next;}}' onek.data | -- sort +1dr -2 +0n -1 -- ---Testcase 5: +--Testcase 15: SELECT (onek.fields->>'unique1')::int4 unique1, (onek.fields->>'string4')::name string4 FROM onek WHERE (onek.fields->>'unique1')::int4 > 980 ORDER BY (fields->>'string4')::name using >, (fields->>'unique1')::int4 using <; @@ -189,7 +189,7 @@ SELECT (onek.fields->>'unique1')::int4 unique1, (onek.fields->>'string4')::name -- awk '{if($1<20){print $1,$16;}else{next;}}' onek.data | -- sort +0nr -1 +1d -2 -- ---Testcase 6: +--Testcase 16: SELECT (onek.fields->>'unique1')::int4 unique1, (onek.fields->>'string4')::name string4 FROM onek WHERE (onek.fields->>'unique1')::int4 < 20 ORDER BY (fields->>'unique1')::int4 using >, (fields->>'string4')::name using <; @@ -221,7 +221,7 @@ SELECT (onek.fields->>'unique1')::int4 unique1, (onek.fields->>'string4')::name -- awk '{if($1<20){print $1,$16;}else{next;}}' onek.data | -- sort +0n -1 +1dr -2 -- ---Testcase 7: +--Testcase 17: SELECT (onek.fields->>'unique1')::int4 unique1, (onek.fields->>'string4')::name string4 FROM onek WHERE (onek.fields->>'unique1')::int4 < 20 ORDER BY (fields->>'unique1')::int4 using <, (fields->>'string4')::name using >; @@ -257,13 +257,16 @@ SELECT (onek.fields->>'unique1')::int4 unique1, (onek.fields->>'string4')::name -- followed by sort, because that could hide index ordering problems. -- -- ANALYZE onek2; +--Testcase 18: SET enable_seqscan TO off; +--Testcase 19: SET enable_bitmapscan TO off; +--Testcase 20: SET enable_sort TO off; -- -- awk '{if($1<10){print $0;}else{next;}}' onek.data | sort +0n -1 -- ---Testcase 8: +--Testcase 21: SELECT onek2.* FROM onek2 WHERE (onek2.fields->>'unique1')::int4 < 10 order by 1; fields ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- @@ -282,7 +285,7 @@ SELECT onek2.* FROM onek2 WHERE (onek2.fields->>'unique1')::int4 < 10 order by 1 -- -- awk '{if($1<20){print $1,$14;}else{next;}}' onek.data | sort +0nr -1 -- ---Testcase 9: +--Testcase 22: SELECT (onek2.fields->>'unique1')::int4 unique1, (onek2.fields->>'stringu1')::name stringu1 FROM onek2 WHERE (onek2.fields->>'unique1')::int4 < 20 ORDER BY (fields->>'unique1')::int4 using >; @@ -313,7 +316,7 @@ SELECT (onek2.fields->>'unique1')::int4 unique1, (onek2.fields->>'stringu1')::na -- -- awk '{if($1>980){print $1,$14;}else{next;}}' onek.data | sort +1d -2 -- ---Testcase 10: +--Testcase 23: SELECT (onek2.fields->>'unique1')::int4 unique1, (onek2.fields->>'stringu1')::name stringu1 FROM onek2 WHERE (onek2.fields->>'unique1')::int4 > 980 order by 1; unique1 | stringu1 @@ -339,13 +342,16 @@ SELECT (onek2.fields->>'unique1')::int4 unique1, (onek2.fields->>'stringu1')::na 999 | LMAAAA (19 rows) +--Testcase 24: RESET enable_seqscan; +--Testcase 25: RESET enable_bitmapscan; +--Testcase 26: RESET enable_sort; ---Testcase 11: -SELECT (fields->>'two')::int4 two, (fields->>'stringu1')::name stringu1, (fields->>'ten')::int4 ten, (fields->>'string4')::name string4 - INTO TABLE tmp - FROM onek; +--Testcase 27: +--SELECT (fields->>'two')::int4 two, (fields->>'stringu1')::name stringu1, (fields->>'ten')::int4 ten, (fields->>'string4')::name string4 +-- INTO TABLE tmp +-- FROM onek; -- -- awk '{print $1,$2;}' person.data | -- awk '{if(NF!=2){print $3,$2;}else{print;}}' - emp.data | @@ -353,7 +359,7 @@ SELECT (fields->>'two')::int4 two, (fields->>'stringu1')::name stringu1, (fields -- awk 'BEGIN{FS=" ";}{if(NF!=2){print $4,$5;}else{print;}}' - stud_emp.data -- -- SELECT name, age FROM person*; ??? check if different ---Testcase 12: +--Testcase 28: SELECT p.fields->>'name' "name", (p.fields->>'age')::int4 age FROM person* p; name | age ---------+----- @@ -424,7 +430,7 @@ SELECT p.fields->>'name' "name", (p.fields->>'age')::int4 age FROM person* p; -- awk 'BEGIN{FS=" ";}{if(NF!=1){print $4,$5;}else{print;}}' - stud_emp.data | -- sort +1nr -2 -- ---Testcase 13: +--Testcase 29: SELECT p.fields->>'name' "name", (p.fields->>'age')::int4 age FROM person* p ORDER BY (fields->>'age')::int4 using >, fields->>'name'; name | age ---------+----- @@ -491,21 +497,21 @@ SELECT p.fields->>'name' "name", (p.fields->>'age')::int4 age FROM person* p ORD -- -- Test some cases involving whole-row Var referencing a subquery -- ---Testcase 14: +--Testcase 30: select foo from (select 1 offset 0) as foo; foo ----- (1) (1 row) ---Testcase 15: +--Testcase 31: select foo from (select null offset 0) as foo; foo ----- () (1 row) ---Testcase 16: +--Testcase 32: select foo from (select 'xyzzy',1,null offset 0) as foo; foo ------------ @@ -515,7 +521,7 @@ select foo from (select 'xyzzy',1,null offset 0) as foo; -- -- Test VALUES lists -- ---Testcase 17: +--Testcase 33: select * from onek, (values(147, 'RFAAAA'), (931, 'VJAAAA')) as v (i, j) WHERE (onek.fields->>'unique1')::int4 = v.i and (onek.fields->>'stringu1')::name = v.j; fields | i | j @@ -526,7 +532,7 @@ select * from onek, (values(147, 'RFAAAA'), (931, 'VJAAAA')) as v (i, j) -- a more complex case -- looks like we're coding lisp :-) ---Testcase 18: +--Testcase 34: select * from onek, (values ((select i from (values(10000), (2), (389), (1000), (2000), ((select 10029))) as foo(i) @@ -538,7 +544,7 @@ select * from onek, (1 row) -- try VALUES in a subquery ---Testcase 19: +--Testcase 35: select * from onek where ((fields->>'unique1')::int4,(fields->>'ten')::int4) in (values (1,1), (20,0), (99,9), (17,99)) order by (fields->>'unique1')::int4; @@ -550,7 +556,7 @@ select * from onek (3 rows) -- VALUES is also legal as a standalone query or a set-operation member ---Testcase 20: +--Testcase 36: VALUES (1,2), (3,4+4), (7,77.7); column1 | column2 ---------+--------- @@ -559,7 +565,7 @@ VALUES (1,2), (3,4+4), (7,77.7); 7 | 77.7 (3 rows) ---Testcase 21: +--Testcase 37: VALUES (1,2), (3,4+4), (7,77.7) UNION ALL SELECT 2+2, 57 @@ -578,12 +584,20 @@ SELECT (fields->>'q1')::int8, (fields->>'q2')::int8 FROM int8_tbl; 4567890123456789 | -4567890123456789 (9 rows) +-- -- corner case: VALUES with no columns +-- InfluxDB not support table with no columns. +-- --Testcase 79: +-- CREATE FOREIGN TABLE nocols() SERVER influxdb_svr; +-- --Testcase 80: +-- INSERT INTO nocols DEFAULT VALUES; +-- --Testcase 81: +-- SELECT * FROM nocols n, LATERAL (VALUES(n.*)) v; -- -- Test ORDER BY options -- ---Testcase 62: +--Testcase 38: CREATE FOREIGN TABLE foo (fields jsonb OPTIONS (fields 'true')) SERVER influxdb_svr OPTIONS (schemaless 'true'); ---Testcase 22: +--Testcase 39: SELECT * FROM foo ORDER BY (fields->>'f1')::int; fields -------------- @@ -594,7 +608,7 @@ SELECT * FROM foo ORDER BY (fields->>'f1')::int; {"f1": "42"} (5 rows) ---Testcase 23: +--Testcase 40: SELECT * FROM foo ORDER BY (fields->>'f1')::int ASC; -- same thing fields -------------- @@ -605,7 +619,7 @@ SELECT * FROM foo ORDER BY (fields->>'f1')::int ASC; -- same thing {"f1": "42"} (5 rows) ---Testcase 24: +--Testcase 41: SELECT * FROM foo ORDER BY (fields->>'f1')::int NULLS FIRST; fields -------------- @@ -616,7 +630,7 @@ SELECT * FROM foo ORDER BY (fields->>'f1')::int NULLS FIRST; {"f1": "42"} (5 rows) ---Testcase 25: +--Testcase 42: SELECT * FROM foo ORDER BY (fields->>'f1')::int DESC; fields -------------- @@ -627,7 +641,7 @@ SELECT * FROM foo ORDER BY (fields->>'f1')::int DESC; {"f1": "1"} (5 rows) ---Testcase 26: +--Testcase 43: SELECT * FROM foo ORDER BY (fields->>'f1')::int DESC NULLS LAST; fields -------------- @@ -661,7 +675,7 @@ SELECT * FROM foo ORDER BY (fields->>'f1')::int DESC NULLS LAST; -- Test planning of some cases with partial indexes -- -- partial index is usable ---Testcase 27: +--Testcase 44: explain (costs off) select * from onek2 where (fields->>'unique2')::int4 = 11 and (fields->>'stringu1')::name = 'ATAAAA'; QUERY PLAN @@ -670,7 +684,7 @@ select * from onek2 where (fields->>'unique2')::int4 = 11 and (fields->>'stringu Filter: (((fields ->> 'stringu1'::text))::name = 'ATAAAA'::name) (2 rows) ---Testcase 28: +--Testcase 45: select * from onek2 where (fields->>'unique2')::int4 = 11 and (fields->>'stringu1')::name = 'ATAAAA'; fields ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- @@ -678,7 +692,7 @@ select * from onek2 where (fields->>'unique2')::int4 = 11 and (fields->>'stringu (1 row) -- actually run the query with an analyze to use the partial index ---Testcase 63: +--Testcase 46: explain (costs off, analyze on, timing off, summary off) select * from onek2 where (fields->>'unique2')::int4 = 11 and (fields->>'stringu1')::name = 'ATAAAA'; QUERY PLAN @@ -687,7 +701,7 @@ select * from onek2 where (fields->>'unique2')::int4 = 11 and (fields->>'stringu Filter: (((fields ->> 'stringu1'::text))::name = 'ATAAAA'::name) (2 rows) ---Testcase 30: +--Testcase 47: explain (costs off) select (fields->>'unique2')::int4 unique2 from onek2 where (fields->>'unique2')::int4 = 11 and (fields->>'stringu1')::name = 'ATAAAA'; QUERY PLAN @@ -696,7 +710,7 @@ select (fields->>'unique2')::int4 unique2 from onek2 where (fields->>'unique2'): Filter: (((fields ->> 'stringu1'::text))::name = 'ATAAAA'::name) (2 rows) ---Testcase 31: +--Testcase 48: select (fields->>'unique2')::int4 unique2 from onek2 where (fields->>'unique2')::int4 = 11 and (fields->>'stringu1')::name = 'ATAAAA'; unique2 --------- @@ -704,7 +718,7 @@ select (fields->>'unique2')::int4 unique2 from onek2 where (fields->>'unique2'): (1 row) -- partial index predicate implies clause, so no need for retest ---Testcase 32: +--Testcase 49: explain (costs off) select * from onek2 where (fields->>'unique2')::int4 = 11 and (fields->>'stringu1')::name < 'B'; QUERY PLAN @@ -713,14 +727,14 @@ select * from onek2 where (fields->>'unique2')::int4 = 11 and (fields->>'stringu Filter: (((fields ->> 'stringu1'::text))::name < 'B'::name) (2 rows) ---Testcase 33: +--Testcase 50: select * from onek2 where (fields->>'unique2')::int4 = 11 and (fields->>'stringu1')::name < 'B'; fields ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- {"odd": "8", "ten": "4", "two": "0", "even": "9", "four": "2", "twenty": "14", "hundred": "4", "string4": "VVVVxx", "unique1": "494", "unique2": "11", "stringu1": "ATAAAA", "stringu2": "LAAAAA", "tenthous": "494", "thousand": "94", "fivethous": "494", "twothousand": "94"} (1 row) ---Testcase 34: +--Testcase 51: explain (costs off) select (fields->>'unique2')::int4 unique2 from onek2 where (fields->>'unique2')::int4 = 11 and (fields->>'stringu1')::name < 'B'; QUERY PLAN @@ -729,7 +743,7 @@ select (fields->>'unique2')::int4 unique2 from onek2 where (fields->>'unique2'): Filter: (((fields ->> 'stringu1'::text))::name < 'B'::name) (2 rows) ---Testcase 35: +--Testcase 52: select (fields->>'unique2')::int4 unique2 from onek2 where (fields->>'unique2')::int4 = 11 and (fields->>'stringu1')::name < 'B'; unique2 --------- @@ -737,7 +751,7 @@ select (fields->>'unique2')::int4 unique2 from onek2 where (fields->>'unique2'): (1 row) -- but if it's an update target, must retest anyway ---Testcase 36: +--Testcase 53: explain (costs off) select (fields->>'unique2')::int4 unique2 from onek2 where (fields->>'unique2')::int4 = 11 and (fields->>'stringu1')::name < 'B' for update; QUERY PLAN @@ -747,7 +761,7 @@ select (fields->>'unique2')::int4 unique2 from onek2 where (fields->>'unique2'): Filter: (((fields ->> 'stringu1'::text))::name < 'B'::name) (3 rows) ---Testcase 37: +--Testcase 54: select (fields->>'unique2')::int4 unique2 from onek2 where (fields->>'unique2')::int4 = 11 and (fields->>'stringu1')::name < 'B' for update; unique2 --------- @@ -755,7 +769,7 @@ select (fields->>'unique2')::int4 unique2 from onek2 where (fields->>'unique2'): (1 row) -- partial index is not applicable ---Testcase 38: +--Testcase 55: explain (costs off) select (fields->>'unique2')::int4 unique2 from onek2 where (fields->>'unique2')::int4 = 11 and (fields->>'stringu1')::name < 'C'; QUERY PLAN @@ -764,7 +778,7 @@ select (fields->>'unique2')::int4 unique2 from onek2 where (fields->>'unique2'): Filter: (((fields ->> 'stringu1'::text))::name < 'C'::name) (2 rows) ---Testcase 39: +--Testcase 56: select (fields->>'unique2')::int4 unique2 from onek2 where (fields->>'unique2')::int4 = 11 and (fields->>'stringu1')::name < 'C'; unique2 --------- @@ -772,8 +786,9 @@ select (fields->>'unique2')::int4 unique2 from onek2 where (fields->>'unique2'): (1 row) -- partial index implies clause, but bitmap scan must recheck predicate anyway +--Testcase 57: SET enable_indexscan TO off; ---Testcase 40: +--Testcase 58: explain (costs off) select (fields->>'unique2')::int4 unique2 from onek2 where (fields->>'unique2')::int4 = 11 and (fields->>'stringu1')::name < 'B'; QUERY PLAN @@ -782,16 +797,17 @@ select (fields->>'unique2')::int4 unique2 from onek2 where (fields->>'unique2'): Filter: (((fields ->> 'stringu1'::text))::name < 'B'::name) (2 rows) ---Testcase 41: +--Testcase 59: select (fields->>'unique2')::int4 unique2 from onek2 where (fields->>'unique2')::int4 = 11 and (fields->>'stringu1')::name < 'B'; unique2 --------- 11 (1 row) +--Testcase 60: RESET enable_indexscan; -- check multi-index cases too ---Testcase 42: +--Testcase 61: explain (costs off) select (fields->>'unique1')::int4 unique1, (fields->>'unique2')::int4 unique2 from onek2 where ((fields->>'unique2')::int4 = 11 or (fields->>'unique1')::int4 = 0) and (fields->>'stringu1')::name < 'B'; @@ -801,7 +817,7 @@ select (fields->>'unique1')::int4 unique1, (fields->>'unique2')::int4 unique2 fr Filter: (((fields ->> 'stringu1'::text))::name < 'B'::name) (2 rows) ---Testcase 43: +--Testcase 62: select (fields->>'unique1')::int4 unique1, (fields->>'unique2')::int4 unique2 from onek2 where ((fields->>'unique2')::int4 = 11 or (fields->>'unique1')::int4 = 0) and (fields->>'stringu1')::name < 'B'; unique1 | unique2 @@ -810,7 +826,7 @@ select (fields->>'unique1')::int4 unique1, (fields->>'unique2')::int4 unique2 fr 0 | 998 (2 rows) ---Testcase 44: +--Testcase 63: explain (costs off) select (fields->>'unique1')::int4 unique1, (fields->>'unique2')::int4 unique2 from onek2 where ((fields->>'unique2')::int4 = 11 and (fields->>'stringu1')::name < 'B') or (fields->>'unique1')::int4 = 0; @@ -820,7 +836,7 @@ select (fields->>'unique1')::int4 unique1, (fields->>'unique2')::int4 unique2 fr Filter: (((((fields ->> 'unique2'::text))::integer = 11) AND (((fields ->> 'stringu1'::text))::name < 'B'::name)) OR (((fields ->> 'unique1'::text))::integer = 0)) (2 rows) ---Testcase 45: +--Testcase 64: select (fields->>'unique1')::int4 unique1, (fields->>'unique2')::int4 unique2 from onek2 where ((fields->>'unique2')::int4 = 11 and (fields->>'stringu1')::name < 'B') or (fields->>'unique1')::int4 = 0; unique1 | unique2 @@ -833,7 +849,7 @@ select (fields->>'unique1')::int4 unique1, (fields->>'unique2')::int4 unique2 fr -- Test some corner cases that have been known to confuse the planner -- -- ORDER BY on a constant doesn't really need any sorting ---Testcase 46: +--Testcase 65: SELECT 1 AS x ORDER BY x; x --- @@ -841,10 +857,10 @@ SELECT 1 AS x ORDER BY x; (1 row) -- But ORDER BY on a set-valued expression does ---Testcase 64: +--Testcase 66: create function sillysrf(int) returns setof int as 'values (1),(10),(2),($1)' language sql immutable; ---Testcase 47: +--Testcase 67: select sillysrf(42); sillysrf ---------- @@ -854,7 +870,7 @@ select sillysrf(42); 42 (4 rows) ---Testcase 48: +--Testcase 68: select sillysrf(-1) order by 1; sillysrf ---------- @@ -864,11 +880,11 @@ select sillysrf(-1) order by 1; 10 (4 rows) ---Testcase 65: +--Testcase 69: drop function sillysrf(int); -- X = X isn't a no-op, it's effectively X IS NOT NULL assuming = is strict -- (see bug #5084) ---Testcase 49: +--Testcase 70: select * from (values (2),(null),(1)) v(k) where k = k order by k; k --- @@ -876,7 +892,7 @@ select * from (values (2),(null),(1)) v(k) where k = k order by k; 2 (2 rows) ---Testcase 50: +--Testcase 71: select * from (values (2),(null),(1)) v(k) where k = k; k --- @@ -886,12 +902,12 @@ select * from (values (2),(null),(1)) v(k) where k = k; -- Test partitioned tables with no partitions, which should be handled the -- same as the non-inheritance case when expanding its RTE. ---Testcase 66: +--Testcase 72: create table list_parted_tbl (a int,b int) partition by list (a); ---Testcase 67: +--Testcase 73: create table list_parted_tbl1 partition of list_parted_tbl for values in (1) partition by list(b); ---Testcase 51: +--Testcase 74: explain (costs off) select * from list_parted_tbl; QUERY PLAN -------------------------- @@ -899,13 +915,13 @@ explain (costs off) select * from list_parted_tbl; One-Time Filter: false (2 rows) ---Testcase 68: +--Testcase 75: drop table list_parted_tbl; -- Clean up: -DROP TABLE IF EXISTS tmp; ---Testcase 69: +--DROP TABLE IF EXISTS tmp; +--Testcase 76: DROP USER MAPPING FOR CURRENT_USER SERVER influxdb_svr; ---Testcase 70: +--Testcase 77: DROP SERVER influxdb_svr CASCADE; NOTICE: drop cascades to 8 other objects DETAIL: drop cascades to foreign table onek @@ -916,5 +932,5 @@ drop cascades to foreign table emp drop cascades to foreign table student drop cascades to foreign table stud_emp drop cascades to foreign table foo ---Testcase 71: +--Testcase 78: DROP EXTENSION influxdb_fdw; diff --git a/expected/14.5/schemaless/extra/select_having.out b/expected/16.0/schemaless/extra/select_having.out similarity index 98% rename from expected/14.5/schemaless/extra/select_having.out rename to expected/16.0/schemaless/extra/select_having.out index b88def8..7b0a8f5 100644 --- a/expected/14.5/schemaless/extra/select_having.out +++ b/expected/16.0/schemaless/extra/select_having.out @@ -11,6 +11,7 @@ CREATE SERVER influxdb_svr FOREIGN DATA WRAPPER influxdb_fdw CREATE USER MAPPING FOR CURRENT_USER SERVER influxdb_svr OPTIONS (:AUTHENTICATION); --Testcase 4: CREATE FOREIGN TABLE test_having (fields jsonb OPTIONS (fields 'true')) SERVER influxdb_svr OPTIONS (schemaless 'true'); +--Testcase 30: CREATE FOREIGN TABLE test_having_nsc (a int, b int, c char(8), d char) SERVER influxdb_svr OPTIONS (table 'test_having'); --Testcase 5: INSERT INTO test_having_nsc VALUES (0, 1, 'XXXX', 'A'); @@ -122,8 +123,11 @@ SELECT 1 AS one FROM test_having WHERE 1/(fields->>'a')::int = 1 HAVING 1 < 2; --Testcase 26: -- Clean up: +--Testcase 31: DELETE FROM test_having_nsc; +--Testcase 32: DROP FOREIGN TABLE test_having; +--Testcase 33: DROP FOREIGN TABLE test_having_nsc; --Testcase 27: DROP USER MAPPING FOR CURRENT_USER SERVER influxdb_svr; diff --git a/expected/16.0/schemaless/influxdb_fdw.out b/expected/16.0/schemaless/influxdb_fdw.out new file mode 100644 index 0000000..07e19b9 --- /dev/null +++ b/expected/16.0/schemaless/influxdb_fdw.out @@ -0,0 +1,1603 @@ +--SET log_min_messages=debug1; +--SET client_min_messages=debug1; +--Testcase 1: +SET datestyle=ISO; +-- timestamp with time zone differs based on this +--Testcase 2: +SET timezone='Japan'; +\set ECHO none +--Testcase 3: +CREATE EXTENSION influxdb_fdw; +--Testcase 4: +CREATE SERVER server1 FOREIGN DATA WRAPPER influxdb_fdw OPTIONS +(dbname 'mydb', :SERVER); +--Testcase 5: +CREATE USER MAPPING FOR CURRENT_USER SERVER server1 OPTIONS (:AUTHENTICATION); +-- import time column as timestamp and text type +IMPORT FOREIGN SCHEMA public FROM SERVER server1 INTO public OPTIONS(import_time_text 'true', schemaless 'true'); +--Testcase 6: +SELECT * FROM cpu; + time | time_text | tags | fields +------------------------+----------------------+--------------------------------------+----------------------------------------------------------------------- + 2015-08-18 09:00:00+09 | 2015-08-18T00:00:00Z | {"tag1": "tag1_A", "tag2": "tag2_A"} | {"value1": "100", "value2": "0.5", "value3": "str", "value4": "true"} + 2015-08-18 09:00:00+09 | 2015-08-18T00:00:00Z | {"tag1": "tag1_B", "tag2": null} | {"value1": "100", "value2": "2", "value3": null, "value4": "false"} + 2015-08-18 09:48:08+09 | 2015-08-18T00:48:08Z | {"tag1": null, "tag2": "tag2_A"} | {"value1": null, "value2": "2", "value3": null, "value4": null} +(3 rows) + +--Testcase 7: +SELECT tags->>'tag1' tag1, (fields->>'value1')::bigint value1 FROM cpu; + tag1 | value1 +--------+-------- + tag1_A | 100 + tag1_B | 100 +(2 rows) + +--Testcase 8: +SELECT (fields->>'value1')::bigint value1, time, (fields->>'value2')::double precision value2 FROM cpu; + value1 | time | value2 +--------+------------------------+-------- + 100 | 2015-08-18 09:00:00+09 | 0.5 + 100 | 2015-08-18 09:00:00+09 | 2 + | 2015-08-18 09:48:08+09 | 2 +(3 rows) + +--Testcase 9: +SELECT (fields->>'value1')::bigint value1, time_text, (fields->>'value2')::double precision value2 FROM cpu; + value1 | time_text | value2 +--------+----------------------+-------- + 100 | 2015-08-18T00:00:00Z | 0.5 + 100 | 2015-08-18T00:00:00Z | 2 + | 2015-08-18T00:48:08Z | 2 +(3 rows) + +--Testcase 10: +DROP FOREIGN TABLE cpu; +--Testcase 11: +DROP FOREIGN TABLE t3; +--Testcase 12: +DROP FOREIGN TABLE t4; +--Testcase 13: +DROP FOREIGN TABLE tx; +--Testcase 14: +DROP FOREIGN TABLE numbers; +-- test EXECPT +IMPORT FOREIGN SCHEMA public EXCEPT (cpu, t3, t4, tx, numbers) FROM SERVER server1 INTO public OPTIONS(schemaless 'true'); +--Testcase 15: +SELECT ftoptions FROM pg_foreign_table; + ftoptions +----------- +(0 rows) + +-- test LIMIT TO +IMPORT FOREIGN SCHEMA public LIMIT TO (cpu) FROM SERVER server1 INTO public OPTIONS(schemaless 'true'); +--Testcase 16: +SELECT ftoptions FROM pg_foreign_table; + ftoptions +---------------------------------------------- + {table=cpu,schemaless=true,"tags=tag1,tag2"} +(1 row) + +--Testcase 17: +DROP FOREIGN TABLE cpu; +IMPORT FOREIGN SCHEMA public FROM SERVER server1 INTO public OPTIONS(import_time_text 'false', schemaless 'true'); +--Testcase 18: +SELECT * FROM cpu; + time | tags | fields +------------------------+--------------------------------------+----------------------------------------------------------------------- + 2015-08-18 09:00:00+09 | {"tag1": "tag1_A", "tag2": "tag2_A"} | {"value1": "100", "value2": "0.5", "value3": "str", "value4": "true"} + 2015-08-18 09:00:00+09 | {"tag1": "tag1_B", "tag2": null} | {"value1": "100", "value2": "2", "value3": null, "value4": "false"} + 2015-08-18 09:48:08+09 | {"tag1": null, "tag2": "tag2_A"} | {"value1": null, "value2": "2", "value3": null, "value4": null} +(3 rows) + +--Testcase 19: +SELECT tags->>'tag1' tag1, (fields->>'value1')::int value1 FROM cpu; + tag1 | value1 +--------+-------- + tag1_A | 100 + tag1_B | 100 +(2 rows) + +--Testcase 20: +SELECT (fields->>'value1')::int value1, time, (fields->>'value2')::double precision value2 FROM cpu; + value1 | time | value2 +--------+------------------------+-------- + 100 | 2015-08-18 09:00:00+09 | 0.5 + 100 | 2015-08-18 09:00:00+09 | 2 + | 2015-08-18 09:48:08+09 | 2 +(3 rows) + +--Testcase 21: +SELECT tags->>'tag1' tag1 FROM cpu; + tag1 +-------- + tag1_A + tag1_B + +(3 rows) + +--Testcase 22: +SELECT * FROM numbers; + time | tags | fields +------------------------+---------------+------------------------ + 1970-01-01 09:00:00+09 | {"tag1": "a"} | {"a": "1", "b": "One"} + 1970-01-01 09:00:01+09 | {"tag1": "a"} | {"a": "2", "b": "Two"} +(2 rows) + +--Testcase 23: +\d cpu; + Foreign table "public.cpu" + Column | Type | Collation | Nullable | Default | FDW options +--------+--------------------------+-----------+----------+---------+----------------- + time | timestamp with time zone | | | | + tags | jsonb | | | | (tags 'true') + fields | jsonb | | | | (fields 'true') +Server: server1 +FDW options: ("table" 'cpu', schemaless 'true', tags 'tag1,tag2') + +--Testcase 24: +SELECT * FROM cpu WHERE (fields->>'value1')::int=100; + time | tags | fields +------------------------+--------------------------------------+----------------------------------------------------------------------- + 2015-08-18 09:00:00+09 | {"tag1": "tag1_A", "tag2": "tag2_A"} | {"value1": "100", "value2": "0.5", "value3": "str", "value4": "true"} + 2015-08-18 09:00:00+09 | {"tag1": "tag1_B", "tag2": null} | {"value1": "100", "value2": "2", "value3": null, "value4": "false"} +(2 rows) + +--Testcase 25: +SELECT * FROM cpu WHERE (fields->>'value2')::double precision=0.5; + time | tags | fields +------------------------+--------------------------------------+----------------------------------------------------------------------- + 2015-08-18 09:00:00+09 | {"tag1": "tag1_A", "tag2": "tag2_A"} | {"value1": "100", "value2": "0.5", "value3": "str", "value4": "true"} +(1 row) + +--Testcase 26: +SELECT * FROM cpu WHERE fields->>'value3'='str'; + time | tags | fields +------------------------+--------------------------------------+----------------------------------------------------------------------- + 2015-08-18 09:00:00+09 | {"tag1": "tag1_A", "tag2": "tag2_A"} | {"value1": "100", "value2": "0.5", "value3": "str", "value4": "true"} +(1 row) + +--Testcase 27: +SELECT * FROM cpu WHERE (fields->>'value4')::boolean=true; + time | tags | fields +------------------------+--------------------------------------+----------------------------------------------------------------------- + 2015-08-18 09:00:00+09 | {"tag1": "tag1_A", "tag2": "tag2_A"} | {"value1": "100", "value2": "0.5", "value3": "str", "value4": "true"} +(1 row) + +--Testcase 28: +SELECT * FROM cpu WHERE NOT ((fields->>'value4')::boolean AND (fields->>'value1')::int=100); + time | tags | fields +------------------------+----------------------------------+--------------------------------------------------------------------- + 2015-08-18 09:00:00+09 | {"tag1": "tag1_B", "tag2": null} | {"value1": "100", "value2": "2", "value3": null, "value4": "false"} +(1 row) + +--Testcase 29: +SELECT * FROM cpu WHERE tags->>'tag1'='tag1_A'; + time | tags | fields +------------------------+--------------------------------------+----------------------------------------------------------------------- + 2015-08-18 09:00:00+09 | {"tag1": "tag1_A", "tag2": "tag2_A"} | {"value1": "100", "value2": "0.5", "value3": "str", "value4": "true"} +(1 row) + +--Testcase 30: +EXPLAIN (VERBOSE, COSTS OFF) +SELECT * FROM cpu WHERE fields->>'value3' IS NULL; + QUERY PLAN +----------------------------------------------------- + Foreign Scan on public.cpu + Output: "time", tags, fields + Filter: ((cpu.fields ->> 'value3'::text) IS NULL) + InfluxDB query: SELECT * FROM "cpu" +(4 rows) + +--Testcase 31: +SELECT * FROM cpu WHERE fields->>'value3' IS NULL; + time | tags | fields +------------------------+----------------------------------+--------------------------------------------------------------------- + 2015-08-18 09:00:00+09 | {"tag1": "tag1_B", "tag2": null} | {"value1": "100", "value2": "2", "value3": null, "value4": "false"} + 2015-08-18 09:48:08+09 | {"tag1": null, "tag2": "tag2_A"} | {"value1": null, "value2": "2", "value3": null, "value4": null} +(2 rows) + +--Testcase 32: +SELECT * FROM cpu WHERE tags->>'tag2' IS NULL; + time | tags | fields +------------------------+----------------------------------+--------------------------------------------------------------------- + 2015-08-18 09:00:00+09 | {"tag1": "tag1_B", "tag2": null} | {"value1": "100", "value2": "2", "value3": null, "value4": "false"} +(1 row) + +--Testcase 33: +SELECT * FROM cpu WHERE fields->>'value3' IS NOT NULL; + time | tags | fields +------------------------+--------------------------------------+----------------------------------------------------------------------- + 2015-08-18 09:00:00+09 | {"tag1": "tag1_A", "tag2": "tag2_A"} | {"value1": "100", "value2": "0.5", "value3": "str", "value4": "true"} +(1 row) + +--Testcase 34: +SELECT * FROM cpu WHERE tags->>'tag2' IS NOT NULL; + time | tags | fields +------------------------+--------------------------------------+----------------------------------------------------------------------- + 2015-08-18 09:00:00+09 | {"tag1": "tag1_A", "tag2": "tag2_A"} | {"value1": "100", "value2": "0.5", "value3": "str", "value4": "true"} + 2015-08-18 09:48:08+09 | {"tag1": null, "tag2": "tag2_A"} | {"value1": null, "value2": "2", "value3": null, "value4": null} +(2 rows) + +-- InfluxDB not support compare timestamp with OR condition +--Testcase 35: +SELECT * FROM cpu WHERE time = '2015-08-18 09:48:08+09' OR (fields->>'value2')::double precision = 0.5; + time | tags | fields +------------------------+--------------------------------------+----------------------------------------------------------------------- + 2015-08-18 09:00:00+09 | {"tag1": "tag1_A", "tag2": "tag2_A"} | {"value1": "100", "value2": "0.5", "value3": "str", "value4": "true"} + 2015-08-18 09:48:08+09 | {"tag1": null, "tag2": "tag2_A"} | {"value1": null, "value2": "2", "value3": null, "value4": null} +(2 rows) + +-- InfluxDB not support compare timestamp with != or <> +--Testcase 36: +SELECT * FROM cpu WHERE time != '2015-08-18 09:48:08+09'; + time | tags | fields +------------------------+--------------------------------------+----------------------------------------------------------------------- + 2015-08-18 09:00:00+09 | {"tag1": "tag1_A", "tag2": "tag2_A"} | {"value1": "100", "value2": "0.5", "value3": "str", "value4": "true"} + 2015-08-18 09:00:00+09 | {"tag1": "tag1_B", "tag2": null} | {"value1": "100", "value2": "2", "value3": null, "value4": "false"} +(2 rows) + +--Testcase 37: +SELECT * FROM cpu WHERE time <> '2015-08-18 09:48:08+09'; + time | tags | fields +------------------------+--------------------------------------+----------------------------------------------------------------------- + 2015-08-18 09:00:00+09 | {"tag1": "tag1_A", "tag2": "tag2_A"} | {"value1": "100", "value2": "0.5", "value3": "str", "value4": "true"} + 2015-08-18 09:00:00+09 | {"tag1": "tag1_B", "tag2": null} | {"value1": "100", "value2": "2", "value3": null, "value4": "false"} +(2 rows) + +--Testcase 38: +SELECT * FROM cpu WHERE time = '2015-08-18 09:48:08+09' OR (fields->>'value2')::double precision = 0.5; + time | tags | fields +------------------------+--------------------------------------+----------------------------------------------------------------------- + 2015-08-18 09:00:00+09 | {"tag1": "tag1_A", "tag2": "tag2_A"} | {"value1": "100", "value2": "0.5", "value3": "str", "value4": "true"} + 2015-08-18 09:48:08+09 | {"tag1": null, "tag2": "tag2_A"} | {"value1": null, "value2": "2", "value3": null, "value4": null} +(2 rows) + +-- There is inconsitency for search of missing values between tag and field +--Testcase 39: +EXPLAIN (VERBOSE, COSTS OFF) +SELECT * FROM cpu WHERE fields->>'value3' = ''; + QUERY PLAN +--------------------------------------------------------------- + Foreign Scan on public.cpu + Output: "time", tags, fields + InfluxDB query: SELECT * FROM "cpu" WHERE (("value3" = '')) +(3 rows) + +--Testcase 40: +SELECT * FROM cpu WHERE fields->>'value3' = ''; + time | tags | fields +------+------+-------- +(0 rows) + +--Testcase 41: +EXPLAIN (VERBOSE, COSTS OFF) +SELECT * FROM cpu WHERE tags->>'tag2' = ''; + QUERY PLAN +------------------------------------------------------------- + Foreign Scan on public.cpu + Output: "time", tags, fields + InfluxDB query: SELECT * FROM "cpu" WHERE (("tag2" = '')) +(3 rows) + +--Testcase 42: +SELECT * FROM cpu WHERE tags->>'tag2' = ''; + time | tags | fields +------------------------+----------------------------------+--------------------------------------------------------------------- + 2015-08-18 09:00:00+09 | {"tag1": "tag1_B", "tag2": null} | {"value1": "100", "value2": "2", "value3": null, "value4": "false"} +(1 row) + +--Testcase 43: +SELECT * FROM cpu WHERE tags->>'tag1' IN ('tag1_A', 'tag1_B'); + time | tags | fields +------------------------+--------------------------------------+----------------------------------------------------------------------- + 2015-08-18 09:00:00+09 | {"tag1": "tag1_A", "tag2": "tag2_A"} | {"value1": "100", "value2": "0.5", "value3": "str", "value4": "true"} + 2015-08-18 09:00:00+09 | {"tag1": "tag1_B", "tag2": null} | {"value1": "100", "value2": "2", "value3": null, "value4": "false"} +(2 rows) + +--Testcase 44: +EXPLAIN VERBOSE +SELECT * FROM cpu WHERE tags->>'tag1' IN ('tag1_A', 'tag1_B'); + QUERY PLAN +-------------------------------------------------------------------------------------- + Foreign Scan on public.cpu (cost=10.00..9.00 rows=9 width=72) + Output: "time", tags, fields + InfluxDB query: SELECT * FROM "cpu" WHERE ("tag1" = 'tag1_A' OR "tag1" = 'tag1_B') +(3 rows) + +-- Rows which have no tag are considered to have empty string +--Testcase 45: +SELECT * FROM cpu WHERE tags->>'tag1' NOT IN ('tag1_A', 'tag1_B'); + time | tags | fields +------------------------+----------------------------------+----------------------------------------------------------------- + 2015-08-18 09:48:08+09 | {"tag1": null, "tag2": "tag2_A"} | {"value1": null, "value2": "2", "value3": null, "value4": null} +(1 row) + +--Testcase 46: +EXPLAIN VERBOSE +SELECT * FROM cpu WHERE tags->>'tag1' NOT IN ('tag1_A', 'tag1_B'); + QUERY PLAN +----------------------------------------------------------------------------------------- + Foreign Scan on public.cpu (cost=10.00..844.00 rows=844 width=72) + Output: "time", tags, fields + InfluxDB query: SELECT * FROM "cpu" WHERE ("tag1" <> 'tag1_A' AND "tag1" <> 'tag1_B') +(3 rows) + +-- test IN/NOT IN +--Testcase 47: +SELECT * FROM cpu WHERE time IN ('2015-08-18 09:48:08+09','2016-08-28 07:44:00+07'); + time | tags | fields +------------------------+----------------------------------+----------------------------------------------------------------- + 2015-08-18 09:48:08+09 | {"tag1": null, "tag2": "tag2_A"} | {"value1": null, "value2": "2", "value3": null, "value4": null} +(1 row) + +--Testcase 48: +SELECT * FROM cpu WHERE time NOT IN ('2015-08-18 09:48:08+09','2016-08-28 07:44:00+07'); + time | tags | fields +------------------------+--------------------------------------+----------------------------------------------------------------------- + 2015-08-18 09:00:00+09 | {"tag1": "tag1_A", "tag2": "tag2_A"} | {"value1": "100", "value2": "0.5", "value3": "str", "value4": "true"} + 2015-08-18 09:00:00+09 | {"tag1": "tag1_B", "tag2": null} | {"value1": "100", "value2": "2", "value3": null, "value4": "false"} +(2 rows) + +--Testcase 49: +SELECT * FROM cpu WHERE (fields->>'value1')::int NOT IN (100, 97); + time | tags | fields +------+------+-------- +(0 rows) + +--Testcase 50: +SELECT * FROM cpu WHERE (fields->>'value1')::int IN (100, 97); + time | tags | fields +------------------------+--------------------------------------+----------------------------------------------------------------------- + 2015-08-18 09:00:00+09 | {"tag1": "tag1_A", "tag2": "tag2_A"} | {"value1": "100", "value2": "0.5", "value3": "str", "value4": "true"} + 2015-08-18 09:00:00+09 | {"tag1": "tag1_B", "tag2": null} | {"value1": "100", "value2": "2", "value3": null, "value4": "false"} +(2 rows) + +--Testcase 51: +SELECT * FROM cpu WHERE (fields->>'value2')::double precision IN (0.5, 10.9); + time | tags | fields +------------------------+--------------------------------------+----------------------------------------------------------------------- + 2015-08-18 09:00:00+09 | {"tag1": "tag1_A", "tag2": "tag2_A"} | {"value1": "100", "value2": "0.5", "value3": "str", "value4": "true"} +(1 row) + +--Testcase 52: +SELECT * FROM cpu WHERE (fields->>'value2')::double precision NOT IN (2, 9.7); + time | tags | fields +------------------------+--------------------------------------+----------------------------------------------------------------------- + 2015-08-18 09:00:00+09 | {"tag1": "tag1_A", "tag2": "tag2_A"} | {"value1": "100", "value2": "0.5", "value3": "str", "value4": "true"} +(1 row) + +--Testcase 53: +SELECT * FROM cpu WHERE (fields->>'value4')::boolean NOT IN ('true', 'true'); + time | tags | fields +------------------------+----------------------------------+--------------------------------------------------------------------- + 2015-08-18 09:00:00+09 | {"tag1": "tag1_B", "tag2": null} | {"value1": "100", "value2": "2", "value3": null, "value4": "false"} +(1 row) + +--Testcase 54: +SELECT * FROM cpu WHERE time IN ('2015-08-18 09:48:08+09','2016-08-28 07:44:00+07'); + time | tags | fields +------------------------+----------------------------------+----------------------------------------------------------------- + 2015-08-18 09:48:08+09 | {"tag1": null, "tag2": "tag2_A"} | {"value1": null, "value2": "2", "value3": null, "value4": null} +(1 row) + +--Testcase 55: +SELECT * FROM cpu WHERE time NOT IN ('2015-08-18 09:48:08+09','2016-08-28 07:44:00+07'); + time | tags | fields +------------------------+--------------------------------------+----------------------------------------------------------------------- + 2015-08-18 09:00:00+09 | {"tag1": "tag1_A", "tag2": "tag2_A"} | {"value1": "100", "value2": "0.5", "value3": "str", "value4": "true"} + 2015-08-18 09:00:00+09 | {"tag1": "tag1_B", "tag2": null} | {"value1": "100", "value2": "2", "value3": null, "value4": "false"} +(2 rows) + +--Testcase 56: +SELECT * FROM cpu WHERE (fields->>'value1')::int NOT IN (100, 97); + time | tags | fields +------+------+-------- +(0 rows) + +--Testcase 57: +SELECT * FROM cpu WHERE (fields->>'value1')::int IN (100, 97); + time | tags | fields +------------------------+--------------------------------------+----------------------------------------------------------------------- + 2015-08-18 09:00:00+09 | {"tag1": "tag1_A", "tag2": "tag2_A"} | {"value1": "100", "value2": "0.5", "value3": "str", "value4": "true"} + 2015-08-18 09:00:00+09 | {"tag1": "tag1_B", "tag2": null} | {"value1": "100", "value2": "2", "value3": null, "value4": "false"} +(2 rows) + +--Testcase 58: +SELECT * FROM cpu WHERE (fields->>'value2')::double precision IN (0.5, 10.9); + time | tags | fields +------------------------+--------------------------------------+----------------------------------------------------------------------- + 2015-08-18 09:00:00+09 | {"tag1": "tag1_A", "tag2": "tag2_A"} | {"value1": "100", "value2": "0.5", "value3": "str", "value4": "true"} +(1 row) + +--Testcase 59: +SELECT * FROM cpu WHERE (fields->>'value2')::double precision NOT IN (2, 9.7); + time | tags | fields +------------------------+--------------------------------------+----------------------------------------------------------------------- + 2015-08-18 09:00:00+09 | {"tag1": "tag1_A", "tag2": "tag2_A"} | {"value1": "100", "value2": "0.5", "value3": "str", "value4": "true"} +(1 row) + +--Testcase 60: +SELECT * FROM cpu WHERE (fields->>'value4')::boolean NOT IN ('true', 'true'); + time | tags | fields +------------------------+----------------------------------+--------------------------------------------------------------------- + 2015-08-18 09:00:00+09 | {"tag1": "tag1_B", "tag2": null} | {"value1": "100", "value2": "2", "value3": null, "value4": "false"} +(1 row) + +--Testcase 61: +SELECT * FROM cpu WHERE (fields->>'value4')::boolean IN ('f', 't'); + time | tags | fields +------------------------+--------------------------------------+----------------------------------------------------------------------- + 2015-08-18 09:00:00+09 | {"tag1": "tag1_A", "tag2": "tag2_A"} | {"value1": "100", "value2": "0.5", "value3": "str", "value4": "true"} + 2015-08-18 09:00:00+09 | {"tag1": "tag1_B", "tag2": null} | {"value1": "100", "value2": "2", "value3": null, "value4": "false"} +(2 rows) + +--Testcase 62: +CREATE FOREIGN TABLE t1(time timestamp with time zone ,tags jsonb OPTIONS(tags 'true'), fields jsonb OPTIONS (fields 'true')) SERVER server1 OPTIONS (table 'cpu', schemaless 'true', tags 'tag1'); +--Testcase 63: +CREATE FOREIGN TABLE t2(time timestamp ,tags jsonb OPTIONS(tags 'true'), fields jsonb OPTIONS (fields 'true')) SERVER server1 OPTIONS (table 'cpu', schemaless 'true', tags 'tag1'); +--Testcase 64: +SELECT * FROM t1; + time | tags | fields +------------------------+--------------------+----------------------------------------------------------------------------------------- + 2015-08-18 09:00:00+09 | {"tag1": "tag1_A"} | {"tag2": "tag2_A", "value1": "100", "value2": "0.5", "value3": "str", "value4": "true"} + 2015-08-18 09:00:00+09 | {"tag1": "tag1_B"} | {"tag2": null, "value1": "100", "value2": "2", "value3": null, "value4": "false"} + 2015-08-18 09:48:08+09 | {"tag1": null} | {"tag2": "tag2_A", "value1": null, "value2": "2", "value3": null, "value4": null} +(3 rows) + +--Testcase 65: +SELECT * FROM t2; + time | tags | fields +---------------------+--------------------+----------------------------------------------------------------------------------------- + 2015-08-18 00:00:00 | {"tag1": "tag1_A"} | {"tag2": "tag2_A", "value1": "100", "value2": "0.5", "value3": "str", "value4": "true"} + 2015-08-18 00:00:00 | {"tag1": "tag1_B"} | {"tag2": null, "value1": "100", "value2": "2", "value3": null, "value4": "false"} + 2015-08-18 00:48:08 | {"tag1": null} | {"tag2": "tag2_A", "value1": null, "value2": "2", "value3": null, "value4": null} +(3 rows) + +-- In following four queries, timestamp condition is added to InfluxQL as "time = '2015-08-18 00:00:00'" +--Testcase 66: +SELECT * FROM t1 WHERE time = TIMESTAMP WITH TIME ZONE '2015-08-18 09:00:00+09'; + time | tags | fields +------------------------+--------------------+----------------------------------------------------------------------------------------- + 2015-08-18 09:00:00+09 | {"tag1": "tag1_A"} | {"tag2": "tag2_A", "value1": "100", "value2": "0.5", "value3": "str", "value4": "true"} + 2015-08-18 09:00:00+09 | {"tag1": "tag1_B"} | {"tag2": null, "value1": "100", "value2": "2", "value3": null, "value4": "false"} +(2 rows) + +--Testcase 67: +SELECT * FROM t1 WHERE time = TIMESTAMP '2015-08-18 00:00:00'; + time | tags | fields +------------------------+--------------------+----------------------------------------------------------------------------------------- + 2015-08-18 09:00:00+09 | {"tag1": "tag1_A"} | {"tag2": "tag2_A", "value1": "100", "value2": "0.5", "value3": "str", "value4": "true"} + 2015-08-18 09:00:00+09 | {"tag1": "tag1_B"} | {"tag2": null, "value1": "100", "value2": "2", "value3": null, "value4": "false"} +(2 rows) + +--Testcase 68: +SELECT * FROM t2 WHERE time = TIMESTAMP WITH TIME ZONE '2015-08-18 09:00:00+09'; + time | tags | fields +---------------------+--------------------+----------------------------------------------------------------------------------------- + 2015-08-18 00:00:00 | {"tag1": "tag1_A"} | {"tag2": "tag2_A", "value1": "100", "value2": "0.5", "value3": "str", "value4": "true"} + 2015-08-18 00:00:00 | {"tag1": "tag1_B"} | {"tag2": null, "value1": "100", "value2": "2", "value3": null, "value4": "false"} +(2 rows) + +--Testcase 69: +SELECT * FROM t2 WHERE time = TIMESTAMP '2015-08-18 00:00:00'; + time | tags | fields +---------------------+--------------------+----------------------------------------------------------------------------------------- + 2015-08-18 00:00:00 | {"tag1": "tag1_A"} | {"tag2": "tag2_A", "value1": "100", "value2": "0.5", "value3": "str", "value4": "true"} + 2015-08-18 00:00:00 | {"tag1": "tag1_B"} | {"tag2": null, "value1": "100", "value2": "2", "value3": null, "value4": "false"} +(2 rows) + +-- pushdown now() +--Testcase 70: +SELECT * FROM t2 WHERE now() > time; + time | tags | fields +---------------------+--------------------+----------------------------------------------------------------------------------------- + 2015-08-18 00:00:00 | {"tag1": "tag1_A"} | {"tag2": "tag2_A", "value1": "100", "value2": "0.5", "value3": "str", "value4": "true"} + 2015-08-18 00:00:00 | {"tag1": "tag1_B"} | {"tag2": null, "value1": "100", "value2": "2", "value3": null, "value4": "false"} + 2015-08-18 00:48:08 | {"tag1": null} | {"tag2": "tag2_A", "value1": null, "value2": "2", "value3": null, "value4": null} +(3 rows) + +--Testcase 71: +EXPLAIN VERBOSE +SELECT * FROM t2 WHERE now() > time; + QUERY PLAN +------------------------------------------------------------------- + Foreign Scan on public.t2 (cost=10.00..284.00 rows=284 width=72) + Output: "time", tags, fields + InfluxDB query: SELECT * FROM "cpu" WHERE ((now() > time)) +(3 rows) + +--Testcase 72: +SELECT * FROM t2 WHERE time = TIMESTAMP WITH TIME ZONE '2015-08-26 05:43:21.1+00' - interval '1 week 1 day 5 hour 43 minute 21 second 100 millisecond'; + time | tags | fields +---------------------+--------------------+----------------------------------------------------------------------------------------- + 2015-08-18 00:00:00 | {"tag1": "tag1_A"} | {"tag2": "tag2_A", "value1": "100", "value2": "0.5", "value3": "str", "value4": "true"} + 2015-08-18 00:00:00 | {"tag1": "tag1_B"} | {"tag2": null, "value1": "100", "value2": "2", "value3": null, "value4": "false"} +(2 rows) + +--Testcase 73: +EXPLAIN VERBOSE +SELECT * FROM t2 WHERE time = TIMESTAMP WITH TIME ZONE '2015-08-26 05:43:21.1+00' - interval '1 week 1 day 5 hour 43 minute 21 second 100 millisecond'; + QUERY PLAN +------------------------------------------------------------------------------------------------------ + Foreign Scan on public.t2 (cost=10.00..4.00 rows=4 width=72) + Output: "time", tags, fields + InfluxDB query: SELECT * FROM "cpu" WHERE ((time = ('2015-08-26 05:43:21.1' - 8d5h43m21s100000u))) +(3 rows) + +-- InfluxDB does not seem to support time column + interval, so below query returns empty result +-- SELECT * FROM t2 WHERE time + interval '1 week 1 day 5 hour 43 minute 21 second 100 millisecond' = TIMESTAMP WITH TIME ZONE '2015-08-26 05:43:21.1+00'; +-- EXPLAIN (VERBOSE, COSTS OFF) +-- SELECT * FROM t2 WHERE time + interval '1 week 1 day 5 hour 43 minute 21 second 100 millisecond' = TIMESTAMP WITH TIME ZONE '2015-08-26 05:43:21.1+00'; +-- InfluxDB does not support month or year interval, so not push down +--Testcase 74: +SELECT * FROM t2 WHERE time = TIMESTAMP '2015-09-18 00:00:00' - interval '1 months'; + time | tags | fields +---------------------+--------------------+----------------------------------------------------------------------------------------- + 2015-08-18 00:00:00 | {"tag1": "tag1_A"} | {"tag2": "tag2_A", "value1": "100", "value2": "0.5", "value3": "str", "value4": "true"} + 2015-08-18 00:00:00 | {"tag1": "tag1_B"} | {"tag2": null, "value1": "100", "value2": "2", "value3": null, "value4": "false"} +(2 rows) + +--Testcase 75: +EXPLAIN VERBOSE +SELECT * FROM t2 WHERE time = TIMESTAMP '2015-09-18 00:00:00' - interval '1 months'; + QUERY PLAN +------------------------------------------------------------------------------ + Foreign Scan on public.t2 (cost=10.00..4.00 rows=4 width=72) + Output: "time", tags, fields + InfluxDB query: SELECT * FROM "cpu" WHERE ((time = '2015-08-18 00:00:00')) +(3 rows) + +--Testcase 76: +SELECT * FROM t2 WHERE (fields->>'value1')::int = ANY (ARRAY(SELECT (fields->>'value1')::int FROM t1 WHERE (fields->>'value1')::int < 1000)); + time | tags | fields +---------------------+--------------------+----------------------------------------------------------------------------------------- + 2015-08-18 00:00:00 | {"tag1": "tag1_A"} | {"tag2": "tag2_A", "value1": "100", "value2": "0.5", "value3": "str", "value4": "true"} + 2015-08-18 00:00:00 | {"tag1": "tag1_B"} | {"tag2": null, "value1": "100", "value2": "2", "value3": null, "value4": "false"} +(2 rows) + +-- ANY with ARRAY expression +--Testcase 77: +EXPLAIN VERBOSE +SELECT (fields->>'a')::int a, fields->>'b' b FROM numbers WHERE (fields->>'a')::int = ANY(ARRAY[1, (fields->>'a')::int + 1]); + QUERY PLAN +----------------------------------------------------------------------------------------- + Foreign Scan on public.numbers (cost=10.00..15.15 rows=15 width=36) + Output: ((fields ->> 'a'::text))::integer, (fields ->> 'b'::text) + InfluxDB query: SELECT "a", "b" FROM "numbers" WHERE (("a" = 1) OR ("a" = ("a" + 1))) +(3 rows) + +--Testcase 78: +SELECT (fields->>'a')::int a, fields->>'b' b FROM numbers WHERE (fields->>'a')::int = ANY(ARRAY[1, (fields->>'a')::int + 1]); + a | b +---+----- + 1 | One +(1 row) + +--Testcase 79: +EXPLAIN VERBOSE +SELECT (fields->>'a')::int a, fields->>'b' b FROM numbers WHERE (fields->>'a')::int <> ANY(ARRAY[1, (fields->>'a')::int + 1]); + QUERY PLAN +------------------------------------------------------------------------------------------- + Foreign Scan on public.numbers (cost=10.00..1476.62 rows=1462 width=36) + Output: ((fields ->> 'a'::text))::integer, (fields ->> 'b'::text) + InfluxDB query: SELECT "a", "b" FROM "numbers" WHERE (("a" <> 1) OR ("a" <> ("a" + 1))) +(3 rows) + +--Testcase 80: +SELECT (fields->>'a')::int a, fields->>'b' b FROM numbers WHERE (fields->>'a')::int <> ANY(ARRAY[1, (fields->>'a')::int + 1]); + a | b +---+----- + 1 | One + 2 | Two +(2 rows) + +--Testcase 81: +EXPLAIN VERBOSE +SELECT (fields->>'a')::int a, fields->>'b' b FROM numbers WHERE (fields->>'a')::int >= ANY(ARRAY[1, (fields->>'a')::int + 1]); + QUERY PLAN +------------------------------------------------------------------------------------------- + Foreign Scan on public.numbers (cost=10.00..820.12 rows=812 width=36) + Output: ((fields ->> 'a'::text))::integer, (fields ->> 'b'::text) + InfluxDB query: SELECT "a", "b" FROM "numbers" WHERE (("a" >= 1) OR ("a" >= ("a" + 1))) +(3 rows) + +--Testcase 82: +SELECT (fields->>'a')::int a, fields->>'b' b FROM numbers WHERE (fields->>'a')::int >= ANY(ARRAY[1, (fields->>'a')::int + 1]); + a | b +---+----- + 1 | One + 2 | Two +(2 rows) + +--Testcase 83: +EXPLAIN VERBOSE +SELECT (fields->>'a')::int a, fields->>'b' b FROM numbers WHERE (fields->>'a')::int <= ANY(ARRAY[1, (fields->>'a')::int + 1]); + QUERY PLAN +------------------------------------------------------------------------------------------- + Foreign Scan on public.numbers (cost=10.00..820.12 rows=812 width=36) + Output: ((fields ->> 'a'::text))::integer, (fields ->> 'b'::text) + InfluxDB query: SELECT "a", "b" FROM "numbers" WHERE (("a" <= 1) OR ("a" <= ("a" + 1))) +(3 rows) + +--Testcase 84: +SELECT (fields->>'a')::int a, fields->>'b' b FROM numbers WHERE (fields->>'a')::int <= ANY(ARRAY[1, (fields->>'a')::int + 1]); + a | b +---+----- + 1 | One + 2 | Two +(2 rows) + +--Testcase 85: +EXPLAIN VERBOSE +SELECT (fields->>'a')::int a, fields->>'b' b FROM numbers WHERE (fields->>'a')::int > ANY(ARRAY[1, (fields->>'a')::int + 1]); + QUERY PLAN +----------------------------------------------------------------------------------------- + Foreign Scan on public.numbers (cost=10.00..820.12 rows=812 width=36) + Output: ((fields ->> 'a'::text))::integer, (fields ->> 'b'::text) + InfluxDB query: SELECT "a", "b" FROM "numbers" WHERE (("a" > 1) OR ("a" > ("a" + 1))) +(3 rows) + +--Testcase 86: +SELECT (fields->>'a')::int a, fields->>'b' b FROM numbers WHERE (fields->>'a')::int > ANY(ARRAY[1, (fields->>'a')::int + 1]); + a | b +---+----- + 2 | Two +(1 row) + +--Testcase 87: +EXPLAIN VERBOSE +SELECT (fields->>'a')::int a, fields->>'b' b FROM numbers WHERE (fields->>'a')::int < ANY(ARRAY[1, (fields->>'a')::int + 1]); + QUERY PLAN +----------------------------------------------------------------------------------------- + Foreign Scan on public.numbers (cost=10.00..820.12 rows=812 width=36) + Output: ((fields ->> 'a'::text))::integer, (fields ->> 'b'::text) + InfluxDB query: SELECT "a", "b" FROM "numbers" WHERE (("a" < 1) OR ("a" < ("a" + 1))) +(3 rows) + +--Testcase 88: +SELECT (fields->>'a')::int a, fields->>'b' b FROM numbers WHERE (fields->>'a')::int < ANY(ARRAY[1, (fields->>'a')::int + 1]); + a | b +---+----- + 1 | One + 2 | Two +(2 rows) + +-- ANY with ARRAY const +--Testcase 89: +EXPLAIN VERBOSE +SELECT (fields->>'a')::int a, fields->>'b' b FROM numbers WHERE (fields->>'a')::int = ANY(ARRAY[1, 2]); + QUERY PLAN +----------------------------------------------------------------------------- + Foreign Scan on public.numbers (cost=10.00..15.15 rows=15 width=36) + Output: ((fields ->> 'a'::text))::integer, (fields ->> 'b'::text) + InfluxDB query: SELECT "a", "b" FROM "numbers" WHERE ("a" = 1 OR "a" = 2) +(3 rows) + +--Testcase 90: +SELECT (fields->>'a')::int a, fields->>'b' b FROM numbers WHERE (fields->>'a')::int = ANY(ARRAY[1, 2]); + a | b +---+----- + 1 | One + 2 | Two +(2 rows) + +--Testcase 91: +EXPLAIN VERBOSE +SELECT (fields->>'a')::int a, fields->>'b' b FROM numbers WHERE (fields->>'a')::int <> ANY(ARRAY[1, 2]); + QUERY PLAN +------------------------------------------------------------------------------- + Foreign Scan on public.numbers (cost=10.00..1476.62 rows=1462 width=36) + Output: ((fields ->> 'a'::text))::integer, (fields ->> 'b'::text) + InfluxDB query: SELECT "a", "b" FROM "numbers" WHERE ("a" <> 1 OR "a" <> 2) +(3 rows) + +--Testcase 92: +SELECT (fields->>'a')::int a, fields->>'b' b FROM numbers WHERE (fields->>'a')::int <> ANY(ARRAY[1, 2]); + a | b +---+----- + 1 | One + 2 | Two +(2 rows) + +--Testcase 93: +EXPLAIN VERBOSE +SELECT (fields->>'a')::int a, fields->>'b' b FROM numbers WHERE (fields->>'a')::int >= ANY(ARRAY[1, 2]); + QUERY PLAN +------------------------------------------------------------------------------- + Foreign Scan on public.numbers (cost=10.00..820.12 rows=812 width=36) + Output: ((fields ->> 'a'::text))::integer, (fields ->> 'b'::text) + InfluxDB query: SELECT "a", "b" FROM "numbers" WHERE ("a" >= 1 OR "a" >= 2) +(3 rows) + +--Testcase 94: +SELECT (fields->>'a')::int a, fields->>'b' b FROM numbers WHERE (fields->>'a')::int >= ANY(ARRAY[1, 2]); + a | b +---+----- + 1 | One + 2 | Two +(2 rows) + +--Testcase 95: +EXPLAIN VERBOSE +SELECT (fields->>'a')::int a, fields->>'b' b FROM numbers WHERE (fields->>'a')::int <= ANY(ARRAY[1, 2]); + QUERY PLAN +------------------------------------------------------------------------------- + Foreign Scan on public.numbers (cost=10.00..820.12 rows=812 width=36) + Output: ((fields ->> 'a'::text))::integer, (fields ->> 'b'::text) + InfluxDB query: SELECT "a", "b" FROM "numbers" WHERE ("a" <= 1 OR "a" <= 2) +(3 rows) + +--Testcase 96: +SELECT (fields->>'a')::int a, fields->>'b' b FROM numbers WHERE (fields->>'a')::int <= ANY(ARRAY[1, 2]); + a | b +---+----- + 1 | One + 2 | Two +(2 rows) + +--Testcase 97: +EXPLAIN VERBOSE +SELECT (fields->>'a')::int a, fields->>'b' b FROM numbers WHERE (fields->>'a')::int > ANY(ARRAY[1, 2]); + QUERY PLAN +----------------------------------------------------------------------------- + Foreign Scan on public.numbers (cost=10.00..820.12 rows=812 width=36) + Output: ((fields ->> 'a'::text))::integer, (fields ->> 'b'::text) + InfluxDB query: SELECT "a", "b" FROM "numbers" WHERE ("a" > 1 OR "a" > 2) +(3 rows) + +--Testcase 98: +SELECT (fields->>'a')::int a, fields->>'b' b FROM numbers WHERE (fields->>'a')::int > ANY(ARRAY[1, 2]); + a | b +---+----- + 2 | Two +(1 row) + +--Testcase 99: +EXPLAIN VERBOSE +SELECT (fields->>'a')::int a, fields->>'b' b FROM numbers WHERE (fields->>'a')::int < ANY(ARRAY[1, 2]); + QUERY PLAN +----------------------------------------------------------------------------- + Foreign Scan on public.numbers (cost=10.00..820.12 rows=812 width=36) + Output: ((fields ->> 'a'::text))::integer, (fields ->> 'b'::text) + InfluxDB query: SELECT "a", "b" FROM "numbers" WHERE ("a" < 1 OR "a" < 2) +(3 rows) + +--Testcase 100: +SELECT (fields->>'a')::int a, fields->>'b' b FROM numbers WHERE (fields->>'a')::int < ANY(ARRAY[1, 2]); + a | b +---+----- + 1 | One +(1 row) + +--Testcase 101: +EXPLAIN VERBOSE +SELECT (fields->>'a')::int a, fields->>'b' b FROM numbers WHERE (fields->>'a')::int = ANY('{1, 2, 3}'); + QUERY PLAN +---------------------------------------------------------------------------------------- + Foreign Scan on public.numbers (cost=10.00..22.22 rows=22 width=36) + Output: ((fields ->> 'a'::text))::integer, (fields ->> 'b'::text) + InfluxDB query: SELECT "a", "b" FROM "numbers" WHERE ("a" = 1 OR "a" = 2 OR "a" = 3) +(3 rows) + +--Testcase 102: +SELECT (fields->>'a')::int a, fields->>'b' b FROM numbers WHERE (fields->>'a')::int = ANY('{1, 2, 3}'); + a | b +---+----- + 1 | One + 2 | Two +(2 rows) + +--Testcase 103: +EXPLAIN VERBOSE +SELECT (fields->>'a')::int a, fields->>'b' b FROM numbers WHERE (fields->>'a')::int <> ANY('{1, 2, 3}'); + QUERY PLAN +------------------------------------------------------------------------------------------- + Foreign Scan on public.numbers (cost=10.00..1476.62 rows=1462 width=36) + Output: ((fields ->> 'a'::text))::integer, (fields ->> 'b'::text) + InfluxDB query: SELECT "a", "b" FROM "numbers" WHERE ("a" <> 1 OR "a" <> 2 OR "a" <> 3) +(3 rows) + +--Testcase 104: +SELECT (fields->>'a')::int a, fields->>'b' b FROM numbers WHERE (fields->>'a')::int <> ANY('{1, 2, 3}'); + a | b +---+----- + 1 | One + 2 | Two +(2 rows) + +-- ALL with ARRAY expression +--Testcase 105: +EXPLAIN VERBOSE +SELECT (fields->>'a')::int a, fields->>'b' b FROM numbers WHERE (fields->>'a')::int = ALL(ARRAY[1, (fields->>'a')::int * 1]); + QUERY PLAN +------------------------------------------------------------------------------------------ + Foreign Scan on public.numbers (cost=10.00..1.01 rows=1 width=36) + Output: ((fields ->> 'a'::text))::integer, (fields ->> 'b'::text) + InfluxDB query: SELECT "a", "b" FROM "numbers" WHERE (("a" = 1) AND ("a" = ("a" * 1))) +(3 rows) + +--Testcase 106: +SELECT (fields->>'a')::int a, fields->>'b' b FROM numbers WHERE (fields->>'a')::int = ALL(ARRAY[1, (fields->>'a')::int * 1]); + a | b +---+----- + 1 | One +(1 row) + +--Testcase 107: +EXPLAIN VERBOSE +SELECT (fields->>'a')::int a, fields->>'b' b FROM numbers WHERE (fields->>'a')::int <> ALL(ARRAY[1, (fields->>'a')::int + 1]); + QUERY PLAN +-------------------------------------------------------------------------------------------- + Foreign Scan on public.numbers (cost=10.00..1461.47 rows=1447 width=36) + Output: ((fields ->> 'a'::text))::integer, (fields ->> 'b'::text) + InfluxDB query: SELECT "a", "b" FROM "numbers" WHERE (("a" <> 1) AND ("a" <> ("a" + 1))) +(3 rows) + +--Testcase 108: +SELECT (fields->>'a')::int a, fields->>'b' b FROM numbers WHERE (fields->>'a')::int <> ALL(ARRAY[1, (fields->>'a')::int + 1]); + a | b +---+----- + 2 | Two +(1 row) + +--Testcase 109: +EXPLAIN VERBOSE +SELECT (fields->>'a')::int a, fields->>'b' b FROM numbers WHERE (fields->>'a')::int >= ALL(ARRAY[1, (fields->>'a')::int / 1]); + QUERY PLAN +-------------------------------------------------------------------------------------------- + Foreign Scan on public.numbers (cost=10.00..163.62 rows=162 width=36) + Output: ((fields ->> 'a'::text))::integer, (fields ->> 'b'::text) + InfluxDB query: SELECT "a", "b" FROM "numbers" WHERE (("a" >= 1) AND ("a" >= ("a" / 1))) +(3 rows) + +--Testcase 110: +SELECT (fields->>'a')::int a, fields->>'b' b FROM numbers WHERE (fields->>'a')::int >= ALL(ARRAY[1, (fields->>'a')::int / 1]); + a | b +---+----- + 1 | One + 2 | Two +(2 rows) + +--Testcase 111: +EXPLAIN VERBOSE +SELECT (fields->>'a')::int a, fields->>'b' b FROM numbers WHERE (fields->>'a')::int <= ALL(ARRAY[1, (fields->>'a')::int + 1]); + QUERY PLAN +-------------------------------------------------------------------------------------------- + Foreign Scan on public.numbers (cost=10.00..163.62 rows=162 width=36) + Output: ((fields ->> 'a'::text))::integer, (fields ->> 'b'::text) + InfluxDB query: SELECT "a", "b" FROM "numbers" WHERE (("a" <= 1) AND ("a" <= ("a" + 1))) +(3 rows) + +--Testcase 112: +SELECT (fields->>'a')::int a, fields->>'b' b FROM numbers WHERE (fields->>'a')::int <= ALL(ARRAY[1, (fields->>'a')::int + 1]); + a | b +---+----- + 1 | One +(1 row) + +--Testcase 113: +EXPLAIN VERBOSE +SELECT (fields->>'a')::int a, fields->>'b' b FROM numbers WHERE (fields->>'a')::int > ALL(ARRAY[1, (fields->>'a')::int - 1]); + QUERY PLAN +------------------------------------------------------------------------------------------ + Foreign Scan on public.numbers (cost=10.00..163.62 rows=162 width=36) + Output: ((fields ->> 'a'::text))::integer, (fields ->> 'b'::text) + InfluxDB query: SELECT "a", "b" FROM "numbers" WHERE (("a" > 1) AND ("a" > ("a" - 1))) +(3 rows) + +--Testcase 114: +SELECT (fields->>'a')::int a, fields->>'b' b FROM numbers WHERE (fields->>'a')::int > ALL(ARRAY[1, (fields->>'a')::int - 1]); + a | b +---+----- + 2 | Two +(1 row) + +--Testcase 115: +EXPLAIN VERBOSE +SELECT (fields->>'a')::int a, fields->>'b' b FROM numbers WHERE (fields->>'a')::int < ALL(ARRAY[2, (fields->>'a')::int + 1]); + QUERY PLAN +------------------------------------------------------------------------------------------ + Foreign Scan on public.numbers (cost=10.00..163.62 rows=162 width=36) + Output: ((fields ->> 'a'::text))::integer, (fields ->> 'b'::text) + InfluxDB query: SELECT "a", "b" FROM "numbers" WHERE (("a" < 2) AND ("a" < ("a" + 1))) +(3 rows) + +--Testcase 116: +SELECT (fields->>'a')::int a, fields->>'b' b FROM numbers WHERE (fields->>'a')::int < ALL(ARRAY[2, (fields->>'a')::int + 1]); + a | b +---+----- + 1 | One +(1 row) + +-- ALL with ARRAY const +--Testcase 117: +EXPLAIN VERBOSE +SELECT (fields->>'a')::int a, fields->>'b' b FROM numbers WHERE (fields->>'a')::int = ALL(ARRAY[1, 1]); + QUERY PLAN +------------------------------------------------------------------------------ + Foreign Scan on public.numbers (cost=10.00..1.01 rows=1 width=36) + Output: ((fields ->> 'a'::text))::integer, (fields ->> 'b'::text) + InfluxDB query: SELECT "a", "b" FROM "numbers" WHERE ("a" = 1 AND "a" = 1) +(3 rows) + +--Testcase 118: +SELECT (fields->>'a')::int a, fields->>'b' b FROM numbers WHERE (fields->>'a')::int = ALL(ARRAY[1, 1]); + a | b +---+----- + 1 | One +(1 row) + +--Testcase 119: +EXPLAIN VERBOSE +SELECT (fields->>'a')::int a, fields->>'b' b FROM numbers WHERE (fields->>'a')::int <> ALL(ARRAY[1, 3]); + QUERY PLAN +-------------------------------------------------------------------------------- + Foreign Scan on public.numbers (cost=10.00..1461.47 rows=1447 width=36) + Output: ((fields ->> 'a'::text))::integer, (fields ->> 'b'::text) + InfluxDB query: SELECT "a", "b" FROM "numbers" WHERE ("a" <> 1 AND "a" <> 3) +(3 rows) + +--Testcase 120: +SELECT (fields->>'a')::int a, fields->>'b' b FROM numbers WHERE (fields->>'a')::int <> ALL(ARRAY[1, 3]); + a | b +---+----- + 2 | Two +(1 row) + +--Testcase 121: +EXPLAIN VERBOSE +SELECT (fields->>'a')::int a, fields->>'b' b FROM numbers WHERE (fields->>'a')::int >= ALL(ARRAY[1, 2]); + QUERY PLAN +-------------------------------------------------------------------------------- + Foreign Scan on public.numbers (cost=10.00..163.62 rows=162 width=36) + Output: ((fields ->> 'a'::text))::integer, (fields ->> 'b'::text) + InfluxDB query: SELECT "a", "b" FROM "numbers" WHERE ("a" >= 1 AND "a" >= 2) +(3 rows) + +--Testcase 122: +SELECT (fields->>'a')::int a, fields->>'b' b FROM numbers WHERE (fields->>'a')::int >= ALL(ARRAY[1, 2]); + a | b +---+----- + 2 | Two +(1 row) + +--Testcase 123: +EXPLAIN VERBOSE +SELECT (fields->>'a')::int a, fields->>'b' b FROM numbers WHERE (fields->>'a')::int <= ALL(ARRAY[1, 2]); + QUERY PLAN +-------------------------------------------------------------------------------- + Foreign Scan on public.numbers (cost=10.00..163.62 rows=162 width=36) + Output: ((fields ->> 'a'::text))::integer, (fields ->> 'b'::text) + InfluxDB query: SELECT "a", "b" FROM "numbers" WHERE ("a" <= 1 AND "a" <= 2) +(3 rows) + +--Testcase 124: +SELECT (fields->>'a')::int a, fields->>'b' b FROM numbers WHERE (fields->>'a')::int <= ALL(ARRAY[1, 2]); + a | b +---+----- + 1 | One +(1 row) + +--Testcase 125: +EXPLAIN VERBOSE +SELECT (fields->>'a')::int a, fields->>'b' b FROM numbers WHERE (fields->>'a')::int > ALL(ARRAY[0, 1]); + QUERY PLAN +------------------------------------------------------------------------------ + Foreign Scan on public.numbers (cost=10.00..163.62 rows=162 width=36) + Output: ((fields ->> 'a'::text))::integer, (fields ->> 'b'::text) + InfluxDB query: SELECT "a", "b" FROM "numbers" WHERE ("a" > 0 AND "a" > 1) +(3 rows) + +--Testcase 126: +SELECT (fields->>'a')::int a, fields->>'b' b FROM numbers WHERE (fields->>'a')::int > ALL(ARRAY[0, 1]); + a | b +---+----- + 2 | Two +(1 row) + +--Testcase 127: +EXPLAIN VERBOSE +SELECT (fields->>'a')::int a, fields->>'b' b FROM numbers WHERE (fields->>'a')::int < ALL(ARRAY[2, 3]); + QUERY PLAN +------------------------------------------------------------------------------ + Foreign Scan on public.numbers (cost=10.00..163.62 rows=162 width=36) + Output: ((fields ->> 'a'::text))::integer, (fields ->> 'b'::text) + InfluxDB query: SELECT "a", "b" FROM "numbers" WHERE ("a" < 2 AND "a" < 3) +(3 rows) + +--Testcase 128: +SELECT (fields->>'a')::int a, fields->>'b' b FROM numbers WHERE (fields->>'a')::int < ALL(ARRAY[2, 3]); + a | b +---+----- + 1 | One +(1 row) + +-- ANY/ALL with TEXT ARRAY const +--Testcase 129: +EXPLAIN VERBOSE +SELECT (fields->>'a')::int a, fields->>'b' b FROM numbers WHERE fields->>'b' = ANY(ARRAY['One', 'Two']); + QUERY PLAN +------------------------------------------------------------------------------------- + Foreign Scan on public.numbers (cost=10.00..15.15 rows=15 width=36) + Output: ((fields ->> 'a'::text))::integer, (fields ->> 'b'::text) + InfluxDB query: SELECT "a", "b" FROM "numbers" WHERE ("b" = 'One' OR "b" = 'Two') +(3 rows) + +--Testcase 130: +SELECT (fields->>'a')::int a, fields->>'b' b FROM numbers WHERE fields->>'b' = ANY(ARRAY['One', 'Two']); + a | b +---+----- + 1 | One + 2 | Two +(2 rows) + +--Testcase 131: +EXPLAIN VERBOSE +SELECT (fields->>'a')::int a, fields->>'b' b FROM numbers WHERE fields->>'b' <> ALL(ARRAY['One', 'Four']); + QUERY PLAN +----------------------------------------------------------------------------------------- + Foreign Scan on public.numbers (cost=10.00..1461.47 rows=1447 width=36) + Output: ((fields ->> 'a'::text))::integer, (fields ->> 'b'::text) + InfluxDB query: SELECT "a", "b" FROM "numbers" WHERE ("b" <> 'One' AND "b" <> 'Four') +(3 rows) + +--Testcase 132: +SELECT (fields->>'a')::int a, fields->>'b' b FROM numbers WHERE fields->>'b' <> ALL(ARRAY['One', 'Four']); + a | b +---+----- + 2 | Two +(1 row) + +--Testcase 133: +EXPLAIN VERBOSE +SELECT (fields->>'a')::int a, fields->>'b' b FROM numbers WHERE fields->>'b' > ANY(ARRAY['One', 'Two']); + QUERY PLAN +------------------------------------------------------------------------ + Foreign Scan on public.numbers (cost=10.00..820.12 rows=812 width=36) + Output: ((fields ->> 'a'::text))::integer, (fields ->> 'b'::text) + Filter: ((numbers.fields ->> 'b'::text) > ANY ('{One,Two}'::text[])) + InfluxDB query: SELECT "a", "b" FROM "numbers" +(4 rows) + +--Testcase 134: +SELECT (fields->>'a')::int a, fields->>'b' b FROM numbers WHERE fields->>'b' > ANY(ARRAY['One', 'Two']); + a | b +---+----- + 2 | Two +(1 row) + +--Testcase 135: +EXPLAIN VERBOSE +SELECT * FROM numbers WHERE fields->>'b' > ALL(ARRAY['Four', 'Five']); + QUERY PLAN +-------------------------------------------------------------------------- + Foreign Scan on public.numbers (cost=10.00..95.00 rows=95 width=72) + Output: "time", tags, fields + Filter: ((numbers.fields ->> 'b'::text) > ALL ('{Four,Five}'::text[])) + InfluxDB query: SELECT * FROM "numbers" +(4 rows) + +--Testcase 136: +SELECT (fields->>'a')::int a, fields->>'b' b FROM numbers WHERE fields->>'b' > ALL(ARRAY['Four', 'Five']); + a | b +---+----- + 1 | One + 2 | Two +(2 rows) + +--Testcase 137: +DROP FOREIGN TABLE numbers; +--Testcase 138: +ALTER SERVER server1 OPTIONS (SET dbname 'no such database'); +--Testcase 139: +SELECT * FROM t1; +ERROR: influxdb_fdw : database not found: no such database +--Testcase 140: +ALTER SERVER server1 OPTIONS (SET dbname 'mydb'); +--Testcase 141: +SELECT * FROM t1; + time | tags | fields +------------------------+--------------------+----------------------------------------------------------------------------------------- + 2015-08-18 09:00:00+09 | {"tag1": "tag1_A"} | {"tag2": "tag2_A", "value1": "100", "value2": "0.5", "value3": "str", "value4": "true"} + 2015-08-18 09:00:00+09 | {"tag1": "tag1_B"} | {"tag2": null, "value1": "100", "value2": "2", "value3": null, "value4": "false"} + 2015-08-18 09:48:08+09 | {"tag1": null} | {"tag2": "tag2_A", "value1": null, "value2": "2", "value3": null, "value4": null} +(3 rows) + +-- map time column to both timestamp and text +--Testcase 142: +CREATE FOREIGN TABLE t5(t timestamp OPTIONS (column_name 'time'), tag1 text OPTIONS (column_name 'time'), fields jsonb OPTIONS (fields 'true')) SERVER server1 OPTIONS (table 'cpu', schemaless 'true'); +--Testcase 143: +SELECT * FROM t5; + t | tag1 | fields +---------------------+----------------------+----------------------------------------------------------------------------------------------------------- + 2015-08-18 00:00:00 | 2015-08-18T00:00:00Z | {"tag1": "tag1_A", "tag2": "tag2_A", "value1": "100", "value2": "0.5", "value3": "str", "value4": "true"} + 2015-08-18 00:00:00 | 2015-08-18T00:00:00Z | {"tag1": "tag1_B", "tag2": null, "value1": "100", "value2": "2", "value3": null, "value4": "false"} + 2015-08-18 00:48:08 | 2015-08-18T00:48:08Z | {"tag1": null, "tag2": "tag2_A", "value1": null, "value2": "2", "value3": null, "value4": null} +(3 rows) + +--get version +--Testcase 144: +\df influxdb_fdw* + List of functions + Schema | Name | Result data type | Argument data types | Type +--------+------------------------+------------------+---------------------+------ + public | influxdb_fdw_handler | fdw_handler | | func + public | influxdb_fdw_validator | void | text[], oid | func + public | influxdb_fdw_version | integer | | func +(3 rows) + +--Testcase 145: +SELECT * FROM public.influxdb_fdw_version(); + influxdb_fdw_version +---------------------- + 20100 +(1 row) + +--Testcase 146: +SELECT influxdb_fdw_version(); + influxdb_fdw_version +---------------------- + 20100 +(1 row) + +--Test pushdown LIMIT...OFFSET +--Testcase 147: +EXPLAIN (VERBOSE, COSTS OFF) +SELECT tableoid::regclass, * FROM t1 LIMIT 1 OFFSET 0; + QUERY PLAN +-------------------------------------------------------- + Foreign Scan on public.t1 + Output: (tableoid)::regclass, "time", tags, fields + InfluxDB query: SELECT * FROM "cpu" LIMIT 1 OFFSET 0 +(3 rows) + +--Testcase 148: +SELECT tableoid::regclass, * FROM t1 LIMIT 1 OFFSET 0; + tableoid | time | tags | fields +----------+------------------------+--------------------+----------------------------------------------------------------------------------------- + t1 | 2015-08-18 09:00:00+09 | {"tag1": "tag1_A"} | {"tag2": "tag2_A", "value1": "100", "value2": "0.5", "value3": "str", "value4": "true"} +(1 row) + +--Testcase 149: +EXPLAIN (VERBOSE, COSTS OFF) +SELECT tableoid::regclass, * FROM t1 LIMIT 1 OFFSET 1; + QUERY PLAN +-------------------------------------------------------- + Foreign Scan on public.t1 + Output: (tableoid)::regclass, "time", tags, fields + InfluxDB query: SELECT * FROM "cpu" LIMIT 1 OFFSET 1 +(3 rows) + +--Testcase 150: +SELECT tableoid::regclass, * FROM t1 LIMIT 1 OFFSET 1; + tableoid | time | tags | fields +----------+------------------------+--------------------+----------------------------------------------------------------------------------- + t1 | 2015-08-18 09:00:00+09 | {"tag1": "tag1_B"} | {"tag2": null, "value1": "100", "value2": "2", "value3": null, "value4": "false"} +(1 row) + +--Testcase 151: +EXPLAIN (VERBOSE, COSTS OFF) +SELECT ctid, * FROM t1 LIMIT 1 OFFSET 0; + QUERY PLAN +-------------------------------------------------------- + Foreign Scan on public.t1 + Output: ctid, "time", tags, fields + InfluxDB query: SELECT * FROM "cpu" LIMIT 1 OFFSET 0 +(3 rows) + +--Testcase 152: +SELECT ctid, * FROM t1 LIMIT 1 OFFSET 0; + ctid | time | tags | fields +----------------+------------------------+--------------------+----------------------------------------------------------------------------------------- + (4294967295,0) | 2015-08-18 09:00:00+09 | {"tag1": "tag1_A"} | {"tag2": "tag2_A", "value1": "100", "value2": "0.5", "value3": "str", "value4": "true"} +(1 row) + +--Testcase 153: +EXPLAIN (VERBOSE, COSTS OFF) +SELECT ctid, * FROM t2 LIMIT 10 OFFSET 20; + QUERY PLAN +---------------------------------------------------------- + Foreign Scan on public.t2 + Output: ctid, "time", tags, fields + InfluxDB query: SELECT * FROM "cpu" LIMIT 10 OFFSET 20 +(3 rows) + +--Testcase 154: +SELECT ctid, * FROM t2 LIMIT 10 OFFSET 20; + ctid | time | tags | fields +------+------+------+-------- +(0 rows) + +--Testcase 155: +EXPLAIN (VERBOSE, COSTS OFF) +SELECT * FROM + t1 + LEFT JOIN t2 + ON (t2.fields->>'value1')::int = 123, + LATERAL (SELECT (t2.fields->>'value1')::int value1, t1.tags->>'tag1' tag1 FROM t1 LIMIT 1 OFFSET 0) AS ss +WHERE (t1.fields->>'value1')::int = ss.value1; + QUERY PLAN +----------------------------------------------------------------------------------------------------------------------------------------------------- + Nested Loop + Output: t1."time", t1.tags, t1.fields, t2."time", t2.tags, t2.fields, (((t2.fields ->> 'value1'::text))::integer), ((t1_1.tags ->> 'tag1'::text)) + Join Filter: (((t1.fields ->> 'value1'::text))::integer = (((t2.fields ->> 'value1'::text))::integer)) + -> Nested Loop Left Join + Output: t1."time", t1.tags, t1.fields, t2."time", t2.tags, t2.fields + -> Foreign Scan on public.t1 + Output: t1."time", t1.tags, t1.fields + InfluxDB query: SELECT * FROM "cpu" + -> Materialize + Output: t2."time", t2.tags, t2.fields + -> Foreign Scan on public.t2 + Output: t2."time", t2.tags, t2.fields + InfluxDB query: SELECT * FROM "cpu" WHERE (("value1" = 123)) + -> Foreign Scan on public.t1 t1_1 + Output: ((t2.fields ->> 'value1'::text))::integer, (t1_1.tags ->> 'tag1'::text) + InfluxDB query: SELECT * FROM "cpu" LIMIT 1 OFFSET 0 +(16 rows) + +--Testcase 156: +EXPLAIN (VERBOSE, COSTS OFF) +SELECT * FROM + t1 + LEFT JOIN t2 + ON (t2.fields->>'value1')::int = 123, + LATERAL (SELECT (t2.fields->>'value1')::int value1, t1.tags->>'tag1' tag1 FROM t1 LIMIT 1 OFFSET 0) AS ss1, + LATERAL (SELECT ss1.* from t3 LIMIT 1 OFFSET 20) AS ss2 +WHERE (t1.fields->>'value1')::int = ss2.value1; + QUERY PLAN +-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- + Nested Loop + Output: t1."time", t1.tags, t1.fields, t2."time", t2.tags, t2.fields, (((t2.fields ->> 'value1'::text))::integer), ((t1_1.tags ->> 'tag1'::text)), ((((t2.fields ->> 'value1'::text))::integer)), (((t1_1.tags ->> 'tag1'::text))) + Join Filter: (((t1.fields ->> 'value1'::text))::integer = ((((t2.fields ->> 'value1'::text))::integer))) + -> Nested Loop + Output: t1."time", t1.tags, t1.fields, t2."time", t2.tags, t2.fields, (((t2.fields ->> 'value1'::text))::integer), ((t1_1.tags ->> 'tag1'::text)) + -> Nested Loop Left Join + Output: t1."time", t1.tags, t1.fields, t2."time", t2.tags, t2.fields + -> Foreign Scan on public.t1 + Output: t1."time", t1.tags, t1.fields + InfluxDB query: SELECT * FROM "cpu" + -> Materialize + Output: t2."time", t2.tags, t2.fields + -> Foreign Scan on public.t2 + Output: t2."time", t2.tags, t2.fields + InfluxDB query: SELECT * FROM "cpu" WHERE (("value1" = 123)) + -> Foreign Scan on public.t1 t1_1 + Output: ((t2.fields ->> 'value1'::text))::integer, (t1_1.tags ->> 'tag1'::text) + InfluxDB query: SELECT * FROM "cpu" LIMIT 1 OFFSET 0 + -> Foreign Scan on public.t3 + Output: (((t2.fields ->> 'value1'::text))::integer), ((t1_1.tags ->> 'tag1'::text)) + InfluxDB query: SELECT * FROM "t3" LIMIT 1 OFFSET 20 +(21 rows) + +--Testcase 157: +DROP FOREIGN TABLE cpu; +--Testcase 158: +DROP FOREIGN TABLE t1; +--Testcase 159: +DROP FOREIGN TABLE t2; +--Testcase 160: +DROP FOREIGN TABLE t3; +--Testcase 161: +DROP FOREIGN TABLE t4; +--Testcase 162: +DROP FOREIGN TABLE t5; +--Testcase 163: +DROP FOREIGN TABLE tx; +-- test INSERT, DELETE +IMPORT FOREIGN SCHEMA public FROM SERVER server1 INTO public OPTIONS(import_time_text 'true', schemaless 'true'); +--Testcase 204: +CREATE FOREIGN TABLE cpu_nsc (time timestamp with time zone, time_text text, tag1 text, tag2 text, value1 int, value2 float, value3 text, value4 boolean) SERVER server1 OPTIONS (table 'cpu', tags 'tag1, tag2'); +--Testcase 164: +SELECT * FROM cpu; + time | time_text | tags | fields +------------------------+----------------------+--------------------------------------+----------------------------------------------------------------------- + 2015-08-18 09:00:00+09 | 2015-08-18T00:00:00Z | {"tag1": "tag1_A", "tag2": "tag2_A"} | {"value1": "100", "value2": "0.5", "value3": "str", "value4": "true"} + 2015-08-18 09:00:00+09 | 2015-08-18T00:00:00Z | {"tag1": "tag1_B", "tag2": null} | {"value1": "100", "value2": "2", "value3": null, "value4": "false"} + 2015-08-18 09:48:08+09 | 2015-08-18T00:48:08Z | {"tag1": null, "tag2": "tag2_A"} | {"value1": null, "value2": "2", "value3": null, "value4": null} +(3 rows) + +--Testcase 165: +EXPLAIN VERBOSE +INSERT INTO cpu_nsc(time, tag1, tag2, value1, value2, value3, value4) VALUES('2021-01-01 00:00:01+09', 'tag1_K', 'tag2_H', 200, 5.5, 'test1', true); + QUERY PLAN +------------------------------------------------------------------------------------------------------------------------------------------------------------------- + Insert on public.cpu_nsc (cost=0.00..0.01 rows=0 width=0) + Batch Size: 1 + -> Result (cost=0.00..0.01 rows=1 width=149) + Output: '2021-01-01 00:00:01+09'::timestamp with time zone, NULL::text, 'tag1_K'::text, 'tag2_H'::text, 200, '5.5'::double precision, 'test1'::text, true +(4 rows) + +--Testcase 166: +INSERT INTO cpu_nsc(time, tag1, tag2, value1, value2, value3, value4) VALUES('2021-01-01 00:00:01+09', 'tag1_K', 'tag2_H', 200, 5.5, 'test', true); +--Testcase 167: +SELECT * FROM cpu; + time | time_text | tags | fields +------------------------+----------------------+--------------------------------------+------------------------------------------------------------------------ + 2015-08-18 09:00:00+09 | 2015-08-18T00:00:00Z | {"tag1": "tag1_A", "tag2": "tag2_A"} | {"value1": "100", "value2": "0.5", "value3": "str", "value4": "true"} + 2015-08-18 09:00:00+09 | 2015-08-18T00:00:00Z | {"tag1": "tag1_B", "tag2": null} | {"value1": "100", "value2": "2", "value3": null, "value4": "false"} + 2015-08-18 09:48:08+09 | 2015-08-18T00:48:08Z | {"tag1": null, "tag2": "tag2_A"} | {"value1": null, "value2": "2", "value3": null, "value4": null} + 2021-01-01 00:00:01+09 | 2020-12-31T15:00:01Z | {"tag1": "tag1_K", "tag2": "tag2_H"} | {"value1": "200", "value2": "5.5", "value3": "test", "value4": "true"} +(4 rows) + +--Testcase 168: +EXPLAIN VERBOSE +INSERT INTO cpu_nsc(time, tag1, tag2, value1, value2, value3, value4) VALUES('2021-01-02 00:00:02+05', 'tag1_I', 'tag2_E', 300, 15.5, 'test2', false), + ('2029-02-02 00:02:02+04', 'tag1_U', 'tag2_DZ', (SELECT 350), (SELECT i FROM (VALUES(6.9)) AS foo (i)), 'funny', true); + QUERY PLAN +------------------------------------------------------------------------------------------------------------------------------------------------------------------------ + Insert on public.cpu_nsc (cost=0.02..0.04 rows=0 width=0) + Batch Size: 1 + InitPlan 1 (returns $0) + -> Result (cost=0.00..0.01 rows=1 width=4) + Output: 350 + InitPlan 2 (returns $1) + -> Result (cost=0.00..0.01 rows=1 width=32) + Output: 6.9 + -> Values Scan on "*VALUES*" (cost=0.00..0.03 rows=2 width=149) + Output: "*VALUES*".column1, NULL::text, "*VALUES*".column2, "*VALUES*".column3, "*VALUES*".column4, "*VALUES*".column5, "*VALUES*".column6, "*VALUES*".column7 +(10 rows) + +--Testcase 169: +INSERT INTO cpu_nsc(time, tag1, tag2, value1, value2, value3, value4) VALUES('2021-01-02 00:00:02+05', 'tag1_I', 'tag2_E', 300, 15.5, 'test2', false), + ('2029-02-02 00:02:02+04', 'tag1_U', 'tag2_DZ', (SELECT 350), (SELECT i FROM (VALUES(6.9)) AS foo (i)), 'funny', true); +--Testcase 170: +SELECT * FROM cpu; + time | time_text | tags | fields +------------------------+----------------------+---------------------------------------+--------------------------------------------------------------------------- + 2015-08-18 09:00:00+09 | 2015-08-18T00:00:00Z | {"tag1": "tag1_A", "tag2": "tag2_A"} | {"value1": "100", "value2": "0.5", "value3": "str", "value4": "true"} + 2015-08-18 09:00:00+09 | 2015-08-18T00:00:00Z | {"tag1": "tag1_B", "tag2": null} | {"value1": "100", "value2": "2", "value3": null, "value4": "false"} + 2015-08-18 09:48:08+09 | 2015-08-18T00:48:08Z | {"tag1": null, "tag2": "tag2_A"} | {"value1": null, "value2": "2", "value3": null, "value4": null} + 2021-01-01 00:00:01+09 | 2020-12-31T15:00:01Z | {"tag1": "tag1_K", "tag2": "tag2_H"} | {"value1": "200", "value2": "5.5", "value3": "test", "value4": "true"} + 2021-01-02 04:00:02+09 | 2021-01-01T19:00:02Z | {"tag1": "tag1_I", "tag2": "tag2_E"} | {"value1": "300", "value2": "15.5", "value3": "test2", "value4": "false"} + 2029-02-02 05:02:02+09 | 2029-02-01T20:02:02Z | {"tag1": "tag1_U", "tag2": "tag2_DZ"} | {"value1": "350", "value2": "6.9", "value3": "funny", "value4": "true"} +(6 rows) + +--Testcase 171: +INSERT INTO cpu_nsc(tag2, value1) VALUES('tag2_KH', 400); +--Testcase 172: +SELECT tags->>'tag1' tag1, tags->>'tag2' tag2, (fields->>'value1')::bigint value1, (fields->>'value2')::double precision value2, fields->>'value3' value3, (fields->>'value4')::boolean value4 FROM cpu; + tag1 | tag2 | value1 | value2 | value3 | value4 +--------+---------+--------+--------+--------+-------- + tag1_A | tag2_A | 100 | 0.5 | str | t + tag1_B | | 100 | 2 | | f + | tag2_A | | 2 | | + tag1_K | tag2_H | 200 | 5.5 | test | t + tag1_I | tag2_E | 300 | 15.5 | test2 | f + | tag2_KH | 400 | | | + tag1_U | tag2_DZ | 350 | 6.9 | funny | t +(7 rows) + +--Testcase 173: +EXPLAIN VERBOSE +DELETE FROM cpu_nsc WHERE tag2 = 'tag2_KH'; + QUERY PLAN +----------------------------------------------------------------------------- + Delete on public.cpu_nsc (cost=10.00..3.00 rows=0 width=0) + -> Foreign Delete on public.cpu_nsc (cost=10.00..3.00 rows=3 width=104) + InfluxDB query: DELETE FROM "cpu" WHERE (("tag2" = 'tag2_KH')) +(3 rows) + +--Testcase 174: +DELETE FROM cpu_nsc WHERE tag2 = 'tag2_KH'; +--Testcase 175: +SELECT tags->>'tag1' tag1, tags->>'tag2' tag2, (fields->>'value1')::bigint value1, (fields->>'value2')::double precision value2, fields->>'value3' value3, (fields->>'value4')::boolean value4 FROM cpu; + tag1 | tag2 | value1 | value2 | value3 | value4 +--------+---------+--------+--------+--------+-------- + tag1_A | tag2_A | 100 | 0.5 | str | t + tag1_B | | 100 | 2 | | f + | tag2_A | | 2 | | + tag1_K | tag2_H | 200 | 5.5 | test | t + tag1_I | tag2_E | 300 | 15.5 | test2 | f + tag1_U | tag2_DZ | 350 | 6.9 | funny | t +(6 rows) + +--Testcase 176: +EXPLAIN VERBOSE +DELETE FROM cpu WHERE time = '2021-01-02 04:00:02+09'; + QUERY PLAN +---------------------------------------------------------------------------------- + Delete on public.cpu (cost=10.00..6.00 rows=0 width=0) + -> Foreign Delete on public.cpu (cost=10.00..6.00 rows=6 width=40) + InfluxDB query: DELETE FROM "cpu" WHERE ((time = '2021-01-01 19:00:02')) +(3 rows) + +--Testcase 177: +DELETE FROM cpu WHERE time = '2021-01-02 04:00:02+09'; +--Testcase 178: +SELECT * FROM cpu; + time | time_text | tags | fields +------------------------+----------------------+---------------------------------------+------------------------------------------------------------------------- + 2015-08-18 09:00:00+09 | 2015-08-18T00:00:00Z | {"tag1": "tag1_A", "tag2": "tag2_A"} | {"value1": "100", "value2": "0.5", "value3": "str", "value4": "true"} + 2015-08-18 09:00:00+09 | 2015-08-18T00:00:00Z | {"tag1": "tag1_B", "tag2": null} | {"value1": "100", "value2": "2", "value3": null, "value4": "false"} + 2015-08-18 09:48:08+09 | 2015-08-18T00:48:08Z | {"tag1": null, "tag2": "tag2_A"} | {"value1": null, "value2": "2", "value3": null, "value4": null} + 2021-01-01 00:00:01+09 | 2020-12-31T15:00:01Z | {"tag1": "tag1_K", "tag2": "tag2_H"} | {"value1": "200", "value2": "5.5", "value3": "test", "value4": "true"} + 2029-02-02 05:02:02+09 | 2029-02-01T20:02:02Z | {"tag1": "tag1_U", "tag2": "tag2_DZ"} | {"value1": "350", "value2": "6.9", "value3": "funny", "value4": "true"} +(5 rows) + +--Testcase 179: +EXPLAIN VERBOSE +DELETE FROM cpu_nsc WHERE time < '2018-07-07' AND tag1 != 'tag1_B'; + QUERY PLAN +------------------------------------------------------------------------------------------------------------- + Delete on public.cpu_nsc (cost=10.00..212.00 rows=0 width=0) + -> Foreign Delete on public.cpu_nsc (cost=10.00..212.00 rows=212 width=104) + InfluxDB query: DELETE FROM "cpu" WHERE ((time < '2018-07-06 15:00:00')) AND (("tag1" <> 'tag1_B')) +(3 rows) + +--Testcase 180: +DELETE FROM cpu_nsc WHERE time < '2018-07-07' AND tag1 != 'tag1_B'; +--Testcase 181: +SELECT * FROM cpu; + time | time_text | tags | fields +------------------------+----------------------+---------------------------------------+------------------------------------------------------------------------- + 2015-08-18 09:00:00+09 | 2015-08-18T00:00:00Z | {"tag1": "tag1_B", "tag2": null} | {"value1": "100", "value2": "2", "value3": null, "value4": "false"} + 2021-01-01 00:00:01+09 | 2020-12-31T15:00:01Z | {"tag1": "tag1_K", "tag2": "tag2_H"} | {"value1": "200", "value2": "5.5", "value3": "test", "value4": "true"} + 2029-02-02 05:02:02+09 | 2029-02-01T20:02:02Z | {"tag1": "tag1_U", "tag2": "tag2_DZ"} | {"value1": "350", "value2": "6.9", "value3": "funny", "value4": "true"} +(3 rows) + +-- Test INSERT, DELETE with time_text column +--Testcase 182: +INSERT INTO cpu_nsc(time_text, tag1, tag2, value1, value2, value3, value4) VALUES('2021-02-02T00:00:00Z', 'tag1_D', 'tag2_E', 600, 20.2, 'test3', true); +--Testcase 183: +SELECT * FROM cpu; + time | time_text | tags | fields +------------------------+----------------------+---------------------------------------+-------------------------------------------------------------------------- + 2015-08-18 09:00:00+09 | 2015-08-18T00:00:00Z | {"tag1": "tag1_B", "tag2": null} | {"value1": "100", "value2": "2", "value3": null, "value4": "false"} + 2021-01-01 00:00:01+09 | 2020-12-31T15:00:01Z | {"tag1": "tag1_K", "tag2": "tag2_H"} | {"value1": "200", "value2": "5.5", "value3": "test", "value4": "true"} + 2021-02-02 09:00:00+09 | 2021-02-02T00:00:00Z | {"tag1": "tag1_D", "tag2": "tag2_E"} | {"value1": "600", "value2": "20.2", "value3": "test3", "value4": "true"} + 2029-02-02 05:02:02+09 | 2029-02-01T20:02:02Z | {"tag1": "tag1_U", "tag2": "tag2_DZ"} | {"value1": "350", "value2": "6.9", "value3": "funny", "value4": "true"} +(4 rows) + +--Testcase 184: +INSERT INTO cpu_nsc(time_text, tag1, value2) VALUES('2021-02-02T00:00:00.123456789Z', 'tag1_P', 25.8); +--Testcase 185: +SELECT * FROM cpu; + time | time_text | tags | fields +-------------------------------+--------------------------------+---------------------------------------+-------------------------------------------------------------------------- + 2015-08-18 09:00:00+09 | 2015-08-18T00:00:00Z | {"tag1": "tag1_B", "tag2": null} | {"value1": "100", "value2": "2", "value3": null, "value4": "false"} + 2021-01-01 00:00:01+09 | 2020-12-31T15:00:01Z | {"tag1": "tag1_K", "tag2": "tag2_H"} | {"value1": "200", "value2": "5.5", "value3": "test", "value4": "true"} + 2021-02-02 09:00:00+09 | 2021-02-02T00:00:00Z | {"tag1": "tag1_D", "tag2": "tag2_E"} | {"value1": "600", "value2": "20.2", "value3": "test3", "value4": "true"} + 2021-02-02 09:00:00.123457+09 | 2021-02-02T00:00:00.123456789Z | {"tag1": "tag1_P", "tag2": null} | {"value1": null, "value2": "25.8", "value3": null, "value4": null} + 2029-02-02 05:02:02+09 | 2029-02-01T20:02:02Z | {"tag1": "tag1_U", "tag2": "tag2_DZ"} | {"value1": "350", "value2": "6.9", "value3": "funny", "value4": "true"} +(5 rows) + +--Testcase 186: +INSERT INTO cpu_nsc(time_text, tag1, value2) VALUES('2021-02-02 00:00:01', 'tag1_J', 37.1); +--Testcase 187: +SELECT * FROM cpu; + time | time_text | tags | fields +-------------------------------+--------------------------------+---------------------------------------+-------------------------------------------------------------------------- + 2015-08-18 09:00:00+09 | 2015-08-18T00:00:00Z | {"tag1": "tag1_B", "tag2": null} | {"value1": "100", "value2": "2", "value3": null, "value4": "false"} + 2021-01-01 00:00:01+09 | 2020-12-31T15:00:01Z | {"tag1": "tag1_K", "tag2": "tag2_H"} | {"value1": "200", "value2": "5.5", "value3": "test", "value4": "true"} + 2021-02-02 09:00:00+09 | 2021-02-02T00:00:00Z | {"tag1": "tag1_D", "tag2": "tag2_E"} | {"value1": "600", "value2": "20.2", "value3": "test3", "value4": "true"} + 2021-02-02 09:00:00.123457+09 | 2021-02-02T00:00:00.123456789Z | {"tag1": "tag1_P", "tag2": null} | {"value1": null, "value2": "25.8", "value3": null, "value4": null} + 2021-02-02 09:00:01+09 | 2021-02-02T00:00:01Z | {"tag1": "tag1_J", "tag2": null} | {"value1": null, "value2": "37.1", "value3": null, "value4": null} + 2029-02-02 05:02:02+09 | 2029-02-01T20:02:02Z | {"tag1": "tag1_U", "tag2": "tag2_DZ"} | {"value1": "350", "value2": "6.9", "value3": "funny", "value4": "true"} +(6 rows) + +--Testcase 188: +INSERT INTO cpu_nsc(time, time_text, tag1, tag2, value1, value2, value3, value4) VALUES('2021-02-02 00:00:01+05', '2021-02-02T00:00:02.123456789Z', 'tag1_A', 'tag2_B', 200, 5.5, 'test', true); +WARNING: Inserting value has both 'time_text' and 'time' columns specified. The 'time' will be ignored. +--Testcase 189: +SELECT * FROM cpu; + time | time_text | tags | fields +-------------------------------+--------------------------------+---------------------------------------+-------------------------------------------------------------------------- + 2015-08-18 09:00:00+09 | 2015-08-18T00:00:00Z | {"tag1": "tag1_B", "tag2": null} | {"value1": "100", "value2": "2", "value3": null, "value4": "false"} + 2021-01-01 00:00:01+09 | 2020-12-31T15:00:01Z | {"tag1": "tag1_K", "tag2": "tag2_H"} | {"value1": "200", "value2": "5.5", "value3": "test", "value4": "true"} + 2021-02-02 09:00:00+09 | 2021-02-02T00:00:00Z | {"tag1": "tag1_D", "tag2": "tag2_E"} | {"value1": "600", "value2": "20.2", "value3": "test3", "value4": "true"} + 2021-02-02 09:00:00.123457+09 | 2021-02-02T00:00:00.123456789Z | {"tag1": "tag1_P", "tag2": null} | {"value1": null, "value2": "25.8", "value3": null, "value4": null} + 2021-02-02 09:00:01+09 | 2021-02-02T00:00:01Z | {"tag1": "tag1_J", "tag2": null} | {"value1": null, "value2": "37.1", "value3": null, "value4": null} + 2021-02-02 09:00:02.123457+09 | 2021-02-02T00:00:02.123456789Z | {"tag1": "tag1_A", "tag2": "tag2_B"} | {"value1": "200", "value2": "5.5", "value3": "test", "value4": "true"} + 2029-02-02 05:02:02+09 | 2029-02-01T20:02:02Z | {"tag1": "tag1_U", "tag2": "tag2_DZ"} | {"value1": "350", "value2": "6.9", "value3": "funny", "value4": "true"} +(7 rows) + +--Testcase 190: +INSERT INTO cpu_nsc(time_text, time, tag1, tag2, value1, value2, value3, value4) VALUES('2021-02-03T00:00:03.123456789Z', '2021-03-03 00:00:01+07', 'tag1_C', 'tag2_D', 200, 5.5, 'test', true); +WARNING: Inserting value has both 'time_text' and 'time' columns specified. The 'time' will be ignored. +--Testcase 191: +SELECT * FROM cpu; + time | time_text | tags | fields +-------------------------------+--------------------------------+---------------------------------------+-------------------------------------------------------------------------- + 2015-08-18 09:00:00+09 | 2015-08-18T00:00:00Z | {"tag1": "tag1_B", "tag2": null} | {"value1": "100", "value2": "2", "value3": null, "value4": "false"} + 2021-01-01 00:00:01+09 | 2020-12-31T15:00:01Z | {"tag1": "tag1_K", "tag2": "tag2_H"} | {"value1": "200", "value2": "5.5", "value3": "test", "value4": "true"} + 2021-02-02 09:00:00+09 | 2021-02-02T00:00:00Z | {"tag1": "tag1_D", "tag2": "tag2_E"} | {"value1": "600", "value2": "20.2", "value3": "test3", "value4": "true"} + 2021-02-02 09:00:00.123457+09 | 2021-02-02T00:00:00.123456789Z | {"tag1": "tag1_P", "tag2": null} | {"value1": null, "value2": "25.8", "value3": null, "value4": null} + 2021-02-02 09:00:01+09 | 2021-02-02T00:00:01Z | {"tag1": "tag1_J", "tag2": null} | {"value1": null, "value2": "37.1", "value3": null, "value4": null} + 2021-02-02 09:00:02.123457+09 | 2021-02-02T00:00:02.123456789Z | {"tag1": "tag1_A", "tag2": "tag2_B"} | {"value1": "200", "value2": "5.5", "value3": "test", "value4": "true"} + 2021-02-03 09:00:03.123457+09 | 2021-02-03T00:00:03.123456789Z | {"tag1": "tag1_C", "tag2": "tag2_D"} | {"value1": "200", "value2": "5.5", "value3": "test", "value4": "true"} + 2029-02-02 05:02:02+09 | 2029-02-01T20:02:02Z | {"tag1": "tag1_U", "tag2": "tag2_DZ"} | {"value1": "350", "value2": "6.9", "value3": "funny", "value4": "true"} +(8 rows) + +--Testcase 192: +EXPLAIN VERBOSE +DELETE FROM cpu_nsc WHERE time_text = '2021-02-02T00:00:00.123456789Z'; + QUERY PLAN +--------------------------------------------------------------------------------------------- + Delete on public.cpu_nsc (cost=10.00..3.00 rows=0 width=0) + -> Foreign Delete on public.cpu_nsc (cost=10.00..3.00 rows=3 width=104) + InfluxDB query: DELETE FROM "cpu" WHERE ((time = '2021-02-02T00:00:00.123456789Z')) +(3 rows) + +--Testcase 193: +DELETE FROM cpu_nsc WHERE time_text = '2021-02-02T00:00:00.123456789Z'; +--Testcase 194: +SELECT * FROM cpu; + time | time_text | tags | fields +-------------------------------+--------------------------------+---------------------------------------+-------------------------------------------------------------------------- + 2015-08-18 09:00:00+09 | 2015-08-18T00:00:00Z | {"tag1": "tag1_B", "tag2": null} | {"value1": "100", "value2": "2", "value3": null, "value4": "false"} + 2021-01-01 00:00:01+09 | 2020-12-31T15:00:01Z | {"tag1": "tag1_K", "tag2": "tag2_H"} | {"value1": "200", "value2": "5.5", "value3": "test", "value4": "true"} + 2021-02-02 09:00:00+09 | 2021-02-02T00:00:00Z | {"tag1": "tag1_D", "tag2": "tag2_E"} | {"value1": "600", "value2": "20.2", "value3": "test3", "value4": "true"} + 2021-02-02 09:00:01+09 | 2021-02-02T00:00:01Z | {"tag1": "tag1_J", "tag2": null} | {"value1": null, "value2": "37.1", "value3": null, "value4": null} + 2021-02-02 09:00:02.123457+09 | 2021-02-02T00:00:02.123456789Z | {"tag1": "tag1_A", "tag2": "tag2_B"} | {"value1": "200", "value2": "5.5", "value3": "test", "value4": "true"} + 2021-02-03 09:00:03.123457+09 | 2021-02-03T00:00:03.123456789Z | {"tag1": "tag1_C", "tag2": "tag2_D"} | {"value1": "200", "value2": "5.5", "value3": "test", "value4": "true"} + 2029-02-02 05:02:02+09 | 2029-02-01T20:02:02Z | {"tag1": "tag1_U", "tag2": "tag2_DZ"} | {"value1": "350", "value2": "6.9", "value3": "funny", "value4": "true"} +(7 rows) + +--Testcase 195: +EXPLAIN VERBOSE +DELETE FROM cpu_nsc WHERE time_text = '2021-02-02T00:00:01Z' AND tag1 = 'tag1_J'; + QUERY PLAN +------------------------------------------------------------------------------------------------------------- + Delete on public.cpu_nsc (cost=10.00..1.00 rows=0 width=0) + -> Foreign Delete on public.cpu_nsc (cost=10.00..1.00 rows=1 width=104) + InfluxDB query: DELETE FROM "cpu" WHERE ((time = '2021-02-02T00:00:01Z')) AND (("tag1" = 'tag1_J')) +(3 rows) + +--Testcase 196: +DELETE FROM cpu_nsc WHERE time_text = '2021-02-02T00:00:01Z' AND tag1 = 'tag1_J'; +--Testcase 197: +SELECT * FROM cpu; + time | time_text | tags | fields +-------------------------------+--------------------------------+---------------------------------------+-------------------------------------------------------------------------- + 2015-08-18 09:00:00+09 | 2015-08-18T00:00:00Z | {"tag1": "tag1_B", "tag2": null} | {"value1": "100", "value2": "2", "value3": null, "value4": "false"} + 2021-01-01 00:00:01+09 | 2020-12-31T15:00:01Z | {"tag1": "tag1_K", "tag2": "tag2_H"} | {"value1": "200", "value2": "5.5", "value3": "test", "value4": "true"} + 2021-02-02 09:00:00+09 | 2021-02-02T00:00:00Z | {"tag1": "tag1_D", "tag2": "tag2_E"} | {"value1": "600", "value2": "20.2", "value3": "test3", "value4": "true"} + 2021-02-02 09:00:02.123457+09 | 2021-02-02T00:00:02.123456789Z | {"tag1": "tag1_A", "tag2": "tag2_B"} | {"value1": "200", "value2": "5.5", "value3": "test", "value4": "true"} + 2021-02-03 09:00:03.123457+09 | 2021-02-03T00:00:03.123456789Z | {"tag1": "tag1_C", "tag2": "tag2_D"} | {"value1": "200", "value2": "5.5", "value3": "test", "value4": "true"} + 2029-02-02 05:02:02+09 | 2029-02-01T20:02:02Z | {"tag1": "tag1_U", "tag2": "tag2_DZ"} | {"value1": "350", "value2": "6.9", "value3": "funny", "value4": "true"} +(6 rows) + +--Testcase 198: +EXPLAIN VERBOSE +DELETE FROM cpu_nsc WHERE time_text = '2021-02-02 00:00:00' OR time ='2029-02-02 05:02:02+09'; + QUERY PLAN +---------------------------------------------------------------------------------------------------------------------------------------------- + Delete on public.cpu_nsc (cost=10.00..6.00 rows=0 width=0) + -> Foreign Scan on public.cpu_nsc (cost=10.00..6.00 rows=6 width=104) + Output: "time", time_text, tag1, tag2 + Filter: ((cpu_nsc.time_text = '2021-02-02 00:00:00'::text) OR (cpu_nsc."time" = '2029-02-02 05:02:02+09'::timestamp with time zone)) + InfluxDB query: SELECT "tag1", "tag2", "value1" FROM "cpu" +(5 rows) + +--Testcase 199: +DELETE FROM cpu_nsc WHERE time_text = '2021-02-02 00:00:00' OR time ='2029-02-02 05:02:02+09'; +--Testcase 200: +SELECT * FROM cpu; + time | time_text | tags | fields +-------------------------------+--------------------------------+--------------------------------------+-------------------------------------------------------------------------- + 2015-08-18 09:00:00+09 | 2015-08-18T00:00:00Z | {"tag1": "tag1_B", "tag2": null} | {"value1": "100", "value2": "2", "value3": null, "value4": "false"} + 2021-01-01 00:00:01+09 | 2020-12-31T15:00:01Z | {"tag1": "tag1_K", "tag2": "tag2_H"} | {"value1": "200", "value2": "5.5", "value3": "test", "value4": "true"} + 2021-02-02 09:00:00+09 | 2021-02-02T00:00:00Z | {"tag1": "tag1_D", "tag2": "tag2_E"} | {"value1": "600", "value2": "20.2", "value3": "test3", "value4": "true"} + 2021-02-02 09:00:02.123457+09 | 2021-02-02T00:00:02.123456789Z | {"tag1": "tag1_A", "tag2": "tag2_B"} | {"value1": "200", "value2": "5.5", "value3": "test", "value4": "true"} + 2021-02-03 09:00:03.123457+09 | 2021-02-03T00:00:03.123456789Z | {"tag1": "tag1_C", "tag2": "tag2_D"} | {"value1": "200", "value2": "5.5", "value3": "test", "value4": "true"} +(5 rows) + +-- Recover data +:RECOVER_INIT_TXT_DROP_BUCKET; +:RECOVER_INIT_TXT_CREATE_BUCKET; +:RECOVER_INIT_TXT; +--Testcase 201: +DROP FOREIGN TABLE cpu_nsc; +--Testcase 205: +DROP USER MAPPING FOR CURRENT_USER SERVER server1; +--Testcase 202: +DROP SERVER server1 CASCADE; +NOTICE: drop cascades to 5 other objects +DETAIL: drop cascades to foreign table cpu +drop cascades to foreign table numbers +drop cascades to foreign table t3 +drop cascades to foreign table t4 +drop cascades to foreign table tx +--Testcase 203: +DROP EXTENSION influxdb_fdw; diff --git a/expected/11.17/schemaless/schemaless.out b/expected/16.0/schemaless/schemaless.out similarity index 99% rename from expected/11.17/schemaless/schemaless.out rename to expected/16.0/schemaless/schemaless.out index 88cd4f7..4a3e213 100644 --- a/expected/11.17/schemaless/schemaless.out +++ b/expected/16.0/schemaless/schemaless.out @@ -725,17 +725,17 @@ SELECT sqrt((fields->>'sig1')::bigint) FROM sc1; --Testcase 72: SELECT sqrt((fields->>'sig1')::bigint) FROM sc1; - sqrt ------------------- - 1 - 1.73205080756888 - 1.4142135623731 - 2.44948974278318 - 2.23606797749979 - 2 - 2.82842712474619 - 2.64575131106459 - 3 + sqrt +-------------------- + 1 + 1.7320508075688772 + 1.4142135623730951 + 2.449489742783178 + 2.23606797749979 + 2 + 2.8284271247461903 + 2.6457513110645907 + 3 (9 rows) -- sparse data - baserel field only @@ -801,7 +801,7 @@ EXPLAIN VERBOSE SELECT avg((fields->>'sig1')::bigint), sum((fields->>'sig1')::bigint) FROM sc1; QUERY PLAN ---------------------------------------------------------------------------------------------- - Aggregate (cost=1491.25..1491.26 rows=1 width=64) + Aggregate (cost=1476.62..1476.63 rows=1 width=64) Output: avg(((fields ->> 'sig1'::text))::bigint), sum(((fields ->> 'sig1'::text))::bigint) -> Foreign Scan on public.sc1 (cost=10.00..1462.00 rows=1462 width=32) Output: "time", tags, fields diff --git a/expected/11.17/schemaless/selectfunc.out b/expected/16.0/schemaless/selectfunc.out similarity index 94% rename from expected/11.17/schemaless/selectfunc.out rename to expected/16.0/schemaless/selectfunc.out index 68d0dcc..f8ca280 100644 --- a/expected/11.17/schemaless/selectfunc.out +++ b/expected/16.0/schemaless/selectfunc.out @@ -75,14 +75,14 @@ SELECT sqrt((fields->>'value1')::float), sqrt((fields->>'value2')::bigint) FROM -- select sqrt (builtin function, result) --Testcase 12: SELECT sqrt((fields->>'value1')::float), sqrt((fields->>'value2')::bigint) FROM s3; - sqrt | sqrt --------------------+----------------- - 0.316227766016838 | 10 - 0.447213595499958 | 10 - 0.547722557505166 | 10 - 1.04880884817015 | 14.142135623731 - 1.48323969741913 | 14.142135623731 - 1.81659021245849 | 14.142135623731 + sqrt | sqrt +---------------------+-------------------- + 0.31622776601683794 | 10 + 0.4472135954999579 | 10 + 0.5477225575051661 | 10 + 1.0488088481701516 | 14.142135623730951 + 1.4832396974191326 | 14.142135623730951 + 1.816590212458495 | 14.142135623730951 (6 rows) -- select sqrt (builtin function, not pushdown constraints, explain) @@ -100,11 +100,11 @@ SELECT sqrt((fields->>'value1')::float), sqrt((fields->>'value2')::bigint) FROM -- select sqrt (builtin function, not pushdown constraints, result) --Testcase 14: SELECT sqrt((fields->>'value1')::float), sqrt((fields->>'value2')::bigint) FROM s3 WHERE to_hex((fields->>'value2')::bigint) != '64'; - sqrt | sqrt -------------------+----------------- - 1.04880884817015 | 14.142135623731 - 1.48323969741913 | 14.142135623731 - 1.81659021245849 | 14.142135623731 + sqrt | sqrt +--------------------+-------------------- + 1.0488088481701516 | 14.142135623730951 + 1.4832396974191326 | 14.142135623730951 + 1.816590212458495 | 14.142135623730951 (3 rows) -- select sqrt (builtin function, pushdown constraints, explain) @@ -121,11 +121,11 @@ SELECT sqrt((fields->>'value1')::float), sqrt((fields->>'value2')::bigint) FROM -- select sqrt (builtin function, pushdown constraints, result) --Testcase 16: SELECT sqrt((fields->>'value1')::float), sqrt((fields->>'value2')::bigint) FROM s3 WHERE (fields->>'value2')::bigint != 200; - sqrt | sqrt --------------------+------ - 0.316227766016838 | 10 - 0.447213595499958 | 10 - 0.547722557505166 | 10 + sqrt | sqrt +---------------------+------ + 0.31622776601683794 | 10 + 0.4472135954999579 | 10 + 0.5477225575051661 | 10 (3 rows) -- select sqrt(*) (stub agg function, explain) @@ -453,7 +453,7 @@ EXPLAIN VERBOSE SELECT log10((fields->>'value1')::float),log10((fields->>'value2')::bigint) FROM s3; QUERY PLAN ------------------------------------------------------------------------------------------------------------------------------------ - Foreign Scan on public.s3 (cost=10.00..2218.59 rows=1462 width=16) + Foreign Scan on public.s3 (cost=10.00..1494.89 rows=1462 width=16) Output: log10(((fields ->> 'value1'::text))::double precision), log10((((fields ->> 'value2'::text))::bigint)::double precision) InfluxDB query: SELECT "value1", "value2" FROM "s3" (3 rows) @@ -461,8 +461,16 @@ SELECT log10((fields->>'value1')::float),log10((fields->>'value2')::bigint) FROM -- select log10 (stub function, result) --Testcase 49: SELECT log10((fields->>'value1')::float),log10((fields->>'value2')::bigint) FROM s3; -ERROR: stub log10(float8) is called -CONTEXT: PL/pgSQL function log10(double precision) line 3 at RAISE + log10 | log10 +---------------------+-------------------- + -1 | 2 + -0.6989700043360187 | 2 + -0.5228787452803376 | 2 + 0.04139268515822507 | 2.3010299956639813 + 0.3424226808222063 | 2.3010299956639813 + 0.5185139398778874 | 2.3010299956639813 +(6 rows) + -- select log10(*) (stub agg function, explain) --Testcase 50: EXPLAIN VERBOSE @@ -521,9 +529,9 @@ SELECT spread((fields->>'value1')::float),spread((fields->>'value2')::bigint),sp -- select spread (stub agg function, result) --Testcase 56: SELECT spread((fields->>'value1')::float),spread((fields->>'value2')::bigint),spread((fields->>'value3')::float),spread((fields->>'value4')::bigint) FROM s3; - spread | spread | spread | spread ---------+--------+--------+-------- - 3.2 | 100 | 3.2 | 100 + spread | spread | spread | spread +--------------------+--------+--------------------+-------- + 3.1999999999999997 | 100 | 3.1999999999999997 | 100 (1 row) -- select spread (stub agg function, raise exception if not expected type) @@ -545,9 +553,9 @@ SELECT sum((fields->>'value3')::float),abs(sum((fields->>'value3')::float)) FROM -- select abs as nest function with agg (pushdown, result) --Testcase 59: SELECT sum((fields->>'value3')::float),abs(sum((fields->>'value3')::float)) FROM s3; - sum | abs -------+----- - -7.2 | 7.2 + sum | abs +--------------------+------------------- + -7.199999999999999 | 7.199999999999999 (1 row) -- select abs as nest with log2 (pushdown, explain) @@ -570,43 +578,43 @@ CONTEXT: PL/pgSQL function log2(double precision) line 3 at RAISE --Testcase 62: EXPLAIN VERBOSE SELECT abs((fields->>'value3')::float), pi(), 4.1 FROM s3; - QUERY PLAN ------------------------------------------------------------------------------------------------------------ + QUERY PLAN +------------------------------------------------------------------------------------------------------------ Foreign Scan on public.s3 (cost=10.00..1476.62 rows=1462 width=48) - Output: abs(((fields ->> 'value3'::text))::double precision), '3.14159265358979'::double precision, 4.1 + Output: abs(((fields ->> 'value3'::text))::double precision), '3.141592653589793'::double precision, 4.1 InfluxDB query: SELECT "value3" FROM "s3" (3 rows) -- select abs with non pushdown func and explicit constant (result) --Testcase 63: SELECT abs((fields->>'value3')::float), pi(), 4.1 FROM s3; - abs | pi | ?column? ------+------------------+---------- - 0.1 | 3.14159265358979 | 4.1 - 0.2 | 3.14159265358979 | 4.1 - 0.3 | 3.14159265358979 | 4.1 - 1.1 | 3.14159265358979 | 4.1 - 2.2 | 3.14159265358979 | 4.1 - 3.3 | 3.14159265358979 | 4.1 + abs | pi | ?column? +-----+-------------------+---------- + 0.1 | 3.141592653589793 | 4.1 + 0.2 | 3.141592653589793 | 4.1 + 0.3 | 3.141592653589793 | 4.1 + 1.1 | 3.141592653589793 | 4.1 + 2.2 | 3.141592653589793 | 4.1 + 3.3 | 3.141592653589793 | 4.1 (6 rows) -- select sqrt as nest function with agg and explicit constant (pushdown, explain) --Testcase 64: EXPLAIN VERBOSE SELECT sqrt(count((fields->>'value1')::float)), pi(), 4.1 FROM s3; - QUERY PLAN ------------------------------------------------------------------------------------------------------------------------------------------ + QUERY PLAN +------------------------------------------------------------------------------------------------------------------------------------------ Foreign Scan (cost=1.00..1.00 rows=1 width=48) - Output: (sqrt((count(((fields ->> 'value1'::text))::double precision))::double precision)), '3.14159265358979'::double precision, 4.1 + Output: (sqrt((count(((fields ->> 'value1'::text))::double precision))::double precision)), '3.141592653589793'::double precision, 4.1 InfluxDB query: SELECT sqrt(count("value1")) FROM "s3" (3 rows) -- select sqrt as nest function with agg and explicit constant (pushdown, result) --Testcase 65: SELECT sqrt(count((fields->>'value1')::float)), pi(), 4.1 FROM s3; - sqrt | pi | ?column? -------------------+------------------+---------- - 2.44948974278318 | 3.14159265358979 | 4.1 + sqrt | pi | ?column? +-------------------+-------------------+---------- + 2.449489742783178 | 3.141592653589793 | 4.1 (1 row) -- select sqrt as nest function with agg and explicit constant and tag (error, explain) @@ -647,18 +655,18 @@ SELECT spread((fields->>'value1')::float),influx_time(time, interval '1s'),tags- -- select spread (stub agg function and group by tag only) (result) --Testcase 69: SELECT tags->>'tag1' tag1,spread((fields->>'value1')::float) FROM s3 WHERE time >= to_timestamp(0) and time <= to_timestamp(4) GROUP BY tags->>'tag1'; - tag1 | spread -------+-------- - a | 0.2 - b | 1.1 + tag1 | spread +------+--------------------- + a | 0.19999999999999998 + b | 1.1 (2 rows) -- select spread (stub agg function and other aggs) (result) --Testcase 70: SELECT sum((fields->>'value1')::float),spread((fields->>'value1')::float),count((fields->>'value1')::float) FROM s3; - sum | spread | count ------+--------+------- - 7.2 | 3.2 | 6 + sum | spread | count +-------------------+--------------------+------- + 7.199999999999999 | 3.1999999999999997 | 6 (1 row) -- select abs with order by (explain) @@ -678,40 +686,40 @@ SELECT (fields->>'value1')::float value1, abs(1-(fields->>'value1')::float) FROM -- select abs with order by (result) --Testcase 72: SELECT (fields->>'value1')::float value1, abs(1-(fields->>'value1')::float) FROM s3 order by abs(1-(fields->>'value1')::float); - value1 | abs ---------+----- - 1.1 | 0.1 - 0.3 | 0.7 - 0.2 | 0.8 - 0.1 | 0.9 - 2.2 | 1.2 - 3.3 | 2.3 + value1 | abs +--------+--------------------- + 1.1 | 0.10000000000000009 + 0.3 | 0.7 + 0.2 | 0.8 + 0.1 | 0.9 + 2.2 | 1.2000000000000002 + 3.3 | 2.3 (6 rows) -- select abs with order by index (result) --Testcase 73: SELECT (fields->>'value1')::float value1, abs(1-(fields->>'value1')::float) FROM s3 order by 2,1; - value1 | abs ---------+----- - 1.1 | 0.1 - 0.3 | 0.7 - 0.2 | 0.8 - 0.1 | 0.9 - 2.2 | 1.2 - 3.3 | 2.3 + value1 | abs +--------+--------------------- + 1.1 | 0.10000000000000009 + 0.3 | 0.7 + 0.2 | 0.8 + 0.1 | 0.9 + 2.2 | 1.2000000000000002 + 3.3 | 2.3 (6 rows) -- select abs with order by index (result) --Testcase 74: SELECT (fields->>'value1')::float value1, abs(1-(fields->>'value1')::float) FROM s3 order by 1,2; - value1 | abs ---------+----- - 0.1 | 0.9 - 0.2 | 0.8 - 0.3 | 0.7 - 1.1 | 0.1 - 2.2 | 1.2 - 3.3 | 2.3 + value1 | abs +--------+--------------------- + 0.1 | 0.9 + 0.2 | 0.8 + 0.3 | 0.7 + 1.1 | 0.10000000000000009 + 2.2 | 1.2000000000000002 + 3.3 | 2.3 (6 rows) -- select abs and as @@ -794,12 +802,12 @@ SELECT spread((t1.fields->>'value1')::float), spread((t2.fields->>'value1')::flo Output: t1.fields, t2.fields -> Foreign Scan on public.s3 t1 (cost=10.00..7.00 rows=7 width=32) Output: t1."time", t1.tags, t1.fields - InfluxDB query: SELECT * FROM "s3" WHERE (("value1" = 0.100000000000000006)) + InfluxDB query: SELECT * FROM "s3" WHERE (("value1" = 0.1)) -> Materialize (cost=10.00..7.04 rows=7 width=32) Output: t2.fields -> Foreign Scan on public.s3 t2 (cost=10.00..7.00 rows=7 width=32) Output: t2.fields - InfluxDB query: SELECT * FROM "s3" WHERE (("value1" = 0.100000000000000006)) + InfluxDB query: SELECT * FROM "s3" WHERE (("value1" = 0.1)) (12 rows) -- select spread over join query (result, stub call error) @@ -813,7 +821,7 @@ EXPLAIN VERBOSE SELECT spread((fields->>'value1')::float) FROM s3 HAVING spread((fields->>'value1')::float) > 100; QUERY PLAN -------------------------------------------------------------------------------------------------- - Aggregate (cost=2214.93..2214.94 rows=1 width=8) + Aggregate (cost=1838.47..1838.48 rows=1 width=8) Output: spread(((fields ->> 'value1'::text))::double precision) Filter: (spread(((s3.fields ->> 'value1'::text))::double precision) > '100'::double precision) -> Foreign Scan on public.s3 (cost=10.00..1462.00 rows=1462 width=32) @@ -1012,14 +1020,14 @@ SELECT abs((fields->>'value1')::float) + 1, (fields->>'value2')::bigint value2, -- select abs with arithmetic and tag in the middle (result) --Testcase 103: SELECT abs((fields->>'value1')::float) + 1, (fields->>'value2')::bigint value2, tags->>'tag1' tag1, sqrt((fields->>'value2')::bigint) FROM s3; - ?column? | value2 | tag1 | sqrt -----------+--------+------+----------------- - 1.1 | 100 | a | 10 - 1.2 | 100 | a | 10 - 1.3 | 100 | a | 10 - 2.1 | 200 | b | 14.142135623731 - 3.2 | 200 | b | 14.142135623731 - 4.3 | 200 | b | 14.142135623731 + ?column? | value2 | tag1 | sqrt +----------+--------+------+-------------------- + 1.1 | 100 | a | 10 + 1.2 | 100 | a | 10 + 1.3 | 100 | a | 10 + 2.1 | 200 | b | 14.142135623730951 + 3.2 | 200 | b | 14.142135623730951 + 4.3 | 200 | b | 14.142135623730951 (6 rows) -- select with order by limit (explain) @@ -1060,14 +1068,14 @@ SELECT abs((fields->>'value1')::float), sqrt((fields->>'value2')::bigint), upper -- select mixing with non pushdown func (result) --Testcase 107: SELECT abs((fields->>'value1')::float), sqrt((fields->>'value2')::bigint), upper(tags->>'tag1') FROM s3; - abs | sqrt | upper ------+-----------------+------- - 0.1 | 10 | A - 0.2 | 10 | A - 0.3 | 10 | A - 1.1 | 14.142135623731 | B - 2.2 | 14.142135623731 | B - 3.3 | 14.142135623731 | B + abs | sqrt | upper +-----+--------------------+------- + 0.1 | 10 | A + 0.2 | 10 | A + 0.3 | 10 | A + 1.1 | 14.142135623730951 | B + 2.2 | 14.142135623730951 | B + 3.3 | 14.142135623730951 | B (6 rows) -- nested function in where clause (explain) @@ -1091,14 +1099,14 @@ SELECT sqrt(abs((fields->>'value3')::float)),min((fields->>'value1')::float) FRO -- nested function in where clause (result) --Testcase 109: SELECT sqrt(abs((fields->>'value3')::float)),min((fields->>'value1')::float) FROM s3 GROUP BY fields->>'value3' HAVING sqrt(abs((fields->>'value3')::float)) > 0 ORDER BY 1,2; - sqrt | min --------------------+----- - 0.316227766016838 | 0.1 - 0.447213595499958 | 0.2 - 0.547722557505166 | 0.3 - 1.04880884817015 | 1.1 - 1.48323969741913 | 2.2 - 1.81659021245849 | 3.3 + sqrt | min +---------------------+----- + 0.31622776601683794 | 0.1 + 0.4472135954999579 | 0.2 + 0.5477225575051661 | 0.3 + 1.0488088481701516 | 1.1 + 1.4832396974191326 | 2.2 + 1.816590212458495 | 3.3 (6 rows) --Testcase 110: @@ -3560,12 +3568,12 @@ SELECT integral((fields->>'value1')::float),influx_time(time, interval '1s'),tag -- select integral (stub agg function and group by influx_time() and tag) (result) --Testcase 390: SELECT integral((fields->>'value1')::float),influx_time(time, interval '1s'),tags->>'tag1' tag1 FROM s3 GROUP BY influx_time(time, interval '1s'), tags->>'tag1'; - integral | influx_time | tag1 -----------+------------------------+------ - 0.15 | 1970-01-01 09:00:00+09 | a - 0.25 | 1970-01-01 09:00:01+09 | a - 1.65 | 1970-01-01 09:00:03+09 | b - 2.75 | 1970-01-01 09:00:04+09 | b + integral | influx_time | tag1 +---------------------+------------------------+------ + 0.15000000000000002 | 1970-01-01 09:00:00+09 | a + 0.25 | 1970-01-01 09:00:01+09 | a + 1.6500000000000001 | 1970-01-01 09:00:03+09 | b + 2.75 | 1970-01-01 09:00:04+09 | b (4 rows) -- select integral (stub agg function and group by influx_time() and tag) (explain) @@ -3582,46 +3590,46 @@ SELECT integral((fields->>'value1')::float, interval '1s'),influx_time(time, int -- select integral (stub agg function and group by influx_time() and tag) (result) --Testcase 392: SELECT integral((fields->>'value1')::float, interval '1s'),influx_time(time, interval '1s'),tags->>'tag1' tag1 FROM s3 GROUP BY influx_time(time, interval '1s'), tags->>'tag1'; - integral | influx_time | tag1 -----------+------------------------+------ - 0.15 | 1970-01-01 09:00:00+09 | a - 0.25 | 1970-01-01 09:00:01+09 | a - 1.65 | 1970-01-01 09:00:03+09 | b - 2.75 | 1970-01-01 09:00:04+09 | b + integral | influx_time | tag1 +---------------------+------------------------+------ + 0.15000000000000002 | 1970-01-01 09:00:00+09 | a + 0.25 | 1970-01-01 09:00:01+09 | a + 1.6500000000000001 | 1970-01-01 09:00:03+09 | b + 2.75 | 1970-01-01 09:00:04+09 | b (4 rows) -- select integral (stub agg function and group by tag only) (result) --Testcase 393: SELECT tags->>'tag1' tag1,integral((fields->>'value1')::float) FROM s3 WHERE time >= to_timestamp(0) and time <= to_timestamp(4) GROUP BY tags->>'tag1' ORDER BY 1; - tag1 | integral -------+---------- - a | 0.4 - b | 1.65 + tag1 | integral +------+-------------------- + a | 0.4 + b | 1.6500000000000001 (2 rows) -- select integral (stub agg function and other aggs) (result) --Testcase 394: SELECT sum((fields->>'value1')::float),integral((fields->>'value1')::float),count((fields->>'value1')::float) FROM s3; - sum | integral | count ------+----------+------- - 7.2 | 5.5 | 6 + sum | integral | count +-------------------+----------+------- + 7.199999999999999 | 5.5 | 6 (1 row) -- select integral (stub agg function and group by tag only) (result) --Testcase 395: SELECT tags->>'tag1' tag1,integral((fields->>'value1')::float, interval '1s') FROM s3 WHERE time >= to_timestamp(0) and time <= to_timestamp(4) GROUP BY tags->>'tag1' ORDER BY 1; - tag1 | integral -------+---------- - a | 0.4 - b | 1.65 + tag1 | integral +------+-------------------- + a | 0.4 + b | 1.6500000000000001 (2 rows) -- select integral (stub agg function and other aggs) (result) --Testcase 396: SELECT sum((fields->>'value1')::float),integral((fields->>'value1')::float, interval '1s'),count((fields->>'value1')::float) FROM s3; - sum | integral | count ------+----------+------- - 7.2 | 5.5 | 6 + sum | integral | count +-------------------+----------+------- + 7.199999999999999 | 5.5 | 6 (1 row) -- select integral over join query (explain) @@ -3636,12 +3644,12 @@ SELECT integral((t1.fields->>'value1')::float), integral((t2.fields->>'value1'): Output: t1.fields, t2.fields -> Foreign Scan on public.s3 t1 (cost=10.00..7.00 rows=7 width=32) Output: t1."time", t1.tags, t1.fields - InfluxDB query: SELECT * FROM "s3" WHERE (("value1" = 0.100000000000000006)) + InfluxDB query: SELECT * FROM "s3" WHERE (("value1" = 0.1)) -> Materialize (cost=10.00..7.04 rows=7 width=32) Output: t2.fields -> Foreign Scan on public.s3 t2 (cost=10.00..7.00 rows=7 width=32) Output: t2.fields - InfluxDB query: SELECT * FROM "s3" WHERE (("value1" = 0.100000000000000006)) + InfluxDB query: SELECT * FROM "s3" WHERE (("value1" = 0.1)) (12 rows) -- select integral over join query (result, stub call error) @@ -3661,12 +3669,12 @@ SELECT integral((t1.fields->>'value1')::float, interval '1s'), integral((t2.fiel Output: t1.fields, t2.fields -> Foreign Scan on public.s3 t1 (cost=10.00..7.00 rows=7 width=32) Output: t1."time", t1.tags, t1.fields - InfluxDB query: SELECT * FROM "s3" WHERE (("value1" = 0.100000000000000006)) + InfluxDB query: SELECT * FROM "s3" WHERE (("value1" = 0.1)) -> Materialize (cost=10.00..7.04 rows=7 width=32) Output: t2.fields -> Foreign Scan on public.s3 t2 (cost=10.00..7.00 rows=7 width=32) Output: t2.fields - InfluxDB query: SELECT * FROM "s3" WHERE (("value1" = 0.100000000000000006)) + InfluxDB query: SELECT * FROM "s3" WHERE (("value1" = 0.1)) (12 rows) -- select integral over join query (result, stub call error) @@ -3680,7 +3688,7 @@ EXPLAIN VERBOSE SELECT integral((fields->>'value1')::float) FROM s3 HAVING integral((fields->>'value1')::float) > 100; QUERY PLAN ---------------------------------------------------------------------------------------------------- - Aggregate (cost=2214.93..2214.94 rows=1 width=8) + Aggregate (cost=1838.47..1838.48 rows=1 width=8) Output: integral(((fields ->> 'value1'::text))::double precision) Filter: (integral(((s3.fields ->> 'value1'::text))::double precision) > '100'::double precision) -> Foreign Scan on public.s3 (cost=10.00..1462.00 rows=1462 width=32) @@ -3699,7 +3707,7 @@ EXPLAIN VERBOSE SELECT integral((fields->>'value1')::float, interval '1s') FROM s3 HAVING integral((fields->>'value1')::float, interval '1s') > 100; QUERY PLAN ------------------------------------------------------------------------------------------------------------------------- - Aggregate (cost=2214.93..2214.94 rows=1 width=8) + Aggregate (cost=1838.47..1838.48 rows=1 width=8) Output: integral(((fields ->> 'value1'::text))::double precision, '@ 1 sec'::interval) Filter: (integral(((s3.fields ->> 'value1'::text))::double precision, '@ 1 sec'::interval) > '100'::double precision) -> Foreign Scan on public.s3 (cost=10.00..1462.00 rows=1462 width=32) @@ -3757,11 +3765,11 @@ SELECT integral_all(*) FROM s3 GROUP BY influx_time(time, interval '1s'), tags-> --Testcase 409: EXPLAIN VERBOSE SELECT integral_all(*) FROM s3 WHERE (fields->>'value1')::float > 0.3 GROUP BY tags->>'tag1'; - QUERY PLAN ------------------------------------------------------------------------------------------------------------- + QUERY PLAN +------------------------------------------------------------------------------------------- Foreign Scan (cost=1.00..1.00 rows=1 width=64) Output: (integral_all(*)), ((tags ->> 'tag1'::text)) - InfluxDB query: SELECT integral(*) FROM "s3" WHERE (("value1" > 0.299999999999999989)) GROUP BY ("tag1") + InfluxDB query: SELECT integral(*) FROM "s3" WHERE (("value1" > 0.3)) GROUP BY ("tag1") (3 rows) -- select integral(*) (stub agg function and group by tag only) (result) @@ -3836,11 +3844,11 @@ SELECT integral('/^v.*/') FROM s3 GROUP BY influx_time(time, interval '1s'), tag --Testcase 417: EXPLAIN VERBOSE SELECT integral('/value[1,4]/') FROM s3 WHERE (fields->>'value1')::float > 0.3 GROUP BY tags->>'tag1'; - QUERY PLAN ------------------------------------------------------------------------------------------------------------------------ + QUERY PLAN +------------------------------------------------------------------------------------------------------ Foreign Scan (cost=1.00..1.00 rows=1 width=64) Output: (integral('/value[1,4]/'::text)), ((tags ->> 'tag1'::text)) - InfluxDB query: SELECT integral(/value[1,4]/) FROM "s3" WHERE (("value1" > 0.299999999999999989)) GROUP BY ("tag1") + InfluxDB query: SELECT integral(/value[1,4]/) FROM "s3" WHERE (("value1" > 0.3)) GROUP BY ("tag1") (3 rows) -- select integral(regex) (stub agg function and group by tag only) (result) @@ -3925,18 +3933,18 @@ SELECT mean((fields->>'value1')::float),influx_time(time, interval '1s'),tags->> -- select mean (stub agg function and group by tag only) (result) --Testcase 426: SELECT tags->>'tag1' tag1,mean((fields->>'value1')::float) FROM s3 WHERE time >= to_timestamp(0) and time <= to_timestamp(4) GROUP BY tags->>'tag1'; - tag1 | mean -------+------ - a | 0.2 - b | 1.65 + tag1 | mean +------+--------------------- + a | 0.20000000000000004 + b | 1.6500000000000001 (2 rows) -- select mean (stub agg function and other aggs) (result) --Testcase 427: SELECT sum((fields->>'value1')::float),mean((fields->>'value1')::float),count((fields->>'value1')::float) FROM s3; - sum | mean | count ------+------+------- - 7.2 | 1.2 | 6 + sum | mean | count +-------------------+------+------- + 7.199999999999999 | 1.2 | 6 (1 row) -- select mean over join query (explain) @@ -3951,12 +3959,12 @@ SELECT mean((t1.fields->>'value1')::float), mean((t2.fields->>'value1')::float) Output: t1.fields, t2.fields -> Foreign Scan on public.s3 t1 (cost=10.00..7.00 rows=7 width=32) Output: t1."time", t1.tags, t1.fields - InfluxDB query: SELECT * FROM "s3" WHERE (("value1" = 0.100000000000000006)) + InfluxDB query: SELECT * FROM "s3" WHERE (("value1" = 0.1)) -> Materialize (cost=10.00..7.04 rows=7 width=32) Output: t2.fields -> Foreign Scan on public.s3 t2 (cost=10.00..7.00 rows=7 width=32) Output: t2.fields - InfluxDB query: SELECT * FROM "s3" WHERE (("value1" = 0.100000000000000006)) + InfluxDB query: SELECT * FROM "s3" WHERE (("value1" = 0.1)) (12 rows) -- select mean over join query (result, stub call error) @@ -3970,7 +3978,7 @@ EXPLAIN VERBOSE SELECT mean((fields->>'value1')::float) FROM s3 HAVING mean((fields->>'value1')::float) > 100; QUERY PLAN ------------------------------------------------------------------------------------------------ - Aggregate (cost=2214.93..2214.94 rows=1 width=8) + Aggregate (cost=1838.47..1838.48 rows=1 width=8) Output: mean(((fields ->> 'value1'::text))::double precision) Filter: (mean(((s3.fields ->> 'value1'::text))::double precision) > '100'::double precision) -> Foreign Scan on public.s3 (cost=10.00..1462.00 rows=1462 width=32) @@ -4169,9 +4177,9 @@ SELECT median((fields->>'value1')::float),median((fields->>'value2')::bigint),me -- select median (stub agg function, result) --Testcase 449: SELECT median((fields->>'value1')::float),median((fields->>'value2')::bigint),median((fields->>'value3')::float),median((fields->>'value4')::bigint) FROM s3; - median | median | median | median ---------+--------+--------+-------- - 0.7 | 150 | -0.7 | -150 + median | median | median | median +--------+--------+---------------------+-------- + 0.7 | 150 | -0.7000000000000001 | -150 (1 row) -- select median (stub agg function, raise exception if not expected type) @@ -4210,18 +4218,18 @@ SELECT median((fields->>'value1')::float),influx_time(time, interval '1s'),tags- -- select median (stub agg function and group by tag only) (result) --Testcase 453: SELECT tags->>'tag1' tag1,median((fields->>'value1')::float) FROM s3 WHERE time >= to_timestamp(0) and time <= to_timestamp(4) GROUP BY tags->>'tag1'; - tag1 | median -------+-------- - a | 0.2 - b | 1.65 + tag1 | median +------+-------------------- + a | 0.2 + b | 1.6500000000000001 (2 rows) -- select median (stub agg function and other aggs) (result) --Testcase 454: SELECT sum((fields->>'value1')::float),median((fields->>'value1')::float),count((fields->>'value1')::float) FROM s3; - sum | median | count ------+--------+------- - 7.2 | 0.7 | 6 + sum | median | count +-------------------+--------+------- + 7.199999999999999 | 0.7 | 6 (1 row) -- select median over join query (explain) @@ -4236,12 +4244,12 @@ SELECT median((t1.fields->>'value1')::float), median((t2.fields->>'value1')::flo Output: t1.fields, t2.fields -> Foreign Scan on public.s3 t1 (cost=10.00..7.00 rows=7 width=32) Output: t1."time", t1.tags, t1.fields - InfluxDB query: SELECT * FROM "s3" WHERE (("value1" = 0.100000000000000006)) + InfluxDB query: SELECT * FROM "s3" WHERE (("value1" = 0.1)) -> Materialize (cost=10.00..7.04 rows=7 width=32) Output: t2.fields -> Foreign Scan on public.s3 t2 (cost=10.00..7.00 rows=7 width=32) Output: t2.fields - InfluxDB query: SELECT * FROM "s3" WHERE (("value1" = 0.100000000000000006)) + InfluxDB query: SELECT * FROM "s3" WHERE (("value1" = 0.1)) (12 rows) -- select median over join query (result, stub call error) @@ -4255,7 +4263,7 @@ EXPLAIN VERBOSE SELECT median((fields->>'value1')::float) FROM s3 HAVING median((fields->>'value1')::float) > 100; QUERY PLAN -------------------------------------------------------------------------------------------------- - Aggregate (cost=2214.93..2214.94 rows=1 width=8) + Aggregate (cost=1838.47..1838.48 rows=1 width=8) Output: median(((fields ->> 'value1'::text))::double precision) Filter: (median(((s3.fields ->> 'value1'::text))::double precision) > '100'::double precision) -> Foreign Scan on public.s3 (cost=10.00..1462.00 rows=1462 width=32) @@ -4507,9 +4515,9 @@ SELECT tags->>'tag1' tag1,influx_mode((fields->>'value1')::numeric) FROM s3 WHER -- select influx_mode (stub agg function and other aggs) (result) --Testcase 481: SELECT sum((fields->>'value1')::float),influx_mode((fields->>'value1')::numeric),count((fields->>'value1')::float) FROM s3; - sum | influx_mode | count ------+-------------+------- - 7.2 | 0.1 | 6 + sum | influx_mode | count +-------------------+-------------+------- + 7.199999999999999 | 0.1 | 6 (1 row) -- select influx_mode over join query (explain) @@ -4524,12 +4532,12 @@ SELECT influx_mode((t1.fields->>'value1')::float), influx_mode((t2.fields->>'val Output: t1.fields, t2.fields -> Foreign Scan on public.s3 t1 (cost=10.00..7.00 rows=7 width=32) Output: t1."time", t1.tags, t1.fields - InfluxDB query: SELECT * FROM "s3" WHERE (("value1" = 0.100000000000000006)) + InfluxDB query: SELECT * FROM "s3" WHERE (("value1" = 0.1)) -> Materialize (cost=10.00..7.04 rows=7 width=32) Output: t2.fields -> Foreign Scan on public.s3 t2 (cost=10.00..7.00 rows=7 width=32) Output: t2.fields - InfluxDB query: SELECT * FROM "s3" WHERE (("value1" = 0.100000000000000006)) + InfluxDB query: SELECT * FROM "s3" WHERE (("value1" = 0.1)) (12 rows) -- select influx_mode over join query (result, stub call error) @@ -4543,7 +4551,7 @@ EXPLAIN VERBOSE SELECT influx_mode((fields->>'value1')::float) FROM s3 HAVING influx_mode((fields->>'value1')::float) > 100; QUERY PLAN ------------------------------------------------------------------------------------------------------- - Aggregate (cost=2214.93..2214.94 rows=1 width=8) + Aggregate (cost=1838.47..1838.48 rows=1 width=8) Output: influx_mode(((fields ->> 'value1'::text))::double precision) Filter: (influx_mode(((s3.fields ->> 'value1'::text))::double precision) > '100'::double precision) -> Foreign Scan on public.s3 (cost=10.00..1462.00 rows=1462 width=32) @@ -4742,9 +4750,9 @@ SELECT stddev((fields->>'value1')::float),stddev((fields->>'value2')::bigint),st -- select stddev (agg function, result) --Testcase 503: SELECT stddev((fields->>'value1')::float),stddev((fields->>'value2')::bigint),stddev((fields->>'value3')::float),stddev((fields->>'value4')::bigint) FROM s3; - stddev | stddev | stddev | stddev -------------------+--------------------+------------------+-------------------- - 1.29923054151294 | 54.772255750516614 | 1.29923054151294 | 54.772255750516614 + stddev | stddev | stddev | stddev +-------------------+--------------------+-------------------+-------------------- + 1.299230541512937 | 54.772255750516614 | 1.299230541512937 | 54.772255750516614 (1 row) -- select stddev (agg function and group by influx_time() and tag) (explain) @@ -4778,18 +4786,18 @@ SELECT stddev((fields->>'value1')::float),influx_time(time, interval '1s'),tags- -- select stddev (agg function and group by tag only) (result) --Testcase 506: SELECT tags->>'tag1' tag1,stddev((fields->>'value1')::float) FROM s3 WHERE time >= to_timestamp(0) and time <= to_timestamp(4) GROUP BY tags->>'tag1'; - tag1 | stddev -------+------------------- - a | 0.1 - b | 0.777817459305202 + tag1 | stddev +------+--------------------- + a | 0.09999999999999999 + b | 0.7778174593052023 (2 rows) -- select stddev (agg function and other aggs) (result) --Testcase 507: SELECT sum((fields->>'value1')::float),stddev((fields->>'value1')::float),count(fields->>'value1') FROM s3; - sum | stddev | count ------+------------------+------- - 7.2 | 1.29923054151294 | 6 + sum | stddev | count +-------------------+-------------------+------- + 7.199999999999999 | 1.299230541512937 | 6 (1 row) -- select stddev(*) (stub agg function, explain) @@ -5840,11 +5848,11 @@ SELECT acos((fields->>'value1')::float), acos((fields->>'value3')::float) FROM s -- select acos (builtin function, not pushdown constraints, result) --Testcase 611: SELECT acos((fields->>'value1')::float), acos((fields->>'value3')::float) FROM s3 WHERE to_hex((fields->>'value2')::bigint) = '64'; - acos | acos -------------------+------------------ - 1.47062890563334 | 1.67096374795646 - 1.36943840600457 | 1.77215424758523 - 1.2661036727795 | 1.87548898081029 + acos | acos +--------------------+-------------------- + 1.4706289056333368 | 1.6709637479564565 + 1.369438406004566 | 1.7721542475852274 + 1.2661036727794992 | 1.8754889808102941 (3 rows) -- select acos (builtin function, pushdown constraints, explain) @@ -5861,11 +5869,11 @@ SELECT acos((fields->>'value1')::float), acos((fields->>'value3')::float) FROM s -- select acos (builtin function, pushdown constraints, result) --Testcase 613: SELECT acos((fields->>'value1')::float), acos((fields->>'value3')::float) FROM s3 WHERE (fields->>'value2')::bigint != 200; - acos | acos -------------------+------------------ - 1.47062890563334 | 1.67096374795646 - 1.36943840600457 | 1.77215424758523 - 1.2661036727795 | 1.87548898081029 + acos | acos +--------------------+-------------------- + 1.4706289056333368 | 1.6709637479564565 + 1.369438406004566 | 1.7721542475852274 + 1.2661036727794992 | 1.8754889808102941 (3 rows) -- select acos as nest function with agg (pushdown, explain) @@ -5882,9 +5890,9 @@ SELECT sum((fields->>'value3')::float), acos(sum((fields->>'value3')::float)) FR -- select acos as nest function with agg (pushdown, result) --Testcase 615: SELECT sum((fields->>'value3')::float), acos(sum((fields->>'value3')::float)) FROM s3 WHERE (fields->>'value2')::bigint != 200; - sum | acos -------+------------------ - -0.6 | 2.21429743558818 + sum | acos +---------------------+------------------- + -0.6000000000000001 | 2.214297435588181 (1 row) -- select acos as nest with log2 (pushdown, explain) @@ -5907,21 +5915,21 @@ CONTEXT: PL/pgSQL function log2(double precision) line 3 at RAISE --Testcase 618: EXPLAIN VERBOSE SELECT acos((fields->>'value3')::float), pi(), 4.1 FROM s3 WHERE (fields->>'value2')::bigint != 200; - QUERY PLAN ------------------------------------------------------------------------------------------------------------- + QUERY PLAN +------------------------------------------------------------------------------------------------------------- Foreign Scan on public.s3 (cost=10.00..1469.55 rows=1455 width=48) - Output: acos(((fields ->> 'value3'::text))::double precision), '3.14159265358979'::double precision, 4.1 + Output: acos(((fields ->> 'value3'::text))::double precision), '3.141592653589793'::double precision, 4.1 InfluxDB query: SELECT "value3" FROM "s3" WHERE (("value2" <> 200)) (3 rows) -- select acos with non pushdown func and explicit constant (result) --Testcase 619: SELECT acos((fields->>'value3')::float), pi(), 4.1 FROM s3 WHERE (fields->>'value2')::bigint != 200; - acos | pi | ?column? -------------------+------------------+---------- - 1.67096374795646 | 3.14159265358979 | 4.1 - 1.77215424758523 | 3.14159265358979 | 4.1 - 1.87548898081029 | 3.14159265358979 | 4.1 + acos | pi | ?column? +--------------------+-------------------+---------- + 1.6709637479564565 | 3.141592653589793 | 4.1 + 1.7721542475852274 | 3.141592653589793 | 4.1 + 1.8754889808102941 | 3.141592653589793 | 4.1 (3 rows) -- select acos with order by (explain) @@ -5941,41 +5949,41 @@ SELECT (fields->>'value1')::float value1, acos(1-(fields->>'value1')::float) FRO -- select acos with order by (result) --Testcase 621: SELECT (fields->>'value1')::float value1, acos(1-(fields->>'value1')::float) FROM s3 WHERE (fields->>'value2')::bigint != 200 ORDER BY acos(1-(fields->>'value1')::float); - value1 | acos ---------+------------------- - 0.1 | 0.451026811796262 - 0.2 | 0.643501108793284 - 0.3 | 0.795398830184144 + value1 | acos +--------+--------------------- + 0.1 | 0.45102681179626236 + 0.2 | 0.6435011087932843 + 0.3 | 0.7953988301841436 (3 rows) -- select acos with order by index (result) --Testcase 622: SELECT (fields->>'value1')::float value1, acos(1-(fields->>'value1')::float) FROM s3 WHERE (fields->>'value2')::bigint != 200 ORDER BY 2,1; - value1 | acos ---------+------------------- - 0.1 | 0.451026811796262 - 0.2 | 0.643501108793284 - 0.3 | 0.795398830184144 + value1 | acos +--------+--------------------- + 0.1 | 0.45102681179626236 + 0.2 | 0.6435011087932843 + 0.3 | 0.7953988301841436 (3 rows) -- select acos with order by index (result) --Testcase 623: SELECT (fields->>'value1')::float value1, acos(1-(fields->>'value1')::float) FROM s3 WHERE (fields->>'value2')::bigint != 200 ORDER BY 1,2; - value1 | acos ---------+------------------- - 0.1 | 0.451026811796262 - 0.2 | 0.643501108793284 - 0.3 | 0.795398830184144 + value1 | acos +--------+--------------------- + 0.1 | 0.45102681179626236 + 0.2 | 0.6435011087932843 + 0.3 | 0.7953988301841436 (3 rows) -- select acos and as --Testcase 624: SELECT acos((fields->>'value3')::float) as acos1 FROM s3 WHERE (fields->>'value2')::bigint != 200; - acos1 ------------------- - 1.67096374795646 - 1.77215424758523 - 1.87548898081029 + acos1 +-------------------- + 1.6709637479564565 + 1.7721542475852274 + 1.8754889808102941 (3 rows) -- select acos(*) (stub agg function, explain) @@ -6063,11 +6071,11 @@ SELECT asin((fields->>'value1')::float), asin((fields->>'value3')::float) FROM s -- select asin (builtin function, not pushdown constraints, result) --Testcase 634: SELECT asin((fields->>'value1')::float), asin((fields->>'value3')::float) FROM s3 WHERE to_hex((fields->>'value2')::bigint) = '64'; - asin | asin --------------------+-------------------- - 0.10016742116156 | -0.10016742116156 - 0.201357920790331 | -0.201357920790331 - 0.304692654015398 | -0.304692654015398 + asin | asin +--------------------+--------------------- + 0.1001674211615598 | -0.1001674211615598 + 0.2013579207903308 | -0.2013579207903308 + 0.3046926540153975 | -0.3046926540153975 (3 rows) -- select asin (builtin function, pushdown constraints, explain) @@ -6084,11 +6092,11 @@ SELECT asin((fields->>'value1')::float), asin((fields->>'value3')::float) FROM s -- select asin (builtin function, pushdown constraints, result) --Testcase 636: SELECT asin((fields->>'value1')::float), asin((fields->>'value3')::float) FROM s3 WHERE (fields->>'value2')::bigint != 200; - asin | asin --------------------+-------------------- - 0.10016742116156 | -0.10016742116156 - 0.201357920790331 | -0.201357920790331 - 0.304692654015398 | -0.304692654015398 + asin | asin +--------------------+--------------------- + 0.1001674211615598 | -0.1001674211615598 + 0.2013579207903308 | -0.2013579207903308 + 0.3046926540153975 | -0.3046926540153975 (3 rows) -- select asin as nest function with agg (pushdown, explain) @@ -6105,9 +6113,9 @@ SELECT sum((fields->>'value3')::float), asin(sum((fields->>'value3')::float)) FR -- select asin as nest function with agg (pushdown, result) --Testcase 638: SELECT sum((fields->>'value3')::float), asin(sum((fields->>'value3')::float)) FROM s3 WHERE (fields->>'value2')::bigint != 200; - sum | asin -------+-------------------- - -0.6 | -0.643501108793284 + sum | asin +---------------------+--------------------- + -0.6000000000000001 | -0.6435011087932845 (1 row) -- select asin as nest with log2 (pushdown, explain) @@ -6130,21 +6138,21 @@ CONTEXT: PL/pgSQL function log2(double precision) line 3 at RAISE --Testcase 641: EXPLAIN VERBOSE SELECT asin((fields->>'value3')::float), pi(), 4.1 FROM s3 WHERE (fields->>'value2')::bigint != 200; - QUERY PLAN ------------------------------------------------------------------------------------------------------------- + QUERY PLAN +------------------------------------------------------------------------------------------------------------- Foreign Scan on public.s3 (cost=10.00..1469.55 rows=1455 width=48) - Output: asin(((fields ->> 'value3'::text))::double precision), '3.14159265358979'::double precision, 4.1 + Output: asin(((fields ->> 'value3'::text))::double precision), '3.141592653589793'::double precision, 4.1 InfluxDB query: SELECT "value3" FROM "s3" WHERE (("value2" <> 200)) (3 rows) -- select asin with non pushdown func and explicit constant (result) --Testcase 642: SELECT asin((fields->>'value3')::float), pi(), 4.1 FROM s3 WHERE (fields->>'value2')::bigint != 200; - asin | pi | ?column? ---------------------+------------------+---------- - -0.10016742116156 | 3.14159265358979 | 4.1 - -0.201357920790331 | 3.14159265358979 | 4.1 - -0.304692654015398 | 3.14159265358979 | 4.1 + asin | pi | ?column? +---------------------+-------------------+---------- + -0.1001674211615598 | 3.141592653589793 | 4.1 + -0.2013579207903308 | 3.141592653589793 | 4.1 + -0.3046926540153975 | 3.141592653589793 | 4.1 (3 rows) -- select asin with order by (explain) @@ -6164,41 +6172,41 @@ SELECT (fields->>'value1')::float value1, asin(1-(fields->>'value1')::float) FRO -- select asin with order by (result) --Testcase 644: SELECT (fields->>'value1')::float value1, asin(1-(fields->>'value1')::float) FROM s3 WHERE (fields->>'value2')::bigint != 200 ORDER BY asin(1-(fields->>'value1')::float); - value1 | asin ---------+------------------- - 0.3 | 0.775397496610753 - 0.2 | 0.927295218001612 - 0.1 | 1.11976951499863 + value1 | asin +--------+-------------------- + 0.3 | 0.775397496610753 + 0.2 | 0.9272952180016123 + 0.1 | 1.1197695149986342 (3 rows) -- select asin with order by index (result) --Testcase 645: SELECT (fields->>'value1')::float value1, asin(1-(fields->>'value1')::float) FROM s3 WHERE (fields->>'value2')::bigint != 200 ORDER BY 2,1; - value1 | asin ---------+------------------- - 0.3 | 0.775397496610753 - 0.2 | 0.927295218001612 - 0.1 | 1.11976951499863 + value1 | asin +--------+-------------------- + 0.3 | 0.775397496610753 + 0.2 | 0.9272952180016123 + 0.1 | 1.1197695149986342 (3 rows) -- select asin with order by index (result) --Testcase 646: SELECT (fields->>'value1')::float value1, asin(1-(fields->>'value1')::float) FROM s3 WHERE (fields->>'value2')::bigint != 200 ORDER BY 1,2; - value1 | asin ---------+------------------- - 0.1 | 1.11976951499863 - 0.2 | 0.927295218001612 - 0.3 | 0.775397496610753 + value1 | asin +--------+-------------------- + 0.1 | 1.1197695149986342 + 0.2 | 0.9272952180016123 + 0.3 | 0.775397496610753 (3 rows) -- select asin and as --Testcase 647: SELECT asin((fields->>'value3')::float) as asin1 FROM s3 WHERE (fields->>'value2')::bigint != 200; - asin1 --------------------- - -0.10016742116156 - -0.201357920790331 - -0.304692654015398 + asin1 +--------------------- + -0.1001674211615598 + -0.2013579207903308 + -0.3046926540153975 (3 rows) -- select asin(*) (stub agg function, explain) @@ -6270,14 +6278,14 @@ SELECT atan((fields->>'value1')::float), atan((fields->>'value2')::bigint), atan -- select atan (builtin function, result) --Testcase 655: SELECT atan((fields->>'value1')::float), atan((fields->>'value2')::bigint), atan((fields->>'value3')::float), atan((fields->>'value4')::bigint) FROM s3; - atan | atan | atan | atan --------------------+------------------+--------------------+------------------- - 0.099668652491162 | 1.56079666010823 | -0.099668652491162 | -1.56079666010823 - 0.197395559849881 | 1.56079666010823 | -0.197395559849881 | -1.56079666010823 - 0.291456794477867 | 1.56079666010823 | -0.291456794477867 | -1.56079666010823 - 0.832981266674432 | 1.56579636846094 | -0.832981266674432 | -1.56579636846094 - 1.14416883366802 | 1.56579636846094 | -1.14416883366802 | -1.56579636846094 - 1.27656176168371 | 1.56579636846094 | -1.27656176168371 | -1.56579636846094 + atan | atan | atan | atan +---------------------+--------------------+----------------------+--------------------- + 0.09966865249116204 | 1.5607966601082315 | -0.09966865249116204 | -1.5607966601082315 + 0.19739555984988078 | 1.5607966601082315 | -0.19739555984988078 | -1.5607966601082315 + 0.2914567944778671 | 1.5607966601082315 | -0.2914567944778671 | -1.5607966601082315 + 0.8329812666744317 | 1.5657963684609384 | -0.8329812666744317 | -1.5657963684609384 + 1.1441688336680205 | 1.5657963684609384 | -1.1441688336680205 | -1.5657963684609384 + 1.2765617616837088 | 1.5657963684609384 | -1.2765617616837088 | -1.5657963684609384 (6 rows) -- select atan (builtin function, not pushdown constraints, explain) @@ -6295,11 +6303,11 @@ SELECT atan((fields->>'value1')::float), atan((fields->>'value2')::bigint), atan -- select atan (builtin function, not pushdown constraints, result) --Testcase 657: SELECT atan((fields->>'value1')::float), atan((fields->>'value2')::bigint), atan((fields->>'value3')::float), atan((fields->>'value4')::bigint) FROM s3 WHERE to_hex((fields->>'value2')::bigint) != '64'; - atan | atan | atan | atan --------------------+------------------+--------------------+------------------- - 0.832981266674432 | 1.56579636846094 | -0.832981266674432 | -1.56579636846094 - 1.14416883366802 | 1.56579636846094 | -1.14416883366802 | -1.56579636846094 - 1.27656176168371 | 1.56579636846094 | -1.27656176168371 | -1.56579636846094 + atan | atan | atan | atan +--------------------+--------------------+---------------------+--------------------- + 0.8329812666744317 | 1.5657963684609384 | -0.8329812666744317 | -1.5657963684609384 + 1.1441688336680205 | 1.5657963684609384 | -1.1441688336680205 | -1.5657963684609384 + 1.2765617616837088 | 1.5657963684609384 | -1.2765617616837088 | -1.5657963684609384 (3 rows) -- select atan (builtin function, pushdown constraints, explain) @@ -6316,11 +6324,11 @@ SELECT atan((fields->>'value1')::float), atan((fields->>'value2')::bigint), atan -- select atan (builtin function, pushdown constraints, result) --Testcase 659: SELECT atan((fields->>'value1')::float), atan((fields->>'value2')::bigint), atan((fields->>'value3')::float), atan((fields->>'value4')::bigint) FROM s3 WHERE (fields->>'value2')::bigint != 200; - atan | atan | atan | atan --------------------+------------------+--------------------+------------------- - 0.099668652491162 | 1.56079666010823 | -0.099668652491162 | -1.56079666010823 - 0.197395559849881 | 1.56079666010823 | -0.197395559849881 | -1.56079666010823 - 0.291456794477867 | 1.56079666010823 | -0.291456794477867 | -1.56079666010823 + atan | atan | atan | atan +---------------------+--------------------+----------------------+--------------------- + 0.09966865249116204 | 1.5607966601082315 | -0.09966865249116204 | -1.5607966601082315 + 0.19739555984988078 | 1.5607966601082315 | -0.19739555984988078 | -1.5607966601082315 + 0.2914567944778671 | 1.5607966601082315 | -0.2914567944778671 | -1.5607966601082315 (3 rows) -- select atan as nest function with agg (pushdown, explain) @@ -6337,9 +6345,9 @@ SELECT sum((fields->>'value3')::float),atan(sum((fields->>'value3')::float)) FRO -- select atan as nest function with agg (pushdown, result) --Testcase 661: SELECT sum((fields->>'value3')::float),atan(sum((fields->>'value3')::float)) FROM s3; - sum | atan -------+------------------- - -7.2 | -1.43279030313738 + sum | atan +--------------------+--------------------- + -7.199999999999999 | -1.4327903031373772 (1 row) -- select atan as nest with log2 (pushdown, explain) @@ -6362,24 +6370,24 @@ CONTEXT: PL/pgSQL function log2(double precision) line 3 at RAISE --Testcase 664: EXPLAIN VERBOSE SELECT atan((fields->>'value3')::float), pi(), 4.1 FROM s3; - QUERY PLAN ------------------------------------------------------------------------------------------------------------- + QUERY PLAN +------------------------------------------------------------------------------------------------------------- Foreign Scan on public.s3 (cost=10.00..1476.62 rows=1462 width=48) - Output: atan(((fields ->> 'value3'::text))::double precision), '3.14159265358979'::double precision, 4.1 + Output: atan(((fields ->> 'value3'::text))::double precision), '3.141592653589793'::double precision, 4.1 InfluxDB query: SELECT "value3" FROM "s3" (3 rows) -- select atan with non pushdown func and explicit constant (result) --Testcase 665: SELECT atan((fields->>'value3')::float), pi(), 4.1 FROM s3; - atan | pi | ?column? ---------------------+------------------+---------- - -0.099668652491162 | 3.14159265358979 | 4.1 - -0.197395559849881 | 3.14159265358979 | 4.1 - -0.291456794477867 | 3.14159265358979 | 4.1 - -0.832981266674432 | 3.14159265358979 | 4.1 - -1.14416883366802 | 3.14159265358979 | 4.1 - -1.27656176168371 | 3.14159265358979 | 4.1 + atan | pi | ?column? +----------------------+-------------------+---------- + -0.09966865249116204 | 3.141592653589793 | 4.1 + -0.19739555984988078 | 3.141592653589793 | 4.1 + -0.2914567944778671 | 3.141592653589793 | 4.1 + -0.8329812666744317 | 3.141592653589793 | 4.1 + -1.1441688336680205 | 3.141592653589793 | 4.1 + -1.2765617616837088 | 3.141592653589793 | 4.1 (6 rows) -- select atan with order by (explain) @@ -6399,53 +6407,53 @@ SELECT (fields->>'value1')::float value1, atan(1-(fields->>'value1')::float) FRO -- select atan with order by (result) --Testcase 667: SELECT (fields->>'value1')::float value1, atan(1-(fields->>'value1')::float) FROM s3 order by atan(1-(fields->>'value1')::float); - value1 | atan ---------+--------------------- - 3.3 | -1.16066898625341 - 2.2 | -0.876058050598194 - 1.1 | -0.0996686524911621 - 0.3 | 0.610725964389209 - 0.2 | 0.674740942223553 - 0.1 | 0.732815101786507 + value1 | atan +--------+---------------------- + 3.3 | -1.1606689862534056 + 2.2 | -0.8760580505981935 + 1.1 | -0.09966865249116212 + 0.3 | 0.6107259643892086 + 0.2 | 0.6747409422235527 + 0.1 | 0.7328151017865066 (6 rows) -- select atan with order by index (result) --Testcase 668: SELECT (fields->>'value1')::float value1, atan(1-(fields->>'value1')::float) FROM s3 order by 2,1; - value1 | atan ---------+--------------------- - 3.3 | -1.16066898625341 - 2.2 | -0.876058050598194 - 1.1 | -0.0996686524911621 - 0.3 | 0.610725964389209 - 0.2 | 0.674740942223553 - 0.1 | 0.732815101786507 + value1 | atan +--------+---------------------- + 3.3 | -1.1606689862534056 + 2.2 | -0.8760580505981935 + 1.1 | -0.09966865249116212 + 0.3 | 0.6107259643892086 + 0.2 | 0.6747409422235527 + 0.1 | 0.7328151017865066 (6 rows) -- select atan with order by index (result) --Testcase 669: SELECT (fields->>'value1')::float value1, atan(1-(fields->>'value1')::float) FROM s3 order by 1,2; - value1 | atan ---------+--------------------- - 0.1 | 0.732815101786507 - 0.2 | 0.674740942223553 - 0.3 | 0.610725964389209 - 1.1 | -0.0996686524911621 - 2.2 | -0.876058050598194 - 3.3 | -1.16066898625341 + value1 | atan +--------+---------------------- + 0.1 | 0.7328151017865066 + 0.2 | 0.6747409422235527 + 0.3 | 0.6107259643892086 + 1.1 | -0.09966865249116212 + 2.2 | -0.8760580505981935 + 3.3 | -1.1606689862534056 (6 rows) -- select atan and as --Testcase 670: SELECT atan((fields->>'value3')::float) as atan1 FROM s3; - atan1 --------------------- - -0.099668652491162 - -0.197395559849881 - -0.291456794477867 - -0.832981266674432 - -1.14416883366802 - -1.27656176168371 + atan1 +---------------------- + -0.09966865249116204 + -0.19739555984988078 + -0.2914567944778671 + -0.8329812666744317 + -1.1441688336680205 + -1.2765617616837088 (6 rows) -- select atan(*) (stub agg function, explain) @@ -6517,14 +6525,14 @@ SELECT atan2((fields->>'value1')::float, (fields->>'value2')::bigint), atan2((fi -- select atan2 (builtin function, result) --Testcase 678: SELECT atan2((fields->>'value1')::float, (fields->>'value2')::bigint), atan2((fields->>'value2')::bigint, (fields->>'value3')::float), atan2((fields->>'value3')::float, (fields->>'value4')::bigint), atan2((fields->>'value4')::bigint, (fields->>'value1')::float) FROM s3; - atan2 | atan2 | atan2 | atan2 -----------------------+------------------+-------------------+------------------- - 0.000999999666666867 | 1.57179632646156 | -3.14059265392313 | -1.56979632712823 - 0.00199999733333973 | 1.57279632412824 | -3.13959265625645 | -1.56879632946156 - 0.0029999910000486 | 1.57379631779495 | -3.13859266258974 | -1.56779633579485 - 0.00549994454267321 | 1.57629627133757 | -3.13609270904712 | -1.56529638225222 - 0.0109995563655408 | 1.58179588316044 | -3.13059309722425 | -1.55979677042936 - 0.0164985028695487 | 1.58729482966445 | -3.12509415072024 | -1.55429782392535 + atan2 | atan2 | atan2 | atan2 +-----------------------+--------------------+---------------------+--------------------- + 0.0009999996666668668 | 1.5717963264615635 | -3.1405926539231266 | -1.5697963271282298 + 0.0019999973333397333 | 1.5727963241282363 | -3.1395926562564536 | -1.5687963294615568 + 0.0029999910000485996 | 1.5737963177949452 | -3.1385926625897445 | -1.5677963357948481 + 0.005499944542673214 | 1.5762962713375699 | -3.1360927090471202 | -1.5652963822522235 + 0.010999556365540751 | 1.5817958831604373 | -3.1305930972242524 | -1.5597967704293558 + 0.01649850286954865 | 1.5872948296644454 | -3.1250941507202445 | -1.554297823925348 (6 rows) -- select atan2 (builtin function, not pushdown constraints, explain) @@ -6542,11 +6550,11 @@ SELECT atan2((fields->>'value1')::float, (fields->>'value2')::bigint), atan2((fi -- select atan2 (builtin function, not pushdown constraints, result) --Testcase 680: SELECT atan2((fields->>'value1')::float, (fields->>'value2')::bigint), atan2((fields->>'value2')::bigint, (fields->>'value3')::float), atan2((fields->>'value3')::float, (fields->>'value4')::bigint), atan2((fields->>'value4')::bigint, (fields->>'value1')::float) FROM s3 WHERE to_hex((fields->>'value2')::bigint) != '64'; - atan2 | atan2 | atan2 | atan2 ----------------------+------------------+-------------------+------------------- - 0.00549994454267321 | 1.57629627133757 | -3.13609270904712 | -1.56529638225222 - 0.0109995563655408 | 1.58179588316044 | -3.13059309722425 | -1.55979677042936 - 0.0164985028695487 | 1.58729482966445 | -3.12509415072024 | -1.55429782392535 + atan2 | atan2 | atan2 | atan2 +----------------------+--------------------+---------------------+--------------------- + 0.005499944542673214 | 1.5762962713375699 | -3.1360927090471202 | -1.5652963822522235 + 0.010999556365540751 | 1.5817958831604373 | -3.1305930972242524 | -1.5597967704293558 + 0.01649850286954865 | 1.5872948296644454 | -3.1250941507202445 | -1.554297823925348 (3 rows) -- select atan2 (builtin function, pushdown constraints, explain) @@ -6563,11 +6571,11 @@ SELECT atan2((fields->>'value1')::float, (fields->>'value2')::bigint), atan2((fi -- select atan2 (builtin function, pushdown constraints, result) --Testcase 682: SELECT atan2((fields->>'value1')::float, (fields->>'value2')::bigint), atan2((fields->>'value2')::bigint, (fields->>'value3')::float), atan2((fields->>'value3')::float, (fields->>'value4')::bigint), atan2((fields->>'value4')::bigint, (fields->>'value1')::float) FROM s3 WHERE (fields->>'value2')::bigint != 200; - atan2 | atan2 | atan2 | atan2 -----------------------+------------------+-------------------+------------------- - 0.000999999666666867 | 1.57179632646156 | -3.14059265392313 | -1.56979632712823 - 0.00199999733333973 | 1.57279632412824 | -3.13959265625645 | -1.56879632946156 - 0.0029999910000486 | 1.57379631779495 | -3.13859266258974 | -1.56779633579485 + atan2 | atan2 | atan2 | atan2 +-----------------------+--------------------+---------------------+--------------------- + 0.0009999996666668668 | 1.5717963264615635 | -3.1405926539231266 | -1.5697963271282298 + 0.0019999973333397333 | 1.5727963241282363 | -3.1395926562564536 | -1.5687963294615568 + 0.0029999910000485996 | 1.5737963177949452 | -3.1385926625897445 | -1.5677963357948481 (3 rows) -- select atan2 as nest function with agg (pushdown, explain) @@ -6584,9 +6592,9 @@ SELECT sum((fields->>'value3')::float), sum((fields->>'value4')::bigint),atan2(s -- select atan2 as nest function with agg (pushdown, result) --Testcase 684: SELECT sum((fields->>'value3')::float), sum((fields->>'value4')::bigint),atan2(sum((fields->>'value3')::float), sum((fields->>'value3')::float)) FROM s3; - sum | sum | atan2 -------+------+------------------- - -7.2 | -900 | -2.35619449019234 + sum | sum | atan2 +--------------------+------+-------------------- + -7.199999999999999 | -900 | -2.356194490192345 (1 row) -- select atan2 as nest with log2 (pushdown, explain) @@ -6609,24 +6617,24 @@ CONTEXT: PL/pgSQL function log2(double precision) line 3 at RAISE --Testcase 687: EXPLAIN VERBOSE SELECT atan2((fields->>'value3')::float, (fields->>'value4')::bigint), pi(), 4.1 FROM s3; - QUERY PLAN ------------------------------------------------------------------------------------------------------------------------------------------------------------------------- + QUERY PLAN +------------------------------------------------------------------------------------------------------------------------------------------------------------------------- Foreign Scan on public.s3 (cost=10.00..1491.24 rows=1462 width=48) - Output: atan2(((fields ->> 'value3'::text))::double precision, (((fields ->> 'value4'::text))::bigint)::double precision), '3.14159265358979'::double precision, 4.1 + Output: atan2(((fields ->> 'value3'::text))::double precision, (((fields ->> 'value4'::text))::bigint)::double precision), '3.141592653589793'::double precision, 4.1 InfluxDB query: SELECT "value3", "value4" FROM "s3" (3 rows) -- select atan2 with non pushdown func and explicit constant (result) --Testcase 688: SELECT atan2((fields->>'value3')::float, (fields->>'value4')::bigint), pi(), 4.1 FROM s3; - atan2 | pi | ?column? --------------------+------------------+---------- - -3.14059265392313 | 3.14159265358979 | 4.1 - -3.13959265625645 | 3.14159265358979 | 4.1 - -3.13859266258974 | 3.14159265358979 | 4.1 - -3.13609270904712 | 3.14159265358979 | 4.1 - -3.13059309722425 | 3.14159265358979 | 4.1 - -3.12509415072024 | 3.14159265358979 | 4.1 + atan2 | pi | ?column? +---------------------+-------------------+---------- + -3.1405926539231266 | 3.141592653589793 | 4.1 + -3.1395926562564536 | 3.141592653589793 | 4.1 + -3.1385926625897445 | 3.141592653589793 | 4.1 + -3.1360927090471202 | 3.141592653589793 | 4.1 + -3.1305930972242524 | 3.141592653589793 | 4.1 + -3.1250941507202445 | 3.141592653589793 | 4.1 (6 rows) -- select atan2 with order by (explain) @@ -6646,53 +6654,53 @@ SELECT (fields->>'value1')::float value1, atan2(1-(fields->>'value1')::float, 1- -- select atan2 with order by (result) --Testcase 690: SELECT (fields->>'value1')::float value1, atan2(1-(fields->>'value1')::float, 1-(fields->>'value2')::bigint) FROM s3 order by atan2(1-(fields->>'value1')::float, 1-(fields->>'value2')::bigint); - value1 | atan2 ---------+------------------- - 1.1 | -3.14109014106928 - 2.2 | -3.13556257592532 - 3.3 | -3.13003537924322 - 0.1 | 3.13250199492473 - 0.2 | 3.13351202139289 - 0.3 | 3.13452206434865 + value1 | atan2 +--------+--------------------- + 1.1 | -3.1410901410692773 + 2.2 | -3.1355625759253205 + 3.3 | -3.130035379243216 + 0.1 | 3.1325019949247332 + 0.2 | 3.1335120213928933 + 0.3 | 3.1345220643486456 (6 rows) -- select atan2 with order by index (result) --Testcase 691: SELECT (fields->>'value1')::float value1, atan2(1-(fields->>'value1')::float, 1-(fields->>'value2')::bigint) FROM s3 order by 2,1; - value1 | atan2 ---------+------------------- - 1.1 | -3.14109014106928 - 2.2 | -3.13556257592532 - 3.3 | -3.13003537924322 - 0.1 | 3.13250199492473 - 0.2 | 3.13351202139289 - 0.3 | 3.13452206434865 + value1 | atan2 +--------+--------------------- + 1.1 | -3.1410901410692773 + 2.2 | -3.1355625759253205 + 3.3 | -3.130035379243216 + 0.1 | 3.1325019949247332 + 0.2 | 3.1335120213928933 + 0.3 | 3.1345220643486456 (6 rows) -- select atan2 with order by index (result) --Testcase 692: SELECT (fields->>'value1')::float value1, atan2(1-(fields->>'value1')::float, 1-(fields->>'value2')::bigint) FROM s3 order by 1,2; - value1 | atan2 ---------+------------------- - 0.1 | 3.13250199492473 - 0.2 | 3.13351202139289 - 0.3 | 3.13452206434865 - 1.1 | -3.14109014106928 - 2.2 | -3.13556257592532 - 3.3 | -3.13003537924322 + value1 | atan2 +--------+--------------------- + 0.1 | 3.1325019949247332 + 0.2 | 3.1335120213928933 + 0.3 | 3.1345220643486456 + 1.1 | -3.1410901410692773 + 2.2 | -3.1355625759253205 + 3.3 | -3.130035379243216 (6 rows) -- select atan2 and as --Testcase 693: SELECT atan2((fields->>'value3')::float, (fields->>'value4')::bigint) as atan21 FROM s3; - atan21 -------------------- - -3.14059265392313 - -3.13959265625645 - -3.13859266258974 - -3.13609270904712 - -3.13059309722425 - -3.12509415072024 + atan21 +--------------------- + -3.1405926539231266 + -3.1395926562564536 + -3.1385926625897445 + -3.1360927090471202 + -3.1305930972242524 + -3.1250941507202445 (6 rows) -- select atan2(*) (stub function, explain) @@ -6792,9 +6800,9 @@ SELECT sum((fields->>'value3')::float),ceil(sum((fields->>'value3')::float)) FRO -- select ceil as nest function with agg (pushdown, result) --Testcase 703: SELECT sum((fields->>'value3')::float),ceil(sum((fields->>'value3')::float)) FROM s3; - sum | ceil -------+------ - -7.2 | -7 + sum | ceil +--------------------+------ + -7.199999999999999 | -7 (1 row) -- select ceil as nest with log2 (pushdown, explain) @@ -6817,24 +6825,24 @@ CONTEXT: PL/pgSQL function log2(double precision) line 3 at RAISE --Testcase 706: EXPLAIN VERBOSE SELECT ceil((fields->>'value3')::float), pi(), 4.1 FROM s3; - QUERY PLAN ------------------------------------------------------------------------------------------------------------- + QUERY PLAN +------------------------------------------------------------------------------------------------------------- Foreign Scan on public.s3 (cost=10.00..1476.62 rows=1462 width=48) - Output: ceil(((fields ->> 'value3'::text))::double precision), '3.14159265358979'::double precision, 4.1 + Output: ceil(((fields ->> 'value3'::text))::double precision), '3.141592653589793'::double precision, 4.1 InfluxDB query: SELECT "value3" FROM "s3" (3 rows) -- select ceil with non pushdown func and explicit constant (result) --Testcase 707: SELECT ceil((fields->>'value3')::float), pi(), 4.1 FROM s3; - ceil | pi | ?column? -------+------------------+---------- - -0 | 3.14159265358979 | 4.1 - -0 | 3.14159265358979 | 4.1 - -0 | 3.14159265358979 | 4.1 - -1 | 3.14159265358979 | 4.1 - -2 | 3.14159265358979 | 4.1 - -3 | 3.14159265358979 | 4.1 + ceil | pi | ?column? +------+-------------------+---------- + -0 | 3.141592653589793 | 4.1 + -0 | 3.141592653589793 | 4.1 + -0 | 3.141592653589793 | 4.1 + -1 | 3.141592653589793 | 4.1 + -2 | 3.141592653589793 | 4.1 + -3 | 3.141592653589793 | 4.1 (6 rows) -- select ceil with order by (explain) @@ -6972,14 +6980,14 @@ SELECT cos((fields->>'value1')::float), cos((fields->>'value2')::bigint), cos((f -- select cos (builtin function, result) --Testcase 720: SELECT cos((fields->>'value1')::float), cos((fields->>'value2')::bigint), cos((fields->>'value3')::float), cos((fields->>'value4')::bigint) FROM s3; - cos | cos | cos | cos ---------------------+-------------------+--------------------+------------------- - 0.995004165278026 | 0.862318872287684 | 0.995004165278026 | 0.862318872287684 - 0.980066577841242 | 0.862318872287684 | 0.980066577841242 | 0.862318872287684 - 0.955336489125606 | 0.862318872287684 | 0.955336489125606 | 0.862318872287684 - 0.453596121425577 | 0.487187675007006 | 0.453596121425577 | 0.487187675007006 - -0.588501117255346 | 0.487187675007006 | -0.588501117255346 | 0.487187675007006 - -0.987479769908865 | 0.487187675007006 | -0.987479769908865 | 0.487187675007006 + cos | cos | cos | cos +---------------------+---------------------+---------------------+--------------------- + 0.9950041652780258 | 0.8623188722876839 | 0.9950041652780258 | 0.8623188722876839 + 0.9800665778412416 | 0.8623188722876839 | 0.9800665778412416 | 0.8623188722876839 + 0.955336489125606 | 0.8623188722876839 | 0.955336489125606 | 0.8623188722876839 + 0.4535961214255773 | 0.48718767500700594 | 0.4535961214255773 | 0.48718767500700594 + -0.5885011172553458 | 0.48718767500700594 | -0.5885011172553458 | 0.48718767500700594 + -0.9874797699088649 | 0.48718767500700594 | -0.9874797699088649 | 0.48718767500700594 (6 rows) -- select cos (builtin function, not pushdown constraints, explain) @@ -6997,11 +7005,11 @@ SELECT cos((fields->>'value1')::float), cos((fields->>'value2')::bigint), cos((f -- select cos (builtin function, not pushdown constraints, result) --Testcase 722: SELECT cos((fields->>'value1')::float), cos((fields->>'value2')::bigint), cos((fields->>'value3')::float), cos((fields->>'value4')::bigint) FROM s3 WHERE to_hex((fields->>'value2')::bigint) != '64'; - cos | cos | cos | cos ---------------------+-------------------+--------------------+------------------- - 0.453596121425577 | 0.487187675007006 | 0.453596121425577 | 0.487187675007006 - -0.588501117255346 | 0.487187675007006 | -0.588501117255346 | 0.487187675007006 - -0.987479769908865 | 0.487187675007006 | -0.987479769908865 | 0.487187675007006 + cos | cos | cos | cos +---------------------+---------------------+---------------------+--------------------- + 0.4535961214255773 | 0.48718767500700594 | 0.4535961214255773 | 0.48718767500700594 + -0.5885011172553458 | 0.48718767500700594 | -0.5885011172553458 | 0.48718767500700594 + -0.9874797699088649 | 0.48718767500700594 | -0.9874797699088649 | 0.48718767500700594 (3 rows) -- select cos (builtin function, pushdown constraints, explain) @@ -7018,11 +7026,11 @@ SELECT cos((fields->>'value1')::float), cos((fields->>'value2')::bigint), cos((f -- select cos (builtin function, pushdown constraints, result) --Testcase 724: SELECT cos((fields->>'value1')::float), cos((fields->>'value2')::bigint), cos((fields->>'value3')::float), cos((fields->>'value4')::bigint) FROM s3 WHERE (fields->>'value2')::bigint != 200; - cos | cos | cos | cos --------------------+-------------------+-------------------+------------------- - 0.995004165278026 | 0.862318872287684 | 0.995004165278026 | 0.862318872287684 - 0.980066577841242 | 0.862318872287684 | 0.980066577841242 | 0.862318872287684 - 0.955336489125606 | 0.862318872287684 | 0.955336489125606 | 0.862318872287684 + cos | cos | cos | cos +--------------------+--------------------+--------------------+-------------------- + 0.9950041652780258 | 0.8623188722876839 | 0.9950041652780258 | 0.8623188722876839 + 0.9800665778412416 | 0.8623188722876839 | 0.9800665778412416 | 0.8623188722876839 + 0.955336489125606 | 0.8623188722876839 | 0.955336489125606 | 0.8623188722876839 (3 rows) -- select cos as nest function with agg (pushdown, explain) @@ -7039,9 +7047,9 @@ SELECT sum((fields->>'value3')::float),cos(sum((fields->>'value3')::float)) FROM -- select cos as nest function with agg (pushdown, result) --Testcase 726: SELECT sum((fields->>'value3')::float),cos(sum((fields->>'value3')::float)) FROM s3; - sum | cos -------+------------------- - -7.2 | 0.608351314532255 + sum | cos +--------------------+-------------------- + -7.199999999999999 | 0.6083513145322552 (1 row) -- select cos as nest with log2 (pushdown, explain) @@ -7064,24 +7072,24 @@ CONTEXT: PL/pgSQL function log2(double precision) line 3 at RAISE --Testcase 729: EXPLAIN VERBOSE SELECT cos((fields->>'value3')::float), pi(), 4.1 FROM s3; - QUERY PLAN ------------------------------------------------------------------------------------------------------------ + QUERY PLAN +------------------------------------------------------------------------------------------------------------ Foreign Scan on public.s3 (cost=10.00..1476.62 rows=1462 width=48) - Output: cos(((fields ->> 'value3'::text))::double precision), '3.14159265358979'::double precision, 4.1 + Output: cos(((fields ->> 'value3'::text))::double precision), '3.141592653589793'::double precision, 4.1 InfluxDB query: SELECT "value3" FROM "s3" (3 rows) -- select cos with non pushdown func and explicit constant (result) --Testcase 730: SELECT cos((fields->>'value3')::float), pi(), 4.1 FROM s3; - cos | pi | ?column? ---------------------+------------------+---------- - 0.995004165278026 | 3.14159265358979 | 4.1 - 0.980066577841242 | 3.14159265358979 | 4.1 - 0.955336489125606 | 3.14159265358979 | 4.1 - 0.453596121425577 | 3.14159265358979 | 4.1 - -0.588501117255346 | 3.14159265358979 | 4.1 - -0.987479769908865 | 3.14159265358979 | 4.1 + cos | pi | ?column? +---------------------+-------------------+---------- + 0.9950041652780258 | 3.141592653589793 | 4.1 + 0.9800665778412416 | 3.141592653589793 | 4.1 + 0.955336489125606 | 3.141592653589793 | 4.1 + 0.4535961214255773 | 3.141592653589793 | 4.1 + -0.5885011172553458 | 3.141592653589793 | 4.1 + -0.9874797699088649 | 3.141592653589793 | 4.1 (6 rows) -- select cos with order by (explain) @@ -7101,53 +7109,53 @@ SELECT (fields->>'value1')::float value1, cos(1-(fields->>'value1')::float) FROM -- select cos with order by (result) --Testcase 732: SELECT (fields->>'value1')::float value1, cos(1-(fields->>'value1')::float) FROM s3 order by cos(1-(fields->>'value1')::float); - value1 | cos ---------+-------------------- - 3.3 | -0.666276021279824 - 2.2 | 0.362357754476673 - 0.1 | 0.621609968270664 - 0.2 | 0.696706709347165 - 0.3 | 0.764842187284488 - 1.1 | 0.995004165278026 + value1 | cos +--------+--------------------- + 3.3 | -0.6662760212798241 + 2.2 | 0.3623577544766734 + 0.1 | 0.6216099682706644 + 0.2 | 0.6967067093471654 + 0.3 | 0.7648421872844885 + 1.1 | 0.9950041652780257 (6 rows) -- select cos with order by index (result) --Testcase 733: SELECT (fields->>'value1')::float value1, cos(1-(fields->>'value1')::float) FROM s3 order by 2,1; - value1 | cos ---------+-------------------- - 3.3 | -0.666276021279824 - 2.2 | 0.362357754476673 - 0.1 | 0.621609968270664 - 0.2 | 0.696706709347165 - 0.3 | 0.764842187284488 - 1.1 | 0.995004165278026 + value1 | cos +--------+--------------------- + 3.3 | -0.6662760212798241 + 2.2 | 0.3623577544766734 + 0.1 | 0.6216099682706644 + 0.2 | 0.6967067093471654 + 0.3 | 0.7648421872844885 + 1.1 | 0.9950041652780257 (6 rows) -- select cos with order by index (result) --Testcase 734: SELECT (fields->>'value1')::float value1, cos(1-(fields->>'value1')::float) FROM s3 order by 1,2; - value1 | cos ---------+-------------------- - 0.1 | 0.621609968270664 - 0.2 | 0.696706709347165 - 0.3 | 0.764842187284488 - 1.1 | 0.995004165278026 - 2.2 | 0.362357754476673 - 3.3 | -0.666276021279824 + value1 | cos +--------+--------------------- + 0.1 | 0.6216099682706644 + 0.2 | 0.6967067093471654 + 0.3 | 0.7648421872844885 + 1.1 | 0.9950041652780257 + 2.2 | 0.3623577544766734 + 3.3 | -0.6662760212798241 (6 rows) -- select cos and as --Testcase 735: SELECT cos((fields->>'value3')::float) as cos1 FROM s3; - cos1 --------------------- - 0.995004165278026 - 0.980066577841242 - 0.955336489125606 - 0.453596121425577 - -0.588501117255346 - -0.987479769908865 + cos1 +--------------------- + 0.9950041652780258 + 0.9800665778412416 + 0.955336489125606 + 0.4535961214255773 + -0.5885011172553458 + -0.9874797699088649 (6 rows) -- select cos(*) (stub agg function, explain) @@ -7203,14 +7211,14 @@ SELECT exp((fields->>'value1')::float), exp((fields->>'value2')::bigint), exp((f -- select exp (builtin function, result) --Testcase 741: SELECT exp((fields->>'value1')::float), exp((fields->>'value2')::bigint), exp((fields->>'value3')::float), exp((fields->>'value4')::bigint) FROM s3; - exp | exp | exp | exp -------------------+----------------------+-------------------+---------------------- - 1.10517091807565 | 2.68811714181614e+43 | 0.90483741803596 | 3.72007597602084e-44 - 1.22140275816017 | 2.68811714181614e+43 | 0.818730753077982 | 3.72007597602084e-44 - 1.349858807576 | 2.68811714181614e+43 | 0.740818220681718 | 3.72007597602084e-44 - 3.00416602394643 | 7.22597376812575e+86 | 0.33287108369808 | 1.38389652673674e-87 - 9.02501349943412 | 7.22597376812575e+86 | 0.110803158362334 | 1.38389652673674e-87 - 27.1126389206579 | 7.22597376812575e+86 | 0.03688316740124 | 1.38389652673674e-87 + exp | exp | exp | exp +--------------------+------------------------+----------------------+------------------------ + 1.1051709180756477 | 2.6881171418161356e+43 | 0.9048374180359595 | 3.720075976020836e-44 + 1.2214027581601699 | 2.6881171418161356e+43 | 0.8187307530779818 | 3.720075976020836e-44 + 1.3498588075760032 | 2.6881171418161356e+43 | 0.7408182206817179 | 3.720075976020836e-44 + 3.0041660239464334 | 7.225973768125749e+86 | 0.33287108369807955 | 1.3838965267367376e-87 + 9.025013499434122 | 7.225973768125749e+86 | 0.11080315836233387 | 1.3838965267367376e-87 + 27.112638920657883 | 7.225973768125749e+86 | 0.036883167401240015 | 1.3838965267367376e-87 (6 rows) -- select exp (builtin function, not pushdown constraints, explain) @@ -7228,11 +7236,11 @@ SELECT exp((fields->>'value1')::float), exp((fields->>'value2')::bigint), exp((f -- select exp (builtin function, not pushdown constraints, result) --Testcase 743: SELECT exp((fields->>'value1')::float), exp((fields->>'value2')::bigint), exp((fields->>'value3')::float), exp((fields->>'value4')::bigint) FROM s3 WHERE to_hex((fields->>'value2')::bigint) != '64'; - exp | exp | exp | exp -------------------+----------------------+-------------------+---------------------- - 3.00416602394643 | 7.22597376812575e+86 | 0.33287108369808 | 1.38389652673674e-87 - 9.02501349943412 | 7.22597376812575e+86 | 0.110803158362334 | 1.38389652673674e-87 - 27.1126389206579 | 7.22597376812575e+86 | 0.03688316740124 | 1.38389652673674e-87 + exp | exp | exp | exp +--------------------+-----------------------+----------------------+------------------------ + 3.0041660239464334 | 7.225973768125749e+86 | 0.33287108369807955 | 1.3838965267367376e-87 + 9.025013499434122 | 7.225973768125749e+86 | 0.11080315836233387 | 1.3838965267367376e-87 + 27.112638920657883 | 7.225973768125749e+86 | 0.036883167401240015 | 1.3838965267367376e-87 (3 rows) -- select exp (builtin function, pushdown constraints, explain) @@ -7249,11 +7257,11 @@ SELECT exp((fields->>'value1')::float), exp((fields->>'value2')::bigint), exp((f -- select exp (builtin function, pushdown constraints, result) --Testcase 745: SELECT exp((fields->>'value1')::float), exp((fields->>'value2')::bigint), exp((fields->>'value3')::float), exp((fields->>'value4')::bigint) FROM s3 WHERE (fields->>'value2')::bigint != 200; - exp | exp | exp | exp -------------------+----------------------+-------------------+---------------------- - 1.10517091807565 | 2.68811714181614e+43 | 0.90483741803596 | 3.72007597602084e-44 - 1.22140275816017 | 2.68811714181614e+43 | 0.818730753077982 | 3.72007597602084e-44 - 1.349858807576 | 2.68811714181614e+43 | 0.740818220681718 | 3.72007597602084e-44 + exp | exp | exp | exp +--------------------+------------------------+--------------------+----------------------- + 1.1051709180756477 | 2.6881171418161356e+43 | 0.9048374180359595 | 3.720075976020836e-44 + 1.2214027581601699 | 2.6881171418161356e+43 | 0.8187307530779818 | 3.720075976020836e-44 + 1.3498588075760032 | 2.6881171418161356e+43 | 0.7408182206817179 | 3.720075976020836e-44 (3 rows) -- select exp as nest function with agg (pushdown, explain) @@ -7270,9 +7278,9 @@ SELECT sum((fields->>'value3')::float),exp(sum((fields->>'value3')::float)) FROM -- select exp as nest function with agg (pushdown, result) --Testcase 747: SELECT sum((fields->>'value3')::float),exp(sum((fields->>'value3')::float)) FROM s3; - sum | exp -------+--------------------- - -7.2 | 0.00074658580837668 + sum | exp +--------------------+----------------------- + -7.199999999999999 | 0.0007465858083766799 (1 row) -- select exp as nest with log2 (pushdown, explain) @@ -7295,24 +7303,24 @@ CONTEXT: PL/pgSQL function log2(double precision) line 3 at RAISE --Testcase 750: EXPLAIN VERBOSE SELECT exp((fields->>'value3')::float), pi(), 4.1 FROM s3; - QUERY PLAN ------------------------------------------------------------------------------------------------------------ + QUERY PLAN +------------------------------------------------------------------------------------------------------------ Foreign Scan on public.s3 (cost=10.00..1476.62 rows=1462 width=48) - Output: exp(((fields ->> 'value3'::text))::double precision), '3.14159265358979'::double precision, 4.1 + Output: exp(((fields ->> 'value3'::text))::double precision), '3.141592653589793'::double precision, 4.1 InfluxDB query: SELECT "value3" FROM "s3" (3 rows) -- select exp with non pushdown func and explicit constant (result) --Testcase 751: SELECT exp((fields->>'value3')::float), pi(), 4.1 FROM s3; - exp | pi | ?column? --------------------+------------------+---------- - 0.90483741803596 | 3.14159265358979 | 4.1 - 0.818730753077982 | 3.14159265358979 | 4.1 - 0.740818220681718 | 3.14159265358979 | 4.1 - 0.33287108369808 | 3.14159265358979 | 4.1 - 0.110803158362334 | 3.14159265358979 | 4.1 - 0.03688316740124 | 3.14159265358979 | 4.1 + exp | pi | ?column? +----------------------+-------------------+---------- + 0.9048374180359595 | 3.141592653589793 | 4.1 + 0.8187307530779818 | 3.141592653589793 | 4.1 + 0.7408182206817179 | 3.141592653589793 | 4.1 + 0.33287108369807955 | 3.141592653589793 | 4.1 + 0.11080315836233387 | 3.141592653589793 | 4.1 + 0.036883167401240015 | 3.141592653589793 | 4.1 (6 rows) -- select exp with order by (explain) @@ -7332,53 +7340,53 @@ SELECT (fields->>'value1')::float value1, exp(1-(fields->>'value1')::float) FROM -- select exp with order by (result) --Testcase 753: SELECT (fields->>'value1')::float value1, exp(1-(fields->>'value1')::float) FROM s3 order by exp(1-(fields->>'value1')::float); - value1 | exp ---------+------------------- - 3.3 | 0.100258843722804 - 2.2 | 0.301194211912202 - 1.1 | 0.90483741803596 - 0.3 | 2.01375270747048 - 0.2 | 2.22554092849247 - 0.1 | 2.45960311115695 + value1 | exp +--------+--------------------- + 3.3 | 0.10025884372280375 + 2.2 | 0.301194211912202 + 1.1 | 0.9048374180359595 + 0.3 | 2.0137527074704766 + 0.2 | 2.225540928492468 + 0.1 | 2.45960311115695 (6 rows) -- select exp with order by index (result) --Testcase 754: SELECT (fields->>'value1')::float value1, exp(1-(fields->>'value1')::float) FROM s3 order by 2,1; - value1 | exp ---------+------------------- - 3.3 | 0.100258843722804 - 2.2 | 0.301194211912202 - 1.1 | 0.90483741803596 - 0.3 | 2.01375270747048 - 0.2 | 2.22554092849247 - 0.1 | 2.45960311115695 + value1 | exp +--------+--------------------- + 3.3 | 0.10025884372280375 + 2.2 | 0.301194211912202 + 1.1 | 0.9048374180359595 + 0.3 | 2.0137527074704766 + 0.2 | 2.225540928492468 + 0.1 | 2.45960311115695 (6 rows) -- select exp with order by index (result) --Testcase 755: SELECT (fields->>'value1')::float value1, exp(1-(fields->>'value1')::float) FROM s3 order by 1,2; - value1 | exp ---------+------------------- - 0.1 | 2.45960311115695 - 0.2 | 2.22554092849247 - 0.3 | 2.01375270747048 - 1.1 | 0.90483741803596 - 2.2 | 0.301194211912202 - 3.3 | 0.100258843722804 + value1 | exp +--------+--------------------- + 0.1 | 2.45960311115695 + 0.2 | 2.225540928492468 + 0.3 | 2.0137527074704766 + 1.1 | 0.9048374180359595 + 2.2 | 0.301194211912202 + 3.3 | 0.10025884372280375 (6 rows) -- select exp and as --Testcase 756: SELECT exp((fields->>'value3')::float) as exp1 FROM s3; - exp1 -------------------- - 0.90483741803596 - 0.818730753077982 - 0.740818220681718 - 0.33287108369808 - 0.110803158362334 - 0.03688316740124 + exp1 +---------------------- + 0.9048374180359595 + 0.8187307530779818 + 0.7408182206817179 + 0.33287108369807955 + 0.11080315836233387 + 0.036883167401240015 (6 rows) -- select exp(*) (stub agg function, explain) @@ -7506,9 +7514,9 @@ SELECT sum((fields->>'value3')::float),floor(sum((fields->>'value3')::float)) FR -- select floor as nest function with agg (pushdown, result) --Testcase 769: SELECT sum((fields->>'value3')::float),floor(sum((fields->>'value3')::float)) FROM s3; - sum | floor -------+------- - -7.2 | -8 + sum | floor +--------------------+------- + -7.199999999999999 | -8 (1 row) -- select floor as nest with log2 (pushdown, explain) @@ -7531,24 +7539,24 @@ CONTEXT: PL/pgSQL function log2(double precision) line 3 at RAISE --Testcase 772: EXPLAIN VERBOSE SELECT floor((fields->>'value3')::float), pi(), 4.1 FROM s3; - QUERY PLAN -------------------------------------------------------------------------------------------------------------- + QUERY PLAN +-------------------------------------------------------------------------------------------------------------- Foreign Scan on public.s3 (cost=10.00..1476.62 rows=1462 width=48) - Output: floor(((fields ->> 'value3'::text))::double precision), '3.14159265358979'::double precision, 4.1 + Output: floor(((fields ->> 'value3'::text))::double precision), '3.141592653589793'::double precision, 4.1 InfluxDB query: SELECT "value3" FROM "s3" (3 rows) -- select floor with non pushdown func and explicit constant (result) --Testcase 773: SELECT floor((fields->>'value3')::float), pi(), 4.1 FROM s3; - floor | pi | ?column? --------+------------------+---------- - -1 | 3.14159265358979 | 4.1 - -1 | 3.14159265358979 | 4.1 - -1 | 3.14159265358979 | 4.1 - -2 | 3.14159265358979 | 4.1 - -3 | 3.14159265358979 | 4.1 - -4 | 3.14159265358979 | 4.1 + floor | pi | ?column? +-------+-------------------+---------- + -1 | 3.141592653589793 | 4.1 + -1 | 3.141592653589793 | 4.1 + -1 | 3.141592653589793 | 4.1 + -2 | 3.141592653589793 | 4.1 + -3 | 3.141592653589793 | 4.1 + -4 | 3.141592653589793 | 4.1 (6 rows) -- select floor with order by (explain) @@ -7686,14 +7694,14 @@ SELECT ln((fields->>'value1')::float), ln((fields->>'value2')::bigint) FROM s3; -- select ln (builtin function, result) --Testcase 786: SELECT ln((fields->>'value1')::float), ln((fields->>'value2')::bigint) FROM s3; - ln | ln ---------------------+------------------ - -2.30258509299405 | 4.60517018598809 - -1.6094379124341 | 4.60517018598809 - -1.20397280432594 | 4.60517018598809 - 0.0953101798043249 | 5.29831736654804 - 0.78845736036427 | 5.29831736654804 - 1.19392246847243 | 5.29831736654804 + ln | ln +---------------------+------------------- + -2.3025850929940455 | 4.605170185988092 + -1.6094379124341003 | 4.605170185988092 + -1.2039728043259361 | 4.605170185988092 + 0.09531017980432493 | 5.298317366548036 + 0.7884573603642703 | 5.298317366548036 + 1.1939224684724346 | 5.298317366548036 (6 rows) -- select ln (builtin function, not pushdown constraints, explain) @@ -7711,11 +7719,11 @@ SELECT ln((fields->>'value1')::float), ln((fields->>'value2')::bigint) FROM s3 W -- select ln (builtin function, not pushdown constraints, result) --Testcase 788: SELECT ln((fields->>'value1')::float), ln((fields->>'value2')::bigint) FROM s3 WHERE to_hex((fields->>'value2')::bigint) != '64'; - ln | ln ---------------------+------------------ - 0.0953101798043249 | 5.29831736654804 - 0.78845736036427 | 5.29831736654804 - 1.19392246847243 | 5.29831736654804 + ln | ln +---------------------+------------------- + 0.09531017980432493 | 5.298317366548036 + 0.7884573603642703 | 5.298317366548036 + 1.1939224684724346 | 5.298317366548036 (3 rows) -- select ln (builtin function, pushdown constraints, explain) @@ -7732,11 +7740,11 @@ SELECT ln((fields->>'value1')::float), ln((fields->>'value2')::bigint) FROM s3 W -- select ln (builtin function, pushdown constraints, result) --Testcase 790: SELECT ln((fields->>'value1')::float), ln((fields->>'value2')::bigint) FROM s3 WHERE (fields->>'value2')::bigint != 200; - ln | ln --------------------+------------------ - -2.30258509299405 | 4.60517018598809 - -1.6094379124341 | 4.60517018598809 - -1.20397280432594 | 4.60517018598809 + ln | ln +---------------------+------------------- + -2.3025850929940455 | 4.605170185988092 + -1.6094379124341003 | 4.605170185988092 + -1.2039728043259361 | 4.605170185988092 (3 rows) -- select ln as nest function with agg (pushdown, explain) @@ -7753,9 +7761,9 @@ SELECT sum((fields->>'value3')::float),ln(sum((fields->>'value3')::float)) FROM -- select ln as nest function with agg (pushdown, result) --Testcase 792: SELECT sum((fields->>'value3')::float),ln(sum((fields->>'value3')::float)) FROM s3; - sum | ln -------+---- - -7.2 | + sum | ln +--------------------+---- + -7.199999999999999 | (1 row) -- select ln as nest with log2 (pushdown, explain) @@ -7778,10 +7786,10 @@ CONTEXT: PL/pgSQL function log2(double precision) line 3 at RAISE --Testcase 795: EXPLAIN VERBOSE SELECT ln((fields->>'value3')::float), pi(), 4.1 FROM s3; - QUERY PLAN ----------------------------------------------------------------------------------------------------------- + QUERY PLAN +----------------------------------------------------------------------------------------------------------- Foreign Scan on public.s3 (cost=10.00..1476.62 rows=1462 width=48) - Output: ln(((fields ->> 'value3'::text))::double precision), '3.14159265358979'::double precision, 4.1 + Output: ln(((fields ->> 'value3'::text))::double precision), '3.141592653589793'::double precision, 4.1 InfluxDB query: SELECT "value3" FROM "s3" (3 rows) @@ -7818,14 +7826,14 @@ ERROR: cannot take logarithm of a negative number -- select ln and as --Testcase 801: SELECT ln((fields->>'value1')::float) as ln1 FROM s3; - ln1 --------------------- - -2.30258509299405 - -1.6094379124341 - -1.20397280432594 - 0.0953101798043249 - 0.78845736036427 - 1.19392246847243 + ln1 +--------------------- + -2.3025850929940455 + -1.6094379124341003 + -1.2039728043259361 + 0.09531017980432493 + 0.7884573603642703 + 1.1939224684724346 (6 rows) -- select ln(*) (stub agg function, explain) @@ -7886,14 +7894,14 @@ SELECT pow((fields->>'value1')::float, 2), pow((fields->>'value2')::bigint, 2), -- select pow (builtin function, result) --Testcase 808: SELECT pow((fields->>'value1')::float, 2), pow((fields->>'value2')::bigint, 2), pow((fields->>'value3')::float, 2), pow((fields->>'value4')::bigint, 2) FROM s3; - pow | pow | pow | pow --------+-------+-------+------- - 0.01 | 10000 | 0.01 | 10000 - 0.04 | 10000 | 0.04 | 10000 - 0.09 | 10000 | 0.09 | 10000 - 1.21 | 40000 | 1.21 | 40000 - 4.84 | 40000 | 4.84 | 40000 - 10.89 | 40000 | 10.89 | 40000 + pow | pow | pow | pow +----------------------+-------+----------------------+------- + 0.010000000000000002 | 10000 | 0.010000000000000002 | 10000 + 0.04000000000000001 | 10000 | 0.04000000000000001 | 10000 + 0.09 | 10000 | 0.09 | 10000 + 1.2100000000000002 | 40000 | 1.2100000000000002 | 40000 + 4.840000000000001 | 40000 | 4.840000000000001 | 40000 + 10.889999999999999 | 40000 | 10.889999999999999 | 40000 (6 rows) -- select pow (builtin function, not pushdown constraints, explain) @@ -7911,11 +7919,11 @@ SELECT pow((fields->>'value1')::float, 2), pow((fields->>'value2')::bigint, 2), -- select pow (builtin function, not pushdown constraints, result) --Testcase 810: SELECT pow((fields->>'value1')::float, 2), pow((fields->>'value2')::bigint, 2), pow((fields->>'value3')::float, 2), pow((fields->>'value4')::bigint, 2) FROM s3 WHERE to_hex((fields->>'value2')::bigint) != '64'; - pow | pow | pow | pow --------+-------+-------+------- - 1.21 | 40000 | 1.21 | 40000 - 4.84 | 40000 | 4.84 | 40000 - 10.89 | 40000 | 10.89 | 40000 + pow | pow | pow | pow +--------------------+-------+--------------------+------- + 1.2100000000000002 | 40000 | 1.2100000000000002 | 40000 + 4.840000000000001 | 40000 | 4.840000000000001 | 40000 + 10.889999999999999 | 40000 | 10.889999999999999 | 40000 (3 rows) -- select pow (builtin function, pushdown constraints, explain) @@ -7932,11 +7940,11 @@ SELECT pow((fields->>'value1')::float, 2), pow((fields->>'value2')::bigint, 2), -- select pow (builtin function, pushdown constraints, result) --Testcase 812: SELECT pow((fields->>'value1')::float, 2), pow((fields->>'value2')::bigint, 2), pow((fields->>'value3')::float, 2), pow((fields->>'value4')::bigint, 2) FROM s3 WHERE (fields->>'value2')::bigint != 200; - pow | pow | pow | pow -------+-------+------+------- - 0.01 | 10000 | 0.01 | 10000 - 0.04 | 10000 | 0.04 | 10000 - 0.09 | 10000 | 0.09 | 10000 + pow | pow | pow | pow +----------------------+-------+----------------------+------- + 0.010000000000000002 | 10000 | 0.010000000000000002 | 10000 + 0.04000000000000001 | 10000 | 0.04000000000000001 | 10000 + 0.09 | 10000 | 0.09 | 10000 (3 rows) -- select pow as nest function with agg (pushdown, explain) @@ -7953,9 +7961,9 @@ SELECT sum((fields->>'value3')::float),pow(sum((fields->>'value3')::float), 2) F -- select pow as nest function with agg (pushdown, result) --Testcase 814: SELECT sum((fields->>'value3')::float),pow(sum((fields->>'value3')::float), 2) FROM s3; - sum | pow -------+------- - -7.2 | 51.84 + sum | pow +--------------------+------------------- + -7.199999999999999 | 51.83999999999999 (1 row) -- select pow as nest with log2 (pushdown, explain) @@ -7978,24 +7986,24 @@ CONTEXT: PL/pgSQL function log2(double precision) line 3 at RAISE --Testcase 817: EXPLAIN VERBOSE SELECT pow((fields->>'value3')::float, 2), pi(), 4.1 FROM s3; - QUERY PLAN ----------------------------------------------------------------------------------------------------------------------------------- + QUERY PLAN +----------------------------------------------------------------------------------------------------------------------------------- Foreign Scan on public.s3 (cost=10.00..1476.62 rows=1462 width=48) - Output: pow(((fields ->> 'value3'::text))::double precision, '2'::double precision), '3.14159265358979'::double precision, 4.1 + Output: pow(((fields ->> 'value3'::text))::double precision, '2'::double precision), '3.141592653589793'::double precision, 4.1 InfluxDB query: SELECT "value3" FROM "s3" (3 rows) -- select pow with non pushdown func and explicit constant (result) --Testcase 818: SELECT pow((fields->>'value3')::float, 2), pi(), 4.1 FROM s3; - pow | pi | ?column? --------+------------------+---------- - 0.01 | 3.14159265358979 | 4.1 - 0.04 | 3.14159265358979 | 4.1 - 0.09 | 3.14159265358979 | 4.1 - 1.21 | 3.14159265358979 | 4.1 - 4.84 | 3.14159265358979 | 4.1 - 10.89 | 3.14159265358979 | 4.1 + pow | pi | ?column? +----------------------+-------------------+---------- + 0.010000000000000002 | 3.141592653589793 | 4.1 + 0.04000000000000001 | 3.141592653589793 | 4.1 + 0.09 | 3.141592653589793 | 4.1 + 1.2100000000000002 | 3.141592653589793 | 4.1 + 4.840000000000001 | 3.141592653589793 | 4.1 + 10.889999999999999 | 3.141592653589793 | 4.1 (6 rows) -- select pow with order by (explain) @@ -8015,53 +8023,53 @@ SELECT (fields->>'value1')::float value1, pow(1-(fields->>'value1')::float, 2) F -- select pow with order by (result) --Testcase 820: SELECT (fields->>'value1')::float value1, pow(1-(fields->>'value1')::float, 2) FROM s3 order by pow(1-(fields->>'value1')::float, 2); - value1 | pow ---------+------ - 1.1 | 0.01 - 0.3 | 0.49 - 0.2 | 0.64 - 0.1 | 0.81 - 2.2 | 1.44 - 3.3 | 5.29 + value1 | pow +--------+---------------------- + 1.1 | 0.010000000000000018 + 0.3 | 0.48999999999999994 + 0.2 | 0.6400000000000001 + 0.1 | 0.81 + 2.2 | 1.4400000000000004 + 3.3 | 5.289999999999999 (6 rows) -- select pow with order by index (result) --Testcase 821: SELECT (fields->>'value1')::float value1, pow(1-(fields->>'value1')::float, 2) FROM s3 order by 2,1; - value1 | pow ---------+------ - 1.1 | 0.01 - 0.3 | 0.49 - 0.2 | 0.64 - 0.1 | 0.81 - 2.2 | 1.44 - 3.3 | 5.29 + value1 | pow +--------+---------------------- + 1.1 | 0.010000000000000018 + 0.3 | 0.48999999999999994 + 0.2 | 0.6400000000000001 + 0.1 | 0.81 + 2.2 | 1.4400000000000004 + 3.3 | 5.289999999999999 (6 rows) -- select pow with order by index (result) --Testcase 822: SELECT (fields->>'value1')::float value1, pow(1-(fields->>'value1')::float, 2) FROM s3 order by 1,2; - value1 | pow ---------+------ - 0.1 | 0.81 - 0.2 | 0.64 - 0.3 | 0.49 - 1.1 | 0.01 - 2.2 | 1.44 - 3.3 | 5.29 + value1 | pow +--------+---------------------- + 0.1 | 0.81 + 0.2 | 0.6400000000000001 + 0.3 | 0.48999999999999994 + 1.1 | 0.010000000000000018 + 2.2 | 1.4400000000000004 + 3.3 | 5.289999999999999 (6 rows) -- select pow and as --Testcase 823: SELECT pow((fields->>'value3')::float, 2) as pow1 FROM s3; - pow1 -------- - 0.01 - 0.04 - 0.09 - 1.21 - 4.84 - 10.89 + pow1 +---------------------- + 0.010000000000000002 + 0.04000000000000001 + 0.09 + 1.2100000000000002 + 4.840000000000001 + 10.889999999999999 (6 rows) -- select pow_all(2) (stub agg function, explain) @@ -8200,9 +8208,9 @@ SELECT sum((fields->>'value3')::float),round(sum((fields->>'value3')::float)) FR -- select round as nest function with agg (pushdown, result) --Testcase 837: SELECT sum((fields->>'value3')::float),round(sum((fields->>'value3')::float)) FROM s3; - sum | round -------+------- - -7.2 | -7 + sum | round +--------------------+------- + -7.199999999999999 | -7 (1 row) -- select round as nest with log2 (pushdown, explain) @@ -8225,24 +8233,24 @@ CONTEXT: PL/pgSQL function log2(double precision) line 3 at RAISE --Testcase 840: EXPLAIN VERBOSE SELECT round((fields->>'value3')::float), pi(), 4.1 FROM s3; - QUERY PLAN -------------------------------------------------------------------------------------------------------------- + QUERY PLAN +-------------------------------------------------------------------------------------------------------------- Foreign Scan on public.s3 (cost=10.00..1476.62 rows=1462 width=48) - Output: round(((fields ->> 'value3'::text))::double precision), '3.14159265358979'::double precision, 4.1 + Output: round(((fields ->> 'value3'::text))::double precision), '3.141592653589793'::double precision, 4.1 InfluxDB query: SELECT "value3" FROM "s3" (3 rows) -- select round with non pushdown func and roundlicit constant (result) --Testcase 841: SELECT round((fields->>'value3')::float), pi(), 4.1 FROM s3; - round | pi | ?column? --------+------------------+---------- - -0 | 3.14159265358979 | 4.1 - -0 | 3.14159265358979 | 4.1 - -0 | 3.14159265358979 | 4.1 - -1 | 3.14159265358979 | 4.1 - -2 | 3.14159265358979 | 4.1 - -3 | 3.14159265358979 | 4.1 + round | pi | ?column? +-------+-------------------+---------- + -0 | 3.141592653589793 | 4.1 + -0 | 3.141592653589793 | 4.1 + -0 | 3.141592653589793 | 4.1 + -1 | 3.141592653589793 | 4.1 + -2 | 3.141592653589793 | 4.1 + -3 | 3.141592653589793 | 4.1 (6 rows) -- select round with order by (explain) @@ -8380,14 +8388,14 @@ SELECT sin((fields->>'value1')::float), sin((fields->>'value2')::bigint), sin((f -- select sin (builtin function, result) --Testcase 854: SELECT sin((fields->>'value1')::float), sin((fields->>'value2')::bigint), sin((fields->>'value3')::float), sin((fields->>'value4')::bigint) FROM s3; - sin | sin | sin | sin ---------------------+--------------------+---------------------+------------------- - 0.0998334166468282 | -0.506365641109759 | -0.0998334166468282 | 0.506365641109759 - 0.198669330795061 | -0.506365641109759 | -0.198669330795061 | 0.506365641109759 - 0.29552020666134 | -0.506365641109759 | -0.29552020666134 | 0.506365641109759 - 0.891207360061435 | -0.873297297213995 | -0.891207360061435 | 0.873297297213995 - 0.80849640381959 | -0.873297297213995 | -0.80849640381959 | 0.873297297213995 - -0.157745694143248 | -0.873297297213995 | 0.157745694143248 | 0.873297297213995 + sin | sin | sin | sin +---------------------+---------------------+----------------------+-------------------- + 0.09983341664682815 | -0.5063656411097588 | -0.09983341664682815 | 0.5063656411097588 + 0.19866933079506122 | -0.5063656411097588 | -0.19866933079506122 | 0.5063656411097588 + 0.29552020666133955 | -0.5063656411097588 | -0.29552020666133955 | 0.5063656411097588 + 0.8912073600614354 | -0.8732972972139946 | -0.8912073600614354 | 0.8732972972139946 + 0.8084964038195901 | -0.8732972972139946 | -0.8084964038195901 | 0.8732972972139946 + -0.1577456941432482 | -0.8732972972139946 | 0.1577456941432482 | 0.8732972972139946 (6 rows) -- select sin (builtin function, not pushdown constraints, explain) @@ -8405,11 +8413,11 @@ SELECT sin((fields->>'value1')::float), sin((fields->>'value2')::bigint), sin((f -- select sin (builtin function, not pushdown constraints, result) --Testcase 856: SELECT sin((fields->>'value1')::float), sin((fields->>'value2')::bigint), sin((fields->>'value3')::float), sin((fields->>'value4')::bigint) FROM s3 WHERE to_hex((fields->>'value2')::bigint) != '64'; - sin | sin | sin | sin ---------------------+--------------------+--------------------+------------------- - 0.891207360061435 | -0.873297297213995 | -0.891207360061435 | 0.873297297213995 - 0.80849640381959 | -0.873297297213995 | -0.80849640381959 | 0.873297297213995 - -0.157745694143248 | -0.873297297213995 | 0.157745694143248 | 0.873297297213995 + sin | sin | sin | sin +---------------------+---------------------+---------------------+-------------------- + 0.8912073600614354 | -0.8732972972139946 | -0.8912073600614354 | 0.8732972972139946 + 0.8084964038195901 | -0.8732972972139946 | -0.8084964038195901 | 0.8732972972139946 + -0.1577456941432482 | -0.8732972972139946 | 0.1577456941432482 | 0.8732972972139946 (3 rows) -- select sin (builtin function, pushdown constraints, explain) @@ -8426,11 +8434,11 @@ SELECT sin((fields->>'value1')::float), sin((fields->>'value2')::bigint), sin((f -- select sin (builtin function, pushdown constraints, result) --Testcase 858: SELECT sin((fields->>'value1')::float), sin((fields->>'value2')::bigint), sin((fields->>'value3')::float), sin((fields->>'value4')::bigint) FROM s3 WHERE (fields->>'value2')::bigint != 200; - sin | sin | sin | sin ---------------------+--------------------+---------------------+------------------- - 0.0998334166468282 | -0.506365641109759 | -0.0998334166468282 | 0.506365641109759 - 0.198669330795061 | -0.506365641109759 | -0.198669330795061 | 0.506365641109759 - 0.29552020666134 | -0.506365641109759 | -0.29552020666134 | 0.506365641109759 + sin | sin | sin | sin +---------------------+---------------------+----------------------+-------------------- + 0.09983341664682815 | -0.5063656411097588 | -0.09983341664682815 | 0.5063656411097588 + 0.19866933079506122 | -0.5063656411097588 | -0.19866933079506122 | 0.5063656411097588 + 0.29552020666133955 | -0.5063656411097588 | -0.29552020666133955 | 0.5063656411097588 (3 rows) -- select sin as nest function with agg (pushdown, explain) @@ -8447,9 +8455,9 @@ SELECT sum((fields->>'value3')::float),sin(sum((fields->>'value3')::float)) FROM -- select sin as nest function with agg (pushdown, result) --Testcase 860: SELECT sum((fields->>'value3')::float),sin(sum((fields->>'value3')::float)) FROM s3; - sum | sin -------+-------------------- - -7.2 | -0.793667863849153 + sum | sin +--------------------+--------------------- + -7.199999999999999 | -0.7936678638491526 (1 row) -- select sin as nest with log2 (pushdown, explain) @@ -8472,24 +8480,24 @@ CONTEXT: PL/pgSQL function log2(double precision) line 3 at RAISE --Testcase 863: EXPLAIN VERBOSE SELECT sin((fields->>'value3')::float), pi(), 4.1 FROM s3; - QUERY PLAN ------------------------------------------------------------------------------------------------------------ + QUERY PLAN +------------------------------------------------------------------------------------------------------------ Foreign Scan on public.s3 (cost=10.00..1476.62 rows=1462 width=48) - Output: sin(((fields ->> 'value3'::text))::double precision), '3.14159265358979'::double precision, 4.1 + Output: sin(((fields ->> 'value3'::text))::double precision), '3.141592653589793'::double precision, 4.1 InfluxDB query: SELECT "value3" FROM "s3" (3 rows) -- select sin with non pushdown func and explicit constant (result) --Testcase 864: SELECT sin((fields->>'value3')::float), pi(), 4.1 FROM s3; - sin | pi | ?column? ----------------------+------------------+---------- - -0.0998334166468282 | 3.14159265358979 | 4.1 - -0.198669330795061 | 3.14159265358979 | 4.1 - -0.29552020666134 | 3.14159265358979 | 4.1 - -0.891207360061435 | 3.14159265358979 | 4.1 - -0.80849640381959 | 3.14159265358979 | 4.1 - 0.157745694143248 | 3.14159265358979 | 4.1 + sin | pi | ?column? +----------------------+-------------------+---------- + -0.09983341664682815 | 3.141592653589793 | 4.1 + -0.19866933079506122 | 3.141592653589793 | 4.1 + -0.29552020666133955 | 3.141592653589793 | 4.1 + -0.8912073600614354 | 3.141592653589793 | 4.1 + -0.8084964038195901 | 3.141592653589793 | 4.1 + 0.1577456941432482 | 3.141592653589793 | 4.1 (6 rows) -- select sin with order by (explain) @@ -8509,53 +8517,53 @@ SELECT (fields->>'value1')::float value1, sin(1-(fields->>'value1')::float) FROM -- select sin with order by (result) --Testcase 866: SELECT (fields->>'value1')::float value1, sin(1-(fields->>'value1')::float) FROM s3 order by sin(1-(fields->>'value1')::float); - value1 | sin ---------+--------------------- - 2.2 | -0.932039085967226 - 3.3 | -0.74570521217672 - 1.1 | -0.0998334166468282 - 0.3 | 0.644217687237691 - 0.2 | 0.717356090899523 - 0.1 | 0.783326909627483 + value1 | sin +--------+---------------------- + 2.2 | -0.9320390859672264 + 3.3 | -0.7457052121767203 + 1.1 | -0.09983341664682824 + 0.3 | 0.644217687237691 + 0.2 | 0.7173560908995228 + 0.1 | 0.7833269096274834 (6 rows) -- select sin with order by index (result) --Testcase 867: SELECT (fields->>'value1')::float value1, sin(1-(fields->>'value1')::float) FROM s3 order by 2,1; - value1 | sin ---------+--------------------- - 2.2 | -0.932039085967226 - 3.3 | -0.74570521217672 - 1.1 | -0.0998334166468282 - 0.3 | 0.644217687237691 - 0.2 | 0.717356090899523 - 0.1 | 0.783326909627483 + value1 | sin +--------+---------------------- + 2.2 | -0.9320390859672264 + 3.3 | -0.7457052121767203 + 1.1 | -0.09983341664682824 + 0.3 | 0.644217687237691 + 0.2 | 0.7173560908995228 + 0.1 | 0.7833269096274834 (6 rows) -- select sin with order by index (result) --Testcase 868: SELECT (fields->>'value1')::float value1, sin(1-(fields->>'value1')::float) FROM s3 order by 1,2; - value1 | sin ---------+--------------------- - 0.1 | 0.783326909627483 - 0.2 | 0.717356090899523 - 0.3 | 0.644217687237691 - 1.1 | -0.0998334166468282 - 2.2 | -0.932039085967226 - 3.3 | -0.74570521217672 + value1 | sin +--------+---------------------- + 0.1 | 0.7833269096274834 + 0.2 | 0.7173560908995228 + 0.3 | 0.644217687237691 + 1.1 | -0.09983341664682824 + 2.2 | -0.9320390859672264 + 3.3 | -0.7457052121767203 (6 rows) -- select sin and as --Testcase 869: SELECT sin((fields->>'value3')::float) as sin1 FROM s3; - sin1 ---------------------- - -0.0998334166468282 - -0.198669330795061 - -0.29552020666134 - -0.891207360061435 - -0.80849640381959 - 0.157745694143248 + sin1 +---------------------- + -0.09983341664682815 + -0.19866933079506122 + -0.29552020666133955 + -0.8912073600614354 + -0.8084964038195901 + 0.1577456941432482 (6 rows) -- select sin(*) (stub agg function, explain) @@ -8611,14 +8619,14 @@ SELECT tan((fields->>'value1')::float), tan((fields->>'value2')::bigint), tan((f -- select tan (builtin function, result) --Testcase 875: SELECT tan((fields->>'value1')::float), tan((fields->>'value2')::bigint), tan((fields->>'value3')::float), tan((fields->>'value4')::bigint) FROM s3; - tan | tan | tan | tan --------------------+--------------------+--------------------+------------------- - 0.100334672085451 | -0.587213915156929 | -0.100334672085451 | 0.587213915156929 - 0.202710035508673 | -0.587213915156929 | -0.202710035508673 | 0.587213915156929 - 0.309336249609623 | -0.587213915156929 | -0.309336249609623 | 0.587213915156929 - 1.96475965724865 | -1.79252748379038 | -1.96475965724865 | 1.79252748379038 - -1.37382305676879 | -1.79252748379038 | 1.37382305676879 | 1.79252748379038 - 0.159745747660032 | -1.79252748379038 | -0.159745747660032 | 1.79252748379038 + tan | tan | tan | tan +---------------------+---------------------+----------------------+-------------------- + 0.10033467208545055 | -0.5872139151569291 | -0.10033467208545055 | 0.5872139151569291 + 0.2027100355086725 | -0.5872139151569291 | -0.2027100355086725 | 0.5872139151569291 + 0.30933624960962325 | -0.5872139151569291 | -0.30933624960962325 | 0.5872139151569291 + 1.9647596572486523 | -1.7925274837903817 | -1.9647596572486523 | 1.7925274837903817 + -1.3738230567687946 | -1.7925274837903817 | 1.3738230567687946 | 1.7925274837903817 + 0.15974574766003222 | -1.7925274837903817 | -0.15974574766003222 | 1.7925274837903817 (6 rows) -- select tan (builtin function, not pushdown constraints, explain) @@ -8636,11 +8644,11 @@ SELECT tan((fields->>'value1')::float), tan((fields->>'value2')::bigint), tan((f -- select tan (builtin function, not pushdown constraints, result) --Testcase 877: SELECT tan((fields->>'value1')::float), tan((fields->>'value2')::bigint), tan((fields->>'value3')::float), tan((fields->>'value4')::bigint) FROM s3 WHERE to_hex((fields->>'value2')::bigint) != '64'; - tan | tan | tan | tan --------------------+-------------------+--------------------+------------------ - 1.96475965724865 | -1.79252748379038 | -1.96475965724865 | 1.79252748379038 - -1.37382305676879 | -1.79252748379038 | 1.37382305676879 | 1.79252748379038 - 0.159745747660032 | -1.79252748379038 | -0.159745747660032 | 1.79252748379038 + tan | tan | tan | tan +---------------------+---------------------+----------------------+-------------------- + 1.9647596572486523 | -1.7925274837903817 | -1.9647596572486523 | 1.7925274837903817 + -1.3738230567687946 | -1.7925274837903817 | 1.3738230567687946 | 1.7925274837903817 + 0.15974574766003222 | -1.7925274837903817 | -0.15974574766003222 | 1.7925274837903817 (3 rows) -- select tan (builtin function, pushdown constraints, explain) @@ -8657,11 +8665,11 @@ SELECT tan((fields->>'value1')::float), tan((fields->>'value2')::bigint), tan((f -- select tan (builtin function, pushdown constraints, result) --Testcase 879: SELECT tan((fields->>'value1')::float), tan((fields->>'value2')::bigint), tan((fields->>'value3')::float), tan((fields->>'value4')::bigint) FROM s3 WHERE (fields->>'value2')::bigint != 200; - tan | tan | tan | tan --------------------+--------------------+--------------------+------------------- - 0.100334672085451 | -0.587213915156929 | -0.100334672085451 | 0.587213915156929 - 0.202710035508673 | -0.587213915156929 | -0.202710035508673 | 0.587213915156929 - 0.309336249609623 | -0.587213915156929 | -0.309336249609623 | 0.587213915156929 + tan | tan | tan | tan +---------------------+---------------------+----------------------+-------------------- + 0.10033467208545055 | -0.5872139151569291 | -0.10033467208545055 | 0.5872139151569291 + 0.2027100355086725 | -0.5872139151569291 | -0.2027100355086725 | 0.5872139151569291 + 0.30933624960962325 | -0.5872139151569291 | -0.30933624960962325 | 0.5872139151569291 (3 rows) -- select tan as nest function with agg (pushdown, explain) @@ -8678,9 +8686,9 @@ SELECT sum((fields->>'value3')::float),tan(sum((fields->>'value3')::float)) FROM -- select tan as nest function with agg (pushdown, result) --Testcase 881: SELECT sum((fields->>'value3')::float),tan(sum((fields->>'value3')::float)) FROM s3; - sum | tan -------+------------------- - -7.2 | -1.30462094005564 + sum | tan +--------------------+--------------------- + -7.199999999999999 | -1.3046209400556357 (1 row) -- select tan as nest with log2 (pushdown, explain) @@ -8703,24 +8711,24 @@ CONTEXT: PL/pgSQL function log2(double precision) line 3 at RAISE --Testcase 884: EXPLAIN VERBOSE SELECT tan((fields->>'value3')::float), pi(), 4.1 FROM s3; - QUERY PLAN ------------------------------------------------------------------------------------------------------------ + QUERY PLAN +------------------------------------------------------------------------------------------------------------ Foreign Scan on public.s3 (cost=10.00..1476.62 rows=1462 width=48) - Output: tan(((fields ->> 'value3'::text))::double precision), '3.14159265358979'::double precision, 4.1 + Output: tan(((fields ->> 'value3'::text))::double precision), '3.141592653589793'::double precision, 4.1 InfluxDB query: SELECT "value3" FROM "s3" (3 rows) -- select tan with non pushdown func and tanlicit constant (result) --Testcase 885: SELECT tan((fields->>'value3')::float), pi(), 4.1 FROM s3; - tan | pi | ?column? ---------------------+------------------+---------- - -0.100334672085451 | 3.14159265358979 | 4.1 - -0.202710035508673 | 3.14159265358979 | 4.1 - -0.309336249609623 | 3.14159265358979 | 4.1 - -1.96475965724865 | 3.14159265358979 | 4.1 - 1.37382305676879 | 3.14159265358979 | 4.1 - -0.159745747660032 | 3.14159265358979 | 4.1 + tan | pi | ?column? +----------------------+-------------------+---------- + -0.10033467208545055 | 3.141592653589793 | 4.1 + -0.2027100355086725 | 3.141592653589793 | 4.1 + -0.30933624960962325 | 3.141592653589793 | 4.1 + -1.9647596572486523 | 3.141592653589793 | 4.1 + 1.3738230567687946 | 3.141592653589793 | 4.1 + -0.15974574766003222 | 3.141592653589793 | 4.1 (6 rows) -- select tan with order by (explain) @@ -8740,53 +8748,53 @@ SELECT (fields->>'value1')::float value1, tan(1-(fields->>'value1')::float) FROM -- select tan with order by (result) --Testcase 887: SELECT (fields->>'value1')::float value1, tan(1-(fields->>'value1')::float) FROM s3 order by tan(1-(fields->>'value1')::float); - value1 | tan ---------+-------------------- - 2.2 | -2.57215162212632 - 1.1 | -0.100334672085451 - 0.3 | 0.842288380463079 - 0.2 | 1.02963855705036 - 3.3 | 1.11921364173413 - 0.1 | 1.26015821755034 + value1 | tan +--------+---------------------- + 2.2 | -2.57215162212632 + 1.1 | -0.10033467208545063 + 0.3 | 0.8422883804630794 + 0.2 | 1.0296385570503641 + 3.3 | 1.1192136417341325 + 0.1 | 1.2601582175503392 (6 rows) -- select tan with order by index (result) --Testcase 888: SELECT (fields->>'value1')::float value1, tan(1-(fields->>'value1')::float) FROM s3 order by 2,1; - value1 | tan ---------+-------------------- - 2.2 | -2.57215162212632 - 1.1 | -0.100334672085451 - 0.3 | 0.842288380463079 - 0.2 | 1.02963855705036 - 3.3 | 1.11921364173413 - 0.1 | 1.26015821755034 + value1 | tan +--------+---------------------- + 2.2 | -2.57215162212632 + 1.1 | -0.10033467208545063 + 0.3 | 0.8422883804630794 + 0.2 | 1.0296385570503641 + 3.3 | 1.1192136417341325 + 0.1 | 1.2601582175503392 (6 rows) -- select tan with order by index (result) --Testcase 889: SELECT (fields->>'value1')::float value1, tan(1-(fields->>'value1')::float) FROM s3 order by 1,2; - value1 | tan ---------+-------------------- - 0.1 | 1.26015821755034 - 0.2 | 1.02963855705036 - 0.3 | 0.842288380463079 - 1.1 | -0.100334672085451 - 2.2 | -2.57215162212632 - 3.3 | 1.11921364173413 + value1 | tan +--------+---------------------- + 0.1 | 1.2601582175503392 + 0.2 | 1.0296385570503641 + 0.3 | 0.8422883804630794 + 1.1 | -0.10033467208545063 + 2.2 | -2.57215162212632 + 3.3 | 1.1192136417341325 (6 rows) -- select tan and as --Testcase 890: SELECT tan((fields->>'value3')::float) as tan1 FROM s3; - tan1 --------------------- - -0.100334672085451 - -0.202710035508673 - -0.309336249609623 - -1.96475965724865 - 1.37382305676879 - -0.159745747660032 + tan1 +---------------------- + -0.10033467208545055 + -0.2027100355086725 + -0.30933624960962325 + -1.9647596572486523 + 1.3738230567687946 + -0.15974574766003222 (6 rows) -- select tan(*) (stub agg function, explain) @@ -8847,13 +8855,13 @@ SELECT holt_winters(min((fields->>'value1')::float), 5, 1) FROM s3 WHERE time >= -- select predictors function holt_winters() (result) --Testcase 897: SELECT holt_winters(min((fields->>'value1')::float), 5, 1) FROM s3 WHERE time >= to_timestamp(0) and time <= to_timestamp(4) GROUP BY influx_time(time, interval '1s'); - holt_winters ------------------- - 5.18746006560853 - 13.2933307845701 - 37.5847742625017 - 116.557520596579 - 392.431171307496 + holt_winters +-------------------- + 5.187460065608529 + 13.293330784570104 + 37.584774262501654 + 116.55752059657874 + 392.43117130749647 (5 rows) -- select predictors function holt_winters_with_fit() (explain) @@ -8873,15 +8881,15 @@ SELECT holt_winters_with_fit(min((fields->>'value1')::float), 5, 1) FROM s3 WHER holt_winters_with_fit ----------------------- 0.1 - 0.146569361982582 - 0.449297189927864 - 1.00876071385362 - 2.21894136309638 - 5.18746006560853 - 13.2933307845701 - 37.5847742625017 - 116.557520596579 - 392.431171307496 + 0.14656936198258175 + 0.44929718992786366 + 1.0087607138536199 + 2.218941363096379 + 5.187460065608529 + 13.293330784570104 + 37.584774262501654 + 116.55752059657874 + 392.43117130749647 (10 rows) -- select count(*) function of InfluxDB (stub agg function, explain) @@ -8955,19 +8963,19 @@ SELECT influx_count_all(*) FROM s3 WHERE time >= to_timestamp(0) and time <= to_ --Testcase 906: EXPLAIN VERBOSE SELECT influx_count_all(*) FROM s3 t1 INNER JOIN s3 t2 ON ((t1.fields->>'value1')::float = (t2.fields->>'value1')::float) where (t1.fields->>'value1')::float = 0.1; - QUERY PLAN --------------------------------------------------------------------------------------------------- + QUERY PLAN +------------------------------------------------------------------------------------ Aggregate (cost=26.88..26.89 rows=1 width=32) Output: influx_count_all(*) -> Nested Loop (cost=20.00..14.63 rows=49 width=0) -> Foreign Scan on public.s3 t1 (cost=10.00..7.00 rows=7 width=32) Output: t1."time", t1.tags, t1.fields - InfluxDB query: SELECT * FROM "s3" WHERE (("value1" = 0.100000000000000006)) + InfluxDB query: SELECT * FROM "s3" WHERE (("value1" = 0.1)) -> Materialize (cost=10.00..7.04 rows=7 width=32) Output: t2.fields -> Foreign Scan on public.s3 t2 (cost=10.00..7.00 rows=7 width=32) Output: t2.fields - InfluxDB query: SELECT * FROM "s3" WHERE (("value1" = 0.100000000000000006)) + InfluxDB query: SELECT * FROM "s3" WHERE (("value1" = 0.1)) (11 rows) -- select count(*) function of InfluxDB over join query (result, stub call error) @@ -9046,20 +9054,20 @@ SELECT influx_distinct((fields->>'value2')::bigint) FROM s3 WHERE time >= to_tim --Testcase 914: EXPLAIN VERBOSE SELECT influx_distinct((t1.fields->>'value2')::bigint) FROM s3 t1 INNER JOIN s3 t2 ON ((t1.fields->>'value1')::float = (t2.fields->>'value1')::float) where (t1.fields->>'value1')::float = 0.1; - QUERY PLAN --------------------------------------------------------------------------------------------------- + QUERY PLAN +------------------------------------------------------------------------------------ Aggregate (cost=27.25..27.26 rows=1 width=8) Output: influx_distinct(((t1.fields ->> 'value2'::text))::bigint) -> Nested Loop (cost=20.00..14.63 rows=49 width=32) Output: t1.fields -> Foreign Scan on public.s3 t1 (cost=10.00..7.00 rows=7 width=32) Output: t1."time", t1.tags, t1.fields - InfluxDB query: SELECT * FROM "s3" WHERE (("value1" = 0.100000000000000006)) + InfluxDB query: SELECT * FROM "s3" WHERE (("value1" = 0.1)) -> Materialize (cost=10.00..7.04 rows=7 width=32) Output: t2.fields -> Foreign Scan on public.s3 t2 (cost=10.00..7.00 rows=7 width=32) Output: t2.fields - InfluxDB query: SELECT * FROM "s3" WHERE (("value1" = 0.100000000000000006)) + InfluxDB query: SELECT * FROM "s3" WHERE (("value1" = 0.1)) (12 rows) -- select distinct over join query (result, stub call error) @@ -9073,7 +9081,7 @@ EXPLAIN VERBOSE SELECT influx_distinct((fields->>'value2')::bigint) FROM s3 HAVING influx_distinct((fields->>'value2')::bigint) > 100; QUERY PLAN ----------------------------------------------------------------------------- - Aggregate (cost=2214.93..2214.94 rows=1 width=8) + Aggregate (cost=1838.47..1838.48 rows=1 width=8) Output: influx_distinct(((fields ->> 'value2'::text))::bigint) Filter: (influx_distinct(((s3.fields ->> 'value2'::text))::bigint) > 100) -> Foreign Scan on public.s3 (cost=10.00..1462.00 rows=1462 width=32) @@ -9108,11 +9116,11 @@ SELECT sqrt(abs((fields->>'value1')::float)) FROM b3 WHERE (fields->>'value3'):: -- bool type var in where clause (result) --Testcase 921: SELECT sqrt(abs((fields->>'value1')::float)) FROM b3 WHERE (fields->>'value3')::boolean != true ORDER BY 1; - sqrt -------------------- - 0.447213595499958 - 1.04880884817015 - 1.81659021245849 + sqrt +-------------------- + 0.4472135954999579 + 1.0488088481701516 + 1.816590212458495 (3 rows) --Testcase 922: diff --git a/expected/11.17/selectfunc.out b/expected/16.0/selectfunc.out similarity index 92% rename from expected/11.17/selectfunc.out rename to expected/16.0/selectfunc.out index d0147ad..26e182d 100644 --- a/expected/11.17/selectfunc.out +++ b/expected/16.0/selectfunc.out @@ -78,14 +78,14 @@ SELECT sqrt(value1), sqrt(value2) FROM s3; -- select sqrt (builtin function, result) --Testcase 12: SELECT sqrt(value1), sqrt(value2) FROM s3; - sqrt | sqrt --------------------+----------------- - 0.316227766016838 | 10 - 0.447213595499958 | 10 - 0.547722557505166 | 10 - 1.04880884817015 | 14.142135623731 - 1.48323969741913 | 14.142135623731 - 1.81659021245849 | 14.142135623731 + sqrt | sqrt +---------------------+-------------------- + 0.31622776601683794 | 10 + 0.4472135954999579 | 10 + 0.5477225575051661 | 10 + 1.0488088481701516 | 14.142135623730951 + 1.4832396974191326 | 14.142135623730951 + 1.816590212458495 | 14.142135623730951 (6 rows) -- select sqrt (builtin function, not pushdown constraints, explain) @@ -103,11 +103,11 @@ SELECT sqrt(value1), sqrt(value2) FROM s3 WHERE to_hex(value2) != '64'; -- select sqrt (builtin function, not pushdown constraints, result) --Testcase 14: SELECT sqrt(value1), sqrt(value2) FROM s3 WHERE to_hex(value2) != '64'; - sqrt | sqrt -------------------+----------------- - 1.04880884817015 | 14.142135623731 - 1.48323969741913 | 14.142135623731 - 1.81659021245849 | 14.142135623731 + sqrt | sqrt +--------------------+-------------------- + 1.0488088481701516 | 14.142135623730951 + 1.4832396974191326 | 14.142135623730951 + 1.816590212458495 | 14.142135623730951 (3 rows) -- select sqrt (builtin function, pushdown constraints, explain) @@ -124,11 +124,11 @@ SELECT sqrt(value1), sqrt(value2) FROM s3 WHERE value2 != 200; -- select sqrt (builtin function, pushdown constraints, result) --Testcase 16: SELECT sqrt(value1), sqrt(value2) FROM s3 WHERE value2 != 200; - sqrt | sqrt --------------------+------ - 0.316227766016838 | 10 - 0.447213595499958 | 10 - 0.547722557505166 | 10 + sqrt | sqrt +---------------------+------ + 0.31622776601683794 | 10 + 0.4472135954999579 | 10 + 0.5477225575051661 | 10 (3 rows) -- select sqrt(*) (stub agg function, explain) @@ -456,7 +456,7 @@ EXPLAIN VERBOSE SELECT log10(value1),log10(value2) FROM s3; QUERY PLAN --------------------------------------------------------------------- - Foreign Scan on public.s3 (cost=10.00..3077.12 rows=2048 width=16) + Foreign Scan on public.s3 (cost=10.00..2063.36 rows=2048 width=16) Output: log10(value1), log10((value2)::double precision) InfluxDB query: SELECT "value1", "value2" FROM "s3" (3 rows) @@ -464,8 +464,16 @@ SELECT log10(value1),log10(value2) FROM s3; -- select log10 (stub function, result) --Testcase 49: SELECT log10(value1),log10(value2) FROM s3; -ERROR: stub log10(float8) is called -CONTEXT: PL/pgSQL function log10(double precision) line 3 at RAISE + log10 | log10 +---------------------+-------------------- + -1 | 2 + -0.6989700043360187 | 2 + -0.5228787452803376 | 2 + 0.04139268515822507 | 2.3010299956639813 + 0.3424226808222063 | 2.3010299956639813 + 0.5185139398778874 | 2.3010299956639813 +(6 rows) + -- select log10(*) (stub agg function, explain) --Testcase 50: EXPLAIN VERBOSE @@ -524,9 +532,9 @@ SELECT spread(value1),spread(value2),spread(value3),spread(value4) FROM s3; -- select spread (stub agg function, result) --Testcase 56: SELECT spread(value1),spread(value2),spread(value3),spread(value4) FROM s3; - spread | spread | spread | spread ---------+--------+--------+-------- - 3.2 | 100 | 3.2 | 100 + spread | spread | spread | spread +--------------------+--------+--------------------+-------- + 3.1999999999999997 | 100 | 3.1999999999999997 | 100 (1 row) -- select spread (stub agg function, raise exception if not expected type) @@ -548,9 +556,9 @@ SELECT sum(value3),abs(sum(value3)) FROM s3; -- select abs as nest function with agg (pushdown, result) --Testcase 59: SELECT sum(value3),abs(sum(value3)) FROM s3; - sum | abs -------+----- - -7.2 | 7.2 + sum | abs +--------------------+------------------- + -7.199999999999999 | 7.199999999999999 (1 row) -- select abs as nest with log2 (pushdown, explain) @@ -576,40 +584,40 @@ SELECT abs(value3), pi(), 4.1 FROM s3; QUERY PLAN --------------------------------------------------------------------- Foreign Scan on public.s3 (cost=10.00..2566.40 rows=2560 width=48) - Output: abs(value3), '3.14159265358979'::double precision, 4.1 + Output: abs(value3), '3.141592653589793'::double precision, 4.1 InfluxDB query: SELECT "value3" FROM "s3" (3 rows) -- select abs with non pushdown func and explicit constant (result) --Testcase 63: SELECT abs(value3), pi(), 4.1 FROM s3; - abs | pi | ?column? ------+------------------+---------- - 0.1 | 3.14159265358979 | 4.1 - 0.2 | 3.14159265358979 | 4.1 - 0.3 | 3.14159265358979 | 4.1 - 1.1 | 3.14159265358979 | 4.1 - 2.2 | 3.14159265358979 | 4.1 - 3.3 | 3.14159265358979 | 4.1 + abs | pi | ?column? +-----+-------------------+---------- + 0.1 | 3.141592653589793 | 4.1 + 0.2 | 3.141592653589793 | 4.1 + 0.3 | 3.141592653589793 | 4.1 + 1.1 | 3.141592653589793 | 4.1 + 2.2 | 3.141592653589793 | 4.1 + 3.3 | 3.141592653589793 | 4.1 (6 rows) -- select sqrt as nest function with agg and explicit constant (pushdown, explain) --Testcase 64: EXPLAIN VERBOSE SELECT sqrt(count(value1)), pi(), 4.1 FROM s3; - QUERY PLAN ------------------------------------------------------------------------------------------------- + QUERY PLAN +------------------------------------------------------------------------------------------------- Foreign Scan (cost=1.00..1.00 rows=1 width=48) - Output: (sqrt((count(value1))::double precision)), '3.14159265358979'::double precision, 4.1 + Output: (sqrt((count(value1))::double precision)), '3.141592653589793'::double precision, 4.1 InfluxDB query: SELECT sqrt(count("value1")) FROM "s3" (3 rows) -- select sqrt as nest function with agg and explicit constant (pushdown, result) --Testcase 65: SELECT sqrt(count(value1)), pi(), 4.1 FROM s3; - sqrt | pi | ?column? -------------------+------------------+---------- - 2.44948974278318 | 3.14159265358979 | 4.1 + sqrt | pi | ?column? +-------------------+-------------------+---------- + 2.449489742783178 | 3.141592653589793 | 4.1 (1 row) -- select sqrt as nest function with agg and explicit constant and tag (error, explain) @@ -650,18 +658,18 @@ SELECT spread("value1"),influx_time(time, interval '1s'),tag1 FROM s3 WHERE time -- select spread (stub agg function and group by tag only) (result) --Testcase 69: SELECT tag1,spread("value1") FROM s3 WHERE time >= to_timestamp(0) and time <= to_timestamp(4) GROUP BY tag1; - tag1 | spread -------+-------- - a | 0.2 - b | 1.1 + tag1 | spread +------+--------------------- + a | 0.19999999999999998 + b | 1.1 (2 rows) -- select spread (stub agg function and other aggs) (result) --Testcase 70: SELECT sum("value1"),spread("value1"),count("value1") FROM s3; - sum | spread | count ------+--------+------- - 7.2 | 3.2 | 6 + sum | spread | count +-------------------+--------------------+------- + 7.199999999999999 | 3.1999999999999997 | 6 (1 row) -- select abs with order by (explain) @@ -681,40 +689,40 @@ SELECT value1, abs(1-value1) FROM s3 order by abs(1-value1); -- select abs with order by (result) --Testcase 72: SELECT value1, abs(1-value1) FROM s3 order by abs(1-value1); - value1 | abs ---------+----- - 1.1 | 0.1 - 0.3 | 0.7 - 0.2 | 0.8 - 0.1 | 0.9 - 2.2 | 1.2 - 3.3 | 2.3 + value1 | abs +--------+--------------------- + 1.1 | 0.10000000000000009 + 0.3 | 0.7 + 0.2 | 0.8 + 0.1 | 0.9 + 2.2 | 1.2000000000000002 + 3.3 | 2.3 (6 rows) -- select abs with order by index (result) --Testcase 73: SELECT value1, abs(1-value1) FROM s3 order by 2,1; - value1 | abs ---------+----- - 1.1 | 0.1 - 0.3 | 0.7 - 0.2 | 0.8 - 0.1 | 0.9 - 2.2 | 1.2 - 3.3 | 2.3 + value1 | abs +--------+--------------------- + 1.1 | 0.10000000000000009 + 0.3 | 0.7 + 0.2 | 0.8 + 0.1 | 0.9 + 2.2 | 1.2000000000000002 + 3.3 | 2.3 (6 rows) -- select abs with order by index (result) --Testcase 74: SELECT value1, abs(1-value1) FROM s3 order by 1,2; - value1 | abs ---------+----- - 0.1 | 0.9 - 0.2 | 0.8 - 0.3 | 0.7 - 1.1 | 0.1 - 2.2 | 1.2 - 3.3 | 2.3 + value1 | abs +--------+--------------------- + 0.1 | 0.9 + 0.2 | 0.8 + 0.3 | 0.7 + 1.1 | 0.10000000000000009 + 2.2 | 1.2000000000000002 + 3.3 | 2.3 (6 rows) -- select abs and as @@ -789,20 +797,20 @@ CONTEXT: PL/pgSQL function abs_all() line 3 at RAISE --Testcase 82: EXPLAIN VERBOSE SELECT spread(t1.value1), spread(t2.value1) FROM s3 t1 INNER JOIN s3 t2 ON (t1.value1 = t2.value1) where t1.value1 = 0.1; - QUERY PLAN ---------------------------------------------------------------------------------------------------------- + QUERY PLAN +---------------------------------------------------------------------------------------- Aggregate (cost=112.64..112.66 rows=1 width=16) Output: spread(t1.value1), spread(t2.value1) -> Nested Loop (cost=20.00..28.14 rows=169 width=16) Output: t1.value1, t2.value1 -> Foreign Scan on public.s3 t1 (cost=10.00..13.00 rows=13 width=8) Output: t1."time", t1.tag1, t1.value1, t1.value2, t1.value3, t1.value4 - InfluxDB query: SELECT "value1" FROM "s3" WHERE (("value1" = 0.100000000000000006)) + InfluxDB query: SELECT "value1" FROM "s3" WHERE (("value1" = 0.1)) -> Materialize (cost=10.00..13.06 rows=13 width=8) Output: t2.value1 -> Foreign Scan on public.s3 t2 (cost=10.00..13.00 rows=13 width=8) Output: t2.value1 - InfluxDB query: SELECT "value1" FROM "s3" WHERE (("value1" = 0.100000000000000006)) + InfluxDB query: SELECT "value1" FROM "s3" WHERE (("value1" = 0.1)) (12 rows) -- select spread over join query (result, stub call error) @@ -816,7 +824,7 @@ EXPLAIN VERBOSE SELECT spread(value1) FROM s3 HAVING spread(value1) > 100; QUERY PLAN -------------------------------------------------------------------------- - Aggregate (cost=3840.00..3840.01 rows=1 width=8) + Aggregate (cost=3200.00..3200.01 rows=1 width=8) Output: spread(value1) Filter: (spread(s3.value1) > '100'::double precision) -> Foreign Scan on public.s3 (cost=10.00..2560.00 rows=2560 width=8) @@ -910,9 +918,9 @@ SELECT (spread_all(*)::s3).* from s3; -- select spread(*) (stub agg function, expose data, result) --Testcase 93: SELECT (spread_all(*)::s3).* from s3; - time | tag1 | value1 | value2 | value3 | value4 -------------------------+------+--------+--------+--------+-------- - 1970-01-01 09:00:00+09 | | 3.2 | 100 | 3.2 | 100 + time | tag1 | value1 | value2 | value3 | value4 +------------------------+------+--------------------+--------+--------------------+-------- + 1970-01-01 09:00:00+09 | | 3.1999999999999997 | 100 | 3.1999999999999997 | 100 (1 row) -- select spread(regex) (stub agg function, explain) @@ -996,9 +1004,9 @@ SELECT (spread('/value[1,4]/')::s3).* from s3; -- select spread(regex) (stub agg function, expose data, result) --Testcase 101: SELECT (spread('/value[1,4]/')::s3).* from s3; - time | tag1 | value1 | value2 | value3 | value4 -------------------------+------+--------+--------+--------+-------- - 1970-01-01 09:00:00+09 | | 3.2 | | | 100 + time | tag1 | value1 | value2 | value3 | value4 +------------------------+------+--------------------+--------+--------+-------- + 1970-01-01 09:00:00+09 | | 3.1999999999999997 | | | 100 (1 row) -- select abs with arithmetic and tag in the middle (explain) @@ -1015,14 +1023,14 @@ SELECT abs(value1) + 1, value2, tag1, sqrt(value2) FROM s3; -- select abs with arithmetic and tag in the middle (result) --Testcase 103: SELECT abs(value1) + 1, value2, tag1, sqrt(value2) FROM s3; - ?column? | value2 | tag1 | sqrt -----------+--------+------+----------------- - 1.1 | 100 | a | 10 - 1.2 | 100 | a | 10 - 1.3 | 100 | a | 10 - 2.1 | 200 | b | 14.142135623731 - 3.2 | 200 | b | 14.142135623731 - 4.3 | 200 | b | 14.142135623731 + ?column? | value2 | tag1 | sqrt +----------+--------+------+-------------------- + 1.1 | 100 | a | 10 + 1.2 | 100 | a | 10 + 1.3 | 100 | a | 10 + 2.1 | 200 | b | 14.142135623730951 + 3.2 | 200 | b | 14.142135623730951 + 4.3 | 200 | b | 14.142135623730951 (6 rows) -- select with order by limit (explain) @@ -1063,14 +1071,14 @@ SELECT abs(value1), sqrt(value2), upper(tag1) FROM s3; -- select mixing with non pushdown func (result) --Testcase 107: SELECT abs(value1), sqrt(value2), upper(tag1) FROM s3; - abs | sqrt | upper ------+-----------------+------- - 0.1 | 10 | A - 0.2 | 10 | A - 0.3 | 10 | A - 1.1 | 14.142135623731 | B - 2.2 | 14.142135623731 | B - 3.3 | 14.142135623731 | B + abs | sqrt | upper +-----+--------------------+------- + 0.1 | 10 | A + 0.2 | 10 | A + 0.3 | 10 | A + 1.1 | 14.142135623730951 | B + 2.2 | 14.142135623730951 | B + 3.3 | 14.142135623730951 | B (6 rows) -- nested function in where clause (explain) @@ -1094,14 +1102,14 @@ SELECT sqrt(abs(value3)),min(value1) FROM s3 GROUP BY value3 HAVING sqrt(abs(val -- nested function in where clause (result) --Testcase 109: SELECT sqrt(abs(value3)),min(value1) FROM s3 GROUP BY value3 HAVING sqrt(abs(value3)) > 0 ORDER BY 1,2; - sqrt | min --------------------+----- - 0.316227766016838 | 0.1 - 0.447213595499958 | 0.2 - 0.547722557505166 | 0.3 - 1.04880884817015 | 1.1 - 1.48323969741913 | 2.2 - 1.81659021245849 | 3.3 + sqrt | min +---------------------+----- + 0.31622776601683794 | 0.1 + 0.4472135954999579 | 0.2 + 0.5477225575051661 | 0.3 + 1.0488088481701516 | 1.1 + 1.4832396974191326 | 2.2 + 1.816590212458495 | 3.3 (6 rows) --Testcase 110: @@ -3563,12 +3571,12 @@ SELECT integral("value1"),influx_time(time, interval '1s'),tag1 FROM s3 GROUP BY -- select integral (stub agg function and group by influx_time() and tag) (result) --Testcase 390: SELECT integral("value1"),influx_time(time, interval '1s'),tag1 FROM s3 GROUP BY influx_time(time, interval '1s'), tag1; - integral | influx_time | tag1 -----------+------------------------+------ - 0.15 | 1970-01-01 09:00:00+09 | a - 0.25 | 1970-01-01 09:00:01+09 | a - 1.65 | 1970-01-01 09:00:03+09 | b - 2.75 | 1970-01-01 09:00:04+09 | b + integral | influx_time | tag1 +---------------------+------------------------+------ + 0.15000000000000002 | 1970-01-01 09:00:00+09 | a + 0.25 | 1970-01-01 09:00:01+09 | a + 1.6500000000000001 | 1970-01-01 09:00:03+09 | b + 2.75 | 1970-01-01 09:00:04+09 | b (4 rows) -- select integral (stub agg function and group by influx_time() and tag) (explain) @@ -3585,66 +3593,66 @@ SELECT integral("value1", interval '1s'),influx_time(time, interval '1s'),tag1 F -- select integral (stub agg function and group by influx_time() and tag) (result) --Testcase 392: SELECT integral("value1", interval '1s'),influx_time(time, interval '1s'),tag1 FROM s3 GROUP BY influx_time(time, interval '1s'), tag1; - integral | influx_time | tag1 -----------+------------------------+------ - 0.15 | 1970-01-01 09:00:00+09 | a - 0.25 | 1970-01-01 09:00:01+09 | a - 1.65 | 1970-01-01 09:00:03+09 | b - 2.75 | 1970-01-01 09:00:04+09 | b + integral | influx_time | tag1 +---------------------+------------------------+------ + 0.15000000000000002 | 1970-01-01 09:00:00+09 | a + 0.25 | 1970-01-01 09:00:01+09 | a + 1.6500000000000001 | 1970-01-01 09:00:03+09 | b + 2.75 | 1970-01-01 09:00:04+09 | b (4 rows) -- select integral (stub agg function and group by tag only) (result) --Testcase 393: SELECT tag1,integral("value1") FROM s3 WHERE time >= to_timestamp(0) and time <= to_timestamp(4) GROUP BY tag1 ORDER BY 1; - tag1 | integral -------+---------- - a | 0.4 - b | 1.65 + tag1 | integral +------+-------------------- + a | 0.4 + b | 1.6500000000000001 (2 rows) -- select integral (stub agg function and other aggs) (result) --Testcase 394: SELECT sum("value1"),integral("value1"),count("value1") FROM s3; - sum | integral | count ------+----------+------- - 7.2 | 5.5 | 6 + sum | integral | count +-------------------+----------+------- + 7.199999999999999 | 5.5 | 6 (1 row) -- select integral (stub agg function and group by tag only) (result) --Testcase 395: SELECT tag1,integral("value1", interval '1s') FROM s3 WHERE time >= to_timestamp(0) and time <= to_timestamp(4) GROUP BY tag1 ORDER BY 1; - tag1 | integral -------+---------- - a | 0.4 - b | 1.65 + tag1 | integral +------+-------------------- + a | 0.4 + b | 1.6500000000000001 (2 rows) -- select integral (stub agg function and other aggs) (result) --Testcase 396: SELECT sum("value1"),integral("value1", interval '1s'),count("value1") FROM s3; - sum | integral | count ------+----------+------- - 7.2 | 5.5 | 6 + sum | integral | count +-------------------+----------+------- + 7.199999999999999 | 5.5 | 6 (1 row) -- select integral over join query (explain) --Testcase 397: EXPLAIN VERBOSE SELECT integral(t1.value1), integral(t2.value1) FROM s3 t1 INNER JOIN s3 t2 ON (t1.value1 = t2.value1) where t1.value1 = 0.1; - QUERY PLAN ---------------------------------------------------------------------------------------------------------- + QUERY PLAN +---------------------------------------------------------------------------------------- Aggregate (cost=112.64..112.66 rows=1 width=16) Output: integral(t1.value1), integral(t2.value1) -> Nested Loop (cost=20.00..28.14 rows=169 width=16) Output: t1.value1, t2.value1 -> Foreign Scan on public.s3 t1 (cost=10.00..13.00 rows=13 width=8) Output: t1."time", t1.tag1, t1.value1, t1.value2, t1.value3, t1.value4 - InfluxDB query: SELECT "value1" FROM "s3" WHERE (("value1" = 0.100000000000000006)) + InfluxDB query: SELECT "value1" FROM "s3" WHERE (("value1" = 0.1)) -> Materialize (cost=10.00..13.06 rows=13 width=8) Output: t2.value1 -> Foreign Scan on public.s3 t2 (cost=10.00..13.00 rows=13 width=8) Output: t2.value1 - InfluxDB query: SELECT "value1" FROM "s3" WHERE (("value1" = 0.100000000000000006)) + InfluxDB query: SELECT "value1" FROM "s3" WHERE (("value1" = 0.1)) (12 rows) -- select integral over join query (result, stub call error) @@ -3656,20 +3664,20 @@ CONTEXT: PL/pgSQL function integral_sfunc(double precision,double precision) li --Testcase 399: EXPLAIN VERBOSE SELECT integral(t1.value1, interval '1s'), integral(t2.value1, interval '1s') FROM s3 t1 INNER JOIN s3 t2 ON (t1.value1 = t2.value1) where t1.value1 = 0.1; - QUERY PLAN ---------------------------------------------------------------------------------------------------------- + QUERY PLAN +---------------------------------------------------------------------------------------------- Aggregate (cost=112.64..112.66 rows=1 width=16) Output: integral(t1.value1, '@ 1 sec'::interval), integral(t2.value1, '@ 1 sec'::interval) -> Nested Loop (cost=20.00..28.14 rows=169 width=16) Output: t1.value1, t2.value1 -> Foreign Scan on public.s3 t1 (cost=10.00..13.00 rows=13 width=8) Output: t1."time", t1.tag1, t1.value1, t1.value2, t1.value3, t1.value4 - InfluxDB query: SELECT "value1" FROM "s3" WHERE (("value1" = 0.100000000000000006)) + InfluxDB query: SELECT "value1" FROM "s3" WHERE (("value1" = 0.1)) -> Materialize (cost=10.00..13.06 rows=13 width=8) Output: t2.value1 -> Foreign Scan on public.s3 t2 (cost=10.00..13.00 rows=13 width=8) Output: t2.value1 - InfluxDB query: SELECT "value1" FROM "s3" WHERE (("value1" = 0.100000000000000006)) + InfluxDB query: SELECT "value1" FROM "s3" WHERE (("value1" = 0.1)) (12 rows) -- select integral over join query (result, stub call error) @@ -3683,7 +3691,7 @@ EXPLAIN VERBOSE SELECT integral(value1) FROM s3 HAVING integral(value1) > 100; QUERY PLAN -------------------------------------------------------------------------- - Aggregate (cost=3840.00..3840.01 rows=1 width=8) + Aggregate (cost=3200.00..3200.01 rows=1 width=8) Output: integral(value1) Filter: (integral(s3.value1) > '100'::double precision) -> Foreign Scan on public.s3 (cost=10.00..2560.00 rows=2560 width=8) @@ -3702,7 +3710,7 @@ EXPLAIN VERBOSE SELECT integral(value1, interval '1s') FROM s3 HAVING integral(value1, interval '1s') > 100; QUERY PLAN -------------------------------------------------------------------------------- - Aggregate (cost=3840.00..3840.01 rows=1 width=8) + Aggregate (cost=3200.00..3200.01 rows=1 width=8) Output: integral(value1, '@ 1 sec'::interval) Filter: (integral(s3.value1, '@ 1 sec'::interval) > '100'::double precision) -> Foreign Scan on public.s3 (cost=10.00..2560.00 rows=2560 width=8) @@ -3760,11 +3768,11 @@ SELECT integral_all(*) FROM s3 GROUP BY influx_time(time, interval '1s'), tag1; --Testcase 409: EXPLAIN VERBOSE SELECT integral_all(*) FROM s3 WHERE value1 > 0.3 GROUP BY tag1; - QUERY PLAN ----------------------------------------------------------------------------------------------------------- + QUERY PLAN +----------------------------------------------------------------------------------------- Foreign Scan (cost=1.00..1.00 rows=1 width=64) Output: (integral_all(*)), tag1 - InfluxDB query: SELECT integral(*) FROM "s3" WHERE (("value1" > 0.299999999999999989)) GROUP BY "tag1" + InfluxDB query: SELECT integral(*) FROM "s3" WHERE (("value1" > 0.3)) GROUP BY "tag1" (3 rows) -- select integral(*) (stub agg function and group by tag only) (result) @@ -3839,11 +3847,11 @@ SELECT integral('/^v.*/') FROM s3 GROUP BY influx_time(time, interval '1s'), tag --Testcase 417: EXPLAIN VERBOSE SELECT integral('/value[1,4]/') FROM s3 WHERE value1 > 0.3 GROUP BY tag1; - QUERY PLAN ---------------------------------------------------------------------------------------------------------------------- + QUERY PLAN +---------------------------------------------------------------------------------------------------- Foreign Scan (cost=1.00..1.00 rows=1 width=64) Output: (integral('/value[1,4]/'::text)), tag1 - InfluxDB query: SELECT integral(/value[1,4]/) FROM "s3" WHERE (("value1" > 0.299999999999999989)) GROUP BY "tag1" + InfluxDB query: SELECT integral(/value[1,4]/) FROM "s3" WHERE (("value1" > 0.3)) GROUP BY "tag1" (3 rows) -- select integral(regex) (stub agg function and group by tag only) (result) @@ -3928,38 +3936,38 @@ SELECT mean("value1"),influx_time(time, interval '1s'),tag1 FROM s3 WHERE time > -- select mean (stub agg function and group by tag only) (result) --Testcase 426: SELECT tag1,mean("value1") FROM s3 WHERE time >= to_timestamp(0) and time <= to_timestamp(4) GROUP BY tag1; - tag1 | mean -------+------ - a | 0.2 - b | 1.65 + tag1 | mean +------+--------------------- + a | 0.20000000000000004 + b | 1.6500000000000001 (2 rows) -- select mean (stub agg function and other aggs) (result) --Testcase 427: SELECT sum("value1"),mean("value1"),count("value1") FROM s3; - sum | mean | count ------+------+------- - 7.2 | 1.2 | 6 + sum | mean | count +-------------------+------+------- + 7.199999999999999 | 1.2 | 6 (1 row) -- select mean over join query (explain) --Testcase 428: EXPLAIN VERBOSE SELECT mean(t1.value1), mean(t2.value1) FROM s3 t1 INNER JOIN s3 t2 ON (t1.value1 = t2.value1) where t1.value1 = 0.1; - QUERY PLAN ---------------------------------------------------------------------------------------------------------- + QUERY PLAN +---------------------------------------------------------------------------------------- Aggregate (cost=112.64..112.66 rows=1 width=16) Output: mean(t1.value1), mean(t2.value1) -> Nested Loop (cost=20.00..28.14 rows=169 width=16) Output: t1.value1, t2.value1 -> Foreign Scan on public.s3 t1 (cost=10.00..13.00 rows=13 width=8) Output: t1."time", t1.tag1, t1.value1, t1.value2, t1.value3, t1.value4 - InfluxDB query: SELECT "value1" FROM "s3" WHERE (("value1" = 0.100000000000000006)) + InfluxDB query: SELECT "value1" FROM "s3" WHERE (("value1" = 0.1)) -> Materialize (cost=10.00..13.06 rows=13 width=8) Output: t2.value1 -> Foreign Scan on public.s3 t2 (cost=10.00..13.00 rows=13 width=8) Output: t2.value1 - InfluxDB query: SELECT "value1" FROM "s3" WHERE (("value1" = 0.100000000000000006)) + InfluxDB query: SELECT "value1" FROM "s3" WHERE (("value1" = 0.1)) (12 rows) -- select mean over join query (result, stub call error) @@ -3973,7 +3981,7 @@ EXPLAIN VERBOSE SELECT mean(value1) FROM s3 HAVING mean(value1) > 100; QUERY PLAN -------------------------------------------------------------------------- - Aggregate (cost=3840.00..3840.01 rows=1 width=8) + Aggregate (cost=3200.00..3200.01 rows=1 width=8) Output: mean(value1) Filter: (mean(s3.value1) > '100'::double precision) -> Foreign Scan on public.s3 (cost=10.00..2560.00 rows=2560 width=8) @@ -4172,9 +4180,9 @@ SELECT median(value1),median(value2),median(value3),median(value4) FROM s3; -- select median (stub agg function, result) --Testcase 449: SELECT median(value1),median(value2),median(value3),median(value4) FROM s3; - median | median | median | median ---------+--------+--------+-------- - 0.7 | 150 | -0.7 | -150 + median | median | median | median +--------+--------+---------------------+-------- + 0.7 | 150 | -0.7000000000000001 | -150 (1 row) -- select median (stub agg function, raise exception if not expected type) @@ -4213,38 +4221,38 @@ SELECT median("value1"),influx_time(time, interval '1s'),tag1 FROM s3 WHERE time -- select median (stub agg function and group by tag only) (result) --Testcase 453: SELECT tag1,median("value1") FROM s3 WHERE time >= to_timestamp(0) and time <= to_timestamp(4) GROUP BY tag1; - tag1 | median -------+-------- - a | 0.2 - b | 1.65 + tag1 | median +------+-------------------- + a | 0.2 + b | 1.6500000000000001 (2 rows) -- select median (stub agg function and other aggs) (result) --Testcase 454: SELECT sum("value1"),median("value1"),count("value1") FROM s3; - sum | median | count ------+--------+------- - 7.2 | 0.7 | 6 + sum | median | count +-------------------+--------+------- + 7.199999999999999 | 0.7 | 6 (1 row) -- select median over join query (explain) --Testcase 455: EXPLAIN VERBOSE SELECT median(t1.value1), median(t2.value1) FROM s3 t1 INNER JOIN s3 t2 ON (t1.value1 = t2.value1) where t1.value1 = 0.1; - QUERY PLAN ---------------------------------------------------------------------------------------------------------- + QUERY PLAN +---------------------------------------------------------------------------------------- Aggregate (cost=112.64..112.66 rows=1 width=16) Output: median(t1.value1), median(t2.value1) -> Nested Loop (cost=20.00..28.14 rows=169 width=16) Output: t1.value1, t2.value1 -> Foreign Scan on public.s3 t1 (cost=10.00..13.00 rows=13 width=8) Output: t1."time", t1.tag1, t1.value1, t1.value2, t1.value3, t1.value4 - InfluxDB query: SELECT "value1" FROM "s3" WHERE (("value1" = 0.100000000000000006)) + InfluxDB query: SELECT "value1" FROM "s3" WHERE (("value1" = 0.1)) -> Materialize (cost=10.00..13.06 rows=13 width=8) Output: t2.value1 -> Foreign Scan on public.s3 t2 (cost=10.00..13.00 rows=13 width=8) Output: t2.value1 - InfluxDB query: SELECT "value1" FROM "s3" WHERE (("value1" = 0.100000000000000006)) + InfluxDB query: SELECT "value1" FROM "s3" WHERE (("value1" = 0.1)) (12 rows) -- select median over join query (result, stub call error) @@ -4258,7 +4266,7 @@ EXPLAIN VERBOSE SELECT median(value1) FROM s3 HAVING median(value1) > 100; QUERY PLAN -------------------------------------------------------------------------- - Aggregate (cost=3840.00..3840.01 rows=1 width=8) + Aggregate (cost=3200.00..3200.01 rows=1 width=8) Output: median(value1) Filter: (median(s3.value1) > '100'::double precision) -> Foreign Scan on public.s3 (cost=10.00..2560.00 rows=2560 width=8) @@ -4352,9 +4360,9 @@ SELECT (median_all(*)::s3).* from s3; -- select median(*) (stub agg function, expose data, result) --Testcase 466: SELECT (median_all(*)::s3).* from s3; - time | tag1 | value1 | value2 | value3 | value4 -------------------------+------+--------+--------+--------+-------- - 1970-01-01 09:00:00+09 | | 0.7 | 150 | -0.7 | -150 + time | tag1 | value1 | value2 | value3 | value4 +------------------------+------+--------+--------+---------------------+-------- + 1970-01-01 09:00:00+09 | | 0.7 | 150 | -0.7000000000000001 | -150 (1 row) -- select median(regex) (stub agg function, explain) @@ -4507,29 +4515,29 @@ SELECT tag1,influx_mode("value1") FROM s3 WHERE time >= to_timestamp(0) and time -- select influx_mode (stub agg function and other aggs) (result) --Testcase 481: SELECT sum("value1"),influx_mode("value1"),count("value1") FROM s3; - sum | influx_mode | count ------+-------------+------- - 7.2 | 0.1 | 6 + sum | influx_mode | count +-------------------+-------------+------- + 7.199999999999999 | 0.1 | 6 (1 row) -- select influx_mode over join query (explain) --Testcase 482: EXPLAIN VERBOSE SELECT influx_mode(t1.value1), influx_mode(t2.value1) FROM s3 t1 INNER JOIN s3 t2 ON (t1.value1 = t2.value1) where t1.value1 = 0.1; - QUERY PLAN ---------------------------------------------------------------------------------------------------------- + QUERY PLAN +---------------------------------------------------------------------------------------- Aggregate (cost=112.64..112.66 rows=1 width=16) Output: influx_mode(t1.value1), influx_mode(t2.value1) -> Nested Loop (cost=20.00..28.14 rows=169 width=16) Output: t1.value1, t2.value1 -> Foreign Scan on public.s3 t1 (cost=10.00..13.00 rows=13 width=8) Output: t1."time", t1.tag1, t1.value1, t1.value2, t1.value3, t1.value4 - InfluxDB query: SELECT "value1" FROM "s3" WHERE (("value1" = 0.100000000000000006)) + InfluxDB query: SELECT "value1" FROM "s3" WHERE (("value1" = 0.1)) -> Materialize (cost=10.00..13.06 rows=13 width=8) Output: t2.value1 -> Foreign Scan on public.s3 t2 (cost=10.00..13.00 rows=13 width=8) Output: t2.value1 - InfluxDB query: SELECT "value1" FROM "s3" WHERE (("value1" = 0.100000000000000006)) + InfluxDB query: SELECT "value1" FROM "s3" WHERE (("value1" = 0.1)) (12 rows) -- select influx_mode over join query (result, stub call error) @@ -4543,7 +4551,7 @@ EXPLAIN VERBOSE SELECT influx_mode(value1) FROM s3 HAVING influx_mode(value1) > 100; QUERY PLAN -------------------------------------------------------------------------- - Aggregate (cost=3840.00..3840.01 rows=1 width=8) + Aggregate (cost=3200.00..3200.01 rows=1 width=8) Output: influx_mode(value1) Filter: (influx_mode(s3.value1) > '100'::double precision) -> Foreign Scan on public.s3 (cost=10.00..2560.00 rows=2560 width=8) @@ -4742,9 +4750,9 @@ SELECT stddev(value1),stddev(value2),stddev(value3),stddev(value4) FROM s3; -- select stddev (agg function, result) --Testcase 503: SELECT stddev(value1),stddev(value2),stddev(value3),stddev(value4) FROM s3; - stddev | stddev | stddev | stddev -------------------+--------------------+------------------+-------------------- - 1.29923054151294 | 54.772255750516614 | 1.29923054151294 | 54.772255750516614 + stddev | stddev | stddev | stddev +-------------------+--------------------+-------------------+-------------------- + 1.299230541512937 | 54.772255750516614 | 1.299230541512937 | 54.772255750516614 (1 row) -- select stddev (agg function and group by influx_time() and tag) (explain) @@ -4778,18 +4786,18 @@ SELECT stddev("value1"),influx_time(time, interval '1s'),tag1 FROM s3 WHERE time -- select stddev (agg function and group by tag only) (result) --Testcase 506: SELECT tag1,stddev("value1") FROM s3 WHERE time >= to_timestamp(0) and time <= to_timestamp(4) GROUP BY tag1; - tag1 | stddev -------+------------------- - a | 0.1 - b | 0.777817459305202 + tag1 | stddev +------+--------------------- + a | 0.09999999999999999 + b | 0.7778174593052023 (2 rows) -- select stddev (agg function and other aggs) (result) --Testcase 507: SELECT sum("value1"),stddev("value1"),count("value1") FROM s3; - sum | stddev | count ------+------------------+------- - 7.2 | 1.29923054151294 | 6 + sum | stddev | count +-------------------+-------------------+------- + 7.199999999999999 | 1.299230541512937 | 6 (1 row) -- select stddev(*) (stub agg function, explain) @@ -5007,9 +5015,9 @@ SELECT (influx_sum_all(*)::s3).* from s3; -- select influx_sum(*) (stub agg function, expose data, result) --Testcase 527: SELECT (influx_sum_all(*)::s3).* from s3; - time | tag1 | value1 | value2 | value3 | value4 -------------------------+------+--------+--------+--------+-------- - 1970-01-01 09:00:00+09 | | 7.2 | 900 | -7.2 | -900 + time | tag1 | value1 | value2 | value3 | value4 +------------------------+------+-------------------+--------+--------------------+-------- + 1970-01-01 09:00:00+09 | | 7.199999999999999 | 900 | -7.199999999999999 | -900 (1 row) -- select influx_sum(regex) (stub function, explain) @@ -5093,9 +5101,9 @@ SELECT (influx_sum('/value[1,4]/')::s3).* from s3; -- select influx_sum(regex) (stub agg function, expose data, result) --Testcase 535: SELECT (influx_sum('/value[1,4]/')::s3).* from s3; - time | tag1 | value1 | value2 | value3 | value4 -------------------------+------+--------+--------+--------+-------- - 1970-01-01 09:00:00+09 | | 7.2 | | | -900 + time | tag1 | value1 | value2 | value3 | value4 +------------------------+------+-------------------+--------+--------+-------- + 1970-01-01 09:00:00+09 | | 7.199999999999999 | | | -900 (1 row) -- selector function bottom() (explain) @@ -5840,11 +5848,11 @@ SELECT acos(value1), acos(value3) FROM s3 WHERE to_hex(value2) = '64'; -- select acos (builtin function, not pushdown constraints, result) --Testcase 611: SELECT acos(value1), acos(value3) FROM s3 WHERE to_hex(value2) = '64'; - acos | acos -------------------+------------------ - 1.47062890563334 | 1.67096374795646 - 1.36943840600457 | 1.77215424758523 - 1.2661036727795 | 1.87548898081029 + acos | acos +--------------------+-------------------- + 1.4706289056333368 | 1.6709637479564565 + 1.369438406004566 | 1.7721542475852274 + 1.2661036727794992 | 1.8754889808102941 (3 rows) -- select acos (builtin function, pushdown constraints, explain) @@ -5861,11 +5869,11 @@ SELECT acos(value1), acos(value3) FROM s3 WHERE value2 != 200; -- select acos (builtin function, pushdown constraints, result) --Testcase 613: SELECT acos(value1), acos(value3) FROM s3 WHERE value2 != 200; - acos | acos -------------------+------------------ - 1.47062890563334 | 1.67096374795646 - 1.36943840600457 | 1.77215424758523 - 1.2661036727795 | 1.87548898081029 + acos | acos +--------------------+-------------------- + 1.4706289056333368 | 1.6709637479564565 + 1.369438406004566 | 1.7721542475852274 + 1.2661036727794992 | 1.8754889808102941 (3 rows) -- select acos as nest function with agg (pushdown, explain) @@ -5882,9 +5890,9 @@ SELECT sum(value3), acos(sum(value3)) FROM s3 WHERE value2 != 200; -- select acos as nest function with agg (pushdown, result) --Testcase 615: SELECT sum(value3), acos(sum(value3)) FROM s3 WHERE value2 != 200; - sum | acos -------+------------------ - -0.6 | 2.21429743558818 + sum | acos +---------------------+------------------- + -0.6000000000000001 | 2.214297435588181 (1 row) -- select acos as nest with log2 (pushdown, explain) @@ -5910,18 +5918,18 @@ SELECT acos(value3), pi(), 4.1 FROM s3 WHERE value2 != 200; QUERY PLAN ----------------------------------------------------------------------- Foreign Scan on public.s3 (cost=10.00..2553.37 rows=2547 width=48) - Output: acos(value3), '3.14159265358979'::double precision, 4.1 + Output: acos(value3), '3.141592653589793'::double precision, 4.1 InfluxDB query: SELECT "value3" FROM "s3" WHERE (("value2" <> 200)) (3 rows) -- select acos with non pushdown func and explicit constant (result) --Testcase 619: SELECT acos(value3), pi(), 4.1 FROM s3 WHERE value2 != 200; - acos | pi | ?column? -------------------+------------------+---------- - 1.67096374795646 | 3.14159265358979 | 4.1 - 1.77215424758523 | 3.14159265358979 | 4.1 - 1.87548898081029 | 3.14159265358979 | 4.1 + acos | pi | ?column? +--------------------+-------------------+---------- + 1.6709637479564565 | 3.141592653589793 | 4.1 + 1.7721542475852274 | 3.141592653589793 | 4.1 + 1.8754889808102941 | 3.141592653589793 | 4.1 (3 rows) -- select acos with order by (explain) @@ -5941,41 +5949,41 @@ SELECT value1, acos(1-value1) FROM s3 WHERE value2 != 200 ORDER BY acos(1-value1 -- select acos with order by (result) --Testcase 621: SELECT value1, acos(1-value1) FROM s3 WHERE value2 != 200 ORDER BY acos(1-value1); - value1 | acos ---------+------------------- - 0.1 | 0.451026811796262 - 0.2 | 0.643501108793284 - 0.3 | 0.795398830184144 + value1 | acos +--------+--------------------- + 0.1 | 0.45102681179626236 + 0.2 | 0.6435011087932843 + 0.3 | 0.7953988301841436 (3 rows) -- select acos with order by index (result) --Testcase 622: SELECT value1, acos(1-value1) FROM s3 WHERE value2 != 200 ORDER BY 2,1; - value1 | acos ---------+------------------- - 0.1 | 0.451026811796262 - 0.2 | 0.643501108793284 - 0.3 | 0.795398830184144 + value1 | acos +--------+--------------------- + 0.1 | 0.45102681179626236 + 0.2 | 0.6435011087932843 + 0.3 | 0.7953988301841436 (3 rows) -- select acos with order by index (result) --Testcase 623: SELECT value1, acos(1-value1) FROM s3 WHERE value2 != 200 ORDER BY 1,2; - value1 | acos ---------+------------------- - 0.1 | 0.451026811796262 - 0.2 | 0.643501108793284 - 0.3 | 0.795398830184144 + value1 | acos +--------+--------------------- + 0.1 | 0.45102681179626236 + 0.2 | 0.6435011087932843 + 0.3 | 0.7953988301841436 (3 rows) -- select acos and as --Testcase 624: SELECT acos(value3) as acos1 FROM s3 WHERE value2 != 200; - acos1 ------------------- - 1.67096374795646 - 1.77215424758523 - 1.87548898081029 + acos1 +-------------------- + 1.6709637479564565 + 1.7721542475852274 + 1.8754889808102941 (3 rows) -- select acos(*) (stub agg function, explain) @@ -6063,11 +6071,11 @@ SELECT asin(value1), asin(value3) FROM s3 WHERE to_hex(value2) = '64'; -- select asin (builtin function, not pushdown constraints, result) --Testcase 634: SELECT asin(value1), asin(value3) FROM s3 WHERE to_hex(value2) = '64'; - asin | asin --------------------+-------------------- - 0.10016742116156 | -0.10016742116156 - 0.201357920790331 | -0.201357920790331 - 0.304692654015398 | -0.304692654015398 + asin | asin +--------------------+--------------------- + 0.1001674211615598 | -0.1001674211615598 + 0.2013579207903308 | -0.2013579207903308 + 0.3046926540153975 | -0.3046926540153975 (3 rows) -- select asin (builtin function, pushdown constraints, explain) @@ -6084,11 +6092,11 @@ SELECT asin(value1), asin(value3) FROM s3 WHERE value2 != 200; -- select asin (builtin function, pushdown constraints, result) --Testcase 636: SELECT asin(value1), asin(value3) FROM s3 WHERE value2 != 200; - asin | asin --------------------+-------------------- - 0.10016742116156 | -0.10016742116156 - 0.201357920790331 | -0.201357920790331 - 0.304692654015398 | -0.304692654015398 + asin | asin +--------------------+--------------------- + 0.1001674211615598 | -0.1001674211615598 + 0.2013579207903308 | -0.2013579207903308 + 0.3046926540153975 | -0.3046926540153975 (3 rows) -- select asin as nest function with agg (pushdown, explain) @@ -6105,9 +6113,9 @@ SELECT sum(value3), asin(sum(value3)) FROM s3 WHERE value2 != 200; -- select asin as nest function with agg (pushdown, result) --Testcase 638: SELECT sum(value3), asin(sum(value3)) FROM s3 WHERE value2 != 200; - sum | asin -------+-------------------- - -0.6 | -0.643501108793284 + sum | asin +---------------------+--------------------- + -0.6000000000000001 | -0.6435011087932845 (1 row) -- select asin as nest with log2 (pushdown, explain) @@ -6133,18 +6141,18 @@ SELECT asin(value3), pi(), 4.1 FROM s3 WHERE value2 != 200; QUERY PLAN ----------------------------------------------------------------------- Foreign Scan on public.s3 (cost=10.00..2553.37 rows=2547 width=48) - Output: asin(value3), '3.14159265358979'::double precision, 4.1 + Output: asin(value3), '3.141592653589793'::double precision, 4.1 InfluxDB query: SELECT "value3" FROM "s3" WHERE (("value2" <> 200)) (3 rows) -- select asin with non pushdown func and explicit constant (result) --Testcase 642: SELECT asin(value3), pi(), 4.1 FROM s3 WHERE value2 != 200; - asin | pi | ?column? ---------------------+------------------+---------- - -0.10016742116156 | 3.14159265358979 | 4.1 - -0.201357920790331 | 3.14159265358979 | 4.1 - -0.304692654015398 | 3.14159265358979 | 4.1 + asin | pi | ?column? +---------------------+-------------------+---------- + -0.1001674211615598 | 3.141592653589793 | 4.1 + -0.2013579207903308 | 3.141592653589793 | 4.1 + -0.3046926540153975 | 3.141592653589793 | 4.1 (3 rows) -- select asin with order by (explain) @@ -6164,41 +6172,41 @@ SELECT value1, asin(1-value1) FROM s3 WHERE value2 != 200 ORDER BY asin(1-value1 -- select asin with order by (result) --Testcase 644: SELECT value1, asin(1-value1) FROM s3 WHERE value2 != 200 ORDER BY asin(1-value1); - value1 | asin ---------+------------------- - 0.3 | 0.775397496610753 - 0.2 | 0.927295218001612 - 0.1 | 1.11976951499863 + value1 | asin +--------+-------------------- + 0.3 | 0.775397496610753 + 0.2 | 0.9272952180016123 + 0.1 | 1.1197695149986342 (3 rows) -- select asin with order by index (result) --Testcase 645: SELECT value1, asin(1-value1) FROM s3 WHERE value2 != 200 ORDER BY 2,1; - value1 | asin ---------+------------------- - 0.3 | 0.775397496610753 - 0.2 | 0.927295218001612 - 0.1 | 1.11976951499863 + value1 | asin +--------+-------------------- + 0.3 | 0.775397496610753 + 0.2 | 0.9272952180016123 + 0.1 | 1.1197695149986342 (3 rows) -- select asin with order by index (result) --Testcase 646: SELECT value1, asin(1-value1) FROM s3 WHERE value2 != 200 ORDER BY 1,2; - value1 | asin ---------+------------------- - 0.1 | 1.11976951499863 - 0.2 | 0.927295218001612 - 0.3 | 0.775397496610753 + value1 | asin +--------+-------------------- + 0.1 | 1.1197695149986342 + 0.2 | 0.9272952180016123 + 0.3 | 0.775397496610753 (3 rows) -- select asin and as --Testcase 647: SELECT asin(value3) as asin1 FROM s3 WHERE value2 != 200; - asin1 --------------------- - -0.10016742116156 - -0.201357920790331 - -0.304692654015398 + asin1 +--------------------- + -0.1001674211615598 + -0.2013579207903308 + -0.3046926540153975 (3 rows) -- select asin(*) (stub agg function, explain) @@ -6270,14 +6278,14 @@ SELECT atan(value1), atan(value2), atan(value3), atan(value4) FROM s3; -- select atan (builtin function, result) --Testcase 655: SELECT atan(value1), atan(value2), atan(value3), atan(value4) FROM s3; - atan | atan | atan | atan --------------------+------------------+--------------------+------------------- - 0.099668652491162 | 1.56079666010823 | -0.099668652491162 | -1.56079666010823 - 0.197395559849881 | 1.56079666010823 | -0.197395559849881 | -1.56079666010823 - 0.291456794477867 | 1.56079666010823 | -0.291456794477867 | -1.56079666010823 - 0.832981266674432 | 1.56579636846094 | -0.832981266674432 | -1.56579636846094 - 1.14416883366802 | 1.56579636846094 | -1.14416883366802 | -1.56579636846094 - 1.27656176168371 | 1.56579636846094 | -1.27656176168371 | -1.56579636846094 + atan | atan | atan | atan +---------------------+--------------------+----------------------+--------------------- + 0.09966865249116204 | 1.5607966601082315 | -0.09966865249116204 | -1.5607966601082315 + 0.19739555984988078 | 1.5607966601082315 | -0.19739555984988078 | -1.5607966601082315 + 0.2914567944778671 | 1.5607966601082315 | -0.2914567944778671 | -1.5607966601082315 + 0.8329812666744317 | 1.5657963684609384 | -0.8329812666744317 | -1.5657963684609384 + 1.1441688336680205 | 1.5657963684609384 | -1.1441688336680205 | -1.5657963684609384 + 1.2765617616837088 | 1.5657963684609384 | -1.2765617616837088 | -1.5657963684609384 (6 rows) -- select atan (builtin function, not pushdown constraints, explain) @@ -6295,11 +6303,11 @@ SELECT atan(value1), atan(value2), atan(value3), atan(value4) FROM s3 WHERE to_h -- select atan (builtin function, not pushdown constraints, result) --Testcase 657: SELECT atan(value1), atan(value2), atan(value3), atan(value4) FROM s3 WHERE to_hex(value2) != '64'; - atan | atan | atan | atan --------------------+------------------+--------------------+------------------- - 0.832981266674432 | 1.56579636846094 | -0.832981266674432 | -1.56579636846094 - 1.14416883366802 | 1.56579636846094 | -1.14416883366802 | -1.56579636846094 - 1.27656176168371 | 1.56579636846094 | -1.27656176168371 | -1.56579636846094 + atan | atan | atan | atan +--------------------+--------------------+---------------------+--------------------- + 0.8329812666744317 | 1.5657963684609384 | -0.8329812666744317 | -1.5657963684609384 + 1.1441688336680205 | 1.5657963684609384 | -1.1441688336680205 | -1.5657963684609384 + 1.2765617616837088 | 1.5657963684609384 | -1.2765617616837088 | -1.5657963684609384 (3 rows) -- select atan (builtin function, pushdown constraints, explain) @@ -6316,11 +6324,11 @@ SELECT atan(value1), atan(value2), atan(value3), atan(value4) FROM s3 WHERE valu -- select atan (builtin function, pushdown constraints, result) --Testcase 659: SELECT atan(value1), atan(value2), atan(value3), atan(value4) FROM s3 WHERE value2 != 200; - atan | atan | atan | atan --------------------+------------------+--------------------+------------------- - 0.099668652491162 | 1.56079666010823 | -0.099668652491162 | -1.56079666010823 - 0.197395559849881 | 1.56079666010823 | -0.197395559849881 | -1.56079666010823 - 0.291456794477867 | 1.56079666010823 | -0.291456794477867 | -1.56079666010823 + atan | atan | atan | atan +---------------------+--------------------+----------------------+--------------------- + 0.09966865249116204 | 1.5607966601082315 | -0.09966865249116204 | -1.5607966601082315 + 0.19739555984988078 | 1.5607966601082315 | -0.19739555984988078 | -1.5607966601082315 + 0.2914567944778671 | 1.5607966601082315 | -0.2914567944778671 | -1.5607966601082315 (3 rows) -- select atan as nest function with agg (pushdown, explain) @@ -6337,9 +6345,9 @@ SELECT sum(value3),atan(sum(value3)) FROM s3; -- select atan as nest function with agg (pushdown, result) --Testcase 661: SELECT sum(value3),atan(sum(value3)) FROM s3; - sum | atan -------+------------------- - -7.2 | -1.43279030313738 + sum | atan +--------------------+--------------------- + -7.199999999999999 | -1.4327903031373772 (1 row) -- select atan as nest with log2 (pushdown, explain) @@ -6365,21 +6373,21 @@ SELECT atan(value3), pi(), 4.1 FROM s3; QUERY PLAN --------------------------------------------------------------------- Foreign Scan on public.s3 (cost=10.00..2566.40 rows=2560 width=48) - Output: atan(value3), '3.14159265358979'::double precision, 4.1 + Output: atan(value3), '3.141592653589793'::double precision, 4.1 InfluxDB query: SELECT "value3" FROM "s3" (3 rows) -- select atan with non pushdown func and explicit constant (result) --Testcase 665: SELECT atan(value3), pi(), 4.1 FROM s3; - atan | pi | ?column? ---------------------+------------------+---------- - -0.099668652491162 | 3.14159265358979 | 4.1 - -0.197395559849881 | 3.14159265358979 | 4.1 - -0.291456794477867 | 3.14159265358979 | 4.1 - -0.832981266674432 | 3.14159265358979 | 4.1 - -1.14416883366802 | 3.14159265358979 | 4.1 - -1.27656176168371 | 3.14159265358979 | 4.1 + atan | pi | ?column? +----------------------+-------------------+---------- + -0.09966865249116204 | 3.141592653589793 | 4.1 + -0.19739555984988078 | 3.141592653589793 | 4.1 + -0.2914567944778671 | 3.141592653589793 | 4.1 + -0.8329812666744317 | 3.141592653589793 | 4.1 + -1.1441688336680205 | 3.141592653589793 | 4.1 + -1.2765617616837088 | 3.141592653589793 | 4.1 (6 rows) -- select atan with order by (explain) @@ -6399,53 +6407,53 @@ SELECT value1, atan(1-value1) FROM s3 order by atan(1-value1); -- select atan with order by (result) --Testcase 667: SELECT value1, atan(1-value1) FROM s3 order by atan(1-value1); - value1 | atan ---------+--------------------- - 3.3 | -1.16066898625341 - 2.2 | -0.876058050598194 - 1.1 | -0.0996686524911621 - 0.3 | 0.610725964389209 - 0.2 | 0.674740942223553 - 0.1 | 0.732815101786507 + value1 | atan +--------+---------------------- + 3.3 | -1.1606689862534056 + 2.2 | -0.8760580505981935 + 1.1 | -0.09966865249116212 + 0.3 | 0.6107259643892086 + 0.2 | 0.6747409422235527 + 0.1 | 0.7328151017865066 (6 rows) -- select atan with order by index (result) --Testcase 668: SELECT value1, atan(1-value1) FROM s3 order by 2,1; - value1 | atan ---------+--------------------- - 3.3 | -1.16066898625341 - 2.2 | -0.876058050598194 - 1.1 | -0.0996686524911621 - 0.3 | 0.610725964389209 - 0.2 | 0.674740942223553 - 0.1 | 0.732815101786507 + value1 | atan +--------+---------------------- + 3.3 | -1.1606689862534056 + 2.2 | -0.8760580505981935 + 1.1 | -0.09966865249116212 + 0.3 | 0.6107259643892086 + 0.2 | 0.6747409422235527 + 0.1 | 0.7328151017865066 (6 rows) -- select atan with order by index (result) --Testcase 669: SELECT value1, atan(1-value1) FROM s3 order by 1,2; - value1 | atan ---------+--------------------- - 0.1 | 0.732815101786507 - 0.2 | 0.674740942223553 - 0.3 | 0.610725964389209 - 1.1 | -0.0996686524911621 - 2.2 | -0.876058050598194 - 3.3 | -1.16066898625341 + value1 | atan +--------+---------------------- + 0.1 | 0.7328151017865066 + 0.2 | 0.6747409422235527 + 0.3 | 0.6107259643892086 + 1.1 | -0.09966865249116212 + 2.2 | -0.8760580505981935 + 3.3 | -1.1606689862534056 (6 rows) -- select atan and as --Testcase 670: SELECT atan(value3) as atan1 FROM s3; - atan1 --------------------- - -0.099668652491162 - -0.197395559849881 - -0.291456794477867 - -0.832981266674432 - -1.14416883366802 - -1.27656176168371 + atan1 +---------------------- + -0.09966865249116204 + -0.19739555984988078 + -0.2914567944778671 + -0.8329812666744317 + -1.1441688336680205 + -1.2765617616837088 (6 rows) -- select atan(*) (stub agg function, explain) @@ -6517,14 +6525,14 @@ SELECT atan2(value1, value2), atan2(value2, value3), atan2(value3, value4), atan -- select atan2 (builtin function, result) --Testcase 678: SELECT atan2(value1, value2), atan2(value2, value3), atan2(value3, value4), atan2(value4, value1) FROM s3; - atan2 | atan2 | atan2 | atan2 -----------------------+------------------+-------------------+------------------- - 0.000999999666666867 | 1.57179632646156 | -3.14059265392313 | -1.56979632712823 - 0.00199999733333973 | 1.57279632412824 | -3.13959265625645 | -1.56879632946156 - 0.0029999910000486 | 1.57379631779495 | -3.13859266258974 | -1.56779633579485 - 0.00549994454267321 | 1.57629627133757 | -3.13609270904712 | -1.56529638225222 - 0.0109995563655408 | 1.58179588316044 | -3.13059309722425 | -1.55979677042936 - 0.0164985028695487 | 1.58729482966445 | -3.12509415072024 | -1.55429782392535 + atan2 | atan2 | atan2 | atan2 +-----------------------+--------------------+---------------------+--------------------- + 0.0009999996666668668 | 1.5717963264615635 | -3.1405926539231266 | -1.5697963271282298 + 0.0019999973333397333 | 1.5727963241282363 | -3.1395926562564536 | -1.5687963294615568 + 0.0029999910000485996 | 1.5737963177949452 | -3.1385926625897445 | -1.5677963357948481 + 0.005499944542673214 | 1.5762962713375699 | -3.1360927090471202 | -1.5652963822522235 + 0.010999556365540751 | 1.5817958831604373 | -3.1305930972242524 | -1.5597967704293558 + 0.01649850286954865 | 1.5872948296644454 | -3.1250941507202445 | -1.554297823925348 (6 rows) -- select atan2 (builtin function, not pushdown constraints, explain) @@ -6542,11 +6550,11 @@ SELECT atan2(value1, value2), atan2(value2, value3), atan2(value3, value4), atan -- select atan2 (builtin function, not pushdown constraints, result) --Testcase 680: SELECT atan2(value1, value2), atan2(value2, value3), atan2(value3, value4), atan2(value4, value1) FROM s3 WHERE to_hex(value2) != '64'; - atan2 | atan2 | atan2 | atan2 ----------------------+------------------+-------------------+------------------- - 0.00549994454267321 | 1.57629627133757 | -3.13609270904712 | -1.56529638225222 - 0.0109995563655408 | 1.58179588316044 | -3.13059309722425 | -1.55979677042936 - 0.0164985028695487 | 1.58729482966445 | -3.12509415072024 | -1.55429782392535 + atan2 | atan2 | atan2 | atan2 +----------------------+--------------------+---------------------+--------------------- + 0.005499944542673214 | 1.5762962713375699 | -3.1360927090471202 | -1.5652963822522235 + 0.010999556365540751 | 1.5817958831604373 | -3.1305930972242524 | -1.5597967704293558 + 0.01649850286954865 | 1.5872948296644454 | -3.1250941507202445 | -1.554297823925348 (3 rows) -- select atan2 (builtin function, pushdown constraints, explain) @@ -6563,11 +6571,11 @@ SELECT atan2(value1, value2), atan2(value2, value3), atan2(value3, value4), atan -- select atan2 (builtin function, pushdown constraints, result) --Testcase 682: SELECT atan2(value1, value2), atan2(value2, value3), atan2(value3, value4), atan2(value4, value1) FROM s3 WHERE value2 != 200; - atan2 | atan2 | atan2 | atan2 -----------------------+------------------+-------------------+------------------- - 0.000999999666666867 | 1.57179632646156 | -3.14059265392313 | -1.56979632712823 - 0.00199999733333973 | 1.57279632412824 | -3.13959265625645 | -1.56879632946156 - 0.0029999910000486 | 1.57379631779495 | -3.13859266258974 | -1.56779633579485 + atan2 | atan2 | atan2 | atan2 +-----------------------+--------------------+---------------------+--------------------- + 0.0009999996666668668 | 1.5717963264615635 | -3.1405926539231266 | -1.5697963271282298 + 0.0019999973333397333 | 1.5727963241282363 | -3.1395926562564536 | -1.5687963294615568 + 0.0029999910000485996 | 1.5737963177949452 | -3.1385926625897445 | -1.5677963357948481 (3 rows) -- select atan2 as nest function with agg (pushdown, explain) @@ -6584,9 +6592,9 @@ SELECT sum(value3), sum(value4),atan2(sum(value3), sum(value3)) FROM s3; -- select atan2 as nest function with agg (pushdown, result) --Testcase 684: SELECT sum(value3), sum(value4),atan2(sum(value3), sum(value3)) FROM s3; - sum | sum | atan2 -------+------+------------------- - -7.2 | -900 | -2.35619449019234 + sum | sum | atan2 +--------------------+------+-------------------- + -7.199999999999999 | -900 | -2.356194490192345 (1 row) -- select atan2 as nest with log2 (pushdown, explain) @@ -6609,24 +6617,24 @@ CONTEXT: PL/pgSQL function log2(double precision) line 3 at RAISE --Testcase 687: EXPLAIN VERBOSE SELECT atan2(value3, value4), pi(), 4.1 FROM s3; - QUERY PLAN ------------------------------------------------------------------------------------------------- + QUERY PLAN +------------------------------------------------------------------------------------------------- Foreign Scan on public.s3 (cost=10.00..2058.24 rows=2048 width=48) - Output: atan2(value3, (value4)::double precision), '3.14159265358979'::double precision, 4.1 + Output: atan2(value3, (value4)::double precision), '3.141592653589793'::double precision, 4.1 InfluxDB query: SELECT "value3", "value4" FROM "s3" (3 rows) -- select atan2 with non pushdown func and explicit constant (result) --Testcase 688: SELECT atan2(value3, value4), pi(), 4.1 FROM s3; - atan2 | pi | ?column? --------------------+------------------+---------- - -3.14059265392313 | 3.14159265358979 | 4.1 - -3.13959265625645 | 3.14159265358979 | 4.1 - -3.13859266258974 | 3.14159265358979 | 4.1 - -3.13609270904712 | 3.14159265358979 | 4.1 - -3.13059309722425 | 3.14159265358979 | 4.1 - -3.12509415072024 | 3.14159265358979 | 4.1 + atan2 | pi | ?column? +---------------------+-------------------+---------- + -3.1405926539231266 | 3.141592653589793 | 4.1 + -3.1395926562564536 | 3.141592653589793 | 4.1 + -3.1385926625897445 | 3.141592653589793 | 4.1 + -3.1360927090471202 | 3.141592653589793 | 4.1 + -3.1305930972242524 | 3.141592653589793 | 4.1 + -3.1250941507202445 | 3.141592653589793 | 4.1 (6 rows) -- select atan2 with order by (explain) @@ -6646,53 +6654,53 @@ SELECT value1, atan2(1-value1, 1-value2) FROM s3 order by atan2(1-value1, 1-valu -- select atan2 with order by (result) --Testcase 690: SELECT value1, atan2(1-value1, 1-value2) FROM s3 order by atan2(1-value1, 1-value2); - value1 | atan2 ---------+------------------- - 1.1 | -3.14109014106928 - 2.2 | -3.13556257592532 - 3.3 | -3.13003537924322 - 0.1 | 3.13250199492473 - 0.2 | 3.13351202139289 - 0.3 | 3.13452206434865 + value1 | atan2 +--------+--------------------- + 1.1 | -3.1410901410692773 + 2.2 | -3.1355625759253205 + 3.3 | -3.130035379243216 + 0.1 | 3.1325019949247332 + 0.2 | 3.1335120213928933 + 0.3 | 3.1345220643486456 (6 rows) -- select atan2 with order by index (result) --Testcase 691: SELECT value1, atan2(1-value1, 1-value2) FROM s3 order by 2,1; - value1 | atan2 ---------+------------------- - 1.1 | -3.14109014106928 - 2.2 | -3.13556257592532 - 3.3 | -3.13003537924322 - 0.1 | 3.13250199492473 - 0.2 | 3.13351202139289 - 0.3 | 3.13452206434865 + value1 | atan2 +--------+--------------------- + 1.1 | -3.1410901410692773 + 2.2 | -3.1355625759253205 + 3.3 | -3.130035379243216 + 0.1 | 3.1325019949247332 + 0.2 | 3.1335120213928933 + 0.3 | 3.1345220643486456 (6 rows) -- select atan2 with order by index (result) --Testcase 692: SELECT value1, atan2(1-value1, 1-value2) FROM s3 order by 1,2; - value1 | atan2 ---------+------------------- - 0.1 | 3.13250199492473 - 0.2 | 3.13351202139289 - 0.3 | 3.13452206434865 - 1.1 | -3.14109014106928 - 2.2 | -3.13556257592532 - 3.3 | -3.13003537924322 + value1 | atan2 +--------+--------------------- + 0.1 | 3.1325019949247332 + 0.2 | 3.1335120213928933 + 0.3 | 3.1345220643486456 + 1.1 | -3.1410901410692773 + 2.2 | -3.1355625759253205 + 3.3 | -3.130035379243216 (6 rows) -- select atan2 and as --Testcase 693: SELECT atan2(value3, value4) as atan21 FROM s3; - atan21 -------------------- - -3.14059265392313 - -3.13959265625645 - -3.13859266258974 - -3.13609270904712 - -3.13059309722425 - -3.12509415072024 + atan21 +--------------------- + -3.1405926539231266 + -3.1395926562564536 + -3.1385926625897445 + -3.1360927090471202 + -3.1305930972242524 + -3.1250941507202445 (6 rows) -- select atan2(*) (stub function, explain) @@ -6792,9 +6800,9 @@ SELECT sum(value3),ceil(sum(value3)) FROM s3; -- select ceil as nest function with agg (pushdown, result) --Testcase 703: SELECT sum(value3),ceil(sum(value3)) FROM s3; - sum | ceil -------+------ - -7.2 | -7 + sum | ceil +--------------------+------ + -7.199999999999999 | -7 (1 row) -- select ceil as nest with log2 (pushdown, explain) @@ -6820,21 +6828,21 @@ SELECT ceil(value3), pi(), 4.1 FROM s3; QUERY PLAN --------------------------------------------------------------------- Foreign Scan on public.s3 (cost=10.00..2566.40 rows=2560 width=48) - Output: ceil(value3), '3.14159265358979'::double precision, 4.1 + Output: ceil(value3), '3.141592653589793'::double precision, 4.1 InfluxDB query: SELECT "value3" FROM "s3" (3 rows) -- select ceil with non pushdown func and explicit constant (result) --Testcase 707: SELECT ceil(value3), pi(), 4.1 FROM s3; - ceil | pi | ?column? -------+------------------+---------- - -0 | 3.14159265358979 | 4.1 - -0 | 3.14159265358979 | 4.1 - -0 | 3.14159265358979 | 4.1 - -1 | 3.14159265358979 | 4.1 - -2 | 3.14159265358979 | 4.1 - -3 | 3.14159265358979 | 4.1 + ceil | pi | ?column? +------+-------------------+---------- + -0 | 3.141592653589793 | 4.1 + -0 | 3.141592653589793 | 4.1 + -0 | 3.141592653589793 | 4.1 + -1 | 3.141592653589793 | 4.1 + -2 | 3.141592653589793 | 4.1 + -3 | 3.141592653589793 | 4.1 (6 rows) -- select ceil with order by (explain) @@ -6972,14 +6980,14 @@ SELECT cos(value1), cos(value2), cos(value3), cos(value4) FROM s3; -- select cos (builtin function, result) --Testcase 720: SELECT cos(value1), cos(value2), cos(value3), cos(value4) FROM s3; - cos | cos | cos | cos ---------------------+-------------------+--------------------+------------------- - 0.995004165278026 | 0.862318872287684 | 0.995004165278026 | 0.862318872287684 - 0.980066577841242 | 0.862318872287684 | 0.980066577841242 | 0.862318872287684 - 0.955336489125606 | 0.862318872287684 | 0.955336489125606 | 0.862318872287684 - 0.453596121425577 | 0.487187675007006 | 0.453596121425577 | 0.487187675007006 - -0.588501117255346 | 0.487187675007006 | -0.588501117255346 | 0.487187675007006 - -0.987479769908865 | 0.487187675007006 | -0.987479769908865 | 0.487187675007006 + cos | cos | cos | cos +---------------------+---------------------+---------------------+--------------------- + 0.9950041652780258 | 0.8623188722876839 | 0.9950041652780258 | 0.8623188722876839 + 0.9800665778412416 | 0.8623188722876839 | 0.9800665778412416 | 0.8623188722876839 + 0.955336489125606 | 0.8623188722876839 | 0.955336489125606 | 0.8623188722876839 + 0.4535961214255773 | 0.48718767500700594 | 0.4535961214255773 | 0.48718767500700594 + -0.5885011172553458 | 0.48718767500700594 | -0.5885011172553458 | 0.48718767500700594 + -0.9874797699088649 | 0.48718767500700594 | -0.9874797699088649 | 0.48718767500700594 (6 rows) -- select cos (builtin function, not pushdown constraints, explain) @@ -6997,11 +7005,11 @@ SELECT cos(value1), cos(value2), cos(value3), cos(value4) FROM s3 WHERE to_hex(v -- select cos (builtin function, not pushdown constraints, result) --Testcase 722: SELECT cos(value1), cos(value2), cos(value3), cos(value4) FROM s3 WHERE to_hex(value2) != '64'; - cos | cos | cos | cos ---------------------+-------------------+--------------------+------------------- - 0.453596121425577 | 0.487187675007006 | 0.453596121425577 | 0.487187675007006 - -0.588501117255346 | 0.487187675007006 | -0.588501117255346 | 0.487187675007006 - -0.987479769908865 | 0.487187675007006 | -0.987479769908865 | 0.487187675007006 + cos | cos | cos | cos +---------------------+---------------------+---------------------+--------------------- + 0.4535961214255773 | 0.48718767500700594 | 0.4535961214255773 | 0.48718767500700594 + -0.5885011172553458 | 0.48718767500700594 | -0.5885011172553458 | 0.48718767500700594 + -0.9874797699088649 | 0.48718767500700594 | -0.9874797699088649 | 0.48718767500700594 (3 rows) -- select cos (builtin function, pushdown constraints, explain) @@ -7018,11 +7026,11 @@ SELECT cos(value1), cos(value2), cos(value3), cos(value4) FROM s3 WHERE value2 ! -- select cos (builtin function, pushdown constraints, result) --Testcase 724: SELECT cos(value1), cos(value2), cos(value3), cos(value4) FROM s3 WHERE value2 != 200; - cos | cos | cos | cos --------------------+-------------------+-------------------+------------------- - 0.995004165278026 | 0.862318872287684 | 0.995004165278026 | 0.862318872287684 - 0.980066577841242 | 0.862318872287684 | 0.980066577841242 | 0.862318872287684 - 0.955336489125606 | 0.862318872287684 | 0.955336489125606 | 0.862318872287684 + cos | cos | cos | cos +--------------------+--------------------+--------------------+-------------------- + 0.9950041652780258 | 0.8623188722876839 | 0.9950041652780258 | 0.8623188722876839 + 0.9800665778412416 | 0.8623188722876839 | 0.9800665778412416 | 0.8623188722876839 + 0.955336489125606 | 0.8623188722876839 | 0.955336489125606 | 0.8623188722876839 (3 rows) -- select cos as nest function with agg (pushdown, explain) @@ -7039,9 +7047,9 @@ SELECT sum(value3),cos(sum(value3)) FROM s3; -- select cos as nest function with agg (pushdown, result) --Testcase 726: SELECT sum(value3),cos(sum(value3)) FROM s3; - sum | cos -------+------------------- - -7.2 | 0.608351314532255 + sum | cos +--------------------+-------------------- + -7.199999999999999 | 0.6083513145322552 (1 row) -- select cos as nest with log2 (pushdown, explain) @@ -7067,21 +7075,21 @@ SELECT cos(value3), pi(), 4.1 FROM s3; QUERY PLAN --------------------------------------------------------------------- Foreign Scan on public.s3 (cost=10.00..2566.40 rows=2560 width=48) - Output: cos(value3), '3.14159265358979'::double precision, 4.1 + Output: cos(value3), '3.141592653589793'::double precision, 4.1 InfluxDB query: SELECT "value3" FROM "s3" (3 rows) -- select cos with non pushdown func and explicit constant (result) --Testcase 730: SELECT cos(value3), pi(), 4.1 FROM s3; - cos | pi | ?column? ---------------------+------------------+---------- - 0.995004165278026 | 3.14159265358979 | 4.1 - 0.980066577841242 | 3.14159265358979 | 4.1 - 0.955336489125606 | 3.14159265358979 | 4.1 - 0.453596121425577 | 3.14159265358979 | 4.1 - -0.588501117255346 | 3.14159265358979 | 4.1 - -0.987479769908865 | 3.14159265358979 | 4.1 + cos | pi | ?column? +---------------------+-------------------+---------- + 0.9950041652780258 | 3.141592653589793 | 4.1 + 0.9800665778412416 | 3.141592653589793 | 4.1 + 0.955336489125606 | 3.141592653589793 | 4.1 + 0.4535961214255773 | 3.141592653589793 | 4.1 + -0.5885011172553458 | 3.141592653589793 | 4.1 + -0.9874797699088649 | 3.141592653589793 | 4.1 (6 rows) -- select cos with order by (explain) @@ -7101,53 +7109,53 @@ SELECT value1, cos(1-value1) FROM s3 order by cos(1-value1); -- select cos with order by (result) --Testcase 732: SELECT value1, cos(1-value1) FROM s3 order by cos(1-value1); - value1 | cos ---------+-------------------- - 3.3 | -0.666276021279824 - 2.2 | 0.362357754476673 - 0.1 | 0.621609968270664 - 0.2 | 0.696706709347165 - 0.3 | 0.764842187284488 - 1.1 | 0.995004165278026 + value1 | cos +--------+--------------------- + 3.3 | -0.6662760212798241 + 2.2 | 0.3623577544766734 + 0.1 | 0.6216099682706644 + 0.2 | 0.6967067093471654 + 0.3 | 0.7648421872844885 + 1.1 | 0.9950041652780257 (6 rows) -- select cos with order by index (result) --Testcase 733: SELECT value1, cos(1-value1) FROM s3 order by 2,1; - value1 | cos ---------+-------------------- - 3.3 | -0.666276021279824 - 2.2 | 0.362357754476673 - 0.1 | 0.621609968270664 - 0.2 | 0.696706709347165 - 0.3 | 0.764842187284488 - 1.1 | 0.995004165278026 + value1 | cos +--------+--------------------- + 3.3 | -0.6662760212798241 + 2.2 | 0.3623577544766734 + 0.1 | 0.6216099682706644 + 0.2 | 0.6967067093471654 + 0.3 | 0.7648421872844885 + 1.1 | 0.9950041652780257 (6 rows) -- select cos with order by index (result) --Testcase 734: SELECT value1, cos(1-value1) FROM s3 order by 1,2; - value1 | cos ---------+-------------------- - 0.1 | 0.621609968270664 - 0.2 | 0.696706709347165 - 0.3 | 0.764842187284488 - 1.1 | 0.995004165278026 - 2.2 | 0.362357754476673 - 3.3 | -0.666276021279824 + value1 | cos +--------+--------------------- + 0.1 | 0.6216099682706644 + 0.2 | 0.6967067093471654 + 0.3 | 0.7648421872844885 + 1.1 | 0.9950041652780257 + 2.2 | 0.3623577544766734 + 3.3 | -0.6662760212798241 (6 rows) -- select cos and as --Testcase 735: SELECT cos(value3) as cos1 FROM s3; - cos1 --------------------- - 0.995004165278026 - 0.980066577841242 - 0.955336489125606 - 0.453596121425577 - -0.588501117255346 - -0.987479769908865 + cos1 +--------------------- + 0.9950041652780258 + 0.9800665778412416 + 0.955336489125606 + 0.4535961214255773 + -0.5885011172553458 + -0.9874797699088649 (6 rows) -- select cos(*) (stub agg function, explain) @@ -7203,14 +7211,14 @@ SELECT exp(value1), exp(value2), exp(value3), exp(value4) FROM s3; -- select exp (builtin function, result) --Testcase 741: SELECT exp(value1), exp(value2), exp(value3), exp(value4) FROM s3; - exp | exp | exp | exp -------------------+----------------------+-------------------+---------------------- - 1.10517091807565 | 2.68811714181614e+43 | 0.90483741803596 | 3.72007597602084e-44 - 1.22140275816017 | 2.68811714181614e+43 | 0.818730753077982 | 3.72007597602084e-44 - 1.349858807576 | 2.68811714181614e+43 | 0.740818220681718 | 3.72007597602084e-44 - 3.00416602394643 | 7.22597376812575e+86 | 0.33287108369808 | 1.38389652673674e-87 - 9.02501349943412 | 7.22597376812575e+86 | 0.110803158362334 | 1.38389652673674e-87 - 27.1126389206579 | 7.22597376812575e+86 | 0.03688316740124 | 1.38389652673674e-87 + exp | exp | exp | exp +--------------------+------------------------+----------------------+------------------------ + 1.1051709180756477 | 2.6881171418161356e+43 | 0.9048374180359595 | 3.720075976020836e-44 + 1.2214027581601699 | 2.6881171418161356e+43 | 0.8187307530779818 | 3.720075976020836e-44 + 1.3498588075760032 | 2.6881171418161356e+43 | 0.7408182206817179 | 3.720075976020836e-44 + 3.0041660239464334 | 7.225973768125749e+86 | 0.33287108369807955 | 1.3838965267367376e-87 + 9.025013499434122 | 7.225973768125749e+86 | 0.11080315836233387 | 1.3838965267367376e-87 + 27.112638920657883 | 7.225973768125749e+86 | 0.036883167401240015 | 1.3838965267367376e-87 (6 rows) -- select exp (builtin function, not pushdown constraints, explain) @@ -7228,11 +7236,11 @@ SELECT exp(value1), exp(value2), exp(value3), exp(value4) FROM s3 WHERE to_hex(v -- select exp (builtin function, not pushdown constraints, result) --Testcase 743: SELECT exp(value1), exp(value2), exp(value3), exp(value4) FROM s3 WHERE to_hex(value2) != '64'; - exp | exp | exp | exp -------------------+----------------------+-------------------+---------------------- - 3.00416602394643 | 7.22597376812575e+86 | 0.33287108369808 | 1.38389652673674e-87 - 9.02501349943412 | 7.22597376812575e+86 | 0.110803158362334 | 1.38389652673674e-87 - 27.1126389206579 | 7.22597376812575e+86 | 0.03688316740124 | 1.38389652673674e-87 + exp | exp | exp | exp +--------------------+-----------------------+----------------------+------------------------ + 3.0041660239464334 | 7.225973768125749e+86 | 0.33287108369807955 | 1.3838965267367376e-87 + 9.025013499434122 | 7.225973768125749e+86 | 0.11080315836233387 | 1.3838965267367376e-87 + 27.112638920657883 | 7.225973768125749e+86 | 0.036883167401240015 | 1.3838965267367376e-87 (3 rows) -- select exp (builtin function, pushdown constraints, explain) @@ -7249,11 +7257,11 @@ SELECT exp(value1), exp(value2), exp(value3), exp(value4) FROM s3 WHERE value2 ! -- select exp (builtin function, pushdown constraints, result) --Testcase 745: SELECT exp(value1), exp(value2), exp(value3), exp(value4) FROM s3 WHERE value2 != 200; - exp | exp | exp | exp -------------------+----------------------+-------------------+---------------------- - 1.10517091807565 | 2.68811714181614e+43 | 0.90483741803596 | 3.72007597602084e-44 - 1.22140275816017 | 2.68811714181614e+43 | 0.818730753077982 | 3.72007597602084e-44 - 1.349858807576 | 2.68811714181614e+43 | 0.740818220681718 | 3.72007597602084e-44 + exp | exp | exp | exp +--------------------+------------------------+--------------------+----------------------- + 1.1051709180756477 | 2.6881171418161356e+43 | 0.9048374180359595 | 3.720075976020836e-44 + 1.2214027581601699 | 2.6881171418161356e+43 | 0.8187307530779818 | 3.720075976020836e-44 + 1.3498588075760032 | 2.6881171418161356e+43 | 0.7408182206817179 | 3.720075976020836e-44 (3 rows) -- select exp as nest function with agg (pushdown, explain) @@ -7270,9 +7278,9 @@ SELECT sum(value3),exp(sum(value3)) FROM s3; -- select exp as nest function with agg (pushdown, result) --Testcase 747: SELECT sum(value3),exp(sum(value3)) FROM s3; - sum | exp -------+--------------------- - -7.2 | 0.00074658580837668 + sum | exp +--------------------+----------------------- + -7.199999999999999 | 0.0007465858083766799 (1 row) -- select exp as nest with log2 (pushdown, explain) @@ -7298,21 +7306,21 @@ SELECT exp(value3), pi(), 4.1 FROM s3; QUERY PLAN --------------------------------------------------------------------- Foreign Scan on public.s3 (cost=10.00..2566.40 rows=2560 width=48) - Output: exp(value3), '3.14159265358979'::double precision, 4.1 + Output: exp(value3), '3.141592653589793'::double precision, 4.1 InfluxDB query: SELECT "value3" FROM "s3" (3 rows) -- select exp with non pushdown func and explicit constant (result) --Testcase 751: SELECT exp(value3), pi(), 4.1 FROM s3; - exp | pi | ?column? --------------------+------------------+---------- - 0.90483741803596 | 3.14159265358979 | 4.1 - 0.818730753077982 | 3.14159265358979 | 4.1 - 0.740818220681718 | 3.14159265358979 | 4.1 - 0.33287108369808 | 3.14159265358979 | 4.1 - 0.110803158362334 | 3.14159265358979 | 4.1 - 0.03688316740124 | 3.14159265358979 | 4.1 + exp | pi | ?column? +----------------------+-------------------+---------- + 0.9048374180359595 | 3.141592653589793 | 4.1 + 0.8187307530779818 | 3.141592653589793 | 4.1 + 0.7408182206817179 | 3.141592653589793 | 4.1 + 0.33287108369807955 | 3.141592653589793 | 4.1 + 0.11080315836233387 | 3.141592653589793 | 4.1 + 0.036883167401240015 | 3.141592653589793 | 4.1 (6 rows) -- select exp with order by (explain) @@ -7332,53 +7340,53 @@ SELECT value1, exp(1-value1) FROM s3 order by exp(1-value1); -- select exp with order by (result) --Testcase 753: SELECT value1, exp(1-value1) FROM s3 order by exp(1-value1); - value1 | exp ---------+------------------- - 3.3 | 0.100258843722804 - 2.2 | 0.301194211912202 - 1.1 | 0.90483741803596 - 0.3 | 2.01375270747048 - 0.2 | 2.22554092849247 - 0.1 | 2.45960311115695 + value1 | exp +--------+--------------------- + 3.3 | 0.10025884372280375 + 2.2 | 0.301194211912202 + 1.1 | 0.9048374180359595 + 0.3 | 2.0137527074704766 + 0.2 | 2.225540928492468 + 0.1 | 2.45960311115695 (6 rows) -- select exp with order by index (result) --Testcase 754: SELECT value1, exp(1-value1) FROM s3 order by 2,1; - value1 | exp ---------+------------------- - 3.3 | 0.100258843722804 - 2.2 | 0.301194211912202 - 1.1 | 0.90483741803596 - 0.3 | 2.01375270747048 - 0.2 | 2.22554092849247 - 0.1 | 2.45960311115695 + value1 | exp +--------+--------------------- + 3.3 | 0.10025884372280375 + 2.2 | 0.301194211912202 + 1.1 | 0.9048374180359595 + 0.3 | 2.0137527074704766 + 0.2 | 2.225540928492468 + 0.1 | 2.45960311115695 (6 rows) -- select exp with order by index (result) --Testcase 755: SELECT value1, exp(1-value1) FROM s3 order by 1,2; - value1 | exp ---------+------------------- - 0.1 | 2.45960311115695 - 0.2 | 2.22554092849247 - 0.3 | 2.01375270747048 - 1.1 | 0.90483741803596 - 2.2 | 0.301194211912202 - 3.3 | 0.100258843722804 + value1 | exp +--------+--------------------- + 0.1 | 2.45960311115695 + 0.2 | 2.225540928492468 + 0.3 | 2.0137527074704766 + 1.1 | 0.9048374180359595 + 2.2 | 0.301194211912202 + 3.3 | 0.10025884372280375 (6 rows) -- select exp and as --Testcase 756: SELECT exp(value3) as exp1 FROM s3; - exp1 -------------------- - 0.90483741803596 - 0.818730753077982 - 0.740818220681718 - 0.33287108369808 - 0.110803158362334 - 0.03688316740124 + exp1 +---------------------- + 0.9048374180359595 + 0.8187307530779818 + 0.7408182206817179 + 0.33287108369807955 + 0.11080315836233387 + 0.036883167401240015 (6 rows) -- select exp(*) (stub agg function, explain) @@ -7506,9 +7514,9 @@ SELECT sum(value3),floor(sum(value3)) FROM s3; -- select floor as nest function with agg (pushdown, result) --Testcase 769: SELECT sum(value3),floor(sum(value3)) FROM s3; - sum | floor -------+------- - -7.2 | -8 + sum | floor +--------------------+------- + -7.199999999999999 | -8 (1 row) -- select floor as nest with log2 (pushdown, explain) @@ -7534,21 +7542,21 @@ SELECT floor(value3), pi(), 4.1 FROM s3; QUERY PLAN --------------------------------------------------------------------- Foreign Scan on public.s3 (cost=10.00..2566.40 rows=2560 width=48) - Output: floor(value3), '3.14159265358979'::double precision, 4.1 + Output: floor(value3), '3.141592653589793'::double precision, 4.1 InfluxDB query: SELECT "value3" FROM "s3" (3 rows) -- select floor with non pushdown func and explicit constant (result) --Testcase 773: SELECT floor(value3), pi(), 4.1 FROM s3; - floor | pi | ?column? --------+------------------+---------- - -1 | 3.14159265358979 | 4.1 - -1 | 3.14159265358979 | 4.1 - -1 | 3.14159265358979 | 4.1 - -2 | 3.14159265358979 | 4.1 - -3 | 3.14159265358979 | 4.1 - -4 | 3.14159265358979 | 4.1 + floor | pi | ?column? +-------+-------------------+---------- + -1 | 3.141592653589793 | 4.1 + -1 | 3.141592653589793 | 4.1 + -1 | 3.141592653589793 | 4.1 + -2 | 3.141592653589793 | 4.1 + -3 | 3.141592653589793 | 4.1 + -4 | 3.141592653589793 | 4.1 (6 rows) -- select floor with order by (explain) @@ -7686,14 +7694,14 @@ SELECT ln(value1), ln(value2) FROM s3; -- select ln (builtin function, result) --Testcase 786: SELECT ln(value1), ln(value2) FROM s3; - ln | ln ---------------------+------------------ - -2.30258509299405 | 4.60517018598809 - -1.6094379124341 | 4.60517018598809 - -1.20397280432594 | 4.60517018598809 - 0.0953101798043249 | 5.29831736654804 - 0.78845736036427 | 5.29831736654804 - 1.19392246847243 | 5.29831736654804 + ln | ln +---------------------+------------------- + -2.3025850929940455 | 4.605170185988092 + -1.6094379124341003 | 4.605170185988092 + -1.2039728043259361 | 4.605170185988092 + 0.09531017980432493 | 5.298317366548036 + 0.7884573603642703 | 5.298317366548036 + 1.1939224684724346 | 5.298317366548036 (6 rows) -- select ln (builtin function, not pushdown constraints, explain) @@ -7711,11 +7719,11 @@ SELECT ln(value1), ln(value2) FROM s3 WHERE to_hex(value2) != '64'; -- select ln (builtin function, not pushdown constraints, result) --Testcase 788: SELECT ln(value1), ln(value2) FROM s3 WHERE to_hex(value2) != '64'; - ln | ln ---------------------+------------------ - 0.0953101798043249 | 5.29831736654804 - 0.78845736036427 | 5.29831736654804 - 1.19392246847243 | 5.29831736654804 + ln | ln +---------------------+------------------- + 0.09531017980432493 | 5.298317366548036 + 0.7884573603642703 | 5.298317366548036 + 1.1939224684724346 | 5.298317366548036 (3 rows) -- select ln (builtin function, pushdown constraints, explain) @@ -7732,11 +7740,11 @@ SELECT ln(value1), ln(value2) FROM s3 WHERE value2 != 200; -- select ln (builtin function, pushdown constraints, result) --Testcase 790: SELECT ln(value1), ln(value2) FROM s3 WHERE value2 != 200; - ln | ln --------------------+------------------ - -2.30258509299405 | 4.60517018598809 - -1.6094379124341 | 4.60517018598809 - -1.20397280432594 | 4.60517018598809 + ln | ln +---------------------+------------------- + -2.3025850929940455 | 4.605170185988092 + -1.6094379124341003 | 4.605170185988092 + -1.2039728043259361 | 4.605170185988092 (3 rows) -- select ln as nest function with agg (pushdown, explain) @@ -7753,9 +7761,9 @@ SELECT sum(value3),ln(sum(value3)) FROM s3; -- select ln as nest function with agg (pushdown, result) --Testcase 792: SELECT sum(value3),ln(sum(value3)) FROM s3; - sum | ln -------+---- - -7.2 | + sum | ln +--------------------+---- + -7.199999999999999 | (1 row) -- select ln as nest with log2 (pushdown, explain) @@ -7781,7 +7789,7 @@ SELECT ln(value3), pi(), 4.1 FROM s3; QUERY PLAN --------------------------------------------------------------------- Foreign Scan on public.s3 (cost=10.00..2566.40 rows=2560 width=48) - Output: ln(value3), '3.14159265358979'::double precision, 4.1 + Output: ln(value3), '3.141592653589793'::double precision, 4.1 InfluxDB query: SELECT "value3" FROM "s3" (3 rows) @@ -7818,14 +7826,14 @@ ERROR: cannot take logarithm of a negative number -- select ln and as --Testcase 801: SELECT ln(value1) as ln1 FROM s3; - ln1 --------------------- - -2.30258509299405 - -1.6094379124341 - -1.20397280432594 - 0.0953101798043249 - 0.78845736036427 - 1.19392246847243 + ln1 +--------------------- + -2.3025850929940455 + -1.6094379124341003 + -1.2039728043259361 + 0.09531017980432493 + 0.7884573603642703 + 1.1939224684724346 (6 rows) -- select ln(*) (stub agg function, explain) @@ -7886,14 +7894,14 @@ SELECT pow(value1, 2), pow(value2, 2), pow(value3, 2), pow(value4, 2) FROM s3; -- select pow (builtin function, result) --Testcase 808: SELECT pow(value1, 2), pow(value2, 2), pow(value3, 2), pow(value4, 2) FROM s3; - pow | pow | pow | pow --------+-------+-------+------- - 0.01 | 10000 | 0.01 | 10000 - 0.04 | 10000 | 0.04 | 10000 - 0.09 | 10000 | 0.09 | 10000 - 1.21 | 40000 | 1.21 | 40000 - 4.84 | 40000 | 4.84 | 40000 - 10.89 | 40000 | 10.89 | 40000 + pow | pow | pow | pow +----------------------+-------+----------------------+------- + 0.010000000000000002 | 10000 | 0.010000000000000002 | 10000 + 0.04000000000000001 | 10000 | 0.04000000000000001 | 10000 + 0.09 | 10000 | 0.09 | 10000 + 1.2100000000000002 | 40000 | 1.2100000000000002 | 40000 + 4.840000000000001 | 40000 | 4.840000000000001 | 40000 + 10.889999999999999 | 40000 | 10.889999999999999 | 40000 (6 rows) -- select pow (builtin function, not pushdown constraints, explain) @@ -7911,11 +7919,11 @@ SELECT pow(value1, 2), pow(value2, 2), pow(value3, 2), pow(value4, 2) FROM s3 WH -- select pow (builtin function, not pushdown constraints, result) --Testcase 810: SELECT pow(value1, 2), pow(value2, 2), pow(value3, 2), pow(value4, 2) FROM s3 WHERE to_hex(value2) != '64'; - pow | pow | pow | pow --------+-------+-------+------- - 1.21 | 40000 | 1.21 | 40000 - 4.84 | 40000 | 4.84 | 40000 - 10.89 | 40000 | 10.89 | 40000 + pow | pow | pow | pow +--------------------+-------+--------------------+------- + 1.2100000000000002 | 40000 | 1.2100000000000002 | 40000 + 4.840000000000001 | 40000 | 4.840000000000001 | 40000 + 10.889999999999999 | 40000 | 10.889999999999999 | 40000 (3 rows) -- select pow (builtin function, pushdown constraints, explain) @@ -7932,11 +7940,11 @@ SELECT pow(value1, 2), pow(value2, 2), pow(value3, 2), pow(value4, 2) FROM s3 WH -- select pow (builtin function, pushdown constraints, result) --Testcase 812: SELECT pow(value1, 2), pow(value2, 2), pow(value3, 2), pow(value4, 2) FROM s3 WHERE value2 != 200; - pow | pow | pow | pow -------+-------+------+------- - 0.01 | 10000 | 0.01 | 10000 - 0.04 | 10000 | 0.04 | 10000 - 0.09 | 10000 | 0.09 | 10000 + pow | pow | pow | pow +----------------------+-------+----------------------+------- + 0.010000000000000002 | 10000 | 0.010000000000000002 | 10000 + 0.04000000000000001 | 10000 | 0.04000000000000001 | 10000 + 0.09 | 10000 | 0.09 | 10000 (3 rows) -- select pow as nest function with agg (pushdown, explain) @@ -7953,9 +7961,9 @@ SELECT sum(value3),pow(sum(value3), 2) FROM s3; -- select pow as nest function with agg (pushdown, result) --Testcase 814: SELECT sum(value3),pow(sum(value3), 2) FROM s3; - sum | pow -------+------- - -7.2 | 51.84 + sum | pow +--------------------+------------------- + -7.199999999999999 | 51.83999999999999 (1 row) -- select pow as nest with log2 (pushdown, explain) @@ -7978,24 +7986,24 @@ CONTEXT: PL/pgSQL function log2(double precision) line 3 at RAISE --Testcase 817: EXPLAIN VERBOSE SELECT pow(value3, 2), pi(), 4.1 FROM s3; - QUERY PLAN ------------------------------------------------------------------------------------------ + QUERY PLAN +------------------------------------------------------------------------------------------ Foreign Scan on public.s3 (cost=10.00..2566.40 rows=2560 width=48) - Output: pow(value3, '2'::double precision), '3.14159265358979'::double precision, 4.1 + Output: pow(value3, '2'::double precision), '3.141592653589793'::double precision, 4.1 InfluxDB query: SELECT "value3" FROM "s3" (3 rows) -- select pow with non pushdown func and explicit constant (result) --Testcase 818: SELECT pow(value3, 2), pi(), 4.1 FROM s3; - pow | pi | ?column? --------+------------------+---------- - 0.01 | 3.14159265358979 | 4.1 - 0.04 | 3.14159265358979 | 4.1 - 0.09 | 3.14159265358979 | 4.1 - 1.21 | 3.14159265358979 | 4.1 - 4.84 | 3.14159265358979 | 4.1 - 10.89 | 3.14159265358979 | 4.1 + pow | pi | ?column? +----------------------+-------------------+---------- + 0.010000000000000002 | 3.141592653589793 | 4.1 + 0.04000000000000001 | 3.141592653589793 | 4.1 + 0.09 | 3.141592653589793 | 4.1 + 1.2100000000000002 | 3.141592653589793 | 4.1 + 4.840000000000001 | 3.141592653589793 | 4.1 + 10.889999999999999 | 3.141592653589793 | 4.1 (6 rows) -- select pow with order by (explain) @@ -8015,53 +8023,53 @@ SELECT value1, pow(1-value1, 2) FROM s3 order by pow(1-value1, 2); -- select pow with order by (result) --Testcase 820: SELECT value1, pow(1-value1, 2) FROM s3 order by pow(1-value1, 2); - value1 | pow ---------+------ - 1.1 | 0.01 - 0.3 | 0.49 - 0.2 | 0.64 - 0.1 | 0.81 - 2.2 | 1.44 - 3.3 | 5.29 + value1 | pow +--------+---------------------- + 1.1 | 0.010000000000000018 + 0.3 | 0.48999999999999994 + 0.2 | 0.6400000000000001 + 0.1 | 0.81 + 2.2 | 1.4400000000000004 + 3.3 | 5.289999999999999 (6 rows) -- select pow with order by index (result) --Testcase 821: SELECT value1, pow(1-value1, 2) FROM s3 order by 2,1; - value1 | pow ---------+------ - 1.1 | 0.01 - 0.3 | 0.49 - 0.2 | 0.64 - 0.1 | 0.81 - 2.2 | 1.44 - 3.3 | 5.29 + value1 | pow +--------+---------------------- + 1.1 | 0.010000000000000018 + 0.3 | 0.48999999999999994 + 0.2 | 0.6400000000000001 + 0.1 | 0.81 + 2.2 | 1.4400000000000004 + 3.3 | 5.289999999999999 (6 rows) -- select pow with order by index (result) --Testcase 822: SELECT value1, pow(1-value1, 2) FROM s3 order by 1,2; - value1 | pow ---------+------ - 0.1 | 0.81 - 0.2 | 0.64 - 0.3 | 0.49 - 1.1 | 0.01 - 2.2 | 1.44 - 3.3 | 5.29 + value1 | pow +--------+---------------------- + 0.1 | 0.81 + 0.2 | 0.6400000000000001 + 0.3 | 0.48999999999999994 + 1.1 | 0.010000000000000018 + 2.2 | 1.4400000000000004 + 3.3 | 5.289999999999999 (6 rows) -- select pow and as --Testcase 823: SELECT pow(value3, 2) as pow1 FROM s3; - pow1 -------- - 0.01 - 0.04 - 0.09 - 1.21 - 4.84 - 10.89 + pow1 +---------------------- + 0.010000000000000002 + 0.04000000000000001 + 0.09 + 1.2100000000000002 + 4.840000000000001 + 10.889999999999999 (6 rows) -- select pow_all(2) (stub agg function, explain) @@ -8200,9 +8208,9 @@ SELECT sum(value3),round(sum(value3)) FROM s3; -- select round as nest function with agg (pushdown, result) --Testcase 837: SELECT sum(value3),round(sum(value3)) FROM s3; - sum | round -------+------- - -7.2 | -7 + sum | round +--------------------+------- + -7.199999999999999 | -7 (1 row) -- select round as nest with log2 (pushdown, explain) @@ -8228,21 +8236,21 @@ SELECT round(value3), pi(), 4.1 FROM s3; QUERY PLAN --------------------------------------------------------------------- Foreign Scan on public.s3 (cost=10.00..2566.40 rows=2560 width=48) - Output: round(value3), '3.14159265358979'::double precision, 4.1 + Output: round(value3), '3.141592653589793'::double precision, 4.1 InfluxDB query: SELECT "value3" FROM "s3" (3 rows) -- select round with non pushdown func and roundlicit constant (result) --Testcase 841: SELECT round(value3), pi(), 4.1 FROM s3; - round | pi | ?column? --------+------------------+---------- - -0 | 3.14159265358979 | 4.1 - -0 | 3.14159265358979 | 4.1 - -0 | 3.14159265358979 | 4.1 - -1 | 3.14159265358979 | 4.1 - -2 | 3.14159265358979 | 4.1 - -3 | 3.14159265358979 | 4.1 + round | pi | ?column? +-------+-------------------+---------- + -0 | 3.141592653589793 | 4.1 + -0 | 3.141592653589793 | 4.1 + -0 | 3.141592653589793 | 4.1 + -1 | 3.141592653589793 | 4.1 + -2 | 3.141592653589793 | 4.1 + -3 | 3.141592653589793 | 4.1 (6 rows) -- select round with order by (explain) @@ -8380,14 +8388,14 @@ SELECT sin(value1), sin(value2), sin(value3), sin(value4) FROM s3; -- select sin (builtin function, result) --Testcase 854: SELECT sin(value1), sin(value2), sin(value3), sin(value4) FROM s3; - sin | sin | sin | sin ---------------------+--------------------+---------------------+------------------- - 0.0998334166468282 | -0.506365641109759 | -0.0998334166468282 | 0.506365641109759 - 0.198669330795061 | -0.506365641109759 | -0.198669330795061 | 0.506365641109759 - 0.29552020666134 | -0.506365641109759 | -0.29552020666134 | 0.506365641109759 - 0.891207360061435 | -0.873297297213995 | -0.891207360061435 | 0.873297297213995 - 0.80849640381959 | -0.873297297213995 | -0.80849640381959 | 0.873297297213995 - -0.157745694143248 | -0.873297297213995 | 0.157745694143248 | 0.873297297213995 + sin | sin | sin | sin +---------------------+---------------------+----------------------+-------------------- + 0.09983341664682815 | -0.5063656411097588 | -0.09983341664682815 | 0.5063656411097588 + 0.19866933079506122 | -0.5063656411097588 | -0.19866933079506122 | 0.5063656411097588 + 0.29552020666133955 | -0.5063656411097588 | -0.29552020666133955 | 0.5063656411097588 + 0.8912073600614354 | -0.8732972972139946 | -0.8912073600614354 | 0.8732972972139946 + 0.8084964038195901 | -0.8732972972139946 | -0.8084964038195901 | 0.8732972972139946 + -0.1577456941432482 | -0.8732972972139946 | 0.1577456941432482 | 0.8732972972139946 (6 rows) -- select sin (builtin function, not pushdown constraints, explain) @@ -8405,11 +8413,11 @@ SELECT sin(value1), sin(value2), sin(value3), sin(value4) FROM s3 WHERE to_hex(v -- select sin (builtin function, not pushdown constraints, result) --Testcase 856: SELECT sin(value1), sin(value2), sin(value3), sin(value4) FROM s3 WHERE to_hex(value2) != '64'; - sin | sin | sin | sin ---------------------+--------------------+--------------------+------------------- - 0.891207360061435 | -0.873297297213995 | -0.891207360061435 | 0.873297297213995 - 0.80849640381959 | -0.873297297213995 | -0.80849640381959 | 0.873297297213995 - -0.157745694143248 | -0.873297297213995 | 0.157745694143248 | 0.873297297213995 + sin | sin | sin | sin +---------------------+---------------------+---------------------+-------------------- + 0.8912073600614354 | -0.8732972972139946 | -0.8912073600614354 | 0.8732972972139946 + 0.8084964038195901 | -0.8732972972139946 | -0.8084964038195901 | 0.8732972972139946 + -0.1577456941432482 | -0.8732972972139946 | 0.1577456941432482 | 0.8732972972139946 (3 rows) -- select sin (builtin function, pushdown constraints, explain) @@ -8426,11 +8434,11 @@ SELECT sin(value1), sin(value2), sin(value3), sin(value4) FROM s3 WHERE value2 ! -- select sin (builtin function, pushdown constraints, result) --Testcase 858: SELECT sin(value1), sin(value2), sin(value3), sin(value4) FROM s3 WHERE value2 != 200; - sin | sin | sin | sin ---------------------+--------------------+---------------------+------------------- - 0.0998334166468282 | -0.506365641109759 | -0.0998334166468282 | 0.506365641109759 - 0.198669330795061 | -0.506365641109759 | -0.198669330795061 | 0.506365641109759 - 0.29552020666134 | -0.506365641109759 | -0.29552020666134 | 0.506365641109759 + sin | sin | sin | sin +---------------------+---------------------+----------------------+-------------------- + 0.09983341664682815 | -0.5063656411097588 | -0.09983341664682815 | 0.5063656411097588 + 0.19866933079506122 | -0.5063656411097588 | -0.19866933079506122 | 0.5063656411097588 + 0.29552020666133955 | -0.5063656411097588 | -0.29552020666133955 | 0.5063656411097588 (3 rows) -- select sin as nest function with agg (pushdown, explain) @@ -8447,9 +8455,9 @@ SELECT sum(value3),sin(sum(value3)) FROM s3; -- select sin as nest function with agg (pushdown, result) --Testcase 860: SELECT sum(value3),sin(sum(value3)) FROM s3; - sum | sin -------+-------------------- - -7.2 | -0.793667863849153 + sum | sin +--------------------+--------------------- + -7.199999999999999 | -0.7936678638491526 (1 row) -- select sin as nest with log2 (pushdown, explain) @@ -8475,21 +8483,21 @@ SELECT sin(value3), pi(), 4.1 FROM s3; QUERY PLAN --------------------------------------------------------------------- Foreign Scan on public.s3 (cost=10.00..2566.40 rows=2560 width=48) - Output: sin(value3), '3.14159265358979'::double precision, 4.1 + Output: sin(value3), '3.141592653589793'::double precision, 4.1 InfluxDB query: SELECT "value3" FROM "s3" (3 rows) -- select sin with non pushdown func and explicit constant (result) --Testcase 864: SELECT sin(value3), pi(), 4.1 FROM s3; - sin | pi | ?column? ----------------------+------------------+---------- - -0.0998334166468282 | 3.14159265358979 | 4.1 - -0.198669330795061 | 3.14159265358979 | 4.1 - -0.29552020666134 | 3.14159265358979 | 4.1 - -0.891207360061435 | 3.14159265358979 | 4.1 - -0.80849640381959 | 3.14159265358979 | 4.1 - 0.157745694143248 | 3.14159265358979 | 4.1 + sin | pi | ?column? +----------------------+-------------------+---------- + -0.09983341664682815 | 3.141592653589793 | 4.1 + -0.19866933079506122 | 3.141592653589793 | 4.1 + -0.29552020666133955 | 3.141592653589793 | 4.1 + -0.8912073600614354 | 3.141592653589793 | 4.1 + -0.8084964038195901 | 3.141592653589793 | 4.1 + 0.1577456941432482 | 3.141592653589793 | 4.1 (6 rows) -- select sin with order by (explain) @@ -8509,53 +8517,53 @@ SELECT value1, sin(1-value1) FROM s3 order by sin(1-value1); -- select sin with order by (result) --Testcase 866: SELECT value1, sin(1-value1) FROM s3 order by sin(1-value1); - value1 | sin ---------+--------------------- - 2.2 | -0.932039085967226 - 3.3 | -0.74570521217672 - 1.1 | -0.0998334166468282 - 0.3 | 0.644217687237691 - 0.2 | 0.717356090899523 - 0.1 | 0.783326909627483 + value1 | sin +--------+---------------------- + 2.2 | -0.9320390859672264 + 3.3 | -0.7457052121767203 + 1.1 | -0.09983341664682824 + 0.3 | 0.644217687237691 + 0.2 | 0.7173560908995228 + 0.1 | 0.7833269096274834 (6 rows) -- select sin with order by index (result) --Testcase 867: SELECT value1, sin(1-value1) FROM s3 order by 2,1; - value1 | sin ---------+--------------------- - 2.2 | -0.932039085967226 - 3.3 | -0.74570521217672 - 1.1 | -0.0998334166468282 - 0.3 | 0.644217687237691 - 0.2 | 0.717356090899523 - 0.1 | 0.783326909627483 + value1 | sin +--------+---------------------- + 2.2 | -0.9320390859672264 + 3.3 | -0.7457052121767203 + 1.1 | -0.09983341664682824 + 0.3 | 0.644217687237691 + 0.2 | 0.7173560908995228 + 0.1 | 0.7833269096274834 (6 rows) -- select sin with order by index (result) --Testcase 868: SELECT value1, sin(1-value1) FROM s3 order by 1,2; - value1 | sin ---------+--------------------- - 0.1 | 0.783326909627483 - 0.2 | 0.717356090899523 - 0.3 | 0.644217687237691 - 1.1 | -0.0998334166468282 - 2.2 | -0.932039085967226 - 3.3 | -0.74570521217672 + value1 | sin +--------+---------------------- + 0.1 | 0.7833269096274834 + 0.2 | 0.7173560908995228 + 0.3 | 0.644217687237691 + 1.1 | -0.09983341664682824 + 2.2 | -0.9320390859672264 + 3.3 | -0.7457052121767203 (6 rows) -- select sin and as --Testcase 869: SELECT sin(value3) as sin1 FROM s3; - sin1 ---------------------- - -0.0998334166468282 - -0.198669330795061 - -0.29552020666134 - -0.891207360061435 - -0.80849640381959 - 0.157745694143248 + sin1 +---------------------- + -0.09983341664682815 + -0.19866933079506122 + -0.29552020666133955 + -0.8912073600614354 + -0.8084964038195901 + 0.1577456941432482 (6 rows) -- select sin(*) (stub agg function, explain) @@ -8611,14 +8619,14 @@ SELECT tan(value1), tan(value2), tan(value3), tan(value4) FROM s3; -- select tan (builtin function, result) --Testcase 875: SELECT tan(value1), tan(value2), tan(value3), tan(value4) FROM s3; - tan | tan | tan | tan --------------------+--------------------+--------------------+------------------- - 0.100334672085451 | -0.587213915156929 | -0.100334672085451 | 0.587213915156929 - 0.202710035508673 | -0.587213915156929 | -0.202710035508673 | 0.587213915156929 - 0.309336249609623 | -0.587213915156929 | -0.309336249609623 | 0.587213915156929 - 1.96475965724865 | -1.79252748379038 | -1.96475965724865 | 1.79252748379038 - -1.37382305676879 | -1.79252748379038 | 1.37382305676879 | 1.79252748379038 - 0.159745747660032 | -1.79252748379038 | -0.159745747660032 | 1.79252748379038 + tan | tan | tan | tan +---------------------+---------------------+----------------------+-------------------- + 0.10033467208545055 | -0.5872139151569291 | -0.10033467208545055 | 0.5872139151569291 + 0.2027100355086725 | -0.5872139151569291 | -0.2027100355086725 | 0.5872139151569291 + 0.30933624960962325 | -0.5872139151569291 | -0.30933624960962325 | 0.5872139151569291 + 1.9647596572486523 | -1.7925274837903817 | -1.9647596572486523 | 1.7925274837903817 + -1.3738230567687946 | -1.7925274837903817 | 1.3738230567687946 | 1.7925274837903817 + 0.15974574766003222 | -1.7925274837903817 | -0.15974574766003222 | 1.7925274837903817 (6 rows) -- select tan (builtin function, not pushdown constraints, explain) @@ -8636,11 +8644,11 @@ SELECT tan(value1), tan(value2), tan(value3), tan(value4) FROM s3 WHERE to_hex(v -- select tan (builtin function, not pushdown constraints, result) --Testcase 877: SELECT tan(value1), tan(value2), tan(value3), tan(value4) FROM s3 WHERE to_hex(value2) != '64'; - tan | tan | tan | tan --------------------+-------------------+--------------------+------------------ - 1.96475965724865 | -1.79252748379038 | -1.96475965724865 | 1.79252748379038 - -1.37382305676879 | -1.79252748379038 | 1.37382305676879 | 1.79252748379038 - 0.159745747660032 | -1.79252748379038 | -0.159745747660032 | 1.79252748379038 + tan | tan | tan | tan +---------------------+---------------------+----------------------+-------------------- + 1.9647596572486523 | -1.7925274837903817 | -1.9647596572486523 | 1.7925274837903817 + -1.3738230567687946 | -1.7925274837903817 | 1.3738230567687946 | 1.7925274837903817 + 0.15974574766003222 | -1.7925274837903817 | -0.15974574766003222 | 1.7925274837903817 (3 rows) -- select tan (builtin function, pushdown constraints, explain) @@ -8657,11 +8665,11 @@ SELECT tan(value1), tan(value2), tan(value3), tan(value4) FROM s3 WHERE value2 ! -- select tan (builtin function, pushdown constraints, result) --Testcase 879: SELECT tan(value1), tan(value2), tan(value3), tan(value4) FROM s3 WHERE value2 != 200; - tan | tan | tan | tan --------------------+--------------------+--------------------+------------------- - 0.100334672085451 | -0.587213915156929 | -0.100334672085451 | 0.587213915156929 - 0.202710035508673 | -0.587213915156929 | -0.202710035508673 | 0.587213915156929 - 0.309336249609623 | -0.587213915156929 | -0.309336249609623 | 0.587213915156929 + tan | tan | tan | tan +---------------------+---------------------+----------------------+-------------------- + 0.10033467208545055 | -0.5872139151569291 | -0.10033467208545055 | 0.5872139151569291 + 0.2027100355086725 | -0.5872139151569291 | -0.2027100355086725 | 0.5872139151569291 + 0.30933624960962325 | -0.5872139151569291 | -0.30933624960962325 | 0.5872139151569291 (3 rows) -- select tan as nest function with agg (pushdown, explain) @@ -8678,9 +8686,9 @@ SELECT sum(value3),tan(sum(value3)) FROM s3; -- select tan as nest function with agg (pushdown, result) --Testcase 881: SELECT sum(value3),tan(sum(value3)) FROM s3; - sum | tan -------+------------------- - -7.2 | -1.30462094005564 + sum | tan +--------------------+--------------------- + -7.199999999999999 | -1.3046209400556357 (1 row) -- select tan as nest with log2 (pushdown, explain) @@ -8706,21 +8714,21 @@ SELECT tan(value3), pi(), 4.1 FROM s3; QUERY PLAN --------------------------------------------------------------------- Foreign Scan on public.s3 (cost=10.00..2566.40 rows=2560 width=48) - Output: tan(value3), '3.14159265358979'::double precision, 4.1 + Output: tan(value3), '3.141592653589793'::double precision, 4.1 InfluxDB query: SELECT "value3" FROM "s3" (3 rows) -- select tan with non pushdown func and tanlicit constant (result) --Testcase 885: SELECT tan(value3), pi(), 4.1 FROM s3; - tan | pi | ?column? ---------------------+------------------+---------- - -0.100334672085451 | 3.14159265358979 | 4.1 - -0.202710035508673 | 3.14159265358979 | 4.1 - -0.309336249609623 | 3.14159265358979 | 4.1 - -1.96475965724865 | 3.14159265358979 | 4.1 - 1.37382305676879 | 3.14159265358979 | 4.1 - -0.159745747660032 | 3.14159265358979 | 4.1 + tan | pi | ?column? +----------------------+-------------------+---------- + -0.10033467208545055 | 3.141592653589793 | 4.1 + -0.2027100355086725 | 3.141592653589793 | 4.1 + -0.30933624960962325 | 3.141592653589793 | 4.1 + -1.9647596572486523 | 3.141592653589793 | 4.1 + 1.3738230567687946 | 3.141592653589793 | 4.1 + -0.15974574766003222 | 3.141592653589793 | 4.1 (6 rows) -- select tan with order by (explain) @@ -8740,53 +8748,53 @@ SELECT value1, tan(1-value1) FROM s3 order by tan(1-value1); -- select tan with order by (result) --Testcase 887: SELECT value1, tan(1-value1) FROM s3 order by tan(1-value1); - value1 | tan ---------+-------------------- - 2.2 | -2.57215162212632 - 1.1 | -0.100334672085451 - 0.3 | 0.842288380463079 - 0.2 | 1.02963855705036 - 3.3 | 1.11921364173413 - 0.1 | 1.26015821755034 + value1 | tan +--------+---------------------- + 2.2 | -2.57215162212632 + 1.1 | -0.10033467208545063 + 0.3 | 0.8422883804630794 + 0.2 | 1.0296385570503641 + 3.3 | 1.1192136417341325 + 0.1 | 1.2601582175503392 (6 rows) -- select tan with order by index (result) --Testcase 888: SELECT value1, tan(1-value1) FROM s3 order by 2,1; - value1 | tan ---------+-------------------- - 2.2 | -2.57215162212632 - 1.1 | -0.100334672085451 - 0.3 | 0.842288380463079 - 0.2 | 1.02963855705036 - 3.3 | 1.11921364173413 - 0.1 | 1.26015821755034 + value1 | tan +--------+---------------------- + 2.2 | -2.57215162212632 + 1.1 | -0.10033467208545063 + 0.3 | 0.8422883804630794 + 0.2 | 1.0296385570503641 + 3.3 | 1.1192136417341325 + 0.1 | 1.2601582175503392 (6 rows) -- select tan with order by index (result) --Testcase 889: SELECT value1, tan(1-value1) FROM s3 order by 1,2; - value1 | tan ---------+-------------------- - 0.1 | 1.26015821755034 - 0.2 | 1.02963855705036 - 0.3 | 0.842288380463079 - 1.1 | -0.100334672085451 - 2.2 | -2.57215162212632 - 3.3 | 1.11921364173413 + value1 | tan +--------+---------------------- + 0.1 | 1.2601582175503392 + 0.2 | 1.0296385570503641 + 0.3 | 0.8422883804630794 + 1.1 | -0.10033467208545063 + 2.2 | -2.57215162212632 + 3.3 | 1.1192136417341325 (6 rows) -- select tan and as --Testcase 890: SELECT tan(value3) as tan1 FROM s3; - tan1 --------------------- - -0.100334672085451 - -0.202710035508673 - -0.309336249609623 - -1.96475965724865 - 1.37382305676879 - -0.159745747660032 + tan1 +---------------------- + -0.10033467208545055 + -0.2027100355086725 + -0.30933624960962325 + -1.9647596572486523 + 1.3738230567687946 + -0.15974574766003222 (6 rows) -- select tan(*) (stub agg function, explain) @@ -8847,13 +8855,13 @@ SELECT holt_winters(min(value1), 5, 1) FROM s3 WHERE time >= to_timestamp(0) and -- select predictors function holt_winters() (result) --Testcase 897: SELECT holt_winters(min(value1), 5, 1) FROM s3 WHERE time >= to_timestamp(0) and time <= to_timestamp(4) GROUP BY influx_time(time, interval '1s'); - holt_winters ------------------- - 5.18746006560853 - 13.2933307845701 - 37.5847742625017 - 116.557520596579 - 392.431171307496 + holt_winters +-------------------- + 5.187460065608529 + 13.293330784570104 + 37.584774262501654 + 116.55752059657874 + 392.43117130749647 (5 rows) -- select predictors function holt_winters_with_fit() (explain) @@ -8873,15 +8881,15 @@ SELECT holt_winters_with_fit(min(value1), 5, 1) FROM s3 WHERE time >= to_timesta holt_winters_with_fit ----------------------- 0.1 - 0.146569361982582 - 0.449297189927864 - 1.00876071385362 - 2.21894136309638 - 5.18746006560853 - 13.2933307845701 - 37.5847742625017 - 116.557520596579 - 392.431171307496 + 0.14656936198258175 + 0.44929718992786366 + 1.0087607138536199 + 2.218941363096379 + 5.187460065608529 + 13.293330784570104 + 37.584774262501654 + 116.55752059657874 + 392.43117130749647 (10 rows) -- select count(*) function of InfluxDB (stub agg function, explain) @@ -8955,19 +8963,19 @@ SELECT influx_count_all(*) FROM s3 WHERE time >= to_timestamp(0) and time <= to_ --Testcase 906: EXPLAIN VERBOSE SELECT influx_count_all(*) FROM s3 t1 INNER JOIN s3 t2 ON (t1.value1 = t2.value1) where t1.value1 = 0.1; - QUERY PLAN ---------------------------------------------------------------------------------------------------------- + QUERY PLAN +---------------------------------------------------------------------------------------- Aggregate (cost=70.39..70.41 rows=1 width=32) Output: influx_count_all(*) -> Nested Loop (cost=20.00..28.14 rows=169 width=0) -> Foreign Scan on public.s3 t1 (cost=10.00..13.00 rows=13 width=8) Output: t1."time", t1.tag1, t1.value1, t1.value2, t1.value3, t1.value4 - InfluxDB query: SELECT "value1" FROM "s3" WHERE (("value1" = 0.100000000000000006)) + InfluxDB query: SELECT "value1" FROM "s3" WHERE (("value1" = 0.1)) -> Materialize (cost=10.00..13.06 rows=13 width=8) Output: t2.value1 -> Foreign Scan on public.s3 t2 (cost=10.00..13.00 rows=13 width=8) Output: t2.value1 - InfluxDB query: SELECT "value1" FROM "s3" WHERE (("value1" = 0.100000000000000006)) + InfluxDB query: SELECT "value1" FROM "s3" WHERE (("value1" = 0.1)) (11 rows) -- select count(*) function of InfluxDB over join query (result, stub call error) @@ -9046,20 +9054,20 @@ SELECT influx_distinct(value2) FROM s3 WHERE time >= to_timestamp(0) and time <= --Testcase 914: EXPLAIN VERBOSE SELECT influx_distinct(t1.value2) FROM s3 t1 INNER JOIN s3 t2 ON (t1.value1 = t2.value1) where t1.value1 = 0.1; - QUERY PLAN -------------------------------------------------------------------------------------------------------------------- + QUERY PLAN +-------------------------------------------------------------------------------------------------- Aggregate (cost=57.15..57.16 rows=1 width=8) Output: influx_distinct(t1.value2) -> Nested Loop (cost=20.00..24.65 rows=130 width=8) Output: t1.value2 -> Foreign Scan on public.s3 t2 (cost=10.00..13.00 rows=13 width=8) Output: t2."time", t2.tag1, t2.value1, t2.value2, t2.value3, t2.value4 - InfluxDB query: SELECT "value1" FROM "s3" WHERE (("value1" = 0.100000000000000006)) + InfluxDB query: SELECT "value1" FROM "s3" WHERE (("value1" = 0.1)) -> Materialize (cost=10.00..10.05 rows=10 width=16) Output: t1.value2, t1.value1 -> Foreign Scan on public.s3 t1 (cost=10.00..10.00 rows=10 width=16) Output: t1.value2, t1.value1 - InfluxDB query: SELECT "value1", "value2" FROM "s3" WHERE (("value1" = 0.100000000000000006)) + InfluxDB query: SELECT "value1", "value2" FROM "s3" WHERE (("value1" = 0.1)) (12 rows) -- select distinct over join query (result, stub call error) @@ -9073,7 +9081,7 @@ EXPLAIN VERBOSE SELECT influx_distinct(value2) FROM s3 HAVING influx_distinct(value2) > 100; QUERY PLAN -------------------------------------------------------------------------- - Aggregate (cost=3840.00..3840.01 rows=1 width=8) + Aggregate (cost=3200.00..3200.01 rows=1 width=8) Output: influx_distinct(value2) Filter: (influx_distinct(s3.value2) > 100) -> Foreign Scan on public.s3 (cost=10.00..2560.00 rows=2560 width=8) @@ -9108,11 +9116,11 @@ SELECT sqrt(abs(value1)) FROM b3 WHERE value3 != true ORDER BY 1; -- bool type var in where clause (result) --Testcase 921: SELECT sqrt(abs(value1)) FROM b3 WHERE value3 != true ORDER BY 1; - sqrt -------------------- - 0.447213595499958 - 1.04880884817015 - 1.81659021245849 + sqrt +-------------------- + 0.4472135954999579 + 1.0488088481701516 + 1.816590212458495 (3 rows) --Testcase 922: diff --git a/influxdb_fdw.c b/influxdb_fdw.c index 16cb2f4..004d180 100644 --- a/influxdb_fdw.c +++ b/influxdb_fdw.c @@ -87,6 +87,9 @@ PG_MODULE_MAGIC; #define IS_KEY_COLUMN(A) ((strcmp(A->defname, "key") == 0) && \ (strcmp(((Value *)(A->arg))->val.str, "true") == 0)) +#define SPD_CMD_CREATE 0 +#define SPD_CMD_DROP 1 + extern Datum influxdb_fdw_handler(PG_FUNCTION_ARGS); extern Datum influxdb_fdw_validator(PG_FUNCTION_ARGS); @@ -243,6 +246,7 @@ static bool influxdb_contain_regex_star_functions(Node *clause); static int influxdb_get_batch_size_option(Relation rel); #endif static void influxdb_extract_slcols(InfluxDBFdwRelationInfo *fpinfo, PlannerInfo *root, RelOptInfo *baserel, List *tlist); +static bool influxdb_is_existed_measurement(Oid serverOid, char* tbl_name, influxdb_opt *options); #ifdef CXX_CLIENT #define free(x) pfree(x) @@ -605,13 +609,23 @@ influxdbGetForeignRelSize(PlannerInfo *root, RelOptInfo *baserel, Oid foreigntab InfluxDBFdwRelationInfo *fpinfo; influxdb_opt *options; ListCell *lc; + Oid userid; +#if PG_VERSION_NUM < 160000 + RangeTblEntry *rte = planner_rt_fetch(baserel->relid, root); +#endif elog(DEBUG1, "influxdb_fdw : %s", __func__); fpinfo = (InfluxDBFdwRelationInfo *) palloc0(sizeof(InfluxDBFdwRelationInfo)); baserel->fdw_private = (void *) fpinfo; +#if PG_VERSION_NUM >= 160000 + userid = OidIsValid(baserel->userid) ? baserel->userid : GetUserId(); +#else + userid = rte->checkAsUser ? rte->checkAsUser : GetUserId(); +#endif + /* Fetch the options */ - options = influxdb_get_options(foreigntableid); + options = influxdb_get_options(foreigntableid, userid); influxdb_get_schemaless_info(&(fpinfo->slinfo), options->schemaless, foreigntableid); @@ -955,8 +969,6 @@ influxdbGetForeignPlan(PlannerInfo *root, */ if (outer_plan) { - ListCell *lc; - /* * Right now, we only consider grouping and aggregation beyond * joins. Queries involving aggregates or grouping do not require @@ -1044,6 +1056,7 @@ influxdbBeginForeignScan(ForeignScanState *node, int eflags) int numParams; int rtindex; bool schemaless; + Oid userid; #ifdef CXX_CLIENT ForeignTable *ftable; #endif @@ -1067,26 +1080,34 @@ influxdbBeginForeignScan(ForeignScanState *node, int eflags) festate->cursor_exists = false; - /* - * Identify which user to do the remote access as. This should match what - * ExecCheckRTEPerms() does. In case of a join or aggregate, use the - * lowest-numbered member RTE as a representative; we would get the same - * result from any. - */ if (fsplan->scan.scanrelid > 0) rtindex = fsplan->scan.scanrelid; else +#if PG_VERSION_NUM < 160000 rtindex = bms_next_member(fsplan->fs_relids, -1); +#else + rtindex = bms_next_member(fsplan->fs_base_relids, -1); +#endif rte = exec_rt_fetch(rtindex, estate); +#if PG_VERSION_NUM >= 160000 + /* + * Identify which user to do the remote access as. This should match what + * ExecCheckPermissions() does. + */ + userid = OidIsValid(fsplan->checkAsUser) ? fsplan->checkAsUser : GetUserId(); +#else + userid = rte->checkAsUser ? rte->checkAsUser : GetUserId(); +#endif + /* Fetch options */ - festate->influxdbFdwOptions = influxdb_get_options(rte->relid); + festate->influxdbFdwOptions = influxdb_get_options(rte->relid, userid); #ifdef CXX_CLIENT if (!festate->influxdbFdwOptions->svr_version) festate->influxdbFdwOptions->svr_version = influxdb_get_version_option(festate->influxdbFdwOptions); /* get user mapping */ ftable = GetForeignTable(rte->relid); - festate->user = GetUserMapping(GetUserId(), ftable->serverid); + festate->user = GetUserMapping(userid, ftable->serverid); #endif influxdb_get_schemaless_info(&(festate->slinfo), schemaless, rte->relid); @@ -1315,8 +1336,8 @@ make_tuple_from_result_row(InfluxDBRow * result_row, Aggref *agg = (Aggref *) target; FuncExpr *func = (FuncExpr *) target; HeapTuple tuple; - bool is_func = false, - is_agg = false; + bool is_func = false; + bool is_agg_internal = false; bool funcstar = false; bool aggstar = false; Oid objectId = InvalidOid; @@ -1328,7 +1349,7 @@ make_tuple_from_result_row(InfluxDBRow * result_row, } else { - is_agg = true; + is_agg_internal = true; aggstar = agg->aggstar; objectId = agg->aggfnoid; } @@ -1348,7 +1369,7 @@ make_tuple_from_result_row(InfluxDBRow * result_row, * count(*) of postgreSQL return only 1 column, which is * different from InfluxDB. It does not need to go here. */ - if ((is_agg && !(aggstar && strcmp(opername, "count") == 0)) || is_func) + if ((is_agg_internal && !(aggstar && strcmp(opername, "count") == 0)) || is_func) { funcstar = influxdb_is_star_func(objectId, opername); @@ -1365,7 +1386,7 @@ make_tuple_from_result_row(InfluxDBRow * result_row, TargetEntry *tle; Node *n; - if (is_agg) + if (is_agg_internal) { regexlc = list_head(agg->args); tle = (TargetEntry *) lfirst(regexlc); @@ -1909,11 +1930,16 @@ influxdbBeginForeignModify(ModifyTableState *mtstate, Relation rel = resultRelInfo->ri_RelationDesc; AttrNumber n_params = 0; Oid typefnoid = InvalidOid; + Oid userid; bool isvarlena = false; ListCell *lc = NULL; Oid foreignTableId = InvalidOid; Plan *subplan; int i; +#if (PG_VERSION_NUM < 160000) + RangeTblEntry *rte; +#endif + #ifdef CXX_CLIENT ForeignTable *ftable; #endif @@ -1937,14 +1963,24 @@ influxdbBeginForeignModify(ModifyTableState *mtstate, fmstate = (InfluxDBFdwExecState *) palloc0(sizeof(InfluxDBFdwExecState)); fmstate->rowidx = 0; +#if (PG_VERSION_NUM >= 160000) + /* Identify which user to do the remote access as. */ + userid = ExecGetResultRelCheckAsUser(resultRelInfo, estate); +#else + /* Find RTE. */ + rte = exec_rt_fetch(resultRelInfo->ri_RangeTableIndex, + mtstate->ps.state); + userid = rte->checkAsUser ? rte->checkAsUser : GetUserId(); +#endif + /* Stash away the state info we have already */ - fmstate->influxdbFdwOptions = influxdb_get_options(foreignTableId); + fmstate->influxdbFdwOptions = influxdb_get_options(foreignTableId, userid); #ifdef CXX_CLIENT if (!fmstate->influxdbFdwOptions->svr_version) fmstate->influxdbFdwOptions->svr_version = influxdb_get_version_option(fmstate->influxdbFdwOptions); /* get user mapping */ ftable = GetForeignTable(foreignTableId); - fmstate->user = GetUserMapping(GetUserId(), ftable->serverid); + fmstate->user = GetUserMapping(userid, ftable->serverid); #endif fmstate->rel = rel; fmstate->query = strVal(list_nth(fdw_private, FdwModifyPrivateUpdateSql)); @@ -2102,9 +2138,7 @@ static int influxdbGetForeignModifyBatchSize(ResultRelInfo *resultRelInfo) { int batch_size; - InfluxDBFdwExecState *fmstate = resultRelInfo->ri_FdwState ? - (InfluxDBFdwExecState *) resultRelInfo->ri_FdwState : - NULL; + InfluxDBFdwExecState *fmstate = (InfluxDBFdwExecState *) resultRelInfo->ri_FdwState; elog(DEBUG1, "influxdb_fdw : %s", __func__); @@ -2112,8 +2146,9 @@ influxdbGetForeignModifyBatchSize(ResultRelInfo *resultRelInfo) Assert(resultRelInfo->ri_BatchSize == 0); /* - * Should never get called when the insert is being performed as part of a - * row movement operation. + * Should never get called when the insert is being performed on a table + * that is also among the target relations of an UPDATE operation, because + * postgresBeginForeignInsert() currently rejects such insert attempts. */ Assert(fmstate == NULL || fmstate->aux_fmstate == NULL); @@ -2327,7 +2362,11 @@ find_modifytable_subplan(PlannerInfo *root, { ForeignScan *fscan = (ForeignScan *) subplan; +#if PG_VERSION_NUM < 160000 if (bms_is_member(rtindex, fscan->fs_relids)) +#else + if (bms_is_member(rtindex, fscan->fs_base_relids)) +#endif return fscan; } @@ -2505,6 +2544,7 @@ influxdbBeginDirectModify(ForeignScanState *node, int eflags) EState *estate = node->ss.ps.state; InfluxDBFdwDirectModifyState *dmstate; Index rtindex; + Oid userid; RangeTblEntry *rte; int numParams; #ifdef CXX_CLIENT @@ -2527,30 +2567,34 @@ influxdbBeginDirectModify(ForeignScanState *node, int eflags) /* * Identify which user to do the remote access as. This should match what - * ExecCheckRTEPerms() does. + * ExecCheckPermissions() does. */ +#if (PG_VERSION_NUM >= 160000) + userid = OidIsValid(fsplan->checkAsUser) ? fsplan->checkAsUser : GetUserId(); + rtindex = node->resultRelInfo->ri_RangeTableIndex; +#else + userid = GetUserId(); #if (PG_VERSION_NUM < 140000) rtindex = estate->es_result_relation_info->ri_RangeTableIndex; #else rtindex = node->resultRelInfo->ri_RangeTableIndex; +#endif #endif rte = exec_rt_fetch(rtindex, estate); - - /* Get info about foreign table. */ if (fsplan->scan.scanrelid == 0) dmstate->rel = ExecOpenScanRelation(estate, rtindex, eflags); else dmstate->rel = node->ss.ss_currentRelation; /* Fetch options */ - dmstate->influxdbFdwOptions = influxdb_get_options(rte->relid); + dmstate->influxdbFdwOptions = influxdb_get_options(rte->relid, userid); #ifdef CXX_CLIENT if (!dmstate->influxdbFdwOptions->svr_version) dmstate->influxdbFdwOptions->svr_version = influxdb_get_version_option(dmstate->influxdbFdwOptions); /* get user mapping */ ftable = GetForeignTable(RelationGetRelid(dmstate->rel)); - dmstate->user = GetUserMapping(GetUserId(), ftable->serverid); + dmstate->user = GetUserMapping(userid, ftable->serverid); #endif /* Update the foreign-join-related fields. */ @@ -2777,7 +2821,7 @@ influxdbImportForeignSchema(ImportForeignSchemaStmt *stmt, errmsg("invalid option \"%s\"", def->defname))); } - options = influxdb_get_options(serverOid); + options = influxdb_get_options(serverOid, GetUserId()); #ifndef CXX_CLIENT ret = InfluxDBSchemaInfo(options->svr_address, options->svr_port, options->svr_username, options->svr_password, @@ -3052,7 +3096,11 @@ foreign_grouping_ok(PlannerInfo *root, RelOptInfo *grouped_rel) Index sgref = get_pathtarget_sortgroupref(grouping_target, i); ListCell *l; - /* Check whether this expression is part of GROUP BY clause */ + /* + * Check whether this expression is part of GROUP BY clause. Note we + * check the whole GROUP BY clause not just processed_groupClause, + * because we will ship all of it, cf. appendGroupByClause. + */ if (sgref && get_sortgroupref_clause_noerr(sgref, query->groupClause)) { TargetEntry *tle; @@ -3153,10 +3201,10 @@ foreign_grouping_ok(PlannerInfo *root, RelOptInfo *grouped_rel) */ foreach(l, aggvars) { - Expr *expr = (Expr *) lfirst(l); + Expr *aggref = (Expr *) lfirst(l); - if (IsA(expr, Aggref)) - tlist = add_to_flat_tlist(tlist, list_make1(expr)); + if (IsA(aggref, Aggref)) + tlist = add_to_flat_tlist(tlist, list_make1(aggref)); } } } @@ -3209,7 +3257,6 @@ foreign_grouping_ok(PlannerInfo *root, RelOptInfo *grouped_rel) if (fpinfo->local_conds) { List *aggvars = NIL; - ListCell *lc; foreach(lc, fpinfo->local_conds) { @@ -4119,3 +4166,121 @@ influxdb_get_batch_size_option(Relation rel) return batch_size; } #endif + +/* + * ExecForeignDDL is a public function that is called by core code. + * It executes DDL command on remote server. + * + * serverOid: remote server to get connected + * rel: relation to be created + * operation: + * 0: CREATE command + * 1: DROP command + * exists_flag: + * in CREATE DDL: true if `IF NOT EXIST` is specified + * in DROP DDL: true if `IF EXIST` is specified + */ +int +ExecForeignDDL(Oid serverOid, + Relation rel, + int operation, + bool exists_flag) +{ + char *ret_err; + StringInfoData sql; + influxdb_opt *options = NULL; + bool isExisted = false; + + elog(DEBUG1, "influxdb_fdw: %s", __func__); + + if (operation != SPD_CMD_CREATE && operation != SPD_CMD_DROP) + elog(ERROR, "Only support CREATE/DROP DATASOURCE"); + + options = influxdb_get_options(RelationGetRelid(rel), GetUserId()); + + /* Check if new datasource measurement is already existed or not */ + isExisted = influxdb_is_existed_measurement(serverOid, options->svr_table, options); + + /* CREATE new datasource */ + if (operation == SPD_CMD_CREATE) + { + if (!exists_flag && isExisted) + /* if CREATE without IF NOT EXIST and mesurement is existed, raise error. */ + elog(ERROR, "influxdb_fdw: table \"%s\" has already existed", options->svr_table); + else + /* New measurement will be created by INSERT operation, so it just return success */ + return 0; + } + + /* DROP datasource */ + if (!exists_flag && !isExisted) + /* if DROP without IF EXIST and mesurement is not existed, raise error. */ + elog(ERROR, "influxdb_fdw: table \"%s\" does not exist", options->svr_table); + + /* init sql query to drop InfluxDB measurement */ + initStringInfo(&sql); + + /* create DROP query */ + influxdb_deparse_drop_measurement_stmt(&sql, rel); + + ret_err = InfluxDBExecDDLCommand(options->svr_address, options->svr_port, + options->svr_username, options->svr_password, + options->svr_database, sql.data +#ifdef CXX_CLIENT + , options->svr_version, options->svr_token, options->svr_retention_policy +#endif + ); + + if (ret_err != NULL) + { + ereport(ERROR, + (errcode(ERRCODE_FDW_UNABLE_TO_CREATE_EXECUTION), + errmsg("influxdb_fdw : %s", ret_err))); + } + + pfree(sql.data); + + return 0; +} + +/* Check measurement is exised or not */ +static bool +influxdb_is_existed_measurement(Oid serverOid, char* tbl_name, influxdb_opt *options) +{ + StringInfoData influxql; + struct InfluxDBQuery_return volatile ret; + struct InfluxDBResult volatile *result = NULL; + bool found = false; + + initStringInfo(&influxql); + appendStringInfo(&influxql, "SHOW MEASUREMENTS ON %s WITH MEASUREMENT = %s", options->svr_database, tbl_name); + +#ifdef CXX_CLIENT + ret = InfluxDBQuery(influxql.data, GetUserMapping(GetUserId(), serverOid), options, +#else + ret = InfluxDBQuery(influxql.data, options->svr_address, options->svr_port, + options->svr_username, options->svr_password, + options->svr_database, +#endif + NULL, NULL, 0); + if (ret.r1 != NULL) + { + char *err = pstrdup(ret.r1); + + free(ret.r1); + ret.r1 = err; + elog(ERROR, "influxdb_fdw : %s", err); + } +#ifdef CXX_CLIENT + result = ret.r0; +#else + result = &ret.r0; +#endif + + found = (result && result->nrow == 1) ? true : false; + + if (result) + InfluxDBFreeResult((InfluxDBResult *)result); + + return found; +} diff --git a/influxdb_fdw.h b/influxdb_fdw.h index 7d47ee7..854735a 100644 --- a/influxdb_fdw.h +++ b/influxdb_fdw.h @@ -75,7 +75,7 @@ #define INFLUXDB_TARGETS_MIXING_AGGREF_UNSAFE (INFLUXDB_TARGETS_MARK_COLUMN | INFLUXDB_TARGETS_MARK_AGGREF) #define INFLUXDB_TARGETS_MIXING_AGGREF_SAFE (0u) -#define CODE_VERSION 20000 +#define CODE_VERSION 20100 #ifdef CXX_CLIENT #define INFLUXDB_VERSION_1 1 @@ -278,7 +278,7 @@ extern bool influxdb_is_foreign_function_tlist(PlannerInfo *root, /* option.c headers */ -extern influxdb_opt * influxdb_get_options(Oid foreigntableid); +extern influxdb_opt * influxdb_get_options(Oid foreigntableid, Oid userid); #ifdef CXX_CLIENT extern int influxdb_get_version_option(influxdb_opt *opt); #endif @@ -297,6 +297,7 @@ extern bool influxdb_deparse_direct_delete_sql(StringInfo buf, PlannerInfo *root List *remote_conds, List **params_list, List **retrieved_attrs); +extern void influxdb_deparse_drop_measurement_stmt(StringInfo buf, Relation rel); extern void influxdb_append_where_clause(StringInfo buf, PlannerInfo *root, RelOptInfo *baserel, List *exprs, bool is_first, List **params); extern void influxdb_deparse_analyze(StringInfo buf, char *dbname, char *relname); @@ -352,4 +353,13 @@ extern int check_connected_influxdb_version(char* addr, int port, char* user, ch /* clean up all cache connections of influx cxx client */ extern void cleanup_cxx_client_connection(void); #endif /* CXX_CLIENT */ + +extern +#if (PG_VERSION_NUM >= 160000) +PGDLLEXPORT +#endif +int ExecForeignDDL(Oid serverOid, + Relation rel, + int operation, + bool if_not_exists); #endif /* InfluxDB_FDW_H */ diff --git a/influxdb_query.c b/influxdb_query.c index ad41756..e54cd58 100644 --- a/influxdb_query.c +++ b/influxdb_query.c @@ -358,8 +358,8 @@ influxdb_bind_sql_var(Oid type, int idx, Datum value, bool *isnull, InfluxDBColu { /* Bind as string */ char *outputString = NULL; - Oid outputFunctionId = InvalidOid; - bool typeVarLength = false; + outputFunctionId = InvalidOid; + typeVarLength = false; getTypeOutputInfo(type, &outputFunctionId, &typeVarLength); outputString = OidOutputFunctionCall(outputFunctionId, value); @@ -371,15 +371,6 @@ influxdb_bind_sql_var(Oid type, int idx, Datum value, bool *isnull, InfluxDBColu case TIMESTAMPOID: case TIMESTAMPTZOID: { - /* Bind as string, but types is time */ - char *outputString = NULL; - Oid outputFunctionId = InvalidOid; - bool typeVarLength = false; - - getTypeOutputInfo(type, &outputFunctionId, &typeVarLength); - outputString = OidOutputFunctionCall(outputFunctionId, value); - param_influxdb_values[idx].s = outputString; -#ifdef CXX_CLIENT if (param_column_info[idx].column_type == INFLUXDB_TIME_KEY) { const int64 postgres_to_unix_epoch_usecs = (POSTGRES_EPOCH_JDATE - UNIX_EPOCH_JDATE) * USECS_PER_DAY; @@ -387,20 +378,27 @@ influxdb_bind_sql_var(Oid type, int idx, Datum value, bool *isnull, InfluxDBColu int64 valueNanoSecs = (valueTimestamp + postgres_to_unix_epoch_usecs) * 1000; param_influxdb_values[idx].i = valueNanoSecs; - } -#endif - /* - * In InfluxDB, Measurements,tag keys,tag values and field - * keys are always strings type. And Field values only can be - * floats, integers, strings, or Booleans. So if column isn't - * 'time' column in InfluxdDB, data will be store like strings - * in InfluxDB. - */ - if (param_column_info[idx].column_type != INFLUXDB_TIME_KEY) - param_influxdb_types[idx] = INFLUXDB_STRING; - else param_influxdb_types[idx] = INFLUXDB_TIME; - + } + else + { + /* Bind as string */ + char *outputString = NULL; + outputFunctionId = InvalidOid; + typeVarLength = false; + + getTypeOutputInfo(type, &outputFunctionId, &typeVarLength); + outputString = OidOutputFunctionCall(outputFunctionId, value); + param_influxdb_values[idx].s = outputString; + /* + * In InfluxDB, Measurements,tag keys,tag values and field + * keys are always strings type. And Field values only can be + * floats, integers, strings, or Booleans. So if column isn't + * 'time' column in InfluxdDB, data will be store like strings + * in InfluxDB. + */ + param_influxdb_types[idx] = INFLUXDB_STRING; + } break; } default: diff --git a/option.c b/option.c index b2ab305..eea01fd 100644 --- a/option.c +++ b/option.c @@ -123,6 +123,7 @@ influxdb_fdw_validator(PG_FUNCTION_ARGS) struct InfluxDBFdwOption *opt; StringInfoData buf; +#if PG_VERSIION_NUM < 160000 /* * Unknown option specified, complain about it. Provide a hint * with list of valid options for the object. @@ -142,6 +143,34 @@ influxdb_fdw_validator(PG_FUNCTION_ARGS) ? errhint("Valid options in this context are: %s", buf.data) : errhint("There are no valid options in this context."))); +#else + /* + * Unknown option specified, complain about it. Provide a hint + * with list of valid options for the object. + */ + const char *closest_match; + ClosestMatchState match_state; + bool has_valid_options = false; + + initClosestMatch(&match_state, def->defname, 4); + for (opt = valid_options; opt->optname; opt++) + { + if (catalog == opt->optcontext) + { + has_valid_options = true; + updateClosestMatch(&match_state, opt->optname); + } + } + + closest_match = getClosestMatch(&match_state); + ereport(ERROR, + (errcode(ERRCODE_FDW_INVALID_OPTION_NAME), + errmsg("invalid option \"%s\"", def->defname), + has_valid_options ? closest_match ? + errhint("Perhaps you meant the option \"%s\".", + closest_match) : 0 : + errhint("There are no valid options in this context."))); +#endif } /* @@ -209,7 +238,7 @@ influxdb_is_valid_option(const char *option, Oid context) * Fetch the options for a influxdb_fdw foreign table. */ influxdb_opt * -influxdb_get_options(Oid foreignoid) +influxdb_get_options(Oid foreignoid, Oid userid) { ForeignTable *f_table = NULL; ForeignServer *f_server = NULL; @@ -236,7 +265,7 @@ influxdb_get_options(Oid foreignoid) } PG_END_TRY(); - f_mapping = GetUserMapping(GetUserId(), f_server->serverid); + f_mapping = GetUserMapping(userid, f_server->serverid); options = NIL; if (f_table) diff --git a/query.cpp b/query.cpp index 1a54cce..efaa46a 100644 --- a/query.cpp +++ b/query.cpp @@ -402,20 +402,29 @@ InfluxDBInsert(char *tablename, UserMapping *user, influxdb_opt *opts, struct In auto influxdb = influxdb_get_connection(user, opts); try { + long long prev_time = 0; + long long cur_time; + influxdb->batchOf(cnumSlots); + + /* wait a microsecond to ensure different timestamps with previous batch */ + pg_usleep(1); + /* Write batches of cnumSlots points */ for (size_t idx = 0; idx < (size_t)cnumSlots; idx++) { influxdb::Point record(tablename); - /* - * InfluxDB does not accept two points with the same timestamp value, - * so, wait a microsecond to ensure that all inserted points have different timestamps - */ - pg_usleep(1); + /* Busy wait to different timestamp */ + do + { + cur_time = getCurrentMicroSecond(); + } + while (cur_time <= prev_time); + prev_time = cur_time; /* set current time in micro second as default */ - record.setTimestamp(getCurrentMicroSecond() * 1000); + record.setTimestamp(cur_time * 1000); for (size_t pos = 0; pos < (size_t)cparamNum; pos++) makeRecord(record, ccolumns + pos, ctypes[idx * cparamNum + pos], cvalues[idx * cparamNum + pos]); influxdb->write(std::move(record)); @@ -423,6 +432,8 @@ InfluxDBInsert(char *tablename, UserMapping *user, influxdb_opt *opts, struct In } catch (const std::exception& e) { + /* clean error batch */ + influxdb->clearBatch(); retMsg = (char *) palloc0(sizeof(char) * (strlen(e.what()) + 1)); strcpy(retMsg, e.what()); return retMsg; @@ -513,3 +524,63 @@ cleanup_cxx_client_connection(void) { influx_cleanup_connection(); } + +/* + * InfluxDBExecDDLCommand + * drop a measurement + * Return NULL if success, otherwise return error message + */ +extern "C" char * +InfluxDBExecDDLCommand(char* addr, int port, char* user, char* pass, char* db, char* cquery, int version, char* auth_token, char* retention_policy) +{ + std::unique_ptr influx; + char* retMsg = NULL; + bool retry_connect = false; + + if (version != INFLUXDB_VERSION_1 && version != INFLUXDB_VERSION_2) + { + /* Automatically detect InfluxDB version 1.x and 2.x: trying to connect InfluxDB v2.x first */ + influx = influxdb::InfluxDBFactory::GetV2(std::string(addr), port, std::string(db), std::string(auth_token), std::string(retention_policy)); + try + { + auto err = influx->query(cquery); + } + catch(const std::exception& e) + { + /* Trying to connect InfluxDB v1.x */ + retry_connect = true; + } + + if (!retry_connect) + return NULL; /* Query successfully */ + + influx = influxdb::InfluxDBFactory::GetV1(std::string(addr), port, std::string(db), std::string(user), std::string(pass)); + try + { + auto err = influx->query(cquery); + } + catch(const std::exception& e) + { + elog(ERROR, "influxdb_fdw: could not execute query: %s", cquery); + } + } + /* InfluxDB version is specified */ + else if (version == INFLUXDB_VERSION_1) + influx = influxdb::InfluxDBFactory::GetV1(std::string(addr), port, std::string(db), std::string(user), std::string(pass)); + else if (version == INFLUXDB_VERSION_2) + influx = influxdb::InfluxDBFactory::GetV2(std::string(addr), port, std::string(db), std::string(auth_token), std::string(retention_policy)); + + if (!influx) + elog(ERROR, "Fail to create influxDB client"); + + try + { + auto err = influx->query(cquery); + } + catch (const std::exception& e) + { + retMsg = (char *) pstrdup(e.what()); + } + + return retMsg; +} diff --git a/query.go b/query.go index 059f22a..a138396 100644 --- a/query.go +++ b/query.go @@ -289,7 +289,7 @@ func bindParameter(ctypes *C.InfluxDBType, cvalues *C.InfluxDBValue, cparamNum C //Each placeholder is "$1", "$2",...,so set "1","2",... to map key for i := range values { switch types[i] { - case C.INFLUXDB_INT64: + case C.INFLUXDB_TIME, C.INFLUXDB_INT64: //Cannot access union member in Go, so use cast query.Parameters[strconv.Itoa(i+1)] = *(*int64)(unsafe.Pointer(&values[i])) break @@ -307,16 +307,6 @@ func bindParameter(ctypes *C.InfluxDBType, cvalues *C.InfluxDBValue, cparamNum C case C.INFLUXDB_STRING: query.Parameters[strconv.Itoa(i+1)] = C.GoString(*(**C.char)(unsafe.Pointer(&(values[i])))) break - case C.INFLUXDB_TIME: - //We need to parse time value from String to Time type and back - timeString := C.GoString(*(**C.char)(unsafe.Pointer(&(values[i])))) - times, err := parseTime(timeString) - if err != nil { - //Parse time value unsuccessful - return err - } - query.Parameters[strconv.Itoa(i+1)] = times.Format(time.RFC3339Nano) - break case C.INFLUXDB_NULL: query.Parameters[strconv.Itoa(i+1)] = "" break @@ -490,12 +480,16 @@ func makeBatchPoint(db *C.char, tablename *C.char, ccolumns *C.struct_InfluxDBCo Database: C.GoString(db), }) + //Wait a microsecond to ensure different timestamps with previous batch + time.Sleep(1 * time.Microsecond) + //Initialize tags, fields and time value paramNum := int(cparamNum) * int(cnumSlots) endOfPoint := float64(cparamNum - 1) fields := make(map[string]interface{}) tags := make(map[string]string) timecol, _ := time.Parse(timestamptzFormat, time.Now().Format(timestamptzFormat)) + prev_time := timecol if cparamNum > 0 { columnInfo := (*[1 << 30]C.struct_InfluxDBColumnInfo)(unsafe.Pointer(ccolumns))[:paramNum:paramNum] @@ -540,14 +534,8 @@ func makeBatchPoint(db *C.char, tablename *C.char, ccolumns *C.struct_InfluxDBCo } break case C.INFLUXDB_TIME: - //We need to parse time value from String to Time type - timeString := C.GoString(*(**C.char)(unsafe.Pointer(&(values[i])))) - times, err := parseTime(timeString) - if err != nil { - //Parse time value unsuccessful - return bp, err - } - timecol = times + //Bind timestamp as epoch time + timecol = time.Unix(0, *(*int64)(unsafe.Pointer(&values[i]))) break case C.INFLUXDB_NULL: //We do not need append null value when execute INSERT @@ -569,7 +557,15 @@ func makeBatchPoint(db *C.char, tablename *C.char, ccolumns *C.struct_InfluxDBCo //Reset value of record fields = make(map[string]interface{}) tags = make(map[string]string) - timecol, _ = time.Parse(timestamptzFormat, time.Now().Format(timestamptzFormat)) + //Busy wait to different timestamp + for { + timecol, _ = time.Parse(timestamptzFormat, time.Now().Format(timestamptzFormat)) + if (timecol.After(prev_time)) { + break + } + } + prev_time = timecol + } } } @@ -609,6 +605,34 @@ func InfluxDBInsert(addr *C.char, port C.int, user *C.char, pass *C.char, db *C. return nil } +//InfluxDBExecDDLCommand drop a measurement +// Return nil if success, otherwise return error message +//export InfluxDBExecDDLCommand +func InfluxDBExecDDLCommand(addr *C.char, port C.int, user *C.char, pass *C.char, + db *C.char, cquery *C.char) (errret *C.char) { + + //Create a new HTTPClient + c, err := client.NewHTTPClient(client.HTTPConfig{ + Addr: C.GoString(addr) + ":" + strconv.Itoa(int(port)), + Username: C.GoString(user), + Password: C.GoString(pass), + }) + if err != nil { + return C.CString(err.Error()) + } + + query := client.Query{ + Command: C.GoString(cquery), + Database: C.GoString(db), + } + _, err = queryDB(c, query) + if err != nil { + return C.CString(err.Error()) + } + + return nil +} + func main() { } diff --git a/query_cxx.h b/query_cxx.h index b9f1b72..f2b67d0 100644 --- a/query_cxx.h +++ b/query_cxx.h @@ -88,4 +88,6 @@ struct InfluxDBQuery_return { char* r1; }; +extern char * InfluxDBExecDDLCommand(char* addr, int port, char* user, char* pass, char* db, char* cquery, int version, char* auth_token, char* retention_policy); + #endif /* QUERY_CXX_H */ diff --git a/sql/11.17/aggregate.sql b/sql/12.16/aggregate.sql similarity index 100% rename from sql/11.17/aggregate.sql rename to sql/12.16/aggregate.sql diff --git a/sql/11.17/extra/aggregates.sql b/sql/12.16/extra/aggregates.sql similarity index 100% rename from sql/11.17/extra/aggregates.sql rename to sql/12.16/extra/aggregates.sql diff --git a/sql/13.8/extra/influxdb_fdw_post.sql b/sql/12.16/extra/influxdb_fdw_post.sql similarity index 99% rename from sql/13.8/extra/influxdb_fdw_post.sql rename to sql/12.16/extra/influxdb_fdw_post.sql index 65ff3b8..aa7d5d2 100644 --- a/sql/13.8/extra/influxdb_fdw_post.sql +++ b/sql/12.16/extra/influxdb_fdw_post.sql @@ -36,7 +36,7 @@ CREATE FOREIGN TABLE "S 1"."T 0" ( "C 1" int NOT NULL, c2 int NOT NULL, c3 text, - time timestamp, + time timestamptz, c6 varchar(10), c7 char(10), c8 text @@ -46,7 +46,7 @@ CREATE FOREIGN TABLE "S 1"."T 1" ( "C 1" int NOT NULL, c2 int NOT NULL, c3 text, - time timestamp, + time timestamptz, c6 varchar(10), c7 char(10), c8 text @@ -80,7 +80,7 @@ INSERT INTO "S 1"."T 1" SELECT id, id % 10, to_char(id, 'FM00000'), - '1970-01-01'::timestamp + ((id % 100) || ' days')::interval, + '1970-01-01'::timestamptz + ((id % 100) || ' days')::interval, id % 10, id % 10, 'foo'::text @@ -121,7 +121,7 @@ CREATE FOREIGN TABLE ft1 ( c1 int NOT NULL, c2 int NOT NULL, c3 text, - time timestamp, + time timestamptz, c6 varchar(10), c7 char(10) default 'ft1', c8 text @@ -134,7 +134,7 @@ CREATE FOREIGN TABLE ft2 ( c2 int NOT NULL, cx int, c3 text, - time timestamp, + time timestamptz, c6 varchar(10), c7 char(10) default 'ft2', c8 text @@ -3189,7 +3189,7 @@ CREATE FOREIGN TABLE ft1_nopw ( c2 int NOT NULL, c3 text, c4 timestamptz, - c5 timestamp, + c5 timestamptz, c6 varchar(10), c7 char(10) default 'ft1', c8 user_enum diff --git a/sql/11.17/extra/init.sql b/sql/12.16/extra/init.sql similarity index 100% rename from sql/11.17/extra/init.sql rename to sql/12.16/extra/init.sql diff --git a/sql/11.17/extra/insert.sql b/sql/12.16/extra/insert.sql similarity index 100% rename from sql/11.17/extra/insert.sql rename to sql/12.16/extra/insert.sql diff --git a/sql/12.12/extra/join.sql b/sql/12.16/extra/join.sql similarity index 100% rename from sql/12.12/extra/join.sql rename to sql/12.16/extra/join.sql diff --git a/sql/11.17/extra/limit.sql b/sql/12.16/extra/limit.sql similarity index 100% rename from sql/11.17/extra/limit.sql rename to sql/12.16/extra/limit.sql diff --git a/sql/11.17/extra/prepare.sql b/sql/12.16/extra/prepare.sql similarity index 100% rename from sql/11.17/extra/prepare.sql rename to sql/12.16/extra/prepare.sql diff --git a/sql/11.17/extra/select.sql b/sql/12.16/extra/select.sql similarity index 100% rename from sql/11.17/extra/select.sql rename to sql/12.16/extra/select.sql diff --git a/sql/11.17/extra/select_having.sql b/sql/12.16/extra/select_having.sql similarity index 100% rename from sql/11.17/extra/select_having.sql rename to sql/12.16/extra/select_having.sql diff --git a/sql/14.5/influxdb_fdw.sql b/sql/12.16/influxdb_fdw.sql similarity index 88% rename from sql/14.5/influxdb_fdw.sql rename to sql/12.16/influxdb_fdw.sql index c7f5e2a..558af8d 100644 --- a/sql/14.5/influxdb_fdw.sql +++ b/sql/12.16/influxdb_fdw.sql @@ -612,6 +612,69 @@ INSERT INTO tmp_time (time, c1, c2, c3) VALUES ('2022-05-06 07:08:09', '07:08:09 -- https://www.timeanddate.com/time/zone/japan/tokyo?syear=1850 SELECT * FROM tmp_time; +-- Type mis-match +--Testcase 212: +CREATE FOREIGN TABLE datatype_test ( + time timestamp with time zone, + tag1 text, + tag2 text, + value1 int, + value2 text +) SERVER server1 OPTIONS (table 'datatype_test', tags 'tag1,tag2'); + +--Testcase 213: +INSERT INTO datatype_test (tag1, tag2, value1, value2) VALUES ('time', '2021-02-02T00:00:01Z', '1', '2021-02-05T00:00:00Z'); +--Testcase 214: +INSERT INTO datatype_test (tag1, tag2, value1, value2) VALUES ('time', '2022-02-02T00:00:01Z', '2', '2022-02-05T00:00:00Z'); +--Testcase 215: +SELECT tag1, tag2, value1, value2 FROM datatype_test; +-- Using text as timestamp +--Testcase 216: +ALTER FOREIGN TABLE datatype_test ALTER COLUMN tag2 TYPE timestamptz; +--Testcase 217: +ALTER FOREIGN TABLE datatype_test ALTER COLUMN value2 TYPE timestamptz; + +-- SELECT OK without filter +--Testcase 218: +SELECT tag1, tag2, value1, value2 FROM datatype_test; + +-- SELECT with timestamp filter, WHERE clause is pushed down +-- InfluxDB cannot compare correctly, 0 row returned +--Testcase 219: +EXPLAIN (VERBOSE, COSTS OFF) +SELECT tag1, tag2, value1, value2 FROM datatype_test WHERE tag2 > '2021-02-02 00:00:01+00'; +--Testcase 220: +SELECT tag1, tag2, value1, value2 FROM datatype_test WHERE tag2 > '2021-02-02 00:00:01+00'; +--Testcase 221: +EXPLAIN (VERBOSE, COSTS OFF) +SELECT tag1, tag2, value1, value2 FROM datatype_test WHERE value2 > '2021-02-05 00:00:00+00'; +--Testcase 222: +SELECT tag1, tag2, value1, value2 FROM datatype_test WHERE value2 > '2021-02-05 00:00:00+00'; + +--Testcase 223: +ALTER FOREIGN TABLE datatype_test ALTER COLUMN tag2 TYPE text; +--Testcase 224: +ALTER FOREIGN TABLE datatype_test ALTER COLUMN value2 TYPE text; + +-- uses explicit cast, WHERE clause is not pushed down +-- compared correctly by postgres, 1 row returned +--Testcase 225: +EXPLAIN (VERBOSE, COSTS OFF) +SELECT tag1, tag2, value1, value2 FROM datatype_test WHERE tag2::timestamptz > '2021-02-02 00:00:01+00'; +--Testcase 226: +SELECT tag1, tag2, value1, value2 FROM datatype_test WHERE tag2::timestamptz > '2021-02-02 00:00:01+00'; +--Testcase 227: +EXPLAIN (VERBOSE, COSTS OFF) +SELECT tag1, tag2, value1, value2 FROM datatype_test WHERE value2::timestamptz > '2021-02-05 00:00:00+00'; +--Testcase 228: +SELECT tag1, tag2, value1, value2 FROM datatype_test WHERE value2::timestamptz > '2021-02-05 00:00:00+00'; + +-- clean-up +--Testcase 229: +DELETE FROM datatype_test; +--Testcase 230: +DROP FOREIGN TABLE datatype_test; + -- Recover data :RECOVER_INIT_TXT_DROP_BUCKET; :RECOVER_INIT_TXT_CREATE_BUCKET; diff --git a/sql/11.17/init.sql b/sql/12.16/init.sql similarity index 100% rename from sql/11.17/init.sql rename to sql/12.16/init.sql diff --git a/sql/11.17/option.sql b/sql/12.16/option.sql similarity index 100% rename from sql/11.17/option.sql rename to sql/12.16/option.sql diff --git a/sql/11.17/schemaless/add_fields.sql b/sql/12.16/schemaless/add_fields.sql similarity index 100% rename from sql/11.17/schemaless/add_fields.sql rename to sql/12.16/schemaless/add_fields.sql diff --git a/sql/11.17/schemaless/add_multi_key.sql b/sql/12.16/schemaless/add_multi_key.sql similarity index 100% rename from sql/11.17/schemaless/add_multi_key.sql rename to sql/12.16/schemaless/add_multi_key.sql diff --git a/sql/11.17/schemaless/add_tags.sql b/sql/12.16/schemaless/add_tags.sql similarity index 100% rename from sql/11.17/schemaless/add_tags.sql rename to sql/12.16/schemaless/add_tags.sql diff --git a/sql/11.17/schemaless/aggregate.sql b/sql/12.16/schemaless/aggregate.sql similarity index 100% rename from sql/11.17/schemaless/aggregate.sql rename to sql/12.16/schemaless/aggregate.sql diff --git a/sql/11.17/schemaless/extra/aggregates.sql b/sql/12.16/schemaless/extra/aggregates.sql similarity index 100% rename from sql/11.17/schemaless/extra/aggregates.sql rename to sql/12.16/schemaless/extra/aggregates.sql diff --git a/sql/12.12/schemaless/extra/influxdb_fdw_post.sql b/sql/12.16/schemaless/extra/influxdb_fdw_post.sql similarity index 99% rename from sql/12.12/schemaless/extra/influxdb_fdw_post.sql rename to sql/12.16/schemaless/extra/influxdb_fdw_post.sql index 7160ed6..dc841c1 100644 --- a/sql/12.12/schemaless/extra/influxdb_fdw_post.sql +++ b/sql/12.16/schemaless/extra/influxdb_fdw_post.sql @@ -32,23 +32,23 @@ CREATE TYPE user_enum AS ENUM ('foo', 'bar', 'buz'); --Testcase 9: CREATE SCHEMA "S 1"; --Testcase 10: -CREATE FOREIGN TABLE "S 1"."T 0" (time timestamp, tags jsonb OPTIONS(tags 'true'), fields jsonb OPTIONS(fields 'true')) SERVER influxdb_svr OPTIONS (table 'T0', tags 'c3', schemaless 'true'); +CREATE FOREIGN TABLE "S 1"."T 0" (time timestamptz, tags jsonb OPTIONS(tags 'true'), fields jsonb OPTIONS(fields 'true')) SERVER influxdb_svr OPTIONS (table 'T0', tags 'c3', schemaless 'true'); CREATE FOREIGN TABLE "S 1".s1t0 ( "C 1" int NOT NULL, c2 int NOT NULL, c3 text, - time timestamp, + time timestamptz, c6 varchar(10), c7 char(10), c8 text ) SERVER influxdb_svr OPTIONS (table 'T0', tags 'c3'); --Testcase 11: -CREATE FOREIGN TABLE "S 1"."T 1" (time timestamp, tags jsonb OPTIONS(tags 'true'), fields jsonb OPTIONS(fields 'true')) SERVER influxdb_svr OPTIONS (table 'T1', tags 'c3', schemaless 'true'); +CREATE FOREIGN TABLE "S 1"."T 1" (time timestamptz, tags jsonb OPTIONS(tags 'true'), fields jsonb OPTIONS(fields 'true')) SERVER influxdb_svr OPTIONS (table 'T1', tags 'c3', schemaless 'true'); CREATE FOREIGN TABLE "S 1".s1t1 ( "C 1" int NOT NULL, c2 int NOT NULL, c3 text, - time timestamp, + time timestamptz, c6 varchar(10), c7 char(10), c8 text @@ -85,7 +85,7 @@ INSERT INTO "S 1".s1t1 SELECT id, id % 10, to_char(id, 'FM00000'), - '1970-01-01'::timestamp + ((id % 100) || ' days')::interval, + '1970-01-01'::timestamptz + ((id % 100) || ' days')::interval, id % 10, id % 10, 'foo'::text @@ -121,26 +121,26 @@ DELETE FROM "S 1".s1t4 WHERE c1 % 3 != 0; -- delete for outer join tests -- create foreign tables -- =================================================================== --Testcase 21: -CREATE FOREIGN TABLE ft1 (time timestamp, tags jsonb OPTIONS(tags 'true'), fields jsonb OPTIONS(fields 'true')) SERVER influxdb_svr OPTIONS (schemaless 'true'); +CREATE FOREIGN TABLE ft1 (time timestamptz, tags jsonb OPTIONS(tags 'true'), fields jsonb OPTIONS(fields 'true')) SERVER influxdb_svr OPTIONS (schemaless 'true'); CREATE FOREIGN TABLE ft1_nsc ( c0 int, c1 int NOT NULL, c2 int NOT NULL, c3 text, - time timestamp, + time timestamptz, c6 varchar(10), c7 char(10) default 'ft1', c8 text ) SERVER influxdb_svr; ALTER FOREIGN TABLE ft1_nsc DROP COLUMN c0; --Testcase 22: -CREATE FOREIGN TABLE ft2 (time timestamp, tags jsonb OPTIONS(tags 'true'), fields jsonb OPTIONS(fields 'true')) SERVER influxdb_svr OPTIONS (schemaless 'true'); +CREATE FOREIGN TABLE ft2 (time timestamptz, tags jsonb OPTIONS(tags 'true'), fields jsonb OPTIONS(fields 'true')) SERVER influxdb_svr OPTIONS (schemaless 'true'); CREATE FOREIGN TABLE ft2_nsc ( c1 int NOT NULL, c2 int NOT NULL, cx int, c3 text, - time timestamp, + time timestamptz, c6 varchar(10), c7 char(10) default 'ft2', c8 text @@ -3219,7 +3219,7 @@ CREATE FOREIGN TABLE ft1_nopw ( c2 int NOT NULL, c3 text, c4 timestamptz, - c5 timestamp, + c5 timestamptz, c6 varchar(10), c7 char(10) default 'ft1', c8 user_enum diff --git a/sql/11.17/schemaless/extra/insert.sql b/sql/12.16/schemaless/extra/insert.sql similarity index 100% rename from sql/11.17/schemaless/extra/insert.sql rename to sql/12.16/schemaless/extra/insert.sql diff --git a/sql/12.12/schemaless/extra/join.sql b/sql/12.16/schemaless/extra/join.sql similarity index 100% rename from sql/12.12/schemaless/extra/join.sql rename to sql/12.16/schemaless/extra/join.sql diff --git a/sql/11.17/schemaless/extra/limit.sql b/sql/12.16/schemaless/extra/limit.sql similarity index 100% rename from sql/11.17/schemaless/extra/limit.sql rename to sql/12.16/schemaless/extra/limit.sql diff --git a/sql/11.17/schemaless/extra/prepare.sql b/sql/12.16/schemaless/extra/prepare.sql similarity index 100% rename from sql/11.17/schemaless/extra/prepare.sql rename to sql/12.16/schemaless/extra/prepare.sql diff --git a/sql/11.17/schemaless/extra/select.sql b/sql/12.16/schemaless/extra/select.sql similarity index 100% rename from sql/11.17/schemaless/extra/select.sql rename to sql/12.16/schemaless/extra/select.sql diff --git a/sql/11.17/schemaless/extra/select_having.sql b/sql/12.16/schemaless/extra/select_having.sql similarity index 100% rename from sql/11.17/schemaless/extra/select_having.sql rename to sql/12.16/schemaless/extra/select_having.sql diff --git a/sql/11.17/schemaless/influxdb_fdw.sql b/sql/12.16/schemaless/influxdb_fdw.sql similarity index 100% rename from sql/11.17/schemaless/influxdb_fdw.sql rename to sql/12.16/schemaless/influxdb_fdw.sql diff --git a/sql/11.17/schemaless/init.sql b/sql/12.16/schemaless/init.sql similarity index 100% rename from sql/11.17/schemaless/init.sql rename to sql/12.16/schemaless/init.sql diff --git a/sql/11.17/schemaless/schemaless.sql b/sql/12.16/schemaless/schemaless.sql similarity index 100% rename from sql/11.17/schemaless/schemaless.sql rename to sql/12.16/schemaless/schemaless.sql diff --git a/sql/11.17/schemaless/selectfunc.sql b/sql/12.16/schemaless/selectfunc.sql similarity index 100% rename from sql/11.17/schemaless/selectfunc.sql rename to sql/12.16/schemaless/selectfunc.sql diff --git a/sql/11.17/selectfunc.sql b/sql/12.16/selectfunc.sql similarity index 100% rename from sql/11.17/selectfunc.sql rename to sql/12.16/selectfunc.sql diff --git a/sql/12.12/aggregate.sql b/sql/13.12/aggregate.sql similarity index 100% rename from sql/12.12/aggregate.sql rename to sql/13.12/aggregate.sql diff --git a/sql/12.12/extra/aggregates.sql b/sql/13.12/extra/aggregates.sql similarity index 100% rename from sql/12.12/extra/aggregates.sql rename to sql/13.12/extra/aggregates.sql diff --git a/sql/11.17/extra/influxdb_fdw_post.sql b/sql/13.12/extra/influxdb_fdw_post.sql similarity index 99% rename from sql/11.17/extra/influxdb_fdw_post.sql rename to sql/13.12/extra/influxdb_fdw_post.sql index 65ff3b8..aa7d5d2 100644 --- a/sql/11.17/extra/influxdb_fdw_post.sql +++ b/sql/13.12/extra/influxdb_fdw_post.sql @@ -36,7 +36,7 @@ CREATE FOREIGN TABLE "S 1"."T 0" ( "C 1" int NOT NULL, c2 int NOT NULL, c3 text, - time timestamp, + time timestamptz, c6 varchar(10), c7 char(10), c8 text @@ -46,7 +46,7 @@ CREATE FOREIGN TABLE "S 1"."T 1" ( "C 1" int NOT NULL, c2 int NOT NULL, c3 text, - time timestamp, + time timestamptz, c6 varchar(10), c7 char(10), c8 text @@ -80,7 +80,7 @@ INSERT INTO "S 1"."T 1" SELECT id, id % 10, to_char(id, 'FM00000'), - '1970-01-01'::timestamp + ((id % 100) || ' days')::interval, + '1970-01-01'::timestamptz + ((id % 100) || ' days')::interval, id % 10, id % 10, 'foo'::text @@ -121,7 +121,7 @@ CREATE FOREIGN TABLE ft1 ( c1 int NOT NULL, c2 int NOT NULL, c3 text, - time timestamp, + time timestamptz, c6 varchar(10), c7 char(10) default 'ft1', c8 text @@ -134,7 +134,7 @@ CREATE FOREIGN TABLE ft2 ( c2 int NOT NULL, cx int, c3 text, - time timestamp, + time timestamptz, c6 varchar(10), c7 char(10) default 'ft2', c8 text @@ -3189,7 +3189,7 @@ CREATE FOREIGN TABLE ft1_nopw ( c2 int NOT NULL, c3 text, c4 timestamptz, - c5 timestamp, + c5 timestamptz, c6 varchar(10), c7 char(10) default 'ft1', c8 user_enum diff --git a/sql/12.12/extra/init.sql b/sql/13.12/extra/init.sql similarity index 100% rename from sql/12.12/extra/init.sql rename to sql/13.12/extra/init.sql diff --git a/sql/12.12/extra/insert.sql b/sql/13.12/extra/insert.sql similarity index 100% rename from sql/12.12/extra/insert.sql rename to sql/13.12/extra/insert.sql diff --git a/sql/13.8/extra/join.sql b/sql/13.12/extra/join.sql similarity index 100% rename from sql/13.8/extra/join.sql rename to sql/13.12/extra/join.sql diff --git a/sql/12.12/extra/limit.sql b/sql/13.12/extra/limit.sql similarity index 100% rename from sql/12.12/extra/limit.sql rename to sql/13.12/extra/limit.sql diff --git a/sql/12.12/extra/prepare.sql b/sql/13.12/extra/prepare.sql similarity index 100% rename from sql/12.12/extra/prepare.sql rename to sql/13.12/extra/prepare.sql diff --git a/sql/12.12/extra/select.sql b/sql/13.12/extra/select.sql similarity index 100% rename from sql/12.12/extra/select.sql rename to sql/13.12/extra/select.sql diff --git a/sql/12.12/extra/select_having.sql b/sql/13.12/extra/select_having.sql similarity index 100% rename from sql/12.12/extra/select_having.sql rename to sql/13.12/extra/select_having.sql diff --git a/sql/11.17/influxdb_fdw.sql b/sql/13.12/influxdb_fdw.sql similarity index 88% rename from sql/11.17/influxdb_fdw.sql rename to sql/13.12/influxdb_fdw.sql index c7f5e2a..558af8d 100644 --- a/sql/11.17/influxdb_fdw.sql +++ b/sql/13.12/influxdb_fdw.sql @@ -612,6 +612,69 @@ INSERT INTO tmp_time (time, c1, c2, c3) VALUES ('2022-05-06 07:08:09', '07:08:09 -- https://www.timeanddate.com/time/zone/japan/tokyo?syear=1850 SELECT * FROM tmp_time; +-- Type mis-match +--Testcase 212: +CREATE FOREIGN TABLE datatype_test ( + time timestamp with time zone, + tag1 text, + tag2 text, + value1 int, + value2 text +) SERVER server1 OPTIONS (table 'datatype_test', tags 'tag1,tag2'); + +--Testcase 213: +INSERT INTO datatype_test (tag1, tag2, value1, value2) VALUES ('time', '2021-02-02T00:00:01Z', '1', '2021-02-05T00:00:00Z'); +--Testcase 214: +INSERT INTO datatype_test (tag1, tag2, value1, value2) VALUES ('time', '2022-02-02T00:00:01Z', '2', '2022-02-05T00:00:00Z'); +--Testcase 215: +SELECT tag1, tag2, value1, value2 FROM datatype_test; +-- Using text as timestamp +--Testcase 216: +ALTER FOREIGN TABLE datatype_test ALTER COLUMN tag2 TYPE timestamptz; +--Testcase 217: +ALTER FOREIGN TABLE datatype_test ALTER COLUMN value2 TYPE timestamptz; + +-- SELECT OK without filter +--Testcase 218: +SELECT tag1, tag2, value1, value2 FROM datatype_test; + +-- SELECT with timestamp filter, WHERE clause is pushed down +-- InfluxDB cannot compare correctly, 0 row returned +--Testcase 219: +EXPLAIN (VERBOSE, COSTS OFF) +SELECT tag1, tag2, value1, value2 FROM datatype_test WHERE tag2 > '2021-02-02 00:00:01+00'; +--Testcase 220: +SELECT tag1, tag2, value1, value2 FROM datatype_test WHERE tag2 > '2021-02-02 00:00:01+00'; +--Testcase 221: +EXPLAIN (VERBOSE, COSTS OFF) +SELECT tag1, tag2, value1, value2 FROM datatype_test WHERE value2 > '2021-02-05 00:00:00+00'; +--Testcase 222: +SELECT tag1, tag2, value1, value2 FROM datatype_test WHERE value2 > '2021-02-05 00:00:00+00'; + +--Testcase 223: +ALTER FOREIGN TABLE datatype_test ALTER COLUMN tag2 TYPE text; +--Testcase 224: +ALTER FOREIGN TABLE datatype_test ALTER COLUMN value2 TYPE text; + +-- uses explicit cast, WHERE clause is not pushed down +-- compared correctly by postgres, 1 row returned +--Testcase 225: +EXPLAIN (VERBOSE, COSTS OFF) +SELECT tag1, tag2, value1, value2 FROM datatype_test WHERE tag2::timestamptz > '2021-02-02 00:00:01+00'; +--Testcase 226: +SELECT tag1, tag2, value1, value2 FROM datatype_test WHERE tag2::timestamptz > '2021-02-02 00:00:01+00'; +--Testcase 227: +EXPLAIN (VERBOSE, COSTS OFF) +SELECT tag1, tag2, value1, value2 FROM datatype_test WHERE value2::timestamptz > '2021-02-05 00:00:00+00'; +--Testcase 228: +SELECT tag1, tag2, value1, value2 FROM datatype_test WHERE value2::timestamptz > '2021-02-05 00:00:00+00'; + +-- clean-up +--Testcase 229: +DELETE FROM datatype_test; +--Testcase 230: +DROP FOREIGN TABLE datatype_test; + -- Recover data :RECOVER_INIT_TXT_DROP_BUCKET; :RECOVER_INIT_TXT_CREATE_BUCKET; diff --git a/sql/12.12/init.sql b/sql/13.12/init.sql similarity index 100% rename from sql/12.12/init.sql rename to sql/13.12/init.sql diff --git a/sql/12.12/option.sql b/sql/13.12/option.sql similarity index 100% rename from sql/12.12/option.sql rename to sql/13.12/option.sql diff --git a/sql/12.12/schemaless/add_fields.sql b/sql/13.12/schemaless/add_fields.sql similarity index 100% rename from sql/12.12/schemaless/add_fields.sql rename to sql/13.12/schemaless/add_fields.sql diff --git a/sql/12.12/schemaless/add_multi_key.sql b/sql/13.12/schemaless/add_multi_key.sql similarity index 100% rename from sql/12.12/schemaless/add_multi_key.sql rename to sql/13.12/schemaless/add_multi_key.sql diff --git a/sql/12.12/schemaless/add_tags.sql b/sql/13.12/schemaless/add_tags.sql similarity index 100% rename from sql/12.12/schemaless/add_tags.sql rename to sql/13.12/schemaless/add_tags.sql diff --git a/sql/12.12/schemaless/aggregate.sql b/sql/13.12/schemaless/aggregate.sql similarity index 100% rename from sql/12.12/schemaless/aggregate.sql rename to sql/13.12/schemaless/aggregate.sql diff --git a/sql/12.12/schemaless/extra/aggregates.sql b/sql/13.12/schemaless/extra/aggregates.sql similarity index 100% rename from sql/12.12/schemaless/extra/aggregates.sql rename to sql/13.12/schemaless/extra/aggregates.sql diff --git a/sql/13.8/schemaless/extra/influxdb_fdw_post.sql b/sql/13.12/schemaless/extra/influxdb_fdw_post.sql similarity index 99% rename from sql/13.8/schemaless/extra/influxdb_fdw_post.sql rename to sql/13.12/schemaless/extra/influxdb_fdw_post.sql index 7160ed6..dc841c1 100644 --- a/sql/13.8/schemaless/extra/influxdb_fdw_post.sql +++ b/sql/13.12/schemaless/extra/influxdb_fdw_post.sql @@ -32,23 +32,23 @@ CREATE TYPE user_enum AS ENUM ('foo', 'bar', 'buz'); --Testcase 9: CREATE SCHEMA "S 1"; --Testcase 10: -CREATE FOREIGN TABLE "S 1"."T 0" (time timestamp, tags jsonb OPTIONS(tags 'true'), fields jsonb OPTIONS(fields 'true')) SERVER influxdb_svr OPTIONS (table 'T0', tags 'c3', schemaless 'true'); +CREATE FOREIGN TABLE "S 1"."T 0" (time timestamptz, tags jsonb OPTIONS(tags 'true'), fields jsonb OPTIONS(fields 'true')) SERVER influxdb_svr OPTIONS (table 'T0', tags 'c3', schemaless 'true'); CREATE FOREIGN TABLE "S 1".s1t0 ( "C 1" int NOT NULL, c2 int NOT NULL, c3 text, - time timestamp, + time timestamptz, c6 varchar(10), c7 char(10), c8 text ) SERVER influxdb_svr OPTIONS (table 'T0', tags 'c3'); --Testcase 11: -CREATE FOREIGN TABLE "S 1"."T 1" (time timestamp, tags jsonb OPTIONS(tags 'true'), fields jsonb OPTIONS(fields 'true')) SERVER influxdb_svr OPTIONS (table 'T1', tags 'c3', schemaless 'true'); +CREATE FOREIGN TABLE "S 1"."T 1" (time timestamptz, tags jsonb OPTIONS(tags 'true'), fields jsonb OPTIONS(fields 'true')) SERVER influxdb_svr OPTIONS (table 'T1', tags 'c3', schemaless 'true'); CREATE FOREIGN TABLE "S 1".s1t1 ( "C 1" int NOT NULL, c2 int NOT NULL, c3 text, - time timestamp, + time timestamptz, c6 varchar(10), c7 char(10), c8 text @@ -85,7 +85,7 @@ INSERT INTO "S 1".s1t1 SELECT id, id % 10, to_char(id, 'FM00000'), - '1970-01-01'::timestamp + ((id % 100) || ' days')::interval, + '1970-01-01'::timestamptz + ((id % 100) || ' days')::interval, id % 10, id % 10, 'foo'::text @@ -121,26 +121,26 @@ DELETE FROM "S 1".s1t4 WHERE c1 % 3 != 0; -- delete for outer join tests -- create foreign tables -- =================================================================== --Testcase 21: -CREATE FOREIGN TABLE ft1 (time timestamp, tags jsonb OPTIONS(tags 'true'), fields jsonb OPTIONS(fields 'true')) SERVER influxdb_svr OPTIONS (schemaless 'true'); +CREATE FOREIGN TABLE ft1 (time timestamptz, tags jsonb OPTIONS(tags 'true'), fields jsonb OPTIONS(fields 'true')) SERVER influxdb_svr OPTIONS (schemaless 'true'); CREATE FOREIGN TABLE ft1_nsc ( c0 int, c1 int NOT NULL, c2 int NOT NULL, c3 text, - time timestamp, + time timestamptz, c6 varchar(10), c7 char(10) default 'ft1', c8 text ) SERVER influxdb_svr; ALTER FOREIGN TABLE ft1_nsc DROP COLUMN c0; --Testcase 22: -CREATE FOREIGN TABLE ft2 (time timestamp, tags jsonb OPTIONS(tags 'true'), fields jsonb OPTIONS(fields 'true')) SERVER influxdb_svr OPTIONS (schemaless 'true'); +CREATE FOREIGN TABLE ft2 (time timestamptz, tags jsonb OPTIONS(tags 'true'), fields jsonb OPTIONS(fields 'true')) SERVER influxdb_svr OPTIONS (schemaless 'true'); CREATE FOREIGN TABLE ft2_nsc ( c1 int NOT NULL, c2 int NOT NULL, cx int, c3 text, - time timestamp, + time timestamptz, c6 varchar(10), c7 char(10) default 'ft2', c8 text @@ -3219,7 +3219,7 @@ CREATE FOREIGN TABLE ft1_nopw ( c2 int NOT NULL, c3 text, c4 timestamptz, - c5 timestamp, + c5 timestamptz, c6 varchar(10), c7 char(10) default 'ft1', c8 user_enum diff --git a/sql/12.12/schemaless/extra/insert.sql b/sql/13.12/schemaless/extra/insert.sql similarity index 100% rename from sql/12.12/schemaless/extra/insert.sql rename to sql/13.12/schemaless/extra/insert.sql diff --git a/sql/13.8/schemaless/extra/join.sql b/sql/13.12/schemaless/extra/join.sql similarity index 100% rename from sql/13.8/schemaless/extra/join.sql rename to sql/13.12/schemaless/extra/join.sql diff --git a/sql/12.12/schemaless/extra/limit.sql b/sql/13.12/schemaless/extra/limit.sql similarity index 100% rename from sql/12.12/schemaless/extra/limit.sql rename to sql/13.12/schemaless/extra/limit.sql diff --git a/sql/12.12/schemaless/extra/prepare.sql b/sql/13.12/schemaless/extra/prepare.sql similarity index 100% rename from sql/12.12/schemaless/extra/prepare.sql rename to sql/13.12/schemaless/extra/prepare.sql diff --git a/sql/12.12/schemaless/extra/select.sql b/sql/13.12/schemaless/extra/select.sql similarity index 100% rename from sql/12.12/schemaless/extra/select.sql rename to sql/13.12/schemaless/extra/select.sql diff --git a/sql/12.12/schemaless/extra/select_having.sql b/sql/13.12/schemaless/extra/select_having.sql similarity index 100% rename from sql/12.12/schemaless/extra/select_having.sql rename to sql/13.12/schemaless/extra/select_having.sql diff --git a/sql/12.12/schemaless/influxdb_fdw.sql b/sql/13.12/schemaless/influxdb_fdw.sql similarity index 100% rename from sql/12.12/schemaless/influxdb_fdw.sql rename to sql/13.12/schemaless/influxdb_fdw.sql diff --git a/sql/12.12/schemaless/init.sql b/sql/13.12/schemaless/init.sql similarity index 100% rename from sql/12.12/schemaless/init.sql rename to sql/13.12/schemaless/init.sql diff --git a/sql/12.12/schemaless/schemaless.sql b/sql/13.12/schemaless/schemaless.sql similarity index 100% rename from sql/12.12/schemaless/schemaless.sql rename to sql/13.12/schemaless/schemaless.sql diff --git a/sql/12.12/schemaless/selectfunc.sql b/sql/13.12/schemaless/selectfunc.sql similarity index 100% rename from sql/12.12/schemaless/selectfunc.sql rename to sql/13.12/schemaless/selectfunc.sql diff --git a/sql/12.12/selectfunc.sql b/sql/13.12/selectfunc.sql similarity index 100% rename from sql/12.12/selectfunc.sql rename to sql/13.12/selectfunc.sql diff --git a/sql/13.8/aggregate.sql b/sql/14.9/aggregate.sql similarity index 100% rename from sql/13.8/aggregate.sql rename to sql/14.9/aggregate.sql diff --git a/sql/14.5/extra/aggregates.sql b/sql/14.9/extra/aggregates.sql similarity index 100% rename from sql/14.5/extra/aggregates.sql rename to sql/14.9/extra/aggregates.sql diff --git a/sql/14.5/extra/influxdb_fdw_post.sql b/sql/14.9/extra/influxdb_fdw_post.sql similarity index 99% rename from sql/14.5/extra/influxdb_fdw_post.sql rename to sql/14.9/extra/influxdb_fdw_post.sql index 210c057..d740fe7 100644 --- a/sql/14.5/extra/influxdb_fdw_post.sql +++ b/sql/14.9/extra/influxdb_fdw_post.sql @@ -36,7 +36,7 @@ CREATE FOREIGN TABLE "S 1"."T 0" ( "C 1" int NOT NULL, c2 int NOT NULL, c3 text, - time timestamp, + time timestamptz, c6 varchar(10), c7 char(10), c8 text @@ -46,7 +46,7 @@ CREATE FOREIGN TABLE "S 1"."T 1" ( "C 1" int NOT NULL, c2 int NOT NULL, c3 text, - time timestamp, + time timestamptz, c6 varchar(10), c7 char(10), c8 text @@ -80,7 +80,7 @@ INSERT INTO "S 1"."T 1" SELECT id, id % 10, to_char(id, 'FM00000'), - '1970-01-01'::timestamp + ((id % 100) || ' days')::interval, + '1970-01-01'::timestamptz + ((id % 100) || ' days')::interval, id % 10, id % 10, 'foo'::text @@ -121,7 +121,7 @@ CREATE FOREIGN TABLE ft1 ( c1 int NOT NULL, c2 int NOT NULL, c3 text, - time timestamp, + time timestamptz, c6 varchar(10), c7 char(10) default 'ft1', c8 text @@ -135,7 +135,7 @@ CREATE FOREIGN TABLE ft2 ( c2 int NOT NULL, cx int, c3 text, - time timestamp, + time timestamptz, c6 varchar(10), c7 char(10) default 'ft2', c8 text @@ -3499,7 +3499,7 @@ CREATE FOREIGN TABLE ft1_nopw ( c2 int NOT NULL, c3 text, c4 timestamptz, - c5 timestamp, + c5 timestamptz, c6 varchar(10), c7 char(10) default 'ft1', c8 user_enum diff --git a/sql/13.8/extra/init.sql b/sql/14.9/extra/init.sql similarity index 100% rename from sql/13.8/extra/init.sql rename to sql/14.9/extra/init.sql diff --git a/sql/13.8/extra/insert.sql b/sql/14.9/extra/insert.sql similarity index 100% rename from sql/13.8/extra/insert.sql rename to sql/14.9/extra/insert.sql diff --git a/sql/14.5/extra/join.sql b/sql/14.9/extra/join.sql similarity index 100% rename from sql/14.5/extra/join.sql rename to sql/14.9/extra/join.sql diff --git a/sql/14.5/extra/limit.sql b/sql/14.9/extra/limit.sql similarity index 100% rename from sql/14.5/extra/limit.sql rename to sql/14.9/extra/limit.sql diff --git a/sql/14.5/extra/prepare.sql b/sql/14.9/extra/prepare.sql similarity index 100% rename from sql/14.5/extra/prepare.sql rename to sql/14.9/extra/prepare.sql diff --git a/sql/14.5/extra/select.sql b/sql/14.9/extra/select.sql similarity index 100% rename from sql/14.5/extra/select.sql rename to sql/14.9/extra/select.sql diff --git a/sql/13.8/extra/select_having.sql b/sql/14.9/extra/select_having.sql similarity index 100% rename from sql/13.8/extra/select_having.sql rename to sql/14.9/extra/select_having.sql diff --git a/sql/13.8/influxdb_fdw.sql b/sql/14.9/influxdb_fdw.sql similarity index 88% rename from sql/13.8/influxdb_fdw.sql rename to sql/14.9/influxdb_fdw.sql index c7f5e2a..558af8d 100644 --- a/sql/13.8/influxdb_fdw.sql +++ b/sql/14.9/influxdb_fdw.sql @@ -612,6 +612,69 @@ INSERT INTO tmp_time (time, c1, c2, c3) VALUES ('2022-05-06 07:08:09', '07:08:09 -- https://www.timeanddate.com/time/zone/japan/tokyo?syear=1850 SELECT * FROM tmp_time; +-- Type mis-match +--Testcase 212: +CREATE FOREIGN TABLE datatype_test ( + time timestamp with time zone, + tag1 text, + tag2 text, + value1 int, + value2 text +) SERVER server1 OPTIONS (table 'datatype_test', tags 'tag1,tag2'); + +--Testcase 213: +INSERT INTO datatype_test (tag1, tag2, value1, value2) VALUES ('time', '2021-02-02T00:00:01Z', '1', '2021-02-05T00:00:00Z'); +--Testcase 214: +INSERT INTO datatype_test (tag1, tag2, value1, value2) VALUES ('time', '2022-02-02T00:00:01Z', '2', '2022-02-05T00:00:00Z'); +--Testcase 215: +SELECT tag1, tag2, value1, value2 FROM datatype_test; +-- Using text as timestamp +--Testcase 216: +ALTER FOREIGN TABLE datatype_test ALTER COLUMN tag2 TYPE timestamptz; +--Testcase 217: +ALTER FOREIGN TABLE datatype_test ALTER COLUMN value2 TYPE timestamptz; + +-- SELECT OK without filter +--Testcase 218: +SELECT tag1, tag2, value1, value2 FROM datatype_test; + +-- SELECT with timestamp filter, WHERE clause is pushed down +-- InfluxDB cannot compare correctly, 0 row returned +--Testcase 219: +EXPLAIN (VERBOSE, COSTS OFF) +SELECT tag1, tag2, value1, value2 FROM datatype_test WHERE tag2 > '2021-02-02 00:00:01+00'; +--Testcase 220: +SELECT tag1, tag2, value1, value2 FROM datatype_test WHERE tag2 > '2021-02-02 00:00:01+00'; +--Testcase 221: +EXPLAIN (VERBOSE, COSTS OFF) +SELECT tag1, tag2, value1, value2 FROM datatype_test WHERE value2 > '2021-02-05 00:00:00+00'; +--Testcase 222: +SELECT tag1, tag2, value1, value2 FROM datatype_test WHERE value2 > '2021-02-05 00:00:00+00'; + +--Testcase 223: +ALTER FOREIGN TABLE datatype_test ALTER COLUMN tag2 TYPE text; +--Testcase 224: +ALTER FOREIGN TABLE datatype_test ALTER COLUMN value2 TYPE text; + +-- uses explicit cast, WHERE clause is not pushed down +-- compared correctly by postgres, 1 row returned +--Testcase 225: +EXPLAIN (VERBOSE, COSTS OFF) +SELECT tag1, tag2, value1, value2 FROM datatype_test WHERE tag2::timestamptz > '2021-02-02 00:00:01+00'; +--Testcase 226: +SELECT tag1, tag2, value1, value2 FROM datatype_test WHERE tag2::timestamptz > '2021-02-02 00:00:01+00'; +--Testcase 227: +EXPLAIN (VERBOSE, COSTS OFF) +SELECT tag1, tag2, value1, value2 FROM datatype_test WHERE value2::timestamptz > '2021-02-05 00:00:00+00'; +--Testcase 228: +SELECT tag1, tag2, value1, value2 FROM datatype_test WHERE value2::timestamptz > '2021-02-05 00:00:00+00'; + +-- clean-up +--Testcase 229: +DELETE FROM datatype_test; +--Testcase 230: +DROP FOREIGN TABLE datatype_test; + -- Recover data :RECOVER_INIT_TXT_DROP_BUCKET; :RECOVER_INIT_TXT_CREATE_BUCKET; diff --git a/sql/13.8/init.sql b/sql/14.9/init.sql similarity index 100% rename from sql/13.8/init.sql rename to sql/14.9/init.sql diff --git a/sql/13.8/option.sql b/sql/14.9/option.sql similarity index 100% rename from sql/13.8/option.sql rename to sql/14.9/option.sql diff --git a/sql/13.8/schemaless/add_fields.sql b/sql/14.9/schemaless/add_fields.sql similarity index 100% rename from sql/13.8/schemaless/add_fields.sql rename to sql/14.9/schemaless/add_fields.sql diff --git a/sql/13.8/schemaless/add_multi_key.sql b/sql/14.9/schemaless/add_multi_key.sql similarity index 100% rename from sql/13.8/schemaless/add_multi_key.sql rename to sql/14.9/schemaless/add_multi_key.sql diff --git a/sql/13.8/schemaless/add_tags.sql b/sql/14.9/schemaless/add_tags.sql similarity index 100% rename from sql/13.8/schemaless/add_tags.sql rename to sql/14.9/schemaless/add_tags.sql diff --git a/sql/13.8/schemaless/aggregate.sql b/sql/14.9/schemaless/aggregate.sql similarity index 100% rename from sql/13.8/schemaless/aggregate.sql rename to sql/14.9/schemaless/aggregate.sql diff --git a/sql/14.5/schemaless/extra/aggregates.sql b/sql/14.9/schemaless/extra/aggregates.sql similarity index 100% rename from sql/14.5/schemaless/extra/aggregates.sql rename to sql/14.9/schemaless/extra/aggregates.sql diff --git a/sql/14.5/schemaless/extra/influxdb_fdw_post.sql b/sql/14.9/schemaless/extra/influxdb_fdw_post.sql similarity index 99% rename from sql/14.5/schemaless/extra/influxdb_fdw_post.sql rename to sql/14.9/schemaless/extra/influxdb_fdw_post.sql index eef6002..303b16b 100644 --- a/sql/14.5/schemaless/extra/influxdb_fdw_post.sql +++ b/sql/14.9/schemaless/extra/influxdb_fdw_post.sql @@ -32,23 +32,23 @@ CREATE TYPE user_enum AS ENUM ('foo', 'bar', 'buz'); --Testcase 9: CREATE SCHEMA "S 1"; --Testcase 10: -CREATE FOREIGN TABLE "S 1"."T 0" (time timestamp, tags jsonb OPTIONS(tags 'true'), fields jsonb OPTIONS(fields 'true')) SERVER influxdb_svr OPTIONS (table 'T0', tags 'c3', schemaless 'true'); +CREATE FOREIGN TABLE "S 1"."T 0" (time timestamptz, tags jsonb OPTIONS(tags 'true'), fields jsonb OPTIONS(fields 'true')) SERVER influxdb_svr OPTIONS (table 'T0', tags 'c3', schemaless 'true'); CREATE FOREIGN TABLE "S 1".s1t0 ( "C 1" int NOT NULL, c2 int NOT NULL, c3 text, - time timestamp, + time timestamptz, c6 varchar(10), c7 char(10), c8 text ) SERVER influxdb_svr OPTIONS (table 'T0', tags 'c3'); --Testcase 11: -CREATE FOREIGN TABLE "S 1"."T 1" (time timestamp, tags jsonb OPTIONS(tags 'true'), fields jsonb OPTIONS(fields 'true')) SERVER influxdb_svr OPTIONS (table 'T1', tags 'c3', schemaless 'true'); +CREATE FOREIGN TABLE "S 1"."T 1" (time timestamptz, tags jsonb OPTIONS(tags 'true'), fields jsonb OPTIONS(fields 'true')) SERVER influxdb_svr OPTIONS (table 'T1', tags 'c3', schemaless 'true'); CREATE FOREIGN TABLE "S 1".s1t1 ( "C 1" int NOT NULL, c2 int NOT NULL, c3 text, - time timestamp, + time timestamptz, c6 varchar(10), c7 char(10), c8 text @@ -85,7 +85,7 @@ INSERT INTO "S 1".s1t1 SELECT id, id % 10, to_char(id, 'FM00000'), - '1970-01-01'::timestamp + ((id % 100) || ' days')::interval, + '1970-01-01'::timestamptz + ((id % 100) || ' days')::interval, id % 10, id % 10, 'foo'::text @@ -121,13 +121,13 @@ DELETE FROM "S 1".s1t4 WHERE c1 % 3 != 0; -- delete for outer join tests -- create foreign tables -- =================================================================== --Testcase 21: -CREATE FOREIGN TABLE ft1 (time timestamp, tags jsonb OPTIONS(tags 'true'), fields jsonb OPTIONS(fields 'true')) SERVER influxdb_svr OPTIONS (schemaless 'true'); +CREATE FOREIGN TABLE ft1 (time timestamptz, tags jsonb OPTIONS(tags 'true'), fields jsonb OPTIONS(fields 'true')) SERVER influxdb_svr OPTIONS (schemaless 'true'); CREATE FOREIGN TABLE ft1_nsc ( c0 int, c1 int NOT NULL, c2 int NOT NULL, c3 text, - time timestamp, + time timestamptz, c6 varchar(10), c7 char(10) default 'ft1', c8 text @@ -136,13 +136,13 @@ CREATE FOREIGN TABLE ft1_nsc ( ALTER FOREIGN TABLE ft1_nsc DROP COLUMN c0; --Testcase 23: -CREATE FOREIGN TABLE ft2 (time timestamp, tags jsonb OPTIONS(tags 'true'), fields jsonb OPTIONS(fields 'true')) SERVER influxdb_svr OPTIONS (schemaless 'true'); +CREATE FOREIGN TABLE ft2 (time timestamptz, tags jsonb OPTIONS(tags 'true'), fields jsonb OPTIONS(fields 'true')) SERVER influxdb_svr OPTIONS (schemaless 'true'); CREATE FOREIGN TABLE ft2_nsc ( c1 int NOT NULL, c2 int NOT NULL, cx int, c3 text, - time timestamp, + time timestamptz, c6 varchar(10), c7 char(10) default 'ft2', c8 text @@ -3531,7 +3531,7 @@ CREATE FOREIGN TABLE ft1_nopw ( c2 int NOT NULL, c3 text, c4 timestamptz, - c5 timestamp, + c5 timestamptz, c6 varchar(10), c7 char(10) default 'ft1', c8 user_enum diff --git a/sql/13.8/schemaless/extra/insert.sql b/sql/14.9/schemaless/extra/insert.sql similarity index 100% rename from sql/13.8/schemaless/extra/insert.sql rename to sql/14.9/schemaless/extra/insert.sql diff --git a/sql/14.5/schemaless/extra/join.sql b/sql/14.9/schemaless/extra/join.sql similarity index 100% rename from sql/14.5/schemaless/extra/join.sql rename to sql/14.9/schemaless/extra/join.sql diff --git a/sql/14.5/schemaless/extra/limit.sql b/sql/14.9/schemaless/extra/limit.sql similarity index 100% rename from sql/14.5/schemaless/extra/limit.sql rename to sql/14.9/schemaless/extra/limit.sql diff --git a/sql/14.5/schemaless/extra/prepare.sql b/sql/14.9/schemaless/extra/prepare.sql similarity index 100% rename from sql/14.5/schemaless/extra/prepare.sql rename to sql/14.9/schemaless/extra/prepare.sql diff --git a/sql/14.5/schemaless/extra/select.sql b/sql/14.9/schemaless/extra/select.sql similarity index 100% rename from sql/14.5/schemaless/extra/select.sql rename to sql/14.9/schemaless/extra/select.sql diff --git a/sql/13.8/schemaless/extra/select_having.sql b/sql/14.9/schemaless/extra/select_having.sql similarity index 100% rename from sql/13.8/schemaless/extra/select_having.sql rename to sql/14.9/schemaless/extra/select_having.sql diff --git a/sql/13.8/schemaless/influxdb_fdw.sql b/sql/14.9/schemaless/influxdb_fdw.sql similarity index 100% rename from sql/13.8/schemaless/influxdb_fdw.sql rename to sql/14.9/schemaless/influxdb_fdw.sql diff --git a/sql/13.8/schemaless/init.sql b/sql/14.9/schemaless/init.sql similarity index 100% rename from sql/13.8/schemaless/init.sql rename to sql/14.9/schemaless/init.sql diff --git a/sql/13.8/schemaless/schemaless.sql b/sql/14.9/schemaless/schemaless.sql similarity index 100% rename from sql/13.8/schemaless/schemaless.sql rename to sql/14.9/schemaless/schemaless.sql diff --git a/sql/13.8/schemaless/selectfunc.sql b/sql/14.9/schemaless/selectfunc.sql similarity index 100% rename from sql/13.8/schemaless/selectfunc.sql rename to sql/14.9/schemaless/selectfunc.sql diff --git a/sql/13.8/selectfunc.sql b/sql/14.9/selectfunc.sql similarity index 100% rename from sql/13.8/selectfunc.sql rename to sql/14.9/selectfunc.sql diff --git a/sql/15.0/influxdb_fdw.sql b/sql/15.0/influxdb_fdw.sql deleted file mode 100644 index c7f5e2a..0000000 --- a/sql/15.0/influxdb_fdw.sql +++ /dev/null @@ -1,625 +0,0 @@ ---SET log_min_messages=debug1; ---SET client_min_messages=debug1; ---Testcase 1: -SET datestyle=ISO; --- timestamp with time zone differs based on this ---Testcase 2: -SET timezone='Japan'; - -\set ECHO none -\ir sql/parameters.conf -\set ECHO all - ---Testcase 3: -CREATE EXTENSION influxdb_fdw; ---Testcase 4: -CREATE SERVER server1 FOREIGN DATA WRAPPER influxdb_fdw OPTIONS -(dbname 'mydb', :SERVER); ---Testcase 5: -CREATE USER MAPPING FOR CURRENT_USER SERVER server1 OPTIONS (:AUTHENTICATION); --- import time column as timestamp and text type -IMPORT FOREIGN SCHEMA public FROM SERVER server1 INTO public OPTIONS(import_time_text 'true'); ---Testcase 6: -SELECT * FROM cpu; ---Testcase 7: -SELECT tag1, value1 FROM cpu; ---Testcase 8: -SELECT value1, time, value2 FROM cpu; ---Testcase 9: -SELECT value1, time_text, value2 FROM cpu; - ---Testcase 10: -DROP FOREIGN TABLE cpu; ---Testcase 11: -DROP FOREIGN TABLE t3; ---Testcase 12: -DROP FOREIGN TABLE t4; ---Testcase 13: -DROP FOREIGN TABLE tx; ---Testcase 14: -DROP FOREIGN TABLE numbers; - --- test EXECPT -IMPORT FOREIGN SCHEMA public EXCEPT (cpu, t3, t4, tx, numbers) FROM SERVER server1 INTO public; ---Testcase 15: -SELECT ftoptions FROM pg_foreign_table; - --- test LIMIT TO -IMPORT FOREIGN SCHEMA public LIMIT TO (cpu) FROM SERVER server1 INTO public; ---Testcase 16: -SELECT ftoptions FROM pg_foreign_table; ---Testcase 17: -DROP FOREIGN TABLE cpu; - -IMPORT FOREIGN SCHEMA public FROM SERVER server1 INTO public OPTIONS(import_time_text 'false'); - ---Testcase 18: -SELECT * FROM cpu; ---Testcase 19: -SELECT tag1, value1 FROM cpu; ---Testcase 20: -SELECT value1, time, value2 FROM cpu; ---Testcase 21: -SELECT tag1 FROM cpu; ---Testcase 22: -SELECT * FROM numbers; - ---Testcase 23: -\d cpu; - ---Testcase 24: -SELECT * FROM cpu WHERE value1=100; ---Testcase 25: -SELECT * FROM cpu WHERE value2=0.5; ---Testcase 26: -SELECT * FROM cpu WHERE value3='str'; ---Testcase 27: -SELECT * FROM cpu WHERE value4=true; ---Testcase 28: -SELECT * FROM cpu WHERE NOT (value4 AND value1=100); ---Testcase 29: -SELECT * FROM cpu WHERE tag1='tag1_A'; - ---Testcase 30: -EXPLAIN (VERBOSE, COSTS OFF) -SELECT * FROM cpu WHERE value3 IS NULL; ---Testcase 31: -SELECT * FROM cpu WHERE value3 IS NULL; ---Testcase 32: -SELECT * FROM cpu WHERE tag2 IS NULL; ---Testcase 33: -SELECT * FROM cpu WHERE value3 IS NOT NULL; ---Testcase 34: -SELECT * FROM cpu WHERE tag2 IS NOT NULL; - --- InfluxDB not support compare timestamp with OR condition ---Testcase 35: -SELECT * FROM cpu WHERE time = '2015-08-18 09:48:08+09' OR value2 = 0.5; - --- InfluxDB not support compare timestamp with != or <> ---Testcase 36: -SELECT * FROM cpu WHERE time != '2015-08-18 09:48:08+09'; ---Testcase 37: -SELECT * FROM cpu WHERE time <> '2015-08-18 09:48:08+09'; - ---Testcase 38: -SELECT * FROM cpu WHERE time = '2015-08-18 09:48:08+09' OR value2 = 0.5; - --- There is inconsitency for search of missing values between tag and field ---Testcase 39: -EXPLAIN (VERBOSE, COSTS OFF) -SELECT * FROM cpu WHERE value3 = ''; ---Testcase 40: -SELECT * FROM cpu WHERE value3 = ''; - ---Testcase 41: -EXPLAIN (VERBOSE, COSTS OFF) -SELECT * FROM cpu WHERE tag2 = ''; ---Testcase 42: -SELECT * FROM cpu WHERE tag2 = ''; - ---Testcase 43: -SELECT * FROM cpu WHERE tag1 IN ('tag1_A', 'tag1_B'); ---Testcase 44: -EXPLAIN VERBOSE -SELECT * FROM cpu WHERE tag1 IN ('tag1_A', 'tag1_B'); - --- Rows which have no tag are considered to have empty string ---Testcase 45: -SELECT * FROM cpu WHERE tag1 NOT IN ('tag1_A', 'tag1_B'); ---Testcase 46: -EXPLAIN VERBOSE -SELECT * FROM cpu WHERE tag1 NOT IN ('tag1_A', 'tag1_B'); - --- test IN/NOT IN ---Testcase 47: -SELECT * FROM cpu WHERE time IN ('2015-08-18 09:48:08+09','2016-08-28 07:44:00+07'); ---Testcase 48: -SELECT * FROM cpu WHERE time NOT IN ('2015-08-18 09:48:08+09','2016-08-28 07:44:00+07'); ---Testcase 49: -SELECT * FROM cpu WHERE value1 NOT IN (100, 97); ---Testcase 50: -SELECT * FROM cpu WHERE value1 IN (100, 97); ---Testcase 51: -SELECT * FROM cpu WHERE value2 IN (0.5, 10.9); ---Testcase 52: -SELECT * FROM cpu WHERE value2 NOT IN (2, 9.7); ---Testcase 53: -SELECT * FROM cpu WHERE value4 NOT IN ('true', 'true'); ---Testcase 54: -SELECT * FROM cpu WHERE time IN ('2015-08-18 09:48:08+09','2016-08-28 07:44:00+07'); ---Testcase 55: -SELECT * FROM cpu WHERE time NOT IN ('2015-08-18 09:48:08+09','2016-08-28 07:44:00+07'); ---Testcase 56: -SELECT * FROM cpu WHERE value1 NOT IN (100, 97); ---Testcase 57: -SELECT * FROM cpu WHERE value1 IN (100, 97); ---Testcase 58: -SELECT * FROM cpu WHERE value2 IN (0.5, 10.9); ---Testcase 59: -SELECT * FROM cpu WHERE value2 NOT IN (2, 9.7); ---Testcase 60: -SELECT * FROM cpu WHERE value4 NOT IN ('true', 'true'); ---Testcase 61: -SELECT * FROM cpu WHERE value4 IN ('f', 't'); - ---Testcase 62: -CREATE FOREIGN TABLE t1(time timestamp with time zone , tag1 text, value1 integer) SERVER server1 OPTIONS (table 'cpu'); ---Testcase 63: -CREATE FOREIGN TABLE t2(time timestamp , tag1 text, value1 integer) SERVER server1 OPTIONS (table 'cpu'); - ---Testcase 64: -SELECT * FROM t1; ---Testcase 65: -SELECT * FROM t2; --- In following four queries, timestamp condition is added to InfluxQL as "time = '2015-08-18 00:00:00'" ---Testcase 66: -SELECT * FROM t1 WHERE time = TIMESTAMP WITH TIME ZONE '2015-08-18 09:00:00+09'; ---Testcase 67: -SELECT * FROM t1 WHERE time = TIMESTAMP '2015-08-18 00:00:00'; - ---Testcase 68: -SELECT * FROM t2 WHERE time = TIMESTAMP WITH TIME ZONE '2015-08-18 09:00:00+09'; ---Testcase 69: -SELECT * FROM t2 WHERE time = TIMESTAMP '2015-08-18 00:00:00'; - --- pushdown now() ---Testcase 70: -SELECT * FROM t2 WHERE now() > time; ---Testcase 71: -EXPLAIN VERBOSE -SELECT * FROM t2 WHERE now() > time; - ---Testcase 72: -SELECT * FROM t2 WHERE time = TIMESTAMP WITH TIME ZONE '2015-08-26 05:43:21.1+00' - interval '1 week 1 day 5 hour 43 minute 21 second 100 millisecond'; ---Testcase 73: -EXPLAIN VERBOSE -SELECT * FROM t2 WHERE time = TIMESTAMP WITH TIME ZONE '2015-08-26 05:43:21.1+00' - interval '1 week 1 day 5 hour 43 minute 21 second 100 millisecond'; - --- InfluxDB does not seem to support time column + interval, so below query returns empty result --- SELECT * FROM t2 WHERE time + interval '1 week 1 day 5 hour 43 minute 21 second 100 millisecond' = TIMESTAMP WITH TIME ZONE '2015-08-26 05:43:21.1+00'; --- EXPLAIN (VERBOSE, COSTS OFF) --- SELECT * FROM t2 WHERE time + interval '1 week 1 day 5 hour 43 minute 21 second 100 millisecond' = TIMESTAMP WITH TIME ZONE '2015-08-26 05:43:21.1+00'; - --- InfluxDB does not support month or year interval, so not push down ---Testcase 74: -SELECT * FROM t2 WHERE time = TIMESTAMP '2015-09-18 00:00:00' - interval '1 months'; ---Testcase 75: -EXPLAIN VERBOSE -SELECT * FROM t2 WHERE time = TIMESTAMP '2015-09-18 00:00:00' - interval '1 months'; - ---Testcase 76: -SELECT * FROM t2 WHERE value1 = ANY (ARRAY(SELECT value1 FROM t1 WHERE value1 < 1000)); - --- ANY with ARRAY expression ---Testcase 77: -EXPLAIN VERBOSE -SELECT a, b FROM numbers WHERE a = ANY(ARRAY[1, a + 1]); ---Testcase 78: -SELECT a, b FROM numbers WHERE a = ANY(ARRAY[1, a + 1]); - ---Testcase 79: -EXPLAIN VERBOSE -SELECT a, b FROM numbers WHERE a <> ANY(ARRAY[1, a + 1]); ---Testcase 80: -SELECT a, b FROM numbers WHERE a <> ANY(ARRAY[1, a + 1]); - ---Testcase 81: -EXPLAIN VERBOSE -SELECT a, b FROM numbers WHERE a >= ANY(ARRAY[1, a + 1]); ---Testcase 82: -SELECT a, b FROM numbers WHERE a >= ANY(ARRAY[1, a + 1]); - ---Testcase 83: -EXPLAIN VERBOSE -SELECT a, b FROM numbers WHERE a <= ANY(ARRAY[1, a + 1]); ---Testcase 84: -SELECT a, b FROM numbers WHERE a <= ANY(ARRAY[1, a + 1]); - ---Testcase 85: -EXPLAIN VERBOSE -SELECT a, b FROM numbers WHERE a > ANY(ARRAY[1, a + 1]); ---Testcase 86: -SELECT a, b FROM numbers WHERE a > ANY(ARRAY[1, a + 1]); - ---Testcase 87: -EXPLAIN VERBOSE -SELECT a, b FROM numbers WHERE a < ANY(ARRAY[1, a + 1]); ---Testcase 88: -SELECT a, b FROM numbers WHERE a < ANY(ARRAY[1, a + 1]); - --- ANY with ARRAY const ---Testcase 89: -EXPLAIN VERBOSE -SELECT a, b FROM numbers WHERE a = ANY(ARRAY[1, 2]); ---Testcase 90: -SELECT a, b FROM numbers WHERE a = ANY(ARRAY[1, 2]); - ---Testcase 91: -EXPLAIN VERBOSE -SELECT a, b FROM numbers WHERE a <> ANY(ARRAY[1, 2]); ---Testcase 92: -SELECT a, b FROM numbers WHERE a <> ANY(ARRAY[1, 2]); - ---Testcase 93: -EXPLAIN VERBOSE -SELECT a, b FROM numbers WHERE a >= ANY(ARRAY[1, 2]); ---Testcase 94: -SELECT a, b FROM numbers WHERE a >= ANY(ARRAY[1, 2]); - ---Testcase 95: -EXPLAIN VERBOSE -SELECT a, b FROM numbers WHERE a <= ANY(ARRAY[1, 2]); ---Testcase 96: -SELECT a, b FROM numbers WHERE a <= ANY(ARRAY[1, 2]); - ---Testcase 97: -EXPLAIN VERBOSE -SELECT a, b FROM numbers WHERE a > ANY(ARRAY[1, 2]); ---Testcase 98: -SELECT a, b FROM numbers WHERE a > ANY(ARRAY[1, 2]); - ---Testcase 99: -EXPLAIN VERBOSE -SELECT a, b FROM numbers WHERE a < ANY(ARRAY[1, 2]); ---Testcase 100: -SELECT a, b FROM numbers WHERE a < ANY(ARRAY[1, 2]); - ---Testcase 101: -EXPLAIN VERBOSE -SELECT a, b FROM numbers WHERE a = ANY('{1, 2, 3}'); ---Testcase 102: -SELECT a, b FROM numbers WHERE a = ANY('{1, 2, 3}'); ---Testcase 103: -EXPLAIN VERBOSE -SELECT a, b FROM numbers WHERE a <> ANY('{1, 2, 3}'); ---Testcase 104: -SELECT a, b FROM numbers WHERE a <> ANY('{1, 2, 3}'); - --- ALL with ARRAY expression ---Testcase 105: -EXPLAIN VERBOSE -SELECT a, b FROM numbers WHERE a = ALL(ARRAY[1, a * 1]); ---Testcase 106: -SELECT a, b FROM numbers WHERE a = ALL(ARRAY[1, a * 1]); - ---Testcase 107: -EXPLAIN VERBOSE -SELECT a, b FROM numbers WHERE a <> ALL(ARRAY[1, a + 1]); ---Testcase 108: -SELECT a, b FROM numbers WHERE a <> ALL(ARRAY[1, a + 1]); - ---Testcase 109: -EXPLAIN VERBOSE -SELECT a, b FROM numbers WHERE a >= ALL(ARRAY[1, a / 1]); ---Testcase 110: -SELECT a, b FROM numbers WHERE a >= ALL(ARRAY[1, a / 1]); - ---Testcase 111: -EXPLAIN VERBOSE -SELECT a, b FROM numbers WHERE a <= ALL(ARRAY[1, a + 1]); ---Testcase 112: -SELECT a, b FROM numbers WHERE a <= ALL(ARRAY[1, a + 1]); - ---Testcase 113: -EXPLAIN VERBOSE -SELECT a, b FROM numbers WHERE a > ALL(ARRAY[1, a - 1]); ---Testcase 114: -SELECT a, b FROM numbers WHERE a > ALL(ARRAY[1, a - 1]); - ---Testcase 115: -EXPLAIN VERBOSE -SELECT a, b FROM numbers WHERE a < ALL(ARRAY[2, a + 1]); ---Testcase 116: -SELECT a, b FROM numbers WHERE a < ALL(ARRAY[2, a + 1]); - --- ALL with ARRAY const ---Testcase 117: -EXPLAIN VERBOSE -SELECT a, b FROM numbers WHERE a = ALL(ARRAY[1, 1]); ---Testcase 118: -SELECT a, b FROM numbers WHERE a = ALL(ARRAY[1, 1]); - ---Testcase 119: -EXPLAIN VERBOSE -SELECT a, b FROM numbers WHERE a <> ALL(ARRAY[1, 3]); ---Testcase 120: -SELECT a, b FROM numbers WHERE a <> ALL(ARRAY[1, 3]); - ---Testcase 121: -EXPLAIN VERBOSE -SELECT a, b FROM numbers WHERE a >= ALL(ARRAY[1, 2]); ---Testcase 122: -SELECT a, b FROM numbers WHERE a >= ALL(ARRAY[1, 2]); - ---Testcase 123: -EXPLAIN VERBOSE -SELECT a, b FROM numbers WHERE a <= ALL(ARRAY[1, 2]); ---Testcase 124: -SELECT a, b FROM numbers WHERE a <= ALL(ARRAY[1, 2]); - ---Testcase 125: -EXPLAIN VERBOSE -SELECT a, b FROM numbers WHERE a > ALL(ARRAY[0, 1]); ---Testcase 126: -SELECT a, b FROM numbers WHERE a > ALL(ARRAY[0, 1]); - ---Testcase 127: -EXPLAIN VERBOSE -SELECT a, b FROM numbers WHERE a < ALL(ARRAY[2, 3]); ---Testcase 128: -SELECT a, b FROM numbers WHERE a < ALL(ARRAY[2, 3]); - --- ANY/ALL with TEXT ARRAY const ---Testcase 129: -EXPLAIN VERBOSE -SELECT a, b FROM numbers WHERE b = ANY(ARRAY['One', 'Two']); ---Testcase 130: -SELECT a, b FROM numbers WHERE b = ANY(ARRAY['One', 'Two']); - ---Testcase 131: -EXPLAIN VERBOSE -SELECT a, b FROM numbers WHERE b <> ALL(ARRAY['One', 'Four']); ---Testcase 132: -SELECT a, b FROM numbers WHERE b <> ALL(ARRAY['One', 'Four']); - ---Testcase 133: -EXPLAIN VERBOSE -SELECT a, b FROM numbers WHERE b > ANY(ARRAY['One', 'Two']); ---Testcase 134: -SELECT a, b FROM numbers WHERE b > ANY(ARRAY['One', 'Two']); - ---Testcase 135: -EXPLAIN VERBOSE -SELECT * FROM numbers WHERE b > ALL(ARRAY['Four', 'Five']); ---Testcase 136: -SELECT a, b FROM numbers WHERE b > ALL(ARRAY['Four', 'Five']); - ---Testcase 137: -DROP FOREIGN TABLE numbers; - ---Testcase 138: -ALTER SERVER server1 OPTIONS (SET dbname 'no such database'); ---Testcase 139: -SELECT * FROM t1; ---Testcase 140: -ALTER SERVER server1 OPTIONS (SET dbname 'mydb'); ---Testcase 141: -SELECT * FROM t1; - --- map time column to both timestamp and text ---Testcase 142: -CREATE FOREIGN TABLE t5(t timestamp OPTIONS (column_name 'time'), tag1 text OPTIONS (column_name 'time'), v1 integer OPTIONS (column_name 'value1')) SERVER server1 OPTIONS (table 'cpu'); ---Testcase 143: -SELECT * FROM t5; - ---get version ---Testcase 144: -\df influxdb_fdw* ---Testcase 145: -SELECT * FROM public.influxdb_fdw_version(); ---Testcase 146: -SELECT influxdb_fdw_version(); ---Test pushdown LIMIT...OFFSET ---Testcase 147: -EXPLAIN (VERBOSE, COSTS OFF) -SELECT tableoid::regclass, * FROM t1 LIMIT 1 OFFSET 0; - ---Testcase 148: -SELECT tableoid::regclass, * FROM t1 LIMIT 1 OFFSET 0; - ---Testcase 149: -EXPLAIN (VERBOSE, COSTS OFF) -SELECT tableoid::regclass, * FROM t1 LIMIT 1 OFFSET 1; - ---Testcase 150: -SELECT tableoid::regclass, * FROM t1 LIMIT 1 OFFSET 1; - ---Testcase 151: -EXPLAIN (VERBOSE, COSTS OFF) -SELECT ctid, * FROM t1 LIMIT 1 OFFSET 0; - ---Testcase 152: -SELECT ctid, * FROM t1 LIMIT 1 OFFSET 0; - ---Testcase 153: -EXPLAIN (VERBOSE, COSTS OFF) -SELECT ctid, * FROM t2 LIMIT 10 OFFSET 20; - ---Testcase 154: -SELECT ctid, * FROM t2 LIMIT 10 OFFSET 20; - ---Testcase 155: -EXPLAIN (VERBOSE, COSTS OFF) -SELECT * FROM - t1 - LEFT JOIN t2 - ON t2.value1 = 123, - LATERAL (SELECT t2.value1, t1.tag1 FROM t1 LIMIT 1 OFFSET 0) AS ss -WHERE t1.value1 = ss.value1; - ---Testcase 156: -EXPLAIN (VERBOSE, COSTS OFF) -SELECT * FROM - t1 - LEFT JOIN t2 - ON t2.value1 = 123, - LATERAL (SELECT t2.value1, t1.tag1 FROM t1 LIMIT 1 OFFSET 0) AS ss1, - LATERAL (SELECT ss1.* from t3 LIMIT 1 OFFSET 20) AS ss2 -WHERE t1.value1 = ss2.value1; - ---Testcase 157: -DROP FOREIGN TABLE cpu; ---Testcase 158: -DROP FOREIGN TABLE t1; ---Testcase 159: -DROP FOREIGN TABLE t2; ---Testcase 160: -DROP FOREIGN TABLE t3; ---Testcase 161: -DROP FOREIGN TABLE t4; ---Testcase 162: -DROP FOREIGN TABLE t5; ---Testcase 163: -DROP FOREIGN TABLE tx; - --- test INSERT, DELETE -IMPORT FOREIGN SCHEMA public FROM SERVER server1 INTO public OPTIONS(import_time_text 'true'); ---Testcase 164: -SELECT * FROM cpu; ---Testcase 165: -EXPLAIN VERBOSE -INSERT INTO cpu(time, tag1, tag2, value1, value2, value3, value4) VALUES('2021-01-01 00:00:01+09', 'tag1_K', 'tag2_H', 200, 5.5, 'test1', true); ---Testcase 166: -INSERT INTO cpu(time, tag1, tag2, value1, value2, value3, value4) VALUES('2021-01-01 00:00:01+09', 'tag1_K', 'tag2_H', 200, 5.5, 'test', true); ---Testcase 167: -SELECT * FROM cpu; - ---Testcase 168: -EXPLAIN VERBOSE -INSERT INTO cpu(time, tag1, tag2, value1, value2, value3, value4) VALUES('2021-01-02 00:00:02+05', 'tag1_I', 'tag2_E', 300, 15.5, 'test2', false), - ('2029-02-02 00:02:02+04', 'tag1_U', 'tag2_DZ', (SELECT 350), (SELECT i FROM (VALUES(6.9)) AS foo (i)), 'funny', true); ---Testcase 169: -INSERT INTO cpu(time, tag1, tag2, value1, value2, value3, value4) VALUES('2021-01-02 00:00:02+05', 'tag1_I', 'tag2_E', 300, 15.5, 'test2', false), - ('2029-02-02 00:02:02+04', 'tag1_U', 'tag2_DZ', (SELECT 350), (SELECT i FROM (VALUES(6.9)) AS foo (i)), 'funny', true); ---Testcase 170: -SELECT * FROM cpu; - ---Testcase 171: -INSERT INTO cpu(tag2, value1) VALUES('tag2_KH', 400); ---Testcase 172: -SELECT tag1, tag2, value1, value2, value3, value4 FROM cpu; - ---Testcase 173: -EXPLAIN VERBOSE -DELETE FROM cpu WHERE tag2 = 'tag2_KH'; ---Testcase 174: -DELETE FROM cpu WHERE tag2 = 'tag2_KH'; ---Testcase 175: -SELECT tag1, tag2, value1, value2, value3, value4 FROM cpu; - ---Testcase 176: -EXPLAIN VERBOSE -DELETE FROM cpu WHERE time = '2021-01-02 04:00:02+09'; ---Testcase 177: -DELETE FROM cpu WHERE time = '2021-01-02 04:00:02+09'; ---Testcase 178: -SELECT * FROM cpu; - ---Testcase 179: -EXPLAIN VERBOSE -DELETE FROM cpu WHERE time < '2018-07-07' AND tag1 != 'tag1_B'; ---Testcase 180: -DELETE FROM cpu WHERE time < '2018-07-07' AND tag1 != 'tag1_B'; ---Testcase 181: -SELECT * FROM cpu; - --- Test INSERT, DELETE with time_text column ---Testcase 182: -INSERT INTO cpu(time_text, tag1, tag2, value1, value2, value3, value4) VALUES('2021-02-02T00:00:00Z', 'tag1_D', 'tag2_E', 600, 20.2, 'test3', true); ---Testcase 183: -SELECT * FROM cpu; - ---Testcase 184: -INSERT INTO cpu(time_text, tag1, value2) VALUES('2021-02-02T00:00:00.123456789Z', 'tag1_P', 25.8); ---Testcase 185: -SELECT * FROM cpu; - ---Testcase 186: -INSERT INTO cpu(time_text, tag1, value2) VALUES('2021-02-02 00:00:01', 'tag1_J', 37.1); ---Testcase 187: -SELECT * FROM cpu; - ---Testcase 188: -INSERT INTO cpu(time, time_text, tag1, tag2, value1, value2, value3, value4) VALUES('2021-02-02 00:00:01+05', '2021-02-02T00:00:02.123456789Z', 'tag1_A', 'tag2_B', 200, 5.5, 'test', true); ---Testcase 189: -SELECT * FROM cpu; - ---Testcase 190: -INSERT INTO cpu(time_text, time, tag1, tag2, value1, value2, value3, value4) VALUES('2021-02-03T00:00:03.123456789Z', '2021-03-03 00:00:01+07', 'tag1_C', 'tag2_D', 200, 5.5, 'test', true); ---Testcase 191: -SELECT * FROM cpu; - ---Testcase 192: -EXPLAIN VERBOSE -DELETE FROM cpu WHERE time_text = '2021-02-02T00:00:00.123456789Z'; ---Testcase 193: -DELETE FROM cpu WHERE time_text = '2021-02-02T00:00:00.123456789Z'; ---Testcase 194: -SELECT * FROM cpu; - ---Testcase 195: -EXPLAIN VERBOSE -DELETE FROM cpu WHERE time_text = '2021-02-02T00:00:01Z' AND tag1 = 'tag1_J'; ---Testcase 196: -DELETE FROM cpu WHERE time_text = '2021-02-02T00:00:01Z' AND tag1 = 'tag1_J'; ---Testcase 197: -SELECT * FROM cpu; - ---Testcase 198: -EXPLAIN VERBOSE -DELETE FROM cpu WHERE time_text = '2021-02-02 00:00:00' OR time ='2029-02-02 05:02:02+09'; ---Testcase 199: -DELETE FROM cpu WHERE time_text = '2021-02-02 00:00:00' OR time ='2029-02-02 05:02:02+09'; ---Testcase 200: -SELECT * FROM cpu; - --- InfluxDB_FDW will store time data for Field values as a strings ---Testcase 204: -CREATE FOREIGN TABLE tmp_time ( -time timestamp, -c1 time, -c2 timestamp, -c3 timestamp with time zone -) SERVER server1 OPTIONS (table 'tmp_time'); ---Testcase 205: -SELECT * FROM tmp_time; ---Testcase 206: -INSERT INTO tmp_time (time, c1) VALUES ('1900-01-01 01:01:01', '01:02:03'); ---Testcase 207: -INSERT INTO tmp_time (time, c1) VALUES ('2100-01-01 01:01:01', '04:05:06'); ---Testcase 208: -INSERT INTO tmp_time (time, c1) VALUES ('1990-01-01 01:01:01', '07:08:09'); ---Testcase 209: -INSERT INTO tmp_time (time, c2) VALUES ('2020-12-27 03:02:56.634467', '1950-02-02 02:02:02'); ---Testcase 210: -INSERT INTO tmp_time (time, c3) VALUES ('2021-12-27 03:02:56.668301', '1800-02-02 02:02:02+9'); ---Testcase 210: -INSERT INTO tmp_time (time, c1, c2, c3) VALUES ('2022-05-06 07:08:09', '07:08:09', '2022-05-06 07:08:09', '2022-05-06 07:08:09+9'); ---Testcase 211: --- 1800-02-02 02:02:02+9 is Daylight Saving Time (DST) changes in Japan. --- Timezone setting Japan so it will plus 18s:59 --- https://www.timeanddate.com/time/zone/japan/tokyo?syear=1850 -SELECT * FROM tmp_time; - --- Recover data -:RECOVER_INIT_TXT_DROP_BUCKET; -:RECOVER_INIT_TXT_CREATE_BUCKET; -:RECOVER_INIT_TXT; - ---Testcase 201: -DROP USER MAPPING FOR CURRENT_USER SERVER server1; ---Testcase 202: -DROP SERVER server1 CASCADE; ---Testcase 203: -DROP EXTENSION influxdb_fdw CASCADE; diff --git a/sql/14.5/aggregate.sql b/sql/15.4/aggregate.sql similarity index 100% rename from sql/14.5/aggregate.sql rename to sql/15.4/aggregate.sql diff --git a/sql/15.0/extra/aggregates.sql b/sql/15.4/extra/aggregates.sql similarity index 100% rename from sql/15.0/extra/aggregates.sql rename to sql/15.4/extra/aggregates.sql diff --git a/sql/15.0/extra/influxdb_fdw_post.sql b/sql/15.4/extra/influxdb_fdw_post.sql similarity index 99% rename from sql/15.0/extra/influxdb_fdw_post.sql rename to sql/15.4/extra/influxdb_fdw_post.sql index 71491cf..89488e8 100644 --- a/sql/15.0/extra/influxdb_fdw_post.sql +++ b/sql/15.4/extra/influxdb_fdw_post.sql @@ -36,7 +36,7 @@ CREATE FOREIGN TABLE "S 1"."T 0" ( "C 1" int NOT NULL, c2 int NOT NULL, c3 text, - time timestamp, + time timestamptz, c6 varchar(10), c7 char(10), c8 text @@ -46,7 +46,7 @@ CREATE FOREIGN TABLE "S 1"."T 1" ( "C 1" int NOT NULL, c2 int NOT NULL, c3 text, - time timestamp, + time timestamptz, c6 varchar(10), c7 char(10), c8 text @@ -80,7 +80,7 @@ INSERT INTO "S 1"."T 1" SELECT id, id % 10, to_char(id, 'FM00000'), - '1970-01-01'::timestamp + ((id % 100) || ' days')::interval, + '1970-01-01'::timestamptz + ((id % 100) || ' days')::interval, id % 10, id % 10, 'foo'::text @@ -121,7 +121,7 @@ CREATE FOREIGN TABLE ft1 ( c1 int NOT NULL, c2 int NOT NULL, c3 text, - time timestamp, + time timestamptz, c6 varchar(10), c7 char(10) default 'ft1', c8 text @@ -135,7 +135,7 @@ CREATE FOREIGN TABLE ft2 ( c2 int NOT NULL, cx int, c3 text, - time timestamp, + time timestamptz, c6 varchar(10), c7 char(10) default 'ft2', c8 text @@ -3621,7 +3621,7 @@ CREATE FOREIGN TABLE pg_temp.ft1_nopw ( c2 int NOT NULL, c3 text, c4 timestamptz, - c5 timestamp, + c5 timestamptz, c6 varchar(10), c7 char(10) default 'ft1', c8 user_enum diff --git a/sql/14.5/extra/init.sql b/sql/15.4/extra/init.sql similarity index 100% rename from sql/14.5/extra/init.sql rename to sql/15.4/extra/init.sql diff --git a/sql/15.0/extra/insert.sql b/sql/15.4/extra/insert.sql similarity index 100% rename from sql/15.0/extra/insert.sql rename to sql/15.4/extra/insert.sql diff --git a/sql/15.0/extra/join.sql b/sql/15.4/extra/join.sql similarity index 100% rename from sql/15.0/extra/join.sql rename to sql/15.4/extra/join.sql diff --git a/sql/15.0/extra/limit.sql b/sql/15.4/extra/limit.sql similarity index 100% rename from sql/15.0/extra/limit.sql rename to sql/15.4/extra/limit.sql diff --git a/sql/15.0/extra/prepare.sql b/sql/15.4/extra/prepare.sql similarity index 100% rename from sql/15.0/extra/prepare.sql rename to sql/15.4/extra/prepare.sql diff --git a/sql/15.0/extra/select.sql b/sql/15.4/extra/select.sql similarity index 100% rename from sql/15.0/extra/select.sql rename to sql/15.4/extra/select.sql diff --git a/sql/15.0/extra/select_having.sql b/sql/15.4/extra/select_having.sql similarity index 100% rename from sql/15.0/extra/select_having.sql rename to sql/15.4/extra/select_having.sql diff --git a/sql/12.12/influxdb_fdw.sql b/sql/15.4/influxdb_fdw.sql similarity index 88% rename from sql/12.12/influxdb_fdw.sql rename to sql/15.4/influxdb_fdw.sql index c7f5e2a..558af8d 100644 --- a/sql/12.12/influxdb_fdw.sql +++ b/sql/15.4/influxdb_fdw.sql @@ -612,6 +612,69 @@ INSERT INTO tmp_time (time, c1, c2, c3) VALUES ('2022-05-06 07:08:09', '07:08:09 -- https://www.timeanddate.com/time/zone/japan/tokyo?syear=1850 SELECT * FROM tmp_time; +-- Type mis-match +--Testcase 212: +CREATE FOREIGN TABLE datatype_test ( + time timestamp with time zone, + tag1 text, + tag2 text, + value1 int, + value2 text +) SERVER server1 OPTIONS (table 'datatype_test', tags 'tag1,tag2'); + +--Testcase 213: +INSERT INTO datatype_test (tag1, tag2, value1, value2) VALUES ('time', '2021-02-02T00:00:01Z', '1', '2021-02-05T00:00:00Z'); +--Testcase 214: +INSERT INTO datatype_test (tag1, tag2, value1, value2) VALUES ('time', '2022-02-02T00:00:01Z', '2', '2022-02-05T00:00:00Z'); +--Testcase 215: +SELECT tag1, tag2, value1, value2 FROM datatype_test; +-- Using text as timestamp +--Testcase 216: +ALTER FOREIGN TABLE datatype_test ALTER COLUMN tag2 TYPE timestamptz; +--Testcase 217: +ALTER FOREIGN TABLE datatype_test ALTER COLUMN value2 TYPE timestamptz; + +-- SELECT OK without filter +--Testcase 218: +SELECT tag1, tag2, value1, value2 FROM datatype_test; + +-- SELECT with timestamp filter, WHERE clause is pushed down +-- InfluxDB cannot compare correctly, 0 row returned +--Testcase 219: +EXPLAIN (VERBOSE, COSTS OFF) +SELECT tag1, tag2, value1, value2 FROM datatype_test WHERE tag2 > '2021-02-02 00:00:01+00'; +--Testcase 220: +SELECT tag1, tag2, value1, value2 FROM datatype_test WHERE tag2 > '2021-02-02 00:00:01+00'; +--Testcase 221: +EXPLAIN (VERBOSE, COSTS OFF) +SELECT tag1, tag2, value1, value2 FROM datatype_test WHERE value2 > '2021-02-05 00:00:00+00'; +--Testcase 222: +SELECT tag1, tag2, value1, value2 FROM datatype_test WHERE value2 > '2021-02-05 00:00:00+00'; + +--Testcase 223: +ALTER FOREIGN TABLE datatype_test ALTER COLUMN tag2 TYPE text; +--Testcase 224: +ALTER FOREIGN TABLE datatype_test ALTER COLUMN value2 TYPE text; + +-- uses explicit cast, WHERE clause is not pushed down +-- compared correctly by postgres, 1 row returned +--Testcase 225: +EXPLAIN (VERBOSE, COSTS OFF) +SELECT tag1, tag2, value1, value2 FROM datatype_test WHERE tag2::timestamptz > '2021-02-02 00:00:01+00'; +--Testcase 226: +SELECT tag1, tag2, value1, value2 FROM datatype_test WHERE tag2::timestamptz > '2021-02-02 00:00:01+00'; +--Testcase 227: +EXPLAIN (VERBOSE, COSTS OFF) +SELECT tag1, tag2, value1, value2 FROM datatype_test WHERE value2::timestamptz > '2021-02-05 00:00:00+00'; +--Testcase 228: +SELECT tag1, tag2, value1, value2 FROM datatype_test WHERE value2::timestamptz > '2021-02-05 00:00:00+00'; + +-- clean-up +--Testcase 229: +DELETE FROM datatype_test; +--Testcase 230: +DROP FOREIGN TABLE datatype_test; + -- Recover data :RECOVER_INIT_TXT_DROP_BUCKET; :RECOVER_INIT_TXT_CREATE_BUCKET; diff --git a/sql/14.5/init.sql b/sql/15.4/init.sql similarity index 100% rename from sql/14.5/init.sql rename to sql/15.4/init.sql diff --git a/sql/14.5/option.sql b/sql/15.4/option.sql similarity index 100% rename from sql/14.5/option.sql rename to sql/15.4/option.sql diff --git a/sql/15.0/schemaless/add_fields.sql b/sql/15.4/schemaless/add_fields.sql similarity index 100% rename from sql/15.0/schemaless/add_fields.sql rename to sql/15.4/schemaless/add_fields.sql diff --git a/sql/15.0/schemaless/add_multi_key.sql b/sql/15.4/schemaless/add_multi_key.sql similarity index 100% rename from sql/15.0/schemaless/add_multi_key.sql rename to sql/15.4/schemaless/add_multi_key.sql diff --git a/sql/15.0/schemaless/add_tags.sql b/sql/15.4/schemaless/add_tags.sql similarity index 100% rename from sql/15.0/schemaless/add_tags.sql rename to sql/15.4/schemaless/add_tags.sql diff --git a/sql/14.5/schemaless/aggregate.sql b/sql/15.4/schemaless/aggregate.sql similarity index 100% rename from sql/14.5/schemaless/aggregate.sql rename to sql/15.4/schemaless/aggregate.sql diff --git a/sql/15.0/schemaless/extra/aggregates.sql b/sql/15.4/schemaless/extra/aggregates.sql similarity index 100% rename from sql/15.0/schemaless/extra/aggregates.sql rename to sql/15.4/schemaless/extra/aggregates.sql diff --git a/sql/15.0/schemaless/extra/influxdb_fdw_post.sql b/sql/15.4/schemaless/extra/influxdb_fdw_post.sql similarity index 99% rename from sql/15.0/schemaless/extra/influxdb_fdw_post.sql rename to sql/15.4/schemaless/extra/influxdb_fdw_post.sql index 8b9de2e..1167ed7 100644 --- a/sql/15.0/schemaless/extra/influxdb_fdw_post.sql +++ b/sql/15.4/schemaless/extra/influxdb_fdw_post.sql @@ -32,25 +32,25 @@ CREATE TYPE user_enum AS ENUM ('foo', 'bar', 'buz'); --Testcase 9: CREATE SCHEMA "S 1"; --Testcase 10: -CREATE FOREIGN TABLE "S 1"."T 0" (time timestamp, tags jsonb OPTIONS(tags 'true'), fields jsonb OPTIONS(fields 'true')) SERVER influxdb_svr OPTIONS (table 'T0', tags 'c3', schemaless 'true'); +CREATE FOREIGN TABLE "S 1"."T 0" (time timestamptz, tags jsonb OPTIONS(tags 'true'), fields jsonb OPTIONS(fields 'true')) SERVER influxdb_svr OPTIONS (table 'T0', tags 'c3', schemaless 'true'); --Testcase 783: CREATE FOREIGN TABLE "S 1".s1t0 ( "C 1" int NOT NULL, c2 int NOT NULL, c3 text, - time timestamp, + time timestamptz, c6 varchar(10), c7 char(10), c8 text ) SERVER influxdb_svr OPTIONS (table 'T0', tags 'c3'); --Testcase 11: -CREATE FOREIGN TABLE "S 1"."T 1" (time timestamp, tags jsonb OPTIONS(tags 'true'), fields jsonb OPTIONS(fields 'true')) SERVER influxdb_svr OPTIONS (table 'T1', tags 'c3', schemaless 'true'); +CREATE FOREIGN TABLE "S 1"."T 1" (time timestamptz, tags jsonb OPTIONS(tags 'true'), fields jsonb OPTIONS(fields 'true')) SERVER influxdb_svr OPTIONS (table 'T1', tags 'c3', schemaless 'true'); --Testcase 784: CREATE FOREIGN TABLE "S 1".s1t1 ( "C 1" int NOT NULL, c2 int NOT NULL, c3 text, - time timestamp, + time timestamptz, c6 varchar(10), c7 char(10), c8 text @@ -90,7 +90,7 @@ INSERT INTO "S 1".s1t1 SELECT id, id % 10, to_char(id, 'FM00000'), - '1970-01-01'::timestamp + ((id % 100) || ' days')::interval, + '1970-01-01'::timestamptz + ((id % 100) || ' days')::interval, id % 10, id % 10, 'foo'::text @@ -126,14 +126,14 @@ DELETE FROM "S 1".s1t4 WHERE c1 % 3 != 0; -- delete for outer join tests -- create foreign tables -- =================================================================== --Testcase 21: -CREATE FOREIGN TABLE ft1 (time timestamp, tags jsonb OPTIONS(tags 'true'), fields jsonb OPTIONS(fields 'true')) SERVER influxdb_svr OPTIONS (schemaless 'true'); +CREATE FOREIGN TABLE ft1 (time timestamptz, tags jsonb OPTIONS(tags 'true'), fields jsonb OPTIONS(fields 'true')) SERVER influxdb_svr OPTIONS (schemaless 'true'); --Testcase 788: CREATE FOREIGN TABLE ft1_nsc ( c0 int, c1 int NOT NULL, c2 int NOT NULL, c3 text, - time timestamp, + time timestamptz, c6 varchar(10), c7 char(10) default 'ft1', c8 text @@ -142,14 +142,14 @@ CREATE FOREIGN TABLE ft1_nsc ( ALTER FOREIGN TABLE ft1_nsc DROP COLUMN c0; --Testcase 23: -CREATE FOREIGN TABLE ft2 (time timestamp, tags jsonb OPTIONS(tags 'true'), fields jsonb OPTIONS(fields 'true')) SERVER influxdb_svr OPTIONS (schemaless 'true'); +CREATE FOREIGN TABLE ft2 (time timestamptz, tags jsonb OPTIONS(tags 'true'), fields jsonb OPTIONS(fields 'true')) SERVER influxdb_svr OPTIONS (schemaless 'true'); --Testcase 789: CREATE FOREIGN TABLE ft2_nsc ( c1 int NOT NULL, c2 int NOT NULL, cx int, c3 text, - time timestamp, + time timestamptz, c6 varchar(10), c7 char(10) default 'ft2', c8 text @@ -3669,7 +3669,7 @@ CREATE FOREIGN TABLE pg_temp.ft1_nopw ( c2 int NOT NULL, c3 text, c4 timestamptz, - c5 timestamp, + c5 timestamptz, c6 varchar(10), c7 char(10) default 'ft1', c8 user_enum diff --git a/sql/15.0/schemaless/extra/insert.sql b/sql/15.4/schemaless/extra/insert.sql similarity index 100% rename from sql/15.0/schemaless/extra/insert.sql rename to sql/15.4/schemaless/extra/insert.sql diff --git a/sql/15.0/schemaless/extra/join.sql b/sql/15.4/schemaless/extra/join.sql similarity index 100% rename from sql/15.0/schemaless/extra/join.sql rename to sql/15.4/schemaless/extra/join.sql diff --git a/sql/15.0/schemaless/extra/limit.sql b/sql/15.4/schemaless/extra/limit.sql similarity index 100% rename from sql/15.0/schemaless/extra/limit.sql rename to sql/15.4/schemaless/extra/limit.sql diff --git a/sql/15.0/schemaless/extra/prepare.sql b/sql/15.4/schemaless/extra/prepare.sql similarity index 100% rename from sql/15.0/schemaless/extra/prepare.sql rename to sql/15.4/schemaless/extra/prepare.sql diff --git a/sql/15.0/schemaless/extra/select.sql b/sql/15.4/schemaless/extra/select.sql similarity index 100% rename from sql/15.0/schemaless/extra/select.sql rename to sql/15.4/schemaless/extra/select.sql diff --git a/sql/15.0/schemaless/extra/select_having.sql b/sql/15.4/schemaless/extra/select_having.sql similarity index 100% rename from sql/15.0/schemaless/extra/select_having.sql rename to sql/15.4/schemaless/extra/select_having.sql diff --git a/sql/15.0/schemaless/influxdb_fdw.sql b/sql/15.4/schemaless/influxdb_fdw.sql similarity index 100% rename from sql/15.0/schemaless/influxdb_fdw.sql rename to sql/15.4/schemaless/influxdb_fdw.sql diff --git a/sql/14.5/schemaless/init.sql b/sql/15.4/schemaless/init.sql similarity index 100% rename from sql/14.5/schemaless/init.sql rename to sql/15.4/schemaless/init.sql diff --git a/sql/14.5/schemaless/schemaless.sql b/sql/15.4/schemaless/schemaless.sql similarity index 100% rename from sql/14.5/schemaless/schemaless.sql rename to sql/15.4/schemaless/schemaless.sql diff --git a/sql/14.5/schemaless/selectfunc.sql b/sql/15.4/schemaless/selectfunc.sql similarity index 100% rename from sql/14.5/schemaless/selectfunc.sql rename to sql/15.4/schemaless/selectfunc.sql diff --git a/sql/14.5/selectfunc.sql b/sql/15.4/selectfunc.sql similarity index 100% rename from sql/14.5/selectfunc.sql rename to sql/15.4/selectfunc.sql diff --git a/sql/15.0/aggregate.sql b/sql/16.0/aggregate.sql similarity index 100% rename from sql/15.0/aggregate.sql rename to sql/16.0/aggregate.sql diff --git a/sql/13.8/extra/aggregates.sql b/sql/16.0/extra/aggregates.sql similarity index 86% rename from sql/13.8/extra/aggregates.sql rename to sql/16.0/extra/aggregates.sql index 6e6cae8..543e764 100644 --- a/sql/13.8/extra/aggregates.sql +++ b/sql/16.0/extra/aggregates.sql @@ -102,19 +102,62 @@ CREATE FOREIGN TABLE FLOAT8_TBL (f1 float8) SERVER influxdb_svr; -- AGGREGATES -- +-- directory paths are passed to us in environment variables +--\getenv abs_srcdir PG_ABS_SRCDIR -- avoid bit-exact output here because operations may not be bit-exact. --Testcase 19: SET extra_float_digits = 0; +--\set filename :abs_srcdir '/init/agg.txt' +--COPY aggtest FROM :'filename'; + +--ANALYZE aggtest; + --Testcase 20: SELECT avg(four) AS avg_1 FROM onek; --Testcase 21: SELECT avg(a) AS avg_32 FROM aggtest WHERE a < 100; +--Testcase 514: +CREATE FOREIGN TABLE v1 (v int4) SERVER influxdb_svr OPTIONS (table 'v1'); + +--Testcase 515: +INSERT INTO v1 (v) VALUES (1), (2), (3); +--Testcase 516: +SELECT any_value(v) FROM v1; +--Testcase 517: +DELETE FROM v1; + +-- NULL datatype is not supported in influxdb. Expectation is error. +--Testcase 518: +INSERT INTO v1 (v) VALUES (NULL); +--Testcase 519: +SELECT any_value(v) FROM v1; +--Testcase 520: +DELETE FROM v1; + +-- NULL datatype is not supported in influxdb. Expectation is error. +--Testcase 521: +INSERT INTO v1 (v) VALUES (NULL), (1), (2); +--Testcase 522: +SELECT any_value(v) FROM v1; +--Testcase 523: +DELETE FROM v1; + +--Testcase 524: +CREATE FOREIGN TABLE v2 (v text[]) SERVER influxdb_svr OPTIONS (table 'v2'); + +-- Cannot binding text array. Expectation is error. +--Testcase 525: +INSERT INTO v2 (v) VALUES (array['hello', 'world']); +--Testcase 526: +SELECT any_value(v) FROM v2; +--Testcase 527: +DELETE FROM v2; + -- In 7.1, avg(float4) is computed using float8 arithmetic. -- Round the result to 3 digits to avoid platform-specific results. - --Testcase 22: SELECT avg(b)::numeric(10,3) AS avg_107_943 FROM aggtest; @@ -473,7 +516,8 @@ CREATE FOREIGN TABLE bitwise_test_empty ( --Testcase 137: SELECT BIT_AND(i2) AS "?", - BIT_OR(i4) AS "?" + BIT_OR(i4) AS "?", + BIT_XOR(i8) AS "?" FROM bitwise_test_empty; --Testcase 138: @@ -500,7 +544,14 @@ SELECT BIT_OR(i8) AS "7", BIT_OR(i) AS "?", BIT_OR(x) AS "7", - BIT_OR(y) AS "1101" + 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; -- @@ -740,6 +791,10 @@ drop foreign table minmaxtest cascade; select max(min(unique1)) from tenk1; --Testcase 195: select (select max(min(unique1)) from int8_tbl) from tenk1; +--Testcase 528: +select avg((select avg(a1.col1 order by (select avg(a2.col2) from tenk1 a3)) + from tenk1 a1(col1))) +from tenk1 a2(col2); -- -- Test removal of redundant GROUP BY columns @@ -818,9 +873,9 @@ drop table p_agg_t1; -- --Testcase 215: -create foreign table agg_t1(f1 int, f2 bigint) server influxdb_svr; +create foreign table agg_t1(f1 int, f2 int) server influxdb_svr; --Testcase 216: -create foreign table agg_t2(f1 bigint, f22 bigint) server influxdb_svr; +create foreign table agg_t2(f1 bigint, f2 oid) server influxdb_svr; --Testcase 217: select f1 from agg_t1 left join agg_t2 using (f1) group by f1; @@ -832,10 +887,95 @@ select agg_t1.f1 from agg_t1 left join agg_t2 using (f1) group by agg_t1.f1; --Testcase 220: select agg_t1.f1 from agg_t1 left join agg_t2 using (f1) group by f1; +-- check case where we have to inject nullingrels into coerced join alias +--Testcase 529: +select f1, count(*) from +agg_t1 x(x0,x1) left join (agg_t1 left join agg_t2 using(f1)) on (x0 = 0) +group by f1; + +-- same, for a RelabelType coercion +--Testcase 530: +select f2, count(*) from +agg_t1 x(x0,x1) left join (agg_t1 left join agg_t2 using(f2)) on (x0 = 0) +group by f2; + --Testcase 221: drop foreign table agg_t1 cascade; --Testcase 222: drop foreign table agg_t2 cascade; + +-- +-- Test planner's selection of pathkeys for ORDER BY aggregates +-- + +-- Ensure we order by four. This suits the most aggregate functions. +--Testcase 531: +explain (costs off) +select sum(two order by two),max(four order by four), min(four order by four) +from tenk1; + +-- Ensure we order by two. It's a tie between ordering by two and four but +-- we tiebreak on the aggregate's position. +--Testcase 532: +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; + +-- Similar to above, but tiebreak on ordering by four +--Testcase 533: +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; + +-- Ensure this one orders by ten since there are 3 aggregates that require ten +-- vs two that suit two and four. +--Testcase 534: +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; + +-- 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. +--Testcase 535: +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; + +-- 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. +--Testcase 536: +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; + +-- Ensure consecutive NULLs are properly treated as distinct from each other +--Testcase 537: +select array_agg(distinct val) +from (select null as val from generate_series(1, 2)); + +-- Ensure no ordering is requested when enable_presorted_aggregate is off +set enable_presorted_aggregate to off; +--Testcase 538: +explain (costs off) +select sum(two order by two) from tenk1; +reset enable_presorted_aggregate; + -- -- Test combinations of DISTINCT and/or ORDER BY -- @@ -1079,6 +1219,83 @@ select string_agg(v, decode('ee', 'hex')) from bytea_test_table; drop table bytea_test_table; */ + +-- Test parallel string_agg and array_agg +--Testcase 539: +create foreign table pagg_test ( + x int, + y int +) server influxdb_svr options (table 'pagg_test'); + +--Testcase 540: +insert into pagg_test +select (case x % 4 when 1 then null else x end), x % 10 +from generate_series(1,5000) x; + +set parallel_setup_cost TO 0; +set parallel_tuple_cost TO 0; +set parallel_leader_participation TO 0; +set min_parallel_table_scan_size = 0; +set bytea_output = 'escape'; +set max_parallel_workers_per_gather = 2; + +-- create a view as we otherwise have to repeat this query a few times. +--Testcase 541: +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; + +-- Ensure results are correct. +--Testcase 542: +select * from v_pagg_test order by y; + +-- Ensure parallel aggregation is actually being used. +-- influxdb_fdw: parallel execution is not supported +--Testcase 543: +explain (costs off) select * from v_pagg_test order by y; + +set max_parallel_workers_per_gather = 0; + +-- Ensure results are the same without parallel aggregation. +--Testcase 544: +select * from v_pagg_test order by y; + +-- Clean up +reset max_parallel_workers_per_gather; +reset bytea_output; +reset min_parallel_table_scan_size; +reset parallel_leader_participation; +reset parallel_tuple_cost; +reset parallel_setup_cost; + +--Testcase 545: +drop view v_pagg_test; +--Testcase 546: +drop table pagg_test; + -- FILTER tests --Testcase 284: @@ -1100,6 +1317,12 @@ having exists (select 1 from onek b where sum(distinct a.four) = b.four); select max(foo COLLATE "C") filter (where (bar collate "POSIX") > '0') from (values ('a', 'b')) AS v(foo,bar); +--Testcase 553: +INSERT INTO v1 (v) VALUES (1), (2), (3); + +--Testcase 547: +select any_value(v) filter (where v > 2) from v1; + -- outer reference in FILTER (PostgreSQL extension) --Testcase 289: select (select count(*) @@ -1132,6 +1355,22 @@ select aggfns(distinct a,b,c order by a,c using ~<~,b) filter (where a > 1) generate_series(1,2) i; rollback; +-- check handling of bare boolean Var in FILTER +--Testcase 454: +select max(0) filter (where b1) from bool_test; +--Testcase 455: +select (select max(0) filter (where b1)) from bool_test; + +-- check for correct detection of nested-aggregate errors in FILTER +--Testcase 456: +select max(unique1) filter (where sum(ten) > 0) from tenk1; +--Testcase 457: +select (select max(unique1) filter (where sum(ten) > 0) from int8_tbl) from tenk1; +--Testcase 458: +select max(unique1) filter (where bool_or(ten > 0)) from tenk1; +--Testcase 459: +select (select max(unique1) filter (where bool_or(ten > 0)) from int8_tbl) from tenk1; + -- ordered-set aggregates begin; @@ -1585,6 +1824,50 @@ SELECT balk(hundred) FROM tenk1; ROLLBACK; +-- test multiple usage of an aggregate whose finalfn returns a R/W datum +BEGIN; + +--Testcase 548: +CREATE FUNCTION rwagg_sfunc(x anyarray, y anyarray) RETURNS anyarray +LANGUAGE plpgsql IMMUTABLE AS $$ +BEGIN + RETURN array_fill(y[1], ARRAY[4]); +END; +$$; + +--Testcase 549: +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; +$$; + +--Testcase 550: +CREATE AGGREGATE rwagg(anyarray) ( + STYPE = anyarray, + SFUNC = rwagg_sfunc, + FINALFUNC = rwagg_finalfunc +); + +--Testcase 551: +CREATE FUNCTION eatarray(x real[]) RETURNS real[] +LANGUAGE plpgsql STRICT IMMUTABLE AS $$ +BEGIN + x[1] := x[1] + 1; + RETURN x; +END; +$$; + +--Testcase 552: +SELECT eatarray(rwagg(ARRAY[1.0::real])), eatarray(rwagg(ARRAY[1.0::real])); + +ROLLBACK; + -- Secondly test the case of a parallel aggregate combiner function -- returning NULL. For that use normal transition function, but a -- combiner function returning NULL. @@ -1704,28 +1987,32 @@ select v||'a', case when v||'a' = 'aa' then 1 else 0 end, count(*) -- does not lead to array overflow due to unexpected duplicate hash keys -- see CAFeeJoKKu0u+A_A9R9316djW-YW3-+Gtgvy3ju655qRHR3jtdA@mail.gmail.com --Testcase 399: +set enable_memoize to off; +--Testcase 400: explain (costs off) select 1 from tenk1 where (hundred, thousand) in (select twothousand, twothousand from onek); +--Testcase 401: +reset enable_memoize; -- -- Hash Aggregation Spill tests -- ---Testcase 400: +--Testcase 402: set enable_sort=false; ---Testcase 401: +--Testcase 403: set work_mem='64kB'; ---Testcase 402: +--Testcase 404: select unique1, count(*), sum(twothousand) from tenk1 group by unique1 having sum(fivethous) > 4975 order by sum(twothousand); ---Testcase 403: +--Testcase 405: set work_mem to default; ---Testcase 404: +--Testcase 406: set enable_sort to default; -- @@ -1733,59 +2020,59 @@ set enable_sort to default; -- aggregation. Force spilling in both cases by setting work_mem low. -- ---Testcase 405: +--Testcase 407: set work_mem='64kB'; ---Testcase 406: +--Testcase 408: create foreign table agg_data_2k(g int) server influxdb_svr; ---Testcase 407: +--Testcase 409: create foreign table agg_data_20k(g int) server influxdb_svr; ---Testcase 408: +--Testcase 410: create foreign table agg_group_1(c1 int, c2 numeric, c3 int) server influxdb_svr; ---Testcase 409: +--Testcase 411: create foreign table agg_group_2(a int, c1 numeric, c2 text, c3 int) server influxdb_svr; ---Testcase 410: +--Testcase 412: create foreign table agg_group_3(c1 numeric, c2 int4, c3 int) server influxdb_svr; ---Testcase 411: +--Testcase 413: create foreign table agg_group_4(c1 numeric, c2 text, c3 int) server influxdb_svr; ---Testcase 412: +--Testcase 414: create foreign table agg_hash_1(c1 int, c2 numeric, c3 int) server influxdb_svr; ---Testcase 413: +--Testcase 415: create foreign table agg_hash_2(a int, c1 numeric, c2 text, c3 int) server influxdb_svr; ---Testcase 414: +--Testcase 416: create foreign table agg_hash_3(c1 numeric, c2 int4, c3 int) server influxdb_svr; ---Testcase 415: +--Testcase 417: create foreign table agg_hash_4(c1 numeric, c2 text, c3 int) server influxdb_svr; ---Testcase 416: +--Testcase 418: insert into agg_data_2k select g from generate_series(0, 1999) g; --analyze agg_data_2k; ---Testcase 417: +--Testcase 419: insert into agg_data_20k select g from generate_series(0, 19999) g; --analyze agg_data_20k; -- Produce results with sorting. ---Testcase 418: +--Testcase 420: set enable_hashagg = false; ---Testcase 419: +--Testcase 421: set jit_above_cost = 0; ---Testcase 420: +--Testcase 422: explain (costs off) select g%10000 as c1, sum(g::numeric) as c2, count(*) as c3 from agg_data_20k group by g%10000; ---Testcase 421: +--Testcase 423: insert into agg_group_1 select g%10000 as c1, sum(g::numeric) as c2, count(*) as c3 from agg_data_20k group by g%10000; ---Testcase 422: +--Testcase 424: insert into agg_group_2 select * from (values (100), (300), (500)) as r(a), @@ -1797,40 +2084,40 @@ select * from where g < r.a group by g/2) as s; ---Testcase 423: +--Testcase 425: set jit_above_cost to default; ---Testcase 424: +--Testcase 426: insert into agg_group_3 select (g/2)::numeric as c1, sum(7::int4) as c2, count(*) as c3 from agg_data_2k group by g/2; ---Testcase 425: +--Testcase 427: insert into agg_group_4 select (g/2)::numeric as c1, array_agg(g::numeric) as c2, count(*) as c3 from agg_data_2k group by g/2; -- Produce results with hash aggregation ---Testcase 426: +--Testcase 428: set enable_hashagg = true; ---Testcase 427: +--Testcase 429: set enable_sort = false; ---Testcase 428: +--Testcase 430: set jit_above_cost = 0; ---Testcase 429: +--Testcase 431: explain (costs off) select g%10000 as c1, sum(g::numeric) as c2, count(*) as c3 from agg_data_20k group by g%10000; ---Testcase 430: +--Testcase 432: insert into agg_hash_1 select g%10000 as c1, sum(g::numeric) as c2, count(*) as c3 from agg_data_20k group by g%10000; ---Testcase 431: +--Testcase 433: insert into agg_hash_2 select * from (values (100), (300), (500)) as r(a), @@ -1842,74 +2129,87 @@ select * from where g < r.a group by g/2) as s; ---Testcase 432: +--Testcase 434: set jit_above_cost to default; ---Testcase 433: +--Testcase 435: insert into agg_hash_3 select (g/2)::numeric as c1, sum(7::int4) as c2, count(*) as c3 from agg_data_2k group by g/2; ---Testcase 434: +--Testcase 436: insert into agg_hash_4 select (g/2)::numeric as c1, array_agg(g::numeric) as c2, count(*) as c3 from agg_data_2k group by g/2; ---Testcase 435: +--Testcase 437: set enable_sort = true; ---Testcase 436: +--Testcase 438: set work_mem to default; -- Compare group aggregation results to hash aggregation results ---Testcase 437: +--Testcase 439: (select * from agg_hash_1 except select * from agg_group_1) union all (select * from agg_group_1 except select * from agg_hash_1); ---Testcase 438: +--Testcase 440: (select * from agg_hash_2 except select * from agg_group_2) union all (select * from agg_group_2 except select * from agg_hash_2); ---Testcase 439: +--Testcase 441: (select * from agg_hash_3 except select * from agg_group_3) union all (select * from agg_group_3 except select * from agg_hash_3); ---Testcase 440: +--Testcase 442: (select * from agg_hash_4 except select * from agg_group_4) union all (select * from agg_group_4 except select * from agg_hash_4); ---Testcase 441: +--Testcase 443: -- Clean up: +--Testcase 485: delete from agg_data_2k; +--Testcase 486: delete from agg_data_20k; +--Testcase 487: delete from agg_group_1; +--Testcase 488: delete from agg_group_2; +--Testcase 489: delete from agg_group_3; +--Testcase 490: delete from agg_group_4; +--Testcase 491: delete from agg_hash_1; +--Testcase 492: delete from agg_hash_2; +--Testcase 493: delete from agg_hash_3; +--Testcase 494: delete from agg_hash_4; +--Testcase 495: drop foreign table agg_data_2k; +--Testcase 496: drop foreign table agg_data_20k; +--Testcase 497: drop foreign table agg_group_1; ---Testcase 442: +--Testcase 444: drop foreign table agg_group_2; ---Testcase 443: +--Testcase 445: drop foreign table agg_group_3; ---Testcase 444: +--Testcase 446: drop foreign table agg_group_4; ---Testcase 445: +--Testcase 447: drop foreign table agg_hash_1; ---Testcase 446: +--Testcase 448: drop foreign table agg_hash_2; ---Testcase 447: +--Testcase 449: drop foreign table agg_hash_3; ---Testcase 448: +--Testcase 450: drop foreign table agg_hash_4; -- Clean up @@ -1925,29 +2225,45 @@ end; $d$; -- Clean up: +--Testcase 498: DROP AGGREGATE IF EXISTS newavg (int4); +--Testcase 499: DROP AGGREGATE IF EXISTS newsum (int4); +--Testcase 500: DROP AGGREGATE IF EXISTS newcnt (*); +--Testcase 501: DROP AGGREGATE IF EXISTS oldcnt (*); +--Testcase 502: DROP AGGREGATE IF EXISTS newcnt ("any"); +--Testcase 503: DROP AGGREGATE IF EXISTS sum2(int8,int8); +--Testcase 504: DROP FUNCTION IF EXISTS sum3(int8,int8,int8); +--Testcase 505: DROP AGGREGATE IF EXISTS aggfns(integer,integer,text); +--Testcase 506: DROP AGGREGATE IF EXISTS aggfstr(integer,integer,text); +--Testcase 507: DROP FUNCTION IF EXISTS aggfns_trans(aggtype[],integer,integer,text); +--Testcase 508: DROP FUNCTION IF EXISTS aggf_trans(aggtype[],integer,integer,text); +--Testcase 509: DROP TYPE IF EXISTS aggtype; +--Testcase 510: DROP AGGREGATE IF EXISTS test_percentile_disc(float8 ORDER BY anyelement); +--Testcase 511: DROP AGGREGATE IF EXISTS test_rank(VARIADIC "any" ORDER BY VARIADIC "any"); +--Testcase 512: DROP AGGREGATE IF EXISTS cleast_agg(variadic items anycompatiblearray); +--Testcase 513: DROP FUNCTION IF EXISTS cleast_accum(anycompatible, variadic anycompatiblearray); ---Testcase 449: +--Testcase 451: DROP USER MAPPING FOR CURRENT_USER SERVER influxdb_svr; ---Testcase 450: +--Testcase 452: DROP SERVER influxdb_svr CASCADE; ---Testcase 451: +--Testcase 453: DROP EXTENSION influxdb_fdw CASCADE; diff --git a/sql/12.12/extra/influxdb_fdw_post.sql b/sql/16.0/extra/influxdb_fdw_post.sql similarity index 68% rename from sql/12.12/extra/influxdb_fdw_post.sql rename to sql/16.0/extra/influxdb_fdw_post.sql index 65ff3b8..ad77b6b 100644 --- a/sql/12.12/extra/influxdb_fdw_post.sql +++ b/sql/16.0/extra/influxdb_fdw_post.sql @@ -36,7 +36,7 @@ CREATE FOREIGN TABLE "S 1"."T 0" ( "C 1" int NOT NULL, c2 int NOT NULL, c3 text, - time timestamp, + time timestamptz, c6 varchar(10), c7 char(10), c8 text @@ -46,7 +46,7 @@ CREATE FOREIGN TABLE "S 1"."T 1" ( "C 1" int NOT NULL, c2 int NOT NULL, c3 text, - time timestamp, + time timestamptz, c6 varchar(10), c7 char(10), c8 text @@ -80,7 +80,7 @@ INSERT INTO "S 1"."T 1" SELECT id, id % 10, to_char(id, 'FM00000'), - '1970-01-01'::timestamp + ((id % 100) || ' days')::interval, + '1970-01-01'::timestamptz + ((id % 100) || ' days')::interval, id % 10, id % 10, 'foo'::text @@ -121,41 +121,43 @@ CREATE FOREIGN TABLE ft1 ( c1 int NOT NULL, c2 int NOT NULL, c3 text, - time timestamp, + time timestamptz, c6 varchar(10), c7 char(10) default 'ft1', c8 text ) SERVER influxdb_svr; +--Testcase 22: ALTER FOREIGN TABLE ft1 DROP COLUMN c0; ---Testcase 22: +--Testcase 23: CREATE FOREIGN TABLE ft2 ( c1 int NOT NULL, c2 int NOT NULL, cx int, c3 text, - time timestamp, + time timestamptz, c6 varchar(10), c7 char(10) default 'ft2', c8 text ) SERVER influxdb_svr; +--Testcase 24: ALTER FOREIGN TABLE ft2 DROP COLUMN cx; ---Testcase 23: +--Testcase 25: CREATE FOREIGN TABLE ft4 ( c1 int NOT NULL, c2 int NOT NULL, c3 text ) SERVER influxdb_svr OPTIONS (table 'T3', tags 'c3'); ---Testcase 24: +--Testcase 26: CREATE FOREIGN TABLE ft5 ( c1 int NOT NULL, c2 int NOT NULL, c3 text ) SERVER influxdb_svr OPTIONS (table 'T4', tags 'c3'); ---Testcase 25: +--Testcase 27: CREATE FOREIGN TABLE ft6 ( c1 int NOT NULL, c2 int NOT NULL, @@ -167,6 +169,7 @@ CREATE FOREIGN TABLE ft6 ( -- =================================================================== -- requiressl and some other parameters are omitted because -- valid values for them depend on configure options +--Testcase 28: ALTER SERVER testserver1 OPTIONS ( -- use_remote_estimate 'false', -- updatable 'true', @@ -195,6 +198,7 @@ ALTER SERVER testserver1 OPTIONS ( --requirepeer 'value', -- krbsrvname 'value', -- gsslib 'value', + -- gssdelegation 'value' --replication 'value' ); @@ -206,6 +210,7 @@ ALTER SERVER testserver1 OPTIONS ( --ALTER SERVER testserver1 OPTIONS (ADD extensions 'foo, bar'); --ALTER SERVER testserver1 OPTIONS (DROP extensions); +--Testcase 29: ALTER USER MAPPING FOR public SERVER testserver1 OPTIONS (DROP user, DROP password); @@ -222,20 +227,25 @@ ALTER USER MAPPING FOR public SERVER testserver1 --ALTER USER MAPPING FOR public SERVER testserver1 -- OPTIONS (ADD sslkey 'value', ADD sslcert 'value'); +--Testcase 30: ALTER FOREIGN TABLE ft1 OPTIONS (table 'T1', tags 'c3'); +--Testcase 31: ALTER FOREIGN TABLE ft2 OPTIONS (table 'T1', tags 'c3'); +--Testcase 32: ALTER FOREIGN TABLE ft1 ALTER COLUMN c1 OPTIONS (column_name 'C 1'); +--Testcase 33: ALTER FOREIGN TABLE ft2 ALTER COLUMN c1 OPTIONS (column_name 'C 1'); ---Testcase 26: +--Testcase 34: \det+ -- Test that alteration of server options causes reconnection -- Remote's errors might be non-English, so hide them to ensure stable results \set VERBOSITY terse ---Testcase 27: +--Testcase 35: SELECT c3, time FROM ft1 ORDER BY c3, c1 LIMIT 1; -- should work +--Testcase 36: ALTER SERVER influxdb_svr OPTIONS (SET dbname 'no such database'); ---Testcase 28: +--Testcase 37: SELECT c3, time FROM ft1 ORDER BY c3, c1 LIMIT 1; -- should fail DO $d$ BEGIN @@ -243,164 +253,189 @@ DO $d$ OPTIONS (SET dbname 'postdb')$$; END; $d$; ---Testcase 29: +--Testcase 38: SELECT c3, time FROM ft1 ORDER BY c3, c1 LIMIT 1; -- should work again \set VERBOSITY default +-- =================================================================== +-- test error case for create publication on foreign table +-- =================================================================== +--Testcase 765: +CREATE PUBLICATION testpub_ftbl FOR TABLE ft1; -- should fail + -- =================================================================== -- simple queries -- =================================================================== -- single table without alias ---Testcase 30: +--Testcase 39: EXPLAIN (COSTS OFF) SELECT * FROM ft1 ORDER BY c3, c1 OFFSET 100 LIMIT 10; ---Testcase 31: +--Testcase 40: SELECT * FROM ft1 ORDER BY c3, c1 OFFSET 100 LIMIT 10; -- single table with alias - also test that tableoid sort is not pushed to remote side ---Testcase 32: +--Testcase 41: EXPLAIN (VERBOSE, COSTS OFF) SELECT * FROM ft1 t1 ORDER BY t1.c3, t1.c1, t1.tableoid OFFSET 100 LIMIT 10; ---Testcase 33: +--Testcase 42: SELECT * FROM ft1 t1 ORDER BY t1.c3, t1.c1, t1.tableoid OFFSET 100 LIMIT 10; -- whole-row reference ---Testcase 34: +--Testcase 43: EXPLAIN (VERBOSE, COSTS OFF) SELECT t1 FROM ft1 t1 ORDER BY t1.c3, t1.c1 OFFSET 100 LIMIT 10; ---Testcase 35: +--Testcase 44: SELECT t1 FROM ft1 t1 ORDER BY t1.c3, t1.c1 OFFSET 100 LIMIT 10; -- empty result ---Testcase 36: +--Testcase 45: SELECT * FROM ft1 WHERE false; -- with WHERE clause ---Testcase 37: +--Testcase 46: EXPLAIN (VERBOSE, COSTS OFF) SELECT * FROM ft1 t1 WHERE t1.c1 = 101 AND t1.c6 = '1' AND t1.c7 >= '1'; ---Testcase 38: +--Testcase 47: SELECT * FROM ft1 t1 WHERE t1.c1 = 101 AND t1.c6 = '1' AND t1.c7 >= '1'; -- with FOR UPDATE/SHARE ---Testcase 39: +--Testcase 48: EXPLAIN (VERBOSE, COSTS OFF) SELECT * FROM ft1 t1 WHERE c1 = 101 FOR UPDATE; ---Testcase 40: +--Testcase 49: SELECT * FROM ft1 t1 WHERE c1 = 101 FOR UPDATE; ---Testcase 41: +--Testcase 50: EXPLAIN (VERBOSE, COSTS OFF) SELECT * FROM ft1 t1 WHERE c1 = 102 FOR SHARE; ---Testcase 42: +--Testcase 51: SELECT * FROM ft1 t1 WHERE c1 = 102 FOR SHARE; -- aggregate ---Testcase 43: +--Testcase 52: SELECT COUNT(*) FROM ft1 t1; -- subquery ---Testcase 44: +--Testcase 53: SELECT * FROM ft1 t1 WHERE t1.c3 IN (SELECT c3 FROM ft2 t2 WHERE c1 <= 10) ORDER BY c1; -- subquery+MAX ---Testcase 45: +--Testcase 54: SELECT * FROM ft1 t1 WHERE t1.c3 = (SELECT MAX(c3) FROM ft2 t2) ORDER BY c1; -- used in CTE ---Testcase 46: +--Testcase 55: WITH t1 AS (SELECT * FROM ft1 WHERE c1 <= 10) SELECT t2.c1, t2.c2, t2.c3, t2.time FROM t1, ft2 t2 WHERE t1.c1 = t2.c1 ORDER BY t1.c1; -- fixed values ---Testcase 47: +--Testcase 56: SELECT 'fixed', NULL FROM ft1 t1 WHERE c1 = 1; -- Test forcing the remote server to produce sorted data for a merge join. +--Testcase 57: SET enable_hashjoin TO false; +--Testcase 58: SET enable_nestloop TO false; -- inner join; expressions in the clauses appear in the equivalence class list ---Testcase 48: +--Testcase 59: EXPLAIN (VERBOSE, COSTS OFF) SELECT t1.c1, t2."C 1" FROM ft2 t1 JOIN "S 1"."T 1" t2 ON (t1.c1 = t2."C 1") OFFSET 100 LIMIT 10; ---Testcase 49: +--Testcase 60: SELECT t1.c1, t2."C 1" FROM ft2 t1 JOIN "S 1"."T 1" t2 ON (t1.c1 = t2."C 1") OFFSET 100 LIMIT 10; -- outer join; expressions in the clauses do not appear in equivalence class -- list but no output change as compared to the previous query ---Testcase 50: +--Testcase 61: EXPLAIN (VERBOSE, COSTS OFF) SELECT t1.c1, t2."C 1" FROM ft2 t1 LEFT JOIN "S 1"."T 1" t2 ON (t1.c1 = t2."C 1") OFFSET 100 LIMIT 10; ---Testcase 51: +--Testcase 62: SELECT t1.c1, t2."C 1" FROM ft2 t1 LEFT JOIN "S 1"."T 1" t2 ON (t1.c1 = t2."C 1") OFFSET 100 LIMIT 10; -- A join between 2 foreign tables. ORDER BY clause is added to the -- foreign join so that the other table can be joined using merge join strategy. ---Testcase 52: +--Testcase 63: EXPLAIN (VERBOSE, COSTS OFF) SELECT t1."C 1" FROM "S 1"."T 1" t1 left join ft1 t2 join ft2 t3 on (t2.c1 = t3.c1) on (t3.c1 = t1."C 1") OFFSET 100 LIMIT 10; ---Testcase 53: +--Testcase 64: SELECT t1."C 1" FROM "S 1"."T 1" t1 left join ft1 t2 join ft2 t3 on (t2.c1 = t3.c1) on (t3.c1 = t1."C 1") OFFSET 100 LIMIT 10; -- Test similar to above, except that the full join prevents any equivalence -- classes from being merged. This produces single relation equivalence classes -- included in join restrictions. ---Testcase 54: +--Testcase 65: EXPLAIN (VERBOSE, COSTS OFF) SELECT t1."C 1", t2.c1, t3.c1 FROM "S 1"."T 1" t1 left join ft1 t2 full join ft2 t3 on (t2.c1 = t3.c1) on (t3.c1 = t1."C 1") OFFSET 100 LIMIT 10; ---Testcase 55: +--Testcase 66: SELECT t1."C 1", t2.c1, t3.c1 FROM "S 1"."T 1" t1 left join ft1 t2 full join ft2 t3 on (t2.c1 = t3.c1) on (t3.c1 = t1."C 1") OFFSET 100 LIMIT 10; -- Test similar to above with all full outer joins ---Testcase 56: +--Testcase 67: EXPLAIN (VERBOSE, COSTS OFF) SELECT t1."C 1", t2.c1, t3.c1 FROM "S 1"."T 1" t1 full join ft1 t2 full join ft2 t3 on (t2.c1 = t3.c1) on (t3.c1 = t1."C 1") OFFSET 100 LIMIT 10; ---Testcase 57: +--Testcase 68: SELECT t1."C 1", t2.c1, t3.c1 FROM "S 1"."T 1" t1 full join ft1 t2 full join ft2 t3 on (t2.c1 = t3.c1) on (t3.c1 = t1."C 1") OFFSET 100 LIMIT 10; +--Testcase 69: RESET enable_hashjoin; +--Testcase 70: RESET enable_nestloop; +-- Test executing assertion in estimate_path_cost_size() that makes sure that +-- retrieved_rows for foreign rel re-used to cost pre-sorted foreign paths is +-- a sensible value even when the rel has tuples=0 +--Testcase 71: +CREATE FOREIGN TABLE loct_empty (c1 int NOT NULL, c2 text) SERVER influxdb_svr; +--Testcase 72: +CREATE FOREIGN TABLE ft_empty (c1 int NOT NULL, c2 text) + SERVER influxdb_svr OPTIONS (table 'loct_empty'); +--Testcase 73: +INSERT INTO loct_empty + SELECT id, 'AAA' || to_char(id, 'FM000') FROM generate_series(1, 100) id; +--Testcase 74: +DELETE FROM loct_empty; +--ANALYZE ft_empty; +--Testcase 75: +EXPLAIN (VERBOSE, COSTS OFF) SELECT * FROM ft_empty ORDER BY c1; + -- =================================================================== -- WHERE with remotely-executable conditions -- =================================================================== ---Testcase 58: +--Testcase 76: EXPLAIN (VERBOSE, COSTS OFF) SELECT * FROM ft1 t1 WHERE t1.c1 = 1; -- Var, OpExpr(b), Const ---Testcase 59: +--Testcase 77: EXPLAIN (VERBOSE, COSTS OFF) SELECT * FROM ft1 t1 WHERE t1.c1 = 100 AND t1.c2 = 0; -- BoolExpr ---Testcase 60: +--Testcase 78: EXPLAIN (VERBOSE, COSTS OFF) SELECT * FROM ft1 t1 WHERE c1 IS NULL; -- NullTest ---Testcase 61: +--Testcase 79: EXPLAIN (VERBOSE, COSTS OFF) SELECT * FROM ft1 t1 WHERE c1 IS NOT NULL; -- NullTest ---Testcase 62: +--Testcase 80: EXPLAIN (VERBOSE, COSTS OFF) SELECT * FROM ft1 t1 WHERE round(abs(c1), 0) = 1; -- FuncExpr ---Testcase 63: +--Testcase 81: EXPLAIN (VERBOSE, COSTS OFF) SELECT * FROM ft1 t1 WHERE c1 = -c1; -- OpExpr(l) ---Testcase 64: -EXPLAIN (VERBOSE, COSTS OFF) SELECT * FROM ft1 t1 WHERE 1 = c1!; -- OpExpr(r) ---Testcase 65: +--Testcase 82: EXPLAIN (VERBOSE, COSTS OFF) SELECT * FROM ft1 t1 WHERE (c1 IS NOT NULL) IS DISTINCT FROM (c1 IS NOT NULL); -- DistinctExpr ---Testcase 66: +--Testcase 83: EXPLAIN (VERBOSE, COSTS OFF) SELECT * FROM ft1 t1 WHERE c1 = ANY(ARRAY[c2, 1, c1 + 0]); -- ScalarArrayOpExpr ---Testcase 67: +--Testcase 84: EXPLAIN (VERBOSE, COSTS OFF) SELECT * FROM ft1 t1 WHERE c1 = (ARRAY[c1,c2,3])[1]; -- SubscriptingRef ---Testcase 68: +--Testcase 85: EXPLAIN (VERBOSE, COSTS OFF) SELECT * FROM ft1 t1 WHERE c6 = E'foo''s\\bar'; -- check special chars ---Testcase 69: +--Testcase 86: EXPLAIN (VERBOSE, COSTS OFF) SELECT * FROM ft1 t1 WHERE c8 = 'foo'; -- can't be sent to remote -- parameterized remote path for foreign table ---Testcase 70: +--Testcase 87: EXPLAIN (VERBOSE, COSTS OFF) SELECT * FROM "S 1"."T 1" a, ft2 b WHERE a."C 1" = 47 AND b.c1 = a.c2; ---Testcase 71: -SELECT * FROM ft2 a, ft2 b WHERE a.c1 = 47 AND b.c1 = a.c2; +--Testcase 88: +SELECT * FROM "S 1"."T 1" a, ft2 b WHERE a."C 1" = 47 AND b.c1 = a.c2; -- check both safe and unsafe join conditions ---Testcase 72: +--Testcase 89: EXPLAIN (VERBOSE, COSTS OFF) SELECT * FROM ft2 a, ft2 b WHERE a.c2 = 6 AND b.c1 = a.c1 AND a.c8 = 'foo' AND b.c7 = upper(a.c7); ---Testcase 73: +--Testcase 90: SELECT * FROM ft2 a, ft2 b WHERE a.c2 = 6 AND b.c1 = a.c1 AND a.c8 = 'foo' AND b.c7 = upper(a.c7) ORDER BY a.c1; -- bug before 9.3.5 due to sloppy handling of remote-estimate parameters ---Testcase 74: +--Testcase 91: SELECT * FROM ft1 WHERE c1 = ANY (ARRAY(SELECT c1 FROM ft2 WHERE c1 < 5)); ---Testcase 75: +--Testcase 92: SELECT * FROM ft2 WHERE c1 = ANY (ARRAY(SELECT c1 FROM ft1 WHERE c1 < 5)); -- we should not push order by clause with volatile expressions or unsafe -- collations ---Testcase 76: +--Testcase 93: EXPLAIN (VERBOSE, COSTS OFF) SELECT * FROM ft2 ORDER BY ft2.c1, random(); ---Testcase 77: +--Testcase 94: EXPLAIN (VERBOSE, COSTS OFF) SELECT * FROM ft2 ORDER BY ft2.c1, ft2.c3 collate "C"; -- user-defined operator/function ---Testcase 78: +--Testcase 95: CREATE FUNCTION influxdb_fdw_abs(int) RETURNS int AS $$ BEGIN RETURN abs($1); END $$ LANGUAGE plpgsql IMMUTABLE; ---Testcase 79: +--Testcase 96: CREATE OPERATOR === ( LEFTARG = int, RIGHTARG = int, @@ -409,210 +444,276 @@ CREATE OPERATOR === ( ); -- built-in operators and functions can be shipped for remote execution ---Testcase 80: +--Testcase 97: EXPLAIN (VERBOSE, COSTS OFF) SELECT count(c3) FROM ft1 t1 WHERE t1.c1 = abs(t1.c2); ---Testcase 81: +--Testcase 98: SELECT count(c3) FROM ft1 t1 WHERE t1.c1 = abs(t1.c2); ---Testcase 82: +--Testcase 99: EXPLAIN (VERBOSE, COSTS OFF) SELECT count(c3) FROM ft1 t1 WHERE t1.c1 = t1.c2; ---Testcase 83: +--Testcase 100: SELECT count(c3) FROM ft1 t1 WHERE t1.c1 = t1.c2; -- by default, user-defined ones cannot ---Testcase 84: +--Testcase 101: EXPLAIN (VERBOSE, COSTS OFF) SELECT count(c3) FROM ft1 t1 WHERE t1.c1 = influxdb_fdw_abs(t1.c2); ---Testcase 85: +--Testcase 102: SELECT count(c3) FROM ft1 t1 WHERE t1.c1 = influxdb_fdw_abs(t1.c2); ---Testcase 86: +--Testcase 103: EXPLAIN (VERBOSE, COSTS OFF) SELECT count(c3) FROM ft1 t1 WHERE t1.c1 === t1.c2; ---Testcase 87: +--Testcase 104: SELECT count(c3) FROM ft1 t1 WHERE t1.c1 === t1.c2; -- ORDER BY can be shipped, though ---Testcase 88: +--Testcase 105: EXPLAIN (VERBOSE, COSTS OFF) SELECT * FROM ft1 t1 WHERE t1.c1 === t1.c2 order by t1.c2 limit 1; ---Testcase 89: +--Testcase 106: SELECT * FROM ft1 t1 WHERE t1.c1 === t1.c2 order by t1.c2 limit 1; -- but let's put them in an extension ... +--Testcase 107: ALTER EXTENSION influxdb_fdw ADD FUNCTION influxdb_fdw_abs(int); +--Testcase 108: ALTER EXTENSION influxdb_fdw ADD OPERATOR === (int, int); -- ALTER SERVER loopback OPTIONS (ADD extensions 'influxdb_fdw'); -- ... now they can be shipped ---Testcase 90: +--Testcase 109: EXPLAIN (VERBOSE, COSTS OFF) SELECT count(c3) FROM ft1 t1 WHERE t1.c1 = influxdb_fdw_abs(t1.c2); ---Testcase 91: +--Testcase 110: SELECT count(c3) FROM ft1 t1 WHERE t1.c1 = influxdb_fdw_abs(t1.c2); ---Testcase 92: +--Testcase 111: EXPLAIN (VERBOSE, COSTS OFF) SELECT count(c3) FROM ft1 t1 WHERE t1.c1 === t1.c2; ---Testcase 93: +--Testcase 112: SELECT count(c3) FROM ft1 t1 WHERE t1.c1 === t1.c2; -- and both ORDER BY and LIMIT can be shipped ---Testcase 94: +--Testcase 113: EXPLAIN (VERBOSE, COSTS OFF) SELECT * FROM ft1 t1 WHERE t1.c1 === t1.c2 order by t1.c2 limit 1; ---Testcase 95: +--Testcase 114: SELECT * FROM ft1 t1 WHERE t1.c1 === t1.c2 order by t1.c2 limit 1; +-- Test CASE pushdown +-- InfluxDB not support CASE expressions. +--Testcase 813: +EXPLAIN (VERBOSE, COSTS OFF) +SELECT c1,c2,c3 FROM ft2 WHERE CASE WHEN c1 > 990 THEN c1 END < 1000 ORDER BY c1; +--Testcase 814: +SELECT c1,c2,c3 FROM ft2 WHERE CASE WHEN c1 > 990 THEN c1 END < 1000 ORDER BY c1; + +-- Nested CASE +--Testcase 815: +EXPLAIN (VERBOSE, COSTS OFF) +SELECT c1,c2,c3 FROM ft2 WHERE CASE CASE WHEN c2 > 0 THEN c2 END WHEN 100 THEN 601 WHEN c2 THEN c2 ELSE 0 END > 600 ORDER BY c1; +--Testcase 816: +SELECT c1,c2,c3 FROM ft2 WHERE CASE CASE WHEN c2 > 0 THEN c2 END WHEN 100 THEN 601 WHEN c2 THEN c2 ELSE 0 END > 600 ORDER BY c1; + +-- CASE arg WHEN +--Testcase 817: +EXPLAIN (VERBOSE, COSTS OFF) +SELECT * FROM ft1 WHERE c1 > (CASE mod(c1, 4) WHEN 0 THEN 1 WHEN 2 THEN 50 ELSE 100 END); + +-- CASE cannot be pushed down because of unshippable arg clause +--Testcase 818: +EXPLAIN (VERBOSE, COSTS OFF) +SELECT * FROM ft1 WHERE c1 > (CASE random()::integer WHEN 0 THEN 1 WHEN 2 THEN 50 ELSE 100 END); + +-- these are shippable +--Testcase 819: +EXPLAIN (VERBOSE, COSTS OFF) +SELECT * FROM ft1 WHERE CASE c6 WHEN 'foo' THEN true ELSE c3 < 'bar' END; +--Testcase 820: +EXPLAIN (VERBOSE, COSTS OFF) +SELECT * FROM ft1 WHERE CASE c3 WHEN c6 THEN true ELSE c3 < 'bar' END; + +-- but this is not because of collation +--Testcase 821: +EXPLAIN (VERBOSE, COSTS OFF) +SELECT * FROM ft1 WHERE CASE c3 COLLATE "C" WHEN c6 THEN true ELSE c3 < 'bar' END; + +-- a regconfig constant referring to this text search configuration +-- is initially unshippable +--Testcase 822: +CREATE TEXT SEARCH CONFIGURATION public.custom_search + (COPY = pg_catalog.english); +--Testcase 823: +EXPLAIN (VERBOSE, COSTS OFF) +SELECT c1, to_tsvector('custom_search'::regconfig, c3) FROM ft1 +WHERE c1 = 642 AND length(to_tsvector('custom_search'::regconfig, c3)) > 0; +--Testcase 824: +SELECT c1, to_tsvector('custom_search'::regconfig, c3) FROM ft1 +WHERE c1 = 642 AND length(to_tsvector('custom_search'::regconfig, c3)) > 0; +-- but if it's in a shippable extension, it can be shipped +ALTER EXTENSION influxdb_fdw ADD TEXT SEARCH CONFIGURATION public.custom_search; +-- however, that doesn't flush the shippability cache, so do a quick reconnect +\c - +EXPLAIN (VERBOSE, COSTS OFF) +SELECT c1, to_tsvector('custom_search'::regconfig, c3) FROM ft1 +WHERE c1 = 642 AND length(to_tsvector('custom_search'::regconfig, c3)) > 0; +SELECT c1, to_tsvector('custom_search'::regconfig, c3) FROM ft1 +WHERE c1 = 642 AND length(to_tsvector('custom_search'::regconfig, c3)) > 0; + -- =================================================================== -- JOIN queries -- =================================================================== -- join two tables ---Testcase 96: +--Testcase 115: EXPLAIN (VERBOSE, COSTS OFF) SELECT t1.c1, t2.c1 FROM ft1 t1 JOIN ft2 t2 ON (t1.c1 = t2.c1) ORDER BY t1.c3, t1.c1 OFFSET 100 LIMIT 10; ---Testcase 97: +--Testcase 116: SELECT t1.c1, t2.c1 FROM ft1 t1 JOIN ft2 t2 ON (t1.c1 = t2.c1) ORDER BY t1.c3, t1.c1 OFFSET 100 LIMIT 10; -- join three tables ---Testcase 98: +--Testcase 117: EXPLAIN (VERBOSE, COSTS OFF) SELECT t1.c1, t2.c2, t3.c3 FROM ft1 t1 JOIN ft2 t2 ON (t1.c1 = t2.c1) JOIN ft4 t3 ON (t3.c1 = t1.c1) ORDER BY t1.c3, t1.c1 OFFSET 10 LIMIT 10; ---Testcase 99: +--Testcase 118: SELECT t1.c1, t2.c2, t3.c3 FROM ft1 t1 JOIN ft2 t2 ON (t1.c1 = t2.c1) JOIN ft4 t3 ON (t3.c1 = t1.c1) ORDER BY t1.c3, t1.c1 OFFSET 10 LIMIT 10; -- left outer join ---Testcase 100: +--Testcase 119: EXPLAIN (VERBOSE, COSTS OFF) SELECT t1.c1, t2.c1 FROM ft4 t1 LEFT JOIN ft5 t2 ON (t1.c1 = t2.c1) ORDER BY t1.c1, t2.c1 OFFSET 10 LIMIT 10; ---Testcase 101: +--Testcase 120: SELECT t1.c1, t2.c1 FROM ft4 t1 LEFT JOIN ft5 t2 ON (t1.c1 = t2.c1) ORDER BY t1.c1, t2.c1 OFFSET 10 LIMIT 10; -- left outer join three tables ---Testcase 102: +--Testcase 121: EXPLAIN (VERBOSE, COSTS OFF) SELECT t1.c1, t2.c2, t3.c3 FROM ft2 t1 LEFT JOIN ft2 t2 ON (t1.c1 = t2.c1) LEFT JOIN ft4 t3 ON (t2.c1 = t3.c1) OFFSET 10 LIMIT 10; ---Testcase 103: +--Testcase 122: SELECT t1.c1, t2.c2, t3.c3 FROM ft2 t1 LEFT JOIN ft2 t2 ON (t1.c1 = t2.c1) LEFT JOIN ft4 t3 ON (t2.c1 = t3.c1) ORDER BY t1.c1 OFFSET 10 LIMIT 10; -- left outer join + placement of clauses. -- clauses within the nullable side are not pulled up, but top level clause on -- non-nullable side is pushed into non-nullable side ---Testcase 104: +--Testcase 123: EXPLAIN (VERBOSE, COSTS OFF) SELECT t1.c1, t1.c2, t2.c1, t2.c2 FROM ft4 t1 LEFT JOIN (SELECT * FROM ft5 WHERE c1 < 10) t2 ON (t1.c1 = t2.c1) WHERE t1.c1 < 10; ---Testcase 105: +--Testcase 124: SELECT t1.c1, t1.c2, t2.c1, t2.c2 FROM ft4 t1 LEFT JOIN (SELECT * FROM ft5 WHERE c1 < 10) t2 ON (t1.c1 = t2.c1) WHERE t1.c1 < 10; -- clauses within the nullable side are not pulled up, but the top level clause -- on nullable side is not pushed down into nullable side ---Testcase 106: +--Testcase 125: EXPLAIN (VERBOSE, COSTS OFF) SELECT t1.c1, t1.c2, t2.c1, t2.c2 FROM ft4 t1 LEFT JOIN (SELECT * FROM ft5 WHERE c1 < 10) t2 ON (t1.c1 = t2.c1) WHERE (t2.c1 < 10 OR t2.c1 IS NULL) AND t1.c1 < 10; ---Testcase 107: +--Testcase 126: SELECT t1.c1, t1.c2, t2.c1, t2.c2 FROM ft4 t1 LEFT JOIN (SELECT * FROM ft5 WHERE c1 < 10) t2 ON (t1.c1 = t2.c1) WHERE (t2.c1 < 10 OR t2.c1 IS NULL) AND t1.c1 < 10; -- right outer join ---Testcase 108: +--Testcase 127: EXPLAIN (VERBOSE, COSTS OFF) SELECT t1.c1, t2.c1 FROM ft5 t1 RIGHT JOIN ft4 t2 ON (t1.c1 = t2.c1) ORDER BY t2.c1, t1.c1 OFFSET 10 LIMIT 10; ---Testcase 109: +--Testcase 128: SELECT t1.c1, t2.c1 FROM ft5 t1 RIGHT JOIN ft4 t2 ON (t1.c1 = t2.c1) ORDER BY t2.c1, t1.c1 OFFSET 10 LIMIT 10; -- right outer join three tables ---Testcase 110: +--Testcase 129: EXPLAIN (VERBOSE, COSTS OFF) SELECT t1.c1, t2.c2, t3.c3 FROM ft2 t1 RIGHT JOIN ft2 t2 ON (t1.c1 = t2.c1) RIGHT JOIN ft4 t3 ON (t2.c1 = t3.c1) OFFSET 10 LIMIT 10; ---Testcase 111: +--Testcase 130: SELECT t1.c1, t2.c2, t3.c3 FROM ft2 t1 RIGHT JOIN ft2 t2 ON (t1.c1 = t2.c1) RIGHT JOIN ft4 t3 ON (t2.c1 = t3.c1) OFFSET 10 LIMIT 10; -- full outer join ---Testcase 112: +--Testcase 131: EXPLAIN (VERBOSE, COSTS OFF) SELECT t1.c1, t2.c1 FROM ft4 t1 FULL JOIN ft5 t2 ON (t1.c1 = t2.c1) ORDER BY t1.c1, t2.c1 OFFSET 45 LIMIT 10; ---Testcase 113: +--Testcase 132: SELECT t1.c1, t2.c1 FROM ft4 t1 FULL JOIN ft5 t2 ON (t1.c1 = t2.c1) ORDER BY t1.c1, t2.c1 OFFSET 45 LIMIT 10; -- full outer join with restrictions on the joining relations -- a. the joining relations are both base relations ---Testcase 114: +--Testcase 133: EXPLAIN (VERBOSE, COSTS OFF) SELECT t1.c1, t2.c1 FROM (SELECT c1 FROM ft4 WHERE c1 between 50 and 60) t1 FULL JOIN (SELECT c1 FROM ft5 WHERE c1 between 50 and 60) t2 ON (t1.c1 = t2.c1) ORDER BY t1.c1, t2.c1; ---Testcase 115: +--Testcase 134: SELECT t1.c1, t2.c1 FROM (SELECT c1 FROM ft4 WHERE c1 between 50 and 60) t1 FULL JOIN (SELECT c1 FROM ft5 WHERE c1 between 50 and 60) t2 ON (t1.c1 = t2.c1) ORDER BY t1.c1, t2.c1; ---Testcase 116: +--Testcase 135: EXPLAIN (VERBOSE, COSTS OFF) SELECT 1 FROM (SELECT c1 FROM ft4 WHERE c1 between 50 and 60) t1 FULL JOIN (SELECT c1 FROM ft5 WHERE c1 between 50 and 60) t2 ON (TRUE) OFFSET 10 LIMIT 10; ---Testcase 117: +--Testcase 136: SELECT 1 FROM (SELECT c1 FROM ft4 WHERE c1 between 50 and 60) t1 FULL JOIN (SELECT c1 FROM ft5 WHERE c1 between 50 and 60) t2 ON (TRUE) OFFSET 10 LIMIT 10; -- b. one of the joining relations is a base relation and the other is a join -- relation ---Testcase 118: +--Testcase 137: EXPLAIN (VERBOSE, COSTS OFF) SELECT t1.c1, ss.a, ss.b FROM (SELECT c1 FROM ft4 WHERE c1 between 50 and 60) t1 FULL JOIN (SELECT t2.c1, t3.c1 FROM ft4 t2 LEFT JOIN ft5 t3 ON (t2.c1 = t3.c1) WHERE (t2.c1 between 50 and 60)) ss(a, b) ON (t1.c1 = ss.a) ORDER BY t1.c1, ss.a, ss.b; ---Testcase 119: +--Testcase 138: SELECT t1.c1, ss.a, ss.b FROM (SELECT c1 FROM ft4 WHERE c1 between 50 and 60) t1 FULL JOIN (SELECT t2.c1, t3.c1 FROM ft4 t2 LEFT JOIN ft5 t3 ON (t2.c1 = t3.c1) WHERE (t2.c1 between 50 and 60)) ss(a, b) ON (t1.c1 = ss.a) ORDER BY t1.c1, ss.a, ss.b; -- c. test deparsing the remote query as nested subqueries ---Testcase 120: +--Testcase 139: EXPLAIN (VERBOSE, COSTS OFF) SELECT t1.c1, ss.a, ss.b FROM (SELECT c1 FROM ft4 WHERE c1 between 50 and 60) t1 FULL JOIN (SELECT t2.c1, t3.c1 FROM (SELECT c1 FROM ft4 WHERE c1 between 50 and 60) t2 FULL JOIN (SELECT c1 FROM ft5 WHERE c1 between 50 and 60) t3 ON (t2.c1 = t3.c1) WHERE t2.c1 IS NULL OR t2.c1 IS NOT NULL) ss(a, b) ON (t1.c1 = ss.a) ORDER BY t1.c1, ss.a, ss.b; ---Testcase 121: +--Testcase 140: SELECT t1.c1, ss.a, ss.b FROM (SELECT c1 FROM ft4 WHERE c1 between 50 and 60) t1 FULL JOIN (SELECT t2.c1, t3.c1 FROM (SELECT c1 FROM ft4 WHERE c1 between 50 and 60) t2 FULL JOIN (SELECT c1 FROM ft5 WHERE c1 between 50 and 60) t3 ON (t2.c1 = t3.c1) WHERE t2.c1 IS NULL OR t2.c1 IS NOT NULL) ss(a, b) ON (t1.c1 = ss.a) ORDER BY t1.c1, ss.a, ss.b; -- d. test deparsing rowmarked relations as subqueries ---Testcase 122: +--Testcase 141: EXPLAIN (VERBOSE, COSTS OFF) SELECT t1.c1, ss.a, ss.b FROM (SELECT c1 FROM "S 1"."T 3" WHERE c1 = 50) t1 INNER JOIN (SELECT t2.c1, t3.c1 FROM (SELECT c1 FROM ft4 WHERE c1 between 50 and 60) t2 FULL JOIN (SELECT c1 FROM ft5 WHERE c1 between 50 and 60) t3 ON (t2.c1 = t3.c1) WHERE t2.c1 IS NULL OR t2.c1 IS NOT NULL) ss(a, b) ON (TRUE) ORDER BY t1.c1, ss.a, ss.b FOR UPDATE OF t1; ---Testcase 123: +--Testcase 142: SELECT t1.c1, ss.a, ss.b FROM (SELECT c1 FROM "S 1"."T 3" WHERE c1 = 50) t1 INNER JOIN (SELECT t2.c1, t3.c1 FROM (SELECT c1 FROM ft4 WHERE c1 between 50 and 60) t2 FULL JOIN (SELECT c1 FROM ft5 WHERE c1 between 50 and 60) t3 ON (t2.c1 = t3.c1) WHERE t2.c1 IS NULL OR t2.c1 IS NOT NULL) ss(a, b) ON (TRUE) ORDER BY t1.c1, ss.a, ss.b FOR UPDATE OF t1; -- full outer join + inner join ---Testcase 124: +--Testcase 143: EXPLAIN (VERBOSE, COSTS OFF) SELECT t1.c1, t2.c1, t3.c1 FROM ft4 t1 INNER JOIN ft5 t2 ON (t1.c1 = t2.c1 + 1 and t1.c1 between 50 and 60) FULL JOIN ft4 t3 ON (t2.c1 = t3.c1) ORDER BY t1.c1, t2.c1, t3.c1 LIMIT 10; ---Testcase 125: +--Testcase 144: SELECT t1.c1, t2.c1, t3.c1 FROM ft4 t1 INNER JOIN ft5 t2 ON (t1.c1 = t2.c1 + 1 and t1.c1 between 50 and 60) FULL JOIN ft4 t3 ON (t2.c1 = t3.c1) ORDER BY t1.c1, t2.c1, t3.c1 LIMIT 10; -- full outer join three tables ---Testcase 126: +--Testcase 145: EXPLAIN (VERBOSE, COSTS OFF) SELECT t1.c1, t2.c2, t3.c3 FROM ft2 t1 FULL JOIN ft2 t2 ON (t1.c1 = t2.c1) FULL JOIN ft4 t3 ON (t2.c1 = t3.c1) OFFSET 10 LIMIT 10; ---Testcase 127: +--Testcase 146: SELECT t1.c1, t2.c2, t3.c3 FROM ft2 t1 FULL JOIN ft2 t2 ON (t1.c1 = t2.c1) FULL JOIN ft4 t3 ON (t2.c1 = t3.c1) ORDER BY t1.c1 OFFSET 10 LIMIT 10; -- full outer join + right outer join ---Testcase 128: +--Testcase 147: EXPLAIN (VERBOSE, COSTS OFF) SELECT t1.c1, t2.c2, t3.c3 FROM ft2 t1 FULL JOIN ft2 t2 ON (t1.c1 = t2.c1) RIGHT JOIN ft4 t3 ON (t2.c1 = t3.c1) OFFSET 10 LIMIT 10; ---Testcase 129: +--Testcase 148: SELECT t1.c1, t2.c2, t3.c3 FROM ft2 t1 FULL JOIN ft2 t2 ON (t1.c1 = t2.c1) RIGHT JOIN ft4 t3 ON (t2.c1 = t3.c1) OFFSET 10 LIMIT 10; -- right outer join + full outer join ---Testcase 130: +--Testcase 149: EXPLAIN (VERBOSE, COSTS OFF) SELECT t1.c1, t2.c2, t3.c3 FROM ft2 t1 RIGHT JOIN ft2 t2 ON (t1.c1 = t2.c1) FULL JOIN ft4 t3 ON (t2.c1 = t3.c1) OFFSET 10 LIMIT 10; ---Testcase 131: +--Testcase 150: SELECT t1.c1, t2.c2, t3.c3 FROM ft2 t1 RIGHT JOIN ft2 t2 ON (t1.c1 = t2.c1) FULL JOIN ft4 t3 ON (t2.c1 = t3.c1) ORDER BY t1.c1 OFFSET 10 LIMIT 10; -- full outer join + left outer join ---Testcase 132: +--Testcase 151: EXPLAIN (VERBOSE, COSTS OFF) SELECT t1.c1, t2.c2, t3.c3 FROM ft2 t1 FULL JOIN ft2 t2 ON (t1.c1 = t2.c1) LEFT JOIN ft4 t3 ON (t2.c1 = t3.c1) OFFSET 10 LIMIT 10; ---Testcase 133: +--Testcase 152: SELECT t1.c1, t2.c2, t3.c3 FROM ft2 t1 FULL JOIN ft2 t2 ON (t1.c1 = t2.c1) LEFT JOIN ft4 t3 ON (t2.c1 = t3.c1) ORDER BY t1.c1 OFFSET 10 LIMIT 10; -- left outer join + full outer join ---Testcase 134: +--Testcase 153: EXPLAIN (VERBOSE, COSTS OFF) SELECT t1.c1, t2.c2, t3.c3 FROM ft2 t1 LEFT JOIN ft2 t2 ON (t1.c1 = t2.c1) FULL JOIN ft4 t3 ON (t2.c1 = t3.c1) OFFSET 10 LIMIT 10; ---Testcase 135: +--Testcase 154: SELECT t1.c1, t2.c2, t3.c3 FROM ft2 t1 LEFT JOIN ft2 t2 ON (t1.c1 = t2.c1) FULL JOIN ft4 t3 ON (t2.c1 = t3.c1) ORDER BY t1.c1 OFFSET 10 LIMIT 10; +--Testcase 155: +SET enable_memoize TO off; -- right outer join + left outer join ---Testcase 136: +--Testcase 156: EXPLAIN (VERBOSE, COSTS OFF) SELECT t1.c1, t2.c2, t3.c3 FROM ft2 t1 RIGHT JOIN ft2 t2 ON (t1.c1 = t2.c1) LEFT JOIN ft4 t3 ON (t2.c1 = t3.c1) OFFSET 10 LIMIT 10; ---Testcase 137: +--Testcase 157: SELECT t1.c1, t2.c2, t3.c3 FROM ft2 t1 RIGHT JOIN ft2 t2 ON (t1.c1 = t2.c1) LEFT JOIN ft4 t3 ON (t2.c1 = t3.c1) ORDER BY t1.c1 OFFSET 10 LIMIT 10; +--Testcase 158: +RESET enable_memoize; -- left outer join + right outer join ---Testcase 138: +--Testcase 159: EXPLAIN (VERBOSE, COSTS OFF) SELECT t1.c1, t2.c2, t3.c3 FROM ft2 t1 LEFT JOIN ft2 t2 ON (t1.c1 = t2.c1) RIGHT JOIN ft4 t3 ON (t2.c1 = t3.c1) OFFSET 10 LIMIT 10; ---Testcase 139: +--Testcase 160: SELECT t1.c1, t2.c2, t3.c3 FROM ft2 t1 LEFT JOIN ft2 t2 ON (t1.c1 = t2.c1) RIGHT JOIN ft4 t3 ON (t2.c1 = t3.c1) ORDER BY t1.c1 OFFSET 10 LIMIT 10; -- full outer join + WHERE clause, only matched rows ---Testcase 140: +--Testcase 161: EXPLAIN (VERBOSE, COSTS OFF) SELECT t1.c1, t2.c1 FROM ft4 t1 FULL JOIN ft5 t2 ON (t1.c1 = t2.c1) WHERE (t1.c1 = t2.c1 OR t1.c1 IS NULL) ORDER BY t1.c1, t2.c1 OFFSET 10 LIMIT 10; ---Testcase 141: +--Testcase 162: SELECT t1.c1, t2.c1 FROM ft4 t1 FULL JOIN ft5 t2 ON (t1.c1 = t2.c1) WHERE (t1.c1 = t2.c1 OR t1.c1 IS NULL) ORDER BY t1.c1, t2.c1 OFFSET 10 LIMIT 10; -- full outer join + WHERE clause with shippable extensions set ---Testcase 142: +--Testcase 163: EXPLAIN (VERBOSE, COSTS OFF) SELECT t1.c1, t2.c2, t1.c3 FROM ft1 t1 FULL JOIN ft2 t2 ON (t1.c1 = t2.c1) WHERE influxdb_fdw_abs(t1.c1) > 0 OFFSET 10 LIMIT 10; -- skip, influxdb does not have option 'extensions' @@ -623,185 +724,235 @@ SELECT t1.c1, t2.c2, t1.c3 FROM ft1 t1 FULL JOIN ft2 t2 ON (t1.c1 = t2.c1) WHERE -- ALTER SERVER loopback OPTIONS (ADD extensions 'influxdb_fdw'); -- join two tables with FOR UPDATE clause -- tests whole-row reference for row marks ---Testcase 143: +--Testcase 164: EXPLAIN (VERBOSE, COSTS OFF) SELECT t1.c1, t2.c1 FROM ft1 t1 JOIN ft2 t2 ON (t1.c1 = t2.c1) ORDER BY t1.c3, t1.c1 OFFSET 100 LIMIT 10 FOR UPDATE OF t1; ---Testcase 144: +--Testcase 165: SELECT t1.c1, t2.c1 FROM ft1 t1 JOIN ft2 t2 ON (t1.c1 = t2.c1) ORDER BY t1.c3, t1.c1 OFFSET 100 LIMIT 10 FOR UPDATE OF t1; ---Testcase 145: +--Testcase 166: EXPLAIN (VERBOSE, COSTS OFF) SELECT t1.c1, t2.c1 FROM ft1 t1 JOIN ft2 t2 ON (t1.c1 = t2.c1) ORDER BY t1.c3, t1.c1 OFFSET 100 LIMIT 10 FOR UPDATE; ---Testcase 146: +--Testcase 167: SELECT t1.c1, t2.c1 FROM ft1 t1 JOIN ft2 t2 ON (t1.c1 = t2.c1) ORDER BY t1.c3, t1.c1 OFFSET 100 LIMIT 10 FOR UPDATE; -- join two tables with FOR SHARE clause ---Testcase 147: +--Testcase 168: EXPLAIN (VERBOSE, COSTS OFF) SELECT t1.c1, t2.c1 FROM ft1 t1 JOIN ft2 t2 ON (t1.c1 = t2.c1) ORDER BY t1.c3, t1.c1 OFFSET 100 LIMIT 10 FOR SHARE OF t1; ---Testcase 148: +--Testcase 169: SELECT t1.c1, t2.c1 FROM ft1 t1 JOIN ft2 t2 ON (t1.c1 = t2.c1) ORDER BY t1.c3, t1.c1 OFFSET 100 LIMIT 10 FOR SHARE OF t1; ---Testcase 149: +--Testcase 170: EXPLAIN (VERBOSE, COSTS OFF) SELECT t1.c1, t2.c1 FROM ft1 t1 JOIN ft2 t2 ON (t1.c1 = t2.c1) ORDER BY t1.c3, t1.c1 OFFSET 100 LIMIT 10 FOR SHARE; ---Testcase 150: +--Testcase 171: SELECT t1.c1, t2.c1 FROM ft1 t1 JOIN ft2 t2 ON (t1.c1 = t2.c1) ORDER BY t1.c3, t1.c1 OFFSET 100 LIMIT 10 FOR SHARE; -- join in CTE ---Testcase 151: +--Testcase 172: EXPLAIN (VERBOSE, COSTS OFF) WITH t (c1_1, c1_3, c2_1) AS MATERIALIZED (SELECT t1.c1, t1.c3, t2.c1 FROM ft1 t1 JOIN ft2 t2 ON (t1.c1 = t2.c1)) SELECT c1_1, c2_1 FROM t ORDER BY c1_3, c1_1 OFFSET 100 LIMIT 10; ---Testcase 152: +--Testcase 173: WITH t (c1_1, c1_3, c2_1) AS MATERIALIZED (SELECT t1.c1, t1.c3, t2.c1 FROM ft1 t1 JOIN ft2 t2 ON (t1.c1 = t2.c1)) SELECT c1_1, c2_1 FROM t ORDER BY c1_3, c1_1 OFFSET 100 LIMIT 10; -- ctid with whole-row reference ---Testcase 153: +--Testcase 174: EXPLAIN (VERBOSE, COSTS OFF) SELECT t1.ctid, t1, t2, t1.c1 FROM ft1 t1 JOIN ft2 t2 ON (t1.c1 = t2.c1) ORDER BY t1.c3, t1.c1 OFFSET 100 LIMIT 10; -- SEMI JOIN, not pushed down ---Testcase 154: +--Testcase 175: EXPLAIN (VERBOSE, COSTS OFF) SELECT t1.c1 FROM ft1 t1 WHERE EXISTS (SELECT 1 FROM ft2 t2 WHERE t1.c1 = t2.c1) ORDER BY t1.c1 OFFSET 100 LIMIT 10; ---Testcase 155: +--Testcase 176: SELECT t1.c1 FROM ft1 t1 WHERE EXISTS (SELECT 1 FROM ft2 t2 WHERE t1.c1 = t2.c1) ORDER BY t1.c1 OFFSET 100 LIMIT 10; -- ANTI JOIN, not pushed down ---Testcase 156: +--Testcase 177: EXPLAIN (VERBOSE, COSTS OFF) SELECT t1.c1 FROM ft1 t1 WHERE NOT EXISTS (SELECT 1 FROM ft2 t2 WHERE t1.c1 = t2.c2) ORDER BY t1.c1 OFFSET 100 LIMIT 10; ---Testcase 157: +--Testcase 178: SELECT t1.c1 FROM ft1 t1 WHERE NOT EXISTS (SELECT 1 FROM ft2 t2 WHERE t1.c1 = t2.c2) ORDER BY t1.c1 OFFSET 100 LIMIT 10; -- CROSS JOIN can be pushed down ---Testcase 158: +--Testcase 179: EXPLAIN (VERBOSE, COSTS OFF) SELECT t1.c1, t2.c1 FROM ft1 t1 CROSS JOIN ft2 t2 ORDER BY t1.c1, t2.c1 OFFSET 100 LIMIT 10; ---Testcase 159: +--Testcase 180: SELECT t1.c1, t2.c1 FROM ft1 t1 CROSS JOIN ft2 t2 ORDER BY t1.c1, t2.c1 OFFSET 100 LIMIT 10; -- different server, not pushed down. No result expected. ---Testcase 160: +--Testcase 181: EXPLAIN (VERBOSE, COSTS OFF) SELECT t1.c1, t2.c1 FROM ft5 t1 JOIN ft6 t2 ON (t1.c1 = t2.c1) ORDER BY t1.c1, t2.c1 OFFSET 100 LIMIT 10; ---Testcase 161: +--Testcase 182: SELECT t1.c1, t2.c1 FROM ft5 t1 JOIN ft6 t2 ON (t1.c1 = t2.c1) ORDER BY t1.c1, t2.c1 OFFSET 100 LIMIT 10; -- unsafe join conditions (c8 has a UDT), not pushed down. Practically a CROSS -- JOIN since c8 in both tables has same value. ---Testcase 162: +--Testcase 183: EXPLAIN (VERBOSE, COSTS OFF) SELECT t1.c1, t2.c1 FROM ft1 t1 LEFT JOIN ft2 t2 ON (t1.c8 = t2.c8) ORDER BY t1.c1, t2.c1 OFFSET 100 LIMIT 10; ---Testcase 163: +--Testcase 184: SELECT t1.c1, t2.c1 FROM ft1 t1 LEFT JOIN ft2 t2 ON (t1.c8 = t2.c8) ORDER BY t1.c1, t2.c1 OFFSET 100 LIMIT 10; -- unsafe conditions on one side (c8 has a UDT), not pushed down. ---Testcase 164: +--Testcase 185: EXPLAIN (VERBOSE, COSTS OFF) SELECT t1.c1, t2.c1 FROM ft1 t1 LEFT JOIN ft2 t2 ON (t1.c1 = t2.c1) WHERE t1.c8 = 'foo' ORDER BY t1.c3, t1.c1 OFFSET 100 LIMIT 10; ---Testcase 165: +--Testcase 186: SELECT t1.c1, t2.c1 FROM ft1 t1 LEFT JOIN ft2 t2 ON (t1.c1 = t2.c1) WHERE t1.c8 = 'foo' ORDER BY t1.c3, t1.c1 OFFSET 100 LIMIT 10; -- join where unsafe to pushdown condition in WHERE clause has a column not -- in the SELECT clause. In this test unsafe clause needs to have column -- references from both joining sides so that the clause is not pushed down -- into one of the joining sides. ---Testcase 166: +--Testcase 187: EXPLAIN (VERBOSE, COSTS OFF) SELECT t1.c1, t2.c1 FROM ft1 t1 JOIN ft2 t2 ON (t1.c1 = t2.c1) WHERE t1.c8 = t2.c8 ORDER BY t1.c3, t1.c1 OFFSET 100 LIMIT 10; ---Testcase 167: +--Testcase 188: SELECT t1.c1, t2.c1 FROM ft1 t1 JOIN ft2 t2 ON (t1.c1 = t2.c1) WHERE t1.c8 = t2.c8 ORDER BY t1.c3, t1.c1 OFFSET 100 LIMIT 10; -- Aggregate after UNION, for testing setrefs ---Testcase 168: +--Testcase 189: EXPLAIN (VERBOSE, COSTS OFF) SELECT t1c1, avg(t1c1 + t2c1) FROM (SELECT t1.c1, t2.c1 FROM ft1 t1 JOIN ft2 t2 ON (t1.c1 = t2.c1) UNION SELECT t1.c1, t2.c1 FROM ft1 t1 JOIN ft2 t2 ON (t1.c1 = t2.c1)) AS t (t1c1, t2c1) GROUP BY t1c1 ORDER BY t1c1 OFFSET 100 LIMIT 10; ---Testcase 169: +--Testcase 190: SELECT t1c1, avg(t1c1 + t2c1) FROM (SELECT t1.c1, t2.c1 FROM ft1 t1 JOIN ft2 t2 ON (t1.c1 = t2.c1) UNION SELECT t1.c1, t2.c1 FROM ft1 t1 JOIN ft2 t2 ON (t1.c1 = t2.c1)) AS t (t1c1, t2c1) GROUP BY t1c1 ORDER BY t1c1 OFFSET 100 LIMIT 10; -- join with lateral reference ---Testcase 170: +--Testcase 191: EXPLAIN (VERBOSE, COSTS OFF) SELECT t1."C 1" FROM "S 1"."T 1" t1, LATERAL (SELECT DISTINCT t2.c1, t3.c1 FROM ft1 t2, ft2 t3 WHERE t2.c1 = t3.c1 AND t2.c2 = t1.c2) q ORDER BY t1."C 1" OFFSET 10 LIMIT 10; ---Testcase 171: +--Testcase 192: SELECT t1."C 1" FROM "S 1"."T 1" t1, LATERAL (SELECT DISTINCT t2.c1, t3.c1 FROM ft1 t2, ft2 t3 WHERE t2.c1 = t3.c1 AND t2.c2 = t1.c2) q ORDER BY t1."C 1" OFFSET 10 LIMIT 10; +-- join with pseudoconstant quals, not pushed down. +EXPLAIN (VERBOSE, COSTS OFF) +SELECT t1.c1, t2.c1 FROM ft1 t1 JOIN ft2 t2 ON (t1.c1 = t2.c1 AND CURRENT_USER = SESSION_USER) ORDER BY t1.c3, t1.c1 OFFSET 100 LIMIT 10; -- non-Var items in targetlist of the nullable rel of a join preventing -- push-down in some cases -- unable to push {ft1, ft2} ---Testcase 172: +--Testcase 193: EXPLAIN (VERBOSE, COSTS OFF) SELECT q.a, ft2.c1 FROM (SELECT 13 FROM ft1 WHERE c1 = 13) q(a) RIGHT JOIN ft2 ON (q.a = ft2.c1) WHERE ft2.c1 BETWEEN 10 AND 15; ---Testcase 173: +--Testcase 194: SELECT q.a, ft2.c1 FROM (SELECT 13 FROM ft1 WHERE c1 = 13) q(a) RIGHT JOIN ft2 ON (q.a = ft2.c1) WHERE ft2.c1 BETWEEN 10 AND 15; -- ok to push {ft1, ft2} but not {ft1, ft2, ft4} ---Testcase 174: +--Testcase 195: EXPLAIN (VERBOSE, COSTS OFF) SELECT ft4.c1, q.* FROM ft4 LEFT JOIN (SELECT 13, ft1.c1, ft2.c1 FROM ft1 RIGHT JOIN ft2 ON (ft1.c1 = ft2.c1) WHERE ft1.c1 = 12) q(a, b, c) ON (ft4.c1 = q.b) WHERE ft4.c1 BETWEEN 10 AND 15; ---Testcase 175: +--Testcase 196: SELECT ft4.c1, q.* FROM ft4 LEFT JOIN (SELECT 13, ft1.c1, ft2.c1 FROM ft1 RIGHT JOIN ft2 ON (ft1.c1 = ft2.c1) WHERE ft1.c1 = 12) q(a, b, c) ON (ft4.c1 = q.b) WHERE ft4.c1 BETWEEN 10 AND 15 ORDER BY ft4.c1; -- join with nullable side with some columns with null values -- influxdb_fdw does not support UPDATE -- UPDATE ft5 SET c3 = null where c1 % 9 = 0; ---Testcase 176: +--Testcase 197: EXPLAIN (VERBOSE, COSTS OFF) SELECT ft5, ft5.c1, ft5.c2, ft5.c3, ft4.c1, ft4.c2 FROM ft5 left join ft4 on ft5.c1 = ft4.c1 WHERE ft4.c1 BETWEEN 10 and 30 ORDER BY ft5.c1, ft4.c1; ---Testcase 177: +--Testcase 198: SELECT ft5, ft5.c1, ft5.c2, ft5.c3, ft4.c1, ft4.c2 FROM ft5 left join ft4 on ft5.c1 = ft4.c1 WHERE ft4.c1 BETWEEN 10 and 30 ORDER BY ft5.c1, ft4.c1; -- multi-way join involving multiple merge joins -- (this case used to have EPQ-related planning problems) ---Testcase 178: +--Testcase 199: CREATE FOREIGN TABLE local_tbl (c1 int NOT NULL, c2 int NOT NULL, c3 text) SERVER influxdb_svr OPTIONS (table 'local_tbl'); ---Testcase 179: +--Testcase 200: INSERT INTO local_tbl SELECT id, id % 10, to_char(id, 'FM0000') FROM generate_series(1, 1000) id; --ANALYZE local_tbl; +--Testcase 201: SET enable_nestloop TO false; +--Testcase 202: SET enable_hashjoin TO false; ---Testcase 180: +--Testcase 203: EXPLAIN (VERBOSE, COSTS OFF) SELECT * FROM ft1, ft2, ft4, ft5, local_tbl WHERE ft1.c1 = ft2.c1 AND ft1.c2 = ft4.c1 AND ft1.c2 = ft5.c1 AND ft1.c2 = local_tbl.c1 AND ft1.c1 < 100 AND ft2.c1 < 100 ORDER BY ft1.c1 FOR UPDATE; ---Testcase 181: +--Testcase 204: SELECT * FROM ft1, ft2, ft4, ft5, local_tbl WHERE ft1.c1 = ft2.c1 AND ft1.c2 = ft4.c1 AND ft1.c2 = ft5.c1 AND ft1.c2 = local_tbl.c1 AND ft1.c1 < 100 AND ft2.c1 < 100 ORDER BY ft1.c1 FOR UPDATE; +--Testcase 205: RESET enable_nestloop; +--Testcase 206: RESET enable_hashjoin; ---Testcase 182: + +-- test that add_paths_with_pathkeys_for_rel() arranges for the epq_path to +-- return columns needed by the parent ForeignScan node +--Testcase 825: +EXPLAIN (VERBOSE, COSTS OFF) +SELECT * FROM local_tbl LEFT JOIN (SELECT ft1.*, COALESCE(ft1.c3 || ft2.c3, 'foobar') FROM ft1 INNER JOIN ft2 ON (ft1.c1 = ft2.c1 AND ft1.c1 < 100)) ss ON (local_tbl.c1 = ss.c1) ORDER BY local_tbl.c1 FOR UPDATE OF local_tbl; + +-- ALTER SERVER loopback OPTIONS (DROP extensions); +-- ALTER SERVER loopback OPTIONS (ADD fdw_startup_cost '10000.0'); +--Testcase 826: +EXPLAIN (VERBOSE, COSTS OFF) +SELECT * FROM local_tbl LEFT JOIN (SELECT ft1.* FROM ft1 INNER JOIN ft2 ON (ft1.c1 = ft2.c1 AND ft1.c1 < 100 AND (ft1.c1 - influxdb_fdw_abs(ft2.c2)) = 0)) ss ON (local_tbl.c3 = ss.c3) ORDER BY local_tbl.c1 FOR UPDATE OF local_tbl; +-- ALTER SERVER loopback OPTIONS (DROP fdw_startup_cost); +-- ALTER SERVER loopback OPTIONS (ADD extensions 'influxdb_fdw'); + +--Testcase 207: DELETE FROM local_tbl; +--Testcase 783: DROP FOREIGN TABLE local_tbl; -- check join pushdown in situations where multiple userids are involved ---Testcase 183: +--Testcase 208: CREATE ROLE regress_view_owner SUPERUSER; ---Testcase 184: +--Testcase 209: CREATE USER MAPPING FOR regress_view_owner SERVER influxdb_svr OPTIONS (:AUTHENTICATION); GRANT SELECT ON ft4 TO regress_view_owner; GRANT SELECT ON ft5 TO regress_view_owner; ---Testcase 185: +--Testcase 210: CREATE VIEW v4 AS SELECT * FROM ft4; ---Testcase 186: +--Testcase 211: CREATE VIEW v5 AS SELECT * FROM ft5; +--Testcase 212: ALTER VIEW v5 OWNER TO regress_view_owner; ---Testcase 187: +--Testcase 213: EXPLAIN (VERBOSE, COSTS OFF) SELECT t1.c1, t2.c2 FROM v4 t1 LEFT JOIN v5 t2 ON (t1.c1 = t2.c1) ORDER BY t1.c1, t2.c1 OFFSET 10 LIMIT 10; -- can't be pushed down, different view owners ---Testcase 188: +--Testcase 214: SELECT t1.c1, t2.c2 FROM v4 t1 LEFT JOIN v5 t2 ON (t1.c1 = t2.c1) ORDER BY t1.c1, t2.c1 OFFSET 10 LIMIT 10; +--Testcase 215: ALTER VIEW v4 OWNER TO regress_view_owner; ---Testcase 189: +--Testcase 216: EXPLAIN (VERBOSE, COSTS OFF) SELECT t1.c1, t2.c2 FROM v4 t1 LEFT JOIN v5 t2 ON (t1.c1 = t2.c1) ORDER BY t1.c1, t2.c1 OFFSET 10 LIMIT 10; -- can be pushed down ---Testcase 190: +--Testcase 217: SELECT t1.c1, t2.c2 FROM v4 t1 LEFT JOIN v5 t2 ON (t1.c1 = t2.c1) ORDER BY t1.c1, t2.c1 OFFSET 10 LIMIT 10; ---Testcase 191: +--Testcase 218: EXPLAIN (VERBOSE, COSTS OFF) SELECT t1.c1, t2.c2 FROM v4 t1 LEFT JOIN ft5 t2 ON (t1.c1 = t2.c1) ORDER BY t1.c1, t2.c1 OFFSET 10 LIMIT 10; -- can't be pushed down, view owner not current user ---Testcase 192: +--Testcase 219: SELECT t1.c1, t2.c2 FROM v4 t1 LEFT JOIN ft5 t2 ON (t1.c1 = t2.c1) ORDER BY t1.c1, t2.c1 OFFSET 10 LIMIT 10; +--Testcase 220: ALTER VIEW v4 OWNER TO CURRENT_USER; ---Testcase 193: +--Testcase 221: EXPLAIN (VERBOSE, COSTS OFF) SELECT t1.c1, t2.c2 FROM v4 t1 LEFT JOIN ft5 t2 ON (t1.c1 = t2.c1) ORDER BY t1.c1, t2.c1 OFFSET 10 LIMIT 10; -- can be pushed down ---Testcase 194: +--Testcase 222: SELECT t1.c1, t2.c2 FROM v4 t1 LEFT JOIN ft5 t2 ON (t1.c1 = t2.c1) ORDER BY t1.c1, t2.c1 OFFSET 10 LIMIT 10; +--Testcase 223: ALTER VIEW v4 OWNER TO regress_view_owner; +-- ==================================================================== +-- Check that userid to use when querying the remote table is correctly +-- propagated into foreign rels present in subqueries under an UNION ALL +-- ==================================================================== +CREATE ROLE regress_view_owner_another; +ALTER VIEW v4 OWNER TO regress_view_owner_another; +GRANT SELECT ON ft4 TO regress_view_owner_another; +-- ALTER FOREIGN TABLE ft4 OPTIONS (ADD use_remote_estimate 'true'); +-- The following should query the remote backing table of ft4 as user +-- regress_view_owner_another, the view owner, though it fails as expected +-- due to the lack of a user mapping for that user. +EXPLAIN (VERBOSE, COSTS OFF) SELECT * FROM v4; +-- Likewise, but with the query under an UNION ALL +EXPLAIN (VERBOSE, COSTS OFF) SELECT * FROM (SELECT * FROM v4 UNION ALL SELECT * FROM v4); +-- Should not get that error once a user mapping is created +CREATE USER MAPPING FOR regress_view_owner_another SERVER influxdb_svr OPTIONS (:AUTHENTICATION); +EXPLAIN (VERBOSE, COSTS OFF) SELECT * FROM v4; +EXPLAIN (VERBOSE, COSTS OFF) SELECT * FROM (SELECT * FROM v4 UNION ALL SELECT * FROM v4); +DROP USER MAPPING FOR regress_view_owner_another SERVER influxdb_svr; +DROP OWNED BY regress_view_owner_another; +DROP ROLE regress_view_owner_another; +-- ALTER FOREIGN TABLE ft4 OPTIONS (SET use_remote_estimate 'false'); + -- cleanup ---Testcase 195: +--Testcase 224: DROP OWNED BY regress_view_owner; ---Testcase 196: +--Testcase 225: DROP ROLE regress_view_owner; @@ -810,238 +961,246 @@ DROP ROLE regress_view_owner; -- =================================================================== -- Simple aggregates ---Testcase 197: +--Testcase 226: explain (verbose, costs off) select count(c6), sum(c1), avg(c1), min(c2), max(c1), stddev(c2), sum(c1) * (random() <= 1)::int as sum2 from ft1 where c2 < 5 group by c2 order by 1, 2; ---Testcase 198: +--Testcase 227: select count(c6), sum(c1), avg(c1), min(c2), max(c1), stddev(c2), sum(c1) * (random() <= 1)::int as sum2 from ft1 where c2 < 5 group by c2 order by 1, 2; ---Testcase 199: +--Testcase 228: explain (verbose, costs off) select count(c6), sum(c1), avg(c1), min(c2), max(c1), stddev(c2), sum(c1) * (random() <= 1)::int as sum2 from ft1 where c2 < 5 group by c2 order by 1, 2 limit 1; ---Testcase 200: +--Testcase 229: select count(c6), sum(c1), avg(c1), min(c2), max(c1), stddev(c2), sum(c1) * (random() <= 1)::int as sum2 from ft1 where c2 < 5 group by c2 order by 1, 2 limit 1; -- Aggregate is not pushed down as aggregation contains random() ---Testcase 201: +--Testcase 230: explain (verbose, costs off) select sum(c1 * (random() <= 1)::int) as sum, avg(c1) from ft1; -- Aggregate over join query ---Testcase 202: +--Testcase 231: explain (verbose, costs off) select count(*), sum(t1.c1), avg(t2.c1) from ft1 t1 inner join ft1 t2 on (t1.c2 = t2.c2) where t1.c2 = 6; ---Testcase 203: +--Testcase 232: select count(*), sum(t1.c1), avg(t2.c1) from ft1 t1 inner join ft1 t2 on (t1.c2 = t2.c2) where t1.c2 = 6; -- Not pushed down due to local conditions present in underneath input rel ---Testcase 204: +--Testcase 233: explain (verbose, costs off) select sum(t1.c1), count(t2.c1) from ft1 t1 inner join ft2 t2 on (t1.c1 = t2.c1) where ((t1.c1 * t2.c1)/(t1.c1 * t2.c1)) * random() <= 1; -- GROUP BY clause having expressions ---Testcase 205: +--Testcase 234: explain (verbose, costs off) select c2/2, sum(c2) * (c2/2) from ft1 group by c2/2 order by c2/2; ---Testcase 206: +--Testcase 235: select c2/2, sum(c2) * (c2/2) from ft1 group by c2/2 order by c2/2; -- Aggregates in subquery are pushed down. ---Testcase 207: +set enable_incremental_sort = off; +--Testcase 236: explain (verbose, costs off) select count(x.a), sum(x.a) from (select c2 a, sum(c1) b from ft1 group by c2, sqrt(c1) order by 1, 2) x; ---Testcase 208: +--Testcase 237: select count(x.a), sum(x.a) from (select c2 a, sum(c1) b from ft1 group by c2, sqrt(c1) order by 1, 2) x; +reset enable_incremental_sort; -- Aggregate is still pushed down by taking unshippable expression out ---Testcase 209: +--Testcase 238: explain (verbose, costs off) select c2 * (random() <= 1)::int as sum1, sum(c1) * c2 as sum2 from ft1 group by c2 order by 1, 2; ---Testcase 210: +--Testcase 239: select c2 * (random() <= 1)::int as sum1, sum(c1) * c2 as sum2 from ft1 group by c2 order by 1, 2; -- Aggregate with unshippable GROUP BY clause are not pushed ---Testcase 211: +--Testcase 240: explain (verbose, costs off) select c2 * (random() <= 1)::int as c2 from ft2 group by c2 * (random() <= 1)::int order by 1; -- GROUP BY clause in various forms, cardinal, alias and constant expression ---Testcase 212: +--Testcase 241: explain (verbose, costs off) select count(c2) w, c2 x, 5 y, 7.0 z from ft1 group by 2, y, 9.0::int order by 2; ---Testcase 213: +--Testcase 242: select count(c2) w, c2 x, 5 y, 7.0 z from ft1 group by 2, y, 9.0::int order by 2; -- GROUP BY clause referring to same column multiple times -- Also, ORDER BY contains an aggregate function ---Testcase 214: +--Testcase 243: explain (verbose, costs off) select c2, c2 from ft1 where c2 > 6 group by 1, 2 order by sum(c1); ---Testcase 215: +--Testcase 244: select c2, c2 from ft1 where c2 > 6 group by 1, 2 order by sum(c1); -- Testing HAVING clause shippability ---Testcase 216: +--Testcase 245: explain (verbose, costs off) select c2, sum(c1) from ft2 group by c2 having avg(c1) < 500 and sum(c1) < 49800 order by c2; ---Testcase 217: +--Testcase 246: select c2, sum(c1) from ft2 group by c2 having avg(c1) < 500 and sum(c1) < 49800 order by c2; -- Unshippable HAVING clause will be evaluated locally, and other qual in HAVING clause is pushed down ---Testcase 218: +--Testcase 247: explain (verbose, costs off) select count(*) from (select time, count(c1) from ft1 group by time, sqrt(c2) having (avg(c1) / avg(c1)) * random() <= 1 and avg(c1) < 500) x; ---Testcase 219: +--Testcase 248: select count(*) from (select time, count(c1) from ft1 group by time, sqrt(c2) having (avg(c1) / avg(c1)) * random() <= 1 and avg(c1) < 500) x; -- Aggregate in HAVING clause is not pushable, and thus aggregation is not pushed down ---Testcase 220: +--Testcase 249: explain (verbose, costs off) select sum(c1) from ft1 group by c2 having avg(c1 * (random() <= 1)::int) > 100 order by 1; -- Remote aggregate in combination with a local Param (for the output -- of an initplan) can be trouble, per bug #15781 ---Testcase 221: +--Testcase 250: explain (verbose, costs off) select exists(select 1 from pg_enum), sum(c1) from ft1; ---Testcase 222: +--Testcase 251: select exists(select 1 from pg_enum), sum(c1) from ft1; ---Testcase 223: +--Testcase 252: explain (verbose, costs off) select exists(select 1 from pg_enum), sum(c1) from ft1 group by 1; ---Testcase 224: +--Testcase 253: select exists(select 1 from pg_enum), sum(c1) from ft1 group by 1; -- Testing ORDER BY, DISTINCT, FILTER, Ordered-sets and VARIADIC within aggregates -- ORDER BY within aggregate, same column used to order ---Testcase 225: +--Testcase 254: explain (verbose, costs off) select array_agg(c1 order by c1) from ft1 where c1 < 100 group by c2 order by 1; ---Testcase 226: +--Testcase 255: select array_agg(c1 order by c1) from ft1 where c1 < 100 group by c2 order by 1; -- ORDER BY within aggregate, different column used to order also using DESC ---Testcase 227: +--Testcase 256: explain (verbose, costs off) select array_agg(time order by c1 desc) from ft2 where c2 = 6 and c1 < 50; ---Testcase 228: +--Testcase 257: select array_agg(time order by c1 desc) from ft2 where c2 = 6 and c1 < 50; -- DISTINCT within aggregate ---Testcase 229: +--Testcase 258: explain (verbose, costs off) select array_agg(distinct (t1.c1)%5) from ft4 t1 full join ft5 t2 on (t1.c1 = t2.c1) where t1.c1 < 20 or (t1.c1 is null and t2.c1 < 5) group by (t2.c1)%3 order by 1; ---Testcase 230: +--Testcase 259: select array_agg(distinct (t1.c1)%5) from ft4 t1 full join ft5 t2 on (t1.c1 = t2.c1) where t1.c1 < 20 or (t1.c1 is null and t2.c1 < 5) group by (t2.c1)%3 order by 1; -- DISTINCT combined with ORDER BY within aggregate ---Testcase 231: +--Testcase 260: explain (verbose, costs off) select array_agg(distinct (t1.c1)%5 order by (t1.c1)%5) from ft4 t1 full join ft5 t2 on (t1.c1 = t2.c1) where t1.c1 < 20 or (t1.c1 is null and t2.c1 < 5) group by (t2.c1)%3 order by 1; ---Testcase 232: +--Testcase 261: select array_agg(distinct (t1.c1)%5 order by (t1.c1)%5) from ft4 t1 full join ft5 t2 on (t1.c1 = t2.c1) where t1.c1 < 20 or (t1.c1 is null and t2.c1 < 5) group by (t2.c1)%3 order by 1; ---Testcase 233: +--Testcase 262: explain (verbose, costs off) select array_agg(distinct (t1.c1)%5 order by (t1.c1)%5 desc nulls last) from ft4 t1 full join ft5 t2 on (t1.c1 = t2.c1) where t1.c1 < 20 or (t1.c1 is null and t2.c1 < 5) group by (t2.c1)%3 order by 1; ---Testcase 234: +--Testcase 263: select array_agg(distinct (t1.c1)%5 order by (t1.c1)%5 desc nulls last) from ft4 t1 full join ft5 t2 on (t1.c1 = t2.c1) where t1.c1 < 20 or (t1.c1 is null and t2.c1 < 5) group by (t2.c1)%3 order by 1; -- FILTER within aggregate ---Testcase 235: +--Testcase 264: explain (verbose, costs off) select sum(c1) filter (where c1 < 100 and c2 > 5) from ft1 group by c2 order by 1 nulls last; ---Testcase 236: +--Testcase 265: select sum(c1) filter (where c1 < 100 and c2 > 5) from ft1 group by c2 order by 1 nulls last; -- DISTINCT, ORDER BY and FILTER within aggregate ---Testcase 237: +--Testcase 266: explain (verbose, costs off) select sum(c1%3), sum(distinct c1%3 order by c1%3) filter (where c1%3 < 2), c2 from ft1 where c2 = 6 group by c2; ---Testcase 238: +--Testcase 267: select sum(c1%3), sum(distinct c1%3 order by c1%3) filter (where c1%3 < 2), c2 from ft1 where c2 = 6 group by c2; -- Outer query is aggregation query ---Testcase 239: +--Testcase 268: explain (verbose, costs off) select distinct (select count(*) filter (where t2.c2 = 6 and t2.c1 < 10) from ft1 t1 where t1.c1 = 6) from ft2 t2 where t2.c2 % 6 = 0 order by 1; ---Testcase 240: +--Testcase 269: select distinct (select count(*) filter (where t2.c2 = 6 and t2.c1 < 10) from ft1 t1 where t1.c1 = 6) from ft2 t2 where t2.c2 % 6 = 0 order by 1; -- Inner query is aggregation query ---Testcase 241: +--Testcase 270: explain (verbose, costs off) select distinct (select count(t1.c1) filter (where t2.c2 = 6 and t2.c1 < 10) from ft1 t1 where t1.c1 = 6) from ft2 t2 where t2.c2 % 6 = 0 order by 1; ---Testcase 242: +--Testcase 271: select distinct (select count(t1.c1) filter (where t2.c2 = 6 and t2.c1 < 10) from ft1 t1 where t1.c1 = 6) from ft2 t2 where t2.c2 % 6 = 0 order by 1; -- Aggregate not pushed down as FILTER condition is not pushable ---Testcase 243: +--Testcase 272: explain (verbose, costs off) select sum(c1) filter (where (c1 / c1) * random() <= 1) from ft1 group by c2 order by 1; ---Testcase 244: +--Testcase 273: explain (verbose, costs off) select sum(c2) filter (where c2 in (select c2 from ft1 where c2 < 5)) from ft1; -- Ordered-sets within aggregate ---Testcase 245: +--Testcase 274: explain (verbose, costs off) select c2, rank('10'::varchar) within group (order by c6), percentile_cont(c2/10::numeric) within group (order by c1) from ft1 where c2 < 10 group by c2 having percentile_cont(c2/10::numeric) within group (order by c1) < 500 order by c2; ---Testcase 246: +--Testcase 275: select c2, rank('10'::varchar) within group (order by c6), percentile_cont(c2/10::numeric) within group (order by c1) from ft1 where c2 < 10 group by c2 having percentile_cont(c2/10::numeric) within group (order by c1) < 500 order by c2; -- Using multiple arguments within aggregates ---Testcase 247: +--Testcase 276: explain (verbose, costs off) select c1, rank(c1, c2) within group (order by c1, c2) from ft1 group by c1, c2 having c1 = 6 order by 1; ---Testcase 248: +--Testcase 277: select c1, rank(c1, c2) within group (order by c1, c2) from ft1 group by c1, c2 having c1 = 6 order by 1; -- User defined function for user defined aggregate, VARIADIC ---Testcase 249: +--Testcase 278: 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)'; ---Testcase 250: +--Testcase 279: create aggregate least_agg(variadic items anyarray) ( stype = anyelement, sfunc = least_accum ); -- Disable hash aggregation for plan stability. +--Testcase 280: set enable_hashagg to false; -- Not pushed down due to user defined aggregate ---Testcase 251: +--Testcase 281: explain (verbose, costs off) select c2, least_agg(c1) from ft1 group by c2 order by c2; -- Add function and aggregate into extension +--Testcase 282: alter extension influxdb_fdw add function least_accum(anyelement, variadic anyarray); +--Testcase 283: alter extension influxdb_fdw add aggregate least_agg(variadic items anyarray); -- Now aggregate will be pushed. Aggregate will display VARIADIC argument. ---Testcase 252: +--Testcase 284: explain (verbose, costs off) select c2, least_agg(c1) from ft1 where c2 < 100 group by c2 order by c2; ---Testcase 253: +--Testcase 285: select c2, least_agg(c1) from ft1 where c2 < 100 group by c2 order by c2; -- Remove function and aggregate from extension +--Testcase 286: alter extension influxdb_fdw drop function least_accum(anyelement, variadic anyarray); +--Testcase 287: alter extension influxdb_fdw drop aggregate least_agg(variadic items anyarray); -- Not pushed down as we have dropped objects from extension. ---Testcase 254: +--Testcase 288: explain (verbose, costs off) select c2, least_agg(c1) from ft1 group by c2 order by c2; -- Cleanup +--Testcase 289: reset enable_hashagg; ---Testcase 255: +--Testcase 290: drop aggregate least_agg(variadic items anyarray); ---Testcase 256: +--Testcase 291: drop function least_accum(anyelement, variadic anyarray); @@ -1050,35 +1209,35 @@ drop function least_accum(anyelement, variadic anyarray); -- operator class. Create those and then add them in extension. Note that -- user defined objects are considered unshippable unless they are part of -- the extension. ---Testcase 257: +--Testcase 292: create operator public.<^ ( leftarg = int4, rightarg = int4, procedure = int4eq ); ---Testcase 258: +--Testcase 293: create operator public.=^ ( leftarg = int4, rightarg = int4, procedure = int4lt ); ---Testcase 259: +--Testcase 294: create operator public.>^ ( leftarg = int4, rightarg = int4, procedure = int4gt ); ---Testcase 260: +--Testcase 295: create operator family my_op_family using btree; ---Testcase 261: +--Testcase 296: create function my_op_cmp(a int, b int) returns int as $$begin return btint4cmp(a, b); end $$ language plpgsql; ---Testcase 262: +--Testcase 297: create operator class my_op_class for type int using btree family my_op_family as operator 1 public.<^, operator 3 public.=^, @@ -1087,102 +1246,129 @@ create operator class my_op_class for type int using btree family my_op_family a -- This will not be pushed as user defined sort operator is not part of the -- extension yet. ---Testcase 263: +--Testcase 298: explain (verbose, costs off) select array_agg(c1 order by c1 using operator(public.<^)) from ft2 where c2 = 6 and c1 < 100 group by c2; +-- This should not be pushed either. +--Testcase 766: +explain (verbose, costs off) +select * from ft2 order by c1 using operator(public.<^); + -- Update local stats on ft2 --ANALYZE ft2; -- Add into extension +--Testcase 299: alter extension influxdb_fdw add operator class my_op_class using btree; +--Testcase 300: alter extension influxdb_fdw add function my_op_cmp(a int, b int); +--Testcase 301: alter extension influxdb_fdw add operator family my_op_family using btree; +--Testcase 302: alter extension influxdb_fdw add operator public.<^(int, int); +--Testcase 303: alter extension influxdb_fdw add operator public.=^(int, int); +--Testcase 304: alter extension influxdb_fdw add operator public.>^(int, int); -- Now this will be pushed as sort operator is part of the extension. ---Testcase 264: +-- alter server loopback options (add fdw_tuple_cost '0.5'); +--Testcase 305: explain (verbose, costs off) select array_agg(c1 order by c1 using operator(public.<^)) from ft2 where c2 = 6 and c1 < 100 group by c2; ---Testcase 265: +--Testcase 306: select array_agg(c1 order by c1 using operator(public.<^)) from ft2 where c2 = 6 and c1 < 100 group by c2; +-- alter server loopback options (drop fdw_tuple_cost); + +-- This should be pushed too. +-- Influx not support user-defined operator +--Testcase 767: +explain (verbose, costs off) +select * from ft2 order by c1 using operator(public.<^); -- Remove from extension +--Testcase 307: alter extension influxdb_fdw drop operator class my_op_class using btree; +--Testcase 308: alter extension influxdb_fdw drop function my_op_cmp(a int, b int); +--Testcase 309: alter extension influxdb_fdw drop operator family my_op_family using btree; +--Testcase 310: alter extension influxdb_fdw drop operator public.<^(int, int); +--Testcase 311: alter extension influxdb_fdw drop operator public.=^(int, int); +--Testcase 312: alter extension influxdb_fdw drop operator public.>^(int, int); -- This will not be pushed as sort operator is now removed from the extension. ---Testcase 266: +--Testcase 313: explain (verbose, costs off) select array_agg(c1 order by c1 using operator(public.<^)) from ft2 where c2 = 6 and c1 < 100 group by c2; -- Cleanup ---Testcase 267: +--Testcase 314: drop operator class my_op_class using btree; ---Testcase 268: +--Testcase 315: drop function my_op_cmp(a int, b int); ---Testcase 269: +--Testcase 316: drop operator family my_op_family using btree; ---Testcase 270: +--Testcase 317: drop operator public.>^(int, int); ---Testcase 271: +--Testcase 318: drop operator public.=^(int, int); ---Testcase 272: +--Testcase 319: drop operator public.<^(int, int); -- Input relation to aggregate push down hook is not safe to pushdown and thus -- the aggregate cannot be pushed down to foreign server. ---Testcase 273: +--Testcase 320: explain (verbose, costs off) select count(t1.c3) from ft2 t1 left join ft2 t2 on (t1.c1 = random() * t2.c2); -- Subquery in FROM clause having aggregate ---Testcase 274: +--Testcase 321: explain (verbose, costs off) select count(*), x.b from ft1, (select c2 a, sum(c1) b from ft1 group by c2) x where ft1.c2 = x.a group by x.b order by 1, 2; ---Testcase 275: +--Testcase 322: select count(*), x.b from ft1, (select c2 a, sum(c1) b from ft1 group by c2) x where ft1.c2 = x.a group by x.b order by 1, 2; -- FULL join with IS NULL check in HAVING ---Testcase 276: +--Testcase 323: explain (verbose, costs off) select avg(t1.c1), sum(t2.c1) from ft4 t1 full join ft5 t2 on (t1.c1 = t2.c1) group by t2.c1 having (avg(t1.c1) is null and sum(t2.c1) < 10) or sum(t2.c1) is null order by 1 nulls last, 2; ---Testcase 277: +--Testcase 324: select avg(t1.c1), sum(t2.c1) from ft4 t1 full join ft5 t2 on (t1.c1 = t2.c1) group by t2.c1 having (avg(t1.c1) is null and sum(t2.c1) < 10) or sum(t2.c1) is null order by 1 nulls last, 2; -- Aggregate over FULL join needing to deparse the joining relations as -- subqueries. ---Testcase 278: +--Testcase 325: explain (verbose, costs off) select count(*), sum(t1.c1), avg(t2.c1) from (select c1 from ft4 where c1 between 50 and 60) t1 full join (select c1 from ft5 where c1 between 50 and 60) t2 on (t1.c1 = t2.c1); ---Testcase 279: +--Testcase 326: select count(*), sum(t1.c1), avg(t2.c1) from (select c1 from ft4 where c1 between 50 and 60) t1 full join (select c1 from ft5 where c1 between 50 and 60) t2 on (t1.c1 = t2.c1); -- ORDER BY expression is part of the target list but not pushed down to -- foreign server. ---Testcase 280: +--Testcase 327: explain (verbose, costs off) select sum(c2) * (random() <= 1)::int as sum from ft1 order by 1; ---Testcase 281: +--Testcase 328: select sum(c2) * (random() <= 1)::int as sum from ft1 order by 1; -- LATERAL join, with parameterization +--Testcase 329: set enable_hashagg to false; ---Testcase 282: +--Testcase 330: explain (verbose, costs off) select c2, sum from "S 1"."T 1" t1, lateral (select sum(t2.c1 + t1."C 1") sum from ft2 t2 group by t2.c1) qry where t1.c2 * 2 = qry.sum and t1.c2 < 3 and t1."C 1" < 100 order by 1; ---Testcase 283: +--Testcase 331: select c2, sum from "S 1"."T 1" t1, lateral (select sum(t2.c1 + t1."C 1") sum from ft2 t2 group by t2.c1) qry where t1.c2 * 2 = qry.sum and t1.c2 < 3 and t1."C 1" < 100 order by 1; +--Testcase 332: reset enable_hashagg; -- bug #15613: bad plan for foreign table scan with lateral reference ---Testcase 284: +--Testcase 333: EXPLAIN (VERBOSE, COSTS OFF) SELECT ref_0.c2, subq_1.* FROM @@ -1196,7 +1382,7 @@ FROM WHERE ref_0."C 1" < 10 AND subq_1.c3 = '00001' ORDER BY ref_0."C 1"; ---Testcase 285: +--Testcase 334: SELECT ref_0.c2, subq_1.* FROM "S 1"."T 1" AS ref_0, @@ -1210,58 +1396,58 @@ WHERE ref_0."C 1" < 10 AND subq_1.c3 = '00001' ORDER BY ref_0."C 1"; -- Check with placeHolderVars ---Testcase 286: +--Testcase 335: explain (verbose, costs off) select sum(q.a), count(q.b) from ft4 left join (select 13, avg(ft1.c1), sum(ft2.c1) from ft1 right join ft2 on (ft1.c1 = ft2.c1)) q(a, b, c) on (ft4.c1 <= q.b); ---Testcase 287: +--Testcase 336: select sum(q.a), count(q.b) from ft4 left join (select 13, avg(ft1.c1), sum(ft2.c1) from ft1 right join ft2 on (ft1.c1 = ft2.c1)) q(a, b, c) on (ft4.c1 <= q.b); -- Not supported cases -- Grouping sets ---Testcase 288: +--Testcase 337: explain (verbose, costs off) select c2, sum(c1) from ft1 where c2 < 3 group by rollup(c2) order by 1 nulls last; ---Testcase 289: +--Testcase 338: select c2, sum(c1) from ft1 where c2 < 3 group by rollup(c2) order by 1 nulls last; ---Testcase 290: +--Testcase 339: explain (verbose, costs off) select c2, sum(c1) from ft1 where c2 < 3 group by cube(c2) order by 1 nulls last; ---Testcase 291: +--Testcase 340: select c2, sum(c1) from ft1 where c2 < 3 group by cube(c2) order by 1 nulls last; ---Testcase 292: +--Testcase 341: explain (verbose, costs off) select c2, c6, sum(c1) from ft1 where c2 < 3 group by grouping sets(c2, c6) order by 1 nulls last, 2 nulls last; ---Testcase 293: +--Testcase 342: select c2, c6, sum(c1) from ft1 where c2 < 3 group by grouping sets(c2, c6) order by 1 nulls last, 2 nulls last; ---Testcase 294: +--Testcase 343: explain (verbose, costs off) select c2, sum(c1), grouping(c2) from ft1 where c2 < 3 group by c2 order by 1 nulls last; ---Testcase 295: +--Testcase 344: select c2, sum(c1), grouping(c2) from ft1 where c2 < 3 group by c2 order by 1 nulls last; -- DISTINCT itself is not pushed down, whereas underneath aggregate is pushed ---Testcase 296: +--Testcase 345: explain (verbose, costs off) select distinct sum(c1)/1000 s from ft2 where c2 < 6 group by c2 order by 1; ---Testcase 297: +--Testcase 346: select distinct sum(c1)/1000 s from ft2 where c2 < 6 group by c2 order by 1; -- WindowAgg ---Testcase 298: +--Testcase 347: explain (verbose, costs off) select c2, sum(c2), count(c2) over (partition by c2%2) from ft2 where c2 < 10 group by c2 order by 1; ---Testcase 299: +--Testcase 348: select c2, sum(c2), count(c2) over (partition by c2%2) from ft2 where c2 < 10 group by c2 order by 1; ---Testcase 300: +--Testcase 349: explain (verbose, costs off) select c2, array_agg(c2) over (partition by c2%2 order by c2 desc) from ft1 where c2 < 10 group by c2 order by 1; ---Testcase 301: +--Testcase 350: select c2, array_agg(c2) over (partition by c2%2 order by c2 desc) from ft1 where c2 < 10 group by c2 order by 1; ---Testcase 302: +--Testcase 351: explain (verbose, costs off) select c2, array_agg(c2) over (partition by c2%2 order by c2 range between current row and unbounded following) from ft1 where c2 < 10 group by c2 order by 1; ---Testcase 303: +--Testcase 352: select c2, array_agg(c2) over (partition by c2%2 order by c2 range between current row and unbounded following) from ft1 where c2 < 10 group by c2 order by 1; @@ -1269,97 +1455,99 @@ select c2, array_agg(c2) over (partition by c2%2 order by c2 range between curre -- parameterized queries -- =================================================================== -- simple join ---Testcase 304: +--Testcase 353: PREPARE st1(int, int) AS SELECT t1.c3, t2.c3 FROM ft1 t1, ft2 t2 WHERE t1.c1 = $1 AND t2.c1 = $2; ---Testcase 305: +--Testcase 354: EXPLAIN (VERBOSE, COSTS OFF) EXECUTE st1(1, 2); ---Testcase 306: +--Testcase 355: EXECUTE st1(1, 1); ---Testcase 307: +--Testcase 356: EXECUTE st1(101, 101); -- subquery using stable function (can't be sent to remote) ---Testcase 308: +--Testcase 357: PREPARE st2(int) AS SELECT * FROM ft1 t1 WHERE t1.c1 < $2 AND t1.c3 IN (SELECT c3 FROM ft2 t2 WHERE c1 > $1 AND date(time) = '1970-01-17'::date) ORDER BY c1; ---Testcase 309: +--Testcase 358: EXPLAIN (VERBOSE, COSTS OFF) EXECUTE st2(10, 20); ---Testcase 310: +--Testcase 359: EXECUTE st2(10, 20); ---Testcase 311: +--Testcase 360: EXECUTE st2(101, 121); -- subquery using immutable function (can be sent to remote) ---Testcase 312: +--Testcase 361: PREPARE st3(int) AS SELECT * FROM ft1 t1 WHERE t1.c1 < $2 AND t1.c3 IN (SELECT c3 FROM ft2 t2 WHERE c1 > $1 AND date(time) = '1970-01-17'::date) ORDER BY c1; ---Testcase 313: +--Testcase 362: EXPLAIN (VERBOSE, COSTS OFF) EXECUTE st3(10, 20); ---Testcase 314: +--Testcase 363: EXECUTE st3(10, 20); ---Testcase 315: +--Testcase 364: EXECUTE st3(20, 30); -- custom plan should be chosen initially ---Testcase 316: +--Testcase 365: PREPARE st4(int) AS SELECT * FROM ft1 t1 WHERE t1.c1 = $1; ---Testcase 317: +--Testcase 366: EXPLAIN (VERBOSE, COSTS OFF) EXECUTE st4(1); ---Testcase 318: +--Testcase 367: EXPLAIN (VERBOSE, COSTS OFF) EXECUTE st4(1); ---Testcase 319: +--Testcase 368: EXPLAIN (VERBOSE, COSTS OFF) EXECUTE st4(1); ---Testcase 320: +--Testcase 369: EXPLAIN (VERBOSE, COSTS OFF) EXECUTE st4(1); ---Testcase 321: +--Testcase 370: EXPLAIN (VERBOSE, COSTS OFF) EXECUTE st4(1); -- once we try it enough times, should switch to generic plan ---Testcase 322: +--Testcase 371: EXPLAIN (VERBOSE, COSTS OFF) EXECUTE st4(1); -- value of $1 should not be sent to remote ---Testcase 323: +--Testcase 372: PREPARE st5(text,int) AS SELECT * FROM ft1 t1 WHERE c8 = $1 and c1 = $2; ---Testcase 324: +--Testcase 373: EXPLAIN (VERBOSE, COSTS OFF) EXECUTE st5('foo', 1); ---Testcase 325: +--Testcase 374: EXPLAIN (VERBOSE, COSTS OFF) EXECUTE st5('foo', 1); ---Testcase 326: +--Testcase 375: EXPLAIN (VERBOSE, COSTS OFF) EXECUTE st5('foo', 1); ---Testcase 327: +--Testcase 376: EXPLAIN (VERBOSE, COSTS OFF) EXECUTE st5('foo', 1); ---Testcase 328: +--Testcase 377: EXPLAIN (VERBOSE, COSTS OFF) EXECUTE st5('foo', 1); ---Testcase 329: +--Testcase 378: EXPLAIN (VERBOSE, COSTS OFF) EXECUTE st5('foo', 1); ---Testcase 330: +--Testcase 379: EXECUTE st5('foo', 1); -- altering FDW options requires replanning ---Testcase 331: +--Testcase 380: PREPARE st6 AS SELECT * FROM ft1 t1 WHERE t1.c1 = t1.c2; ---Testcase 332: +--Testcase 381: EXPLAIN (VERBOSE, COSTS OFF) EXECUTE st6; ---Testcase 333: +--Testcase 382: PREPARE st7 AS INSERT INTO ft1 (c1,c2,c3) VALUES (1001,101,'foo'); ---Testcase 334: +--Testcase 383: EXPLAIN (VERBOSE, COSTS OFF) EXECUTE st7; ---Testcase 335: +--Testcase 384: INSERT INTO "S 1"."T 0" SELECT * FROM "S 1"."T 1"; +--Testcase 385: ALTER FOREIGN TABLE ft1 OPTIONS (SET table 'T0'); ---Testcase 336: +--Testcase 386: EXPLAIN (VERBOSE, COSTS OFF) EXECUTE st6; ---Testcase 337: +--Testcase 387: EXECUTE st6; ---Testcase 338: +--Testcase 388: EXPLAIN (VERBOSE, COSTS OFF) EXECUTE st7; ---Testcase 339: +--Testcase 389: DELETE FROM "S 1"."T 0"; +--Testcase 390: ALTER FOREIGN TABLE ft1 OPTIONS (SET table 'T1'); ---Testcase 340: +--Testcase 391: PREPARE st8 AS SELECT count(c3) FROM ft1 t1 WHERE t1.c1 === t1.c2; ---Testcase 341: +--Testcase 392: EXPLAIN (VERBOSE, COSTS OFF) EXECUTE st8; -- Skip, influxdb_fdw does not support extensions -- ALTER SERVER loopback OPTIONS (DROP extensions); ---Testcase 342: +--Testcase 393: EXPLAIN (VERBOSE, COSTS OFF) EXECUTE st8; ---Testcase 343: +--Testcase 394: EXECUTE st8; -- ALTER SERVER loopback OPTIONS (ADD extensions 'influxdb_fdw'); @@ -1374,59 +1562,116 @@ DEALLOCATE st7; DEALLOCATE st8; -- System columns, except ctid and oid, should not be sent to remote ---Testcase 344: +--Testcase 395: EXPLAIN (VERBOSE, COSTS OFF) SELECT * FROM ft1 t1 WHERE t1.tableoid = 'pg_class'::regclass LIMIT 1; ---Testcase 345: +--Testcase 396: SELECT * FROM ft1 t1 WHERE t1.tableoid = 'ft1'::regclass ORDER BY c1 LIMIT 1; ---Testcase 346: +--Testcase 397: EXPLAIN (VERBOSE, COSTS OFF) SELECT tableoid::regclass, * FROM ft1 t1 LIMIT 1; ---Testcase 347: +--Testcase 398: SELECT tableoid::regclass, * FROM ft1 t1 ORDER BY c1 LIMIT 1; ---Testcase 348: +--Testcase 399: EXPLAIN (VERBOSE, COSTS OFF) SELECT * FROM ft1 t1 WHERE t1.ctid = '(0,2)'; ---Testcase 349: +--Testcase 400: SELECT * FROM ft1 t1 WHERE t1.ctid = '(0,2)'; ---Testcase 350: +--Testcase 401: EXPLAIN (VERBOSE, COSTS OFF) SELECT ctid, * FROM ft1 t1 LIMIT 1; ---Testcase 351: +--Testcase 402: SELECT ctid, * FROM ft1 t1 ORDER BY c1 LIMIT 1; -- =================================================================== -- used in PL/pgSQL function -- =================================================================== ---Testcase 352: +--Testcase 403: CREATE OR REPLACE FUNCTION f_test(p_c1 int) RETURNS int AS $$ DECLARE v_c1 int; BEGIN ---Testcase 353: +--Testcase 404: SELECT c1 INTO v_c1 FROM ft1 WHERE c1 = p_c1 LIMIT 1; PERFORM c1 FROM ft1 WHERE c1 = p_c1 AND p_c1 = v_c1 LIMIT 1; RETURN v_c1; END; $$ LANGUAGE plpgsql; ---Testcase 354: +--Testcase 405: SELECT f_test(100); ---Testcase 355: +--Testcase 406: DROP FUNCTION f_test(int); +-- =================================================================== +-- REINDEX +-- =================================================================== +-- remote table is not created here +--Testcase 407: +CREATE FOREIGN TABLE reindex_foreign (c1 int, c2 int) + SERVER influxdb_svr2 OPTIONS (table 'reindex_local'); +REINDEX TABLE reindex_foreign; -- error +REINDEX TABLE CONCURRENTLY reindex_foreign; -- error +--Testcase 408: +DROP FOREIGN TABLE reindex_foreign; +-- partitions and foreign tables +--Testcase 409: +CREATE TABLE reind_fdw_parent (c1 int) PARTITION BY RANGE (c1); +--Testcase 410: +CREATE TABLE reind_fdw_0_10 PARTITION OF reind_fdw_parent + FOR VALUES FROM (0) TO (10); +--Testcase 411: +CREATE FOREIGN TABLE reind_fdw_10_20 PARTITION OF reind_fdw_parent + FOR VALUES FROM (10) TO (20) + SERVER influxdb_svr OPTIONS (table 'reind_local_10_20'); +REINDEX TABLE reind_fdw_parent; -- ok +REINDEX TABLE CONCURRENTLY reind_fdw_parent; -- ok +--Testcase 412: +DROP TABLE reind_fdw_parent; + -- =================================================================== -- conversion error -- =================================================================== +--Testcase 413: ALTER FOREIGN TABLE ft1 ALTER COLUMN c8 TYPE int; ---Testcase 356: -SELECT * FROM ft1 WHERE c1 = 1; -- ERROR ---Testcase 357: -SELECT ft1.c1, ft2.c2, ft1.c8 FROM ft1, ft2 WHERE ft1.c1 = ft2.c1 AND ft1.c1 = 1; -- ERROR ---Testcase 358: -SELECT ft1.c1, ft2.c2, ft1 FROM ft1, ft2 WHERE ft1.c1 = ft2.c1 AND ft1.c1 = 1; -- ERROR ---Testcase 359: +--Testcase 414: +SELECT * FROM ft1 ftx(x1,x2,x3,x4,x6,x7,x8) WHERE x1 = 1; -- ERROR +--Testcase 415: +SELECT ftx.x1, ft2.c2, ftx.x8 FROM ft1 ftx(x1,x2,x3,x4,x6,x7,x8), ft2 + WHERE ftx.x1 = ft2.c1 AND ftx.x1 = 1; -- ERROR +--Testcase 416: +SELECT ftx.x1, ft2.c2, ftx FROM ft1 ftx(x1,x2,x3,x4,x6,x7,x8), ft2 + WHERE ftx.x1 = ft2.c1 AND ftx.x1 = 1; -- ERROR +--Testcase 417: SELECT sum(c2), array_agg(c8) FROM ft1 GROUP BY c8; -- ERROR +-- ANALYZE ft1; -- ERROR +ALTER FOREIGN TABLE ft1 ALTER COLUMN c8 TYPE user_enum; + +-- =================================================================== +-- local type can be different from remote type in some cases, +-- in particular if similarly-named operators do equivalent things +-- =================================================================== +-- Testcase 418: ALTER FOREIGN TABLE ft1 ALTER COLUMN c8 TYPE text; +-- Testcase 768: +EXPLAIN (VERBOSE, COSTS OFF) +SELECT * FROM ft1 WHERE c8 = 'foo' LIMIT 1; +-- Testcase 769: +SELECT * FROM ft1 WHERE c8 = 'foo' LIMIT 1; +-- Testcase 770: +EXPLAIN (VERBOSE, COSTS OFF) +SELECT * FROM ft1 WHERE 'foo' = c8 LIMIT 1; +-- Testcase 771: +SELECT * FROM ft1 WHERE 'foo' = c8 LIMIT 1; +-- we declared c8 to be text locally, but it's still the same type on +-- the remote which will balk if we try to do anything incompatible +-- with that remote type +-- Can not create user define type in InfluxDB. +-- Type c8 of foreign table ft1 and remote table T1 are +-- match. These case below not error with influxdb_fdw. +-- Testcase 772: +SELECT * FROM ft1 WHERE c8 LIKE 'foo' LIMIT 1; -- ERROR +-- Testcase 773: +SELECT * FROM ft1 WHERE c8::text LIKE 'foo' LIMIT 1; -- ERROR; cast not pushed down /* -- influxdb_fdw does not support transactions @@ -1452,34 +1697,34 @@ COMMIT; -- =================================================================== -- test handling of collations -- =================================================================== ---Testcase 360: +--Testcase 419: create foreign table loct3 (f1 text collate "C", f2 text, f3 varchar(10)) server influxdb_svr options (table 'loct3'); ---Testcase 361: +--Testcase 420: create foreign table ft3 (f1 text collate "C", f2 text, f3 varchar(10)) server influxdb_svr options (table 'loct3'); -- can be sent to remote ---Testcase 362: +--Testcase 421: explain (verbose, costs off) select * from ft3 where f1 = 'foo'; ---Testcase 363: +--Testcase 422: explain (verbose, costs off) select * from ft3 where f1 COLLATE "C" = 'foo'; ---Testcase 364: +--Testcase 423: explain (verbose, costs off) select * from ft3 where f2 = 'foo'; ---Testcase 365: +--Testcase 424: explain (verbose, costs off) select * from ft3 where f3 = 'foo'; ---Testcase 366: +--Testcase 425: explain (verbose, costs off) select * from ft3 f, loct3 l where f.f3 = l.f3 and l.f1 = 'foo'; -- can't be sent to remote ---Testcase 367: +--Testcase 426: explain (verbose, costs off) select * from ft3 where f1 COLLATE "POSIX" = 'foo'; ---Testcase 368: +--Testcase 427: explain (verbose, costs off) select * from ft3 where f1 = 'foo' COLLATE "C"; ---Testcase 369: +--Testcase 428: explain (verbose, costs off) select * from ft3 where f2 COLLATE "C" = 'foo'; ---Testcase 370: +--Testcase 429: explain (verbose, costs off) select * from ft3 where f2 = 'foo' COLLATE "C"; ---Testcase 371: +--Testcase 430: explain (verbose, costs off) select * from ft3 f, loct3 l where f.f3 = l.f3 COLLATE "POSIX" and l.f1 = 'foo'; @@ -1487,16 +1732,16 @@ explain (verbose, costs off) select * from ft3 f, loct3 l -- =================================================================== -- test writable foreign table stuff -- =================================================================== ---Testcase 372: +--Testcase 431: EXPLAIN (verbose, costs off) INSERT INTO ft2 (c1,c2,c3) SELECT c1+1000,c2+100, c3 || c3 FROM ft2 ORDER BY c1 LIMIT 20; ---Testcase 373: +--Testcase 432: INSERT INTO ft2 (c1,c2,c3) SELECT c1+1000,c2+100, c3 || c3 FROM ft2 ORDER BY c1 LIMIT 20; ---Testcase 374: +--Testcase 433: INSERT INTO ft2 (c1,c2,c3) VALUES (1101,201,'aaa'), (1102,202,'bbb'), (1103,203,'ccc'); ---Testcase 375: +--Testcase 434: SELECT c1, c2, c3, c6, c7, c8 FROM ft2 WHERE c2 > 200; ---Testcase 376: +--Testcase 435: INSERT INTO ft2 (c1,c2,c3) VALUES (1104,204,'ddd'), (1105,205,'eee'); --EXPLAIN (verbose, costs off) --UPDATE ft2 SET c2 = c2 + 300, c3 = c3 || '_update3' WHERE c1 % 10 = 3; -- can be pushed down @@ -1509,44 +1754,44 @@ INSERT INTO ft2 (c1,c2,c3) VALUES (1104,204,'ddd'), (1105,205,'eee'); -- FROM ft1 WHERE ft1.c1 = ft2.c2 AND ft1.c1 % 10 = 9; -- can be pushed down --UPDATE ft2 SET c2 = ft2.c2 + 500, c3 = ft2.c3 || '_update9', c7 = DEFAULT -- FROM ft1 WHERE ft1.c1 = ft2.c2 AND ft1.c1 % 10 = 9; ---Testcase 377: +--Testcase 436: EXPLAIN (verbose, costs off) DELETE FROM ft2 WHERE c1 % 10 = 5; -- can be pushed down ---Testcase 378: +--Testcase 437: SELECT c1 FROM ft2 WHERE c1 % 10 = 5 ORDER BY c1; ---Testcase 379: +--Testcase 438: DELETE FROM ft2 WHERE c1 % 10 = 5; ---Testcase 380: +--Testcase 439: SELECT c1 FROM ft2 WHERE c1 % 10 = 5; ---Testcase 381: +--Testcase 440: EXPLAIN (verbose, costs off) DELETE FROM ft2 USING ft1 WHERE ft1.c1 = ft2.c2 AND ft1.c1 % 10 = 2; ---Testcase 382: +--Testcase 441: DELETE FROM ft2 USING ft1 WHERE ft1.c1 = ft2.c2 AND ft1.c1 % 10 = 2; ---Testcase 383: +--Testcase 442: SELECT c1,c2,c3 FROM ft2 ORDER BY c1; ---Testcase 384: +--Testcase 443: EXPLAIN (verbose, costs off) INSERT INTO ft2 (c1,c2,c3) VALUES (1200,999,'foo'); ---Testcase 385: +--Testcase 444: INSERT INTO ft2 (c1,c2,c3) VALUES (1200,999,'foo'); ---Testcase 386: +--Testcase 445: SELECT c1 FROM ft2 WHERE c1 = 1200 AND c2 = 999; --EXPLAIN (verbose, costs off) --UPDATE ft2 SET c3 = 'bar' WHERE c1 = 1200 RETURNING tableoid::regclass; -- can be pushed down --UPDATE ft2 SET c3 = 'bar' WHERE c1 = 1200 RETURNING tableoid::regclass; ---Testcase 387: +--Testcase 446: EXPLAIN (verbose, costs off) DELETE FROM ft2 WHERE c1 = 1200; ---Testcase 388: +--Testcase 447: SELECT c1 FROM ft2 WHERE c1 = 1200; ---Testcase 389: +--Testcase 448: DELETE FROM ft2 WHERE c1 = 1200; ---Testcase 390: +--Testcase 449: SELECT c1 FROM ft2 WHERE c1 = 1200; -- Test UPDATE/DELETE with RETURNING on a three-table join ---Testcase 391: +--Testcase 450: INSERT INTO ft2 (c1,c2,c3) SELECT id, id - 1200, to_char(id, 'FM00000') FROM generate_series(1201, 1300) id; --EXPLAIN (verbose, costs off) @@ -1558,24 +1803,24 @@ INSERT INTO ft2 (c1,c2,c3) -- FROM ft4 INNER JOIN ft5 ON (ft4.c1 = ft5.c1) -- WHERE ft2.c1 > 1200 AND ft2.c2 = ft4.c1 -- RETURNING ft2, ft2.*, ft4, ft4.*; ---Testcase 392: +--Testcase 451: EXPLAIN (verbose, costs off) DELETE FROM ft2 USING ft4 LEFT JOIN ft5 ON (ft4.c1 = ft5.c1) WHERE ft2.c1 > 1200 AND ft2.c1 % 10 = 0 AND ft2.c2 = ft4.c1; -- can be pushed down ---Testcase 393: +--Testcase 452: SELECT 100 FROM ft2, ft4 LEFT JOIN ft5 ON (ft4.c1 = ft5.c1) WHERE ft2.c1 > 1200 AND ft2.c1 % 10 = 0 AND ft2.c2 = ft4.c1; ---Testcase 394: +--Testcase 453: DELETE FROM ft2 USING ft4 LEFT JOIN ft5 ON (ft4.c1 = ft5.c1) WHERE ft2.c1 > 1200 AND ft2.c1 % 10 = 0 AND ft2.c2 = ft4.c1; ---Testcase 395: +--Testcase 454: SELECT 100 FROM ft2, ft4 LEFT JOIN ft5 ON (ft4.c1 = ft5.c1) WHERE ft2.c1 > 1200 AND ft2.c1 % 10 = 0 AND ft2.c2 = ft4.c1; ---Testcase 396: +--Testcase 455: DELETE FROM ft2 WHERE ft2.c1 > 1200; -- Test UPDATE with a MULTIEXPR sub-select @@ -1598,9 +1843,17 @@ DELETE FROM ft2 WHERE ft2.c1 > 1200; -- WHERE targ--et.c1 = src.c1 --) WHERE c1 > 1100; +-- Test UPDATE involving a join that can be pushed down, +-- but a SET clause that can't be +-- EXPLAIN (VERBOSE, COSTS OFF) +-- UPDATE ft2 d SET c2 = CASE WHEN random() >= 0 THEN d.c2 ELSE 0 END +-- FROM ft2 AS t WHERE d.c1 = t.c1 AND d.c1 > 1000; +-- UPDATE ft2 d SET c2 = CASE WHEN random() >= 0 THEN d.c2 ELSE 0 END +-- FROM ft2 AS t WHERE d.c1 = t.c1 AND d.c1 > 1000; + -- Test UPDATE/DELETE with WHERE or JOIN/ON conditions containing -- user-defined operators/functions ---Testcase 397: +--Testcase 456: INSERT INTO ft2 (c1,c2,c3) SELECT id, id % 10, to_char(id, 'FM00000') FROM generate_series(2001, 2010) id; --EXPLAIN (verbose, costs off) @@ -1615,58 +1868,59 @@ INSERT INTO ft2 (c1,c2,c3) -- FROM ft4 INNER JOIN ft5 ON (ft4.c1 = ft5.c1) -- WHERE ft2.c1 > 2000 AND ft2.c2 === ft4.c1 -- RETURNING ft2.*, ft4.*, ft5.*; ---Testcase 398: +--Testcase 457: EXPLAIN (verbose, costs off) DELETE FROM ft2 USING ft4 INNER JOIN ft5 ON (ft4.c1 === ft5.c1) WHERE ft2.c1 > 2000 AND ft2.c2 = ft4.c1; -- can't be pushed down ---Testcase 399: +--Testcase 458: SELECT ft2.c1, ft2.c2, ft2.c3 FROM ft2, ft4 INNER JOIN ft5 ON (ft4.c1 === ft5.c1) WHERE ft2.c1 > 2000 AND ft2.c2 = ft4.c1; ---Testcase 400: +--Testcase 459: DELETE FROM ft2 USING ft4 INNER JOIN ft5 ON (ft4.c1 === ft5.c1) WHERE ft2.c1 > 2000 AND ft2.c2 = ft4.c1; ---Testcase 401: +--Testcase 460: SELECT ft2.c1, ft2.c2, ft2.c3 FROM ft2, ft4 INNER JOIN ft5 ON (ft4.c1 === ft5.c1) WHERE ft2.c1 > 2000 AND ft2.c2 = ft4.c1; ---Testcase 402: +--Testcase 461: DELETE FROM ft2 WHERE ft2.c1 > 2000; -- Test that trigger on remote table works as expected ---Testcase 403: +--Testcase 462: CREATE OR REPLACE FUNCTION "S 1".F_BRTRIG() RETURNS trigger AS $$ BEGIN NEW.c3 = NEW.c3 || '_trig_update'; RETURN NEW; END; $$ LANGUAGE plpgsql; ---Testcase 404: +--Testcase 463: CREATE TRIGGER t1_br_insert BEFORE INSERT OR UPDATE ON "S 1"."T 1" FOR EACH ROW EXECUTE PROCEDURE "S 1".F_BRTRIG(); ---Testcase 405: +--Testcase 464: INSERT INTO ft2 (c1,c2,c3) VALUES (1208, 818, 'fff'); ---Testcase 406: +--Testcase 465: SELECT c1, c2, c3, c6, c7, c8 FROM ft2 WHERE c1 = 1208; ---Testcase 407: +--Testcase 466: INSERT INTO ft2 (c1,c2,c3,c6) VALUES (1218, 818, 'ggg', '(--;'); ---Testcase 408: +--Testcase 467: SELECT c1, c2, c3, c6, c7, c8 FROM ft2 WHERE c1 = 1218; --UPDATE ft2 SET c2 = c2 + 600 WHERE c1 % 10 = 8 AND c1 < 1200 RETURNING *; -- Test errors thrown on remote side during update +--Testcase 468: ALTER TABLE "S 1"."T 1" ADD CONSTRAINT c2positive CHECK (c2 >= 0); -- influxdb_fdw does not support key, ON CONFLICT --INSERT INTO ft1(c1, c2) VALUES(11, 12); -- duplicate key ---Testcase 409: +--Testcase 469: INSERT INTO ft1(c1, c2) VALUES(11, 12) ON CONFLICT DO NOTHING; -- works ---Testcase 410: +--Testcase 470: INSERT INTO ft1(c1, c2) VALUES(11, 12) ON CONFLICT (c1, c2) DO NOTHING; -- unsupported ---Testcase 411: +--Testcase 471: INSERT INTO ft1(c1, c2) VALUES(11, 12) ON CONFLICT (c1, c2) DO UPDATE SET c3 = 'ffg'; -- unsupported --INSERT INTO ft1(c1, c2) VALUES(1111, -2); -- c2positive --UPDATE ft1 SET c2 = -c2 WHERE c1 = 1; -- c2positive @@ -1707,19 +1961,19 @@ select c2, count(*) from "S 1"."T 1" where c2 < 500 group by 1 order by 1; -- Above DMLs add data with c6 as NULL in ft1, so test ORDER BY NULLS LAST and NULLs -- FIRST behavior here. -- ORDER BY DESC NULLS LAST options ---Testcase 412: +--Testcase 472: EXPLAIN (VERBOSE, COSTS OFF) SELECT * FROM ft1 ORDER BY c6 DESC NULLS LAST, c1 OFFSET 795 LIMIT 10; ---Testcase 413: +--Testcase 473: SELECT c1, c2, c3, c6, c7, c8 FROM ft1 ORDER BY c6 DESC NULLS LAST, c1 OFFSET 795 LIMIT 10; -- ORDER BY DESC NULLS FIRST options ---Testcase 414: +--Testcase 474: EXPLAIN (VERBOSE, COSTS OFF) SELECT * FROM ft1 ORDER BY c6 DESC NULLS FIRST, c1 OFFSET 15 LIMIT 10; ---Testcase 415: +--Testcase 475: SELECT c1, c2, c3, c6, c7, c8 FROM ft1 ORDER BY c6 DESC NULLS FIRST, c1 OFFSET 15 LIMIT 10; -- ORDER BY ASC NULLS FIRST options ---Testcase 416: +--Testcase 476: EXPLAIN (VERBOSE, COSTS OFF) SELECT * FROM ft1 ORDER BY c6 ASC NULLS FIRST, c1 OFFSET 15 LIMIT 10; ---Testcase 417: +--Testcase 477: SELECT c1, c2, c3, c6, c7, c8 FROM ft1 ORDER BY c6 ASC NULLS FIRST, c1 OFFSET 15 LIMIT 10; -- =================================================================== @@ -1727,39 +1981,47 @@ SELECT c1, c2, c3, c6, c7, c8 FROM ft1 ORDER BY c6 ASC NULLS FIRST, c1 OFFSET 15 -- =================================================================== -- Consistent check constraints provide consistent results +--Testcase 478: ALTER FOREIGN TABLE ft1 ADD CONSTRAINT ft1_c2positive CHECK (c2 >= 0); ---Testcase 418: +--Testcase 479: EXPLAIN (VERBOSE, COSTS OFF) SELECT count(*) FROM ft1 WHERE c2 < 0; -- InfluxDB return null value because it does not have any record. ---Testcase 419: +--Testcase 480: SELECT count(*) FROM ft1 WHERE c2 < 0; +--Testcase 481: SET constraint_exclusion = 'on'; ---Testcase 420: +--Testcase 482: EXPLAIN (VERBOSE, COSTS OFF) SELECT count(*) FROM ft1 WHERE c2 < 0; ---Testcase 421: +--Testcase 483: SELECT count(*) FROM ft1 WHERE c2 < 0; +--Testcase 484: RESET constraint_exclusion; -- check constraint is enforced on the remote side, not locally -- INSERT INTO ft1(c1, c2) VALUES(1111, -2); -- c2positive -- UPDATE ft1 SET c2 = -c2 WHERE c1 = 1; -- c2positive +--Testcase 485: ALTER FOREIGN TABLE ft1 DROP CONSTRAINT ft1_c2positive; -- But inconsistent check constraints provide inconsistent results +--Testcase 486: ALTER FOREIGN TABLE ft1 ADD CONSTRAINT ft1_c2negative CHECK (c2 < 0); ---Testcase 422: +--Testcase 487: EXPLAIN (VERBOSE, COSTS OFF) SELECT count(*) FROM ft1 WHERE c2 >= 0; ---Testcase 423: +--Testcase 488: SELECT count(*) FROM ft1 WHERE c2 >= 0; +--Testcase 489: SET constraint_exclusion = 'on'; ---Testcase 424: +--Testcase 490: EXPLAIN (VERBOSE, COSTS OFF) SELECT count(*) FROM ft1 WHERE c2 >= 0; ---Testcase 425: +--Testcase 491: SELECT count(*) FROM ft1 WHERE c2 >= 0; +--Testcase 492: RESET constraint_exclusion; -- local check constraint is not actually enforced ---Testcase 426: +--Testcase 493: INSERT INTO ft1(c1, c2) VALUES(1111, 2); -- UPDATE ft1 SET c2 = c2 + 1 WHERE c1 = 1; +--Testcase 494: ALTER FOREIGN TABLE ft1 DROP CONSTRAINT ft1_c2negative; -- influxdb_fdw does not support this feature @@ -1767,34 +2029,34 @@ ALTER FOREIGN TABLE ft1 DROP CONSTRAINT ft1_c2negative; -- test WITH CHECK OPTION constraints -- =================================================================== ---Testcase 427: +--Testcase 495: CREATE FUNCTION row_before_insupd_trigfunc() RETURNS trigger AS $$BEGIN NEW.a := NEW.a + 10; RETURN NEW; END$$ LANGUAGE plpgsql; ---Testcase 428: +--Testcase 496: CREATE FOREIGN TABLE base_tbl (a int, b int) SERVER influxdb_svr OPTIONS (table 'base_tbl'); --ALTER FOREIGN TABLE base_tbl SET (autovacuum_enabled = 'false'); ---Testcase 429: +--Testcase 497: CREATE TRIGGER row_before_insupd_trigger BEFORE INSERT OR UPDATE ON base_tbl FOR EACH ROW EXECUTE PROCEDURE row_before_insupd_trigfunc(); ---Testcase 430: +--Testcase 498: CREATE FOREIGN TABLE foreign_tbl (a int, b int) SERVER influxdb_svr OPTIONS (table 'base_tbl'); ---Testcase 431: +--Testcase 499: CREATE VIEW rw_view AS SELECT * FROM base_tbl WHERE a < b WITH CHECK OPTION; ---Testcase 432: +--Testcase 500: \d+ rw_view ---Testcase 433: +--Testcase 501: EXPLAIN (VERBOSE, COSTS OFF) INSERT INTO rw_view VALUES (0, 5); ---Testcase 434: +--Testcase 502: INSERT INTO rw_view VALUES (0, 5); -- should fail ---Testcase 435: +--Testcase 503: EXPLAIN (VERBOSE, COSTS OFF) INSERT INTO rw_view VALUES (0, 15); ---Testcase 436: +--Testcase 504: INSERT INTO rw_view VALUES (0, 15); -- ok ---Testcase 437: +--Testcase 505: SELECT * FROM foreign_tbl; --EXPLAIN (VERBOSE, COSTS OFF) @@ -1805,47 +2067,65 @@ SELECT * FROM foreign_tbl; --UPDATE rw_view SET b = b + 15; -- ok --SELECT * FROM foreign_tbl; ---Testcase 438: +-- We don't allow batch insert when there are any WCO constraints +ALTER SERVER influxdb_svr OPTIONS (ADD batch_size '10'); +--Testcase 827: +EXPLAIN (VERBOSE, COSTS OFF) +INSERT INTO rw_view VALUES (0, 15), (0, 5); +--Testcase 828: +INSERT INTO rw_view VALUES (0, 15), (0, 5); -- should fail +--Testcase 829: +SELECT * FROM foreign_tbl; +ALTER SERVER influxdb_svr OPTIONS (DROP batch_size); + +--Testcase 506: DELETE FROM foreign_tbl; +--Testcase 784: DROP FOREIGN TABLE foreign_tbl CASCADE; ---Testcase 439: +--Testcase 507: DROP TRIGGER row_before_insupd_trigger ON base_tbl; ---Testcase 440: +--Testcase 508: DROP FOREIGN TABLE base_tbl CASCADE; -- influxdb_fdw does not support partitions -- test WCO for partitions ---Testcase 441: +--Testcase 509: CREATE FOREIGN TABLE child_tbl (a int, b int) SERVER influxdb_svr OPTIONS (table 'child_tbl'); --ALTER FOREIGN TABLE child_tbl SET (autovacuum_enabled = 'false'); ---Testcase 442: +--Testcase 510: CREATE TRIGGER row_before_insupd_trigger BEFORE INSERT OR UPDATE ON child_tbl FOR EACH ROW EXECUTE PROCEDURE row_before_insupd_trigfunc(); ---Testcase 443: +--Testcase 511: CREATE FOREIGN TABLE foreign_tbl (a int, b int) SERVER influxdb_svr OPTIONS (table 'child_tbl'); ---Testcase 444: +--Testcase 512: CREATE TABLE parent_tbl (a int, b int) PARTITION BY RANGE(a); +--Testcase 513: +ALTER TABLE parent_tbl ATTACH PARTITION child_tbl FOR VALUES FROM (0) TO (100); +-- Detach and re-attach once, to stress the concurrent detach case. +--Testcase 774: +ALTER TABLE parent_tbl DETACH PARTITION child_tbl CONCURRENTLY; +--Testcase 775: ALTER TABLE parent_tbl ATTACH PARTITION child_tbl FOR VALUES FROM (0) TO (100); ---Testcase 445: +--Testcase 514: CREATE VIEW rw_view AS SELECT * FROM parent_tbl WHERE a < b WITH CHECK OPTION; ---Testcase 446: +--Testcase 515: \d+ rw_view ---Testcase 447: +--Testcase 516: EXPLAIN (VERBOSE, COSTS OFF) INSERT INTO rw_view VALUES (0, 5); ---Testcase 448: +--Testcase 517: INSERT INTO rw_view VALUES (0, 5); -- should fail ---Testcase 449: +--Testcase 518: EXPLAIN (VERBOSE, COSTS OFF) INSERT INTO rw_view VALUES (0, 15); ---Testcase 450: +--Testcase 519: INSERT INTO rw_view VALUES (0, 15); -- ok ---Testcase 451: +--Testcase 520: SELECT * FROM foreign_tbl; --EXPLAIN (VERBOSE, COSTS OFF) @@ -1856,72 +2136,163 @@ SELECT * FROM foreign_tbl; --UPDATE rw_view SET b = b + 15; -- ok --SELECT * FROM foreign_tbl; ---Testcase 452: +-- We don't allow batch insert when there are any WCO constraints +ALTER SERVER influxdb_svr OPTIONS (ADD batch_size '10'); +--Testcase 830: +EXPLAIN (VERBOSE, COSTS OFF) +INSERT INTO rw_view VALUES (0, 15), (0, 5); +--Testcase 831: +INSERT INTO rw_view VALUES (0, 15), (0, 5); -- should fail +--Testcase 832: +SELECT * FROM foreign_tbl; +ALTER SERVER influxdb_svr OPTIONS (DROP batch_size); + +--Testcase 521: DROP FOREIGN TABLE foreign_tbl CASCADE; ---Testcase 453: +--Testcase 522: DROP TRIGGER row_before_insupd_trigger ON child_tbl; ---Testcase 454: +--Testcase 523: DROP FOREIGN TABLE child_tbl CASCADE; ---Testcase 455: +--Testcase 524: DROP TABLE parent_tbl CASCADE; ---Testcase 456: +--Testcase 525: DROP FUNCTION row_before_insupd_trigfunc; +-- Try a more complex permutation of WCO where there are multiple levels of +-- partitioned tables with columns not all in the same order +CREATE TABLE parent_tbl (a int, b text, c numeric) PARTITION BY RANGE(a); +CREATE TABLE sub_parent (c numeric, a int, b text) PARTITION BY RANGE(a); +ALTER TABLE parent_tbl ATTACH PARTITION sub_parent FOR VALUES FROM (1) TO (10); +CREATE TABLE child_local (b text, c numeric, a int); +CREATE FOREIGN TABLE child_foreign (b text, c numeric, a int) + SERVER influxdb_svr OPTIONS (table 'child_local'); +ALTER TABLE sub_parent ATTACH PARTITION child_foreign FOR VALUES FROM (1) TO (10); +CREATE VIEW rw_view AS SELECT * FROM parent_tbl WHERE a < 5 WITH CHECK OPTION; + +-- Not support partition insert +INSERT INTO parent_tbl (a) VALUES(1),(5); +-- UPDATE is not supported +EXPLAIN (VERBOSE, COSTS OFF) +UPDATE rw_view SET b = 'text', c = 123.456; +-- UPDATE is not supported +UPDATE rw_view SET b = 'text', c = 123.456; +SELECT * FROM parent_tbl ORDER BY a; + +DROP VIEW rw_view; +DROP TABLE child_local; +DROP FOREIGN TABLE child_foreign; +DROP TABLE sub_parent; +DROP TABLE parent_tbl; + -- =================================================================== -- test serial columns (ie, sequence-based defaults) -- =================================================================== ---Testcase 457: +--Testcase 526: create foreign table loc1 (f1 serial, f2 text) server influxdb_svr options(table 'loc1'); --alter foreign table loc1 set (autovacuum_enabled = 'false'); ---Testcase 458: +--Testcase 527: create foreign table rem1 (f1 serial, f2 text) server influxdb_svr options(table 'loc1'); ---Testcase 459: +--Testcase 528: select pg_catalog.setval('rem1_f1_seq', 10, false); ---Testcase 460: +--Testcase 529: insert into loc1(f2) values('hi'); ---Testcase 461: +--Testcase 530: insert into rem1(f2) values('hi remote'); ---Testcase 462: +--Testcase 531: insert into loc1(f2) values('bye'); ---Testcase 463: +--Testcase 532: insert into rem1(f2) values('bye remote'); ---Testcase 464: +--Testcase 533: select * from loc1; ---Testcase 465: +--Testcase 534: select * from rem1; -- =================================================================== -- test generated columns -- =================================================================== ---Testcase 466: -create foreign table gloc1 (a int, b int generated always as (a * 2) stored) +--Testcase 535: +create foreign table gloc1 ( + a int, + b int generated always as (a * 2) stored) server influxdb_svr options(table 'gloc1'); --alter foreign table gloc1 set (autovacuum_enabled = 'false'); ---Testcase 467: +--Testcase 536: create foreign table grem1 ( a int, b int generated always as (a * 2) stored) server influxdb_svr options(table 'gloc1'); ---Testcase 468: +--Testcase 537: +explain (verbose, costs off) +insert into grem1 (a) values (1), (22); +--Testcase 765: insert into grem1 (a) values (1), (22); +--explain (verbose, costs off) --update grem1 set a = 22 where a = 2; ---Testcase 469: +--update grem1 set a = 22 where a = 2; +--Testcase 538: +select * from gloc1; +--Testcase 539: +select * from grem1; +--Testcase 766: +delete from grem1; + +/* +-- InfluxDB FDW does not support partition insert +-- test copy from +copy grem1 from stdin; +1 +2 +\. select * from gloc1; ---Testcase 470: select * from grem1; +delete from grem1; +*/ --- Clean up: +-- test batch insert +--Testcase 767: +alter server influxdb_svr options (add batch_size '10'); +--Testcase 768: +explain (verbose, costs off) +insert into grem1 (a) values (1), (2); +--Testcase 769: +insert into grem1 (a) values (1), (2); +--Testcase 770: +select * from gloc1; +--Testcase 771: +select * from grem1; +--Testcase 772: delete from grem1; +-- batch insert with foreign partitions. +-- This schema uses two partitions, one local and one remote with a modulo +-- to loop across all of them in batches. +create table tab_batch_local (id int, data text); +insert into tab_batch_local select i, 'test'|| i from generate_series(1, 45) i; +create table tab_batch_sharded (id int, data text) partition by hash(id); +create table tab_batch_sharded_p0 partition of tab_batch_sharded + for values with (modulus 2, remainder 0); +create table tab_batch_sharded_p1_remote (id int, data text); +create foreign table tab_batch_sharded_p1 partition of tab_batch_sharded + for values with (modulus 2, remainder 1) + server influxdb_svr options (table 'tab_batch_sharded_p1_remote'); +-- Not support partition insert +insert into tab_batch_sharded select * from tab_batch_local; +select count(*) from tab_batch_sharded; +drop table tab_batch_local; +drop table tab_batch_sharded; +drop table tab_batch_sharded_p1_remote; + +--Testcase 773: +alter server influxdb_svr options (drop batch_size); -- =================================================================== -- test local triggers -- =================================================================== -- Trigger functions "borrowed" from triggers regress test. ---Testcase 471: +--Testcase 540: CREATE FUNCTION trigger_func() RETURNS trigger LANGUAGE plpgsql AS $$ BEGIN RAISE NOTICE 'trigger_func(%) called: action = %, when = %, level = %', @@ -1929,14 +2300,14 @@ BEGIN RETURN NULL; END;$$; ---Testcase 472: -CREATE TRIGGER trig_stmt_before BEFORE DELETE OR INSERT OR UPDATE ON rem1 +--Testcase 541: +CREATE TRIGGER trig_stmt_before BEFORE DELETE OR INSERT OR UPDATE OR TRUNCATE ON rem1 FOR EACH STATEMENT EXECUTE PROCEDURE trigger_func(); ---Testcase 473: -CREATE TRIGGER trig_stmt_after AFTER DELETE OR INSERT OR UPDATE ON rem1 +--Testcase 542: +CREATE TRIGGER trig_stmt_after AFTER DELETE OR INSERT OR UPDATE OR TRUNCATE ON rem1 FOR EACH STATEMENT EXECUTE PROCEDURE trigger_func(); ---Testcase 474: +--Testcase 543: CREATE OR REPLACE FUNCTION trigger_data() RETURNS trigger LANGUAGE plpgsql AS $$ @@ -1977,71 +2348,72 @@ end; $$; -- Test basic functionality ---Testcase 475: +--Testcase 544: CREATE TRIGGER trig_row_before BEFORE INSERT OR UPDATE OR DELETE ON rem1 FOR EACH ROW EXECUTE PROCEDURE trigger_data(23,'skidoo'); ---Testcase 476: +--Testcase 545: CREATE TRIGGER trig_row_after AFTER INSERT OR UPDATE OR DELETE ON rem1 FOR EACH ROW EXECUTE PROCEDURE trigger_data(23,'skidoo'); ---Testcase 477: +--Testcase 546: delete from rem1; ---Testcase 478: +--Testcase 547: insert into rem1 values(1,'insert'); --update rem1 set f2 = 'update' where f1 = 1; --update rem1 set f2 = f2 || f2; +--truncate rem1; -- cleanup ---Testcase 479: +--Testcase 548: DROP TRIGGER trig_row_before ON rem1; ---Testcase 480: +--Testcase 549: DROP TRIGGER trig_row_after ON rem1; ---Testcase 481: +--Testcase 550: DROP TRIGGER trig_stmt_before ON rem1; ---Testcase 482: +--Testcase 551: DROP TRIGGER trig_stmt_after ON rem1; ---Testcase 483: +--Testcase 552: DELETE from rem1; -- Test multiple AFTER ROW triggers on a foreign table ---Testcase 484: +--Testcase 553: CREATE TRIGGER trig_row_after1 AFTER INSERT OR UPDATE OR DELETE ON rem1 FOR EACH ROW EXECUTE PROCEDURE trigger_data(23,'skidoo'); ---Testcase 485: +--Testcase 554: CREATE TRIGGER trig_row_after2 AFTER INSERT OR UPDATE OR DELETE ON rem1 FOR EACH ROW EXECUTE PROCEDURE trigger_data(23,'skidoo'); ---Testcase 486: +--Testcase 555: insert into rem1 values(1,'insert'); --update rem1 set f2 = 'update' where f1 = 1; --update rem1 set f2 = f2 || f2; ---Testcase 487: +--Testcase 556: delete from rem1; -- cleanup ---Testcase 488: +--Testcase 557: DROP TRIGGER trig_row_after1 ON rem1; ---Testcase 489: +--Testcase 558: DROP TRIGGER trig_row_after2 ON rem1; -- Test WHEN conditions ---Testcase 490: +--Testcase 559: CREATE TRIGGER trig_row_before_insupd BEFORE INSERT OR UPDATE ON rem1 FOR EACH ROW WHEN (NEW.f2 like '%update%') EXECUTE PROCEDURE trigger_data(23,'skidoo'); ---Testcase 491: +--Testcase 560: CREATE TRIGGER trig_row_after_insupd AFTER INSERT OR UPDATE ON rem1 FOR EACH ROW @@ -2049,23 +2421,23 @@ WHEN (NEW.f2 like '%update%') EXECUTE PROCEDURE trigger_data(23,'skidoo'); -- Insert or update not matching: nothing happens ---Testcase 492: +--Testcase 561: INSERT INTO rem1 values(1, 'insert'); --UPDATE rem1 set f2 = 'test'; -- Insert or update matching: triggers are fired ---Testcase 493: +--Testcase 562: INSERT INTO rem1 values(2, 'update'); --UPDATE rem1 set f2 = 'update update' where f1 = '2'; ---Testcase 494: +--Testcase 563: CREATE TRIGGER trig_row_before_delete BEFORE DELETE ON rem1 FOR EACH ROW WHEN (OLD.f2 like '%update%') EXECUTE PROCEDURE trigger_data(23,'skidoo'); ---Testcase 495: +--Testcase 564: CREATE TRIGGER trig_row_after_delete AFTER DELETE ON rem1 FOR EACH ROW @@ -2073,23 +2445,23 @@ WHEN (OLD.f2 like '%update%') EXECUTE PROCEDURE trigger_data(23,'skidoo'); -- Trigger is fired for f1=2, not for f1=1 ---Testcase 496: +--Testcase 565: DELETE FROM rem1; -- cleanup ---Testcase 497: +--Testcase 566: DROP TRIGGER trig_row_before_insupd ON rem1; ---Testcase 498: +--Testcase 567: DROP TRIGGER trig_row_after_insupd ON rem1; ---Testcase 499: +--Testcase 568: DROP TRIGGER trig_row_before_delete ON rem1; ---Testcase 500: +--Testcase 569: DROP TRIGGER trig_row_after_delete ON rem1; -- Test various RETURN statements in BEFORE triggers. ---Testcase 501: +--Testcase 570: CREATE FUNCTION trig_row_before_insupdate() RETURNS TRIGGER AS $$ BEGIN NEW.f2 := NEW.f2 || ' triggered !'; @@ -2097,21 +2469,21 @@ CREATE FUNCTION trig_row_before_insupdate() RETURNS TRIGGER AS $$ END $$ language plpgsql; ---Testcase 502: +--Testcase 571: CREATE TRIGGER trig_row_before_insupd BEFORE INSERT OR UPDATE ON rem1 FOR EACH ROW EXECUTE PROCEDURE trig_row_before_insupdate(); -- The new values should have 'triggered' appended ---Testcase 503: +--Testcase 572: INSERT INTO rem1 values(1, 'insert'); ---Testcase 504: +--Testcase 573: SELECT * from loc1; ---Testcase 505: +--Testcase 574: INSERT INTO rem1 values(2, 'insert'); ---Testcase 506: +--Testcase 575: SELECT f2 FROM rem1 WHERE f1 = 2; ---Testcase 507: +--Testcase 576: SELECT * from loc1; --UPDATE rem1 set f2 = ''; --SELECT * from loc1; @@ -2123,350 +2495,386 @@ SELECT * from loc1; --UPDATE rem1 set f1 = 10; --SELECT * from loc1; ---Testcase 508: +--Testcase 577: DELETE FROM rem1; -- Add a second trigger, to check that the changes are propagated correctly -- from trigger to trigger ---Testcase 509: +--Testcase 578: CREATE TRIGGER trig_row_before_insupd2 BEFORE INSERT OR UPDATE ON rem1 FOR EACH ROW EXECUTE PROCEDURE trig_row_before_insupdate(); ---Testcase 510: +--Testcase 579: INSERT INTO rem1 values(1, 'insert'); ---Testcase 511: +--Testcase 580: SELECT * from loc1; ---Testcase 512: +--Testcase 581: INSERT INTO rem1 values(2, 'insert'); ---Testcase 513: +--Testcase 582: SELECT f2 FROM rem1 WHERE f1 = 2; ---Testcase 514: +--Testcase 583: SELECT * from loc1; --UPDATE rem1 set f2 = ''; --SELECT * from loc1; --UPDATE rem1 set f2 = 'skidoo' RETURNING f2; --SELECT * from loc1; ---Testcase 515: +--Testcase 584: DROP TRIGGER trig_row_before_insupd ON rem1; ---Testcase 516: +--Testcase 585: DROP TRIGGER trig_row_before_insupd2 ON rem1; ---Testcase 517: +--Testcase 586: DELETE from rem1; ---Testcase 518: +--Testcase 587: INSERT INTO rem1 VALUES (1, 'test'); -- Test with a trigger returning NULL ---Testcase 519: +--Testcase 588: CREATE FUNCTION trig_null() RETURNS TRIGGER AS $$ BEGIN RETURN NULL; END $$ language plpgsql; ---Testcase 520: +--Testcase 589: CREATE TRIGGER trig_null BEFORE INSERT OR UPDATE OR DELETE ON rem1 FOR EACH ROW EXECUTE PROCEDURE trig_null(); -- Nothing should have changed. ---Testcase 521: +--Testcase 590: INSERT INTO rem1 VALUES (2, 'test2'); ---Testcase 522: +--Testcase 591: SELECT * from loc1; --UPDATE rem1 SET f2 = 'test2'; --SELECT * from loc1; ---Testcase 523: +--Testcase 592: DELETE from rem1; ---Testcase 524: +--Testcase 593: SELECT * from loc1; ---Testcase 525: +--Testcase 594: DROP TRIGGER trig_null ON rem1; ---Testcase 526: +--Testcase 595: DELETE from rem1; -- Test a combination of local and remote triggers ---Testcase 527: +--Testcase 596: CREATE TRIGGER trig_row_before BEFORE INSERT OR UPDATE OR DELETE ON rem1 FOR EACH ROW EXECUTE PROCEDURE trigger_data(23,'skidoo'); ---Testcase 528: +--Testcase 597: CREATE TRIGGER trig_row_after AFTER INSERT OR UPDATE OR DELETE ON rem1 FOR EACH ROW EXECUTE PROCEDURE trigger_data(23,'skidoo'); ---Testcase 529: +--Testcase 598: CREATE TRIGGER trig_local_before BEFORE INSERT OR UPDATE ON loc1 FOR EACH ROW EXECUTE PROCEDURE trig_row_before_insupdate(); ---Testcase 530: +--Testcase 599: INSERT INTO rem1(f2) VALUES ('test'); --UPDATE rem1 SET f2 = 'testo'; -- Test returning a system attribute ---Testcase 531: +--Testcase 600: INSERT INTO rem1(f2) VALUES ('test'); ---Testcase 532: +--Testcase 601: SELECT * FROM rem1 WHERE f2 = 'test'; -- cleanup ---Testcase 533: +--Testcase 602: DROP TRIGGER trig_row_before ON rem1; ---Testcase 534: +--Testcase 603: DROP TRIGGER trig_row_after ON rem1; ---Testcase 535: +--Testcase 604: DROP TRIGGER trig_local_before ON loc1; -- Test direct foreign table modification functionality +--Testcase 774: +EXPLAIN (verbose, costs off) +DELETE FROM rem1; -- can be pushed down +--Testcase 775: +EXPLAIN (verbose, costs off) +DELETE FROM rem1 WHERE false; -- currently can't be pushed down -- Test with statement-level triggers ---Testcase 536: +--Testcase 605: CREATE TRIGGER trig_stmt_before BEFORE DELETE OR INSERT OR UPDATE ON rem1 FOR EACH STATEMENT EXECUTE PROCEDURE trigger_func(); --EXPLAIN (verbose, costs off) --UPDATE rem1 set f2 = ''; -- can be pushed down ---Testcase 537: +--Testcase 606: EXPLAIN (verbose, costs off) DELETE FROM rem1; -- can be pushed down ---Testcase 538: +--Testcase 607: DROP TRIGGER trig_stmt_before ON rem1; ---Testcase 539: +--Testcase 608: CREATE TRIGGER trig_stmt_after AFTER DELETE OR INSERT OR UPDATE ON rem1 FOR EACH STATEMENT EXECUTE PROCEDURE trigger_func(); --EXPLAIN (verbose, costs off) --UPDATE rem1 set f2 = ''; -- can be pushed down ---Testcase 540: +--Testcase 609: EXPLAIN (verbose, costs off) DELETE FROM rem1; -- can be pushed down ---Testcase 541: +--Testcase 610: DROP TRIGGER trig_stmt_after ON rem1; -- Test with row-level ON INSERT triggers ---Testcase 542: +--Testcase 611: CREATE TRIGGER trig_row_before_insert BEFORE INSERT ON rem1 FOR EACH ROW EXECUTE PROCEDURE trigger_data(23,'skidoo'); --EXPLAIN (verbose, costs off) --UPDATE rem1 set f2 = ''; -- can be pushed down ---Testcase 543: +--Testcase 612: EXPLAIN (verbose, costs off) DELETE FROM rem1; -- can be pushed down ---Testcase 544: +--Testcase 613: DROP TRIGGER trig_row_before_insert ON rem1; ---Testcase 545: +--Testcase 614: CREATE TRIGGER trig_row_after_insert AFTER INSERT ON rem1 FOR EACH ROW EXECUTE PROCEDURE trigger_data(23,'skidoo'); --EXPLAIN (verbose, costs off) --UPDATE rem1 set f2 = ''; -- can be pushed down ---Testcase 546: +--Testcase 615: EXPLAIN (verbose, costs off) DELETE FROM rem1; -- can be pushed down ---Testcase 547: +--Testcase 616: DROP TRIGGER trig_row_after_insert ON rem1; -- Test with row-level ON UPDATE triggers ---Testcase 548: +--Testcase 617: CREATE TRIGGER trig_row_before_update BEFORE UPDATE ON rem1 FOR EACH ROW EXECUTE PROCEDURE trigger_data(23,'skidoo'); --EXPLAIN (verbose, costs off) --UPDATE rem1 set f2 = ''; -- can't be pushed down ---Testcase 549: +--Testcase 618: EXPLAIN (verbose, costs off) DELETE FROM rem1; -- can be pushed down ---Testcase 550: +--Testcase 619: DROP TRIGGER trig_row_before_update ON rem1; ---Testcase 551: +--Testcase 620: CREATE TRIGGER trig_row_after_update AFTER UPDATE ON rem1 FOR EACH ROW EXECUTE PROCEDURE trigger_data(23,'skidoo'); --EXPLAIN (verbose, costs off) --UPDATE rem1 set f2 = ''; -- can't be pushed down ---Testcase 552: +--Testcase 621: EXPLAIN (verbose, costs off) DELETE FROM rem1; -- can be pushed down ---Testcase 553: +--Testcase 622: DROP TRIGGER trig_row_after_update ON rem1; -- Test with row-level ON DELETE triggers ---Testcase 554: +--Testcase 623: CREATE TRIGGER trig_row_before_delete BEFORE DELETE ON rem1 FOR EACH ROW EXECUTE PROCEDURE trigger_data(23,'skidoo'); --EXPLAIN (verbose, costs off) --UPDATE rem1 set f2 = ''; -- can be pushed down ---Testcase 555: +--Testcase 624: EXPLAIN (verbose, costs off) DELETE FROM rem1; -- can't be pushed down ---Testcase 556: +--Testcase 625: DROP TRIGGER trig_row_before_delete ON rem1; ---Testcase 557: +--Testcase 626: CREATE TRIGGER trig_row_after_delete AFTER DELETE ON rem1 FOR EACH ROW EXECUTE PROCEDURE trigger_data(23,'skidoo'); --EXPLAIN (verbose, costs off) --UPDATE rem1 set f2 = ''; -- can be pushed down ---Testcase 558: +--Testcase 627: EXPLAIN (verbose, costs off) DELETE FROM rem1; -- can't be pushed down ---Testcase 559: +--Testcase 628: DROP TRIGGER trig_row_after_delete ON rem1; -- =================================================================== -- test inheritance features -- =================================================================== ---Testcase 560: +--Testcase 629: CREATE TABLE a (aa TEXT); --CREATE TABLE loct (aa TEXT, bb TEXT); +--Testcase 630: ALTER TABLE a SET (autovacuum_enabled = 'false'); --ALTER TABLE loct SET (autovacuum_enabled = 'false'); -- Because influxdb_fdw does not support UPDATE, to test locally -- we create local table. ---Testcase 561: +--Testcase 631: CREATE TABLE b (bb TEXT) INHERITS (a); ---Testcase 562: +--Testcase 632: INSERT INTO a(aa) VALUES('aaa'); ---Testcase 563: +--Testcase 633: INSERT INTO a(aa) VALUES('aaaa'); ---Testcase 564: +--Testcase 634: INSERT INTO a(aa) VALUES('aaaaa'); ---Testcase 565: +--Testcase 635: INSERT INTO b(aa) VALUES('bbb'); ---Testcase 566: +--Testcase 636: INSERT INTO b(aa) VALUES('bbbb'); ---Testcase 567: +--Testcase 637: INSERT INTO b(aa) VALUES('bbbbb'); ---Testcase 568: +--Testcase 638: SELECT tableoid::regclass, * FROM a; ---Testcase 569: +--Testcase 639: SELECT tableoid::regclass, * FROM b; ---Testcase 570: +--Testcase 640: SELECT tableoid::regclass, * FROM ONLY a; ---Testcase 571: +--Testcase 641: UPDATE a SET aa = 'zzzzzz' WHERE aa LIKE 'aaaa%'; ---Testcase 572: +--Testcase 642: SELECT tableoid::regclass, * FROM a; ---Testcase 573: +--Testcase 643: SELECT tableoid::regclass, * FROM b; ---Testcase 574: +--Testcase 644: SELECT tableoid::regclass, * FROM ONLY a; ---Testcase 575: +--Testcase 645: UPDATE b SET aa = 'new'; ---Testcase 576: +--Testcase 646: SELECT tableoid::regclass, * FROM a; ---Testcase 577: +--Testcase 647: SELECT tableoid::regclass, * FROM b; ---Testcase 578: +--Testcase 648: SELECT tableoid::regclass, * FROM ONLY a; ---Testcase 579: +--Testcase 649: UPDATE a SET aa = 'newtoo'; ---Testcase 580: +--Testcase 650: SELECT tableoid::regclass, * FROM a; ---Testcase 581: +--Testcase 651: SELECT tableoid::regclass, * FROM b; ---Testcase 582: +--Testcase 652: SELECT tableoid::regclass, * FROM ONLY a; ---Testcase 583: +--Testcase 653: DELETE FROM a; ---Testcase 584: +--Testcase 654: SELECT tableoid::regclass, * FROM a; ---Testcase 585: +--Testcase 655: SELECT tableoid::regclass, * FROM b; ---Testcase 586: +--Testcase 656: SELECT tableoid::regclass, * FROM ONLY a; ---Testcase 587: +--Testcase 657: DROP TABLE a CASCADE; --DROP TABLE loct; -- Check SELECT FOR UPDATE/SHARE with an inherited source table ---Testcase 588: +--Testcase 658: create foreign table loct1 (f1 int, f2 int, f3 int) server influxdb_svr options(table 'loct1'); ---Testcase 589: +--Testcase 659: create foreign table loct2 (f1 int, f2 int, f3 int) server influxdb_svr options(table 'loct2'); --alter table loct1 set (autovacuum_enabled = 'false'); --alter table loct2 set (autovacuum_enabled = 'false'); ---Testcase 590: +--Testcase 660: create foreign table foo (f1 int, f2 int) server influxdb_svr options (table 'foo'); ---Testcase 591: +--Testcase 661: create foreign table foo2 (f3 int) inherits (foo) server influxdb_svr options (table 'loct1'); ---Testcase 592: +--Testcase 662: create foreign table bar (f1 int, f2 int) server influxdb_svr options (table 'bar'); ---Testcase 593: +--Testcase 663: create foreign table bar2 (f3 int) inherits (bar) server influxdb_svr options (table 'loct2'); --alter table foo set (autovacuum_enabled = 'false'); --alter table bar set (autovacuum_enabled = 'false'); ---Testcase 594: +--Testcase 664: insert into foo values(1,1); ---Testcase 595: +--Testcase 665: insert into foo values(3,3); ---Testcase 596: +--Testcase 666: insert into foo2 values(2,2,2); ---Testcase 597: +--Testcase 667: insert into foo2 values(4,4,4); ---Testcase 598: +--Testcase 668: insert into bar values(1,11); ---Testcase 599: +--Testcase 669: insert into bar values(2,22); ---Testcase 600: +--Testcase 670: insert into bar values(6,66); ---Testcase 601: +--Testcase 671: insert into bar2 values(3,33,33); ---Testcase 602: +--Testcase 672: insert into bar2 values(4,44,44); ---Testcase 603: +--Testcase 673: insert into bar2 values(7,77,77); ---Testcase 604: +--Testcase 674: explain (verbose, costs off) select * from bar where f1 in (select f1 from foo); ---Testcase 605: +--Testcase 675: select * from bar where f1 in (select f1 from foo); ---Testcase 606: +--Testcase 676: explain (verbose, costs off) select * from bar where f1 in (select f1 from foo); ---Testcase 607: +--Testcase 677: select * from bar where f1 in (select f1 from foo); +-- Now check SELECT FOR UPDATE/SHARE with an inherited source table, +-- where the parent is itself a foreign table +--Testcase 678: +create foreign table foo2child (f3 int) inherits (foo2) + server influxdb_svr options (table 'loct4'); + +--Testcase 679: +explain (verbose, costs off) +select * from bar where f1 in (select f1 from foo2) for share; +--Testcase 680: +select * from bar where f1 in (select f1 from foo2) for share; + +--Testcase 681: +drop foreign table foo2child; + +-- And with a local child relation of the foreign table parent +--Testcase 682: +create foreign table foo2child (f3 int) inherits (foo2) + server influxdb_svr options (table 'foo2child'); + +--Testcase 683: +explain (verbose, costs off) +select * from bar where f1 in (select f1 from foo2) for share; +--Testcase 684: +select * from bar where f1 in (select f1 from foo2) for share; + +--Testcase 685: +drop foreign table foo2child; + /* -- influxdb_fdw does not support UPDATE -- Check UPDATE with inherited target and an inherited source table @@ -2612,6 +3020,10 @@ select tableoid::regclass, * FROM remp2; delete from itrtest; +-- MERGE ought to fail cleanly +merge into itrtest using (select 1, 'foo') as source on (true) + when matched then do nothing; + create unique index loct1_idx on loct1 (a); -- DO NOTHING without an inference specification is supported @@ -2778,6 +3190,28 @@ copy remp1 from stdin; select tableoid::regclass, * FROM remp1; +delete from ctrtest; + +-- Test copy tuple routing with the batch_size option enabled +alter server loopback options (add batch_size '2'); + +copy ctrtest from stdin; +1 foo +1 bar +2 baz +2 qux +1 test1 +2 test2 +\. + +select tableoid::regclass, * FROM ctrtest; +select tableoid::regclass, * FROM remp1; +select tableoid::regclass, * FROM remp2; + +delete from ctrtest; + +alter server loopback options (drop batch_size); + drop table ctrtest; drop table loct1; drop table loct2; @@ -2927,52 +3361,243 @@ copy rem3 from stdin; 1 foo 2 bar \. -commit; -select * from rem3; -drop foreign table rem3; -drop table loc3; +commit; +select * from rem3; +drop foreign table rem3; +drop table loc3; + +-- Test COPY FROM with the batch_size option enabled +alter server loopback options (add batch_size '2'); + +-- Test basic functionality +copy rem2 from stdin; +1 foo +2 bar +3 baz +\. +select * from rem2; + +delete from rem2; + +-- Test check constraints +alter table loc2 add constraint loc2_f1positive check (f1 >= 0); +alter foreign table rem2 add constraint rem2_f1positive check (f1 >= 0); + +-- check constraint is enforced on the remote side, not locally +copy rem2 from stdin; +1 foo +2 bar +3 baz +\. +copy rem2 from stdin; -- ERROR +-1 xyzzy +\. +select * from rem2; + +alter foreign table rem2 drop constraint rem2_f1positive; +alter table loc2 drop constraint loc2_f1positive; + +delete from rem2; + +-- Test remote triggers +create trigger trig_row_before_insert before insert on loc2 + for each row execute procedure trig_row_before_insupdate(); + +-- The new values are concatenated with ' triggered !' +copy rem2 from stdin; +1 foo +2 bar +3 baz +\. +select * from rem2; + +drop trigger trig_row_before_insert on loc2; + +delete from rem2; + +create trigger trig_null before insert on loc2 + for each row execute procedure trig_null(); + +-- Nothing happens +copy rem2 from stdin; +1 foo +2 bar +3 baz +\. +select * from rem2; + +drop trigger trig_null on loc2; + +delete from rem2; + +-- Check with zero-column foreign table; batch insert will be disabled +alter table loc2 drop column f1; +alter table loc2 drop column f2; +alter table rem2 drop column f1; +alter table rem2 drop column f2; +copy rem2 from stdin; + + + +\. +select * from rem2; + +delete from rem2; + +alter server loopback options (drop batch_size); +*/ + +/* +-- Skip test because influxdb does not support TRUNCATE +-- =================================================================== +-- test for TRUNCATE +-- =================================================================== +CREATE TABLE tru_rtable0 (id int primary key); +CREATE FOREIGN TABLE tru_ftable (id int) + SERVER loopback OPTIONS (table_name 'tru_rtable0'); +INSERT INTO tru_rtable0 (SELECT x FROM generate_series(1,10) x); + +CREATE TABLE tru_ptable (id int) PARTITION BY HASH(id); +CREATE TABLE tru_ptable__p0 PARTITION OF tru_ptable + FOR VALUES WITH (MODULUS 2, REMAINDER 0); +CREATE TABLE tru_rtable1 (id int primary key); +CREATE FOREIGN TABLE tru_ftable__p1 PARTITION OF tru_ptable + FOR VALUES WITH (MODULUS 2, REMAINDER 1) + SERVER loopback OPTIONS (table_name 'tru_rtable1'); +INSERT INTO tru_ptable (SELECT x FROM generate_series(11,20) x); + +CREATE TABLE tru_pk_table(id int primary key); +CREATE TABLE tru_fk_table(fkey int references tru_pk_table(id)); +INSERT INTO tru_pk_table (SELECT x FROM generate_series(1,10) x); +INSERT INTO tru_fk_table (SELECT x % 10 + 1 FROM generate_series(5,25) x); +CREATE FOREIGN TABLE tru_pk_ftable (id int) + SERVER loopback OPTIONS (table_name 'tru_pk_table'); + +CREATE TABLE tru_rtable_parent (id int); +CREATE TABLE tru_rtable_child (id int); +CREATE FOREIGN TABLE tru_ftable_parent (id int) + SERVER loopback OPTIONS (table_name 'tru_rtable_parent'); +CREATE FOREIGN TABLE tru_ftable_child () INHERITS (tru_ftable_parent) + SERVER loopback OPTIONS (table_name 'tru_rtable_child'); +INSERT INTO tru_rtable_parent (SELECT x FROM generate_series(1,8) x); +INSERT INTO tru_rtable_child (SELECT x FROM generate_series(10, 18) x); + +-- normal truncate +SELECT sum(id) FROM tru_ftable; -- 55 +TRUNCATE tru_ftable; +SELECT count(*) FROM tru_rtable0; -- 0 +SELECT count(*) FROM tru_ftable; -- 0 + +-- 'truncatable' option +ALTER SERVER loopback OPTIONS (ADD truncatable 'false'); +TRUNCATE tru_ftable; -- error +ALTER FOREIGN TABLE tru_ftable OPTIONS (ADD truncatable 'true'); +TRUNCATE tru_ftable; -- accepted +ALTER FOREIGN TABLE tru_ftable OPTIONS (SET truncatable 'false'); +TRUNCATE tru_ftable; -- error +ALTER SERVER loopback OPTIONS (DROP truncatable); +ALTER FOREIGN TABLE tru_ftable OPTIONS (SET truncatable 'false'); +TRUNCATE tru_ftable; -- error +ALTER FOREIGN TABLE tru_ftable OPTIONS (SET truncatable 'true'); +TRUNCATE tru_ftable; -- accepted + +-- partitioned table with both local and foreign tables as partitions +SELECT sum(id) FROM tru_ptable; -- 155 +TRUNCATE tru_ptable; +SELECT count(*) FROM tru_ptable; -- 0 +SELECT count(*) FROM tru_ptable__p0; -- 0 +SELECT count(*) FROM tru_ftable__p1; -- 0 +SELECT count(*) FROM tru_rtable1; -- 0 + +-- 'CASCADE' option +SELECT sum(id) FROM tru_pk_ftable; -- 55 +TRUNCATE tru_pk_ftable; -- failed by FK reference +TRUNCATE tru_pk_ftable CASCADE; +SELECT count(*) FROM tru_pk_ftable; -- 0 +SELECT count(*) FROM tru_fk_table; -- also truncated,0 + +-- truncate two tables at a command +INSERT INTO tru_ftable (SELECT x FROM generate_series(1,8) x); +INSERT INTO tru_pk_ftable (SELECT x FROM generate_series(3,10) x); +SELECT count(*) from tru_ftable; -- 8 +SELECT count(*) from tru_pk_ftable; -- 8 +TRUNCATE tru_ftable, tru_pk_ftable CASCADE; +SELECT count(*) from tru_ftable; -- 0 +SELECT count(*) from tru_pk_ftable; -- 0 + +-- truncate with ONLY clause +-- Since ONLY is specified, the table tru_ftable_child that inherits +-- tru_ftable_parent locally is not truncated. +TRUNCATE ONLY tru_ftable_parent; +SELECT sum(id) FROM tru_ftable_parent; -- 126 +TRUNCATE tru_ftable_parent; +SELECT count(*) FROM tru_ftable_parent; -- 0 + +-- in case when remote table has inherited children +CREATE TABLE tru_rtable0_child () INHERITS (tru_rtable0); +INSERT INTO tru_rtable0 (SELECT x FROM generate_series(5,9) x); +INSERT INTO tru_rtable0_child (SELECT x FROM generate_series(10,14) x); +SELECT sum(id) FROM tru_ftable; -- 95 + +-- Both parent and child tables in the foreign server are truncated +-- even though ONLY is specified because ONLY has no effect +-- when truncating a foreign table. +TRUNCATE ONLY tru_ftable; +SELECT count(*) FROM tru_ftable; -- 0 + +INSERT INTO tru_rtable0 (SELECT x FROM generate_series(21,25) x); +INSERT INTO tru_rtable0_child (SELECT x FROM generate_series(26,30) x); +SELECT sum(id) FROM tru_ftable; -- 255 +TRUNCATE tru_ftable; -- truncate both of parent and child +SELECT count(*) FROM tru_ftable; -- 0 + +-- cleanup +DROP FOREIGN TABLE tru_ftable_parent, tru_ftable_child, tru_pk_ftable,tru_ftable__p1,tru_ftable; +DROP TABLE tru_rtable0, tru_rtable1, tru_ptable, tru_ptable__p0, tru_pk_table, tru_fk_table, +tru_rtable_parent,tru_rtable_child, tru_rtable0_child; */ + -- =================================================================== -- test IMPORT FOREIGN SCHEMA -- =================================================================== ---Testcase 608: +--Testcase 686: CREATE SCHEMA import_influx1; IMPORT FOREIGN SCHEMA public FROM SERVER influxdb_svr INTO import_influx1; ---Testcase 609: +--Testcase 687: \det+ import_influx1.* ---Testcase 610: +--Testcase 688: \d import_influx1.* -- Options ---Testcase 611: +--Testcase 689: CREATE SCHEMA import_influx2; IMPORT FOREIGN SCHEMA public FROM SERVER influxdb_svr INTO import_influx2 OPTIONS (import_default 'true'); ---Testcase 612: +--Testcase 690: \det+ import_influx2.* ---Testcase 613: +--Testcase 691: \d import_influx2.* ---Testcase 614: +--Testcase 692: CREATE SCHEMA import_influx3; IMPORT FOREIGN SCHEMA public FROM SERVER influxdb_svr INTO import_influx3 OPTIONS (import_collate 'false', import_not_null 'false'); ---Testcase 615: +--Testcase 693: \det+ import_influx3.* ---Testcase 616: +--Testcase 694: \d import_influx3.* -- Check LIMIT TO and EXCEPT ---Testcase 617: +--Testcase 695: CREATE SCHEMA import_influx4; IMPORT FOREIGN SCHEMA public LIMIT TO ("T1", loct, nonesuch) FROM SERVER influxdb_svr INTO import_influx4; ---Testcase 618: +--Testcase 696: \det+ import_influx4.* IMPORT FOREIGN SCHEMA public EXCEPT ("T1", loct, nonesuch) FROM SERVER influxdb_svr INTO import_influx4; ---Testcase 619: +--Testcase 697: \det+ import_influx4.* -- Assorted error cases @@ -3184,27 +3809,23 @@ $d$; CREATE USER MAPPING FOR public SERVER loopback_nopw; CREATE USER MAPPING FOR CURRENT_USER SERVER loopback_nopw; -CREATE FOREIGN TABLE ft1_nopw ( +CREATE FOREIGN TABLE pg_temp.ft1_nopw ( c1 int NOT NULL, c2 int NOT NULL, c3 text, c4 timestamptz, - c5 timestamp, + c5 timestamptz, c6 varchar(10), c7 char(10) default 'ft1', c8 user_enum ) SERVER loopback_nopw OPTIONS (schema_name 'public', table_name 'ft1'); -SELECT * FROM ft1_nopw LIMIT 1; +SELECT 1 FROM ft1_nopw LIMIT 1; -- If we add a password to the connstr it'll fail, because we don't allow passwords -- in connstrs only in user mappings. -DO $d$ - BEGIN - EXECUTE $$ALTER SERVER loopback_nopw OPTIONS (ADD password 'dummypw')$$; - END; -$d$; +ALTER SERVER loopback_nopw OPTIONS (ADD password 'dummypw'); -- If we add a password for our user mapping instead, we should get a different -- error because the password wasn't actually *used* when we run with trust auth. @@ -3213,13 +3834,13 @@ $d$; ALTER USER MAPPING FOR CURRENT_USER SERVER loopback_nopw OPTIONS (ADD password 'dummypw'); -SELECT * FROM ft1_nopw LIMIT 1; +SELECT 1 FROM ft1_nopw LIMIT 1; -- Unpriv user cannot make the mapping passwordless ALTER USER MAPPING FOR CURRENT_USER SERVER loopback_nopw OPTIONS (ADD password_required 'false'); -SELECT * FROM ft1_nopw LIMIT 1; +SELECT 1 FROM ft1_nopw LIMIT 1; RESET ROLE; @@ -3229,7 +3850,7 @@ ALTER USER MAPPING FOR regress_nosuper SERVER loopback_nopw OPTIONS (ADD passwor SET ROLE regress_nosuper; -- Should finally work now -SELECT * FROM ft1_nopw LIMIT 1; +SELECT 1 FROM ft1_nopw LIMIT 1; -- unpriv user also cannot set sslcert / sslkey on the user mapping -- first set password_required so we see the right error messages @@ -3243,13 +3864,13 @@ DROP USER MAPPING FOR CURRENT_USER SERVER loopback_nopw; -- This will fail again as it'll resolve the user mapping for public, which -- lacks password_required=false -SELECT * FROM ft1_nopw LIMIT 1; +SELECT 1 FROM ft1_nopw LIMIT 1; RESET ROLE; -- The user mapping for public is passwordless and lacks the password_required=false -- mapping option, but will work because the current user is a superuser. -SELECT * FROM ft1_nopw LIMIT 1; +SELECT 1 FROM ft1_nopw LIMIT 1; -- cleanup DROP USER MAPPING FOR public SERVER loopback_nopw; @@ -3260,53 +3881,1062 @@ DROP ROLE regress_nosuper; -- influxdb_fdw does not support transactions -- Two-phase transactions are not supported. --BEGIN; ---Testcase 620: +--Testcase 698: SELECT count(*) FROM ft1; -- error here --PREPARE TRANSACTION 'fdw_tpc'; --ROLLBACK; +/* +-- Influxdb_fdw does not use connection, and does not support connection functions +-- =================================================================== +-- reestablish new connection +-- =================================================================== + +-- Change application_name of remote connection to special one +-- so that we can easily terminate the connection later. +ALTER SERVER loopback OPTIONS (application_name 'fdw_retry_check'); + +-- Make sure we have a remote connection. +SELECT 1 FROM ft1 LIMIT 1; + +-- Terminate the remote connection and wait for the termination to complete. +-- (If a cache flush happens, the remote connection might have already been +-- dropped; so code this step in a way that doesn't fail if no connection.) +DO $$ BEGIN +PERFORM pg_terminate_backend(pid, 180000) FROM pg_stat_activity + WHERE application_name = 'fdw_retry_check'; +END $$; + +-- This query should detect the broken connection when starting new remote +-- transaction, reestablish new connection, and then succeed. +BEGIN; +SELECT 1 FROM ft1 LIMIT 1; + +-- If we detect the broken connection when starting a new remote +-- subtransaction, we should fail instead of establishing a new connection. +-- Terminate the remote connection and wait for the termination to complete. +DO $$ BEGIN +PERFORM pg_terminate_backend(pid, 180000) FROM pg_stat_activity + WHERE application_name = 'fdw_retry_check'; +END $$; +SAVEPOINT s; +-- The text of the error might vary across platforms, so only show SQLSTATE. +\set VERBOSITY sqlstate +SELECT 1 FROM ft1 LIMIT 1; -- should fail +\set VERBOSITY default +COMMIT; + +-- ============================================================================= +-- test connection invalidation cases and postgres_fdw_get_connections function +-- ============================================================================= +-- Let's ensure to close all the existing cached connections. +SELECT 1 FROM postgres_fdw_disconnect_all(); +-- No cached connections, so no records should be output. +SELECT server_name FROM postgres_fdw_get_connections() ORDER BY 1; +-- This test case is for closing the connection in pgfdw_xact_callback +BEGIN; +-- Connection xact depth becomes 1 i.e. the connection is in midst of the xact. +SELECT 1 FROM ft1 LIMIT 1; +SELECT 1 FROM ft7 LIMIT 1; +-- List all the existing cached connections. loopback and loopback3 should be +-- output. +SELECT server_name FROM postgres_fdw_get_connections() ORDER BY 1; +-- Connections are not closed at the end of the alter and drop statements. +-- That's because the connections are in midst of this xact, +-- they are just marked as invalid in pgfdw_inval_callback. +ALTER SERVER loopback OPTIONS (ADD use_remote_estimate 'off'); +DROP SERVER loopback3 CASCADE; +-- List all the existing cached connections. loopback and loopback3 +-- should be output as invalid connections. Also the server name for +-- loopback3 should be NULL because the server was dropped. +SELECT * FROM postgres_fdw_get_connections() ORDER BY 1; +-- The invalid connections get closed in pgfdw_xact_callback during commit. +COMMIT; +-- All cached connections were closed while committing above xact, so no +-- records should be output. +SELECT server_name FROM postgres_fdw_get_connections() ORDER BY 1; + +-- ======================================================================= +-- test postgres_fdw_disconnect and postgres_fdw_disconnect_all functions +-- ======================================================================= +BEGIN; +-- Ensure to cache loopback connection. +SELECT 1 FROM ft1 LIMIT 1; +-- Ensure to cache loopback2 connection. +SELECT 1 FROM ft6 LIMIT 1; +-- List all the existing cached connections. loopback and loopback2 should be +-- output. +SELECT server_name FROM postgres_fdw_get_connections() ORDER BY 1; +-- Issue a warning and return false as loopback connection is still in use and +-- can not be closed. +SELECT postgres_fdw_disconnect('loopback'); +-- List all the existing cached connections. loopback and loopback2 should be +-- output. +SELECT server_name FROM postgres_fdw_get_connections() ORDER BY 1; +-- Return false as connections are still in use, warnings are issued. +-- But disable warnings temporarily because the order of them is not stable. +SET client_min_messages = 'ERROR'; +SELECT postgres_fdw_disconnect_all(); +RESET client_min_messages; +COMMIT; +-- Ensure that loopback2 connection is closed. +SELECT 1 FROM postgres_fdw_disconnect('loopback2'); +SELECT server_name FROM postgres_fdw_get_connections() WHERE server_name = 'loopback2'; +-- Return false as loopback2 connection is closed already. +SELECT postgres_fdw_disconnect('loopback2'); +-- Return an error as there is no foreign server with given name. +SELECT postgres_fdw_disconnect('unknownserver'); +-- Let's ensure to close all the existing cached connections. +SELECT 1 FROM postgres_fdw_disconnect_all(); +-- No cached connections, so no records should be output. +SELECT server_name FROM postgres_fdw_get_connections() ORDER BY 1; + +-- ============================================================================= +-- test case for having multiple cached connections for a foreign server +-- ============================================================================= +CREATE ROLE regress_multi_conn_user1 SUPERUSER; +CREATE ROLE regress_multi_conn_user2 SUPERUSER; +CREATE USER MAPPING FOR regress_multi_conn_user1 SERVER loopback; +CREATE USER MAPPING FOR regress_multi_conn_user2 SERVER loopback; + +BEGIN; +-- Will cache loopback connection with user mapping for regress_multi_conn_user1 +SET ROLE regress_multi_conn_user1; +SELECT 1 FROM ft1 LIMIT 1; +RESET ROLE; + +-- Will cache loopback connection with user mapping for regress_multi_conn_user2 +SET ROLE regress_multi_conn_user2; +SELECT 1 FROM ft1 LIMIT 1; +RESET ROLE; + +-- Should output two connections for loopback server +SELECT server_name FROM postgres_fdw_get_connections() ORDER BY 1; +COMMIT; +-- Let's ensure to close all the existing cached connections. +SELECT 1 FROM postgres_fdw_disconnect_all(); +-- No cached connections, so no records should be output. +SELECT server_name FROM postgres_fdw_get_connections() ORDER BY 1; + +-- Clean up +DROP USER MAPPING FOR regress_multi_conn_user1 SERVER loopback; +DROP USER MAPPING FOR regress_multi_conn_user2 SERVER loopback; +DROP ROLE regress_multi_conn_user1; +DROP ROLE regress_multi_conn_user2; + +-- =================================================================== +-- Test foreign server level option keep_connections +-- =================================================================== +-- By default, the connections associated with foreign server are cached i.e. +-- keep_connections option is on. Set it to off. +ALTER SERVER loopback OPTIONS (keep_connections 'off'); +-- connection to loopback server is closed at the end of xact +-- as keep_connections was set to off. +SELECT 1 FROM ft1 LIMIT 1; +-- No cached connections, so no records should be output. +SELECT server_name FROM postgres_fdw_get_connections() ORDER BY 1; +ALTER SERVER loopback OPTIONS (SET keep_connections 'on'); +*/ + +-- =================================================================== +-- batch insert +-- =================================================================== + +BEGIN; + +--Testcase 699: +CREATE SERVER batch10 FOREIGN DATA WRAPPER influxdb_fdw + OPTIONS(dbname 'postdb', :SERVER, batch_size '10' ); + +--Testcase 700: +SELECT count(*) +FROM pg_foreign_server +WHERE srvname = 'batch10' +AND srvoptions @> array['batch_size=10']; + +--Testcase 701: +ALTER SERVER batch10 OPTIONS( SET batch_size '20' ); + +--Testcase 702: +SELECT count(*) +FROM pg_foreign_server +WHERE srvname = 'batch10' +AND srvoptions @> array['batch_size=10']; + +--Testcase 703: +SELECT count(*) +FROM pg_foreign_server +WHERE srvname = 'batch10' +AND srvoptions @> array['batch_size=20']; + +--Testcase 704: +CREATE FOREIGN TABLE table30 ( x int ) SERVER batch10 OPTIONS ( batch_size '30' ); + +--Testcase 705: +SELECT COUNT(*) +FROM pg_foreign_table +WHERE ftrelid = 'table30'::regclass +AND ftoptions @> array['batch_size=30']; + +--Testcase 706: +ALTER FOREIGN TABLE table30 OPTIONS ( SET batch_size '40'); + +--Testcase 707: +SELECT COUNT(*) +FROM pg_foreign_table +WHERE ftrelid = 'table30'::regclass +AND ftoptions @> array['batch_size=30']; + +--Testcase 708: +SELECT COUNT(*) +FROM pg_foreign_table +WHERE ftrelid = 'table30'::regclass +AND ftoptions @> array['batch_size=40']; + +ROLLBACK; + +--Testcase 709: +CREATE FOREIGN TABLE batch_table ( x int ) SERVER influxdb_svr; +--Testcase 710: +CREATE FOREIGN TABLE ftable ( x int ) SERVER influxdb_svr OPTIONS ( table 'batch_table', batch_size '10' ); +--Testcase 711: +EXPLAIN (VERBOSE, COSTS OFF) INSERT INTO ftable SELECT * FROM generate_series(1, 10) i; +--Testcase 712: +INSERT INTO ftable SELECT * FROM generate_series(1, 10) i; +--Testcase 713: +INSERT INTO ftable SELECT * FROM generate_series(11, 31) i; +--Testcase 714: +INSERT INTO ftable VALUES (32); +--Testcase 715: +INSERT INTO ftable VALUES (33), (34); +--Testcase 721: +SELECT COUNT(*) FROM ftable; +--Testcase 722: +DELETE FROM batch_table; +--Testcase 723: +DROP FOREIGN TABLE ftable; + +-- Disable batch insert +--Testcase 724: +CREATE FOREIGN TABLE ftable ( x int ) SERVER influxdb_svr OPTIONS ( table 'batch_table', batch_size '1' ); +--Testcase 725: +EXPLAIN (VERBOSE, COSTS OFF) INSERT INTO ftable VALUES (1), (2); +--Testcase 726: +INSERT INTO ftable VALUES (1), (2); +--Testcase 727: +SELECT COUNT(*) FROM ftable; + +-- Disable batch inserting into foreign tables with BEFORE ROW INSERT triggers +-- even if the batch_size option is enabled. +--Testcase 776: +ALTER FOREIGN TABLE ftable OPTIONS ( SET batch_size '10' ); +--Testcase 777: +CREATE TRIGGER trig_row_before BEFORE INSERT ON ftable +FOR EACH ROW EXECUTE PROCEDURE trigger_data(23,'skidoo'); +--Testcase 778: +EXPLAIN (VERBOSE, COSTS OFF) INSERT INTO ftable VALUES (3), (4); +--Testcase 779: +INSERT INTO ftable VALUES (3), (4); +--Testcase 780: +SELECT COUNT(*) FROM ftable; + +-- Clean up +--Testcase 781: +DROP TRIGGER trig_row_before ON ftable; + +--Testcase 728: +DROP FOREIGN TABLE ftable; +--Testcase 729: +DELETE FROM batch_table; +--Testcase 785: +DROP FOREIGN TABLE batch_table; + +-- influxdb_fdw does not support partition insert +-- Use partitioning +--Testcase 730: +CREATE TABLE batch_table ( x int ) PARTITION BY HASH (x); + +--Testcase 731: +CREATE TABLE batch_table_p0 (LIKE batch_table); +--Testcase 732: +CREATE FOREIGN TABLE batch_table_p0f + PARTITION OF batch_table + FOR VALUES WITH (MODULUS 3, REMAINDER 0) + SERVER influxdb_svr + OPTIONS (table 'batch_table_p0', batch_size '10'); + +--Testcase 733: +CREATE TABLE batch_table_p1 (LIKE batch_table); +--Testcase 734: +CREATE FOREIGN TABLE batch_table_p1f + PARTITION OF batch_table + FOR VALUES WITH (MODULUS 3, REMAINDER 1) + SERVER influxdb_svr + OPTIONS (table 'batch_table_p1', batch_size '1'); + +--Testcase 735: +CREATE TABLE batch_table_p2 + PARTITION OF batch_table + FOR VALUES WITH (MODULUS 3, REMAINDER 2); + +--Testcase 736: +INSERT INTO batch_table SELECT * FROM generate_series(1, 66) i; +--Testcase 737: +SELECT COUNT(*) FROM batch_table; + +-- Clean up +DROP TABLE batch_table; +DROP TABLE batch_table_p0; +DROP TABLE batch_table_p1; + +-- Check that batched mode also works for some inserts made during +-- cross-partition updates +--Testcase 738: +CREATE TABLE batch_cp_upd_test (a int) PARTITION BY LIST (a); +--Testcase 739: +CREATE TABLE batch_cp_upd_test1 (LIKE batch_cp_upd_test); +--Testcase 740: +CREATE FOREIGN TABLE batch_cp_upd_test1_f + PARTITION OF batch_cp_upd_test + FOR VALUES IN (1) + SERVER influxdb_svr + OPTIONS (table 'batch_cp_upd_test1', batch_size '10'); +--Testcase 741: +CREATE TABLE batch_cp_upd_test2 PARTITION OF batch_cp_upd_test + FOR VALUES IN (2); +--Testcase 742: +CREATE TABLE batch_cp_upd_test3 (LIKE batch_cp_upd_test); +CREATE FOREIGN TABLE batch_cp_upd_test3_f + PARTITION OF batch_cp_upd_test + FOR VALUES IN (3) + SERVER influxdb_svr + OPTIONS (table 'batch_cp_upd_test3', batch_size '1'); + +-- Create statement triggers on remote tables that "log" any INSERTs +-- performed on them. +CREATE TABLE cmdlog (cmd text); +CREATE FUNCTION log_stmt() RETURNS TRIGGER LANGUAGE plpgsql AS $$ + BEGIN INSERT INTO public.cmdlog VALUES (TG_OP || ' on ' || TG_RELNAME); RETURN NULL; END; +$$; +CREATE TRIGGER stmt_trig AFTER INSERT ON batch_cp_upd_test1 + FOR EACH STATEMENT EXECUTE FUNCTION log_stmt(); +CREATE TRIGGER stmt_trig AFTER INSERT ON batch_cp_upd_test3 + FOR EACH STATEMENT EXECUTE FUNCTION log_stmt(); + +-- This update moves rows from the local partition 'batch_cp_upd_test2' to the +-- foreign partition 'batch_cp_upd_test1', one that has insert batching +-- enabled, so a single INSERT for both rows. +INSERT INTO batch_cp_upd_test VALUES (2), (2); +-- influxdb_fdw does not support update +-- UPDATE batch_cp_upd_test t SET a = 1 FROM (VALUES (1), (2)) s(a) WHERE t.a = s.a AND s.a = 2; + +-- This one moves rows from the local partition 'batch_cp_upd_test2' to the +-- foreign partition 'batch_cp_upd_test2', one that has insert batching +-- disabled, so separate INSERTs for the two rows. +INSERT INTO batch_cp_upd_test VALUES (2), (2); +-- UPDATE batch_cp_upd_test t SET a = 3 FROM (VALUES (1), (2)) s(a) WHERE t.a = s.a AND s.a = 2; + +SELECT tableoid::regclass, * FROM batch_cp_upd_test ORDER BY 1; + +-- Should see 1 INSERT on batch_cp_upd_test1 and 2 on batch_cp_upd_test3 as +-- described above. +SELECT * FROM cmdlog ORDER BY 1; + +-- Clean up +DROP TABLE batch_cp_upd_test; +DROP TABLE batch_cp_upd_test1; +DROP TABLE batch_cp_upd_test3; +DROP TABLE cmdlog; +DROP FUNCTION log_stmt(); + +-- influxdb_fdw does not support partition insert +-- Use partitioning +--Testcase 745: +ALTER SERVER influxdb_svr OPTIONS (ADD batch_size '10'); + +--Testcase 746: +CREATE TABLE batch_table ( x int, field1 text, field2 text) PARTITION BY HASH (x); + +--Testcase 747: +CREATE TABLE batch_table_p0 (LIKE batch_table); +--Testcase 748: +ALTER TABLE batch_table_p0 ADD CONSTRAINT p0_pkey PRIMARY KEY (x); +--Testcase 749: +CREATE FOREIGN TABLE batch_table_p0f + PARTITION OF batch_table + FOR VALUES WITH (MODULUS 2, REMAINDER 0) + SERVER influxdb_svr + OPTIONS (table 'batch_table_p0'); + +--Testcase 750: +CREATE TABLE batch_table_p1 (LIKE batch_table); +--Testcase 751: +ALTER TABLE batch_table_p1 ADD CONSTRAINT p1_pkey PRIMARY KEY (x); +--Testcase 752: +CREATE FOREIGN TABLE batch_table_p1f + PARTITION OF batch_table + FOR VALUES WITH (MODULUS 2, REMAINDER 1) + SERVER influxdb_svr + OPTIONS (table 'batch_table_p1'); + +--Testcase 753: +INSERT INTO batch_table SELECT i, 'test'||i, 'test'|| i FROM generate_series(1, 50) i; +--Testcase 754: +SELECT COUNT(*) FROM batch_table; +--Testcase 755: +SELECT * FROM batch_table ORDER BY x; + +-- Clean up +DROP TABLE batch_table; +DROP TABLE batch_table_p0; +DROP TABLE batch_table_p1; + +--Testcase 756: +ALTER SERVER influxdb_svr OPTIONS (DROP batch_size); + +-- Test that pending inserts are handled properly when needed +CREATE TABLE batch_table (a text, b int); +CREATE FOREIGN TABLE ftable (a text, b int) + SERVER influxdb_svr + OPTIONS (table 'batch_table', batch_size '2'); +CREATE TABLE ltable (a text, b int); +CREATE FUNCTION ftable_rowcount_trigf() RETURNS trigger LANGUAGE plpgsql AS +$$ +begin + raise notice '%: there are % rows in ftable', + TG_NAME, (SELECT count(*) FROM ftable); + if TG_OP = 'DELETE' then + return OLD; + else + return NEW; + end if; +end; +$$; +CREATE TRIGGER ftable_rowcount_trigger +BEFORE INSERT OR UPDATE OR DELETE ON ltable +FOR EACH ROW EXECUTE PROCEDURE ftable_rowcount_trigf(); + +WITH t AS ( + INSERT INTO ltable VALUES ('AAA', 42), ('BBB', 42) RETURNING * +) +INSERT INTO ftable SELECT * FROM t; + +SELECT * FROM ltable; +SELECT * FROM ftable; +DELETE FROM ftable; + +WITH t AS ( + UPDATE ltable SET b = b + 100 RETURNING * +) +INSERT INTO ftable SELECT * FROM t; + +SELECT * FROM ltable; +SELECT * FROM ftable; +DELETE FROM ftable; + +WITH t AS ( + DELETE FROM ltable RETURNING * +) +INSERT INTO ftable SELECT * FROM t; + +SELECT * FROM ltable; +SELECT * FROM ftable; +DELETE FROM ftable; + +-- Clean up +DROP FOREIGN TABLE ftable; +DROP TABLE batch_table; +DROP TRIGGER ftable_rowcount_trigger ON ltable; +DROP TABLE ltable; + +CREATE TABLE parent (a text, b int) PARTITION BY LIST (a); +CREATE TABLE batch_table (a text, b int); +CREATE FOREIGN TABLE ftable + PARTITION OF parent + FOR VALUES IN ('AAA') + SERVER influxdb_svr + OPTIONS (table 'batch_table', batch_size '2'); +CREATE TABLE ltable + PARTITION OF parent + FOR VALUES IN ('BBB'); +CREATE TRIGGER ftable_rowcount_trigger +BEFORE INSERT ON ltable +FOR EACH ROW EXECUTE PROCEDURE ftable_rowcount_trigf(); + +-- Not support partition insert +INSERT INTO parent VALUES ('AAA', 42), ('BBB', 42), ('AAA', 42), ('BBB', 42); + +SELECT tableoid::regclass, * FROM parent; + +-- Clean up +DROP FOREIGN TABLE ftable; +DROP TABLE batch_table; +DROP TRIGGER ftable_rowcount_trigger ON ltable; +DROP TABLE ltable; +DROP TABLE parent; +DROP FUNCTION ftable_rowcount_trigf; + +/* InfluxDB does not support partition table +-- =================================================================== +-- test asynchronous execution +-- =================================================================== + +ALTER SERVER loopback OPTIONS (DROP extensions); +ALTER SERVER loopback OPTIONS (ADD async_capable 'true'); +ALTER SERVER loopback2 OPTIONS (ADD async_capable 'true'); + +CREATE TABLE async_pt (a int, b int, c text) PARTITION BY RANGE (a); +CREATE TABLE base_tbl1 (a int, b int, c text); +CREATE TABLE base_tbl2 (a int, b int, c text); +CREATE FOREIGN TABLE async_p1 PARTITION OF async_pt FOR VALUES FROM (1000) TO (2000) + SERVER loopback OPTIONS (table_name 'base_tbl1'); +CREATE FOREIGN TABLE async_p2 PARTITION OF async_pt FOR VALUES FROM (2000) TO (3000) + SERVER loopback2 OPTIONS (table_name 'base_tbl2'); +INSERT INTO async_p1 SELECT 1000 + i, i, to_char(i, 'FM0000') FROM generate_series(0, 999, 5) i; +INSERT INTO async_p2 SELECT 2000 + i, i, to_char(i, 'FM0000') FROM generate_series(0, 999, 5) i; +ANALYZE async_pt; + +-- simple queries +CREATE TABLE result_tbl (a int, b int, c text); + +EXPLAIN (VERBOSE, COSTS OFF) +INSERT INTO result_tbl SELECT * FROM async_pt WHERE b % 100 = 0; +INSERT INTO result_tbl SELECT * FROM async_pt WHERE b % 100 = 0; + +SELECT * FROM result_tbl ORDER BY a; +DELETE FROM result_tbl; + +EXPLAIN (VERBOSE, COSTS OFF) +INSERT INTO result_tbl SELECT * FROM async_pt WHERE b === 505; +INSERT INTO result_tbl SELECT * FROM async_pt WHERE b === 505; + +SELECT * FROM result_tbl ORDER BY a; +DELETE FROM result_tbl; + +EXPLAIN (VERBOSE, COSTS OFF) +INSERT INTO result_tbl SELECT a, b, 'AAA' || c FROM async_pt WHERE b === 505; +INSERT INTO result_tbl SELECT a, b, 'AAA' || c FROM async_pt WHERE b === 505; + +SELECT * FROM result_tbl ORDER BY a; +DELETE FROM result_tbl; + +-- Check case where multiple partitions use the same connection +CREATE TABLE base_tbl3 (a int, b int, c text); +CREATE FOREIGN TABLE async_p3 PARTITION OF async_pt FOR VALUES FROM (3000) TO (4000) + SERVER loopback2 OPTIONS (table_name 'base_tbl3'); +INSERT INTO async_p3 SELECT 3000 + i, i, to_char(i, 'FM0000') FROM generate_series(0, 999, 5) i; +ANALYZE async_pt; + +EXPLAIN (VERBOSE, COSTS OFF) +INSERT INTO result_tbl SELECT * FROM async_pt WHERE b === 505; +INSERT INTO result_tbl SELECT * FROM async_pt WHERE b === 505; + +SELECT * FROM result_tbl ORDER BY a; +DELETE FROM result_tbl; + +DROP FOREIGN TABLE async_p3; +DROP TABLE base_tbl3; + +-- Check case where the partitioned table has local/remote partitions +CREATE TABLE async_p3 PARTITION OF async_pt FOR VALUES FROM (3000) TO (4000); +INSERT INTO async_p3 SELECT 3000 + i, i, to_char(i, 'FM0000') FROM generate_series(0, 999, 5) i; +ANALYZE async_pt; + +EXPLAIN (VERBOSE, COSTS OFF) +INSERT INTO result_tbl SELECT * FROM async_pt WHERE b === 505; +INSERT INTO result_tbl SELECT * FROM async_pt WHERE b === 505; + +SELECT * FROM result_tbl ORDER BY a; +DELETE FROM result_tbl; + +-- partitionwise joins +SET enable_partitionwise_join TO true; + +CREATE TABLE join_tbl (a1 int, b1 int, c1 text, a2 int, b2 int, c2 text); + +EXPLAIN (VERBOSE, COSTS OFF) +INSERT INTO join_tbl SELECT * FROM async_pt t1, async_pt t2 WHERE t1.a = t2.a AND t1.b = t2.b AND t1.b % 100 = 0; +INSERT INTO join_tbl SELECT * FROM async_pt t1, async_pt t2 WHERE t1.a = t2.a AND t1.b = t2.b AND t1.b % 100 = 0; + +SELECT * FROM join_tbl ORDER BY a1; +DELETE FROM join_tbl; + +EXPLAIN (VERBOSE, COSTS OFF) +INSERT INTO join_tbl SELECT t1.a, t1.b, 'AAA' || t1.c, t2.a, t2.b, 'AAA' || t2.c FROM async_pt t1, async_pt t2 WHERE t1.a = t2.a AND t1.b = t2.b AND t1.b % 100 = 0; +INSERT INTO join_tbl SELECT t1.a, t1.b, 'AAA' || t1.c, t2.a, t2.b, 'AAA' || t2.c FROM async_pt t1, async_pt t2 WHERE t1.a = t2.a AND t1.b = t2.b AND t1.b % 100 = 0; + +SELECT * FROM join_tbl ORDER BY a1; +DELETE FROM join_tbl; + +RESET enable_partitionwise_join; + +-- Test rescan of an async Append node with do_exec_prune=false +SET enable_hashjoin TO false; + +EXPLAIN (VERBOSE, COSTS OFF) +INSERT INTO join_tbl SELECT * FROM async_p1 t1, async_pt t2 WHERE t1.a = t2.a AND t1.b = t2.b AND t1.b % 100 = 0; +INSERT INTO join_tbl SELECT * FROM async_p1 t1, async_pt t2 WHERE t1.a = t2.a AND t1.b = t2.b AND t1.b % 100 = 0; + +SELECT * FROM join_tbl ORDER BY a1; +DELETE FROM join_tbl; + +RESET enable_hashjoin; + +-- Test interaction of async execution with plan-time partition pruning +EXPLAIN (VERBOSE, COSTS OFF) +SELECT * FROM async_pt WHERE a < 3000; + +EXPLAIN (VERBOSE, COSTS OFF) +SELECT * FROM async_pt WHERE a < 2000; + +-- Test interaction of async execution with run-time partition pruning +SET plan_cache_mode TO force_generic_plan; + +PREPARE async_pt_query (int, int) AS + INSERT INTO result_tbl SELECT * FROM async_pt WHERE a < $1 AND b === $2; + +EXPLAIN (VERBOSE, COSTS OFF) +EXECUTE async_pt_query (3000, 505); +EXECUTE async_pt_query (3000, 505); + +SELECT * FROM result_tbl ORDER BY a; +DELETE FROM result_tbl; + +EXPLAIN (VERBOSE, COSTS OFF) +EXECUTE async_pt_query (2000, 505); +EXECUTE async_pt_query (2000, 505); + +SELECT * FROM result_tbl ORDER BY a; +DELETE FROM result_tbl; + +RESET plan_cache_mode; + +CREATE TABLE local_tbl(a int, b int, c text); +INSERT INTO local_tbl VALUES (1505, 505, 'foo'), (2505, 505, 'bar'); +ANALYZE local_tbl; + +CREATE INDEX base_tbl1_idx ON base_tbl1 (a); +CREATE INDEX base_tbl2_idx ON base_tbl2 (a); +CREATE INDEX async_p3_idx ON async_p3 (a); +ANALYZE base_tbl1; +ANALYZE base_tbl2; +ANALYZE async_p3; + +ALTER FOREIGN TABLE async_p1 OPTIONS (use_remote_estimate 'true'); +ALTER FOREIGN TABLE async_p2 OPTIONS (use_remote_estimate 'true'); + +EXPLAIN (VERBOSE, COSTS OFF) +SELECT * FROM local_tbl, async_pt WHERE local_tbl.a = async_pt.a AND local_tbl.c = 'bar'; +EXPLAIN (ANALYZE, COSTS OFF, SUMMARY OFF, TIMING OFF) +SELECT * FROM local_tbl, async_pt WHERE local_tbl.a = async_pt.a AND local_tbl.c = 'bar'; +SELECT * FROM local_tbl, async_pt WHERE local_tbl.a = async_pt.a AND local_tbl.c = 'bar'; + +ALTER FOREIGN TABLE async_p1 OPTIONS (DROP use_remote_estimate); +ALTER FOREIGN TABLE async_p2 OPTIONS (DROP use_remote_estimate); + +DROP TABLE local_tbl; +DROP INDEX base_tbl1_idx; +DROP INDEX base_tbl2_idx; +DROP INDEX async_p3_idx; + +-- UNION queries +EXPLAIN (VERBOSE, COSTS OFF) +INSERT INTO result_tbl +(SELECT a, b, 'AAA' || c FROM async_p1 ORDER BY a LIMIT 10) +UNION +(SELECT a, b, 'AAA' || c FROM async_p2 WHERE b < 10); +INSERT INTO result_tbl +(SELECT a, b, 'AAA' || c FROM async_p1 ORDER BY a LIMIT 10) +UNION +(SELECT a, b, 'AAA' || c FROM async_p2 WHERE b < 10); + +SELECT * FROM result_tbl ORDER BY a; +DELETE FROM result_tbl; + +EXPLAIN (VERBOSE, COSTS OFF) +INSERT INTO result_tbl +(SELECT a, b, 'AAA' || c FROM async_p1 ORDER BY a LIMIT 10) +UNION ALL +(SELECT a, b, 'AAA' || c FROM async_p2 WHERE b < 10); +INSERT INTO result_tbl +(SELECT a, b, 'AAA' || c FROM async_p1 ORDER BY a LIMIT 10) +UNION ALL +(SELECT a, b, 'AAA' || c FROM async_p2 WHERE b < 10); + +SELECT * FROM result_tbl ORDER BY a; +DELETE FROM result_tbl; + +-- Disable async execution if we use gating Result nodes for pseudoconstant +-- quals +EXPLAIN (VERBOSE, COSTS OFF) +SELECT * FROM async_pt WHERE CURRENT_USER = SESSION_USER; + +EXPLAIN (VERBOSE, COSTS OFF) +(SELECT * FROM async_p1 WHERE CURRENT_USER = SESSION_USER) +UNION ALL +(SELECT * FROM async_p2 WHERE CURRENT_USER = SESSION_USER); + +EXPLAIN (VERBOSE, COSTS OFF) +SELECT * FROM ((SELECT * FROM async_p1 WHERE b < 10) UNION ALL (SELECT * FROM async_p2 WHERE b < 10)) s WHERE CURRENT_USER = SESSION_USER; + +-- Test that pending requests are processed properly +SET enable_mergejoin TO false; +SET enable_hashjoin TO false; + +EXPLAIN (VERBOSE, COSTS OFF) +SELECT * FROM async_pt t1, async_p2 t2 WHERE t1.a = t2.a AND t1.b === 505; +SELECT * FROM async_pt t1, async_p2 t2 WHERE t1.a = t2.a AND t1.b === 505; + +CREATE TABLE local_tbl (a int, b int, c text); +INSERT INTO local_tbl VALUES (1505, 505, 'foo'); +ANALYZE local_tbl; + +EXPLAIN (VERBOSE, COSTS OFF) +SELECT * FROM local_tbl t1 LEFT JOIN (SELECT *, (SELECT count(*) FROM async_pt WHERE a < 3000) FROM async_pt WHERE a < 3000) t2 ON t1.a = t2.a; +EXPLAIN (ANALYZE, COSTS OFF, SUMMARY OFF, TIMING OFF) +SELECT * FROM local_tbl t1 LEFT JOIN (SELECT *, (SELECT count(*) FROM async_pt WHERE a < 3000) FROM async_pt WHERE a < 3000) t2 ON t1.a = t2.a; +SELECT * FROM local_tbl t1 LEFT JOIN (SELECT *, (SELECT count(*) FROM async_pt WHERE a < 3000) FROM async_pt WHERE a < 3000) t2 ON t1.a = t2.a; + +EXPLAIN (VERBOSE, COSTS OFF) +SELECT * FROM async_pt t1 WHERE t1.b === 505 LIMIT 1; +EXPLAIN (ANALYZE, COSTS OFF, SUMMARY OFF, TIMING OFF) +SELECT * FROM async_pt t1 WHERE t1.b === 505 LIMIT 1; +SELECT * FROM async_pt t1 WHERE t1.b === 505 LIMIT 1; + +-- Check with foreign modify +CREATE TABLE base_tbl3 (a int, b int, c text); +CREATE FOREIGN TABLE remote_tbl (a int, b int, c text) + SERVER loopback OPTIONS (table_name 'base_tbl3'); +INSERT INTO remote_tbl VALUES (2505, 505, 'bar'); + +CREATE TABLE base_tbl4 (a int, b int, c text); +CREATE FOREIGN TABLE insert_tbl (a int, b int, c text) + SERVER loopback OPTIONS (table_name 'base_tbl4'); + +EXPLAIN (VERBOSE, COSTS OFF) +INSERT INTO insert_tbl (SELECT * FROM local_tbl UNION ALL SELECT * FROM remote_tbl); +INSERT INTO insert_tbl (SELECT * FROM local_tbl UNION ALL SELECT * FROM remote_tbl); + +SELECT * FROM insert_tbl ORDER BY a; + +-- Check with direct modify +EXPLAIN (VERBOSE, COSTS OFF) +WITH t AS (UPDATE remote_tbl SET c = c || c RETURNING *) +INSERT INTO join_tbl SELECT * FROM async_pt LEFT JOIN t ON (async_pt.a = t.a AND async_pt.b = t.b) WHERE async_pt.b === 505; +WITH t AS (UPDATE remote_tbl SET c = c || c RETURNING *) +INSERT INTO join_tbl SELECT * FROM async_pt LEFT JOIN t ON (async_pt.a = t.a AND async_pt.b = t.b) WHERE async_pt.b === 505; + +SELECT * FROM join_tbl ORDER BY a1; +DELETE FROM join_tbl; + +DROP TABLE local_tbl; +DROP FOREIGN TABLE remote_tbl; +DROP FOREIGN TABLE insert_tbl; +DROP TABLE base_tbl3; +DROP TABLE base_tbl4; + +RESET enable_mergejoin; +RESET enable_hashjoin; + +-- Test that UPDATE/DELETE with inherited target works with async_capable enabled +EXPLAIN (VERBOSE, COSTS OFF) +UPDATE async_pt SET c = c || c WHERE b = 0 RETURNING *; +UPDATE async_pt SET c = c || c WHERE b = 0 RETURNING *; +EXPLAIN (VERBOSE, COSTS OFF) +DELETE FROM async_pt WHERE b = 0 RETURNING *; +DELETE FROM async_pt WHERE b = 0 RETURNING *; + +-- Check EXPLAIN ANALYZE for a query that scans empty partitions asynchronously +DELETE FROM async_p1; +DELETE FROM async_p2; +DELETE FROM async_p3; + +EXPLAIN (ANALYZE, COSTS OFF, SUMMARY OFF, TIMING OFF) +SELECT * FROM async_pt; + +-- Clean up +DROP TABLE async_pt; +DROP TABLE base_tbl1; +DROP TABLE base_tbl2; +DROP TABLE result_tbl; +DROP TABLE join_tbl; + +-- Test that an asynchronous fetch is processed before restarting the scan in +-- ReScanForeignScan +CREATE TABLE base_tbl (a int, b int); +INSERT INTO base_tbl VALUES (1, 11), (2, 22), (3, 33); +CREATE FOREIGN TABLE foreign_tbl (b int) + SERVER loopback OPTIONS (table_name 'base_tbl'); +CREATE FOREIGN TABLE foreign_tbl2 () INHERITS (foreign_tbl) + SERVER loopback OPTIONS (table_name 'base_tbl'); + +EXPLAIN (VERBOSE, COSTS OFF) +SELECT a FROM base_tbl WHERE a IN (SELECT a FROM foreign_tbl); +SELECT a FROM base_tbl WHERE a IN (SELECT a FROM foreign_tbl); + +-- Clean up +DROP FOREIGN TABLE foreign_tbl CASCADE; +DROP TABLE base_tbl; + +ALTER SERVER loopback OPTIONS (DROP async_capable); +ALTER SERVER loopback2 OPTIONS (DROP async_capable); +*/ + +-- =================================================================== +-- test invalid server, foreign table and foreign data wrapper options +-- =================================================================== +/* +-- InfluxDB FDW does not have these options +-- Invalid fdw_startup_cost option +CREATE SERVER inv_scst FOREIGN DATA WRAPPER postgres_fdw + OPTIONS(fdw_startup_cost '100$%$#$#'); +-- Invalid fdw_tuple_cost option +CREATE SERVER inv_scst FOREIGN DATA WRAPPER postgres_fdw + OPTIONS(fdw_tuple_cost '100$%$#$#'); +-- Invalid fetch_size option +CREATE FOREIGN TABLE inv_fsz (c1 int ) + SERVER loopback OPTIONS (fetch_size '100$%$#$#'); +*/ +-- Invalid batch_size option +--Testcase 776: +CREATE FOREIGN TABLE inv_bsz (c1 int ) + SERVER influxdb_svr OPTIONS (batch_size '100$%$#$#'); + +-- No option is allowed to be specified at foreign data wrapper level +--Testcase 782: +ALTER FOREIGN DATA WRAPPER influxdb_fdw OPTIONS (nonexistent 'fdw'); + +/* +-- =================================================================== +-- application_name is an option in libpq of postgres +-- so Influxdb_fdw not support application_name. +-- test postgres_fdw.application_name GUC +-- =================================================================== +-- To avoid race conditions in checking the remote session's application_name, +-- use this view to make the remote session itself read its application_name. +CREATE VIEW my_application_name AS + SELECT application_name FROM pg_stat_activity WHERE pid = pg_backend_pid(); + +CREATE FOREIGN TABLE remote_application_name (application_name text) + SERVER loopback2 + OPTIONS (schema_name 'public', table_name 'my_application_name'); + +SELECT count(*) FROM remote_application_name; + +-- Specify escape sequences in application_name option of a server +-- object so as to test that they are replaced with status information +-- expectedly. Note that we are also relying on ALTER SERVER to force +-- the remote session to be restarted with its new application name. +-- +-- Since pg_stat_activity.application_name may be truncated to less than +-- NAMEDATALEN characters, note that substring() needs to be used +-- at the condition of test query to make sure that the string consisting +-- of database name and process ID is also less than that. +ALTER SERVER loopback2 OPTIONS (application_name 'fdw_%d%p'); +SELECT count(*) FROM remote_application_name + WHERE application_name = + substring('fdw_' || current_database() || pg_backend_pid() for + current_setting('max_identifier_length')::int); + +-- postgres_fdw.application_name overrides application_name option +-- of a server object if both settings are present. +ALTER SERVER loopback2 OPTIONS (SET application_name 'fdw_wrong'); +SET postgres_fdw.application_name TO 'fdw_%a%u%%'; +SELECT count(*) FROM remote_application_name + WHERE application_name = + substring('fdw_' || current_setting('application_name') || + CURRENT_USER || '%' for current_setting('max_identifier_length')::int); +RESET postgres_fdw.application_name; + +-- Test %c (session ID) and %C (cluster name) escape sequences. +ALTER SERVER loopback2 OPTIONS (SET application_name 'fdw_%C%c'); +SELECT count(*) FROM remote_application_name + WHERE application_name = + substring('fdw_' || current_setting('cluster_name') || + to_hex(trunc(EXTRACT(EPOCH FROM (SELECT backend_start FROM + pg_stat_get_activity(pg_backend_pid()))))::integer) || '.' || + to_hex(pg_backend_pid()) + for current_setting('max_identifier_length')::int); + +-- Clean up. +DROP FOREIGN TABLE remote_application_name; +DROP VIEW my_application_name; + +-- =================================================================== +-- test parallel commit and parallel abort +-- =================================================================== +ALTER SERVER loopback OPTIONS (ADD parallel_commit 'true'); +ALTER SERVER loopback OPTIONS (ADD parallel_abort 'true'); +ALTER SERVER loopback2 OPTIONS (ADD parallel_commit 'true'); +ALTER SERVER loopback2 OPTIONS (ADD parallel_abort 'true'); + +CREATE TABLE ploc1 (f1 int, f2 text); +CREATE FOREIGN TABLE prem1 (f1 int, f2 text) + SERVER loopback OPTIONS (table_name 'ploc1'); +CREATE TABLE ploc2 (f1 int, f2 text); +CREATE FOREIGN TABLE prem2 (f1 int, f2 text) + SERVER loopback2 OPTIONS (table_name 'ploc2'); + +BEGIN; +INSERT INTO prem1 VALUES (101, 'foo'); +INSERT INTO prem2 VALUES (201, 'bar'); +COMMIT; +SELECT * FROM prem1; +SELECT * FROM prem2; + +BEGIN; +SAVEPOINT s; +INSERT INTO prem1 VALUES (102, 'foofoo'); +INSERT INTO prem2 VALUES (202, 'barbar'); +RELEASE SAVEPOINT s; +COMMIT; +SELECT * FROM prem1; +SELECT * FROM prem2; + +-- This tests executing DEALLOCATE ALL against foreign servers in parallel +-- during pre-commit +BEGIN; +SAVEPOINT s; +INSERT INTO prem1 VALUES (103, 'baz'); +INSERT INTO prem2 VALUES (203, 'qux'); +ROLLBACK TO SAVEPOINT s; +RELEASE SAVEPOINT s; +INSERT INTO prem1 VALUES (104, 'bazbaz'); +INSERT INTO prem2 VALUES (204, 'quxqux'); +COMMIT; +SELECT * FROM prem1; +SELECT * FROM prem2; + +BEGIN; +INSERT INTO prem1 VALUES (105, 'test1'); +INSERT INTO prem2 VALUES (205, 'test2'); +ABORT; +SELECT * FROM prem1; +SELECT * FROM prem2; + +-- This tests executing DEALLOCATE ALL against foreign servers in parallel +-- during post-abort +BEGIN; +SAVEPOINT s; +INSERT INTO prem1 VALUES (105, 'test1'); +INSERT INTO prem2 VALUES (205, 'test2'); +ROLLBACK TO SAVEPOINT s; +RELEASE SAVEPOINT s; +INSERT INTO prem1 VALUES (105, 'test1'); +INSERT INTO prem2 VALUES (205, 'test2'); +ABORT; +SELECT * FROM prem1; +SELECT * FROM prem2; + +ALTER SERVER loopback OPTIONS (DROP parallel_commit); +ALTER SERVER loopback OPTIONS (DROP parallel_abort); +ALTER SERVER loopback2 OPTIONS (DROP parallel_commit); +ALTER SERVER loopback2 OPTIONS (DROP parallel_abort); + +-- =================================================================== +-- test for ANALYZE sampling +-- =================================================================== + +CREATE TABLE analyze_table (id int, a text, b bigint); + +CREATE FOREIGN TABLE analyze_ftable (id int, a text, b bigint) + SERVER loopback OPTIONS (table_name 'analyze_rtable1'); + +INSERT INTO analyze_table (SELECT x FROM generate_series(1,1000) x); +ANALYZE analyze_table; + +SET default_statistics_target = 10; +ANALYZE analyze_table; + +ALTER SERVER loopback OPTIONS (analyze_sampling 'invalid'); + +ALTER SERVER loopback OPTIONS (analyze_sampling 'auto'); +ANALYZE analyze_table; + +ALTER SERVER loopback OPTIONS (SET analyze_sampling 'system'); +ANALYZE analyze_table; + +ALTER SERVER loopback OPTIONS (SET analyze_sampling 'bernoulli'); +ANALYZE analyze_table; + +ALTER SERVER loopback OPTIONS (SET analyze_sampling 'random'); +ANALYZE analyze_table; + +ALTER SERVER loopback OPTIONS (SET analyze_sampling 'off'); +ANALYZE analyze_table; + +-- cleanup +DROP FOREIGN TABLE analyze_ftable; +DROP TABLE analyze_table; +*/ -- Clean-up +--Testcase 786: delete from ft1; +--Testcase 787: delete from ft2; +--Testcase 788: delete from ft4; +--Testcase 789: delete from ft5; +--Testcase 790: delete from foo; +--Testcase 791: delete from bar; +--Testcase 792: delete from loct1; +--Testcase 793: delete from loct2; +--Testcase 794: delete from rem1; +--Testcase 795: drop foreign table foo cascade; +--Testcase 796: drop foreign table bar cascade; +--Testcase 797: drop foreign table loct1; +--Testcase 798: drop foreign table loct2; +--Testcase 799: drop foreign table ft1; +--Testcase 800: drop foreign table ft2; +--Testcase 801: drop foreign table ft4; +--Testcase 802: drop foreign table ft5; +--Testcase 803: DROP TYPE IF EXISTS user_enum; +--Testcase 804: DROP SCHEMA IF EXISTS "S 1" CASCADE; +--Testcase 805: DROP FUNCTION IF EXISTS trigger_func(); +--Testcase 806: DROP FUNCTION IF EXISTS trig_row_before_insupdate(); +--Testcase 807: DROP FUNCTION IF EXISTS trig_null(); +--Testcase 808: DROP SCHEMA IF EXISTS import_influx1 CASCADE; +--Testcase 809: DROP SCHEMA IF EXISTS import_influx2 CASCADE; +--Testcase 810: DROP SCHEMA IF EXISTS import_influx3 CASCADE; +--Testcase 811: DROP SCHEMA IF EXISTS import_influx4 CASCADE; ---Testcase 621: +--Testcase 758: DROP USER MAPPING FOR public SERVER testserver1; ---Testcase 622: +--Testcase 759: DROP USER MAPPING FOR CURRENT_USER SERVER influxdb_svr; ---Testcase 623: +--Testcase 760: DROP USER MAPPING FOR CURRENT_USER SERVER influxdb_svr2; ---Testcase 624: +--Testcase 761: DROP SERVER testserver1 CASCADE; ---Testcase 625: +--Testcase 762: DROP SERVER influxdb_svr CASCADE; ---Testcase 626: +--Testcase 763: DROP SERVER influxdb_svr2 CASCADE; ---Testcase 627: +--Testcase 764: DROP EXTENSION influxdb_fdw CASCADE; diff --git a/sql/15.0/extra/init.sql b/sql/16.0/extra/init.sql similarity index 100% rename from sql/15.0/extra/init.sql rename to sql/16.0/extra/init.sql diff --git a/sql/14.5/extra/insert.sql b/sql/16.0/extra/insert.sql similarity index 96% rename from sql/14.5/extra/insert.sql rename to sql/16.0/extra/insert.sql index 785e0ef..afa55c9 100644 --- a/sql/14.5/extra/insert.sql +++ b/sql/16.0/extra/insert.sql @@ -65,7 +65,9 @@ select col1, col2, char_length(col3) from inserttest; --Testcase 20: -- Clean up: +--Testcase 24: delete from inserttest; +--Testcase 25: drop foreign table inserttest; /* @@ -289,33 +291,6 @@ select tableoid::regclass::text, a, min(b) as min_b, max(b) as max_b from list_p -- direct partition inserts should check hash partition bound constraint --- 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 or replace function part_hashint4_noop(value int4, seed int8) -returns int8 as $$ -select value + seed; -$$ language sql immutable; - -create operator class part_test_int4_ops -for type int4 -using hash as -operator 1 =, -function 2 part_hashint4_noop(int4, int8); - -create or replace function part_hashtext_length(value text, seed int8) -RETURNS int8 AS $$ -select length(coalesce(value, ''))::int8 -$$ language sql immutable; - -create operator class part_test_text_ops -for type text -using hash as -operator 1 =, -function 2 part_hashtext_length(text, int8); - create table hash_parted ( a int ) partition by hash (a part_test_int4_ops); diff --git a/sql/11.17/extra/join.sql b/sql/16.0/extra/join.sql similarity index 80% rename from sql/11.17/extra/join.sql rename to sql/16.0/extra/join.sql index 4737d00..cdf67aa 100644 --- a/sql/11.17/extra/join.sql +++ b/sql/16.0/extra/join.sql @@ -74,6 +74,25 @@ INSERT INTO J2_TBL VALUES (0, NULL); --Testcase 24: INSERT INTO J2_TBL VALUES (NULL, 0); +CREATE FOREIGN 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 +) SERVER influxdb_svr; + --Testcase 25: CREATE FOREIGN TABLE tenk1 ( unique1 int4, @@ -236,26 +255,48 @@ SELECT * FROM J1_TBL t1 (a, b, c) JOIN J2_TBL t2 (a, b) USING (b) ORDER BY b, t1.a; +-- test join using aliases +--Testcase 49: +SELECT * FROM J1_TBL JOIN J2_TBL USING (i) WHERE J1_TBL.t = 'one'; -- ok +--Testcase 50: +SELECT * FROM J1_TBL JOIN J2_TBL USING (i) AS x WHERE J1_TBL.t = 'one'; -- ok +--Testcase 51: +SELECT * FROM (J1_TBL JOIN J2_TBL USING (i)) AS x WHERE J1_TBL.t = 'one'; -- error +--Testcase 52: +SELECT * FROM J1_TBL JOIN J2_TBL USING (i) AS x WHERE x.i = 1; -- ok +--Testcase 53: +SELECT * FROM J1_TBL JOIN J2_TBL USING (i) AS x WHERE x.t = 'one'; -- error +--Testcase 54: +SELECT * FROM (J1_TBL JOIN J2_TBL USING (i) AS x) AS xx WHERE x.i = 1; -- error (XXX could use better hint) +--Testcase 55: +SELECT * FROM J1_TBL a1 JOIN J2_TBL a2 USING (i) AS a1; -- error +--Testcase 56: +SELECT x.* FROM J1_TBL JOIN J2_TBL USING (i) AS x WHERE J1_TBL.t = 'one'; +--Testcase 57: +SELECT ROW(x.*) FROM J1_TBL JOIN J2_TBL USING (i) AS x WHERE J1_TBL.t = 'one'; +--Testcase 58: +SELECT row_to_json(x.*) FROM J1_TBL JOIN J2_TBL USING (i) AS x WHERE J1_TBL.t = 'one'; + -- -- NATURAL JOIN -- Inner equi-join on all columns with the same name -- ---Testcase 49: +--Testcase 59: SELECT * FROM J1_TBL NATURAL JOIN J2_TBL; ---Testcase 50: +--Testcase 60: SELECT * FROM J1_TBL t1 (a, b, c) NATURAL JOIN J2_TBL t2 (a, d); ---Testcase 51: +--Testcase 61: SELECT * FROM J1_TBL t1 (a, b, c) NATURAL JOIN J2_TBL t2 (d, a); -- mismatch number of columns -- currently, Postgres will fill in with underlying names ---Testcase 52: +--Testcase 62: SELECT * FROM J1_TBL t1 (a, b) NATURAL JOIN J2_TBL t2 (a); @@ -264,11 +305,11 @@ SELECT * -- Inner joins (equi-joins) -- ---Testcase 53: +--Testcase 63: SELECT * FROM J1_TBL JOIN J2_TBL ON (J1_TBL.i = J2_TBL.i); ---Testcase 54: +--Testcase 64: SELECT * FROM J1_TBL JOIN J2_TBL ON (J1_TBL.i = J2_TBL.k); @@ -277,7 +318,7 @@ SELECT * -- Non-equi-joins -- ---Testcase 55: +--Testcase 65: SELECT * FROM J1_TBL JOIN J2_TBL ON (J1_TBL.i <= J2_TBL.k); @@ -287,46 +328,46 @@ SELECT * -- Note that OUTER is a noise word -- ---Testcase 56: +--Testcase 66: SELECT * FROM J1_TBL LEFT OUTER JOIN J2_TBL USING (i) ORDER BY i, k, t; ---Testcase 57: +--Testcase 67: SELECT * FROM J1_TBL LEFT JOIN J2_TBL USING (i) ORDER BY i, k, t; ---Testcase 58: +--Testcase 68: SELECT * FROM J1_TBL RIGHT OUTER JOIN J2_TBL USING (i); ---Testcase 59: +--Testcase 69: SELECT * FROM J1_TBL RIGHT JOIN J2_TBL USING (i); ---Testcase 60: +--Testcase 70: SELECT * FROM J1_TBL FULL OUTER JOIN J2_TBL USING (i) ORDER BY i, k, t; ---Testcase 61: +--Testcase 71: SELECT * FROM J1_TBL FULL JOIN J2_TBL USING (i) ORDER BY i, k, t; ---Testcase 62: +--Testcase 72: SELECT * FROM J1_TBL LEFT JOIN J2_TBL USING (i) WHERE (k = 1); ---Testcase 63: +--Testcase 73: SELECT * FROM J1_TBL LEFT JOIN J2_TBL USING (i) WHERE (i = 1); -- -- semijoin selectivity for <> -- ---Testcase 64: +--Testcase 74: explain (costs off) select * from int4_tbl i4, tenk1 a where exists(select * from tenk1 b @@ -342,29 +383,29 @@ where exists(select * from tenk1 b -- Multiway full join -- ---Testcase 65: +--Testcase 75: CREATE FOREIGN TABLE t1 (name TEXT, n INTEGER) SERVER influxdb_svr; ---Testcase 66: +--Testcase 76: CREATE FOREIGN TABLE t2 (name TEXT, n INTEGER) SERVER influxdb_svr; ---Testcase 67: +--Testcase 77: CREATE FOREIGN TABLE t3 (name TEXT, n INTEGER) SERVER influxdb_svr; ---Testcase 68: +--Testcase 78: INSERT INTO t1 VALUES ( 'bb', 11 ); ---Testcase 69: +--Testcase 79: INSERT INTO t2 VALUES ( 'bb', 12 ); ---Testcase 70: +--Testcase 80: INSERT INTO t2 VALUES ( 'cc', 22 ); ---Testcase 71: +--Testcase 81: INSERT INTO t2 VALUES ( 'ee', 42 ); ---Testcase 72: +--Testcase 82: INSERT INTO t3 VALUES ( 'bb', 13 ); ---Testcase 73: +--Testcase 83: INSERT INTO t3 VALUES ( 'cc', 23 ); ---Testcase 74: +--Testcase 84: INSERT INTO t3 VALUES ( 'dd', 33 ); ---Testcase 75: +--Testcase 85: SELECT * FROM t1 FULL JOIN t2 USING (name) FULL JOIN t3 USING (name); -- @@ -372,21 +413,21 @@ SELECT * FROM t1 FULL JOIN t2 USING (name) FULL JOIN t3 USING (name); -- -- Basic cases (we expect planner to pull up the subquery here) ---Testcase 76: +--Testcase 86: SELECT * FROM (SELECT * FROM t2) as s2 INNER JOIN (SELECT * FROM t3) s3 USING (name); ---Testcase 77: +--Testcase 87: SELECT * FROM (SELECT * FROM t2) as s2 LEFT JOIN (SELECT * FROM t3) s3 USING (name); ---Testcase 78: +--Testcase 88: SELECT * FROM (SELECT * FROM t2) as s2 FULL JOIN @@ -395,25 +436,25 @@ USING (name); -- Cases with non-nullable expressions in subquery results; -- make sure these go to null as expected ---Testcase 79: +--Testcase 89: 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; ---Testcase 80: +--Testcase 90: 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; ---Testcase 81: +--Testcase 91: 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; ---Testcase 82: +--Testcase 92: SELECT * FROM (SELECT name, n as s1_n, 1 as s1_1 FROM t1) as s1 NATURAL INNER JOIN @@ -421,7 +462,7 @@ NATURAL INNER JOIN NATURAL INNER JOIN (SELECT name, n as s3_n, 3 as s3_2 FROM t3) s3; ---Testcase 83: +--Testcase 93: SELECT * FROM (SELECT name, n as s1_n, 1 as s1_1 FROM t1) as s1 NATURAL FULL JOIN @@ -429,7 +470,7 @@ NATURAL FULL JOIN NATURAL FULL JOIN (SELECT name, n as s3_n, 3 as s3_2 FROM t3) s3; ---Testcase 84: +--Testcase 94: SELECT * FROM (SELECT name, n as s1_n FROM t1) as s1 NATURAL FULL JOIN @@ -439,7 +480,7 @@ NATURAL FULL JOIN (SELECT name, n as s3_n FROM t3) as s3 ) ss2; ---Testcase 85: +--Testcase 95: SELECT * FROM (SELECT name, n as s1_n FROM t1) as s1 NATURAL FULL JOIN @@ -450,7 +491,7 @@ NATURAL FULL JOIN ) ss2; -- Constants as join keys can also be problematic ---Testcase 86: +--Testcase 96: SELECT * FROM (SELECT name, n as s1_n FROM t1) as s1 FULL JOIN @@ -460,60 +501,60 @@ ON (s1_n = s2_n); -- Test for propagation of nullability constraints into sub-joins ---Testcase 87: +--Testcase 97: create foreign table x (x1 int, x2 int) server influxdb_svr; ---Testcase 88: +--Testcase 98: insert into x values (1,11); ---Testcase 89: +--Testcase 99: insert into x values (2,22); ---Testcase 90: +--Testcase 100: insert into x values (3,null); ---Testcase 91: +--Testcase 101: insert into x values (4,44); ---Testcase 92: +--Testcase 102: insert into x values (5,null); ---Testcase 93: +--Testcase 103: create foreign table y (y1 int, y2 int) server influxdb_svr; ---Testcase 94: +--Testcase 104: insert into y values (1,111); ---Testcase 95: +--Testcase 105: insert into y values (2,222); ---Testcase 96: +--Testcase 106: insert into y values (3,333); ---Testcase 97: +--Testcase 107: insert into y values (4,null); ---Testcase 98: +--Testcase 108: select * from x; ---Testcase 99: +--Testcase 109: select * from y; ---Testcase 100: +--Testcase 110: select * from x left join y on (x1 = y1 and x2 is not null); ---Testcase 101: +--Testcase 111: select * from x left join y on (x1 = y1 and y2 is not null); ---Testcase 102: +--Testcase 112: select * from (x left join y on (x1 = y1)) left join x xx(xx1,xx2) on (x1 = xx1); ---Testcase 103: +--Testcase 113: select * from (x left join y on (x1 = y1)) left join x xx(xx1,xx2) on (x1 = xx1 and x2 is not null); ---Testcase 104: +--Testcase 114: select * from (x left join y on (x1 = y1)) left join x xx(xx1,xx2) on (x1 = xx1 and y2 is not null); ---Testcase 105: +--Testcase 115: select * from (x left join y on (x1 = y1)) left join x xx(xx1,xx2) on (x1 = xx1 and xx2 is not null); -- these should NOT give the same answers as above ---Testcase 106: +--Testcase 116: select * from (x left join y on (x1 = y1)) left join x xx(xx1,xx2) on (x1 = xx1) where (x2 is not null); ---Testcase 107: +--Testcase 117: select * from (x left join y on (x1 = y1)) left join x xx(xx1,xx2) on (x1 = xx1) where (y2 is not null); ---Testcase 108: +--Testcase 118: select * from (x left join y on (x1 = y1)) left join x xx(xx1,xx2) on (x1 = xx1) where (xx2 is not null); @@ -521,7 +562,7 @@ on (x1 = xx1) where (xx2 is not null); -- regression test: check for bug with propagation of implied equality -- to outside an IN -- ---Testcase 109: +--Testcase 119: select count(*) from tenk1 a where unique1 in (select unique1 from tenk1 b join tenk1 c using (unique1) where b.unique2 = 42); @@ -530,7 +571,7 @@ select count(*) from tenk1 a where unique1 in -- regression test: check for failure to generate a plan with multiple -- degenerate IN clauses -- ---Testcase 110: +--Testcase 120: 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 @@ -538,11 +579,11 @@ select count(*) from tenk1 x where -- try that with GEQO too begin; ---Testcase 111: +--Testcase 121: set geqo = on; ---Testcase 112: +--Testcase 122: set geqo_threshold = 2; ---Testcase 113: +--Testcase 123: 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 @@ -552,41 +593,41 @@ rollback; -- -- regression test: be sure we cope with proven-dummy append rels -- ---Testcase 114: -create table b (aa int, bb int); +--Testcase 124: +CREATE FOREIGN TABLE b_star(class char, aa int4, bb text, a int4) SERVER influxdb_svr; ---Testcase 115: +--Testcase 125: explain (costs off) select aa, bb, unique1, unique1 - from tenk1 right join b on aa = unique1 + from tenk1 right join b_star on aa = unique1 where bb < bb and bb is null; ---Testcase 116: +--Testcase 126: select aa, bb, unique1, unique1 - from tenk1 right join b on aa = unique1 + from tenk1 right join b_star on aa = unique1 where bb < bb and bb is null; ---Testcase 117: -drop table b; +--Testcase 127: +drop foreign table b_star; -- -- regression test: check handling of empty-FROM subquery underneath outer join -- ---Testcase 118: +--Testcase 128: 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; ---Testcase 119: +--Testcase 129: 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; -- --- regression test: check a case where join_clause_is_movable_into() gives --- an imprecise result, causing an assertion failure +-- regression test: check a case where join_clause_is_movable_into() +-- used to give an imprecise result, causing an assertion failure -- ---Testcase 120: +--Testcase 130: select count(*) from (select t3.tenthous as x1, coalesce(t1.stringu1, t2.stringu1) as x2 @@ -601,7 +642,7 @@ where t4.thousand = t5.unique1 and ss.x1 = t4.tenthous and ss.x2 = t5.stringu1; -- regression test: check a case where we formerly missed including an EC -- enforcement clause because it was expected to be handled at scan level -- ---Testcase 121: +--Testcase 131: explain (costs off) select a.f1, b.f1, t.thousand, t.tenthous from tenk1 t, @@ -609,25 +650,134 @@ select a.f1, b.f1, t.thousand, t.tenthous from (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; ---Testcase 122: +--Testcase 132: 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; +-- +-- 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; + +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; + +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; + +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; + +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; + +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; + +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; + +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); + +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; + +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; + +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; + +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; + +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; + +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; + +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; + +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; + -- -- check a case where we formerly got confused by conflicting sort orders -- in redundant merge join path keys -- ---Testcase 123: +--Testcase 133: 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; ---Testcase 124: +--Testcase 134: select * from j1_tbl full join (select * from j2_tbl order by j2_tbl.i desc, j2_tbl.k asc) j2_tbl @@ -636,7 +786,7 @@ select * from -- -- a different check for handling of redundant sort keys in merge joins -- ---Testcase 125: +--Testcase 135: explain (costs off) select count(*) from (select * from tenk1 x order by x.thousand, x.twothousand, x.fivethous) x @@ -644,196 +794,291 @@ select count(*) from (select * from tenk1 y order by y.unique2) y on x.thousand = y.unique2 and x.twothousand = y.hundred and x.fivethous = y.unique2; ---Testcase 126: +--Testcase 136: 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; +set enable_hashjoin = 0; +set enable_nestloop = 0; +set enable_hashagg = 0; + +-- +-- 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; + +reset enable_hashagg; +reset enable_nestloop; +reset enable_hashjoin; -- -- Clean up -- ---Testcase 127: +--Testcase 137: DELETE FROM t1; ---Testcase 128: +--Testcase 138: DELETE FROM t2; ---Testcase 129: +--Testcase 139: DELETE FROM t3; ---Testcase 130: +--Testcase 140: DROP FOREIGN TABLE t1; ---Testcase 131: +--Testcase 141: DROP FOREIGN TABLE t2; ---Testcase 132: +--Testcase 142: DROP FOREIGN TABLE t3; ---Testcase 133: +--Testcase 143: DELETE FROM J1_TBL; +--Testcase 575: DROP FOREIGN TABLE J1_TBL; ---Testcase 134: +--Testcase 144: DELETE FROM J2_TBL; +--Testcase 576: DROP FOREIGN TABLE J2_TBL; +--Testcase 577: DELETE FROM x; +--Testcase 578: DELETE FROM y; +--Testcase 579: DROP FOREIGN TABLE x; +--Testcase 580: DROP FOREIGN TABLE y; -- Both DELETE and UPDATE allow the specification of additional tables -- to "join" against to determine which rows should be modified. ---Testcase 135: +--Testcase 145: CREATE FOREIGN TABLE t1 (a int, b int) SERVER influxdb_svr; ---Testcase 136: +--Testcase 146: CREATE FOREIGN TABLE t2 (a int, b int) SERVER influxdb_svr; ---Testcase 137: +--Testcase 147: CREATE FOREIGN TABLE t3 (x int, y int) SERVER influxdb_svr; ---Testcase 138: +--Testcase 148: INSERT INTO t1 VALUES (5, 10); ---Testcase 139: +--Testcase 149: INSERT INTO t1 VALUES (15, 20); ---Testcase 140: +--Testcase 150: INSERT INTO t1 VALUES (100, 100); ---Testcase 141: +--Testcase 151: INSERT INTO t1 VALUES (200, 1000); ---Testcase 142: +--Testcase 152: INSERT INTO t2 VALUES (200, 2000); ---Testcase 143: +--Testcase 153: INSERT INTO t3 VALUES (5, 20); ---Testcase 144: +--Testcase 154: INSERT INTO t3 VALUES (6, 7); ---Testcase 145: +--Testcase 155: INSERT INTO t3 VALUES (7, 8); ---Testcase 146: +--Testcase 156: INSERT INTO t3 VALUES (500, 100); ---Testcase 147: +--Testcase 157: ALTER TABLE t3 ADD time timestamp; ---Testcase 148: +--Testcase 158: SELECT x, y FROM t3; ---Testcase 149: +--Testcase 159: DELETE FROM t3 USING t1 table1 WHERE t3.x = table1.a; ---Testcase 150: +--Testcase 160: SELECT x, y FROM t3; ---Testcase 151: +--Testcase 161: DELETE FROM t3 USING t1 JOIN t2 USING (a) WHERE t3.x > t1.a; ---Testcase 152: +--Testcase 162: SELECT x, y FROM t3; ---Testcase 153: +--Testcase 163: DELETE FROM t3 USING t3 t3_other WHERE t3.x = t3_other.x AND t3.y = t3_other.y; ---Testcase 154: +--Testcase 164: SELECT x, y FROM t3; -- Test join against inheritance tree ---Testcase 155: +--Testcase 165: create temp table t2a () inherits (t2); ---Testcase 156: +--Testcase 166: insert into t2a values (200, 2001); ---Testcase 157: +--Testcase 167: select * from t1 left join t2 on (t1.a = t2.a); -- Test matching of column name with wrong alias ---Testcase 158: +--Testcase 168: select t1.x from t1 join t3 on (t1.a = t3.x); +-- Test matching of locking clause with wrong alias + +--Testcase 602: +select t1.*, t2.*, unnamed_join.* from + t1 join t2 on (t1.a = t2.a), t3 as unnamed_join + for update of unnamed_join; + +--Testcase 603: +select foo.*, unnamed_join.* from + t1 join t2 using (a) as foo, t3 as unnamed_join + for update of unnamed_join; + +--Testcase 604: +select foo.*, unnamed_join.* from + t1 join t2 using (a) as foo, t3 as unnamed_join + for update of foo; + +--Testcase 605: +select bar.*, unnamed_join.* from + (t1 join t2 using (a) as foo) as bar, t3 as unnamed_join + for update of foo; + +--Testcase 606: +select bar.*, unnamed_join.* from + (t1 join t2 using (a) as foo) as bar, t3 as unnamed_join + for update of bar; + -- -- regression test for 8.1 merge right join bug -- ---Testcase 159: +--Testcase 169: CREATE FOREIGN TABLE tt1 ( tt1_id int4, joincol int4 ) SERVER influxdb_svr; ---Testcase 160: +--Testcase 170: INSERT INTO tt1 VALUES (1, 11); ---Testcase 161: +--Testcase 171: INSERT INTO tt1 VALUES (2, NULL); ---Testcase 162: +--Testcase 172: CREATE FOREIGN TABLE tt2 ( tt2_id int4, joincol int4 ) SERVER influxdb_svr; ---Testcase 163: +--Testcase 173: INSERT INTO tt2 VALUES (21, 11); ---Testcase 164: +--Testcase 174: INSERT INTO tt2 VALUES (22, 11); ---Testcase 165: +--Testcase 175: set enable_hashjoin to off; ---Testcase 166: +--Testcase 176: set enable_nestloop to off; -- these should give the same results ---Testcase 167: +--Testcase 177: select tt1.*, tt2.* from tt1 left join tt2 on tt1.joincol = tt2.joincol; ---Testcase 168: +--Testcase 178: select tt1.*, tt2.* from tt2 right join tt1 on tt1.joincol = tt2.joincol; ---Testcase 169: +--Testcase 179: reset enable_hashjoin; ---Testcase 170: +--Testcase 180: reset enable_nestloop; -- -- regression test for bug #13908 (hash join with skew tuples & nbatch increase) -- ---Testcase 171: +--Testcase 181: set work_mem to '64kB'; ---Testcase 172: +--Testcase 182: set enable_mergejoin to off; +--Testcase 183: +set enable_memoize to off; ---Testcase 173: +--Testcase 184: explain (costs off) select count(*) from tenk1 a, tenk1 b where a.hundred = b.thousand and (b.fivethous % 10) < 10; ---Testcase 174: +--Testcase 185: select count(*) from tenk1 a, tenk1 b where a.hundred = b.thousand and (b.fivethous % 10) < 10; ---Testcase 175: +--Testcase 186: reset work_mem; ---Testcase 176: +--Testcase 187: reset enable_mergejoin; +--Testcase 188: +reset enable_memoize; -- -- regression test for 8.2 bug with improper re-ordering of left joins -- ---Testcase 177: +--Testcase 189: create foreign table tt3(f1 int, f2 text) server influxdb_svr; ---Testcase 178: +--Testcase 190: insert into tt3 select x, repeat('xyzzy', 100) from generate_series(1,10000) x; ---Testcase 179: +--Testcase 191: create foreign table tt4(f1 int) server influxdb_svr; ---Testcase 180: +--Testcase 192: insert into tt4 values (0),(1),(9999); ---Testcase 181: +set enable_nestloop to off; + +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; + SELECT a.f1 FROM tt4 a LEFT JOIN ( SELECT b.f1 FROM tt3 b LEFT JOIN tt3 c ON (b.f1 = c.f1) - WHERE c.f1 IS NULL + WHERE COALESCE(c.f1, 0) = 0 ) AS d ON (a.f1 = d.f1) -WHERE d.f1 IS NULL; +WHERE COALESCE(d.f1, 0) = 0 +ORDER BY 1; + +reset enable_nestloop; + +-- +-- basic semijoin and antijoin recognition tests +-- + +explain (costs off) +select a.* from tenk1 a +where unique1 in (select unique2 from tenk1 b); + +-- sadly, this is not an antijoin +explain (costs off) +select a.* from tenk1 a +where unique1 not in (select unique2 from tenk1 b); + +explain (costs off) +select a.* from tenk1 a +where exists (select 1 from tenk1 b where a.unique1 = b.unique2); + +explain (costs off) +select a.* from tenk1 a +where not exists (select 1 from tenk1 b where a.unique1 = b.unique2); + +explain (costs off) +select a.* from tenk1 a left join tenk1 b on a.unique1 = b.unique2 +where b.unique2 is null; -- -- regression test for proper handling of outer joins within antijoins -- ---Testcase 182: +--Testcase 194: create foreign table tt4x(c1 int, c2 int, c3 int) server influxdb_svr; ---Testcase 183: +--Testcase 195: explain (costs off) select * from tt4x t1 where not exists ( @@ -849,50 +1094,50 @@ where not exists ( -- regression test for problems of the sort depicted in bug #3494 -- ---Testcase 184: +--Testcase 196: create foreign table tt5(f1 int, f2 int) server influxdb_svr; ---Testcase 185: +--Testcase 197: create foreign table tt6(f1 int, f2 int) server influxdb_svr; ---Testcase 186: +--Testcase 198: insert into tt5 values(1, 10); ---Testcase 187: +--Testcase 199: insert into tt5 values(1, 11); ---Testcase 188: +--Testcase 200: insert into tt6 values(1, 9); ---Testcase 189: +--Testcase 201: insert into tt6 values(1, 2); ---Testcase 190: +--Testcase 202: insert into tt6 values(2, 9); ---Testcase 191: +--Testcase 203: select * from tt5,tt6 where tt5.f1 = tt6.f1 and tt5.f1 = tt5.f2 - tt6.f2; -- -- regression test for problems of the sort depicted in bug #3588 -- ---Testcase 192: +--Testcase 204: create foreign table xx (pkxx int) server influxdb_svr; ---Testcase 193: +--Testcase 205: create foreign table yy (pkyy int, pkxx int) server influxdb_svr; ---Testcase 194: +--Testcase 206: insert into xx values (1); ---Testcase 195: +--Testcase 207: insert into xx values (2); ---Testcase 196: +--Testcase 208: insert into xx values (3); ---Testcase 197: +--Testcase 209: insert into yy values (101, 1); ---Testcase 198: +--Testcase 210: insert into yy values (201, 2); ---Testcase 199: +--Testcase 211: insert into yy values (301, NULL); ---Testcase 200: +--Testcase 212: 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 @@ -905,27 +1150,27 @@ from yy -- (as seen in early 8.2.x releases) -- ---Testcase 201: +--Testcase 213: create foreign table zt1 (f1 int) server influxdb_svr; ---Testcase 202: +--Testcase 214: create foreign table zt2 (f2 int) server influxdb_svr; ---Testcase 203: +--Testcase 215: create foreign table zt3 (f3 int) server influxdb_svr; ---Testcase 204: +--Testcase 216: insert into zt1 values(53); ---Testcase 205: +--Testcase 217: insert into zt2 values(53); ---Testcase 206: +--Testcase 218: select * from zt2 left join zt3 on (f2 = f3) left join zt1 on (f3 = f1) where f2 = 53; ---Testcase 207: +--Testcase 219: create temp view zv1 as select *,'dummy'::text AS junk from zt1; ---Testcase 208: +--Testcase 220: select * from zt2 left join zt3 on (f2 = f3) left join zv1 on (f3 = f1) @@ -936,7 +1181,7 @@ where f2 = 53; -- (as seen in early 8.3.x releases) -- ---Testcase 209: +--Testcase 221: 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 @@ -945,14 +1190,14 @@ where a.unique1 = 42 and -- -- test proper positioning of one-time quals in EXISTS (8.4devel bug) -- ---Testcase 210: +--Testcase 222: 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)); ---Testcase 211: +--Testcase 223: execute foo(true); ---Testcase 212: +--Testcase 224: execute foo(false); -- @@ -961,24 +1206,24 @@ execute foo(false); begin; ---Testcase 213: +--Testcase 225: set enable_mergejoin = 1; ---Testcase 214: +--Testcase 226: set enable_hashjoin = 0; ---Testcase 215: +--Testcase 227: set enable_nestloop = 0; ---Testcase 216: +--Testcase 228: create foreign table a (i integer) server influxdb_svr; ---Testcase 217: +--Testcase 229: create foreign table b (x integer, y integer) server influxdb_svr; ---Testcase 218: +--Testcase 230: select * from a left join b on i = x and i = y and x = i; ---Testcase 219: +--Testcase 231: DROP FOREIGN TABLE a; ---Testcase 220: +--Testcase 232: DROP FOREIGN TABLE b; rollback; @@ -987,24 +1232,24 @@ rollback; -- begin; ---Testcase 221: +--Testcase 233: create type mycomptype as (id int, v bigint); ---Testcase 222: +--Testcase 234: create temp table tidv (idv mycomptype); ---Testcase 223: +--Testcase 235: create index on tidv (idv); ---Testcase 224: +--Testcase 236: explain (costs off) select a.idv, b.idv from tidv a, tidv b where a.idv = b.idv; ---Testcase 225: +--Testcase 237: set enable_mergejoin = 0; ---Testcase 226: +--Testcase 238: set enable_hashjoin = 0; ---Testcase 227: +--Testcase 239: explain (costs off) select a.idv, b.idv from tidv a, tidv b where a.idv = b.idv; @@ -1013,22 +1258,22 @@ rollback; -- -- test NULL behavior of whole-row Vars, per bug #5025 -- ---Testcase 228: +--Testcase 240: 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; ---Testcase 229: +--Testcase 241: 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; ---Testcase 230: +--Testcase 242: 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; ---Testcase 231: +--Testcase 243: 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 @@ -1040,37 +1285,37 @@ group by t1.q2 order by 1; -- begin; ---Testcase 232: +--Testcase 244: create foreign table a ( code char ) server influxdb_svr; ---Testcase 233: +--Testcase 245: create foreign table b ( a char, num integer ) server influxdb_svr; ---Testcase 234: +--Testcase 246: create foreign table c ( name char, a char ) server influxdb_svr; ---Testcase 235: +--Testcase 247: insert into a (code) values ('p'); ---Testcase 236: +--Testcase 248: insert into a (code) values ('q'); ---Testcase 237: +--Testcase 249: insert into b (a, num) values ('p', 1); ---Testcase 238: +--Testcase 250: insert into b (a, num) values ('p', 2); ---Testcase 239: +--Testcase 251: insert into c (name, a) values ('A', 'p'); ---Testcase 240: +--Testcase 252: insert into c (name, a) values ('B', 'q'); ---Testcase 241: +--Testcase 253: insert into c (name, a) values ('C', null); ---Testcase 242: +--Testcase 254: 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 @@ -1081,17 +1326,17 @@ from c left join on (c.a = ss.code) order by c.name; ---Testcase 243: +--Testcase 255: DELETE FROM a; ---Testcase 244: +--Testcase 256: DELETE FROM b; ---Testcase 245: +--Testcase 257: DELETE FROM c; ---Testcase 246: +--Testcase 258: DROP FOREIGN TABLE a; ---Testcase 247: +--Testcase 259: DROP FOREIGN TABLE b; ---Testcase 248: +--Testcase 260: DROP FOREIGN TABLE c; rollback; @@ -1099,7 +1344,7 @@ rollback; -- test incorrect handling of placeholders that only appear in targetlists, -- per bug #6154 -- ---Testcase 249: +--Testcase 261: SELECT * FROM ( SELECT 1 as key1 ) sub1 LEFT JOIN @@ -1117,7 +1362,7 @@ LEFT JOIN ON sub1.key1 = sub2.key3; -- test the path using join aliases, too ---Testcase 250: +--Testcase 262: SELECT * FROM ( SELECT 1 as key1 ) sub1 LEFT JOIN @@ -1138,7 +1383,7 @@ ON sub1.key1 = sub2.key3; -- test case where a PlaceHolderVar is used as a nestloop parameter -- ---Testcase 251: +--Testcase 263: EXPLAIN (COSTS OFF) SELECT qq, unique1 FROM @@ -1148,7 +1393,7 @@ SELECT qq, unique1 USING (qq) INNER JOIN tenk1 c ON qq = unique2; ---Testcase 252: +--Testcase 264: SELECT qq, unique1 FROM ( SELECT COALESCE(q1, 0) AS qq FROM int8_tbl a ) AS ss1 @@ -1161,46 +1406,46 @@ SELECT qq, unique1 -- nested nestloops can require nested PlaceHolderVars -- ---Testcase 253: +--Testcase 265: create foreign table nt1 ( id int, a1 boolean, a2 boolean ) server influxdb_svr; ---Testcase 254: +--Testcase 266: create foreign table nt2 ( id int, nt1_id int, b1 boolean, b2 boolean ) server influxdb_svr; ---Testcase 255: +--Testcase 267: create foreign table nt3 ( id int, nt2_id int, c1 boolean ) server influxdb_svr; ---Testcase 256: +--Testcase 268: insert into nt1 values (1,true,true); ---Testcase 257: +--Testcase 269: insert into nt1 values (2,true,false); ---Testcase 258: +--Testcase 270: insert into nt1 values (3,false,false); ---Testcase 259: +--Testcase 271: insert into nt2 values (1,1,true,true); ---Testcase 260: +--Testcase 272: insert into nt2 values (2,2,true,false); ---Testcase 261: +--Testcase 273: insert into nt2 values (3,3,false,false); ---Testcase 262: +--Testcase 274: insert into nt3 values (1,1,true); ---Testcase 263: +--Testcase 275: insert into nt3 values (2,2,false); ---Testcase 264: +--Testcase 276: insert into nt3 values (3,3,true); ---Testcase 265: +--Testcase 277: explain (costs off) select nt3.id from nt3 as nt3 @@ -1214,7 +1459,7 @@ from nt3 as nt3 on ss2.id = nt3.nt2_id where nt3.id = 1 and ss2.b3; ---Testcase 266: +--Testcase 278: select nt3.id from nt3 as nt3 left join @@ -1231,7 +1476,7 @@ where nt3.id = 1 and ss2.b3; -- test case where a PlaceHolderVar is propagated into a subquery -- ---Testcase 267: +--Testcase 279: explain (costs off) select * from int8_tbl t1 left join @@ -1241,7 +1486,7 @@ where 1 = (select 1 from int8_tbl t3 where ss.y is not null limit 1) order by 1,2; ---Testcase 268: +--Testcase 280: select * from int8_tbl t1 left join (select q1 as x, 42 as y from int8_tbl t2) ss @@ -1254,7 +1499,7 @@ order by 1,2; -- variant where a PlaceHolderVar is needed at a join, but not above the join -- ---Testcase 269: +--Testcase 281: explain (costs off) select * from int4_tbl as i41, @@ -1267,7 +1512,7 @@ select * from where ss1.loc = ss1.lat) as ss2 where i41.f1 > 0; ---Testcase 270: +--Testcase 282: select * from int4_tbl as i41, lateral @@ -1282,28 +1527,28 @@ where i41.f1 > 0; -- -- test the corner cases FULL JOIN ON TRUE and FULL JOIN ON FALSE -- ---Testcase 271: +--Testcase 283: select * from int4_tbl a full join int4_tbl b on true; ---Testcase 272: +--Testcase 284: select * from int4_tbl a full join int4_tbl b on false; -- -- test for ability to use a cartesian join when necessary -- ---Testcase 273: +--Testcase 285: create foreign table q1 (q1 int) server influxdb_svr; ---Testcase 274: +--Testcase 286: create foreign table q2 (q2 int) server influxdb_svr; ---Testcase 275: +--Testcase 287: explain (costs off) select * from tenk1 join int4_tbl on f1 = twothousand, q1, q2 where q1 = thousand or q2 = thousand; ---Testcase 276: +--Testcase 288: explain (costs off) select * from tenk1 join int4_tbl on f1 = twothousand, @@ -1314,7 +1559,7 @@ where thousand = (q1 + q2); -- test ability to generate a suitable plan for a star-schema query -- ---Testcase 277: +--Testcase 289: explain (costs off) select * from tenk1, int8_tbl a, int8_tbl b @@ -1324,7 +1569,7 @@ where thousand = a.q1 and tenthous = b.q1 and a.q2 = 1 and b.q2 = 2; -- test a corner case in which we shouldn't apply the star-schema optimization -- ---Testcase 278: +--Testcase 290: explain (costs off) select t1.unique2, t1.stringu1, t2.unique1, t2.stringu2 from tenk1 t1 @@ -1339,7 +1584,7 @@ select t1.unique2, t1.stringu1, t2.unique1, t2.stringu2 from on (subq1.y1 = t2.unique1) where t1.unique2 < 42 and t1.stringu1 > t2.stringu2; ---Testcase 279: +--Testcase 291: select t1.unique2, t1.stringu1, t2.unique1, t2.stringu2 from tenk1 t1 inner join int4_tbl i1 @@ -1355,7 +1600,7 @@ where t1.unique2 < 42 and t1.stringu1 > t2.stringu2; -- variant that isn't quite a star-schema case ---Testcase 280: +--Testcase 292: select ss1.d1 from tenk1 as t1 inner join tenk1 as t2 @@ -1374,7 +1619,7 @@ where t1.unique1 < i4.f1; -- this variant is foldable by the remove-useless-RESULT-RTEs code ---Testcase 281: +--Testcase 293: explain (costs off) select t1.unique2, t1.stringu1, t2.unique1, t2.stringu2 from tenk1 t1 @@ -1389,7 +1634,7 @@ select t1.unique2, t1.stringu1, t2.unique1, t2.stringu2 from on (subq1.y1 = t2.unique1) where t1.unique2 < 42 and t1.stringu1 > t2.stringu2; ---Testcase 282: +--Testcase 294: select t1.unique2, t1.stringu1, t2.unique1, t2.stringu2 from tenk1 t1 inner join int4_tbl i1 @@ -1405,18 +1650,18 @@ where t1.unique2 < 42 and t1.stringu1 > t2.stringu2; -- Here's a variant that we can't fold too aggressively, though, -- or we end up with noplace to evaluate the lateral PHV ---Testcase 283: +--Testcase 295: 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; ---Testcase 284: +--Testcase 296: 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; -- Test proper handling of appendrel PHVs during useless-RTE removal ---Testcase 285: +--Testcase 297: explain (costs off) select * from (select 0 as z) as t1 @@ -1428,7 +1673,7 @@ select * from select a as b) as t3 where b; ---Testcase 286: +--Testcase 298: select * from (select 0 as z) as t1 left join @@ -1439,56 +1684,85 @@ select * from select a as b) as t3 where b; +-- 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 ); + +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 ); + +-- 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; + +-- 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; + -- -- test inlining of immutable functions -- ---Testcase 287: +--Testcase 299: create function f_immutable_int4(i integer) returns integer as $$ begin return i; end; $$ language plpgsql immutable; -- check optimization of function scan with join ---Testcase 288: +--Testcase 300: explain (costs off) select unique1 from tenk1, (select * from f_immutable_int4(1) x) x where x = unique1; ---Testcase 289: +--Testcase 301: explain (verbose, costs off) select unique1, x.* from tenk1, (select *, random() from f_immutable_int4(1) x) x where x = unique1; ---Testcase 290: +--Testcase 302: explain (costs off) select unique1 from tenk1, f_immutable_int4(1) x where x = unique1; ---Testcase 291: +--Testcase 303: explain (costs off) select unique1 from tenk1, lateral f_immutable_int4(1) x where x = unique1; ---Testcase 292: +--Testcase 569: +explain (costs off) +select unique1 from tenk1, lateral f_immutable_int4(1) x where x in (select 17); + +--Testcase 304: explain (costs off) select unique1, x from tenk1 join f_immutable_int4(1) x on unique1 = x; ---Testcase 293: +--Testcase 305: explain (costs off) select unique1, x from tenk1 left join f_immutable_int4(1) x on unique1 = x; ---Testcase 294: +--Testcase 306: explain (costs off) select unique1, x from tenk1 right join f_immutable_int4(1) x on unique1 = x; ---Testcase 295: +--Testcase 307: explain (costs off) select unique1, x from tenk1 full join f_immutable_int4(1) x on unique1 = x; -- check that pullup of a const function allows further const-folding ---Testcase 296: +--Testcase 308: explain (costs off) select unique1 from tenk1, f_immutable_int4(1) x where x = 42; -- test inlining of immutable functions with PlaceHolderVars ---Testcase 297: +--Testcase 309: explain (costs off) select nt3.id from nt3 as nt3 @@ -1502,34 +1776,34 @@ from nt3 as nt3 on ss2.id = nt3.nt2_id where nt3.id = 1 and ss2.b3; ---Testcase 298: +--Testcase 310: drop function f_immutable_int4(int); -- test inlining when function returns composite ---Testcase 299: +--Testcase 311: create function mki8(bigint, bigint) returns int8_tbl as $$select row($1,$2)::int8_tbl$$ language sql; ---Testcase 300: +--Testcase 312: create function mki4(int) returns int4_tbl as $$select row($1)::int4_tbl$$ language sql; ---Testcase 301: +--Testcase 313: explain (verbose, costs off) select * from mki8(1,2); ---Testcase 302: +--Testcase 314: select * from mki8(1,2); ---Testcase 303: +--Testcase 315: explain (verbose, costs off) select * from mki4(42); ---Testcase 304: +--Testcase 316: select * from mki4(42); ---Testcase 305: +--Testcase 317: drop function mki8(bigint, bigint); ---Testcase 306: +--Testcase 318: drop function mki4(int); -- @@ -1537,15 +1811,15 @@ drop function mki4(int); -- (we used to only do this for indexable clauses) -- ---Testcase 307: +--Testcase 319: 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); ---Testcase 308: +--Testcase 320: 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); ---Testcase 309: +--Testcase 321: explain (costs off) select * from tenk1 a join tenk1 b on (a.unique1 = 1 and b.unique1 = 2) or @@ -1555,34 +1829,34 @@ select * from tenk1 a join tenk1 b on -- test placement of movable quals in a parameterized join tree -- ---Testcase 310: +--Testcase 322: 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; ---Testcase 311: +--Testcase 323: 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; ---Testcase 312: +--Testcase 324: 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; ---Testcase 313: +--Testcase 325: 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; ---Testcase 314: +--Testcase 326: explain (costs off) select b.unique1 from tenk1 a join tenk1 b on a.unique1 = b.unique2 @@ -1591,7 +1865,7 @@ select b.unique1 from right join int4_tbl i2 on i2.f1 = b.tenthous order by 1; ---Testcase 315: +--Testcase 327: 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 @@ -1599,7 +1873,7 @@ select b.unique1 from right join int4_tbl i2 on i2.f1 = b.tenthous order by 1; ---Testcase 316: +--Testcase 328: explain (costs off) select * from ( @@ -1609,7 +1883,7 @@ select * from where fault = 122 order by fault; ---Testcase 317: +--Testcase 329: select * from ( select unique1, q1, coalesce(unique1, -1) + q1 as fault @@ -1618,14 +1892,14 @@ select * from where fault = 122 order by fault; ---Testcase 318: +--Testcase 330: 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; ---Testcase 319: +--Testcase 331: 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 @@ -1635,24 +1909,24 @@ left join unnest(v1ys) as u1(u1y) on u1y = v2y; -- test handling of potential equivalence clauses above outer joins -- ---Testcase 320: +--Testcase 332: 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); ---Testcase 321: +--Testcase 333: 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); ---Testcase 322: +--Testcase 334: 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; ---Testcase 323: +--Testcase 335: 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; @@ -1661,22 +1935,31 @@ select f1, unique2, case when unique2 is null then f1 else 0 end -- another case with equivalence clauses above outer joins (bug #8591) -- ---Testcase 324: +--Testcase 336: 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; ---Testcase 325: +--Testcase 337: 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; +-- 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; + +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; + -- -- check handling of join aliases when flattening multiple levels of subquery -- ---Testcase 326: +--Testcase 338: 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) @@ -1691,7 +1974,7 @@ left join ) foo3 using (join_key); ---Testcase 327: +--Testcase 339: select foo1.join_key as foo1_id, foo3.join_key AS foo3_id, bug_field from (values (0),(1)) foo1(join_key) left join @@ -1705,13 +1988,37 @@ left join ) foo3 using (join_key); +-- +-- 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; + +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; + -- -- test successful handling of nested outer joins with degenerate join quals -- ---Testcase 328: +--Testcase 340: create foreign table text_tbl(f1 text) server influxdb_svr; ---Testcase 329: +--Testcase 341: explain (verbose, costs off) select t1.* from text_tbl t1 @@ -1724,7 +2031,7 @@ select t1.* from left join int4_tbl i4 on (i8.q2 = i4.f1); ---Testcase 330: +--Testcase 342: select t1.* from text_tbl t1 left join (select *, '***'::text as d1 from int8_tbl i8b1) b1 @@ -1736,7 +2043,7 @@ select t1.* from left join int4_tbl i4 on (i8.q2 = i4.f1); ---Testcase 331: +--Testcase 343: explain (verbose, costs off) select t1.* from text_tbl t1 @@ -1749,7 +2056,7 @@ select t1.* from left join int4_tbl i4 on (i8.q2 = i4.f1); ---Testcase 332: +--Testcase 344: select t1.* from text_tbl t1 left join (select *, '***'::text as d1 from int8_tbl i8b1) b1 @@ -1761,7 +2068,7 @@ select t1.* from left join int4_tbl i4 on (i8.q2 = i4.f1); ---Testcase 333: +--Testcase 345: explain (verbose, costs off) select t1.* from text_tbl t1 @@ -1775,7 +2082,7 @@ select t1.* from left join int4_tbl i4 on (i8.q2 = i4.f1); ---Testcase 334: +--Testcase 346: select t1.* from text_tbl t1 left join (select *, '***'::text as d1 from int8_tbl i8b1) b1 @@ -1788,7 +2095,7 @@ select t1.* from left join int4_tbl i4 on (i8.q2 = i4.f1); ---Testcase 335: +--Testcase 347: explain (verbose, costs off) select * from text_tbl t1 @@ -1799,7 +2106,7 @@ select * from left join int4_tbl i4 on i8.q1 = i4.f1; ---Testcase 336: +--Testcase 348: select * from text_tbl t1 inner join int8_tbl i8 @@ -1809,11 +2116,32 @@ select * from left join int4_tbl i4 on i8.q1 = i4.f1; +-- 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; + +-- 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; + -- -- test for appropriate join order in the presence of lateral references -- ---Testcase 337: +--Testcase 349: explain (verbose, costs off) select * from text_tbl t1 @@ -1822,7 +2150,7 @@ select * from lateral (select i8.q1, t2.f1 from text_tbl t2 limit 1) as ss where t1.f1 = ss.f1; ---Testcase 338: +--Testcase 350: select * from text_tbl t1 left join int8_tbl i8 @@ -1830,7 +2158,7 @@ select * from lateral (select i8.q1, t2.f1 from text_tbl t2 limit 1) as ss where t1.f1 = ss.f1; ---Testcase 339: +--Testcase 351: explain (verbose, costs off) select * from text_tbl t1 @@ -1840,7 +2168,7 @@ select * from lateral (select ss1.* from text_tbl t3 limit 1) as ss2 where t1.f1 = ss2.f1; ---Testcase 340: +--Testcase 352: select * from text_tbl t1 left join int8_tbl i8 @@ -1849,7 +2177,7 @@ select * from lateral (select ss1.* from text_tbl t3 limit 1) as ss2 where t1.f1 = ss2.f1; ---Testcase 341: +--Testcase 353: explain (verbose, costs off) select 1 from text_tbl as tt1 @@ -1859,7 +2187,7 @@ select 1 from lateral (select tt4.f1 as c0 from text_tbl as tt5 limit 1) as ss1 where tt1.f1 = ss1.c0; ---Testcase 342: +--Testcase 354: select 1 from text_tbl as tt1 inner join text_tbl as tt2 on (tt1.f1 = 'foo') @@ -1868,11 +2196,50 @@ select 1 from lateral (select tt4.f1 as c0 from text_tbl as tt5 limit 1) as ss1 where tt1.f1 = ss1.c0; +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; + +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; + +-- +-- check a case where we formerly generated invalid parameterized paths +-- + +begin; + +CREATE FOREIGN TABLE temp_t (a int) SERVER influxdb_svr; + +explain (costs off) +select 1 from temp_t t1 + join lateral (select t1.a from (select 1) foo offset 0) as s1 on true + join + (select 1 from temp_t t2 + inner join (temp_t t3 + left join (temp_t t4 left join temp_t t5 on t4.a = 1) + on t3.a = t4.a) + on false + where t3.a = coalesce(t5.a,1)) as s2 + on true; + +rollback; + -- -- check a case in which a PlaceHolderVar forces join order -- ---Testcase 343: +--Testcase 355: explain (verbose, costs off) select ss2.* from int4_tbl i41 @@ -1884,7 +2251,7 @@ select ss2.* from lateral (select i41.*, i8.*, ss1.* from text_tbl limit 1) ss2 where ss1.c2 = 0; ---Testcase 344: +--Testcase 356: select ss2.* from int4_tbl i41 left join int8_tbl i8 @@ -1899,7 +2266,7 @@ where ss1.c2 = 0; -- test successful handling of full join underneath left join (bug #14105) -- ---Testcase 345: +--Testcase 357: explain (costs off) select * from (select 1 as id) as xx @@ -1907,7 +2274,7 @@ select * from (tenk1 as a1 full join (select 1 as id) as yy on (a1.unique1 = yy.id)) on (xx.id = coalesce(yy.id)); ---Testcase 346: +--Testcase 358: select * from (select 1 as id) as xx left join @@ -1918,11 +2285,11 @@ select * from -- test ability to push constants through outer join clauses -- ---Testcase 347: +--Testcase 359: explain (costs off) select * from int4_tbl a left join tenk1 b on f1 = unique2 where f1 = 0; ---Testcase 348: +--Testcase 360: explain (costs off) select * from tenk1 a full join tenk1 b using(unique2) where unique2 = 42; @@ -1932,75 +2299,226 @@ explain (costs off) -- we force a mergejoin so that coalesce(b.q1, 1) appears as a join input -- ---Testcase 349: +--Testcase 361: set enable_hashjoin to off; ---Testcase 350: +--Testcase 362: set enable_nestloop to off; ---Testcase 351: +--Testcase 363: 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; ---Testcase 352: +--Testcase 364: 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; ---Testcase 353: +--Testcase 365: reset enable_hashjoin; ---Testcase 354: +--Testcase 366: reset enable_nestloop; +-- +-- 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 = any (select q1 from int8_tbl c where c.q1 < b.unique1); + +select a.unique1, b.unique2 + from onek a left join onek b on a.unique1 = b.unique2 + where b.unique2 = any (select q1 from int8_tbl c where c.q1 < b.unique1); + +-- +-- 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; + +select a.unique1, b.unique2 + from onek a full join onek b on a.unique1 = b.unique2 + where a.unique1 = 42; + +explain (costs off) +select a.unique1, b.unique2 + from onek a full join onek b on a.unique1 = b.unique2 + where b.unique2 = 43; + +select a.unique1, b.unique2 + from onek a full join onek b on a.unique1 = b.unique2 + where b.unique2 = 43; + +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; + +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; + +-- +-- 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; + +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; + -- -- test join removal -- begin; ---Testcase 355: +--Testcase 367: CREATE FOREIGN TABLE a (id int, b_id int) SERVER influxdb_svr; ---Testcase 356: +--Testcase 368: CREATE FOREIGN TABLE b (id int, c_id int) SERVER influxdb_svr; ---Testcase 357: +--Testcase 369: CREATE FOREIGN TABLE c (id int) SERVER influxdb_svr; ---Testcase 358: +--Testcase 370: CREATE FOREIGN TABLE d (a int, b int) SERVER influxdb_svr; ---Testcase 359: +--Testcase 371: INSERT INTO a VALUES (0, 0), (1, NULL); ---Testcase 360: +--Testcase 372: INSERT INTO b VALUES (0, 0), (1, NULL); ---Testcase 361: +--Testcase 373: INSERT INTO c VALUES (0), (1); ---Testcase 362: +--Testcase 374: INSERT INTO d VALUES (1,3), (2,2), (3,1); -- all three cases should be optimizable into a simple seqscan ---Testcase 363: +--Testcase 375: explain (costs off) SELECT a.* FROM a LEFT JOIN b ON a.b_id = b.id; ---Testcase 364: +--Testcase 376: explain (costs off) SELECT b.* FROM b LEFT JOIN c ON b.c_id = c.id; ---Testcase 365: +--Testcase 377: 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); -- check optimization of outer join within another special join ---Testcase 366: +--Testcase 378: explain (costs off) select id from a where id in ( select b.id from b left join c on b.id = c.id ); +-- 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; + +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; + +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; + +-- 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; + +-- 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; + +-- 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; -- 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; + +-- 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; + +-- 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; + +-- 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; + -- check that join removal works for a left join when joining a subquery -- that is guaranteed to be unique by its GROUP BY clause ---Testcase 367: +--Testcase 379: 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; -- similarly, but keying off a DISTINCT clause ---Testcase 368: +--Testcase 380: 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; @@ -2009,97 +2527,115 @@ select d.* from d left join (select distinct * from b) s -- 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.) ---Testcase 369: +--Testcase 381: 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; -- similarly, but keying off a DISTINCT clause ---Testcase 370: +--Testcase 382: explain (costs off) select d.* from d left join (select distinct * from b) s on d.a = s.id; +-- 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; + -- check join removal works when uniqueness of the join condition is enforced -- by a UNION ---Testcase 371: +--Testcase 383: explain (costs off) select d.* from d left join (select id from a union select id from b) s on d.a = s.id; -- check join removal with a cross-type comparison operator ---Testcase 372: +--Testcase 384: 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; -- check join removal with lateral references ---Testcase 373: +--Testcase 385: 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; ---Testcase 374: +-- 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; + +CREATE TEMP TABLE parted_b (id int PRIMARY KEY) partition by range(id); +CREATE TEMP TABLE parted_b1 partition of parted_b for values from (0) to (10); + +-- 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; + +--Testcase 386: DELETE FROM a; ---Testcase 375: +--Testcase 387: DELETE FROM b; ---Testcase 376: +--Testcase 388: DELETE FROM c; ---Testcase 377: +--Testcase 389: DELETE FROM d; ---Testcase 378: +--Testcase 390: DROP FOREIGN TABLE a; ---Testcase 379: +--Testcase 391: DROP FOREIGN TABLE b; ---Testcase 380: +--Testcase 392: DROP FOREIGN TABLE c; ---Testcase 381: +--Testcase 393: DROP FOREIGN TABLE d; rollback; ---Testcase 382: +--Testcase 394: create foreign table parent (k int, pd int) server influxdb_svr; ---Testcase 383: +--Testcase 395: create foreign table child (k int, cd int) server influxdb_svr; ---Testcase 384: +--Testcase 396: insert into parent values (1, 10), (2, 20), (3, 30); ---Testcase 385: +--Testcase 397: insert into child values (1, 100), (4, 400); -- this case is optimizable ---Testcase 386: +--Testcase 398: select p.* from parent p left join child c on (p.k = c.k); ---Testcase 387: +--Testcase 399: explain (costs off) select p.* from parent p left join child c on (p.k = c.k); -- this case is not ---Testcase 388: +--Testcase 400: select p.*, linked from parent p left join (select c.*, true as linked from child c) as ss on (p.k = ss.k); ---Testcase 389: +--Testcase 401: 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); -- check for a 9.0rc1 bug: join removal breaks pseudoconstant qual handling ---Testcase 390: +--Testcase 402: select p.* from parent p left join child c on (p.k = c.k) where p.k = 1 and p.k = 2; ---Testcase 391: +--Testcase 403: 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; ---Testcase 392: +--Testcase 404: 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; ---Testcase 393: +--Testcase 405: 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 @@ -2108,39 +2644,39 @@ select p.* from -- bug 5255: this is not optimizable by join removal begin; ---Testcase 394: +--Testcase 406: CREATE FOREIGN TABLE a (id int) SERVER influxdb_svr; ---Testcase 395: +--Testcase 407: CREATE FOREIGN TABLE b (id int, a_id int) SERVER influxdb_svr; ---Testcase 396: +--Testcase 408: INSERT INTO a VALUES (0), (1); ---Testcase 397: +--Testcase 409: INSERT INTO b VALUES (0, 0), (1, NULL); ---Testcase 398: +--Testcase 410: SELECT * FROM b LEFT JOIN a ON (b.a_id = a.id) WHERE (a.id IS NULL OR a.id > 0); ---Testcase 399: +--Testcase 411: SELECT b.* FROM b LEFT JOIN a ON (b.a_id = a.id) WHERE (a.id IS NULL OR a.id > 0); ---Testcase 400: +--Testcase 412: DELETE FROM a; ---Testcase 401: +--Testcase 413: DELETE FROM b; ---Testcase 402: +--Testcase 414: DROP FOREIGN TABLE a; ---Testcase 403: +--Testcase 415: DROP FOREIGN TABLE b; rollback; -- another join removal bug: this is not optimizable, either begin; ---Testcase 404: +--Testcase 416: create foreign table innertab (id int8, dat1 int8) server influxdb_svr; ---Testcase 405: +--Testcase 417: insert into innertab values(123, 42); ---Testcase 406: +--Testcase 418: SELECT * FROM (SELECT 1 AS x) ss1 LEFT JOIN @@ -2148,8 +2684,33 @@ SELECT * FROM FROM int8_tbl LEFT JOIN innertab ON q2 = id) ss2 ON true; +-- 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; + +-- 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; + +-- 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; + -- Clean up +--Testcase 581: DELETE FROM innertab; +--Testcase 582: DROP FOREIGN TABLE innertab; rollback; @@ -2157,10 +2718,10 @@ rollback; -- another join removal bug: we must clean up correctly when removing a PHV begin; ---Testcase 407: +--Testcase 419: create foreign table uniquetbl (f1 text) server influxdb_svr; ---Testcase 408: +--Testcase 420: explain (costs off) select t1.* from uniquetbl as t1 @@ -2169,7 +2730,7 @@ select t1.* from left join uniquetbl t3 on t2.d1 = t3.f1; ---Testcase 409: +--Testcase 421: explain (costs off) select t0.* from @@ -2183,7 +2744,7 @@ from on t0.f1 = ss.case1 where ss.stringu2 !~* ss.case1; ---Testcase 410: +--Testcase 422: select t0.* from text_tbl t0 @@ -2198,8 +2759,69 @@ where ss.stringu2 !~* ss.case1; rollback; +-- another join removal bug: we must clean up EquivalenceClasses too +begin; + +create foreign table t (a int) server influxdb_svr OPTIONS (table 't1_eq_class'); +insert into t values (1); + +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; + +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; + +delete from t; + +rollback; + +-- test cases where we can remove a join, but not a PHV computed at it +begin; + +create foreign table t (a int, b int) server influxdb_svr OPTIONS (table 't2_eq_class'); +insert into t values (1,1), (2,2); + +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; + +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; + +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; + +delete from t; + +rollback; + -- test case to expose miscomputation of required relid set for a PHV ---Testcase 411: +--Testcase 423: explain (verbose, costs off) select i8.*, ss.v, t.unique2 from int8_tbl i8 @@ -2208,7 +2830,7 @@ select i8.*, ss.v, t.unique2 left join tenk1 t on t.unique2 = ss.v where q2 = 456; ---Testcase 412: +--Testcase 424: select i8.*, ss.v, t.unique2 from int8_tbl i8 left join int4_tbl i4 on i4.f1 = 1 @@ -2216,15 +2838,37 @@ select i8.*, ss.v, t.unique2 left join tenk1 t on t.unique2 = ss.v where q2 = 456; +-- InfluxDB does not support partition table, create local table for test +-- and check a related issue where we miscompute required relids for +-- a PHV that's been translated to a child rel +--Testcase 570: +create temp table parttbl (a integer primary key) partition by range (a); +--Testcase 571: +create temp table parttbl1 partition of parttbl for values from (1) to (100); +--Testcase 572: +insert into parttbl values (11), (12); +--Testcase 573: +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; + +--Testcase 574: +select * from + (select *, 12 as phv from parttbl) as ss + right join int4_tbl on true +where ss.a = ss.phv and f1 = 0; + -- bug #8444: we've historically allowed duplicate aliases within aliased JOINs ---Testcase 413: +--Testcase 425: select * from int8_tbl x join (int4_tbl x cross join int4_tbl y) j on q1 = f1; -- error ---Testcase 414: +--Testcase 426: select * from int8_tbl x join (int4_tbl x cross join int4_tbl y) j on q1 = y.f1; -- error ---Testcase 415: +--Testcase 427: select * from int8_tbl x join (int4_tbl x cross join int4_tbl y(ff)) j on q1 = f1; -- ok @@ -2232,228 +2876,236 @@ select * from -- Test hints given on incorrect column references are useful -- ---Testcase 416: +--Testcase 428: select t1.uunique1 from tenk1 t1 join tenk2 t2 on t1.two = t2.two; -- error, prefer "t1" suggestion ---Testcase 417: +--Testcase 429: select t2.uunique1 from tenk1 t1 join tenk2 t2 on t1.two = t2.two; -- error, prefer "t2" suggestion ---Testcase 418: +--Testcase 430: select uunique1 from tenk1 t1 join tenk2 t2 on t1.two = t2.two; -- error, suggest both at once +select ctid from + tenk1 t1 join tenk2 t2 on t1.two = t2.two; -- error, need qualification -- -- Take care to reference the correct RTE -- ---Testcase 556: +--Testcase 431: 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'; +-- 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; + -- -- Test LATERAL -- ---Testcase 419: +--Testcase 432: select unique2, x.* from tenk1 a, lateral (select * from int4_tbl b where f1 = a.unique1) x; ---Testcase 420: +--Testcase 433: explain (costs off) select unique2, x.* from tenk1 a, lateral (select * from int4_tbl b where f1 = a.unique1) x; ---Testcase 421: +--Testcase 434: select unique2, x.* from int4_tbl x, lateral (select unique2 from tenk1 where f1 = unique1) ss; ---Testcase 422: +--Testcase 435: explain (costs off) select unique2, x.* from int4_tbl x, lateral (select unique2 from tenk1 where f1 = unique1) ss; ---Testcase 423: +--Testcase 436: explain (costs off) select unique2, x.* from int4_tbl x cross join lateral (select unique2 from tenk1 where f1 = unique1) ss; ---Testcase 424: +--Testcase 437: select unique2, x.* from int4_tbl x left join lateral (select unique1, unique2 from tenk1 where f1 = unique1) ss on true; ---Testcase 425: +--Testcase 438: explain (costs off) select unique2, x.* from int4_tbl x left join lateral (select unique1, unique2 from tenk1 where f1 = unique1) ss on true; -- check scoping of lateral versus parent references -- the first of these should return int8_tbl.q2, the second int8_tbl.q1 ---Testcase 426: +--Testcase 439: select *, (select r from (select q1 as q2) x, (select q2 as r) y) from int8_tbl; ---Testcase 427: +--Testcase 440: select *, (select r from (select q1 as q2) x, lateral (select q2 as r) y) from int8_tbl; -- lateral with function in FROM ---Testcase 428: +--Testcase 441: select count(*) from tenk1 a, lateral generate_series(1,two) g; ---Testcase 429: +--Testcase 442: explain (costs off) select count(*) from tenk1 a, lateral generate_series(1,two) g; ---Testcase 430: +--Testcase 443: explain (costs off) select count(*) from tenk1 a cross join lateral generate_series(1,two) g; -- don't need the explicit LATERAL keyword for functions ---Testcase 431: +--Testcase 444: explain (costs off) select count(*) from tenk1 a, generate_series(1,two) g; -- lateral with UNION ALL subselect ---Testcase 432: +--Testcase 445: 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; ---Testcase 433: +--Testcase 446: 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; -- lateral with VALUES ---Testcase 434: +--Testcase 447: explain (costs off) select count(*) from tenk1 a, tenk1 b join lateral (values(a.unique1)) ss(x) on b.unique2 = ss.x; ---Testcase 435: +--Testcase 448: select count(*) from tenk1 a, tenk1 b join lateral (values(a.unique1)) ss(x) on b.unique2 = ss.x; -- lateral with VALUES, no flattening possible ---Testcase 436: +--Testcase 449: explain (costs off) select count(*) from tenk1 a, tenk1 b join lateral (values(a.unique1),(-1)) ss(x) on b.unique2 = ss.x; ---Testcase 437: +--Testcase 450: select count(*) from tenk1 a, tenk1 b join lateral (values(a.unique1),(-1)) ss(x) on b.unique2 = ss.x; -- lateral injecting a strange outer join condition ---Testcase 438: +--Testcase 451: 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; ---Testcase 439: +--Testcase 452: 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; -- lateral reference to a join alias variable ---Testcase 440: +--Testcase 453: select * from (select f1/2 as x from int4_tbl) ss1 join int4_tbl i4 on x = f1, lateral (select x) ss2(y); ---Testcase 441: +--Testcase 454: select * from (select f1 as x from int4_tbl) ss1 join int4_tbl i4 on x = f1, lateral (values(x)) ss2(y); ---Testcase 442: +--Testcase 455: select * from ((select f1/2 as x from int4_tbl) ss1 join int4_tbl i4 on x = f1) j, lateral (select x) ss2(y); -- lateral references requiring pullup ---Testcase 443: +--Testcase 456: select * from (values(1)) x(lb), lateral generate_series(lb,4) x4; ---Testcase 444: +--Testcase 457: select * from (select f1/1000000000 from int4_tbl) x(lb), lateral generate_series(lb,4) x4; ---Testcase 445: +--Testcase 458: select * from (values(1)) x(lb), lateral (values(lb)) y(lbcopy); ---Testcase 446: +--Testcase 459: select * from (values(1)) x(lb), lateral (select lb from int4_tbl) y(lbcopy); ---Testcase 447: +--Testcase 460: 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); ---Testcase 448: +--Testcase 461: 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); ---Testcase 449: +--Testcase 462: 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); ---Testcase 450: +--Testcase 463: 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); ---Testcase 451: +--Testcase 464: 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); ---Testcase 452: +--Testcase 465: 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); ---Testcase 453: +--Testcase 466: 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; ---Testcase 454: +--Testcase 467: select * from int8_tbl a left join lateral (select *, a.q2 as x from int8_tbl b) ss on a.q2 = ss.q1; ---Testcase 455: +--Testcase 468: 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; ---Testcase 456: +--Testcase 469: 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; -- lateral can result in join conditions appearing below their -- real semantic level ---Testcase 457: +--Testcase 470: 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; ---Testcase 458: +--Testcase 471: select * from int4_tbl i left join lateral (select * from int2_tbl j where i.f1 = j.f1) k on true; ---Testcase 459: +--Testcase 472: 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; ---Testcase 460: +--Testcase 473: select * from int4_tbl i left join lateral (select coalesce(i) from int2_tbl j where i.f1 = j.f1) k on true; ---Testcase 461: +--Testcase 474: 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; ---Testcase 462: +--Testcase 475: 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; -- lateral reference in a PlaceHolderVar evaluated at join level ---Testcase 463: +--Testcase 476: 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; ---Testcase 464: +--Testcase 477: 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 @@ -2461,7 +3113,7 @@ select * from on a.q2 = ss.bq1; -- case requiring nested PlaceHolderVars ---Testcase 465: +--Testcase 478: explain (verbose, costs off) select * from int8_tbl c left join ( @@ -2473,7 +3125,7 @@ select * from lateral (select ss2.y offset 0) ss3; -- case that breaks the old ph_may_need optimization ---Testcase 466: +--Testcase 479: explain (verbose, costs off) select c.*,a.*,ss1.q1,ss2.q1,ss3.* from int8_tbl c left join ( @@ -2487,7 +3139,7 @@ select c.*,a.*,ss1.q1,ss2.q1,ss3.* from lateral (select * from int4_tbl i where ss2.y > f1) ss3; -- check processing of postponed quals (bug #9041) ---Testcase 467: +--Testcase 480: explain (verbose, costs off) select * from (select 1 as x offset 0) x cross join (select 2 as y offset 0) y @@ -2495,18 +3147,24 @@ select * from select * from (select 3 as z offset 0) z where z.z = x.x ) zz on zz.z = y.y; +-- 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; + -- check dummy rels with lateral references (bug #15694) ---Testcase 468: +--Testcase 481: explain (verbose, costs off) select * from int8_tbl i8 left join lateral (select *, i8.q2 from int4_tbl where false) ss on true; ---Testcase 469: +--Testcase 482: 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; -- check handling of nested appendrels inside LATERAL ---Testcase 470: +--Testcase 483: select * from ((select 2 as v) union all (select 3 as v)) as q1 cross join lateral @@ -2517,17 +3175,18 @@ select * from ) as q2; -- check the number of columns specified +--Testcase 601: SELECT * FROM (int8_tbl i cross join int4_tbl j) ss(a,b,c,d); -- check we don't try to do a unique-ified semijoin with LATERAL ---Testcase 471: +--Testcase 484: 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; ---Testcase 472: +--Testcase 485: select * from (values (0,9998), (1,1000)) v(id,x), lateral (select f1 from int4_tbl @@ -2536,7 +3195,7 @@ select * from -- check proper extParam/allParam handling (this isn't exactly a LATERAL issue, -- but we can make the test case much more compact with LATERAL) ---Testcase 473: +--Testcase 486: explain (verbose, costs off) select * from (values (0), (1)) v(id), lateral (select * from int8_tbl t1, @@ -2547,7 +3206,7 @@ lateral (select * from int8_tbl t1, and (select v.id=0)) offset 0) ss2) ss where t1.q1 = ss.q2) ss0; ---Testcase 474: +--Testcase 487: select * from (values (0), (1)) v(id), lateral (select * from int8_tbl t1, lateral (select * from @@ -2558,50 +3217,50 @@ lateral (select * from int8_tbl t1, where t1.q1 = ss.q2) ss0; -- test some error cases where LATERAL should have been used but wasn't ---Testcase 475: +--Testcase 488: select f1,g from int4_tbl a, (select f1 as g) ss; ---Testcase 476: +--Testcase 489: select f1,g from int4_tbl a, (select a.f1 as g) ss; ---Testcase 477: +--Testcase 490: select f1,g from int4_tbl a cross join (select f1 as g) ss; ---Testcase 478: +--Testcase 491: select f1,g from int4_tbl a cross join (select a.f1 as g) ss; -- SQL:2008 says the left table is in scope but illegal to access here ---Testcase 479: +--Testcase 492: select f1,g from int4_tbl a right join lateral generate_series(0, a.f1) g on true; ---Testcase 480: +--Testcase 493: select f1,g from int4_tbl a full join lateral generate_series(0, a.f1) g on true; -- check we complain about ambiguous table references ---Testcase 481: +--Testcase 494: select * from int8_tbl x cross join (int4_tbl x cross join lateral (select x.f1) ss); -- LATERAL can be used to put an aggregate into the FROM clause of its query ---Testcase 482: +--Testcase 495: select 1 from tenk1 a, lateral (select max(a.unique1) from int4_tbl b) ss; -- check behavior of LATERAL in UPDATE/DELETE ---Testcase 483: +--Testcase 496: create temp table xx1 as select f1 as x1, -f1 as x2 from int4_tbl; -- error, can't do this: ---Testcase 484: +--Testcase 497: update xx1 set x2 = f1 from (select * from int4_tbl where f1 = x1) ss; ---Testcase 485: +--Testcase 498: update xx1 set x2 = f1 from (select * from int4_tbl where f1 = xx1.x1) ss; -- can't do it even with LATERAL: ---Testcase 486: +--Testcase 499: update xx1 set x2 = f1 from lateral (select * from int4_tbl where f1 = x1) ss; -- we might in future allow something like this, but for now it's an error: ---Testcase 487: +--Testcase 500: update xx1 set x2 = f1 from xx1, lateral (select * from int4_tbl where f1 = x1) ss; -- also errors: ---Testcase 488: +--Testcase 501: delete from xx1 using (select * from int4_tbl where f1 = x1) ss; ---Testcase 489: +--Testcase 502: delete from xx1 using (select * from int4_tbl where f1 = xx1.x1) ss; ---Testcase 490: +--Testcase 503: delete from xx1 using lateral (select * from int4_tbl where f1 = x1) ss; /* @@ -2665,17 +3324,17 @@ rollback; begin; ---Testcase 491: +--Testcase 504: create foreign table fkest (a int, b int, c int) server influxdb_svr; ---Testcase 492: +--Testcase 505: create foreign table fkest1 (a int, b int) server influxdb_svr; ---Testcase 493: +--Testcase 506: insert into fkest select x/10, x%10, x from generate_series(1,1000) x; ---Testcase 494: +--Testcase 507: insert into fkest1 select x/10, x%10 from generate_series(1,1000) x; ---Testcase 495: +--Testcase 508: explain (costs off) select * from fkest f @@ -2690,135 +3349,144 @@ rollback; -- test planner's ability to mark joins as unique -- ---Testcase 496: +--Testcase 509: create foreign table j1 (id int) server influxdb_svr; ---Testcase 497: +--Testcase 510: create foreign table j2 (id int) server influxdb_svr; ---Testcase 498: +--Testcase 511: create foreign table j3 (id int) server influxdb_svr; ---Testcase 499: +--Testcase 512: insert into j1 values(1),(2),(3); ---Testcase 500: +--Testcase 513: insert into j2 values(1),(2),(3); ---Testcase 501: +--Testcase 514: insert into j3 values(1),(1); -- ensure join is properly marked as unique ---Testcase 502: +--Testcase 515: explain (verbose, costs off) select * from j1 inner join j2 on j1.id = j2.id; -- ensure join is not unique when not an equi-join ---Testcase 503: +--Testcase 516: explain (verbose, costs off) select * from j1 inner join j2 on j1.id > j2.id; -- ensure non-unique rel is not chosen as inner ---Testcase 504: +--Testcase 517: explain (verbose, costs off) select * from j1 inner join j3 on j1.id = j3.id; -- ensure left join is marked as unique ---Testcase 505: +--Testcase 518: explain (verbose, costs off) select * from j1 left join j2 on j1.id = j2.id; -- ensure right join is marked as unique ---Testcase 506: +--Testcase 519: explain (verbose, costs off) select * from j1 right join j2 on j1.id = j2.id; -- ensure full join is marked as unique ---Testcase 507: +--Testcase 520: explain (verbose, costs off) select * from j1 full join j2 on j1.id = j2.id; -- a clauseless (cross) join can't be unique ---Testcase 508: +--Testcase 521: explain (verbose, costs off) select * from j1 cross join j2; -- ensure a natural join is marked as unique ---Testcase 509: +--Testcase 522: explain (verbose, costs off) select * from j1 natural join j2; -- ensure a distinct clause allows the inner to become unique ---Testcase 510: +--Testcase 523: explain (verbose, costs off) select * from j1 inner join (select distinct id from j3) j3 on j1.id = j3.id; -- ensure group by clause allows the inner to become unique ---Testcase 511: +--Testcase 524: explain (verbose, costs off) select * from j1 inner join (select id from j3 group by id) j3 on j1.id = j3.id; ---Testcase 512: +--Testcase 525: delete from j1; ---Testcase 513: +--Testcase 526: delete from j2; ---Testcase 514: +--Testcase 527: delete from j3; ---Testcase 515: +--Testcase 528: drop foreign table j1; ---Testcase 516: +--Testcase 529: drop foreign table j2; ---Testcase 517: +--Testcase 530: drop foreign table j3; -- test more complex permutations of unique joins ---Testcase 518: +--Testcase 531: create foreign table j1 (id1 int, id2 int) server influxdb_svr; ---Testcase 519: +--Testcase 532: create foreign table j2 (id1 int, id2 int) server influxdb_svr; ---Testcase 520: +--Testcase 533: create foreign table j3 (id1 int, id2 int) server influxdb_svr; ---Testcase 521: +--Testcase 534: insert into j1 values(1,1),(1,2); ---Testcase 522: +--Testcase 535: insert into j2 values(1,1); ---Testcase 523: +--Testcase 536: insert into j3 values(1,1); -- ensure there's no unique join when not all columns which are part of the -- unique index are seen in the join clause ---Testcase 524: +--Testcase 537: explain (verbose, costs off) select * from j1 inner join j2 on j1.id1 = j2.id1; -- ensure proper unique detection with multiple join quals ---Testcase 525: +--Testcase 538: explain (verbose, costs off) select * from j1 inner join j2 on j1.id1 = j2.id1 and j1.id2 = j2.id2; -- ensure we don't detect the join to be unique when quals are not part of the -- join condition ---Testcase 526: +--Testcase 539: explain (verbose, costs off) select * from j1 inner join j2 on j1.id1 = j2.id1 where j1.id2 = 1; -- as above, but for left joins. ---Testcase 527: +--Testcase 540: explain (verbose, costs off) select * from j1 left join j2 on j1.id1 = j2.id1 where j1.id2 = 1; +-- create unique index j1_id2_idx on j1(id2) where id2 is not null; + +-- 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; + +-- drop index j1_id2_idx; + -- 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. ---Testcase 528: +--Testcase 541: set enable_nestloop to 0; ---Testcase 529: +--Testcase 542: set enable_hashjoin to 0; ---Testcase 530: +--Testcase 543: set enable_sort to 0; -- create indexes that will be preferred over the PKs to perform the join @@ -2826,85 +3494,64 @@ set enable_sort to 0; --create index j2_id1_idx on j2 (id1) where id1 % 1000 = 1; -- need an additional row in j2, if we want j2_id1_idx to be preferred ---Testcase 531: +--Testcase 544: insert into j2 values(1,2); --analyze j2; ---Testcase 532: +--Testcase 545: 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; ---Testcase 533: +--Testcase 546: 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; -- Exercise array keys mark/restore B-Tree code ---Testcase 534: +--Testcase 547: 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]); ---Testcase 535: +--Testcase 548: 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]); -- Exercise array keys "find extreme element" B-Tree code ---Testcase 536: +--Testcase 549: 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]); ---Testcase 537: +--Testcase 550: 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]); ---Testcase 538: +--Testcase 551: reset enable_nestloop; ---Testcase 539: +--Testcase 552: reset enable_hashjoin; ---Testcase 540: +--Testcase 553: reset enable_sort; ---Testcase 541: +--Testcase 554: delete from j1; ---Testcase 542: +--Testcase 555: delete from j2; ---Testcase 543: +--Testcase 556: delete from j3; ---Testcase 544: +--Testcase 557: drop foreign table j1; ---Testcase 545: +--Testcase 558: drop foreign table j2; ---Testcase 546: +--Testcase 559: drop foreign table j3; -- check that semijoin inner is not seen as unique for a portion of the outerrel ---Testcase 547: -CREATE FOREIGN 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 -) SERVER influxdb_svr; - --- check that semijoin inner is not seen as unique for a portion of the outerrel ---Testcase 548: +--Testcase 561: explain (verbose, costs off) select t1.unique1, t2.hundred from onek t1, tenk1 t2 @@ -2913,13 +3560,13 @@ where exists (select 1 from tenk1 t3 and t1.unique1 < 1; -- ... unless it actually is unique ---Testcase 549: +--Testcase 562: create table j3 as select unique1, tenthous from onek; vacuum analyze j3; ---Testcase 550: +--Testcase 563: create unique index on j3(unique1, tenthous); ---Testcase 551: +--Testcase 564: explain (verbose, costs off) select t1.unique1, t2.hundred from onek t1, tenk1 t2 @@ -2927,27 +3574,45 @@ where exists (select 1 from j3 where j3.unique1 = t1.unique1 and j3.tenthous = t2.hundred) and t1.unique1 < 1; ---Testcase 552: +--Testcase 565: drop table j3; -- Clean up +--Testcase 583: DELETE FROM t1; +--Testcase 584: DELETE FROM t2; +--Testcase 585: DELETE FROM t3; +--Testcase 586: DELETE FROM tt1; +--Testcase 587: DELETE FROM tt2; +--Testcase 588: DELETE FROM tt3; +--Testcase 589: DELETE FROM tt4; +--Testcase 590: DELETE FROM tt5; +--Testcase 591: DELETE FROM tt6; +--Testcase 592: DELETE FROM xx; +--Testcase 593: DELETE FROM yy; +--Testcase 594: DELETE FROM zt1; +--Testcase 595: DELETE FROM zt2; +--Testcase 596: DELETE FROM nt1; +--Testcase 597: DELETE FROM nt2; +--Testcase 598: DELETE FROM nt3; +--Testcase 599: DELETE FROM parent; +--Testcase 600: DELETE FROM child; DO $d$ @@ -2961,9 +3626,9 @@ begin end; $d$; ---Testcase 553: +--Testcase 566: DROP USER MAPPING FOR CURRENT_USER SERVER influxdb_svr; ---Testcase 554: +--Testcase 567: DROP SERVER influxdb_svr CASCADE; ---Testcase 555: +--Testcase 568: DROP EXTENSION influxdb_fdw CASCADE; diff --git a/sql/13.8/extra/limit.sql b/sql/16.0/extra/limit.sql similarity index 98% rename from sql/13.8/extra/limit.sql rename to sql/16.0/extra/limit.sql index eb907d3..716e656 100644 --- a/sql/13.8/extra/limit.sql +++ b/sql/16.0/extra/limit.sql @@ -2,24 +2,21 @@ \ir sql/parameters.conf \set ECHO all ---Testcase 51: +--Testcase 1: CREATE EXTENSION influxdb_fdw; ---Testcase 52: +--Testcase 2: CREATE SERVER influxdb_svr FOREIGN DATA WRAPPER influxdb_fdw OPTIONS (dbname 'coredb', :SERVER); ---Testcase 53: +--Testcase 3: CREATE USER MAPPING FOR CURRENT_USER SERVER influxdb_svr OPTIONS (:AUTHENTICATION); --- import time column as timestamp and text type --- IMPORT FOREIGN SCHEMA influxdb_schema FROM SERVER influxdb_svr INTO public; - -- -- LIMIT -- Check the LIMIT/OFFSET feature of SELECT -- ---Testcase 54: +--Testcase 4: CREATE FOREIGN TABLE onek ( unique1 int4, unique2 int4, @@ -39,10 +36,10 @@ CREATE FOREIGN TABLE onek ( string4 name ) SERVER influxdb_svr; ---Testcase 55: +--Testcase 5: CREATE FOREIGN TABLE int8_tbl(q1 int8, q2 int8) SERVER influxdb_svr; ---Testcase 56: +--Testcase 6: CREATE FOREIGN TABLE tenk1 ( unique1 int4, unique2 int4, @@ -62,133 +59,133 @@ CREATE FOREIGN TABLE tenk1 ( string4 name ) SERVER influxdb_svr OPTIONS (table 'tenk'); ---Testcase 1: +--Testcase 7: SELECT ''::text AS two, unique1, unique2, stringu1 FROM onek WHERE unique1 > 50 ORDER BY unique1 LIMIT 2; ---Testcase 2: +--Testcase 8: SELECT ''::text AS five, unique1, unique2, stringu1 FROM onek WHERE unique1 > 60 ORDER BY unique1 LIMIT 5; ---Testcase 3: +--Testcase 9: SELECT ''::text AS two, unique1, unique2, stringu1 FROM onek WHERE unique1 > 60 AND unique1 < 63 ORDER BY unique1 LIMIT 5; ---Testcase 4: +--Testcase 10: SELECT ''::text AS three, unique1, unique2, stringu1 FROM onek WHERE unique1 > 100 ORDER BY unique1 LIMIT 3 OFFSET 20; ---Testcase 5: +--Testcase 11: SELECT ''::text AS zero, unique1, unique2, stringu1 FROM onek WHERE unique1 < 50 ORDER BY unique1 DESC LIMIT 8 OFFSET 99; ---Testcase 6: +--Testcase 12: SELECT ''::text AS eleven, unique1, unique2, stringu1 FROM onek WHERE unique1 < 50 ORDER BY unique1 DESC LIMIT 20 OFFSET 39; ---Testcase 7: +--Testcase 13: SELECT ''::text AS ten, unique1, unique2, stringu1 FROM onek ORDER BY unique1 OFFSET 990; ---Testcase 8: +--Testcase 14: SELECT ''::text AS five, unique1, unique2, stringu1 FROM onek ORDER BY unique1 OFFSET 990 LIMIT 5; ---Testcase 9: +--Testcase 15: SELECT ''::text AS five, unique1, unique2, stringu1 FROM onek ORDER BY unique1 LIMIT 5 OFFSET 900; -- Test null limit and offset. The planner would discard a simple null -- constant, so to ensure executor is exercised, do this: ---Testcase 10: +--Testcase 16: select * from int8_tbl limit (case when random() < 0.5 then null::bigint end); ---Testcase 11: +--Testcase 17: select * from int8_tbl offset (case when random() < 0.5 then null::bigint end); -- Test assorted cases involving backwards fetch from a LIMIT plan node begin; declare c1 scroll cursor for select * from int8_tbl limit 10; ---Testcase 12: +--Testcase 18: fetch all in c1; ---Testcase 13: +--Testcase 19: fetch 1 in c1; ---Testcase 14: +--Testcase 20: fetch backward 1 in c1; ---Testcase 15: +--Testcase 21: fetch backward all in c1; ---Testcase 16: +--Testcase 22: fetch backward 1 in c1; ---Testcase 17: +--Testcase 23: fetch all in c1; declare c2 scroll cursor for select * from int8_tbl limit 3; ---Testcase 18: +--Testcase 24: fetch all in c2; ---Testcase 19: +--Testcase 25: fetch 1 in c2; ---Testcase 20: +--Testcase 26: fetch backward 1 in c2; ---Testcase 21: +--Testcase 27: fetch backward all in c2; ---Testcase 22: +--Testcase 28: fetch backward 1 in c2; ---Testcase 23: +--Testcase 29: fetch all in c2; declare c3 scroll cursor for select * from int8_tbl offset 3; ---Testcase 24: +--Testcase 30: fetch all in c3; ---Testcase 25: +--Testcase 31: fetch 1 in c3; ---Testcase 26: +--Testcase 32: fetch backward 1 in c3; ---Testcase 27: +--Testcase 33: fetch backward all in c3; ---Testcase 28: +--Testcase 34: fetch backward 1 in c3; ---Testcase 29: +--Testcase 35: fetch all in c3; declare c4 scroll cursor for select * from int8_tbl offset 10; ---Testcase 30: +--Testcase 36: fetch all in c4; ---Testcase 31: +--Testcase 37: fetch 1 in c4; ---Testcase 32: +--Testcase 38: fetch backward 1 in c4; ---Testcase 33: +--Testcase 39: fetch backward all in c4; ---Testcase 34: +--Testcase 40: fetch backward 1 in c4; ---Testcase 35: +--Testcase 41: fetch all in c4; declare c5 scroll cursor for select * from int8_tbl order by q1 fetch first 2 rows with ties; ---Testcase 57: +--Testcase 42: fetch all in c5; ---Testcase 58: +--Testcase 43: fetch 1 in c5; ---Testcase 59: +--Testcase 44: fetch backward 1 in c5; ---Testcase 60: +--Testcase 45: fetch backward 1 in c5; ---Testcase 61: +--Testcase 46: fetch all in c5; ---Testcase 62: +--Testcase 47: fetch backward all in c5; ---Testcase 63: +--Testcase 48: fetch all in c5; ---Testcase 64: +--Testcase 49: fetch backward all in c5; rollback; -- Stress test for variable LIMIT in conjunction with bounded-heap sorting ---Testcase 65: +--Testcase 50: CREATE FOREIGN TABLE generate_series4(a int) SERVER influxdb_svr; ---Testcase 36: +--Testcase 51: SELECT (SELECT a FROM (VALUES (1)) AS x, @@ -201,65 +198,65 @@ SELECT -- with ORDER BY and LIMIT. -- ---Testcase 66: +--Testcase 52: create temp sequence testseq; ---Testcase 37: +--Testcase 53: explain (verbose, costs off) select unique1, unique2, nextval('testseq') from tenk1 order by unique2 limit 10; ---Testcase 38: +--Testcase 54: select unique1, unique2, nextval('testseq') from tenk1 order by unique2 limit 10; ---Testcase 39: +--Testcase 55: select currval('testseq'); ---Testcase 40: +--Testcase 56: explain (verbose, costs off) select unique1, unique2, nextval('testseq') from tenk1 order by tenthous limit 10; ---Testcase 41: +--Testcase 57: select unique1, unique2, nextval('testseq') from tenk1 order by tenthous limit 10; ---Testcase 42: +--Testcase 58: select currval('testseq'); ---Testcase 43: +--Testcase 59: explain (verbose, costs off) select unique1, unique2, generate_series(1,10) from tenk1 order by unique2 limit 7; ---Testcase 44: +--Testcase 60: select unique1, unique2, generate_series(1,10) from tenk1 order by unique2 limit 7; ---Testcase 45: +--Testcase 61: explain (verbose, costs off) select unique1, unique2, generate_series(1,10) from tenk1 order by tenthous limit 7; ---Testcase 46: +--Testcase 62: select unique1, unique2, generate_series(1,10) from tenk1 order by tenthous limit 7; -- use of random() is to keep planner from folding the expressions together ---Testcase 47: +--Testcase 63: explain (verbose, costs off) select generate_series(0,2) as s1, generate_series((random()*.1)::int,2) as s2; ---Testcase 48: +--Testcase 64: select generate_series(0,2) as s1, generate_series((random()*.1)::int,2) as s2; ---Testcase 49: +--Testcase 65: explain (verbose, costs off) select generate_series(0,2) as s1, generate_series((random()*.1)::int,2) as s2 order by s2 desc; ---Testcase 50: +--Testcase 66: select generate_series(0,2) as s1, generate_series((random()*.1)::int,2) as s2 order by s2 desc; @@ -298,6 +295,12 @@ SELECT thousand FROM onek WHERE thousand < 5 ORDER BY thousand FETCH FIRST 2 ROW ONLY; +-- SKIP LOCKED and WITH TIES are incompatible +--Testcase 90: +SELECT thousand + FROM onek WHERE thousand < 5 + ORDER BY thousand FETCH FIRST 1 ROW WITH TIES FOR UPDATE SKIP LOCKED; + -- should fail --Testcase 73: SELECT ''::text AS two, unique1, unique2, stringu1 diff --git a/sql/13.8/extra/prepare.sql b/sql/16.0/extra/prepare.sql similarity index 85% rename from sql/13.8/extra/prepare.sql rename to sql/16.0/extra/prepare.sql index 13c7439..19c08e2 100644 --- a/sql/13.8/extra/prepare.sql +++ b/sql/16.0/extra/prepare.sql @@ -5,16 +5,16 @@ \ir sql/parameters.conf \set ECHO all ---Testcase 27: +--Testcase 1: CREATE EXTENSION influxdb_fdw; ---Testcase 28: +--Testcase 2: CREATE SERVER influxdb_svr FOREIGN DATA WRAPPER influxdb_fdw OPTIONS (dbname 'coredb', :SERVER); ---Testcase 29: +--Testcase 3: CREATE USER MAPPING FOR CURRENT_USER SERVER influxdb_svr OPTIONS (:AUTHENTICATION); ---Testcase 30: +--Testcase 4: CREATE FOREIGN TABLE tenk1 ( unique1 int4, unique2 int4, @@ -37,117 +37,121 @@ CREATE FOREIGN TABLE tenk1 ( -- Does not support this command -- ALTER TABLE tenk1 SET WITH OIDS; ---Testcase 31: +--Testcase 5: CREATE FOREIGN TABLE road ( name text, thepath path ) SERVER influxdb_svr; ---Testcase 32: +--Testcase 6: CREATE FOREIGN TABLE road_tmp (a int, b int) SERVER influxdb_svr; ---Testcase 1: -SELECT name, statement, parameter_types FROM pg_prepared_statements; +--Testcase 7: +SELECT name, statement, parameter_types, result_types FROM pg_prepared_statements; ---Testcase 2: +--Testcase 8: PREPARE q1 AS SELECT a AS a FROM road_tmp; ---Testcase 3: +--Testcase 9: EXECUTE q1; ---Testcase 4: -SELECT name, statement, parameter_types FROM pg_prepared_statements; +--Testcase 10: +SELECT name, statement, parameter_types, result_types FROM pg_prepared_statements; -- should fail ---Testcase 5: +--Testcase 11: PREPARE q1 AS SELECT b FROM road_tmp; -- should succeed DEALLOCATE q1; ---Testcase 6: +--Testcase 12: PREPARE q1 AS SELECT b FROM road_tmp; ---Testcase 7: +--Testcase 13: EXECUTE q1; ---Testcase 8: +--Testcase 14: PREPARE q2 AS SELECT b AS b FROM road_tmp; ---Testcase 9: -SELECT name, statement, parameter_types FROM pg_prepared_statements; +--Testcase 15: +SELECT name, statement, parameter_types, result_types FROM pg_prepared_statements; -- sql92 syntax DEALLOCATE PREPARE q1; ---Testcase 10: -SELECT name, statement, parameter_types FROM pg_prepared_statements; +--Testcase 16: +SELECT name, statement, parameter_types, result_types FROM pg_prepared_statements; DEALLOCATE PREPARE q2; -- the view should return the empty set again ---Testcase 11: -SELECT name, statement, parameter_types FROM pg_prepared_statements; +--Testcase 17: +SELECT name, statement, parameter_types, result_types FROM pg_prepared_statements; -- parameterized queries ---Testcase 12: +--Testcase 18: PREPARE q2(text) AS SELECT datname, datistemplate, datallowconn FROM pg_database WHERE datname = $1; ---Testcase 13: +--Testcase 19: EXECUTE q2('postgres'); ---Testcase 14: +--Testcase 20: 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; ---Testcase 15: +--Testcase 21: EXECUTE q3('AAAAxx', 5::smallint, 10.5::float, false, 4::bigint); -- too few params ---Testcase 16: +--Testcase 22: EXECUTE q3('bool'); -- too many params ---Testcase 17: +--Testcase 23: EXECUTE q3('bytea', 5::smallint, 10.5::float, false, 4::bigint, true); -- wrong param types ---Testcase 18: +--Testcase 24: EXECUTE q3(5::smallint, 10.5::float, false, 4::bigint, 'bytea'); -- invalid type ---Testcase 19: +--Testcase 25: PREPARE q4(nonexistenttype) AS SELECT $1; -- create table as execute ---Testcase 20: +--Testcase 26: PREPARE q5(int, text) AS SELECT * FROM tenk1 WHERE unique1 = $1 OR stringu1 = $2 ORDER BY unique1; ---Testcase 33: +--Testcase 27: CREATE TEMPORARY TABLE q5_prep_results AS EXECUTE q5(200, 'DTAAAA'); ---Testcase 21: +--Testcase 28: SELECT * FROM q5_prep_results; ---Testcase 34: +--Testcase 29: CREATE TEMPORARY TABLE q5_prep_nodata AS EXECUTE q5(200, 'DTAAAA') WITH NO DATA; ---Testcase 22: +--Testcase 30: SELECT * FROM q5_prep_nodata; -- unknown or unspecified parameter types: should succeed ---Testcase 23: +--Testcase 31: PREPARE q6 AS SELECT * FROM tenk1 WHERE unique1 = $1 AND stringu1 = $2; ---Testcase 24: +--Testcase 32: PREPARE q7(unknown) AS SELECT * FROM road WHERE thepath = $1; ---Testcase 25: -SELECT name, statement, parameter_types FROM pg_prepared_statements +--Testcase 33: +-- DML statements +PREPARE q8 AS + UPDATE tenk1 SET stringu1 = $2 WHERE unique1 = $1; + +SELECT name, statement, parameter_types, result_types FROM pg_prepared_statements ORDER BY name; -- test DEALLOCATE ALL; DEALLOCATE ALL; ---Testcase 26: +--Testcase 34: SELECT name, statement, parameter_types FROM pg_prepared_statements ORDER BY name; diff --git a/sql/13.8/extra/select.sql b/sql/16.0/extra/select.sql similarity index 95% rename from sql/13.8/extra/select.sql rename to sql/16.0/extra/select.sql index db8bf84..e461319 100644 --- a/sql/13.8/extra/select.sql +++ b/sql/16.0/extra/select.sql @@ -5,16 +5,16 @@ \ir sql/parameters.conf \set ECHO all ---Testcase 52: +--Testcase 1: CREATE EXTENSION influxdb_fdw; ---Testcase 53: +--Testcase 2: CREATE SERVER influxdb_svr FOREIGN DATA WRAPPER influxdb_fdw OPTIONS (dbname 'coredb', :SERVER); ---Testcase 54: +--Testcase 3: CREATE USER MAPPING FOR CURRENT_USER SERVER influxdb_svr OPTIONS (:AUTHENTICATION); ---Testcase 55: +--Testcase 4: CREATE FOREIGN TABLE onek ( unique1 int4, unique2 int4, @@ -34,7 +34,7 @@ CREATE FOREIGN TABLE onek ( string4 name ) SERVER influxdb_svr; ---Testcase 56: +--Testcase 5: CREATE FOREIGN TABLE onek2 ( unique1 int4, unique2 int4, @@ -54,13 +54,13 @@ CREATE FOREIGN TABLE onek2 ( string4 name ) SERVER influxdb_svr OPTIONS (table 'onek'); ---Testcase 57: +--Testcase 6: CREATE FOREIGN TABLE INT8_TBL ( q1 int8, q2 int8 ) SERVER influxdb_svr; ---Testcase 58: +--Testcase 7: CREATE FOREIGN TABLE person ( name text, age int4, @@ -68,20 +68,20 @@ CREATE FOREIGN TABLE person ( ) SERVER influxdb_svr; ---Testcase 59: +--Testcase 8: CREATE FOREIGN TABLE emp ( salary int4, manager text ) INHERITS (person) SERVER influxdb_svr; ---Testcase 60: +--Testcase 9: CREATE FOREIGN TABLE student ( gpa float8 ) INHERITS (person) SERVER influxdb_svr; ---Testcase 61: +--Testcase 10: CREATE FOREIGN TABLE stud_emp ( percent int4 ) INHERITS (emp, student) SERVER influxdb_svr; @@ -89,7 +89,7 @@ CREATE FOREIGN TABLE stud_emp ( -- btree index -- awk '{if($1<10){print;}else{next;}}' onek.data | sort +0n -1 -- ---Testcase 1: +--Testcase 11: SELECT * FROM onek WHERE onek.unique1 < 10 ORDER BY onek.unique1; @@ -97,7 +97,7 @@ SELECT * FROM onek -- -- awk '{if($1<20){print $1,$14;}else{next;}}' onek.data | sort +0nr -1 -- ---Testcase 2: +--Testcase 12: SELECT onek.unique1, onek.stringu1 FROM onek WHERE onek.unique1 < 20 ORDER BY unique1 using >; @@ -105,7 +105,7 @@ SELECT onek.unique1, onek.stringu1 FROM onek -- -- awk '{if($1>980){print $1,$14;}else{next;}}' onek.data | sort +1d -2 -- ---Testcase 3: +--Testcase 13: SELECT onek.unique1, onek.stringu1 FROM onek WHERE onek.unique1 > 980 ORDER BY stringu1 using <; @@ -114,7 +114,7 @@ SELECT onek.unique1, onek.stringu1 FROM onek -- awk '{if($1>980){print $1,$16;}else{next;}}' onek.data | -- sort +1d -2 +0nr -1 -- ---Testcase 4: +--Testcase 14: SELECT onek.unique1, onek.string4 FROM onek WHERE onek.unique1 > 980 ORDER BY string4 using <, unique1 using >; @@ -123,7 +123,7 @@ SELECT onek.unique1, onek.string4 FROM onek -- awk '{if($1>980){print $1,$16;}else{next;}}' onek.data | -- sort +1dr -2 +0n -1 -- ---Testcase 5: +--Testcase 15: SELECT onek.unique1, onek.string4 FROM onek WHERE onek.unique1 > 980 ORDER BY string4 using >, unique1 using <; @@ -132,7 +132,7 @@ SELECT onek.unique1, onek.string4 FROM onek -- awk '{if($1<20){print $1,$16;}else{next;}}' onek.data | -- sort +0nr -1 +1d -2 -- ---Testcase 6: +--Testcase 16: SELECT onek.unique1, onek.string4 FROM onek WHERE onek.unique1 < 20 ORDER BY unique1 using >, string4 using <; @@ -141,7 +141,7 @@ SELECT onek.unique1, onek.string4 FROM onek -- awk '{if($1<20){print $1,$16;}else{next;}}' onek.data | -- sort +0n -1 +1dr -2 -- ---Testcase 7: +--Testcase 17: SELECT onek.unique1, onek.string4 FROM onek WHERE onek.unique1 < 20 ORDER BY unique1 using <, string4 using >; @@ -155,20 +155,23 @@ SELECT onek.unique1, onek.string4 FROM onek -- -- ANALYZE onek2; +--Testcase 18: SET enable_seqscan TO off; +--Testcase 19: SET enable_bitmapscan TO off; +--Testcase 20: SET enable_sort TO off; -- -- awk '{if($1<10){print $0;}else{next;}}' onek.data | sort +0n -1 -- ---Testcase 8: +--Testcase 21: SELECT onek2.* FROM onek2 WHERE onek2.unique1 < 10 order by 1; -- -- awk '{if($1<20){print $1,$14;}else{next;}}' onek.data | sort +0nr -1 -- ---Testcase 9: +--Testcase 22: SELECT onek2.unique1, onek2.stringu1 FROM onek2 WHERE onek2.unique1 < 20 ORDER BY unique1 using >; @@ -176,19 +179,22 @@ SELECT onek2.unique1, onek2.stringu1 FROM onek2 -- -- awk '{if($1>980){print $1,$14;}else{next;}}' onek.data | sort +1d -2 -- ---Testcase 10: +--Testcase 23: SELECT onek2.unique1, onek2.stringu1 FROM onek2 WHERE onek2.unique1 > 980 order by 1; +--Testcase 24: RESET enable_seqscan; +--Testcase 25: RESET enable_bitmapscan; +--Testcase 26: RESET enable_sort; ---Testcase 11: -SELECT two, stringu1, ten, string4 - INTO TABLE tmp - FROM onek; +--Testcase 27: +--SELECT two, stringu1, ten, string4 +-- INTO TABLE tmp +-- FROM onek; -- -- awk '{print $1,$2;}' person.data | @@ -197,7 +203,7 @@ SELECT two, stringu1, ten, string4 -- awk 'BEGIN{FS=" ";}{if(NF!=2){print $4,$5;}else{print;}}' - stud_emp.data -- -- SELECT name, age FROM person*; ??? check if different ---Testcase 12: +--Testcase 28: SELECT p.name, p.age FROM person* p; -- @@ -207,29 +213,29 @@ SELECT p.name, p.age FROM person* p; -- awk 'BEGIN{FS=" ";}{if(NF!=1){print $4,$5;}else{print;}}' - stud_emp.data | -- sort +1nr -2 -- ---Testcase 13: +--Testcase 29: SELECT p.name, p.age FROM person* p ORDER BY age using >, name; -- -- Test some cases involving whole-row Var referencing a subquery -- ---Testcase 14: +--Testcase 30: select foo from (select 1 offset 0) as foo; ---Testcase 15: +--Testcase 31: select foo from (select null offset 0) as foo; ---Testcase 16: +--Testcase 32: select foo from (select 'xyzzy',1,null offset 0) as foo; -- -- Test VALUES lists -- ---Testcase 17: +--Testcase 33: select * from onek, (values(147, 'RFAAAA'), (931, 'VJAAAA')) as v (i, j) WHERE onek.unique1 = v.i and onek.stringu1 = v.j; -- a more complex case -- looks like we're coding lisp :-) ---Testcase 18: +--Testcase 34: select * from onek, (values ((select i from (values(10000), (2), (389), (1000), (2000), ((select 10029))) as foo(i) @@ -237,38 +243,47 @@ select * from onek, where onek.unique1 = bar.i; -- try VALUES in a subquery ---Testcase 19: +--Testcase 35: select * from onek where (unique1,ten) in (values (1,1), (20,0), (99,9), (17,99)) order by unique1; -- VALUES is also legal as a standalone query or a set-operation member ---Testcase 20: +--Testcase 36: VALUES (1,2), (3,4+4), (7,77.7); ---Testcase 21: +--Testcase 37: VALUES (1,2), (3,4+4), (7,77.7) UNION ALL SELECT 2+2, 57 UNION ALL TABLE int8_tbl; +-- -- corner case: VALUES with no columns +-- InfluxDB not support table with no columns. +-- --Testcase 79: +-- CREATE FOREIGN TABLE nocols() SERVER influxdb_svr; +-- --Testcase 80: +-- INSERT INTO nocols DEFAULT VALUES; +-- --Testcase 81: +-- SELECT * FROM nocols n, LATERAL (VALUES(n.*)) v; + -- -- Test ORDER BY options -- ---Testcase 62: +--Testcase 38: CREATE FOREIGN TABLE foo (f1 int) SERVER influxdb_svr; ---Testcase 22: +--Testcase 39: SELECT * FROM foo ORDER BY f1; ---Testcase 23: +--Testcase 40: SELECT * FROM foo ORDER BY f1 ASC; -- same thing ---Testcase 24: +--Testcase 41: SELECT * FROM foo ORDER BY f1 NULLS FIRST; ---Testcase 25: +--Testcase 42: SELECT * FROM foo ORDER BY f1 DESC; ---Testcase 26: +--Testcase 43: SELECT * FROM foo ORDER BY f1 DESC NULLS LAST; -- check if indexscans do the right things @@ -301,64 +316,66 @@ SELECT * FROM foo ORDER BY f1 DESC NULLS LAST; -- -- partial index is usable ---Testcase 27: +--Testcase 44: explain (costs off) select * from onek2 where unique2 = 11 and stringu1 = 'ATAAAA'; ---Testcase 28: +--Testcase 45: select * from onek2 where unique2 = 11 and stringu1 = 'ATAAAA'; -- actually run the query with an analyze to use the partial index ---Testcase 63: +--Testcase 46: explain (costs off, analyze on, timing off, summary off) select * from onek2 where unique2 = 11 and stringu1 = 'ATAAAA'; ---Testcase 30: +--Testcase 47: explain (costs off) select unique2 from onek2 where unique2 = 11 and stringu1 = 'ATAAAA'; ---Testcase 31: +--Testcase 48: select unique2 from onek2 where unique2 = 11 and stringu1 = 'ATAAAA'; -- partial index predicate implies clause, so no need for retest ---Testcase 32: +--Testcase 49: explain (costs off) select * from onek2 where unique2 = 11 and stringu1 < 'B'; ---Testcase 33: +--Testcase 50: select * from onek2 where unique2 = 11 and stringu1 < 'B'; ---Testcase 34: +--Testcase 51: explain (costs off) select unique2 from onek2 where unique2 = 11 and stringu1 < 'B'; ---Testcase 35: +--Testcase 52: select unique2 from onek2 where unique2 = 11 and stringu1 < 'B'; -- but if it's an update target, must retest anyway ---Testcase 36: +--Testcase 53: explain (costs off) select unique2 from onek2 where unique2 = 11 and stringu1 < 'B' for update; ---Testcase 37: +--Testcase 54: select unique2 from onek2 where unique2 = 11 and stringu1 < 'B' for update; -- partial index is not applicable ---Testcase 38: +--Testcase 55: explain (costs off) select unique2 from onek2 where unique2 = 11 and stringu1 < 'C'; ---Testcase 39: +--Testcase 56: select unique2 from onek2 where unique2 = 11 and stringu1 < 'C'; -- partial index implies clause, but bitmap scan must recheck predicate anyway +--Testcase 57: SET enable_indexscan TO off; ---Testcase 40: +--Testcase 58: explain (costs off) select unique2 from onek2 where unique2 = 11 and stringu1 < 'B'; ---Testcase 41: +--Testcase 59: select unique2 from onek2 where unique2 = 11 and stringu1 < 'B'; +--Testcase 60: RESET enable_indexscan; -- check multi-index cases too ---Testcase 42: +--Testcase 61: explain (costs off) select unique1, unique2 from onek2 where (unique2 = 11 or unique1 = 0) and stringu1 < 'B'; ---Testcase 43: +--Testcase 62: select unique1, unique2 from onek2 where (unique2 = 11 or unique1 = 0) and stringu1 < 'B'; ---Testcase 44: +--Testcase 63: explain (costs off) select unique1, unique2 from onek2 where (unique2 = 11 and stringu1 < 'B') or unique1 = 0; ---Testcase 45: +--Testcase 64: select unique1, unique2 from onek2 where (unique2 = 11 and stringu1 < 'B') or unique1 = 0; @@ -367,47 +384,47 @@ select unique1, unique2 from onek2 -- -- ORDER BY on a constant doesn't really need any sorting ---Testcase 46: +--Testcase 65: SELECT 1 AS x ORDER BY x; -- But ORDER BY on a set-valued expression does ---Testcase 64: +--Testcase 66: create function sillysrf(int) returns setof int as 'values (1),(10),(2),($1)' language sql immutable; ---Testcase 47: +--Testcase 67: select sillysrf(42); ---Testcase 48: +--Testcase 68: select sillysrf(-1) order by 1; ---Testcase 65: +--Testcase 69: drop function sillysrf(int); -- X = X isn't a no-op, it's effectively X IS NOT NULL assuming = is strict -- (see bug #5084) ---Testcase 49: +--Testcase 70: select * from (values (2),(null),(1)) v(k) where k = k order by k; ---Testcase 50: +--Testcase 71: select * from (values (2),(null),(1)) v(k) where k = k; -- Test partitioned tables with no partitions, which should be handled the -- same as the non-inheritance case when expanding its RTE. ---Testcase 66: +--Testcase 72: create table list_parted_tbl (a int,b int) partition by list (a); ---Testcase 67: +--Testcase 73: create table list_parted_tbl1 partition of list_parted_tbl for values in (1) partition by list(b); ---Testcase 51: +--Testcase 74: explain (costs off) select * from list_parted_tbl; ---Testcase 68: +--Testcase 75: drop table list_parted_tbl; -- Clean up: -DROP TABLE IF EXISTS tmp; +--DROP TABLE IF EXISTS tmp; ---Testcase 69: +--Testcase 76: DROP USER MAPPING FOR CURRENT_USER SERVER influxdb_svr; ---Testcase 70: +--Testcase 77: DROP SERVER influxdb_svr CASCADE; ---Testcase 71: +--Testcase 78: DROP EXTENSION influxdb_fdw CASCADE; diff --git a/sql/14.5/extra/select_having.sql b/sql/16.0/extra/select_having.sql similarity index 98% rename from sql/14.5/extra/select_having.sql rename to sql/16.0/extra/select_having.sql index 4e2b933..23775bb 100644 --- a/sql/14.5/extra/select_having.sql +++ b/sql/16.0/extra/select_having.sql @@ -83,7 +83,9 @@ SELECT 1 AS one FROM test_having WHERE 1/a = 1 HAVING 1 < 2; --Testcase 26: -- Clean up: +--Testcase 30: DELETE FROM test_having; +--Testcase 31: DROP FOREIGN TABLE test_having; --Testcase 27: DROP USER MAPPING FOR CURRENT_USER SERVER influxdb_svr; diff --git a/sql/16.0/influxdb_fdw.sql b/sql/16.0/influxdb_fdw.sql new file mode 100644 index 0000000..558af8d --- /dev/null +++ b/sql/16.0/influxdb_fdw.sql @@ -0,0 +1,688 @@ +--SET log_min_messages=debug1; +--SET client_min_messages=debug1; +--Testcase 1: +SET datestyle=ISO; +-- timestamp with time zone differs based on this +--Testcase 2: +SET timezone='Japan'; + +\set ECHO none +\ir sql/parameters.conf +\set ECHO all + +--Testcase 3: +CREATE EXTENSION influxdb_fdw; +--Testcase 4: +CREATE SERVER server1 FOREIGN DATA WRAPPER influxdb_fdw OPTIONS +(dbname 'mydb', :SERVER); +--Testcase 5: +CREATE USER MAPPING FOR CURRENT_USER SERVER server1 OPTIONS (:AUTHENTICATION); +-- import time column as timestamp and text type +IMPORT FOREIGN SCHEMA public FROM SERVER server1 INTO public OPTIONS(import_time_text 'true'); +--Testcase 6: +SELECT * FROM cpu; +--Testcase 7: +SELECT tag1, value1 FROM cpu; +--Testcase 8: +SELECT value1, time, value2 FROM cpu; +--Testcase 9: +SELECT value1, time_text, value2 FROM cpu; + +--Testcase 10: +DROP FOREIGN TABLE cpu; +--Testcase 11: +DROP FOREIGN TABLE t3; +--Testcase 12: +DROP FOREIGN TABLE t4; +--Testcase 13: +DROP FOREIGN TABLE tx; +--Testcase 14: +DROP FOREIGN TABLE numbers; + +-- test EXECPT +IMPORT FOREIGN SCHEMA public EXCEPT (cpu, t3, t4, tx, numbers) FROM SERVER server1 INTO public; +--Testcase 15: +SELECT ftoptions FROM pg_foreign_table; + +-- test LIMIT TO +IMPORT FOREIGN SCHEMA public LIMIT TO (cpu) FROM SERVER server1 INTO public; +--Testcase 16: +SELECT ftoptions FROM pg_foreign_table; +--Testcase 17: +DROP FOREIGN TABLE cpu; + +IMPORT FOREIGN SCHEMA public FROM SERVER server1 INTO public OPTIONS(import_time_text 'false'); + +--Testcase 18: +SELECT * FROM cpu; +--Testcase 19: +SELECT tag1, value1 FROM cpu; +--Testcase 20: +SELECT value1, time, value2 FROM cpu; +--Testcase 21: +SELECT tag1 FROM cpu; +--Testcase 22: +SELECT * FROM numbers; + +--Testcase 23: +\d cpu; + +--Testcase 24: +SELECT * FROM cpu WHERE value1=100; +--Testcase 25: +SELECT * FROM cpu WHERE value2=0.5; +--Testcase 26: +SELECT * FROM cpu WHERE value3='str'; +--Testcase 27: +SELECT * FROM cpu WHERE value4=true; +--Testcase 28: +SELECT * FROM cpu WHERE NOT (value4 AND value1=100); +--Testcase 29: +SELECT * FROM cpu WHERE tag1='tag1_A'; + +--Testcase 30: +EXPLAIN (VERBOSE, COSTS OFF) +SELECT * FROM cpu WHERE value3 IS NULL; +--Testcase 31: +SELECT * FROM cpu WHERE value3 IS NULL; +--Testcase 32: +SELECT * FROM cpu WHERE tag2 IS NULL; +--Testcase 33: +SELECT * FROM cpu WHERE value3 IS NOT NULL; +--Testcase 34: +SELECT * FROM cpu WHERE tag2 IS NOT NULL; + +-- InfluxDB not support compare timestamp with OR condition +--Testcase 35: +SELECT * FROM cpu WHERE time = '2015-08-18 09:48:08+09' OR value2 = 0.5; + +-- InfluxDB not support compare timestamp with != or <> +--Testcase 36: +SELECT * FROM cpu WHERE time != '2015-08-18 09:48:08+09'; +--Testcase 37: +SELECT * FROM cpu WHERE time <> '2015-08-18 09:48:08+09'; + +--Testcase 38: +SELECT * FROM cpu WHERE time = '2015-08-18 09:48:08+09' OR value2 = 0.5; + +-- There is inconsitency for search of missing values between tag and field +--Testcase 39: +EXPLAIN (VERBOSE, COSTS OFF) +SELECT * FROM cpu WHERE value3 = ''; +--Testcase 40: +SELECT * FROM cpu WHERE value3 = ''; + +--Testcase 41: +EXPLAIN (VERBOSE, COSTS OFF) +SELECT * FROM cpu WHERE tag2 = ''; +--Testcase 42: +SELECT * FROM cpu WHERE tag2 = ''; + +--Testcase 43: +SELECT * FROM cpu WHERE tag1 IN ('tag1_A', 'tag1_B'); +--Testcase 44: +EXPLAIN VERBOSE +SELECT * FROM cpu WHERE tag1 IN ('tag1_A', 'tag1_B'); + +-- Rows which have no tag are considered to have empty string +--Testcase 45: +SELECT * FROM cpu WHERE tag1 NOT IN ('tag1_A', 'tag1_B'); +--Testcase 46: +EXPLAIN VERBOSE +SELECT * FROM cpu WHERE tag1 NOT IN ('tag1_A', 'tag1_B'); + +-- test IN/NOT IN +--Testcase 47: +SELECT * FROM cpu WHERE time IN ('2015-08-18 09:48:08+09','2016-08-28 07:44:00+07'); +--Testcase 48: +SELECT * FROM cpu WHERE time NOT IN ('2015-08-18 09:48:08+09','2016-08-28 07:44:00+07'); +--Testcase 49: +SELECT * FROM cpu WHERE value1 NOT IN (100, 97); +--Testcase 50: +SELECT * FROM cpu WHERE value1 IN (100, 97); +--Testcase 51: +SELECT * FROM cpu WHERE value2 IN (0.5, 10.9); +--Testcase 52: +SELECT * FROM cpu WHERE value2 NOT IN (2, 9.7); +--Testcase 53: +SELECT * FROM cpu WHERE value4 NOT IN ('true', 'true'); +--Testcase 54: +SELECT * FROM cpu WHERE time IN ('2015-08-18 09:48:08+09','2016-08-28 07:44:00+07'); +--Testcase 55: +SELECT * FROM cpu WHERE time NOT IN ('2015-08-18 09:48:08+09','2016-08-28 07:44:00+07'); +--Testcase 56: +SELECT * FROM cpu WHERE value1 NOT IN (100, 97); +--Testcase 57: +SELECT * FROM cpu WHERE value1 IN (100, 97); +--Testcase 58: +SELECT * FROM cpu WHERE value2 IN (0.5, 10.9); +--Testcase 59: +SELECT * FROM cpu WHERE value2 NOT IN (2, 9.7); +--Testcase 60: +SELECT * FROM cpu WHERE value4 NOT IN ('true', 'true'); +--Testcase 61: +SELECT * FROM cpu WHERE value4 IN ('f', 't'); + +--Testcase 62: +CREATE FOREIGN TABLE t1(time timestamp with time zone , tag1 text, value1 integer) SERVER server1 OPTIONS (table 'cpu'); +--Testcase 63: +CREATE FOREIGN TABLE t2(time timestamp , tag1 text, value1 integer) SERVER server1 OPTIONS (table 'cpu'); + +--Testcase 64: +SELECT * FROM t1; +--Testcase 65: +SELECT * FROM t2; +-- In following four queries, timestamp condition is added to InfluxQL as "time = '2015-08-18 00:00:00'" +--Testcase 66: +SELECT * FROM t1 WHERE time = TIMESTAMP WITH TIME ZONE '2015-08-18 09:00:00+09'; +--Testcase 67: +SELECT * FROM t1 WHERE time = TIMESTAMP '2015-08-18 00:00:00'; + +--Testcase 68: +SELECT * FROM t2 WHERE time = TIMESTAMP WITH TIME ZONE '2015-08-18 09:00:00+09'; +--Testcase 69: +SELECT * FROM t2 WHERE time = TIMESTAMP '2015-08-18 00:00:00'; + +-- pushdown now() +--Testcase 70: +SELECT * FROM t2 WHERE now() > time; +--Testcase 71: +EXPLAIN VERBOSE +SELECT * FROM t2 WHERE now() > time; + +--Testcase 72: +SELECT * FROM t2 WHERE time = TIMESTAMP WITH TIME ZONE '2015-08-26 05:43:21.1+00' - interval '1 week 1 day 5 hour 43 minute 21 second 100 millisecond'; +--Testcase 73: +EXPLAIN VERBOSE +SELECT * FROM t2 WHERE time = TIMESTAMP WITH TIME ZONE '2015-08-26 05:43:21.1+00' - interval '1 week 1 day 5 hour 43 minute 21 second 100 millisecond'; + +-- InfluxDB does not seem to support time column + interval, so below query returns empty result +-- SELECT * FROM t2 WHERE time + interval '1 week 1 day 5 hour 43 minute 21 second 100 millisecond' = TIMESTAMP WITH TIME ZONE '2015-08-26 05:43:21.1+00'; +-- EXPLAIN (VERBOSE, COSTS OFF) +-- SELECT * FROM t2 WHERE time + interval '1 week 1 day 5 hour 43 minute 21 second 100 millisecond' = TIMESTAMP WITH TIME ZONE '2015-08-26 05:43:21.1+00'; + +-- InfluxDB does not support month or year interval, so not push down +--Testcase 74: +SELECT * FROM t2 WHERE time = TIMESTAMP '2015-09-18 00:00:00' - interval '1 months'; +--Testcase 75: +EXPLAIN VERBOSE +SELECT * FROM t2 WHERE time = TIMESTAMP '2015-09-18 00:00:00' - interval '1 months'; + +--Testcase 76: +SELECT * FROM t2 WHERE value1 = ANY (ARRAY(SELECT value1 FROM t1 WHERE value1 < 1000)); + +-- ANY with ARRAY expression +--Testcase 77: +EXPLAIN VERBOSE +SELECT a, b FROM numbers WHERE a = ANY(ARRAY[1, a + 1]); +--Testcase 78: +SELECT a, b FROM numbers WHERE a = ANY(ARRAY[1, a + 1]); + +--Testcase 79: +EXPLAIN VERBOSE +SELECT a, b FROM numbers WHERE a <> ANY(ARRAY[1, a + 1]); +--Testcase 80: +SELECT a, b FROM numbers WHERE a <> ANY(ARRAY[1, a + 1]); + +--Testcase 81: +EXPLAIN VERBOSE +SELECT a, b FROM numbers WHERE a >= ANY(ARRAY[1, a + 1]); +--Testcase 82: +SELECT a, b FROM numbers WHERE a >= ANY(ARRAY[1, a + 1]); + +--Testcase 83: +EXPLAIN VERBOSE +SELECT a, b FROM numbers WHERE a <= ANY(ARRAY[1, a + 1]); +--Testcase 84: +SELECT a, b FROM numbers WHERE a <= ANY(ARRAY[1, a + 1]); + +--Testcase 85: +EXPLAIN VERBOSE +SELECT a, b FROM numbers WHERE a > ANY(ARRAY[1, a + 1]); +--Testcase 86: +SELECT a, b FROM numbers WHERE a > ANY(ARRAY[1, a + 1]); + +--Testcase 87: +EXPLAIN VERBOSE +SELECT a, b FROM numbers WHERE a < ANY(ARRAY[1, a + 1]); +--Testcase 88: +SELECT a, b FROM numbers WHERE a < ANY(ARRAY[1, a + 1]); + +-- ANY with ARRAY const +--Testcase 89: +EXPLAIN VERBOSE +SELECT a, b FROM numbers WHERE a = ANY(ARRAY[1, 2]); +--Testcase 90: +SELECT a, b FROM numbers WHERE a = ANY(ARRAY[1, 2]); + +--Testcase 91: +EXPLAIN VERBOSE +SELECT a, b FROM numbers WHERE a <> ANY(ARRAY[1, 2]); +--Testcase 92: +SELECT a, b FROM numbers WHERE a <> ANY(ARRAY[1, 2]); + +--Testcase 93: +EXPLAIN VERBOSE +SELECT a, b FROM numbers WHERE a >= ANY(ARRAY[1, 2]); +--Testcase 94: +SELECT a, b FROM numbers WHERE a >= ANY(ARRAY[1, 2]); + +--Testcase 95: +EXPLAIN VERBOSE +SELECT a, b FROM numbers WHERE a <= ANY(ARRAY[1, 2]); +--Testcase 96: +SELECT a, b FROM numbers WHERE a <= ANY(ARRAY[1, 2]); + +--Testcase 97: +EXPLAIN VERBOSE +SELECT a, b FROM numbers WHERE a > ANY(ARRAY[1, 2]); +--Testcase 98: +SELECT a, b FROM numbers WHERE a > ANY(ARRAY[1, 2]); + +--Testcase 99: +EXPLAIN VERBOSE +SELECT a, b FROM numbers WHERE a < ANY(ARRAY[1, 2]); +--Testcase 100: +SELECT a, b FROM numbers WHERE a < ANY(ARRAY[1, 2]); + +--Testcase 101: +EXPLAIN VERBOSE +SELECT a, b FROM numbers WHERE a = ANY('{1, 2, 3}'); +--Testcase 102: +SELECT a, b FROM numbers WHERE a = ANY('{1, 2, 3}'); +--Testcase 103: +EXPLAIN VERBOSE +SELECT a, b FROM numbers WHERE a <> ANY('{1, 2, 3}'); +--Testcase 104: +SELECT a, b FROM numbers WHERE a <> ANY('{1, 2, 3}'); + +-- ALL with ARRAY expression +--Testcase 105: +EXPLAIN VERBOSE +SELECT a, b FROM numbers WHERE a = ALL(ARRAY[1, a * 1]); +--Testcase 106: +SELECT a, b FROM numbers WHERE a = ALL(ARRAY[1, a * 1]); + +--Testcase 107: +EXPLAIN VERBOSE +SELECT a, b FROM numbers WHERE a <> ALL(ARRAY[1, a + 1]); +--Testcase 108: +SELECT a, b FROM numbers WHERE a <> ALL(ARRAY[1, a + 1]); + +--Testcase 109: +EXPLAIN VERBOSE +SELECT a, b FROM numbers WHERE a >= ALL(ARRAY[1, a / 1]); +--Testcase 110: +SELECT a, b FROM numbers WHERE a >= ALL(ARRAY[1, a / 1]); + +--Testcase 111: +EXPLAIN VERBOSE +SELECT a, b FROM numbers WHERE a <= ALL(ARRAY[1, a + 1]); +--Testcase 112: +SELECT a, b FROM numbers WHERE a <= ALL(ARRAY[1, a + 1]); + +--Testcase 113: +EXPLAIN VERBOSE +SELECT a, b FROM numbers WHERE a > ALL(ARRAY[1, a - 1]); +--Testcase 114: +SELECT a, b FROM numbers WHERE a > ALL(ARRAY[1, a - 1]); + +--Testcase 115: +EXPLAIN VERBOSE +SELECT a, b FROM numbers WHERE a < ALL(ARRAY[2, a + 1]); +--Testcase 116: +SELECT a, b FROM numbers WHERE a < ALL(ARRAY[2, a + 1]); + +-- ALL with ARRAY const +--Testcase 117: +EXPLAIN VERBOSE +SELECT a, b FROM numbers WHERE a = ALL(ARRAY[1, 1]); +--Testcase 118: +SELECT a, b FROM numbers WHERE a = ALL(ARRAY[1, 1]); + +--Testcase 119: +EXPLAIN VERBOSE +SELECT a, b FROM numbers WHERE a <> ALL(ARRAY[1, 3]); +--Testcase 120: +SELECT a, b FROM numbers WHERE a <> ALL(ARRAY[1, 3]); + +--Testcase 121: +EXPLAIN VERBOSE +SELECT a, b FROM numbers WHERE a >= ALL(ARRAY[1, 2]); +--Testcase 122: +SELECT a, b FROM numbers WHERE a >= ALL(ARRAY[1, 2]); + +--Testcase 123: +EXPLAIN VERBOSE +SELECT a, b FROM numbers WHERE a <= ALL(ARRAY[1, 2]); +--Testcase 124: +SELECT a, b FROM numbers WHERE a <= ALL(ARRAY[1, 2]); + +--Testcase 125: +EXPLAIN VERBOSE +SELECT a, b FROM numbers WHERE a > ALL(ARRAY[0, 1]); +--Testcase 126: +SELECT a, b FROM numbers WHERE a > ALL(ARRAY[0, 1]); + +--Testcase 127: +EXPLAIN VERBOSE +SELECT a, b FROM numbers WHERE a < ALL(ARRAY[2, 3]); +--Testcase 128: +SELECT a, b FROM numbers WHERE a < ALL(ARRAY[2, 3]); + +-- ANY/ALL with TEXT ARRAY const +--Testcase 129: +EXPLAIN VERBOSE +SELECT a, b FROM numbers WHERE b = ANY(ARRAY['One', 'Two']); +--Testcase 130: +SELECT a, b FROM numbers WHERE b = ANY(ARRAY['One', 'Two']); + +--Testcase 131: +EXPLAIN VERBOSE +SELECT a, b FROM numbers WHERE b <> ALL(ARRAY['One', 'Four']); +--Testcase 132: +SELECT a, b FROM numbers WHERE b <> ALL(ARRAY['One', 'Four']); + +--Testcase 133: +EXPLAIN VERBOSE +SELECT a, b FROM numbers WHERE b > ANY(ARRAY['One', 'Two']); +--Testcase 134: +SELECT a, b FROM numbers WHERE b > ANY(ARRAY['One', 'Two']); + +--Testcase 135: +EXPLAIN VERBOSE +SELECT * FROM numbers WHERE b > ALL(ARRAY['Four', 'Five']); +--Testcase 136: +SELECT a, b FROM numbers WHERE b > ALL(ARRAY['Four', 'Five']); + +--Testcase 137: +DROP FOREIGN TABLE numbers; + +--Testcase 138: +ALTER SERVER server1 OPTIONS (SET dbname 'no such database'); +--Testcase 139: +SELECT * FROM t1; +--Testcase 140: +ALTER SERVER server1 OPTIONS (SET dbname 'mydb'); +--Testcase 141: +SELECT * FROM t1; + +-- map time column to both timestamp and text +--Testcase 142: +CREATE FOREIGN TABLE t5(t timestamp OPTIONS (column_name 'time'), tag1 text OPTIONS (column_name 'time'), v1 integer OPTIONS (column_name 'value1')) SERVER server1 OPTIONS (table 'cpu'); +--Testcase 143: +SELECT * FROM t5; + +--get version +--Testcase 144: +\df influxdb_fdw* +--Testcase 145: +SELECT * FROM public.influxdb_fdw_version(); +--Testcase 146: +SELECT influxdb_fdw_version(); +--Test pushdown LIMIT...OFFSET +--Testcase 147: +EXPLAIN (VERBOSE, COSTS OFF) +SELECT tableoid::regclass, * FROM t1 LIMIT 1 OFFSET 0; + +--Testcase 148: +SELECT tableoid::regclass, * FROM t1 LIMIT 1 OFFSET 0; + +--Testcase 149: +EXPLAIN (VERBOSE, COSTS OFF) +SELECT tableoid::regclass, * FROM t1 LIMIT 1 OFFSET 1; + +--Testcase 150: +SELECT tableoid::regclass, * FROM t1 LIMIT 1 OFFSET 1; + +--Testcase 151: +EXPLAIN (VERBOSE, COSTS OFF) +SELECT ctid, * FROM t1 LIMIT 1 OFFSET 0; + +--Testcase 152: +SELECT ctid, * FROM t1 LIMIT 1 OFFSET 0; + +--Testcase 153: +EXPLAIN (VERBOSE, COSTS OFF) +SELECT ctid, * FROM t2 LIMIT 10 OFFSET 20; + +--Testcase 154: +SELECT ctid, * FROM t2 LIMIT 10 OFFSET 20; + +--Testcase 155: +EXPLAIN (VERBOSE, COSTS OFF) +SELECT * FROM + t1 + LEFT JOIN t2 + ON t2.value1 = 123, + LATERAL (SELECT t2.value1, t1.tag1 FROM t1 LIMIT 1 OFFSET 0) AS ss +WHERE t1.value1 = ss.value1; + +--Testcase 156: +EXPLAIN (VERBOSE, COSTS OFF) +SELECT * FROM + t1 + LEFT JOIN t2 + ON t2.value1 = 123, + LATERAL (SELECT t2.value1, t1.tag1 FROM t1 LIMIT 1 OFFSET 0) AS ss1, + LATERAL (SELECT ss1.* from t3 LIMIT 1 OFFSET 20) AS ss2 +WHERE t1.value1 = ss2.value1; + +--Testcase 157: +DROP FOREIGN TABLE cpu; +--Testcase 158: +DROP FOREIGN TABLE t1; +--Testcase 159: +DROP FOREIGN TABLE t2; +--Testcase 160: +DROP FOREIGN TABLE t3; +--Testcase 161: +DROP FOREIGN TABLE t4; +--Testcase 162: +DROP FOREIGN TABLE t5; +--Testcase 163: +DROP FOREIGN TABLE tx; + +-- test INSERT, DELETE +IMPORT FOREIGN SCHEMA public FROM SERVER server1 INTO public OPTIONS(import_time_text 'true'); +--Testcase 164: +SELECT * FROM cpu; +--Testcase 165: +EXPLAIN VERBOSE +INSERT INTO cpu(time, tag1, tag2, value1, value2, value3, value4) VALUES('2021-01-01 00:00:01+09', 'tag1_K', 'tag2_H', 200, 5.5, 'test1', true); +--Testcase 166: +INSERT INTO cpu(time, tag1, tag2, value1, value2, value3, value4) VALUES('2021-01-01 00:00:01+09', 'tag1_K', 'tag2_H', 200, 5.5, 'test', true); +--Testcase 167: +SELECT * FROM cpu; + +--Testcase 168: +EXPLAIN VERBOSE +INSERT INTO cpu(time, tag1, tag2, value1, value2, value3, value4) VALUES('2021-01-02 00:00:02+05', 'tag1_I', 'tag2_E', 300, 15.5, 'test2', false), + ('2029-02-02 00:02:02+04', 'tag1_U', 'tag2_DZ', (SELECT 350), (SELECT i FROM (VALUES(6.9)) AS foo (i)), 'funny', true); +--Testcase 169: +INSERT INTO cpu(time, tag1, tag2, value1, value2, value3, value4) VALUES('2021-01-02 00:00:02+05', 'tag1_I', 'tag2_E', 300, 15.5, 'test2', false), + ('2029-02-02 00:02:02+04', 'tag1_U', 'tag2_DZ', (SELECT 350), (SELECT i FROM (VALUES(6.9)) AS foo (i)), 'funny', true); +--Testcase 170: +SELECT * FROM cpu; + +--Testcase 171: +INSERT INTO cpu(tag2, value1) VALUES('tag2_KH', 400); +--Testcase 172: +SELECT tag1, tag2, value1, value2, value3, value4 FROM cpu; + +--Testcase 173: +EXPLAIN VERBOSE +DELETE FROM cpu WHERE tag2 = 'tag2_KH'; +--Testcase 174: +DELETE FROM cpu WHERE tag2 = 'tag2_KH'; +--Testcase 175: +SELECT tag1, tag2, value1, value2, value3, value4 FROM cpu; + +--Testcase 176: +EXPLAIN VERBOSE +DELETE FROM cpu WHERE time = '2021-01-02 04:00:02+09'; +--Testcase 177: +DELETE FROM cpu WHERE time = '2021-01-02 04:00:02+09'; +--Testcase 178: +SELECT * FROM cpu; + +--Testcase 179: +EXPLAIN VERBOSE +DELETE FROM cpu WHERE time < '2018-07-07' AND tag1 != 'tag1_B'; +--Testcase 180: +DELETE FROM cpu WHERE time < '2018-07-07' AND tag1 != 'tag1_B'; +--Testcase 181: +SELECT * FROM cpu; + +-- Test INSERT, DELETE with time_text column +--Testcase 182: +INSERT INTO cpu(time_text, tag1, tag2, value1, value2, value3, value4) VALUES('2021-02-02T00:00:00Z', 'tag1_D', 'tag2_E', 600, 20.2, 'test3', true); +--Testcase 183: +SELECT * FROM cpu; + +--Testcase 184: +INSERT INTO cpu(time_text, tag1, value2) VALUES('2021-02-02T00:00:00.123456789Z', 'tag1_P', 25.8); +--Testcase 185: +SELECT * FROM cpu; + +--Testcase 186: +INSERT INTO cpu(time_text, tag1, value2) VALUES('2021-02-02 00:00:01', 'tag1_J', 37.1); +--Testcase 187: +SELECT * FROM cpu; + +--Testcase 188: +INSERT INTO cpu(time, time_text, tag1, tag2, value1, value2, value3, value4) VALUES('2021-02-02 00:00:01+05', '2021-02-02T00:00:02.123456789Z', 'tag1_A', 'tag2_B', 200, 5.5, 'test', true); +--Testcase 189: +SELECT * FROM cpu; + +--Testcase 190: +INSERT INTO cpu(time_text, time, tag1, tag2, value1, value2, value3, value4) VALUES('2021-02-03T00:00:03.123456789Z', '2021-03-03 00:00:01+07', 'tag1_C', 'tag2_D', 200, 5.5, 'test', true); +--Testcase 191: +SELECT * FROM cpu; + +--Testcase 192: +EXPLAIN VERBOSE +DELETE FROM cpu WHERE time_text = '2021-02-02T00:00:00.123456789Z'; +--Testcase 193: +DELETE FROM cpu WHERE time_text = '2021-02-02T00:00:00.123456789Z'; +--Testcase 194: +SELECT * FROM cpu; + +--Testcase 195: +EXPLAIN VERBOSE +DELETE FROM cpu WHERE time_text = '2021-02-02T00:00:01Z' AND tag1 = 'tag1_J'; +--Testcase 196: +DELETE FROM cpu WHERE time_text = '2021-02-02T00:00:01Z' AND tag1 = 'tag1_J'; +--Testcase 197: +SELECT * FROM cpu; + +--Testcase 198: +EXPLAIN VERBOSE +DELETE FROM cpu WHERE time_text = '2021-02-02 00:00:00' OR time ='2029-02-02 05:02:02+09'; +--Testcase 199: +DELETE FROM cpu WHERE time_text = '2021-02-02 00:00:00' OR time ='2029-02-02 05:02:02+09'; +--Testcase 200: +SELECT * FROM cpu; + +-- InfluxDB_FDW will store time data for Field values as a strings +--Testcase 204: +CREATE FOREIGN TABLE tmp_time ( +time timestamp, +c1 time, +c2 timestamp, +c3 timestamp with time zone +) SERVER server1 OPTIONS (table 'tmp_time'); +--Testcase 205: +SELECT * FROM tmp_time; +--Testcase 206: +INSERT INTO tmp_time (time, c1) VALUES ('1900-01-01 01:01:01', '01:02:03'); +--Testcase 207: +INSERT INTO tmp_time (time, c1) VALUES ('2100-01-01 01:01:01', '04:05:06'); +--Testcase 208: +INSERT INTO tmp_time (time, c1) VALUES ('1990-01-01 01:01:01', '07:08:09'); +--Testcase 209: +INSERT INTO tmp_time (time, c2) VALUES ('2020-12-27 03:02:56.634467', '1950-02-02 02:02:02'); +--Testcase 210: +INSERT INTO tmp_time (time, c3) VALUES ('2021-12-27 03:02:56.668301', '1800-02-02 02:02:02+9'); +--Testcase 210: +INSERT INTO tmp_time (time, c1, c2, c3) VALUES ('2022-05-06 07:08:09', '07:08:09', '2022-05-06 07:08:09', '2022-05-06 07:08:09+9'); +--Testcase 211: +-- 1800-02-02 02:02:02+9 is Daylight Saving Time (DST) changes in Japan. +-- Timezone setting Japan so it will plus 18s:59 +-- https://www.timeanddate.com/time/zone/japan/tokyo?syear=1850 +SELECT * FROM tmp_time; + +-- Type mis-match +--Testcase 212: +CREATE FOREIGN TABLE datatype_test ( + time timestamp with time zone, + tag1 text, + tag2 text, + value1 int, + value2 text +) SERVER server1 OPTIONS (table 'datatype_test', tags 'tag1,tag2'); + +--Testcase 213: +INSERT INTO datatype_test (tag1, tag2, value1, value2) VALUES ('time', '2021-02-02T00:00:01Z', '1', '2021-02-05T00:00:00Z'); +--Testcase 214: +INSERT INTO datatype_test (tag1, tag2, value1, value2) VALUES ('time', '2022-02-02T00:00:01Z', '2', '2022-02-05T00:00:00Z'); +--Testcase 215: +SELECT tag1, tag2, value1, value2 FROM datatype_test; +-- Using text as timestamp +--Testcase 216: +ALTER FOREIGN TABLE datatype_test ALTER COLUMN tag2 TYPE timestamptz; +--Testcase 217: +ALTER FOREIGN TABLE datatype_test ALTER COLUMN value2 TYPE timestamptz; + +-- SELECT OK without filter +--Testcase 218: +SELECT tag1, tag2, value1, value2 FROM datatype_test; + +-- SELECT with timestamp filter, WHERE clause is pushed down +-- InfluxDB cannot compare correctly, 0 row returned +--Testcase 219: +EXPLAIN (VERBOSE, COSTS OFF) +SELECT tag1, tag2, value1, value2 FROM datatype_test WHERE tag2 > '2021-02-02 00:00:01+00'; +--Testcase 220: +SELECT tag1, tag2, value1, value2 FROM datatype_test WHERE tag2 > '2021-02-02 00:00:01+00'; +--Testcase 221: +EXPLAIN (VERBOSE, COSTS OFF) +SELECT tag1, tag2, value1, value2 FROM datatype_test WHERE value2 > '2021-02-05 00:00:00+00'; +--Testcase 222: +SELECT tag1, tag2, value1, value2 FROM datatype_test WHERE value2 > '2021-02-05 00:00:00+00'; + +--Testcase 223: +ALTER FOREIGN TABLE datatype_test ALTER COLUMN tag2 TYPE text; +--Testcase 224: +ALTER FOREIGN TABLE datatype_test ALTER COLUMN value2 TYPE text; + +-- uses explicit cast, WHERE clause is not pushed down +-- compared correctly by postgres, 1 row returned +--Testcase 225: +EXPLAIN (VERBOSE, COSTS OFF) +SELECT tag1, tag2, value1, value2 FROM datatype_test WHERE tag2::timestamptz > '2021-02-02 00:00:01+00'; +--Testcase 226: +SELECT tag1, tag2, value1, value2 FROM datatype_test WHERE tag2::timestamptz > '2021-02-02 00:00:01+00'; +--Testcase 227: +EXPLAIN (VERBOSE, COSTS OFF) +SELECT tag1, tag2, value1, value2 FROM datatype_test WHERE value2::timestamptz > '2021-02-05 00:00:00+00'; +--Testcase 228: +SELECT tag1, tag2, value1, value2 FROM datatype_test WHERE value2::timestamptz > '2021-02-05 00:00:00+00'; + +-- clean-up +--Testcase 229: +DELETE FROM datatype_test; +--Testcase 230: +DROP FOREIGN TABLE datatype_test; + +-- Recover data +:RECOVER_INIT_TXT_DROP_BUCKET; +:RECOVER_INIT_TXT_CREATE_BUCKET; +:RECOVER_INIT_TXT; + +--Testcase 201: +DROP USER MAPPING FOR CURRENT_USER SERVER server1; +--Testcase 202: +DROP SERVER server1 CASCADE; +--Testcase 203: +DROP EXTENSION influxdb_fdw CASCADE; diff --git a/sql/15.0/init.sql b/sql/16.0/init.sql similarity index 100% rename from sql/15.0/init.sql rename to sql/16.0/init.sql diff --git a/sql/15.0/option.sql b/sql/16.0/option.sql similarity index 100% rename from sql/15.0/option.sql rename to sql/16.0/option.sql diff --git a/sql/14.5/schemaless/add_fields.sql b/sql/16.0/schemaless/add_fields.sql similarity index 86% rename from sql/14.5/schemaless/add_fields.sql rename to sql/16.0/schemaless/add_fields.sql index 503b4d9..6c00ea6 100644 --- a/sql/14.5/schemaless/add_fields.sql +++ b/sql/16.0/schemaless/add_fields.sql @@ -30,7 +30,7 @@ SELECT * FROM sctbl1; --Testcase 7: SELECT max(time), max((fields->>'sig1')::bigint), max((fields->>'sig1')::bigint)+10, max((fields->>'sig1')::bigint)-10, max((fields->>'sig3')::float8), max((fields->>'sig3')::float8)/2 FROM sctbl1 GROUP BY time,(fields->>'sig1')::bigint; --Testcase 8: -SELECT tags->>'device_id' device_id,(fields->>'sig1')::bigint sig1,fields->>'sig2' sig2, (fields->>'sig3')::float8 sig3, (fields->>'sig4')::boolean sig4 from sctbl1 ORDER BY tags->>'device_id'; +SELECT (tags->>'device_id' COLLATE "en_US") device_id,(fields->>'sig1')::bigint sig1,fields->>'sig2' sig2, (fields->>'sig3')::float8 sig3, (fields->>'sig4')::boolean sig4 from sctbl1 ORDER BY (tags->>'device_id' COLLATE "en_US"); --Testcase 9: SELECT bool_or((fields->>'sig1')::bigint <> 10) AND true, bool_and(fields->>'sig2' != 'aghsjfh'), bool_or((fields->>'sig1')::bigint+(fields->>'sig3')::float8 <=5.5) OR false from sctbl1 GROUP BY (fields->>'sig1')::bigint,fields->>'sig2'; --Testcase 10: @@ -38,7 +38,7 @@ SELECT sqrt(abs((fields->>'sig1')::float8)), sqrt(abs((fields->>'sig3')::float8) --Testcase 11: SELECT fields->>'sig2' sig2, mode((fields->>'sig3')::float8) WITHIN GROUP (ORDER BY (fields->>'sig3')::float8) AS m1 from sctbl1 GROUP BY fields->>'sig2'; --Testcase 12: -SELECT upper(fields->>'sig2'), upper(fields->>'sig2'), lower(fields->>'sig2'), lower(fields->>'sig2') FROM sctbl1 ORDER BY 1 ASC,2 DESC,3 ASC,4; +SELECT upper(fields->>'sig2' COLLATE "en_US"), upper(fields->>'sig2'), lower(fields->>'sig2'), lower(fields->>'sig2') FROM sctbl1 ORDER BY 1 ASC,2 DESC,3 ASC,4; -------------------------------------------------------------------------------------------Update data--Add 1 field------------------------------------------------------------------------------------------------------------ --Update data @@ -53,21 +53,21 @@ CREATE FOREIGN TABLE sctbl1 (time timestamp with time zone, tags jsonb OPTIONS(t SELECT * FROM sctbl1; --Select fields,tags --Testcase 16: -SELECT tags->>'device_id' device_id,(fields->>'sig1')::bigint sig1,(fields->>'sig3')::float8 sig3 FROM sctbl1 WHERE NOT (fields->>'sig1')::bigint < (fields->>'sig3')::float8 ORDER BY 1 DESC,2 ASC,3 DESC LIMIT 5 OFFSET 0; +SELECT (tags->>'device_id' COLLATE "en_US") device_id,(fields->>'sig1')::bigint sig1,(fields->>'sig3')::float8 sig3 FROM sctbl1 WHERE NOT (fields->>'sig1')::bigint < (fields->>'sig3')::float8 ORDER BY 1 DESC,2 ASC,3 DESC LIMIT 5 OFFSET 0; --Testcase 17: -SELECT tags->>'device_id' device_id,(fields->>'sig1')::bigint sig1,(fields->>'sig3')::float8 sig3 FROM sctbl1 WHERE (fields->>'sig3')::float8 < 0 ORDER BY 1 DESC,2 ASC,3 DESC LIMIT 5 OFFSET 0; +SELECT (tags->>'device_id' COLLATE "en_US") device_id,(fields->>'sig1')::bigint sig1,(fields->>'sig3')::float8 sig3 FROM sctbl1 WHERE (fields->>'sig3')::float8 < 0 ORDER BY 1 DESC,2 ASC,3 DESC LIMIT 5 OFFSET 0; --Testcase 18: -SELECT tags->>'device_id' device_id,(fields->>'sig1')::bigint sig1,(fields->>'sig3')::float8 sig3 FROM sctbl1 WHERE NOT time >'2020-1-3 20:30:50' ORDER BY 1 DESC,2 ASC,3 DESC LIMIT 5 OFFSET 2; +SELECT (tags->>'device_id' COLLATE "en_US") device_id,(fields->>'sig1')::bigint sig1,(fields->>'sig3')::float8 sig3 FROM sctbl1 WHERE NOT time >'2020-1-3 20:30:50' ORDER BY 1 DESC,2 ASC,3 DESC LIMIT 5 OFFSET 2; --Testcase 19: -SELECT time, tags->>'device_id' device_id,(fields->>'sig1')::bigint sig1,fields->>'sig2' sig2,(fields->>'sig3')::float8 sig3,(fields->>'sig4')::boolean sig4,(fields->>'sig5')::boolean sig5 FROM sctbl1 WHERE true ORDER BY 1 DESC,2 ASC,3 DESC,4,5 LIMIT 5 OFFSET 0; +SELECT time, (tags->>'device_id' COLLATE "en_US") device_id,(fields->>'sig1')::bigint sig1,fields->>'sig2' sig2,(fields->>'sig3')::float8 sig3,(fields->>'sig4')::boolean sig4,(fields->>'sig5')::boolean sig5 FROM sctbl1 WHERE true ORDER BY 1 DESC,2 ASC,3 DESC,4,5 LIMIT 5 OFFSET 0; --Testcase 20: SELECT time, tags->>'device_id' device_id,(fields->>'sig1')::bigint sig1,fields->>'sig2' sig2,(fields->>'sig3')::float8 sig3,(fields->>'sig4')::boolean sig4,(fields->>'sig5')::boolean sig5 FROM sctbl1 WHERE false ORDER BY 1 DESC,2 ASC,3 DESC,4,5 LIMIT 5 OFFSET 0; --Testcase 21: SELECT (fields->>'sig1')::bigint sig1,(fields->>'sig3')::float8 sig3, (fields->>'sig4')::boolean sig4,(fields->>'sig5')::boolean sig5 FROM sctbl1 WHERE (fields->>'sig1')::bigint BETWEEN 0 AND 10000 ORDER BY (fields->>'sig1')::bigint DESC LIMIT 5 OFFSET 0; --Testcase 22: -SELECT time, tags->>'device_id' device_id,(fields->>'sig1')::bigint sig1,fields->>'sig2' sig2,(fields->>'sig3')::float8 sig3,(fields->>'sig4')::boolean sig4,(fields->>'sig5')::boolean sig5 FROM sctbl1 WHERE fields->>'sig2' LIKE 'x%' ORDER BY 1 DESC,2 ASC,3 DESC,4,5 LIMIT 5 OFFSET 0; +SELECT time, (tags->>'device_id' COLLATE "en_US") device_id,(fields->>'sig1')::bigint sig1,fields->>'sig2' sig2,(fields->>'sig3')::float8 sig3,(fields->>'sig4')::boolean sig4,(fields->>'sig5')::boolean sig5 FROM sctbl1 WHERE fields->>'sig2' LIKE 'x%' ORDER BY 1 DESC,2 ASC,3 DESC,4,5 LIMIT 5 OFFSET 0; --Testcase 23: -SELECT tags->>'device_id' device_id,(fields->>'sig1')::bigint sig1,fields->>'sig2' sig2,(fields->>'sig3')::float8 sig3,(fields->>'sig4')::boolean sig4 FROM sctbl1 WHERE NOT EXISTS (SELECT fields->>'sig2' FROM sctbl1 WHERE fields->>'sig2'='AHW') ORDER BY 1 DESC,2 ASC LIMIT 5 OFFSET 0; +SELECT (tags->>'device_id' COLLATE "en_US") device_id,(fields->>'sig1')::bigint sig1,fields->>'sig2' sig2,(fields->>'sig3')::float8 sig3,(fields->>'sig4')::boolean sig4 FROM sctbl1 WHERE NOT EXISTS (SELECT fields->>'sig2' FROM sctbl1 WHERE fields->>'sig2'='AHW') ORDER BY 1 DESC,2 ASC LIMIT 5 OFFSET 0; --Testcase 24: SELECT (fields->>'sig1')::bigint sig1,fields->>'sig2' sig2, (fields->>'sig3')::float8 sig3, (fields->>'sig4')::boolean sig4,(fields->>'sig5')::boolean sig5 FROM sctbl1 WHERE (fields->>'sig3')::float8 < ALL (SELECT (fields->>'sig1')::bigint FROM sctbl1 WHERE (fields->>'sig1')::bigint > 0) ORDER BY 1 DESC,2 ASC,3 DESC LIMIT 5 OFFSET 0; --Testcase 25: @@ -81,15 +81,15 @@ SELECT (fields->>'sig1')::bigint sig1,fields->>'sig2' sig2,(fields->>'sig3')::fl --Testcase 29: SELECT (fields->>'sig1')::bigint sig1,(fields->>'sig3')::float8 sig3,(fields->>'sig5')::boolean sig5,(fields->>'sig1')::bigint+(fields->>'sig3')::float8 as ss FROM sctbl1 WHERE fields->>'sig2' IS NULL ORDER BY (fields->>'sig1')::bigint DESC,fields->>'sig2' ASC LIMIT 5 OFFSET 0; --Testcase 30: -SELECT (fields->>'sig1')::bigint sig1,(fields->>'sig3')::float8 sig3,(fields->>'sig5')::boolean sig5,(fields->>'sig1')::bigint/(fields->>'sig3')::float8 as dd FROM sctbl1 WHERE fields->>'sig2' IS NOT NULL ORDER BY fields->>'sig2' DESC,(fields->>'sig1')::bigint ASC LIMIT 5 OFFSET 0; +SELECT (fields->>'sig1')::bigint sig1,(fields->>'sig3')::float8 sig3,(fields->>'sig5')::boolean sig5,(fields->>'sig1')::bigint/(fields->>'sig3')::float8 as dd FROM sctbl1 WHERE (fields->>'sig2' COLLATE "en_US") IS NOT NULL ORDER BY (fields->>'sig2' COLLATE "en_US") DESC,(fields->>'sig1')::bigint ASC LIMIT 5 OFFSET 0; --Testcase 31: -SELECT (fields->>'sig1')::bigint sig1,(fields->>'sig3')::float8 sig3,(fields->>'sig5')::boolean sig5,(fields->>'sig1')::bigint*(fields->>'sig3')::float8 as mm FROM sctbl1 WHERE NOT (fields->>'sig1')::bigint=5 ORDER BY fields->>'sig2' DESC LIMIT 5 OFFSET 0; +SELECT (fields->>'sig1')::bigint sig1,(fields->>'sig3')::float8 sig3,(fields->>'sig5')::boolean sig5,(fields->>'sig1')::bigint*(fields->>'sig3')::float8 as mm FROM sctbl1 WHERE NOT (fields->>'sig1')::bigint=5 ORDER BY (fields->>'sig2' COLLATE "en_US") DESC LIMIT 5 OFFSET 0; --Testcase 32: SELECT (fields->>'sig1')::bigint sig1,fields->>'sig2' sig2,(fields->>'sig3')::float8 sig3,(fields->>'sig4')::boolean sig4,(fields->>'sig5')::boolean sig5 FROM ( SELECT * FROM sctbl1 WHERE (fields->>'sig1')::bigint>-1000 AND (fields->>'sig3')::float8 < 1 ) AS tb1 WHERE (fields->>'sig1')::bigint != 0 AND (fields->>'sig3')::float8=0.32 ORDER BY 1 DESC,2 ASC LIMIT 5 OFFSET 0; --Testcase 33: SELECT (fields->>'sig1')::bigint sig1, fields->>'sig2' sig2, (fields->>'sig3')::float8 sig3, (fields->>'sig4')::boolean sig4, (fields->>'sig5')::boolean sig5 FROM ( SELECT * FROM sctbl1 WHERE (fields->>'sig1')::bigint>-1000 AND (fields->>'sig3')::float8 < 1 ) AS tb1 WHERE (fields->>'sig3')::float8 > -1.0 OR fields->>'sig2' != 'Hello' ORDER BY 1 DESC,2 ASC,3 DESC,4,5 LIMIT 5 OFFSET 0; --Testcase 34: -SELECT (fields->>'sig1')::bigint sig1,fields->>'sig2' sig2,(fields->>'sig3')::float8 sig3,(fields->>'sig4')::boolean sig4,(fields->>'sig5')::boolean sig5 FROM ( SELECT * FROM sctbl1 WHERE (fields->>'sig1')::bigint>-1000 AND (fields->>'sig3')::float8 < 1 ) AS tb1 WHERE (fields->>'sig3')::float8 < -0.1 AND fields->>'sig2' > 'Mee' ORDER BY 1 DESC,2 ASC,3 DESC,4,5 LIMIT 5 OFFSET 0; +SELECT (fields->>'sig1')::bigint sig1,fields->>'sig2' sig2,(fields->>'sig3')::float8 sig3,(fields->>'sig4')::boolean sig4,(fields->>'sig5')::boolean sig5 FROM ( SELECT * FROM sctbl1 WHERE (fields->>'sig1')::bigint>-1000 AND (fields->>'sig3')::float8 < 1 ) AS tb1 WHERE (fields->>'sig3')::float8 < -0.1 AND (fields->>'sig2' COLLATE "en_US") > 'Mee' ORDER BY 1 DESC,2 ASC,3 DESC,4,5 LIMIT 5 OFFSET 0; --Testcase 35: SELECT (fields->>'sig1')::bigint sig1,fields->>'sig2' sig2,(fields->>'sig3')::float8 sig3,(fields->>'sig4')::boolean sig4,(fields->>'sig5')::boolean sig5 FROM ( SELECT * FROM sctbl1 WHERE (fields->>'sig1')::bigint>-1000 AND (fields->>'sig3')::float8 < 1 ) AS tb1 WHERE (fields->>'sig3')::float8 IN (-1,1,0,2,-2) ORDER BY 1 DESC,2 ASC,3 DESC,4,5 LIMIT 5 OFFSET 0; --Testcase 36: @@ -101,7 +101,7 @@ SELECT (fields->>'sig1')::bigint sig1,fields->>'sig2' sig2,(fields->>'sig3')::fl --Testcase 39: SELECT (fields->>'sig1')::bigint sig1,fields->>'sig2' sig2,(fields->>'sig3')::float8 sig3,(fields->>'sig4')::boolean sig4,(fields->>'sig5')::boolean sig5 FROM ( SELECT * FROM sctbl1 WHERE (fields->>'sig1')::bigint>-1000 AND (fields->>'sig3')::float8 < 1 ) AS tb1 WHERE fields->>'sig3'=ANY (ARRAY(SELECT fields->>'sig3' FROM sctbl1 WHERE (fields->>'sig1')::bigint%2=0)) ORDER BY 1 DESC,2 ASC,3 DESC,4,5 LIMIT 5 OFFSET 1; --Testcase 40: -SELECT time, fields->>'sig2' sig2 FROM sctbl1 WHERE fields->>'sig2' <= 'A' AND (fields->>'sig3')::float8 <>-5 AND (fields->>'sig1')::bigint <> 100 ORDER BY 1 ASC,2 DESC LIMIT 5 OFFSET 1; +SELECT time, (fields->>'sig2' COLLATE "en_US") sig2 FROM sctbl1 WHERE (fields->>'sig2' COLLATE "en_US") <= 'A' AND (fields->>'sig3')::float8 <>-5 AND (fields->>'sig1')::bigint <> 100 ORDER BY 1 ASC,2 DESC LIMIT 5 OFFSET 1; --Select aggregate functions --Testcase 41: @@ -131,7 +131,7 @@ SELECT min(time)+'10 days'::interval, min((fields->>'sig1')::bigint + (fields->> --Testcase 53: SELECT floor((fields->>'sig1')::bigint*(fields->>'sig3')::float8), floor((fields->>'sig1')::bigint/(fields->>'sig3')::float8) FROM sctbl1 WHERE ((fields->>'sig3')::float8 - 1)/3 != 1 GROUP BY fields->>'sig1', fields->>'sig3' HAVING sum((fields->>'sig3')::float8) < avg((fields->>'sig1')::float8) ORDER BY 1 ASC,2 DESC LIMIT 5 OFFSET 0; --Testcase 54: -SELECT time, tags->>'device_id' device_id, pow((fields->>'sig1')::bigint,-2) FROM sctbl1 WHERE ((fields->>'sig3')::float8 - 1)/3 != 1 GROUP BY time, tags->>'device_id', fields->>'sig1' ORDER BY 1 ASC,2 DESC LIMIT 5 OFFSET 0; +SELECT time, (tags->>'device_id' COLLATE "en_US") device_id, pow((fields->>'sig1')::bigint,-2) FROM sctbl1 WHERE ((fields->>'sig3')::float8 - 1)/3 != 1 GROUP BY time, (tags->>'device_id' COLLATE "en_US"), fields->>'sig1' ORDER BY 1 ASC,2 DESC LIMIT 5 OFFSET 0; --Testcase 55: SELECT min(time)+'10 days'::interval, min((fields->>'sig3')::float8) FROM sctbl1 WHERE false GROUP BY fields->>'sig1',fields->>'sig2', fields->>'sig3' HAVING sum((fields->>'sig3')::float8) < avg((fields->>'sig1')::float8) ORDER BY 1 ASC,2 DESC LIMIT 5 OFFSET 0; --Testcase 56: @@ -141,7 +141,7 @@ SELECT max((fields->>'sig3')::float8), count(*), exists(SELECT * FROM sctbl1 WHE --Join table, each table has 5 fields --Testcase 58: -SELECT * FROM sctbl1 s1 FULL JOIN sctbl2 s2 ON s1.tags->>'device_id'=s2.tags->>'device_id'; +SELECT * FROM sctbl1 s1 FULL JOIN sctbl2 s2 ON (s1.tags->>'device_id' COLLATE "en_US")=(s2.tags->>'device_id' COLLATE "en_US"); --Testcase 59: SELECT s1.tags->>'device_id' device_id,(s1.fields->>'sig1')::bigint sig1,s1.fields->>'sig2' sig2,(s1.fields->>'sig3')::float8 sig3,(s1.fields->>'sig4')::boolean sig4,s2.fields->>'sig5' sig5 FROM sctbl1 s1 LEFT JOIN sctbl2 s2 ON (s1.fields->>'sig4')::boolean=(s2.fields->>'sig4')::boolean; --Testcase 60: @@ -174,13 +174,13 @@ SELECT sum('NaN'::numeric) FROM sctbl1; --Select fields,tags --Testcase 70: -SELECT tags->>'device_id' device_id,(fields->>'sig1')::bigint sig1,(fields->>'sig3')::float8 sig3,(fields->>'sig6')::bigint sig6 FROM sctbl1 WHERE NOT (fields->>'sig6')::bigint < (fields->>'sig1')::bigint ORDER BY 1 DESC,2 ASC,3 DESC LIMIT 15 OFFSET 0; +SELECT (tags->>'device_id' COLLATE "en_US") device_id,(fields->>'sig1')::bigint sig1,(fields->>'sig3')::float8 sig3,(fields->>'sig6')::bigint sig6 FROM sctbl1 WHERE NOT (fields->>'sig6')::bigint < (fields->>'sig1')::bigint ORDER BY 1 DESC,2 ASC,3 DESC LIMIT 15 OFFSET 0; --Testcase 71: -SELECT tags->>'device_id' device_id,(fields->>'sig1')::bigint sig1,(fields->>'sig3')::float8 sig3,(fields->>'sig7')::float8 sig7 FROM sctbl1 WHERE (fields->>'sig7')::float8 < 0 ORDER BY 1 DESC,2 ASC,3 DESC LIMIT 15 OFFSET 0; +SELECT (tags->>'device_id' COLLATE "en_US") device_id,(fields->>'sig1')::bigint sig1,(fields->>'sig3')::float8 sig3,(fields->>'sig7')::float8 sig7 FROM sctbl1 WHERE (fields->>'sig7')::float8 < 0 ORDER BY 1 DESC,2 ASC,3 DESC LIMIT 15 OFFSET 0; --Testcase 72: -SELECT tags->>'device_id' device_id,(fields->>'sig1')::bigint sig1,(fields->>'sig3')::float8 sig3,(fields->>'sig8')::float8 sig8 FROM sctbl1 WHERE NOT time >'2020-1-3 20:30:50' ORDER BY 1 DESC,2 ASC,3 DESC LIMIT 15 OFFSET 2; +SELECT (tags->>'device_id' COLLATE "en_US") device_id,(fields->>'sig1')::bigint sig1,(fields->>'sig3')::float8 sig3,(fields->>'sig8')::float8 sig8 FROM sctbl1 WHERE NOT time >'2020-1-3 20:30:50' ORDER BY 1 DESC,2 ASC,3 DESC LIMIT 15 OFFSET 2; --Testcase 73: -SELECT time, tags->>'device_id' device_id,(fields->>'sig1')::bigint sig1,fields->>'sig2' sig2,(fields->>'sig3')::float8 sig3,(fields->>'sig4')::boolean sig4,(fields->>'sig5')::boolean sig5,(fields->>'sig6')::bigint sig6,(fields->>'sig7')::float8 sig7,(fields->>'sig8')::float8 sig8,(fields->>'sig9')::float8 sig9,(fields->>'sig10')::int sig10,fields->>'sig11' sig11,fields->>'sig12' sig12,(fields->>'sig13')::boolean sig13,fields->>'sig14' sig14,(fields->>'sig15')::bigint sig15,(fields->>'sig16')::bigint sig16,(fields->>'sig17')::bigint sig17,fields->>'sig18' sig18,fields->>'sig19' sig19,fields->>'sig20' sig20,(fields->>'sig21')::boolean sig21,fields->>'sig22' sig22,(fields->>'sig23')::bigint sig23,(fields->>'sig24')::int sig24,(fields->>'sig25')::float8 sig25 FROM sctbl1 WHERE true ORDER BY 1 DESC,2 ASC,3 DESC,4,5 LIMIT 15 OFFSET 0; +SELECT time, (tags->>'device_id' COLLATE "en_US") device_id,(fields->>'sig1')::bigint sig1,fields->>'sig2' sig2,(fields->>'sig3')::float8 sig3,(fields->>'sig4')::boolean sig4,(fields->>'sig5')::boolean sig5,(fields->>'sig6')::bigint sig6,(fields->>'sig7')::float8 sig7,(fields->>'sig8')::float8 sig8,(fields->>'sig9')::float8 sig9,(fields->>'sig10')::int sig10,fields->>'sig11' sig11,fields->>'sig12' sig12,(fields->>'sig13')::boolean sig13,fields->>'sig14' sig14,(fields->>'sig15')::bigint sig15,(fields->>'sig16')::bigint sig16,(fields->>'sig17')::bigint sig17,fields->>'sig18' sig18,fields->>'sig19' sig19,fields->>'sig20' sig20,(fields->>'sig21')::boolean sig21,fields->>'sig22' sig22,(fields->>'sig23')::bigint sig23,(fields->>'sig24')::int sig24,(fields->>'sig25')::float8 sig25 FROM sctbl1 WHERE true ORDER BY 1 DESC,2 ASC,3 DESC,4,5 LIMIT 15 OFFSET 0; --Testcase 74: SELECT time, tags->>'device_id' device_id,(fields->>'sig1')::bigint sig1,fields->>'sig2' sig2,(fields->>'sig3')::float8 sig3,(fields->>'sig4')::boolean sig4,(fields->>'sig5')::boolean sig5,(fields->>'sig6')::bigint sig6,(fields->>'sig7')::float8 sig7,(fields->>'sig8')::float8 sig8,(fields->>'sig9')::float8 sig9,(fields->>'sig10')::int sig10,fields->>'sig11' sig11,fields->>'sig12' sig12,(fields->>'sig13')::boolean sig13,fields->>'sig14' sig14,(fields->>'sig15')::bigint sig15,(fields->>'sig16')::bigint sig16,(fields->>'sig17')::bigint sig17,fields->>'sig18' sig18,fields->>'sig19' sig19,fields->>'sig20' sig20,(fields->>'sig21')::boolean sig21,fields->>'sig22' sig22,(fields->>'sig23')::bigint sig23,(fields->>'sig24')::int sig24,(fields->>'sig25')::float8 sig25 FROM sctbl1 WHERE false ORDER BY 1 DESC,2 ASC,3 DESC,4,5 LIMIT 15 OFFSET 0; --Testcase 75: @@ -188,7 +188,7 @@ SELECT (fields->>'sig1')::bigint sig1,(fields->>'sig9')::float8 sig9, (fields->> --Testcase 76: SELECT * FROM sctbl1 WHERE fields->>'sig11' LIKE 'w%' ORDER BY fields->>'sig11' DESC LIMIT 15 OFFSET 0; --Testcase 77: -SELECT tags->>'device_id' device_id,(fields->>'sig1')::bigint sig1,fields->>'sig2' sig2,fields->>'sig12' sig12,(fields->>'sig13')::boolean sig13 FROM sctbl1 WHERE NOT EXISTS (SELECT fields->>'sig12' FROM sctbl1 WHERE fields->>'sig11'='33') ORDER BY tags->>'device_id' DESC,(fields->>'sig1')::bigint ASC LIMIT 15 OFFSET 0; +SELECT tags->>'device_id' device_id,(fields->>'sig1')::bigint sig1,fields->>'sig2' sig2,fields->>'sig12' sig12,(fields->>'sig13')::boolean sig13 FROM sctbl1 WHERE NOT EXISTS (SELECT fields->>'sig12' FROM sctbl1 WHERE fields->>'sig11'='33') ORDER BY (tags->>'device_id' COLLATE "en_US") DESC,(fields->>'sig1')::bigint ASC LIMIT 15 OFFSET 0; --Testcase 78: SELECT (fields->>'sig1')::bigint sig1,fields->>'sig2' sig2,(fields->>'sig3')::float8 sig3,fields->>'sig14' sig14,(fields->>'sig15')::bigint sig15 FROM sctbl1 WHERE (fields->>'sig9')::float8 < ALL (SELECT (fields->>'sig8')::float8 FROM sctbl1 WHERE (fields->>'sig1')::bigint > 0 AND fields->>'sig8' IS NOT NULL) ORDER BY 1 DESC,2 ASC,3 DESC LIMIT 15 OFFSET 0; --Testcase 79: @@ -252,7 +252,7 @@ SELECT min(time)+'10 days'::interval, min((fields->>'sig10')::bigint + (fields-> --Testcase 107: SELECT floor((fields->>'sig23')::bigint*(fields->>'sig25')::float8), floor((fields->>'sig24')::bigint/(fields->>'sig25')::float8) FROM sctbl1 WHERE ((fields->>'sig25')::float8 - 1)/3 != 1 GROUP BY (fields->>'sig23')::bigint, (fields->>'sig24')::bigint,(fields->>'sig25')::float8 HAVING sum((fields->>'sig23')::bigint) > avg((fields->>'sig24')::bigint) ORDER BY 1 ASC,2 DESC LIMIT 15 OFFSET 0; --Testcase 108: -SELECT time, tags->>'device_id' device_id, pow((fields->>'sig25')::float8,2) FROM sctbl1 WHERE ((fields->>'sig25')::float8 - 1)/3 != 1 GROUP BY time,tags->>'device_id',fields->>'sig25' ORDER BY 1 ASC,2 DESC LIMIT 15 OFFSET 0; +SELECT time, (tags->>'device_id' COLLATE "en_US") device_id, pow((fields->>'sig25')::float8,2) FROM sctbl1 WHERE ((fields->>'sig25')::float8 - 1)/3 != 1 GROUP BY time,(tags->>'device_id' COLLATE "en_US"),fields->>'sig25' ORDER BY 1 ASC,2 DESC LIMIT 15 OFFSET 0; --Testcase 109: SELECT min(time)+'10 days'::interval, min((fields->>'sig23')::bigint) FROM sctbl1 WHERE false GROUP BY (fields->>'sig23')::bigint HAVING sum((fields->>'sig23')::bigint) > avg((fields->>'sig24')::bigint) ORDER BY 1 ASC,2 DESC LIMIT 15 OFFSET 0; --Testcase 110: @@ -264,13 +264,13 @@ SELECT (fields->>'sig9')::float8 sig9, abs(avg((fields->>'sig16')::bigint)),stri --Join table --Testcase 113: -SELECT s1.tags->>'device_id' device_id,(s1.fields->>'sig21')::boolean sig21,s1.fields->>'sig22' sig22,(s1.fields->>'sig23')::bigint sig23,(s1.fields->>'sig24')::int sig24,(s1.fields->>'sig25')::float8 sig25 FROM sctbl1 s1 FULL JOIN sctbl2 s2 ON s1.tags->>'device_id'=s2.tags->>'device_id' ORDER BY device_id,sig21,sig22,sig23,sig24,sig25; +SELECT (s1.tags->>'device_id' COLLATE "en_US") device_id,(s1.fields->>'sig21')::boolean sig21,s1.fields->>'sig22' sig22,(s1.fields->>'sig23')::bigint sig23,(s1.fields->>'sig24')::int sig24,(s1.fields->>'sig25')::float8 sig25 FROM sctbl1 s1 FULL JOIN sctbl2 s2 ON s1.tags->>'device_id'=s2.tags->>'device_id' ORDER BY device_id,sig21,sig22,sig23,sig24,sig25; --Testcase 114: SELECT s1.tags->>'device_id' device_id,(s1.fields->>'sig21')::boolean sig21,s1.fields->>'sig22' sig22,(s1.fields->>'sig23')::bigint sig23,(s2.fields->>'sig4')::boolean sig4,s2.fields->>'sig5' sig5 FROM sctbl1 s1 LEFT JOIN sctbl2 s2 ON (s1.fields->>'sig21')::boolean=(s2.fields->>'sig4')::boolean; --Testcase 115: SELECT s1.device_id,s1.sig21,s1.sig22,s1.sig23,s1.sig24,s1.sig25 FROM (SELECT time, tags->>'device_id' device_id, (fields->>'sig1')::bigint sig1, fields->>'sig2' sig2, (fields->>'sig3')::float8 sig3, (fields->>'sig4')::boolean sig4,(fields->>'sig5')::boolean sig5,(fields->>'sig6')::bigint sig6, (fields->>'sig7')::float8 sig7,(fields->>'sig8')::float8 sig8,(fields->>'sig9')::float8 sig9,(fields->>'sig10')::bigint sig10,fields->>'sig11' sig11,fields->>'sig12' sig12, (fields->>'sig13')::boolean sig13, fields->>'sig14' sig14, (fields->>'sig15')::bigint sig15,(fields->>'sig16')::bigint sig16, (fields->>'sig17')::bigint sig17, fields->>'sig18' sig18,fields->>'sig19' sig19, fields->>'sig20' sig20, (fields->>'sig21')::boolean sig21, fields->>'sig22' sig22, (fields->>'sig23')::bigint sig23, (fields->>'sig24')::bigint sig24, (fields->>'sig25')::float8 sig25 FROM sctbl1) s1 RIGHT JOIN (SELECT time, tags->>'device_id' device_id, (fields->>'sig1')::bigint sig1, fields->>'sig2' sig2, (fields->>'sig3')::float8 sig3, (fields->>'sig4')::boolean sig4, (fields->>'sig5')::boolean sig5 FROM sctbl2) s2 using(sig1) where s2.sig3 != 0; --Testcase 116: -SELECT * FROM (SELECT time, tags->>'device_id' device_id, (fields->>'sig1')::bigint sig1, fields->>'sig2' sig2, (fields->>'sig3')::float8 sig3, (fields->>'sig4')::boolean sig4,(fields->>'sig5')::boolean sig5,(fields->>'sig6')::bigint sig6, (fields->>'sig7')::float8 sig7,(fields->>'sig8')::float8 sig8,(fields->>'sig9')::float8 sig9,(fields->>'sig10')::bigint sig10,fields->>'sig11' sig11,fields->>'sig12' sig12, (fields->>'sig13')::boolean sig13, fields->>'sig14' sig14, (fields->>'sig15')::bigint sig15,(fields->>'sig16')::bigint sig16, (fields->>'sig17')::bigint sig17, fields->>'sig18' sig18,fields->>'sig19' sig19, fields->>'sig20' sig20, (fields->>'sig21')::boolean sig21, fields->>'sig22' sig22, (fields->>'sig23')::bigint sig23, (fields->>'sig24')::bigint sig24, (fields->>'sig25')::float8 sig25 FROM sctbl1) s1 FULL OUTER JOIN (SELECT time, tags->>'device_id' device_id, (fields->>'sig1')::bigint sig1, fields->>'sig2' sig2, (fields->>'sig3')::float8 sig3, (fields->>'sig4')::boolean sig4,fields->>'sig5' sig5 FROM sctbl2) s2 USING(sig2) ORDER BY s1.sig2, s1.time, s1.device_id, s2.time, s2.device_id; +SELECT * FROM (SELECT time, tags->>'device_id' device_id, (fields->>'sig1')::bigint sig1, fields->>'sig2' sig2, (fields->>'sig3')::float8 sig3, (fields->>'sig4')::boolean sig4,(fields->>'sig5')::boolean sig5,(fields->>'sig6')::bigint sig6, (fields->>'sig7')::float8 sig7,(fields->>'sig8')::float8 sig8,(fields->>'sig9')::float8 sig9,(fields->>'sig10')::bigint sig10,fields->>'sig11' sig11,fields->>'sig12' sig12, (fields->>'sig13')::boolean sig13, fields->>'sig14' sig14, (fields->>'sig15')::bigint sig15,(fields->>'sig16')::bigint sig16, (fields->>'sig17')::bigint sig17, fields->>'sig18' sig18,fields->>'sig19' sig19, fields->>'sig20' sig20, (fields->>'sig21')::boolean sig21, fields->>'sig22' sig22, (fields->>'sig23')::bigint sig23, (fields->>'sig24')::bigint sig24, (fields->>'sig25')::float8 sig25 FROM sctbl1) s1 FULL OUTER JOIN (SELECT time, tags->>'device_id' device_id, (fields->>'sig1')::bigint sig1, fields->>'sig2' sig2, (fields->>'sig3')::float8 sig3, (fields->>'sig4')::boolean sig4,fields->>'sig5' sig5 FROM sctbl2) s2 USING(sig2) ORDER BY s1.sig2 COLLATE "en_US", s1.time, s1.device_id, s2.time, s2.device_id; --Testcase 117: SELECT s2.device_id,s2.sig1,s2.sig2,s2.sig3,s2.sig4,s2.sig5 FROM (SELECT time, tags->>'device_id' device_id, (fields->>'sig1')::bigint sig1, fields->>'sig2' sig2, (fields->>'sig3')::float8 sig3, (fields->>'sig4')::boolean sig4,(fields->>'sig5')::boolean sig5,(fields->>'sig6')::bigint sig6, (fields->>'sig7')::float8 sig7,(fields->>'sig8')::float8 sig8,(fields->>'sig9')::float8 sig9,(fields->>'sig10')::bigint sig10,fields->>'sig11' sig11,fields->>'sig12' sig12, (fields->>'sig13')::boolean sig13, fields->>'sig14' sig14, (fields->>'sig15')::bigint sig15,(fields->>'sig16')::bigint sig16, (fields->>'sig17')::bigint sig17, fields->>'sig18' sig18,fields->>'sig19' sig19, fields->>'sig20' sig20, (fields->>'sig21')::boolean sig21, fields->>'sig22' sig22, (fields->>'sig23')::bigint sig23, (fields->>'sig24')::bigint sig24, (fields->>'sig25')::float8 sig25 FROM sctbl1) s1 NATURAL JOIN (SELECT time, tags->>'device_id' device_id, (fields->>'sig1')::bigint sig1, fields->>'sig2' sig2, (fields->>'sig3')::float8 sig3, (fields->>'sig4')::boolean sig4,fields->>'sig5' sig5 FROM sctbl2) s2; --Testcase 118: @@ -279,7 +279,11 @@ SELECT s1.device_id,s1.sig11,s1.sig12,s1.sig13,s1.sig14,s1.sig15 FROM (SELECT ti --Clean --Testcase 119: DROP FOREIGN TABLE sctbl1; +--Testcase 120: DROP FOREIGN TABLE sctbl2; +--Testcase 121: DROP USER MAPPING FOR CURRENT_USER SERVER influxdb_svr; +--Testcase 122: DROP SERVER influxdb_svr CASCADE; +--Testcase 123: DROP EXTENSION influxdb_fdw; diff --git a/sql/14.5/schemaless/add_multi_key.sql b/sql/16.0/schemaless/add_multi_key.sql similarity index 93% rename from sql/14.5/schemaless/add_multi_key.sql rename to sql/16.0/schemaless/add_multi_key.sql index 2575cf5..73837a2 100644 --- a/sql/14.5/schemaless/add_multi_key.sql +++ b/sql/16.0/schemaless/add_multi_key.sql @@ -50,7 +50,7 @@ SELECT max(time), max((fields->>'c3')::bigint), max((fields->>'c3')::bigint)+10, --Testcase 17: SELECT count(fields->>'c2'), (fields->>'c3')::bigint c3, fields->>'c4' c4 from sctbl3 GROUP BY fields->>'c2'; --Testcase 18: -SELECT 32 + (fields->>'c3')::bigint, (fields->>'c3')::bigint + (fields->>'c3')::bigint from sctbl3 GROUP BY fields->>'c3', fields->>'c5', fields->>'c2' ORDER BY fields->>'c2'; +SELECT 32 + (fields->>'c3')::bigint, (fields->>'c3')::bigint + (fields->>'c3')::bigint from sctbl3 GROUP BY fields->>'c3', fields->>'c5', (fields->>'c2' COLLATE "en_US") ORDER BY (fields->>'c2' COLLATE "en_US"); --Testcase 19: SELECT max(fields->>'c2'), min((fields->>'c3')::bigint), max((fields->>'c3')::bigint) from sctbl3 GROUP BY fields->>'c3' ORDER BY (fields->>'c3')::bigint; --Testcase 20: @@ -60,7 +60,7 @@ SELECT count(*), count(time), count (DISTINCT (fields->>'c3')::bigint), count (A --Testcase 22: SELECT stddev((fields->>'c3')::bigint), stddev((fields->>'c3')::bigint ORDER BY (fields->>'c3')::bigint) FROM sctbl3 GROUP BY time ORDER BY 1 ASC,2 DESC; --Testcase 23: -SELECT string_agg(fields->>'c2', ';' ORDER BY fields->>'c2') FROM sctbl3 GROUP BY fields->>'c2' ORDER BY 1; +SELECT string_agg(fields->>'c2' COLLATE "en_US", ';' ORDER BY fields->>'c2') FROM sctbl3 GROUP BY fields->>'c2' ORDER BY 1; --Testcase 24: SELECT every((fields->>'c3')::bigint>0), every((fields->>'c3')::bigint != (fields->>'c3')::bigint) FROM sctbl3 GROUP BY time ORDER BY 1 ASC,2 DESC; --Testcase 25: @@ -152,7 +152,7 @@ SELECT time,fields->>'c2' c2,(fields->>'c3')::bigint c3,(fields->>'c4')::double -- Select many target aggregate in one query and combine with condition --Testcase 62: -SELECT upper(fields->>'c2'), upper(fields->>'c2'), lower(fields->>'c2'), lower(fields->>'c2') FROM sctbl3 ORDER BY 1 ASC,2 DESC,3 ASC,4; +SELECT upper(fields->>'c2' COLLATE "en_US"), upper(fields->>'c2' COLLATE "en_US"), lower(fields->>'c2' COLLATE "en_US"), lower(fields->>'c2' COLLATE "en_US") FROM sctbl3 ORDER BY 1 ASC,2 DESC,3 ASC,4; --Testcase 63: SELECT max(time), min((fields->>'c3')::bigint), sum((fields->>'c3')::bigint ORDER BY (fields->>'c3')::bigint), count(*), avg((fields->>'c3')::bigint ORDER BY (fields->>'c3')::bigint) FROM view_sctbl3 GROUP BY time ORDER BY 1 DESC,2 ASC,3 DESC,4,5; --Testcase 64: @@ -176,13 +176,13 @@ SELECT count(fields->>'c2'), bit_and((fields->>'c3')::bigint), bit_or((fields->> --Testcase 73: SELECT array_agg((fields->>'c3')::bigint-(fields->>'c3')::bigint-(fields->>'c3')::bigint), array_agg((fields->>'c3')::bigint/(fields->>'c3')::bigint*(fields->>'c3')::bigint), array_agg(((fields->>'c3')::bigint+(fields->>'c3')::bigint/(fields->>'c3')::bigint)*-1000), array_agg((fields->>'c3')::bigint*(fields->>'c3')::bigint-(fields->>'c3')::bigint), array_agg(((fields->>'c3')::bigint-(fields->>'c3')::bigint+(fields->>'c3')::bigint)+9999999999999.998) from sctbl3 GROUP BY (fields->>'c3')::bigint, (fields->>'c3')::bigint ORDER BY 1, 2, 3, 4, 5; --Testcase 74: -SELECT avg((fields->>'c3')::bigint-(fields->>'c3')::bigint-(fields->>'c3')::bigint)-0.567-avg((fields->>'c3')::bigint/3+(fields->>'c3')::bigint)+17.55435, avg((fields->>'c3')::bigint+(fields->>'c3')::bigint/((fields->>'c3')::bigint+45))- -9.5+2*avg((fields->>'c3')::bigint), avg((fields->>'c3')::bigint/((fields->>'c3')::bigint-10.2)*(fields->>'c3')::bigint)+0.567+avg((fields->>'c3')::bigint)*4.5+(fields->>'c3')::bigint, avg((fields->>'c3')::bigint+(fields->>'c3')::bigint/((fields->>'c3')::bigint+5.6))+100-(fields->>'c3')::bigint from sctbl3 WHERE fields->>'c2'<='$' AND (fields->>'c3')::bigint<>-5 AND (fields->>'c3')::bigint<>10.746 GROUP BY fields->>'c3', fields->>'c3' ORDER BY 1,2,3,4 limit 5; +SELECT avg((fields->>'c3')::bigint-(fields->>'c3')::bigint-(fields->>'c3')::bigint)-0.567-avg((fields->>'c3')::bigint/3+(fields->>'c3')::bigint)+17.55435, avg((fields->>'c3')::bigint+(fields->>'c3')::bigint/((fields->>'c3')::bigint+45))- -9.5+2*avg((fields->>'c3')::bigint), avg((fields->>'c3')::bigint/((fields->>'c3')::bigint-10.2)*(fields->>'c3')::bigint)+0.567+avg((fields->>'c3')::bigint)*4.5+(fields->>'c3')::bigint, avg((fields->>'c3')::bigint+(fields->>'c3')::bigint/((fields->>'c3')::bigint+5.6))+100-(fields->>'c3')::bigint from sctbl3 WHERE fields->>'c2'<='$' COLLATE "en_US" AND (fields->>'c3')::bigint<>-5 AND (fields->>'c3')::bigint<>10.746 GROUP BY fields->>'c3', fields->>'c3' ORDER BY 1,2,3,4 limit 5; --Testcase 75: -SELECT bit_and((fields->>'c3')::bigint/3*(fields->>'c3')::bigint)-1 + bit_and((fields->>'c3')::bigint/4/((fields->>'c3')::bigint+6)),2* bit_and((fields->>'c3')::bigint-(fields->>'c3')::bigint+(fields->>'c3')::bigint)*1, 5-bit_and((fields->>'c3')::bigint+(fields->>'c3')::bigint-(fields->>'c3')::bigint)-1000000+(fields->>'c3')::bigint from sctbl3 WHERE fields->>'c2'<='$' AND (fields->>'c3')::bigint<>-5 AND (fields->>'c3')::bigint<>10.746 GROUP BY fields->>'c3' ORDER BY 1,2,3; +SELECT bit_and((fields->>'c3')::bigint/3*(fields->>'c3')::bigint)-1 + bit_and((fields->>'c3')::bigint/4/((fields->>'c3')::bigint+6)),2* bit_and((fields->>'c3')::bigint-(fields->>'c3')::bigint+(fields->>'c3')::bigint)*1, 5-bit_and((fields->>'c3')::bigint+(fields->>'c3')::bigint-(fields->>'c3')::bigint)-1000000+(fields->>'c3')::bigint from sctbl3 WHERE fields->>'c2'<='$' COLLATE "en_US" AND (fields->>'c3')::bigint<>-5 AND (fields->>'c3')::bigint<>10.746 GROUP BY fields->>'c3' ORDER BY 1,2,3; --Testcase 76: -SELECT bit_or((fields->>'c3')::bigint/3*(fields->>'c3')::bigint)-1 + bit_or((fields->>'c3')::bigint/4/((fields->>'c3')::bigint+6)),2* bit_or((fields->>'c3')::bigint-(fields->>'c3')::bigint+(fields->>'c3')::bigint)*1, 5-bit_or((fields->>'c3')::bigint+(fields->>'c3')::bigint-(fields->>'c3')::bigint)-1000000+(fields->>'c3')::bigint from sctbl3 WHERE fields->>'c2'<='$' AND (fields->>'c3')::bigint<>-5 AND (fields->>'c3')::bigint<>10.746 GROUP BY fields->>'c3' ORDER BY 1,2,3; +SELECT bit_or((fields->>'c3')::bigint/3*(fields->>'c3')::bigint)-1 + bit_or((fields->>'c3')::bigint/4/((fields->>'c3')::bigint+6)),2* bit_or((fields->>'c3')::bigint-(fields->>'c3')::bigint+(fields->>'c3')::bigint)*1, 5-bit_or((fields->>'c3')::bigint+(fields->>'c3')::bigint-(fields->>'c3')::bigint)-1000000+(fields->>'c3')::bigint from sctbl3 WHERE fields->>'c2'<='$' COLLATE "en_US" AND (fields->>'c3')::bigint<>-5 AND (fields->>'c3')::bigint<>10.746 GROUP BY fields->>'c3' ORDER BY 1,2,3; --Testcase 77: -SELECT count(*)-5.6, 2*count(*), 10.2/count(*)+count(*)-(fields->>'c3')::bigint from sctbl3 WHERE (fields->>'c3')::bigint>0.774 OR fields->>'c2' = 'Which started out as a kind' GROUP BY fields->>'c3' ORDER BY 1, 2, 3; +SELECT count(*)-5.6, 2*count(*), 10.2/count(*)+count(*)-(fields->>'c3')::bigint from sctbl3 WHERE (fields->>'c3')::bigint>0.774 OR fields->>'c2' = 'Which started out as a kind' COLLATE "en_US" GROUP BY fields->>'c3' ORDER BY 1, 2, 3; --Testcase 78: SELECT count(fields->>'c2')-2*count((fields->>'c3')::bigint), count((fields->>'c3')::bigint)/count((fields->>'c5')::bool)-(fields->>'c3')::bigint from sctbl3 GROUP BY fields->>'c5', fields->>'c3' order by 1, 2 limit 1; --Testcase 79: @@ -196,7 +196,7 @@ SELECT sum((fields->>'c3')::bigint-(fields->>'c3')::bigint)-6+sum((fields->>'c3' --Testcase 83: SELECT max((fields->>'c4')::double precision), max((fields->>'c3')::bigint)+(fields->>'c3')::bigint-1, max((fields->>'c3')::bigint+(fields->>'c3')::bigint)-(fields->>'c3')::bigint-3, max((fields->>'c3')::bigint)+max((fields->>'c3')::bigint) from sctbl3 WHERE (fields->>'c4')::double precision>= 0 GROUP BY fields->>'c3', fields->>'c3' ORDER BY 1,2,3,4; --Testcase 84: -SELECT min(fields->>'c2'), min((fields->>'c3')::bigint)+(fields->>'c3')::bigint-1, min((fields->>'c3')::bigint+(fields->>'c3')::bigint)-(fields->>'c3')::bigint-3, min((fields->>'c3')::bigint)+min((fields->>'c3')::bigint) from sctbl3 WHERE (fields->>'c4')::double precision<0 GROUP BY fields->>'c3', fields->>'c3' ORDER BY 1,2,3,4; +SELECT min(fields->>'c2' COLLATE "en_US"), min((fields->>'c3')::bigint)+(fields->>'c3')::bigint-1, min((fields->>'c3')::bigint+(fields->>'c3')::bigint)-(fields->>'c3')::bigint-3, min((fields->>'c3')::bigint)+min((fields->>'c3')::bigint) from sctbl3 WHERE (fields->>'c4')::double precision<0 GROUP BY fields->>'c3', fields->>'c3' ORDER BY 1,2,3,4; --Testcase 85: SELECT variance((fields->>'c3')::bigint+(fields->>'c3')::bigint)+(fields->>'c3')::bigint, variance((fields->>'c3')::bigint*3)+(fields->>'c3')::bigint+1, variance((fields->>'c3')::bigint-2)+10 from sctbl3 GROUP BY fields->>'c3', fields->>'c3' ORDER BY 1,2,3; --Testcase 86: @@ -212,16 +212,19 @@ SELECT (fields->>'c3')::bigint-30, (fields->>'c3')::bigint-10, sum((fields->>'c3 ---------------------------------------------------------- Update data: add 1 tag and 1 fields------------------------------------------------------------------------------------------------- -- Update data :RECOVER_INIT_MULTILEY_ADD_1TAG_1FIELDS; +--Testcase 202: drop view if exists view_sctbl3 ; +--Testcase 203: drop foreign table if exists sctbl3; +--Testcase 204: CREATE FOREIGN TABLE sctbl3 (time timestamp with time zone, tags jsonb OPTIONS(tags 'true'), fields jsonb OPTIONS(fields 'true')) SERVER influxdb_svr OPTIONS (schemaless 'true', tags 't1'); -- Select all data with condition and combine clause --Testcase 90: SELECT time,tags->>'t1' t1,(fields->>'c1')::bool c1,fields->>'c2' c2,(fields->>'c3')::bigint c3,(fields->>'c4')::double precision c4, (fields->>'c5')::bool c5 FROM sctbl3 WHERE (fields->>'c3')::bigint=ANY (ARRAY[1,2,3]) ORDER BY 1 DESC,2 ASC,3 DESC,4,5; --Testcase 91: -SELECT * FROM sctbl3 WHERE EXISTS (SELECT (fields->>'c3')::bigint FROM sctbl3 WHERE (fields->>'c3')::bigint != 40.772) ORDER BY tags->>'t1'; +SELECT * FROM sctbl3 WHERE EXISTS (SELECT (fields->>'c3')::bigint FROM sctbl3 WHERE (fields->>'c3')::bigint != 40.772) ORDER BY tags->>'t1' COLLATE "en_US"; --Testcase 92: SELECT time,tags->>'t1' t1,(fields->>'c1')::bool c1,fields->>'c2' c2,(fields->>'c3')::bigint c3,(fields->>'c4')::double precision c4, (fields->>'c5')::bool c5 FROM sctbl3 WHERE fields->>'c2'=ANY (ARRAY(SELECT fields->>'c2' FROM sctbl3 WHERE (fields->>'c3')::bigint%2=0)) ORDER BY 1 DESC,2 ASC,3 DESC,4,5 LIMIT 25 OFFSET 0; --Testcase 93: @@ -235,11 +238,11 @@ SELECT time,tags->>'t1' t1,(fields->>'c1')::bool c1,fields->>'c2' c2,(fields->>' -- Select aggregate function and specific column from original table --Testcase 97: -SELECT tags->>'t1' t1, (fields->>'c1')::bool c1, max(tags->>'t1'), sum((fields->>'c3')::bigint), sum((fields->>'c3')::bigint ORDER BY (fields->>'c3')::bigint) FROM sctbl3 GROUP BY tags->>'t1', (fields->>'c1')::bool, (fields->>'c3')::bigint, fields->>'c2' ORDER BY 1; +SELECT (tags->>'t1' COLLATE "en_US") t1, (fields->>'c1')::bool c1, max(tags->>'t1'), sum((fields->>'c3')::bigint), sum((fields->>'c3')::bigint ORDER BY (fields->>'c3')::bigint) FROM sctbl3 GROUP BY (tags->>'t1' COLLATE "en_US"), (fields->>'c1')::bool, (fields->>'c3')::bigint, fields->>'c2' ORDER BY 1; --Testcase 98: SELECT sum((fields->>'c3')::bigint), tags->>'t1' t1, sum((fields->>'c3')::bigint ORDER BY (fields->>'c3')::bigint), fields->>'c1' c1 FROM sctbl3 GROUP BY fields->>'c1', fields->>'c3', fields->>'c3', tags->>'t1' HAVING min((fields->>'c3')::bigint)>min((fields->>'c3')::bigint) ORDER BY 1 ASC,2 DESC; --Testcase 99: -SELECT stddev((fields->>'c3')::bigint), (fields->>'c1')::bool c1, stddev((fields->>'c3')::bigint ORDER BY (fields->>'c3')::bigint), tags->>'t1' t1 FROM sctbl3 GROUP BY time, fields->>'c3', tags->>'t1', fields->>'c1' ORDER BY tags->>'t1' ASC,fields->>'c1' DESC; +SELECT stddev((fields->>'c3')::bigint), (fields->>'c1')::bool c1, stddev((fields->>'c3')::bigint ORDER BY (fields->>'c3')::bigint), (tags->>'t1' COLLATE "en_US") t1 FROM sctbl3 GROUP BY time, fields->>'c3', (tags->>'t1' COLLATE "en_US"), fields->>'c1' ORDER BY (tags->>'t1' COLLATE "en_US") ASC,fields->>'c1' DESC; --Testcase 100: SELECT every((fields->>'c3')::bigint>0), (fields->>'c1')::bool c1, every((fields->>'c3')::bigint != (fields->>'c3')::bigint) FROM sctbl3 GROUP BY time, fields->>'c1', fields->>'c3' ORDER BY (fields->>'c1')::bool ASC, (fields->>'c3')::bigint DESC; --Testcase 101: @@ -251,7 +254,7 @@ SELECT bool_or((fields->>'c4')::double precision <> 10) AND true, bool_or(fields --Testcase 103: SELECT max(time), max((fields->>'c3')::bigint), max((fields->>'c3')::bigint)+10, max((fields->>'c3')::bigint)-10, max((fields->>'c3')::bigint), max((fields->>'c3')::bigint)/2, max(tags->>'t1') FROM sctbl3 GROUP BY fields->>'c2', tags->>'t1'; --Testcase 104: -SELECT array_agg((fields->>'c3')::bigint/2 ORDER BY (fields->>'c3')::bigint), array_agg((fields->>'c1')::bool), array_agg(tags->>'t1'), array_agg(fields->>'c2' ORDER BY fields->>'c2'), array_agg(time ORDER BY time) FROM ( SELECT * FROM sctbl3 WHERE (fields->>'c3')::bigint>-1000 AND (fields->>'c3')::bigint<1000 ) AS sctbl3 GROUP BY fields->>'c5' HAVING (fields->>'c5')::boolean != true ORDER BY 1 DESC, 2, 3; +SELECT array_agg((fields->>'c3')::bigint/2 ORDER BY (fields->>'c3')::bigint), array_agg((fields->>'c1' COLLATE "en_US")::bool ORDER BY (fields->>'c1' COLLATE "en_US")::bool), array_agg((tags->>'t1' COLLATE "en_US") ORDER BY (tags->>'t1' COLLATE "en_US")), array_agg((fields->>'c2' COLLATE "en_US") ORDER BY (fields->>'c2' COLLATE "en_US")), array_agg(time ORDER BY time) FROM ( SELECT * FROM sctbl3 WHERE (fields->>'c3')::bigint>-1000 AND (fields->>'c3')::bigint<1000 ) AS sctbl3 GROUP BY fields->>'c5' HAVING (fields->>'c5')::boolean != true ORDER BY 1 DESC, 2, 3; --Testcase 105: SELECT bit_and((fields->>'c3')::bigint), bit_and((fields->>'c3')::bigint+15) FROM sctbl3 GROUP BY fields->>'c2', fields->>'c3', fields->>'c3' HAVING sum((fields->>'c3')::bigint)>avg((fields->>'c3')::bigint) ORDER BY 1 ASC,2 DESC; --Testcase 106: @@ -284,7 +287,7 @@ SELECT (fields->>'c1')::bool c1, tags->>'t1' t1, (fields->>'c4')::double precisi --Testcase 119: SELECT tags->>'t1' t1, (fields->>'c1')::bool c1, fields->>'c2' c2 FROM ( SELECT * FROM sctbl3 WHERE (fields->>'c1')::bool != TRUE ) AS tb3 WHERE (fields->>'c3')::bigint NOT IN (345245, 1000, -132, -254) ORDER BY 1 DESC,2 ASC,3 LIMIT 5; --Testcase 120: -SELECT (fields->>'c1')::bool c1, fields->>'c2' c2, (fields->>'c4')::double precision c4 FROM ( SELECT * FROM sctbl3 WHERE (fields->>'c3')::bigint>-1000 AND (fields->>'c3')::bigint<1000 ) AS tb3 WHERE fields->>'c2'=ANY (ARRAY(SELECT fields->>'c2' FROM sctbl3 WHERE (fields->>'c3')::bigint%2=0)) ORDER BY tags->>'t1'; +SELECT (fields->>'c1')::bool c1, fields->>'c2' c2, (fields->>'c4')::double precision c4 FROM ( SELECT * FROM sctbl3 WHERE (fields->>'c3')::bigint>-1000 AND (fields->>'c3')::bigint<1000 ) AS tb3 WHERE fields->>'c2'=ANY (ARRAY(SELECT fields->>'c2' FROM sctbl3 WHERE (fields->>'c3')::bigint%2=0)) ORDER BY (tags->>'t1' COLLATE "en_US"); --Testcase 121: SELECT max(time), max((fields->>'c3')::bigint*0.5), max((fields->>'c3')::bigint+10), max(tags->>'t1') FROM ( SELECT * FROM sctbl3 WHERE (fields->>'c3')::bigint>-1000 AND (fields->>'c3')::bigint<1000 ) AS tb3 WHERE true GROUP BY fields->>'c2' ORDER BY 1 DESC, 2, 3 LIMIT 25 OFFSET 8; @@ -320,11 +323,11 @@ SELECT * FROM view_sctbl3 WHERE (fields->>'c3')::bigint NOT IN (-1,1,0,2,-2) ORD -- Select many target aggregate in one query and combine with (fields->>'c1')::bool --Testcase 136: -SELECT upper(fields->>'c2'), lower(fields->>'c2'), lower(tags->>'t1') FROM sctbl3 ORDER BY 1 ASC,2 DESC,3; +SELECT upper(fields->>'c2' COLLATE "en_US"), lower(fields->>'c2' COLLATE "en_US"), lower(tags->>'t1') FROM sctbl3 ORDER BY 1 ASC,2 DESC,3; --Testcase 137: SELECT max(time), min((fields->>'c3')::bigint), sum((fields->>'c3')::bigint ORDER BY (fields->>'c3')::bigint), count(*), count(tags->>'t1'), avg((fields->>'c3')::bigint ORDER BY (fields->>'c3')::bigint) FROM view_sctbl3 GROUP BY time ORDER BY 1 DESC,2 ASC,3 DESC,4,5; --Testcase 138: -SELECT (fields->>'c3')::bigint*(random()<=1)::int, (random()<=1)::int*(25-10)+10 FROM sctbl3 ORDER BY tags->>'t1' ASC,fields->>'c1' DESC; +SELECT (fields->>'c3')::bigint*(random()<=1)::int, (random()<=1)::int*(25-10)+10 FROM sctbl3 ORDER BY (tags->>'t1' COLLATE "en_US") ASC,fields->>'c1' DESC; --Testcase 139: SELECT max((fields->>'c3')::bigint), count(*), exists(SELECT * FROM sctbl3 WHERE (fields->>'c3')::bigint>1), exists (SELECT count(*) FROM sctbl3 WHERE (fields->>'c3')::bigint>10.5) FROM sctbl3 GROUP BY fields->>'c3', fields->>'c3' HAVING min((fields->>'c3')::bigint)>min((fields->>'c3')::bigint) ORDER BY 1 ASC,2 DESC,3 ASC,4; --Testcase 140: @@ -340,18 +343,22 @@ SELECT count((fields->>'c3')::bigint), max((fields->>'c3')::bigint), sum((fields --Testcase 145: SELECT array_agg((fields->>'c3')::bigint-(fields->>'c3')::bigint-(fields->>'c3')::bigint), array_agg((fields->>'c3')::bigint/(fields->>'c3')::bigint*(fields->>'c3')::bigint), array_agg(((fields->>'c3')::bigint+(fields->>'c3')::bigint/(fields->>'c3')::bigint)*-1000), array_agg((fields->>'c3')::bigint*(fields->>'c3')::bigint-(fields->>'c3')::bigint), array_agg(((fields->>'c3')::bigint-(fields->>'c3')::bigint+(fields->>'c3')::bigint)+9999999999999.998) from sctbl3 GROUP BY (fields->>'c3')::bigint, (fields->>'c3')::bigint ORDER BY 1, 2, 3, 4, 5; --Testcase 146: -SELECT avg((fields->>'c3')::bigint-(fields->>'c3')::bigint-(fields->>'c3')::bigint)-0.567-avg((fields->>'c3')::bigint/3+(fields->>'c3')::bigint)+17.55435, avg((fields->>'c3')::bigint+(fields->>'c3')::bigint/((fields->>'c3')::bigint+45))- -9.5+2*avg((fields->>'c3')::bigint), avg((fields->>'c3')::bigint/((fields->>'c3')::bigint-10.2)*(fields->>'c3')::bigint)+0.567+avg((fields->>'c3')::bigint)*4.5+(fields->>'c3')::bigint, avg((fields->>'c3')::bigint+(fields->>'c3')::bigint/((fields->>'c3')::bigint+5.6))+100-(fields->>'c3')::bigint from sctbl3 WHERE fields->>'c2'<='$' AND (fields->>'c3')::bigint<>-5 AND (fields->>'c3')::bigint<>10.746 GROUP BY fields->>'c3', fields->>'c3' ORDER BY 1,2,3,4 limit 5; +SELECT avg((fields->>'c3')::bigint-(fields->>'c3')::bigint-(fields->>'c3')::bigint)-0.567-avg((fields->>'c3')::bigint/3+(fields->>'c3')::bigint)+17.55435, avg((fields->>'c3')::bigint+(fields->>'c3')::bigint/((fields->>'c3')::bigint+45))- -9.5+2*avg((fields->>'c3')::bigint), avg((fields->>'c3')::bigint/((fields->>'c3')::bigint-10.2)*(fields->>'c3')::bigint)+0.567+avg((fields->>'c3')::bigint)*4.5+(fields->>'c3')::bigint, avg((fields->>'c3')::bigint+(fields->>'c3')::bigint/((fields->>'c3')::bigint+5.6))+100-(fields->>'c3')::bigint from sctbl3 WHERE fields->>'c2'<='$' COLLATE "en_US" AND (fields->>'c3')::bigint<>-5 AND (fields->>'c3')::bigint<>10.746 GROUP BY fields->>'c3', fields->>'c3' ORDER BY 1,2,3,4 limit 5; --Testcase 147: SELECT count(*)-5.6, 2*count(*), 10.2/count(*)+count(*)-(fields->>'c3')::bigint from sctbl3 WHERE (fields->>'c3')::bigint>0.774 OR fields->>'c2' = 'Which started out as a kind' GROUP BY fields->>'c3' ORDER BY 1, 2, 3; -- ------------------------------Update data: add 5 tags and 20 fields----------------------------------------- -- Update data :RECOVER_INIT_MULTILEY_ADD_5TAG_20FIELDS; +--Testcase 205: drop view if exists view_sctbl3 ; +--Testcase 206: drop foreign table if exists sctbl3; +--Testcase 207: CREATE FOREIGN TABLE sctbl3 (time timestamp with time zone, tags jsonb OPTIONS(tags 'true'), fields jsonb OPTIONS(fields 'true')) SERVER influxdb_svr OPTIONS (schemaless 'true', tags 't1, t2, t3, t4, t5'); +--Testcase 208: create view view_sctbl3 as select * from sctbl3 where ((fields->>'c20')::int != 6789 OR (fields->>'c19')::double precision != -1); @@ -376,7 +383,7 @@ SELECT tags->>'t1' t1,(tags->>'t2')::int t2,(tags->>'t3')::double precision t3,t --Testcase 155: SELECT max(tags->>'t4'), max(tags->>'t5'), max((fields->>'c3')::bigint), count(*),count((fields->>'c11')::bigint), count((fields->>'c13')::int), count((fields->>'c19')::double precision), exists(SELECT * FROM sctbl3 WHERE (fields->>'c3')::bigint>1), exists (SELECT count(*) FROM sctbl3 WHERE (fields->>'c3')::bigint>10.5) FROM view_sctbl3 WHERE (fields->>'c3')::bigint<0 GROUP BY time ORDER BY 1 ASC,2 DESC,3 ASC,4 LIMIT 25 OFFSET 0; --Testcase 156: -SELECT max(fields->>'c2'), min((fields->>'c3')::bigint), max((fields->>'c3')::bigint), max((fields->>'c11')::bigint), max((fields->>'c6')::double precision), max((fields->>'c7')::double precision), max((fields->>'c8')::float), max (20) from sctbl3 GROUP BY fields->>'c3' ORDER BY (fields->>'c3')::bigint; +SELECT max(fields->>'c2' COLLATE "en_US"), min((fields->>'c3')::bigint), max((fields->>'c3')::bigint), max((fields->>'c11')::bigint), max((fields->>'c6')::double precision), max((fields->>'c7')::double precision), max((fields->>'c8')::float), max (20) from sctbl3 GROUP BY fields->>'c3' ORDER BY (fields->>'c3')::bigint; --Testcase 157: SELECT sum((fields->>'c3')::bigint), sum((fields->>'c3')::bigint ORDER BY (fields->>'c3')::bigint), sum((fields->>'c6')::double precision), sum((fields->>'c7')::double precision), sum((fields->>'c8')::float), sum((fields->>'c11')::bigint), sum((fields->>'c13')::int), sum((fields->>'c16')::int) FROM sctbl3 GROUP BY fields->>'c2' ORDER BY 1; --Testcase 158: @@ -412,13 +419,13 @@ SELECT min(time)+'10 days'::interval, min((fields->>'c3')::bigint+(fields->>'c3' --Testcase 171: SELECT time, fields->>'c2' c2, fields->>'c15' c15, tags->>'t1' t1, (tags->>'t3')::double precision t3, tags->>'t5' t5, (fields->>'c12')::bool c12, (fields->>'c14')::bigint c14 FROM ( SELECT * FROM sctbl3 WHERE (fields->>'c13')::int>-1000 OR (fields->>'c19')::double precision<1000 ) AS sctbl3; --Testcase 172: -SELECT max(time), max(7), max((fields->>'c7')::double precision)+17, max((fields->>'c11')::bigint)+10, max((fields->>'c3')::bigint), max((fields->>'c14')::bigint)/2 FROM ( SELECT * FROM sctbl3 WHERE (fields->>'c3')::bigint>-1000 AND (fields->>'c3')::bigint<1000 ) AS sctbl3 GROUP BY fields->>'c2' ORDER BY fields->>'c2'; +SELECT max(time), max(7), max((fields->>'c7')::double precision)+17, max((fields->>'c11')::bigint)+10, max((fields->>'c3')::bigint), max((fields->>'c14')::bigint)/2 FROM ( SELECT * FROM sctbl3 WHERE (fields->>'c3')::bigint>-1000 AND (fields->>'c3')::bigint<1000 ) AS sctbl3 GROUP BY (fields->>'c2' COLLATE "en_US") ORDER BY (fields->>'c2' COLLATE "en_US"); --Testcase 173: SELECT stddev((fields->>'c3')::bigint), stddev((fields->>'c3')::bigint ORDER BY (fields->>'c3')::bigint), stddev((fields->>'c11')::bigint), stddev((fields->>'c14')::bigint), stddev((fields->>'c19')::double precision) FROM ( SELECT * FROM sctbl3 WHERE (fields->>'c3')::bigint>-1000 AND (fields->>'c3')::bigint<1000 ) AS sctbl3 GROUP BY time ORDER BY 1 ASC,2 DESC; --Testcase 174: SELECT sqrt(abs((fields->>'c3')::bigint)), sqrt(abs((fields->>'c3')::bigint)), sqrt(abs((fields->>'c11')::bigint)), sqrt(abs((fields->>'c20')::int)) FROM ( SELECT * FROM sctbl3 WHERE tags->>'t5' LIKE '111111' ) AS sctbl3 ORDER BY 1 ASC,2 DESC; --Testcase 175: -SELECT * FROM ( SELECT tags->>'t1' t1, (tags->>'t2')::int t2, (tags->>'t3')::double precision t3, tags->>'t4' t4, tags->>'t5' t5, fields->>'c2' c2, (fields->>'c3')::bigint c3 FROM sctbl3 WHERE (fields->>'c13')::int>-1000 OR (fields->>'c14')::bigint<1000 ) AS tb3 WHERE c3 <-1 AND c2 > 'KissMe' ORDER BY 1 DESC,2 ASC,3 DESC,4,5 LIMIT 5 OFFSET 0; +SELECT * FROM ( SELECT tags->>'t1' t1, (tags->>'t2')::int t2, (tags->>'t3')::double precision t3, tags->>'t4' t4, tags->>'t5' t5, fields->>'c2' c2, (fields->>'c3')::bigint c3 FROM sctbl3 WHERE (fields->>'c13')::int>-1000 OR (fields->>'c14')::bigint<1000 ) AS tb3 WHERE c3 <-1 AND c2 > 'KissMe' ORDER BY t1 COLLATE "en_US" DESC,2 ASC,3 DESC,4,5 LIMIT 5 OFFSET 0; --Testcase 176: SELECT * FROM ( SELECT time,tags->>'t1' t1,(tags->>'t2')::int t2,(tags->>'t3')::double precision t3,tags->>'t4' t4, tags->>'t5' t5, (fields->>'c1')::bool c1,fields->>'c2' c2,(fields->>'c3')::bigint c3,(fields->>'c4')::double precision c4, (fields->>'c5')::bool c5, (fields->>'c6')::double precision c6, (fields->>'c7')::double precision c7, (fields->>'c8')::float c8, fields->>'c9' c9, fields->>'c10' c10, (fields->>'c11')::bigint c11, (fields->>'c12')::bool c12, (fields->>'c13')::int c13, (fields->>'c14')::bigint c14, fields->>'c15' c15, (fields->>'c16')::int c16, (fields->>'c17')::bool c17, (fields->>'c18')::bool c18, (fields->>'c19')::double precision c19, (fields->>'c20')::int c20 FROM sctbl3 WHERE (fields->>'c3')::bigint>-1000 AND (fields->>'c3')::bigint<1000 ) AS tb3 WHERE c3 IN (-1,1,0,2,-2) ORDER BY 1 DESC,2 ASC,3 DESC,4,5 LIMIT 25 OFFSET 0; --Testcase 177: @@ -438,7 +445,7 @@ SELECT avg((fields->>'c3')::bigint-(fields->>'c3')::bigint ORDER BY (fields->>'c --Testcase 184: SELECT bit_or((fields->>'c3')::bigint), bit_or((fields->>'c3')::bigint/2), (tags->>'t2')::int t2, (tags->>'t3')::double precision t3 FROM view_sctbl3 GROUP BY tags->>'t2', tags->>'t3', fields->>'c3', fields->>'c3' HAVING min((fields->>'c16')::int)<100 AND max((fields->>'c11')::bigint)<1000 OR sum((fields->>'c7')::double precision)>-7894 AND avg((fields->>'c3')::bigint)>-1000 ORDER BY 1 ASC,2 DESC; --Testcase 185: -SELECT bool_and((fields->>'c11')::bigint>0), bool_and((fields->>'c13')::int<0), bool_and((fields->>'c3')::bigint<(fields->>'c3')::bigint), bool_and((fields->>'c7')::double precision>=(fields->>'c8')::float) FROM view_sctbl3 GROUP BY time, tags->>'t1', tags->>'t2',tags->>'t3' ORDER BY tags->>'t1' DESC,(tags->>'t2')::float, (tags->>'t3')::double precision; +SELECT bool_and((fields->>'c11')::bigint>0), bool_and((fields->>'c13')::int<0), bool_and((fields->>'c3')::bigint<(fields->>'c3')::bigint), bool_and((fields->>'c7')::double precision>=(fields->>'c8')::float) FROM view_sctbl3 GROUP BY time, (tags->>'t1' COLLATE "en_US"), tags->>'t2',tags->>'t3' ORDER BY (tags->>'t1' COLLATE "en_US") DESC,(tags->>'t2')::float, (tags->>'t3')::double precision; --Testcase 186: SELECT time,tags->>'t1' t1,(tags->>'t2')::int t2,(tags->>'t3')::double precision t3,tags->>'t4' t4, tags->>'t5' t5, (fields->>'c1')::bool c1,fields->>'c2' c2,(fields->>'c3')::bigint c3,(fields->>'c4')::double precision c4, (fields->>'c5')::bool c5, (fields->>'c6')::double precision c6, (fields->>'c7')::double precision c7, (fields->>'c8')::float c8, fields->>'c9' c9, fields->>'c10' c10, (fields->>'c11')::bigint c11, (fields->>'c12')::bool c12, (fields->>'c13')::int c13, (fields->>'c14')::bigint c14, fields->>'c15' c15, (fields->>'c16')::int c16, (fields->>'c17')::bool c17, (fields->>'c18')::bool c18, (fields->>'c19')::double precision c19, (fields->>'c20')::int c20 FROM view_sctbl3 WHERE fields->>'c2'<='$' AND (fields->>'c3')::bigint<>-5 AND (fields->>'c3')::bigint<>10.746 ORDER BY 1 DESC,2 ASC,3 DESC,4,5; --Testcase 187: @@ -452,7 +459,7 @@ SELECT time,tags->>'t1' t1,(tags->>'t2')::int t2,(tags->>'t3')::double precision -- Select many target aggregate in one query and combine with condition --Testcase 191: -SELECT count((fields->>'c1')::bool)+count(fields->>'c2')-2*count((fields->>'c3')::bigint), count((fields->>'c3')::bigint)/count((fields->>'c5')::bool)-(fields->>'c3')::bigint, count((fields->>'c11')::bigint-(fields->>'c14')::bigint), 2*count(*) from sctbl3 GROUP BY fields->>'c5', fields->>'c3', fields->>'c1', fields->>'c20', tags->>'t5' order by tags->>'t5', fields->>'c1', (fields->>'c20')::int limit 1; +SELECT count((fields->>'c1')::bool)+count(fields->>'c2')-2*count((fields->>'c3')::bigint), count((fields->>'c3')::bigint)/count((fields->>'c5')::bool)-(fields->>'c3')::bigint, count((fields->>'c11')::bigint-(fields->>'c14')::bigint), 2*count(*) from sctbl3 GROUP BY fields->>'c5', fields->>'c3', fields->>'c1', fields->>'c20', (tags->>'t5' COLLATE "en_US") order by (tags->>'t5' COLLATE "en_US"), fields->>'c1', (fields->>'c20')::int limit 1; --Testcase 192: SELECT every((fields->>'c1')::bool != TRUE) AND true, every((fields->>'c3')::bigint <> 10) OR every((fields->>'c3')::bigint > 5.6), every((fields->>'c3')::bigint <= 2) OR (fields->>'c5')::bool from sctbl3 GROUP BY fields->>'c5' ORDER BY 1,2,3 limit 6; --Testcase 193: @@ -475,7 +482,11 @@ SELECT variance((fields->>'c3')::bigint)-5*min((fields->>'c3')::bigint)-1, every SELECT (fields->>'c3')::bigint-30, (fields->>'c3')::bigint-10, sum((fields->>'c3')::bigint)/3-(fields->>'c3')::bigint, min((fields->>'c3')::bigint)+(fields->>'c3')::bigint/4, (fields->>'c5')::bool c5, (fields->>'c20')::int-(fields->>'c19')::double precision-(fields->>'c16')::int from sctbl3 GROUP BY (fields->>'c20')::int, (fields->>'c19')::double precision, (fields->>'c16')::int, (fields->>'c3')::bigint, (fields->>'c3')::bigint, (fields->>'c5')::bool ORDER BY 1,2,3,4,5; -- Clean +--Testcase 209: DROP FOREIGN TABLE sctbl3 CASCADE; +--Testcase 210: DROP USER MAPPING FOR CURRENT_USER SERVER influxdb_svr; +--Testcase 211: DROP SERVER influxdb_svr CASCADE; +--Testcase 212: DROP EXTENSION influxdb_fdw; diff --git a/sql/14.5/schemaless/add_tags.sql b/sql/16.0/schemaless/add_tags.sql similarity index 96% rename from sql/14.5/schemaless/add_tags.sql rename to sql/16.0/schemaless/add_tags.sql index 14e453c..2594ac6 100644 --- a/sql/14.5/schemaless/add_tags.sql +++ b/sql/16.0/schemaless/add_tags.sql @@ -32,7 +32,7 @@ select max(fields->>'sig2'), min(time), bool_or(fields->>'sig2' != 'JAPA') from --Testcase 9: select bool_and((fields->>'sig3')::double precision > -10), string_agg('446757svbvskkk', fields->>'sig2'), avg ((fields->>'sig1')::bigint) from sctbl4; --Testcase 10: -select count(fields->>'sig1'), stddev((fields->>'sig3')::double precision + 333), min(fields->>'sig2') from sctbl4; +select count(fields->>'sig1'), stddev((fields->>'sig3')::double precision + 333), min(fields->>'sig2' COLLATE "en_US") from sctbl4; --Testcase 11: select bool_or((fields->>'sig1')::bigint >= 1234), stddev((fields->>'sig1')::bigint), stddev((fields->>'sig3')::double precision) from sctbl4; @@ -101,7 +101,7 @@ select stddev((fields->>'sig3')::double precision * 0.416754 + (fields->>'sig1') --Testcase 36: select bool_or((fields->>'sig3')::double precision / (fields->>'sig1')::bigint >= 15.5678), max ((fields->>'sig3')::double precision / (fields->>'sig1')::bigint * (fields->>'sig1')::bigint), every(((fields->>'sig3')::double precision - (fields->>'sig1')::bigint) < 0) from sctbl4 WHERE (fields->>'sig4')::boolean <> false GROUP BY tags->>'sid',fields->>'sig4' HAVING (fields->>'sig4')::boolean = true ORDER BY tags->>'sid' LIMIT 5 OFFSET 2; --Testcase 37: -select max (fields->>'sig2' || 'kethattinh' || 'hanoilanhqua'), sum ((fields->>'sig3')::double precision - (fields->>'sig3')::double precision - (fields->>'sig1')::bigint), avg((fields->>'sig1')::bigint + (fields->>'sig1')::bigint + (fields->>'sig3')::double precision) from sctbl4 WHERE (fields->>'sig1')::bigint <= 10000000 GROUP BY tags->>'sid',fields->>'sig2',fields->>'sig4' HAVING fields->>'sig2' IN ('%c%', '%1%') OR fields->>'sig2' LIKE '%a%' ORDER BY tags->>'sid' LIMIT 5 OFFSET 2; +select max (fields->>'sig2' || 'kethattinh' || 'hanoilanhqua'), sum ((fields->>'sig3')::double precision - (fields->>'sig3')::double precision - (fields->>'sig1')::bigint), avg((fields->>'sig1')::bigint + (fields->>'sig1')::bigint + (fields->>'sig3')::double precision) from sctbl4 WHERE (fields->>'sig1')::bigint <= 10000000 GROUP BY tags->>'sid',(fields->>'sig2' COLLATE "en_US"),fields->>'sig4' HAVING (fields->>'sig2' COLLATE "en_US") IN ('%c%', '%1%') OR (fields->>'sig2' COLLATE "en_US") LIKE '%a%' ORDER BY tags->>'sid' LIMIT 5 OFFSET 2; -- Select with subquery --Testcase 38: @@ -130,11 +130,11 @@ select max(time), count(tags->>'sid1'), sum((tags->>'sid2')::bigint) from sctbl4 --Testcase 46: select string_agg(tags->>'sid19', tags->>'sid17'), avg((tags->>'sid3')::bigint), stddev((tags->>'sid13')::double precision) from sctbl4 GROUP BY tags->>'sid17',tags->>'sid19',(tags->>'sid3')::bigint,(tags->>'sid13')::double precision,(fields->>'sig1')::bigint ORDER BY (fields->>'sig1')::bigint; --Testcase 47: -select sum((tags->>'sid3')::bigint), sum((tags->>'sid20')::bigint), bool_and((tags->>'sid5')::boolean != (tags->>'sid6')::boolean) from sctbl4 GROUP BY fields->>'sig2' ORDER BY fields->>'sig2'; +select sum((tags->>'sid3')::bigint), sum((tags->>'sid20')::bigint), bool_and((tags->>'sid5')::boolean != (tags->>'sid6')::boolean) from sctbl4 GROUP BY (fields->>'sig2' COLLATE "en_US") ORDER BY (fields->>'sig2' COLLATE "en_US"); --Testcase 48: select stddev((tags->>'sid20')::bigint), avg((tags->>'sid2')::bigint order by (tags->>'sid2')::bigint), min(tags->>'sid10') from sctbl4 GROUP BY fields->>'sig3' ORDER BY (fields->>'sig3')::double precision; --Testcase 49: -select every((tags->>'sid11')::boolean = (tags->>'sid15')::boolean), bool_or((tags->>'sid6')::boolean != (tags->>'sid11')::boolean), count(time) from sctbl4 GROUP BY fields->>'sig2' ORDER BY fields->>'sig2'; +select every((tags->>'sid11')::boolean = (tags->>'sid15')::boolean), bool_or((tags->>'sid6')::boolean != (tags->>'sid11')::boolean), count(time) from sctbl4 GROUP BY (fields->>'sig2' COLLATE "en_US") ORDER BY (fields->>'sig2' COLLATE "en_US"); --Testcase 50: select count(*), sum((tags->>'sid3')::bigint), string_agg(tags->>'sid9', tags->>'sid17') from sctbl4 GROUP BY fields->>'sig3' ORDER BY (fields->>'sig3')::double precision; --Testcase 51: @@ -172,13 +172,13 @@ select min((fields->>'sig1')::bigint * (tags->>'sid20')::bigint - (tags->>'sid13 --Testcase 66: select bool_and((tags->>'sid6')::boolean != false OR (tags->>'sid11')::boolean = true), min((tags->>'sid13')::double precision / (fields->>'sig3')::double precision - (tags->>'sid12')::bigint), avg((tags->>'sid20')::bigint / (tags->>'sid12')::bigint + (tags->>'sid3')::bigint) from sctbl4 GROUP BY tags->>'sid12' ORDER BY (tags->>'sid12')::bigint; --Testcase 67: -select stddev((tags->>'sid13')::double precision + (fields->>'sig1')::bigint * (tags->>'sid2')::bigint), sum((tags->>'sid12')::bigint + (tags->>'sid20')::bigint - (tags->>'sid3')::bigint), string_agg(tags->>'sid7' || '豚は誰も好', 'なぜ18歳で' || (tags->>'sid17')::text) from sctbl4 GROUP BY tags->>'sid8' ORDER BY tags->>'sid8'; +select stddev((tags->>'sid13')::double precision + (fields->>'sig1')::bigint * (tags->>'sid2')::bigint), sum((tags->>'sid12')::bigint + (tags->>'sid20')::bigint - (tags->>'sid3')::bigint), string_agg(tags->>'sid7' || '豚は誰も好', 'なぜ18歳で' || (tags->>'sid17')::text) from sctbl4 GROUP BY (tags->>'sid8' COLLATE "en_US") ORDER BY (tags->>'sid8' COLLATE "en_US"); --Testcase 68: select stddev((tags->>'sid3')::bigint * (tags->>'sid2')::bigint - (tags->>'sid20')::bigint), min(tags->>'sid10' || '12345#$%&7' || (tags->>'sid19')::text), every(tags->>'sid4' IN ('japan', 'vietnam')) from sctbl4 GROUP BY tags->>'sid9' ORDER BY tags->>'sid9'; -- Select combine-aggregate --Testcase 69: -select stddev((tags->>'sid3')::bigint) + count(tags->>'sid10') + count(tags->>'sid4'), count(time) + count(tags->>'sid1') - sum((tags->>'sid2')::bigint), avg((tags->>'sid3')::bigint) * count(*) + count(tags->>'sid17') from sctbl4 GROUP BY fields->>'sig2' ORDER BY fields->>'sig2'; +select stddev((tags->>'sid3')::bigint) + count(tags->>'sid10') + count(tags->>'sid4'), count(time) + count(tags->>'sid1') - sum((tags->>'sid2')::bigint), avg((tags->>'sid3')::bigint) * count(*) + count(tags->>'sid17') from sctbl4 GROUP BY (fields->>'sig2' COLLATE "en_US") ORDER BY (fields->>'sig2' COLLATE "en_US"); --Testcase 70: select stddev((tags->>'sid13')::double precision) * avg((fields->>'sig1')::bigint) / avg((fields->>'sig3')::double precision), sum((tags->>'sid2')::bigint) / count(tags->>'sid10') + sum((fields->>'sig1')::bigint), stddev((fields->>'sig3')::double precision) / stddev((tags->>'sid12')::double precision) - min((tags->>'sid12')::double precision) from sctbl4 GROUP BY tags->>'sid2' ORDER BY (tags->>'sid2')::bigint; --Testcase 71: @@ -192,11 +192,11 @@ select bool_or(tags->>'sid16' = 'id1') OR false AND every((tags->>'sid15')::bool --Testcase 75: select bool_and(time > '1900-09-09 23:59:00+00') AND bool_and((fields->>'sig4')::boolean) AND every((fields->>'sig4')::boolean), stddev((tags->>'sid20')::bigint) / stddev((fields->>'sig1')::bigint) / sum((tags->>'sid13')::double precision), stddev((tags->>'sid13')::double precision) / sum((tags->>'sid13')::double precision) * count(*) from sctbl4 GROUP BY tags->>'sid7' ORDER BY tags->>'sid7'; --Testcase 76: -select sum((tags->>'sid2')::bigint) + count(tags->>'sid1') - count(tags->>'sid8'), count((fields->>'sig3')::double precision) - count(tags->>'sid9') + count(tags->>'sid17'), string_agg(tags->>'sid19' || 'hf675578ytgu', tags->>'sid17' || (tags->>'sid14')::text) from sctbl4 GROUP BY tags->>'sid8' ORDER BY tags->>'sid8'; +select sum((tags->>'sid2')::bigint) + count(tags->>'sid1') - count(tags->>'sid8'), count((fields->>'sig3')::double precision) - count(tags->>'sid9') + count(tags->>'sid17'), string_agg(tags->>'sid19' || 'hf675578ytgu', tags->>'sid17' || (tags->>'sid14')::text) from sctbl4 GROUP BY (tags->>'sid8' COLLATE "en_US") ORDER BY (tags->>'sid8' COLLATE "en_US"); --Testcase 77: -select sum((tags->>'sid3')::bigint) - avg((tags->>'sid12')::bigint) * count(tags->>'sid9'), bool_and((tags->>'sid11')::boolean) AND bool_and((tags->>'sid20')::bigint >= -16735467) OR every(tags->>'sid16' != 'id3'), sum((tags->>'sid20')::bigint) + avg((tags->>'sid12')::bigint) / count(tags->>'sid19') from sctbl4 GROUP BY fields->>'sig2' ORDER BY fields->>'sig2'; +select sum((tags->>'sid3')::bigint) - avg((tags->>'sid12')::bigint) * count(tags->>'sid9'), bool_and((tags->>'sid11')::boolean) AND bool_and((tags->>'sid20')::bigint >= -16735467) OR every(tags->>'sid16' != 'id3'), sum((tags->>'sid20')::bigint) + avg((tags->>'sid12')::bigint) / count(tags->>'sid19') from sctbl4 GROUP BY (fields->>'sig2' COLLATE "en_US") ORDER BY (fields->>'sig2' COLLATE "en_US"); --Testcase 78: -select string_agg(tags->>'sid19' || (tags->>'sid17')::text || (tags->>'sid10')::text, tags->>'sid9' || (tags->>'sid8')::text || (tags->>'sid7')::text), avg((tags->>'sid20')::bigint) / avg((tags->>'sid2')::bigint) + stddev((tags->>'sid12')::bigint), count(tags->>'sid1') - count(tags->>'sid14') + count((fields->>'sig3')::double precision) from sctbl4 GROUP BY tags->>'sid10' ORDER BY tags->>'sid10'; +select string_agg(tags->>'sid19' || (tags->>'sid17')::text || (tags->>'sid10')::text, tags->>'sid9' || (tags->>'sid8')::text || (tags->>'sid7')::text), avg((tags->>'sid20')::bigint) / avg((tags->>'sid2')::bigint) + stddev((tags->>'sid12')::bigint), count(tags->>'sid1') - count(tags->>'sid14') + count((fields->>'sig3')::double precision) from sctbl4 GROUP BY (tags->>'sid10' COLLATE "en_US") ORDER BY (tags->>'sid10' COLLATE "en_US"); -- Select with WHERE multi-condition --Testcase 79: @@ -255,7 +255,11 @@ select sctbl4.tags->>'sid8' sid8, sctbl4.tags->>'sid9' sid9, (sctbl9.fields->>'s -- Clean --Testcase 103: DROP FOREIGN TABLE sctbl4; +--Testcase 104: DROP FOREIGN TABLE sctbl9; +--Testcase 105: DROP USER MAPPING FOR CURRENT_USER SERVER influxdb_svr; +--Testcase 106: DROP SERVER influxdb_svr CASCADE; +--Testcase 107: DROP EXTENSION influxdb_fdw; diff --git a/sql/15.0/schemaless/aggregate.sql b/sql/16.0/schemaless/aggregate.sql similarity index 100% rename from sql/15.0/schemaless/aggregate.sql rename to sql/16.0/schemaless/aggregate.sql diff --git a/sql/13.8/schemaless/extra/aggregates.sql b/sql/16.0/schemaless/extra/aggregates.sql similarity index 85% rename from sql/13.8/schemaless/extra/aggregates.sql rename to sql/16.0/schemaless/extra/aggregates.sql index 367fe93..73ee21b 100644 --- a/sql/13.8/schemaless/extra/aggregates.sql +++ b/sql/16.0/schemaless/extra/aggregates.sql @@ -54,6 +54,17 @@ CREATE FOREIGN TABLE FLOAT8_TBL (fields jsonb OPTIONS(fields 'true')) SERVER inf -- AGGREGATES -- +-- directory paths are passed to us in environment variables +--\getenv abs_srcdir PG_ABS_SRCDIR +-- avoid bit-exact output here because operations may not be bit-exact. +--Testcase 19: +SET extra_float_digits = 0; + +--\set filename :abs_srcdir '/init/agg.txt' +--COPY aggtest_nsc FROM :'filename'; + +--ANALYZE aggtest_nsc; + -- avoid bit-exact output here because operations may not be bit-exact. --Testcase 19: SET extra_float_digits = 0; @@ -64,6 +75,47 @@ SELECT avg((fields->>'four')::int4) AS avg_1 FROM onek; --Testcase 21: SELECT avg((fields->>'a')::int2) AS avg_32 FROM aggtest WHERE (fields->>'a')::int2 < 100; +--Testcase 538: +CREATE FOREIGN TABLE v1_nsc (v int4) SERVER influxdb_svr OPTIONS (table 'v1'); +--Testcase 539: +CREATE FOREIGN TABLE v1(fields jsonb OPTIONS(fields 'true')) SERVER influxdb_svr OPTIONS (schemaless 'true'); + +--Testcase 540: +INSERT INTO v1_nsc (v) VALUES (1), (2), (3); +--Testcase 541: +SELECT any_value((fields->>'v')::int2) FROM v1; +--Testcase 542: +DELETE FROM v1_nsc; + +-- NULL datatype is not supported in influxdb. Expectation is error. +--Testcase 543: +INSERT INTO v1_nsc (v) VALUES (NULL); +--Testcase 544: +SELECT any_value((fields->>'v')::int2) FROM v1; +--Testcase 545: +DELETE FROM v1_nsc; + +-- NULL datatype is not supported in influxdb. Expectation is error. +--Testcase 546: +INSERT INTO v1_nsc (v) VALUES (NULL), (1), (2); +--Testcase 547: +SELECT any_value((fields->>'v')::int2) FROM v1; +--Testcase 548: +DELETE FROM v1_nsc; + +--Testcase 524: +CREATE FOREIGN TABLE v2_nsc (v text[]) SERVER influxdb_svr OPTIONS (table 'v2'); +--Testcase 549: +CREATE FOREIGN TABLE v2(fields jsonb OPTIONS(fields 'true')) SERVER influxdb_svr OPTIONS (schemaless 'true'); + +-- Cannot binding text array. Expectation is error. +--Testcase 550: +INSERT INTO v2_nsc (v) VALUES (array['hello', 'world']); +--Testcase 551: +SELECT any_value(v) FROM v2; +--Testcase 552: +DELETE FROM v2_nsc; + -- In 7.1, avg(float4) is computed using float8 arithmetic. -- Round the result to 3 digits to avoid platform-specific results. @@ -418,7 +470,8 @@ CREATE FOREIGN TABLE bitwise_test_empty (fields jsonb OPTIONS(fields 'true')) SE --Testcase 137: SELECT BIT_AND((fields->>'i2')::INT2) AS "?", - BIT_OR((fields->>'i4')::INT4) AS "?" + BIT_OR((fields->>'i4')::INT4) AS "?", + BIT_XOR((fields->>'i8')::INT8) AS "?" FROM bitwise_test_empty; --Testcase 138: @@ -438,7 +491,14 @@ SELECT BIT_OR((fields->>'i8')::INT8) AS "7", BIT_OR((fields->>'i')::INT) AS "?", BIT_OR((fields->>'x')::INT2) AS "7", - BIT_OR((fields->>'y')::BIT(4)) AS "1101" + BIT_OR((fields->>'y')::BIT(4)) AS "1101", + + BIT_XOR((fields->>'i2')::INT2) AS "5", + BIT_XOR((fields->>'i4')::INT4) AS "5", + BIT_XOR((fields->>'i8')::INT8) AS "5", + BIT_XOR((fields->>'i')::INT) AS "?", + BIT_XOR((fields->>'x')::INT2) AS "7", + BIT_XOR((fields->>'y')::BIT(4)) AS "1101" FROM bitwise_test; -- @@ -620,6 +680,7 @@ select max(100) from tenk1; -- try it on an inheritance tree --Testcase 178: create foreign table minmaxtest(fields jsonb OPTIONS(fields 'true')) SERVER influxdb_svr OPTIONS (schemaless 'true'); +--Testcase 485: create foreign table minmaxtest_nsc(f1 int) server influxdb_svr OPTIONS (table 'minmaxtest'); --Testcase 179: create table minmaxtest1() inherits (minmaxtest); @@ -660,12 +721,20 @@ select distinct min((fields->>'f1')::int), max((fields->>'f1')::int) from minmax --Testcase 193: drop foreign table minmaxtest cascade; +--Testcase 486: drop foreign table minmaxtest_nsc cascade; -- check for correct detection of nested-aggregate errors --Testcase 194: select max(min((fields->>'unique1')::int4)) from tenk1; --Testcase 195: select (select max(min((fields->>'unique1')::int4)) from int8_tbl) from tenk1; +-- Data in schemaless table is jsonb, so need to specific a column to be converted to number. +-- Asume the column is selected is odd, so this test case does not get error by avg function. +-- Expectation is get error: aggregate function calls cannot be nested. +--Testcase 553: +select avg((select avg((a1.col1->>'odd')::int order by (select avg((a2.col2->>'odd')::int) from tenk1 a3)) + from tenk1 a1(col1))) +from tenk1 a2(col2); -- -- Test removal of redundant GROUP BY columns @@ -758,10 +827,98 @@ select (agg_t1.fields->>'f1')::int f1 from agg_t1 left join (select (fields->>'f --Testcase 220: select (agg_t1.fields->>'f1')::int f1 from agg_t1 left join (select (fields->>'f1')::bigint f1, (fields->>'f22')::bigint f22 from agg_t2) agg_t2 on (agg_t1.fields->>'f1')::bigint = (agg_t2.f1)::bigint group by f1; +-- check case where we have to inject nullingrels into coerced join alias +-- Table agg_t1 and agg_t2 is schemaless table, there is only 1 column. +-- This table does not have data. +-- So do not port x1 column, and replace f1 column by fields column. +--Testcase 554: +select fields, count(*) from +agg_t1 x(x0) left join (agg_t1 left join agg_t2 using(fields)) on (x0::int = 0) +group by fields; + +-- Comment out because tables agg_t1 and agg_t2 only have one column. There is no column f1 and f2, so we do not separate this test case from previous test cases. +-- same, for a RelabelType coercion +-- select (fields->>'f1')::int, count(*) from +-- agg_t1 x((fields->>'x0')::int,(fields->>'x1')::int) left join (agg_t1 left join agg_t2 using((fields->>'f1')::int)) on ((fields->>'x0')::int = 0) +-- group by (fields->>'f1')::int; + --Testcase 221: drop foreign table agg_t1 cascade; --Testcase 222: drop foreign table agg_t2 cascade; + +-- +-- Test planner's selection of pathkeys for ORDER BY aggregates +-- + +-- Ensure we order by four. This suits the most aggregate functions. +--Testcase 555: +explain (costs off) +select sum((fields->>'one')::int4 order by (fields->>'two')::int4),max((fields->>'four')::int4 order by (fields->>'four')::int4), min((fields->>'four')::int4 order by (fields->>'four')::int4) +from tenk1; + +-- Ensure we order by two. It's a tie between ordering by two and four but +-- we tiebreak on the aggregate's position. +--Testcase 556: +explain (costs off) +select + sum((fields->>'two')::int4 order by (fields->>'two')::int4), max((fields->>'four')::int4 order by (fields->>'four')::int4), + min((fields->>'four')::int4 order by (fields->>'four')::int4), max((fields->>'two')::int4 order by (fields->>'two')::int4) +from tenk1; + +-- Similar to above, but tiebreak on ordering by four +--Testcase 557: +explain (costs off) +select + max((fields->>'four')::int4 order by (fields->>'four')::int4), sum((fields->>'two')::int4 order by (fields->>'two')::int4), + min((fields->>'four')::int4 order by (fields->>'four')::int4), max((fields->>'two')::int4 order by (fields->>'two')::int4) +from tenk1; + +-- Ensure this one orders by ten since there are 3 aggregates that require ten +-- vs two that suit two and four. +--Testcase 558: +explain (costs off) +select + max((fields->>'four')::int4 order by (fields->>'four')::int4), sum((fields->>'two')::int4 order by (fields->>'two')::int4), + min((fields->>'four')::int4 order by (fields->>'four')::int4), max((fields->>'two')::int4 order by (fields->>'two')::int4), + sum((fields->>'ten')::int4 order by (fields->>'ten')::int4), min((fields->>'ten')::int4 order by (fields->>'ten')::int4), max((fields->>'ten')::int4 order by (fields->>'ten')::int4) +from tenk1; + +-- 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. +--Testcase 559: +explain (costs off) +select + sum((fields->>'unique1')::int4 order by (fields->>'ten')::int4, (fields->>'two')::int4), sum((fields->>'unique1')::int4 order by (fields->>'four')::int4), + sum((fields->>'unique1')::int4 order by (fields->>'two')::int4, (fields->>'four')::int4) +from tenk1 +group by (fields->>'ten')::int4; + +-- 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. +--Testcase 560: +explain (costs off) +select + sum((fields->>'unique1')::int4 order by (fields->>'two')::int4), sum((fields->>'unique1')::int4 order by (fields->>'four')::int4), + sum((fields->>'unique1')::int4 order by (fields->>'four')::int4, (fields->>'two')::int4), sum((fields->>'unique1')::int4 order by (fields->>'two')::int4, random()), + sum((fields->>'unique1')::int4 order by (fields->>'two')::int4, random(), random() + 1) +from tenk1 +group by (fields->>'ten')::int4; + +-- Ensure consecutive NULLs are properly treated as distinct from each other +--Testcase 561: +select array_agg(distinct val) +from (select null as val from generate_series(1, 2)); + +-- Ensure no ordering is requested when enable_presorted_aggregate is off +set enable_presorted_aggregate to off; +--Testcase 562: +explain (costs off) +select sum((fields->>'two')::int4 order by (fields->>'two')::int4) from tenk1; +reset enable_presorted_aggregate; + -- -- Test combinations of DISTINCT and/or ORDER BY -- @@ -1005,6 +1162,90 @@ select string_agg(v, decode('ee', 'hex')) from bytea_test_table; drop table bytea_test_table; */ + +-- Test parallel string_agg and array_agg +--Testcase 563: +create foreign table pagg_test_nsc ( + x int, + y int +) server influxdb_svr options (table 'pagg_test'); + +--Testcase 564: +create foreign table pagg_test ( + fields jsonb options(fields 'true') +) server influxdb_svr options (schemaless 'true'); + +--Testcase 565: +insert into pagg_test_nsc +select (case x % 4 when 1 then null else x end), x % 10 +from generate_series(1,5000) x; + +set parallel_setup_cost TO 0; +set parallel_tuple_cost TO 0; +set parallel_leader_participation TO 0; +set min_parallel_table_scan_size = 0; +set bytea_output = 'escape'; +set max_parallel_workers_per_gather = 2; + +-- create a view as we otherwise have to repeat this query a few times. +--Testcase 566: +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 + (fields->>'y')::int4 AS y, + string_agg((fields->>'x')::text, ',') AS t, + string_agg((fields->>'x')::text::bytea, ',') AS b, + array_agg((fields->>'x')::int) AS a, + array_agg(ARRAY[(fields->>'x')::int]) AS aa + from pagg_test + group by y + ) a1 +) a2 +group by y; + +-- Ensure results are correct. +--Testcase 567: +select * from v_pagg_test; + +-- Ensure parallel aggregation is actually being used. +-- influxdb_fdw: parallel execution is not supported +--Testcase 568: +explain (costs off) select * from v_pagg_test; + +set max_parallel_workers_per_gather = 0; + +-- Ensure results are the same without parallel aggregation. +--Testcase 569: +select * from v_pagg_test; + +-- Clean up +reset max_parallel_workers_per_gather; +reset bytea_output; +reset min_parallel_table_scan_size; +reset parallel_leader_participation; +reset parallel_tuple_cost; +reset parallel_setup_cost; + +--Testcase 570: +drop view v_pagg_test; +--Testcase 571: +drop foreign table pagg_test_nsc; +--Testcase 572: +drop foreign table pagg_test; + -- FILTER tests --Testcase 284: @@ -1026,6 +1267,9 @@ having exists (select 1 from onek b where sum(distinct (a.fields->>'four')::int4 select max(foo COLLATE "C") filter (where (bar collate "POSIX") > '0') from (values ('a', 'b')) AS v(foo,bar); +--Testcase 573: +select any_value(v) filter (where v > 2) from (values (1), (2), (3)) as v (v); + -- outer reference in FILTER (PostgreSQL extension) --Testcase 289: select (select count(*) @@ -1058,6 +1302,22 @@ select aggfns(distinct (fields->>'a')::int,(fields->>'b')::int,fields->>'c' orde generate_series(1,2) i; rollback; +-- check handling of bare boolean Var in FILTER +--Testcase 454: +select max(0) filter (where (fields->>'b1')::boolean) from bool_test; +--Testcase 455: +select (select max(0) filter (where (fields->>'b1')::boolean)) from bool_test; + +-- check for correct detection of nested-aggregate errors in FILTER +--Testcase 456: +select max((fields->>'unique1')::int) filter (where sum((fields->>'ten')::int) > 0) from tenk1; +--Testcase 457: +select (select max((fields->>'unique1')::int) filter (where sum((fields->>'ten')::int) > 0) from int8_tbl) from tenk1; +--Testcase 458: +select max((fields->>'unique1')::int) filter (where bool_or((fields->>'ten')::int > 0)) from tenk1; +--Testcase 459: +select (select max((fields->>'unique1')::int) filter (where bool_or((fields->>'ten')::int > 0)) from int8_tbl) from tenk1; + -- ordered-set aggregates begin; @@ -1511,6 +1771,50 @@ SELECT balk((fields->>'hundred')::int4) FROM tenk1; ROLLBACK; +-- test multiple usage of an aggregate whose finalfn returns a R/W datum +BEGIN; + +--Testcase 574: +CREATE FUNCTION rwagg_sfunc(x anyarray, y anyarray) RETURNS anyarray +LANGUAGE plpgsql IMMUTABLE AS $$ +BEGIN + RETURN array_fill(y[1], ARRAY[4]); +END; +$$; + +--Testcase 575: +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; +$$; + +--Testcase 576: +CREATE AGGREGATE rwagg(anyarray) ( + STYPE = anyarray, + SFUNC = rwagg_sfunc, + FINALFUNC = rwagg_finalfunc +); + +--Testcase 577: +CREATE FUNCTION eatarray(x real[]) RETURNS real[] +LANGUAGE plpgsql STRICT IMMUTABLE AS $$ +BEGIN + x[1] := x[1] + 1; + RETURN x; +END; +$$; + +--Testcase 578: +SELECT eatarray(rwagg(ARRAY[1.0::real])), eatarray(rwagg(ARRAY[1.0::real])); + +ROLLBACK; + -- Secondly test the case of a parallel aggregate combiner function -- returning NULL. For that use normal transition function, but a -- combiner function returning NULL. @@ -1630,17 +1934,21 @@ select v||'a', case when v||'a' = 'aa' then 1 else 0 end, count(*) -- does not lead to array overflow due to unexpected duplicate hash keys -- see CAFeeJoKKu0u+A_A9R9316djW-YW3-+Gtgvy3ju655qRHR3jtdA@mail.gmail.com --Testcase 399: +set enable_memoize to off; +--Testcase 400: explain (costs off) select 1 from tenk1 where ((fields->>'hundred')::int, (fields->>'thousand')::int) in (select (fields->>'twothousand')::int, (fields->>'twothousand')::int from onek); +--Testcase 401: +reset enable_memoize; -- -- Hash Aggregation Spill tests -- ---Testcase 400: +--Testcase 402: set enable_sort=false; ---Testcase 401: +--Testcase 403: set work_mem='64kB'; --Testcase 404: @@ -1649,9 +1957,9 @@ group by fields->>'unique1' having sum((fields->>'fivethous')::int) > 4975 order by sum((fields->>'twothousand')::int); ---Testcase 403: +--Testcase 405: set work_mem to default; ---Testcase 404: +--Testcase 406: set enable_sort to default; -- @@ -1659,66 +1967,76 @@ set enable_sort to default; -- aggregation. Force spilling in both cases by setting work_mem low. -- ---Testcase 405: +--Testcase 407: set work_mem='64kB'; ---Testcase 406: -create foreign table agg_data_2k(fields jsonb OPTIONS(fields 'true')) server influxdb_svr OPTIONS (schemaless 'true'); +--Testcase 408: +create foreign table agg_data_2k (fields jsonb OPTIONS(fields 'true')) SERVER influxdb_svr OPTIONS (schemaless 'true'); +--Testcase 489: create foreign table agg_data_2k_nsc (g int) server influxdb_svr OPTIONS (table 'agg_data_2k'); ---Testcase 407: -create foreign table agg_data_20k(fields jsonb OPTIONS(fields 'true')) server influxdb_svr OPTIONS (schemaless 'true'); +--Testcase 409: +create foreign table agg_data_20k (fields jsonb OPTIONS(fields 'true')) SERVER influxdb_svr OPTIONS (schemaless 'true'); +--Testcase 490: create foreign table agg_data_20k_nsc (g int) server influxdb_svr OPTIONS (table 'agg_data_20k'); ---Testcase 408: +--Testcase 410: create foreign table agg_group_1 (fields jsonb OPTIONS(fields 'true')) SERVER influxdb_svr OPTIONS (schemaless 'true'); +--Testcase 491: create foreign table agg_group_1_nsc (c1 int, c2 numeric, c3 int) server influxdb_svr OPTIONS (table 'agg_group_1'); ---Testcase 409: +--Testcase 411: create foreign table agg_group_2 (fields jsonb OPTIONS(fields 'true')) SERVER influxdb_svr OPTIONS (schemaless 'true'); +--Testcase 492: create foreign table agg_group_2_nsc (a int, c1 numeric, c2 text, c3 int) server influxdb_svr OPTIONS (table 'agg_group_2'); ---Testcase 410: +--Testcase 412: create foreign table agg_group_3 (fields jsonb OPTIONS(fields 'true')) SERVER influxdb_svr OPTIONS (schemaless 'true'); +--Testcase 493: create foreign table agg_group_3_nsc (c1 numeric, c2 int4, c3 int) server influxdb_svr OPTIONS (table 'agg_group_3'); ---Testcase 411: +--Testcase 413: create foreign table agg_group_4 (fields jsonb OPTIONS(fields 'true')) SERVER influxdb_svr OPTIONS (schemaless 'true'); +--Testcase 494: create foreign table agg_group_4_nsc (c1 numeric, c2 text, c3 int) server influxdb_svr OPTIONS (table 'agg_group_4'); ---Testcase 412: +--Testcase 414: create foreign table agg_hash_1 (fields jsonb OPTIONS(fields 'true')) SERVER influxdb_svr OPTIONS (schemaless 'true'); +--Testcase 495: create foreign table agg_hash_1_nsc (c1 int, c2 numeric, c3 int) server influxdb_svr OPTIONS (table 'agg_hash_1'); ---Testcase 413: +--Testcase 415: create foreign table agg_hash_2 (fields jsonb OPTIONS(fields 'true')) SERVER influxdb_svr OPTIONS (schemaless 'true'); +--Testcase 496: create foreign table agg_hash_2_nsc (a int, c1 numeric, c2 text, c3 int) server influxdb_svr OPTIONS (table 'agg_hash_2'); ---Testcase 414: +--Testcase 416: create foreign table agg_hash_3 (fields jsonb OPTIONS(fields 'true')) SERVER influxdb_svr OPTIONS (schemaless 'true'); +--Testcase 497: create foreign table agg_hash_3_nsc (c1 numeric, c2 int4, c3 int) server influxdb_svr OPTIONS (table 'agg_hash_3'); ---Testcase 415: +--Testcase 417: create foreign table agg_hash_4 (fields jsonb OPTIONS(fields 'true')) SERVER influxdb_svr OPTIONS (schemaless 'true'); +--Testcase 498: create foreign table agg_hash_4_nsc (c1 numeric, c2 text, c3 int) server influxdb_svr OPTIONS (table 'agg_hash_4'); ---Testcase 416: +--Testcase 418: insert into agg_data_2k_nsc select g from generate_series(0, 1999) g; --analyze agg_data_2k; ---Testcase 417: +--Testcase 419: insert into agg_data_20k_nsc select g from generate_series(0, 19999) g; --analyze agg_data_20k; -- Produce results with sorting. ---Testcase 418: +--Testcase 420: set enable_hashagg = false; ---Testcase 419: +--Testcase 421: set jit_above_cost = 0; ---Testcase 420: +--Testcase 422: explain (costs off) select (fields->>'g')::int%10000 as c1, sum((fields->>'g')::numeric) as c2, count(*) as c3 from agg_data_20k group by (fields->>'g')::int%10000; ---Testcase 421: +--Testcase 423: insert into agg_group_1_nsc select g%10000 as c1, sum(g::numeric) as c2, count(*) as c3 from agg_data_20k_nsc group by g%10000; ---Testcase 422: +--Testcase 424: insert into agg_group_2_nsc select * from (values (100), (300), (500)) as r(a), @@ -1730,40 +2048,40 @@ select * from where g < r.a group by g/2) as s; ---Testcase 423: +--Testcase 425: set jit_above_cost to default; ---Testcase 424: +--Testcase 426: insert into agg_group_3_nsc select (g/2)::numeric as c1, sum(7::int4) as c2, count(*) as c3 from agg_data_2k_nsc group by g/2; ---Testcase 425: +--Testcase 427: insert into agg_group_4_nsc select (g/2)::numeric as c1, array_agg(g::numeric) as c2, count(*) as c3 from agg_data_2k_nsc group by g/2; -- Produce results with hash aggregation ---Testcase 426: +--Testcase 428: set enable_hashagg = true; ---Testcase 427: +--Testcase 429: set enable_sort = false; ---Testcase 428: +--Testcase 430: set jit_above_cost = 0; ---Testcase 429: +--Testcase 431: explain (costs off) select (fields->>'g')::int%10000 as c1, sum((fields->>'g')::numeric) as c2, count(*) as c3 from agg_data_20k group by (fields->>'g')::int%10000; ---Testcase 430: +--Testcase 432: insert into agg_hash_1_nsc select g%10000 as c1, sum(g::numeric) as c2, count(*) as c3 from agg_data_20k_nsc group by g%10000; ---Testcase 431: +--Testcase 433: insert into agg_hash_2_nsc select * from (values (100), (300), (500)) as r(a), @@ -1775,84 +2093,107 @@ select * from where g < r.a group by g/2) as s; ---Testcase 432: +--Testcase 434: set jit_above_cost to default; ---Testcase 433: +--Testcase 435: insert into agg_hash_3_nsc select (g/2)::numeric as c1, sum(7::int4) as c2, count(*) as c3 from agg_data_2k_nsc group by g/2; ---Testcase 434: +--Testcase 436: insert into agg_hash_4_nsc select (g/2)::numeric as c1, array_agg(g::numeric) as c2, count(*) as c3 from agg_data_2k_nsc group by g/2; ---Testcase 435: +--Testcase 437: set enable_sort = true; ---Testcase 436: +--Testcase 438: set work_mem to default; -- Compare group aggregation results to hash aggregation results ---Testcase 437: +--Testcase 439: (select * from agg_hash_1 except select * from agg_group_1) union all (select * from agg_group_1 except select * from agg_hash_1); ---Testcase 438: +--Testcase 440: (select * from agg_hash_2 except select * from agg_group_2) union all (select * from agg_group_2 except select * from agg_hash_2); ---Testcase 439: +--Testcase 441: (select * from agg_hash_3 except select * from agg_group_3) union all (select * from agg_group_3 except select * from agg_hash_3); ---Testcase 440: +--Testcase 442: (select * from agg_hash_4 except select * from agg_group_4) union all (select * from agg_group_4 except select * from agg_hash_4); ---Testcase 441: +--Testcase 443: -- Clean up: +--Testcase 499: delete from agg_data_2k_nsc; +--Testcase 500: delete from agg_data_20k_nsc; +--Testcase 501: delete from agg_group_1_nsc; +--Testcase 502: delete from agg_group_2_nsc; +--Testcase 503: delete from agg_group_3_nsc; +--Testcase 504: delete from agg_group_4_nsc; +--Testcase 505: delete from agg_hash_1_nsc; +--Testcase 506: delete from agg_hash_2_nsc; +--Testcase 507: delete from agg_hash_3_nsc; +--Testcase 508: delete from agg_hash_4_nsc; +--Testcase 509: drop foreign table agg_data_2k; +--Testcase 510: drop foreign table agg_data_2k_nsc; +--Testcase 511: drop foreign table agg_data_20k; +--Testcase 512: drop foreign table agg_data_20k_nsc; +--Testcase 513: drop foreign table agg_group_1; +--Testcase 514: drop foreign table agg_group_1_nsc; ---Testcase 442: +--Testcase 444: drop foreign table agg_group_2; +--Testcase 515: drop foreign table agg_group_2_nsc; ---Testcase 443: +--Testcase 445: drop foreign table agg_group_3; +--Testcase 516: drop foreign table agg_group_3_nsc; ---Testcase 444: +--Testcase 446: drop foreign table agg_group_4; +--Testcase 517: drop foreign table agg_group_4_nsc; ---Testcase 445: +--Testcase 447: drop foreign table agg_hash_1; +--Testcase 518: drop foreign table agg_hash_1_nsc; ---Testcase 446: +--Testcase 448: drop foreign table agg_hash_2; +--Testcase 519: drop foreign table agg_hash_2_nsc; ---Testcase 447: +--Testcase 449: drop foreign table agg_hash_3; +--Testcase 520: drop foreign table agg_hash_3_nsc; ---Testcase 448: +--Testcase 450: drop foreign table agg_hash_4; +--Testcase 521: drop foreign table agg_hash_4_nsc; -- Clean up DO $d$ @@ -1867,29 +2208,45 @@ end; $d$; -- Clean up: +--Testcase 522: DROP AGGREGATE IF EXISTS newavg (int4); +--Testcase 523: DROP AGGREGATE IF EXISTS newsum (int4); +--Testcase 524: DROP AGGREGATE IF EXISTS newcnt (*); +--Testcase 525: DROP AGGREGATE IF EXISTS oldcnt (*); +--Testcase 526: DROP AGGREGATE IF EXISTS newcnt ("any"); +--Testcase 527: DROP AGGREGATE IF EXISTS sum2(int8,int8); +--Testcase 528: DROP FUNCTION IF EXISTS sum3(int8,int8,int8); +--Testcase 529: DROP AGGREGATE IF EXISTS aggfns(integer,integer,text); +--Testcase 530: DROP AGGREGATE IF EXISTS aggfstr(integer,integer,text); +--Testcase 531: DROP FUNCTION IF EXISTS aggfns_trans(aggtype[],integer,integer,text); +--Testcase 532: DROP FUNCTION IF EXISTS aggf_trans(aggtype[],integer,integer,text); +--Testcase 533: DROP TYPE IF EXISTS aggtype; +--Testcase 534: DROP AGGREGATE IF EXISTS test_percentile_disc(float8 ORDER BY anyelement); +--Testcase 535: DROP AGGREGATE IF EXISTS test_rank(VARIADIC "any" ORDER BY VARIADIC "any"); +--Testcase 536: DROP AGGREGATE IF EXISTS cleast_agg(variadic items anycompatiblearray); +--Testcase 537: DROP FUNCTION IF EXISTS cleast_accum(anycompatible, variadic anycompatiblearray); ---Testcase 449: +--Testcase 451: DROP USER MAPPING FOR CURRENT_USER SERVER influxdb_svr; ---Testcase 450: +--Testcase 452: DROP SERVER influxdb_svr CASCADE; ---Testcase 451: +--Testcase 453: DROP EXTENSION influxdb_fdw; diff --git a/sql/11.17/schemaless/extra/influxdb_fdw_post.sql b/sql/16.0/schemaless/extra/influxdb_fdw_post.sql similarity index 73% rename from sql/11.17/schemaless/extra/influxdb_fdw_post.sql rename to sql/16.0/schemaless/extra/influxdb_fdw_post.sql index 7160ed6..2427705 100644 --- a/sql/11.17/schemaless/extra/influxdb_fdw_post.sql +++ b/sql/16.0/schemaless/extra/influxdb_fdw_post.sql @@ -32,35 +32,39 @@ CREATE TYPE user_enum AS ENUM ('foo', 'bar', 'buz'); --Testcase 9: CREATE SCHEMA "S 1"; --Testcase 10: -CREATE FOREIGN TABLE "S 1"."T 0" (time timestamp, tags jsonb OPTIONS(tags 'true'), fields jsonb OPTIONS(fields 'true')) SERVER influxdb_svr OPTIONS (table 'T0', tags 'c3', schemaless 'true'); +CREATE FOREIGN TABLE "S 1"."T 0" (time timestamptz, tags jsonb OPTIONS(tags 'true'), fields jsonb OPTIONS(fields 'true')) SERVER influxdb_svr OPTIONS (table 'T0', tags 'c3', schemaless 'true'); +--Testcase 783: CREATE FOREIGN TABLE "S 1".s1t0 ( "C 1" int NOT NULL, c2 int NOT NULL, c3 text, - time timestamp, + time timestamptz, c6 varchar(10), c7 char(10), c8 text ) SERVER influxdb_svr OPTIONS (table 'T0', tags 'c3'); --Testcase 11: -CREATE FOREIGN TABLE "S 1"."T 1" (time timestamp, tags jsonb OPTIONS(tags 'true'), fields jsonb OPTIONS(fields 'true')) SERVER influxdb_svr OPTIONS (table 'T1', tags 'c3', schemaless 'true'); +CREATE FOREIGN TABLE "S 1"."T 1" (time timestamptz, tags jsonb OPTIONS(tags 'true'), fields jsonb OPTIONS(fields 'true')) SERVER influxdb_svr OPTIONS (table 'T1', tags 'c3', schemaless 'true'); +--Testcase 784: CREATE FOREIGN TABLE "S 1".s1t1 ( "C 1" int NOT NULL, c2 int NOT NULL, c3 text, - time timestamp, + time timestamptz, c6 varchar(10), c7 char(10), c8 text ) SERVER influxdb_svr OPTIONS (table 'T1', tags 'c3'); --Testcase 12: CREATE FOREIGN TABLE "S 1"."T 2" (tags jsonb OPTIONS(tags 'true'), fields jsonb OPTIONS(fields 'true')) SERVER influxdb_svr OPTIONS (table 'T2', tags 'c2', schemaless 'true'); +--Testcase 785: CREATE FOREIGN TABLE "S 1".s1t2 ( c1 int NOT NULL, c2 text ) SERVER influxdb_svr OPTIONS (table 'T2', tags 'c2'); --Testcase 13: CREATE FOREIGN TABLE "S 1"."T 3" (tags jsonb OPTIONS(tags 'true'), fields jsonb OPTIONS(fields 'true')) SERVER influxdb_svr OPTIONS (table 'T3', tags 'c3', schemaless 'true'); +--Testcase 786: CREATE FOREIGN TABLE "S 1".s1t3 ( c1 int NOT NULL, c2 int NOT NULL, @@ -68,6 +72,7 @@ CREATE FOREIGN TABLE "S 1".s1t3 ( ) SERVER influxdb_svr OPTIONS (table 'T3', tags 'c3'); --Testcase 14: CREATE FOREIGN TABLE "S 1"."T 4" (tags jsonb OPTIONS(tags 'true'), fields jsonb OPTIONS(fields 'true')) SERVER influxdb_svr OPTIONS (table 'T4', tags 'c3', schemaless 'true'); +--Testcase 787: CREATE FOREIGN TABLE "S 1".s1t4 ( c1 int NOT NULL, c2 int NOT NULL, @@ -85,7 +90,7 @@ INSERT INTO "S 1".s1t1 SELECT id, id % 10, to_char(id, 'FM00000'), - '1970-01-01'::timestamp + ((id % 100) || ' days')::interval, + '1970-01-01'::timestamptz + ((id % 100) || ' days')::interval, id % 10, id % 10, 'foo'::text @@ -121,52 +126,61 @@ DELETE FROM "S 1".s1t4 WHERE c1 % 3 != 0; -- delete for outer join tests -- create foreign tables -- =================================================================== --Testcase 21: -CREATE FOREIGN TABLE ft1 (time timestamp, tags jsonb OPTIONS(tags 'true'), fields jsonb OPTIONS(fields 'true')) SERVER influxdb_svr OPTIONS (schemaless 'true'); +CREATE FOREIGN TABLE ft1 (time timestamptz, tags jsonb OPTIONS(tags 'true'), fields jsonb OPTIONS(fields 'true')) SERVER influxdb_svr OPTIONS (schemaless 'true'); +--Testcase 788: CREATE FOREIGN TABLE ft1_nsc ( c0 int, c1 int NOT NULL, c2 int NOT NULL, c3 text, - time timestamp, + time timestamptz, c6 varchar(10), c7 char(10) default 'ft1', c8 text ) SERVER influxdb_svr; -ALTER FOREIGN TABLE ft1_nsc DROP COLUMN c0; --Testcase 22: -CREATE FOREIGN TABLE ft2 (time timestamp, tags jsonb OPTIONS(tags 'true'), fields jsonb OPTIONS(fields 'true')) SERVER influxdb_svr OPTIONS (schemaless 'true'); +ALTER FOREIGN TABLE ft1_nsc DROP COLUMN c0; + +--Testcase 23: +CREATE FOREIGN TABLE ft2 (time timestamptz, tags jsonb OPTIONS(tags 'true'), fields jsonb OPTIONS(fields 'true')) SERVER influxdb_svr OPTIONS (schemaless 'true'); +--Testcase 789: CREATE FOREIGN TABLE ft2_nsc ( c1 int NOT NULL, c2 int NOT NULL, cx int, c3 text, - time timestamp, + time timestamptz, c6 varchar(10), c7 char(10) default 'ft2', c8 text ) SERVER influxdb_svr; +--Testcase 24: ALTER FOREIGN TABLE ft2_nsc DROP COLUMN cx; ---Testcase 23: + +--Testcase 25: CREATE FOREIGN TABLE ft4 (tags jsonb OPTIONS(tags 'true'), fields jsonb OPTIONS(fields 'true')) SERVER influxdb_svr OPTIONS (table 'T3', tags 'c3', schemaless 'true'); +--Testcase 790: CREATE FOREIGN TABLE ft4_nsc ( c1 int NOT NULL, c2 int NOT NULL, c3 text ) SERVER influxdb_svr OPTIONS (table 'T3', tags 'c3'); ---Testcase 24: +--Testcase 26: CREATE FOREIGN TABLE ft5 (tags jsonb OPTIONS(tags 'true'), fields jsonb OPTIONS(fields 'true')) SERVER influxdb_svr OPTIONS (table 'T4', tags 'c3', schemaless 'true'); +--Testcase 791: CREATE FOREIGN TABLE ft5_nsc ( c1 int NOT NULL, c2 int NOT NULL, c3 text ) SERVER influxdb_svr OPTIONS (table 'T4', tags 'c3'); ---Testcase 25: +--Testcase 27: CREATE FOREIGN TABLE ft6 (tags jsonb OPTIONS(tags 'true'), fields jsonb OPTIONS(fields 'true')) SERVER influxdb_svr2 OPTIONS (table 'T4', tags 'c3', schemaless 'true'); -- =================================================================== -- tests for validator -- =================================================================== -- requiressl and some other parameters are omitted because -- valid values for them depend on configure options +--Testcase 28: ALTER SERVER testserver1 OPTIONS ( -- use_remote_estimate 'false', -- updatable 'true', @@ -206,6 +220,7 @@ ALTER SERVER testserver1 OPTIONS ( --ALTER SERVER testserver1 OPTIONS (ADD extensions 'foo, bar'); --ALTER SERVER testserver1 OPTIONS (DROP extensions); +--Testcase 29: ALTER USER MAPPING FOR public SERVER testserver1 OPTIONS (DROP user, DROP password); @@ -222,22 +237,27 @@ ALTER USER MAPPING FOR public SERVER testserver1 --ALTER USER MAPPING FOR public SERVER testserver1 -- OPTIONS (ADD sslkey 'value', ADD sslcert 'value'); +--Testcase 30: ALTER FOREIGN TABLE ft1 OPTIONS (table 'T1', tags 'c3'); ALTER FOREIGN TABLE ft1_nsc OPTIONS (table 'T1', tags 'c3'); +--Testcase 31: ALTER FOREIGN TABLE ft2 OPTIONS (table 'T1', tags 'c3'); ALTER FOREIGN TABLE ft2_nsc OPTIONS (table 'T1', tags 'c3'); +--Testcase 32: ALTER FOREIGN TABLE ft1_nsc ALTER COLUMN c1 OPTIONS (column_name 'C 1'); +--Testcase 33: ALTER FOREIGN TABLE ft2_nsc ALTER COLUMN c1 OPTIONS (column_name 'C 1'); ---Testcase 26: +--Testcase 34: \det+ -- Test that alteration of server options causes reconnection -- Remote's errors might be non-English, so hide them to ensure stable results \set VERBOSITY terse ---Testcase 27: +--Testcase 35: SELECT tags->>'c3' c3, time FROM ft1 ORDER BY tags->>'c3', (fields->>'C 1')::int LIMIT 1; -- should work +--Testcase 36: ALTER SERVER influxdb_svr OPTIONS (SET dbname 'no such database'); ---Testcase 28: +--Testcase 37: SELECT tags->>'c3' c3, time FROM ft1 ORDER BY tags->>'c3', (fields->>'C 1')::int LIMIT 1; -- should fail DO $d$ BEGIN @@ -245,164 +265,192 @@ DO $d$ OPTIONS (SET dbname 'postdb')$$; END; $d$; ---Testcase 29: +--Testcase 38: SELECT tags->>'c3' c3, time FROM ft1 ORDER BY tags->>'c3', (fields->>'C 1')::int LIMIT 1; -- should work again \set VERBOSITY default +-- =================================================================== +-- test error case for create publication on foreign table +-- =================================================================== +--Testcase 765: +CREATE PUBLICATION testpub_ftbl FOR TABLE ft1; -- should fail + -- =================================================================== -- simple queries -- =================================================================== -- single table without alias ---Testcase 30: +--Testcase 39: EXPLAIN (COSTS OFF) SELECT * FROM ft1 ORDER BY tags->>'c3', (fields->>'C 1')::int OFFSET 100 LIMIT 10; ---Testcase 31: +--Testcase 40: SELECT * FROM ft1 ORDER BY tags->>'c3', (fields->>'C 1')::int OFFSET 100 LIMIT 10; -- single table with alias - also test that tableoid sort is not pushed to remote side ---Testcase 32: +--Testcase 41: EXPLAIN (VERBOSE, COSTS OFF) SELECT * FROM ft1 t1 ORDER BY t1.tags->>'c3', (t1.fields->>'C 1')::int, t1.tableoid OFFSET 100 LIMIT 10; ---Testcase 33: +--Testcase 42: SELECT * FROM ft1 t1 ORDER BY t1.tags->>'c3', (t1.fields->>'C 1')::int, t1.tableoid OFFSET 100 LIMIT 10; -- whole-row reference ---Testcase 34: +--Testcase 43: EXPLAIN (VERBOSE, COSTS OFF) SELECT t1 FROM ft1 t1 ORDER BY t1.tags->>'c3', (t1.fields->>'C 1')::int OFFSET 100 LIMIT 10; ---Testcase 35: +--Testcase 44: SELECT t1 FROM ft1 t1 ORDER BY t1.tags->>'c3', (t1.fields->>'C 1')::int OFFSET 100 LIMIT 10; -- empty result ---Testcase 36: +--Testcase 45: SELECT * FROM ft1 WHERE false; -- with WHERE clause ---Testcase 37: +--Testcase 46: EXPLAIN (VERBOSE, COSTS OFF) SELECT * FROM ft1 t1 WHERE (t1.fields->>'C 1')::int = 101 AND t1.fields->>'c6' = '1' AND t1.fields->>'c7' >= '1'; ---Testcase 38: +--Testcase 47: SELECT * FROM ft1 t1 WHERE (t1.fields->>'C 1')::int = 101 AND t1.fields->>'c6' = '1' AND t1.fields->>'c7' >= '1'; -- with FOR UPDATE/SHARE ---Testcase 39: +--Testcase 48: EXPLAIN (VERBOSE, COSTS OFF) SELECT * FROM ft1 t1 WHERE (fields->>'C 1')::int = 101 FOR UPDATE; ---Testcase 40: +--Testcase 49: SELECT * FROM ft1 t1 WHERE (fields->>'C 1')::int = 101 FOR UPDATE; ---Testcase 41: +--Testcase 50: EXPLAIN (VERBOSE, COSTS OFF) SELECT * FROM ft1 t1 WHERE (fields->>'C 1')::int = 102 FOR SHARE; ---Testcase 42: +--Testcase 51: SELECT * FROM ft1 t1 WHERE (fields->>'C 1')::int = 102 FOR SHARE; -- aggregate ---Testcase 43: +--Testcase 52: SELECT COUNT(*) FROM ft1 t1; -- subquery ---Testcase 44: +--Testcase 53: SELECT * FROM ft1 t1 WHERE t1.tags->>'c3' IN (SELECT tags->>'c3' FROM ft2 t2 WHERE (fields->>'C 1')::int <= 10) ORDER BY (fields->>'C 1')::int; -- subquery+MAX ---Testcase 45: +--Testcase 54: SELECT * FROM ft1 t1 WHERE t1.tags->>'c3' = (SELECT MAX(tags->>'c3') FROM ft2 t2) ORDER BY (fields->>'C 1')::int; -- used in CTE ---Testcase 46: +--Testcase 55: WITH t1 AS (SELECT * FROM ft1 WHERE (fields->>'C 1')::int <= 10) SELECT (t2.fields->>'C 1')::int c1, (t2.fields->>'c2')::int c2, t2.tags->>'c3' c3, t2.time FROM t1, ft2 t2 WHERE (t1.fields->>'C 1')::int = (t2.fields->>'C 1')::int ORDER BY (t1.fields->>'C 1')::int; -- fixed values ---Testcase 47: +--Testcase 56: SELECT 'fixed', NULL FROM ft1 t1 WHERE (fields->>'C 1')::int = 1; -- Test forcing the remote server to produce sorted data for a merge join. +--Testcase 57: SET enable_hashjoin TO false; +--Testcase 58: SET enable_nestloop TO false; -- inner join; expressions in the clauses appear in the equivalence class list ---Testcase 48: +--Testcase 59: EXPLAIN (VERBOSE, COSTS OFF) SELECT t1.c1, t2."C 1" FROM (SELECT (fields->>'C 1')::int c1, (fields->>'c2')::int c2, tags->>'c3' c3, fields->>'c4' c4, fields->>'c5' c5, fields->>'c6' c6, fields->>'c7' c7, fields->>'c8' c8 FROM ft2 t1) t1 JOIN (SELECT (fields->>'C 1')::int "C 1", (fields->>'c2')::int c2, tags->>'c3' c3, fields->>'c4' c4, fields->>'c5' c5, fields->>'c6' c6, fields->>'c7' c7, fields->>'c8' c8 FROM "S 1"."T 1" t2) t2 ON ((t1.c1)::int = (t2."C 1")::int) OFFSET 100 LIMIT 10; ---Testcase 49: +--Testcase 60: SELECT t1.c1, t2."C 1" FROM (SELECT (fields->>'C 1')::int c1, (fields->>'c2')::int c2, tags->>'c3' c3, fields->>'c4' c4, fields->>'c5' c5, fields->>'c6' c6, fields->>'c7' c7, fields->>'c8' c8 FROM ft2 t1) t1 JOIN (SELECT (fields->>'C 1')::int "C 1", (fields->>'c2')::int c2, tags->>'c3' c3, fields->>'c4' c4, fields->>'c5' c5, fields->>'c6' c6, fields->>'c7' c7, fields->>'c8' c8 FROM "S 1"."T 1" t2) t2 ON ((t1.c1)::int = (t2."C 1")::int) OFFSET 100 LIMIT 10; -- outer join; expressions in the clauses do not appear in equivalence class -- list but no output change as compared to the previous query ---Testcase 50: +--Testcase 61: EXPLAIN (VERBOSE, COSTS OFF) SELECT t1.c1, t2."C 1" FROM (SELECT (fields->>'C 1')::int c1, (fields->>'c2')::int c2, tags->>'c3' c3, fields->>'c4' c4, fields->>'c5' c5, fields->>'c6' c6, fields->>'c7' c7, fields->>'c8' c8 FROM ft2 t1) t1 LEFT JOIN (SELECT (fields->>'C 1')::int "C 1", (fields->>'c2')::int c2, tags->>'c3' c3, fields->>'c4' c4, fields->>'c5' c5, fields->>'c6' c6, fields->>'c7' c7, fields->>'c8' c8 FROM "S 1"."T 1" t2) t2 ON ((t1.c1)::int = (t2."C 1")::int) OFFSET 100 LIMIT 10; ---Testcase 51: +--Testcase 62: SELECT t1.c1, t2."C 1" FROM (SELECT (fields->>'C 1')::int c1, (fields->>'c2')::int c2, tags->>'c3' c3, fields->>'c4' c4, fields->>'c5' c5, fields->>'c6' c6, fields->>'c7' c7, fields->>'c8' c8 FROM ft2 t1) t1 LEFT JOIN (SELECT (fields->>'C 1')::int "C 1", (fields->>'c2')::int c2, tags->>'c3' c3, fields->>'c4' c4, fields->>'c5' c5, fields->>'c6' c6, fields->>'c7' c7, fields->>'c8' c8 FROM "S 1"."T 1" t2) t2 ON ((t1.c1)::int = (t2."C 1")::int) OFFSET 100 LIMIT 10; -- A join between 2 foreign tables. ORDER BY clause is added to the -- foreign join so that the other table can be joined using merge join strategy. ---Testcase 52: +--Testcase 63: EXPLAIN (VERBOSE, COSTS OFF) SELECT t1."C 1" FROM (SELECT (fields->>'C 1')::int "C 1", (fields->>'c2')::int c2, tags->>'c3' c3, fields->>'c4' c4, fields->>'c5' c5, fields->>'c6' c6, fields->>'c7' c7, fields->>'c8' c8 FROM "S 1"."T 1" t1) t1 left join (SELECT (fields->>'C 1')::int c1, (fields->>'c2')::int c2, tags->>'c3' c3, fields->>'c4' c4, fields->>'c5' c5, fields->>'c6' c6, fields->>'c7' c7, fields->>'c8' c8 FROM ft1 t2) t2 join (SELECT (fields->>'C 1')::int c1, (fields->>'c2')::int c2, tags->>'c3' c3, fields->>'c4' c4, fields->>'c5' c5, fields->>'c6' c6, fields->>'c7' c7, fields->>'c8' c8 FROM ft2 t3) t3 on ((t2.c1)::int = (t3.c1)::int) on ((t3.c1)::int = (t1."C 1")::int) OFFSET 100 LIMIT 10; ---Testcase 53: +--Testcase 64: SELECT t1."C 1" FROM (SELECT (fields->>'C 1')::int "C 1", (fields->>'c2')::int c2, tags->>'c3' c3, fields->>'c4' c4, fields->>'c5' c5, fields->>'c6' c6, fields->>'c7' c7, fields->>'c8' c8 FROM "S 1"."T 1" t1) t1 left join (SELECT (fields->>'C 1')::int c1, (fields->>'c2')::int c2, tags->>'c3' c3, fields->>'c4' c4, fields->>'c5' c5, fields->>'c6' c6, fields->>'c7' c7, fields->>'c8' c8 FROM ft1 t2) t2 join (SELECT (fields->>'C 1')::int c1, (fields->>'c2')::int c2, tags->>'c3' c3, fields->>'c4' c4, fields->>'c5' c5, fields->>'c6' c6, fields->>'c7' c7, fields->>'c8' c8 FROM ft2 t3) t3 on ((t2.c1)::int = (t3.c1)::int) on ((t3.c1)::int = (t1."C 1")::int) OFFSET 100 LIMIT 10; -- Test similar to above, except that the full join prevents any equivalence -- classes from being merged. This produces single relation equivalence classes -- included in join restrictions. ---Testcase 54: +--Testcase 65: EXPLAIN (VERBOSE, COSTS OFF) SELECT t1."C 1", t2.c1, t3.c1 FROM (SELECT (fields->>'C 1')::int "C 1", (fields->>'c2')::int c2, tags->>'c3' c3, fields->>'c4' c4, fields->>'c5' c5, fields->>'c6' c6, fields->>'c7' c7, fields->>'c8' c8 FROM "S 1"."T 1" t1) t1 left join (SELECT (fields->>'C 1')::int c1, (fields->>'c2')::int c2, tags->>'c3' c3, fields->>'c4' c4, fields->>'c5' c5, fields->>'c6' c6, fields->>'c7' c7, fields->>'c8' c8 FROM ft1 t2) t2 full join (SELECT (fields->>'C 1')::int c1, (fields->>'c2')::int c2, tags->>'c3' c3, fields->>'c4' c4, fields->>'c5' c5, fields->>'c6' c6, fields->>'c7' c7, fields->>'c8' c8 FROM ft2 t3) t3 on ((t2.c1)::int = (t3.c1)::int) on ((t3.c1)::int = (t1."C 1")::int) OFFSET 100 LIMIT 10; ---Testcase 55: +--Testcase 66: SELECT t1."C 1", t2.c1, t3.c1 FROM (SELECT (fields->>'C 1')::int "C 1", (fields->>'c2')::int c2, tags->>'c3' c3, fields->>'c4' c4, fields->>'c5' c5, fields->>'c6' c6, fields->>'c7' c7, fields->>'c8' c8 FROM "S 1"."T 1" t1) t1 left join (SELECT (fields->>'C 1')::int c1, (fields->>'c2')::int c2, tags->>'c3' c3, fields->>'c4' c4, fields->>'c5' c5, fields->>'c6' c6, fields->>'c7' c7, fields->>'c8' c8 FROM ft1 t2) t2 full join (SELECT (fields->>'C 1')::int c1, (fields->>'c2')::int c2, tags->>'c3' c3, fields->>'c4' c4, fields->>'c5' c5, fields->>'c6' c6, fields->>'c7' c7, fields->>'c8' c8 FROM ft2 t3) t3 on ((t2.c1)::int = (t3.c1)::int) on ((t3.c1)::int = (t1."C 1")::int) OFFSET 100 LIMIT 10; -- Test similar to above with all full outer joins ---Testcase 56: +--Testcase 67: EXPLAIN (VERBOSE, COSTS OFF) SELECT t1."C 1", t2.c1, t3.c1 FROM (SELECT (fields->>'C 1')::int "C 1", (fields->>'c2')::int c2, tags->>'c3' c3, fields->>'c4' c4, fields->>'c5' c5, fields->>'c6' c6, fields->>'c7' c7, fields->>'c8' c8 FROM "S 1"."T 1" t1) t1 full join (SELECT (fields->>'C 1')::int c1, (fields->>'c2')::int c2, tags->>'c3' c3, fields->>'c4' c4, fields->>'c5' c5, fields->>'c6' c6, fields->>'c7' c7, fields->>'c8' c8 FROM ft1 t2) t2 full join (SELECT (fields->>'C 1')::int c1, (fields->>'c2')::int c2, tags->>'c3' c3, fields->>'c4' c4, fields->>'c5' c5, fields->>'c6' c6, fields->>'c7' c7, fields->>'c8' c8 FROM ft2 t3) t3 on ((t2.c1)::int = (t3.c1)::int) on ((t3.c1)::int = (t1."C 1")::int) OFFSET 100 LIMIT 10; ---Testcase 57: +--Testcase 68: SELECT t1."C 1", t2.c1, t3.c1 FROM (SELECT (fields->>'C 1')::int "C 1", (fields->>'c2')::int c2, tags->>'c3' c3, fields->>'c4' c4, fields->>'c5' c5, fields->>'c6' c6, fields->>'c7' c7, fields->>'c8' c8 FROM "S 1"."T 1" t1) t1 full join (SELECT (fields->>'C 1')::int c1, (fields->>'c2')::int c2, tags->>'c3' c3, fields->>'c4' c4, fields->>'c5' c5, fields->>'c6' c6, fields->>'c7' c7, fields->>'c8' c8 FROM ft1 t2) t2 full join (SELECT (fields->>'C 1')::int c1, (fields->>'c2')::int c2, tags->>'c3' c3, fields->>'c4' c4, fields->>'c5' c5, fields->>'c6' c6, fields->>'c7' c7, fields->>'c8' c8 FROM ft2 t3) t3 on ((t2.c1)::int = (t3.c1)::int) on ((t3.c1)::int = (t1."C 1")::int) OFFSET 100 LIMIT 10; +--Testcase 69: RESET enable_hashjoin; +--Testcase 70: RESET enable_nestloop; +-- Test executing assertion in estimate_path_cost_size() that makes sure that +-- retrieved_rows for foreign rel re-used to cost pre-sorted foreign paths is +-- a sensible value even when the rel has tuples=0 +--Testcase 71: +CREATE FOREIGN TABLE loct_empty (fields jsonb OPTIONS(fields 'true')) SERVER influxdb_svr OPTIONS (schemaless 'true'); +--Testcase 792: +CREATE FOREIGN TABLE loct_empty_nsc (c1 int NOT NULL, c2 text) SERVER influxdb_svr OPTIONS (table 'loct_empty'); +--Testcase 72: +CREATE FOREIGN TABLE ft_empty (fields jsonb OPTIONS(fields 'true')) SERVER influxdb_svr OPTIONS (table 'loct_empty', schemaless 'true'); +--Testcase 73: +INSERT INTO loct_empty_nsc + SELECT id, 'AAA' || to_char(id, 'FM000') FROM generate_series(1, 100) id; +--Testcase 74: +DELETE FROM loct_empty_nsc; +--Testcase 793: +DROP FOREIGN TABLE loct_empty_nsc; +--ANALYZE ft_empty; +--Testcase 75: +EXPLAIN (VERBOSE, COSTS OFF) SELECT * FROM ft_empty ORDER BY (fields->>'c1')::int; + -- =================================================================== -- WHERE with remotely-executable conditions -- =================================================================== ---Testcase 58: +--Testcase 76: EXPLAIN (VERBOSE, COSTS OFF) SELECT * FROM ft1 t1 WHERE (t1.fields->>'C 1')::int = 1; -- Var, OpExpr(b), Const ---Testcase 59: +--Testcase 77: EXPLAIN (VERBOSE, COSTS OFF) SELECT * FROM ft1 t1 WHERE (t1.fields->>'C 1')::int = 100 AND (t1.fields->>'c2')::int = 0; -- BoolExpr ---Testcase 60: +--Testcase 78: EXPLAIN (VERBOSE, COSTS OFF) SELECT * FROM ft1 t1 WHERE (t1.fields->>'C 1')::int IS NULL; -- NullTest ---Testcase 61: +--Testcase 79: EXPLAIN (VERBOSE, COSTS OFF) SELECT * FROM ft1 t1 WHERE (t1.fields->>'C 1')::int IS NOT NULL; -- NullTest ---Testcase 62: +--Testcase 80: EXPLAIN (VERBOSE, COSTS OFF) SELECT * FROM ft1 t1 WHERE round(abs((t1.fields->>'C 1')::int), 0) = 1; -- FuncExpr ---Testcase 63: +--Testcase 81: EXPLAIN (VERBOSE, COSTS OFF) SELECT * FROM ft1 t1 WHERE (t1.fields->>'C 1')::int = -(t1.fields->>'C 1')::int; -- OpExpr(l) ---Testcase 64: -EXPLAIN (VERBOSE, COSTS OFF) SELECT * FROM ft1 t1 WHERE 1 = (t1.fields->>'C 1')::int!; -- OpExpr(r) ---Testcase 65: +--Testcase 82: EXPLAIN (VERBOSE, COSTS OFF) SELECT * FROM ft1 t1 WHERE ((t1.fields->>'C 1')::int IS NOT NULL) IS DISTINCT FROM ((t1.fields->>'C 1')::int IS NOT NULL); -- DistinctExpr ---Testcase 66: +--Testcase 83: EXPLAIN (VERBOSE, COSTS OFF) SELECT * FROM ft1 t1 WHERE (t1.fields->>'C 1')::int = ANY(ARRAY[(fields->>'c2')::int, 1, (t1.fields->>'C 1')::int + 0]); -- ScalarArrayOpExpr ---Testcase 67: +--Testcase 84: EXPLAIN (VERBOSE, COSTS OFF) SELECT * FROM ft1 t1 WHERE (t1.fields->>'C 1')::int = (ARRAY[(t1.fields->>'C 1')::int,(fields->>'c2')::int,3])[1]; -- SubscriptingRef ---Testcase 68: +--Testcase 85: EXPLAIN (VERBOSE, COSTS OFF) SELECT * FROM ft1 t1 WHERE fields->>'c6' = E'foo''s\\bar'; -- check special chars ---Testcase 69: +--Testcase 86: EXPLAIN (VERBOSE, COSTS OFF) SELECT * FROM ft1 t1 WHERE fields->>'c8' = 'foo'; -- can't be sent to remote -- parameterized remote path for foreign table ---Testcase 70: +--Testcase 87: EXPLAIN (VERBOSE, COSTS OFF) SELECT * FROM "S 1"."T 1" a, ft2 b WHERE (a.fields->>'C 1')::int = 47 AND (b.fields->>'C 1')::int = (a.fields->>'c2')::int; ---Testcase 71: -SELECT * FROM ft2 a, ft2 b WHERE (a.fields->>'C 1')::int = 47 AND (b.fields->>'C 1')::int = (a.fields->>'c2')::int; +--Testcase 88: +SELECT * FROM "S 1"."T 1" a, ft2 b WHERE (a.fields->>'C 1')::int = 47 AND (b.fields->>'C 1')::int = (a.fields->>'c2')::int; -- check both safe and unsafe join conditions ---Testcase 72: +--Testcase 89: EXPLAIN (VERBOSE, COSTS OFF) SELECT * FROM ft2 a, ft2 b WHERE (a.fields->>'c2')::int = 6 AND (b.fields->>'C 1')::int = (a.fields->>'C 1')::int AND a.fields->>'c8' = 'foo' AND b.fields->>'c7' = upper(a.fields->>'c7'); ---Testcase 73: +--Testcase 90: SELECT * FROM ft2 a, ft2 b WHERE (a.fields->>'c2')::int = 6 AND (b.fields->>'C 1')::int = (a.fields->>'C 1')::int AND a.fields->>'c8' = 'foo' AND b.fields->>'c7' = upper(a.fields->>'c7') ORDER BY (a.fields->>'C 1')::int; -- bug before 9.3.5 due to sloppy handling of remote-estimate parameters ---Testcase 74: +--Testcase 91: SELECT * FROM ft1 WHERE (fields->>'C 1')::int = ANY (ARRAY(SELECT (fields->>'C 1')::int FROM ft2 WHERE (fields->>'C 1')::int < 5)); ---Testcase 75: +--Testcase 92: SELECT * FROM ft2 WHERE (fields->>'C 1')::int = ANY (ARRAY(SELECT (fields->>'C 1')::int FROM ft1 WHERE (fields->>'C 1')::int < 5)); -- we should not push order by clause with volatile expressions or unsafe -- collations ---Testcase 76: +--Testcase 93: EXPLAIN (VERBOSE, COSTS OFF) SELECT * FROM ft2 ORDER BY (ft2.fields->>'C 1')::int, random(); ---Testcase 77: +--Testcase 94: EXPLAIN (VERBOSE, COSTS OFF) SELECT * FROM ft2 ORDER BY (ft2.fields->>'C 1')::int, ft2.tags->>'c3' collate "C"; -- user-defined operator/function ---Testcase 78: +--Testcase 95: CREATE FUNCTION influxdb_fdw_abs(int) RETURNS int AS $$ BEGIN RETURN abs($1); END $$ LANGUAGE plpgsql IMMUTABLE; ---Testcase 79: +--Testcase 96: CREATE OPERATOR === ( LEFTARG = int, RIGHTARG = int, @@ -411,65 +459,118 @@ CREATE OPERATOR === ( ); -- built-in operators and functions can be shipped for remote execution ---Testcase 80: +--Testcase 97: EXPLAIN (VERBOSE, COSTS OFF) SELECT count(tags->>'c3') FROM ft1 t1 WHERE (t1.fields->>'C 1')::int = abs((t1.fields->>'c2')::int); ---Testcase 81: +--Testcase 98: SELECT count(tags->>'c3') FROM ft1 t1 WHERE (t1.fields->>'C 1')::int = abs((t1.fields->>'c2')::int); ---Testcase 82: +--Testcase 99: EXPLAIN (VERBOSE, COSTS OFF) SELECT count(tags->>'c3') FROM ft1 t1 WHERE (t1.fields->>'C 1')::int = (t1.fields->>'c2')::int; ---Testcase 83: +--Testcase 100: SELECT count(tags->>'c3') FROM ft1 t1 WHERE (t1.fields->>'C 1')::int = (t1.fields->>'c2')::int; -- by default, user-defined ones cannot ---Testcase 84: +--Testcase 101: EXPLAIN (VERBOSE, COSTS OFF) SELECT count(tags->>'c3') FROM ft1 t1 WHERE (t1.fields->>'C 1')::int = influxdb_fdw_abs((t1.fields->>'c2')::int); ---Testcase 85: +--Testcase 102: SELECT count(tags->>'c3') FROM ft1 t1 WHERE (t1.fields->>'C 1')::int = influxdb_fdw_abs((t1.fields->>'c2')::int); ---Testcase 86: +--Testcase 103: EXPLAIN (VERBOSE, COSTS OFF) SELECT count(tags->>'c3') FROM ft1 t1 WHERE (t1.fields->>'C 1')::int === (t1.fields->>'c2')::int; ---Testcase 87: +--Testcase 104: SELECT count(tags->>'c3') FROM ft1 t1 WHERE (t1.fields->>'C 1')::int === (t1.fields->>'c2')::int; -- ORDER BY can be shipped, though ---Testcase 88: +--Testcase 105: EXPLAIN (VERBOSE, COSTS OFF) SELECT * FROM ft1 t1 WHERE (t1.fields->>'C 1')::int === (t1.fields->>'c2')::int order by (t1.fields->>'c2')::int limit 1; ---Testcase 89: +--Testcase 106: SELECT * FROM ft1 t1 WHERE (t1.fields->>'C 1')::int === (t1.fields->>'c2')::int order by (t1.fields->>'c2')::int limit 1; -- but let's put them in an extension ... +--Testcase 107: ALTER EXTENSION influxdb_fdw ADD FUNCTION influxdb_fdw_abs(int); +--Testcase 108: ALTER EXTENSION influxdb_fdw ADD OPERATOR === (int, int); -- ALTER SERVER loopback OPTIONS (ADD extensions 'influxdb_fdw'); -- ... now they can be shipped ---Testcase 90: +--Testcase 109: EXPLAIN (VERBOSE, COSTS OFF) SELECT count(tags->>'c3') FROM ft1 t1 WHERE (t1.fields->>'C 1')::int = influxdb_fdw_abs((t1.fields->>'c2')::int); ---Testcase 91: +--Testcase 110: SELECT count(tags->>'c3') FROM ft1 t1 WHERE (t1.fields->>'C 1')::int = influxdb_fdw_abs((t1.fields->>'c2')::int); ---Testcase 92: +--Testcase 111: EXPLAIN (VERBOSE, COSTS OFF) SELECT count(tags->>'c3') FROM ft1 t1 WHERE (t1.fields->>'C 1')::int === (t1.fields->>'c2')::int; ---Testcase 93: +--Testcase 112: SELECT count(tags->>'c3') FROM ft1 t1 WHERE (t1.fields->>'C 1')::int === (t1.fields->>'c2')::int; -- and both ORDER BY and LIMIT can be shipped ---Testcase 94: +--Testcase 113: EXPLAIN (VERBOSE, COSTS OFF) SELECT * FROM ft1 t1 WHERE (t1.fields->>'C 1')::int === (t1.fields->>'c2')::int order by (t1.fields->>'c2')::int limit 1; ---Testcase 95: +--Testcase 114: SELECT * FROM ft1 t1 WHERE (t1.fields->>'C 1')::int === (t1.fields->>'c2')::int order by (t1.fields->>'c2')::int limit 1; +-- Test CASE pushdown +--Testcase 854: +EXPLAIN (VERBOSE, COSTS OFF) +SELECT fields->>'C 1',fields->>'c2',tags->>'c3' FROM ft2 WHERE CASE WHEN (fields->>'C 1')::int > 990 THEN (fields->>'C 1')::int END < 1000 ORDER BY (fields->>'C 1')::int; +--Testcase 855: +SELECT fields->>'C 1',fields->>'c2',tags->>'c3' FROM ft2 WHERE CASE WHEN (fields->>'C 1')::int > 990 THEN (fields->>'C 1')::int END < 1000 ORDER BY (fields->>'C 1')::int; + +-- Nested CASE +--Testcase 856: +EXPLAIN (VERBOSE, COSTS OFF) +SELECT fields->>'C 1',fields->>'c2',tags->>'c3' FROM ft2 WHERE CASE CASE WHEN (fields->>'c2')::int > 0 THEN (fields->>'c2')::int END WHEN 100 THEN 601 WHEN (fields->>'c2')::int THEN (fields->>'c2')::int ELSE 0 END > 600 ORDER BY (fields->>'C 1')::int; +--Testcase 857: +SELECT fields->>'C 1',fields->>'c2',tags->>'c3' FROM ft2 WHERE CASE CASE WHEN (fields->>'c2')::int > 0 THEN (fields->>'c2')::int END WHEN 100 THEN 601 WHEN (fields->>'c2')::int THEN (fields->>'c2')::int ELSE 0 END > 600 ORDER BY (fields->>'C 1')::int; + +-- CASE arg WHEN +--Testcase 858: +EXPLAIN (VERBOSE, COSTS OFF) +SELECT * FROM ft1 WHERE (fields->>'C 1')::int > (CASE mod((fields->>'C 1')::int, 4) WHEN 0 THEN 1 WHEN 2 THEN 50 ELSE 100 END); + +-- CASE cannot be pushed down because of unshippable arg clause +--Testcase 859: +EXPLAIN (VERBOSE, COSTS OFF) +SELECT * FROM ft1 WHERE (fields->>'C 1')::int > (CASE random()::integer WHEN 0 THEN 1 WHEN 2 THEN 50 ELSE 100 END); + +-- these are shippable +--Testcase 860: +EXPLAIN (VERBOSE, COSTS OFF) +SELECT * FROM ft1 WHERE CASE (fields->>'c6')::text WHEN 'foo' THEN true ELSE (tags->>'c3')::text < 'bar' END; +--Testcase 861: +EXPLAIN (VERBOSE, COSTS OFF) +SELECT * FROM ft1 WHERE CASE (tags->>'c3')::text WHEN (fields->>'c6')::text THEN true ELSE (tags->>'c3')::text < 'bar' END; + +-- but this is not because of collation +--Testcase 862: +EXPLAIN (VERBOSE, COSTS OFF) +SELECT * FROM ft1 WHERE CASE (tags->>'c3')::text COLLATE "C" WHEN (fields->>'c6')::text THEN true ELSE (tags->>'c3')::text < 'bar' END; + -- This test case drop configuration when execute non-schemaless before +--Testcase 863: DROP TEXT SEARCH CONFIGURATION IF EXISTS public.custom_search; --- check schema-qualification of regconfig constant +-- a regconfig constant referring to this text search configuration +-- is initially unshippable +--Testcase 864: CREATE TEXT SEARCH CONFIGURATION public.custom_search (COPY = pg_catalog.english); +--Testcase 865: +EXPLAIN (VERBOSE, COSTS OFF) +SELECT (fields->>'C 1')::int c1, to_tsvector('custom_search'::regconfig, tags->>'c3') FROM ft1 +WHERE (fields->>'C 1')::int = 642 AND length(to_tsvector('custom_search'::regconfig, tags->>'c3')) > 0; +--Testcase 866: +SELECT (fields->>'C 1')::int c1, to_tsvector('custom_search'::regconfig, tags->>'c3') FROM ft1 +WHERE (fields->>'C 1')::int = 642 AND length(to_tsvector('custom_search'::regconfig, tags->>'c3')) > 0; +-- but if it's in a shippable extension, it can be shipped +ALTER EXTENSION influxdb_fdw ADD TEXT SEARCH CONFIGURATION public.custom_search; +-- however, that doesn't flush the shippability cache, so do a quick reconnect +\c - EXPLAIN (VERBOSE, COSTS OFF) SELECT (fields->>'C 1')::int c1, to_tsvector('custom_search'::regconfig, tags->>'c3') FROM ft1 WHERE (fields->>'C 1')::int = 642 AND length(to_tsvector('custom_search'::regconfig, tags->>'c3')) > 0; @@ -481,151 +582,155 @@ WHERE (fields->>'C 1')::int = 642 AND length(to_tsvector('custom_search'::regcon -- =================================================================== -- join two tables ---Testcase 96: +--Testcase 115: EXPLAIN (VERBOSE, COSTS OFF) SELECT t1.c1, t2.c1 FROM (SELECT (fields->>'C 1')::int c1, (fields->>'c2')::int c2, tags->>'c3' c3, fields->>'c4' c4, fields->>'c5' c5, fields->>'c6' c6, fields->>'c7' c7, fields->>'c8' c8 FROM ft1 t1) t1 JOIN (SELECT (fields->>'C 1')::int c1, (fields->>'c2')::int c2, tags->>'c3' c3, fields->>'c4' c4, fields->>'c5' c5, fields->>'c6' c6, fields->>'c7' c7, fields->>'c8' c8 FROM ft2 t2) t2 ON ((t1.c1)::int = (t2.c1)::int) ORDER BY t1.c3, (t1.c1)::int OFFSET 100 LIMIT 10; ---Testcase 97: +--Testcase 116: SELECT t1.c1, t2.c1 FROM (SELECT (fields->>'C 1')::int c1, (fields->>'c2')::int c2, tags->>'c3' c3, fields->>'c4' c4, fields->>'c5' c5, fields->>'c6' c6, fields->>'c7' c7, fields->>'c8' c8 FROM ft1 t1) t1 JOIN (SELECT (fields->>'C 1')::int c1, (fields->>'c2')::int c2, tags->>'c3' c3, fields->>'c4' c4, fields->>'c5' c5, fields->>'c6' c6, fields->>'c7' c7, fields->>'c8' c8 FROM ft2 t2) t2 ON ((t1.c1)::int = (t2.c1)::int) ORDER BY t1.c3, (t1.c1)::int OFFSET 100 LIMIT 10; -- join three tables ---Testcase 98: +--Testcase 117: EXPLAIN (VERBOSE, COSTS OFF) SELECT t1.c1, t2.c2, t3.c3 FROM (SELECT (fields->>'C 1')::int c1, (fields->>'c2')::int c2, tags->>'c3' c3, fields->>'c4' c4, fields->>'c5' c5, fields->>'c6' c6, fields->>'c7' c7, fields->>'c8' c8 FROM ft1 t1) t1 JOIN (SELECT (fields->>'C 1')::int c1, (fields->>'c2')::int c2, tags->>'c3' c3, fields->>'c4' c4, fields->>'c5' c5, fields->>'c6' c6, fields->>'c7' c7, fields->>'c8' c8 FROM ft2 t2) t2 ON ((t1.c1)::int = (t2.c1)::int) JOIN (SELECT (fields->>'c1')::int c1, (fields->>'c2')::int c2, tags->>'c3' c3 FROM ft4 t3) t3 ON ((t3.c1)::int = (t1.c1)::int) ORDER BY t1.c3, (t1.c1)::int OFFSET 10 LIMIT 10; ---Testcase 99: +--Testcase 118: SELECT t1.c1, t2.c2, t3.c3 FROM (SELECT (fields->>'C 1')::int c1, (fields->>'c2')::int c2, tags->>'c3' c3, fields->>'c4' c4, fields->>'c5' c5, fields->>'c6' c6, fields->>'c7' c7, fields->>'c8' c8 FROM ft1 t1) t1 JOIN (SELECT (fields->>'C 1')::int c1, (fields->>'c2')::int c2, tags->>'c3' c3, fields->>'c4' c4, fields->>'c5' c5, fields->>'c6' c6, fields->>'c7' c7, fields->>'c8' c8 FROM ft2 t2) t2 ON ((t1.c1)::int = (t2.c1)::int) JOIN (SELECT (fields->>'c1')::int c1, (fields->>'c2')::int c2, tags->>'c3' c3 FROM ft4 t3) t3 ON ((t3.c1)::int = (t1.c1)::int) ORDER BY t1.c3, (t1.c1)::int OFFSET 10 LIMIT 10; -- left outer join ---Testcase 100: +--Testcase 119: EXPLAIN (VERBOSE, COSTS OFF) SELECT t1.c1, t2.c1 FROM (SELECT (fields->>'c1')::int c1, (fields->>'c2')::int c2, tags->>'c3' c3 FROM ft4 t1) t1 LEFT JOIN (SELECT (fields->>'c1')::int c1, (fields->>'c2')::int c2, tags->>'c3' c3 FROM ft5 t2) t2 ON ((t1.c1)::int = (t2.c1)::int) ORDER BY (t1.c1)::int, (t2.c1)::int OFFSET 10 LIMIT 10; ---Testcase 101: +--Testcase 120: SELECT t1.c1, t2.c1 FROM (SELECT (fields->>'c1')::int c1, (fields->>'c2')::int c2, tags->>'c3' c3 FROM ft4 t1) t1 LEFT JOIN (SELECT (fields->>'c1')::int c1, (fields->>'c2')::int c2, tags->>'c3' c3 FROM ft5 t2) t2 ON ((t1.c1)::int = (t2.c1)::int) ORDER BY (t1.c1)::int, (t2.c1)::int OFFSET 10 LIMIT 10; -- left outer join three tables ---Testcase 102: +--Testcase 121: EXPLAIN (VERBOSE, COSTS OFF) SELECT t1.c1, t2.c2, t3.c3 FROM (SELECT (fields->>'C 1')::int c1, (fields->>'c2')::int c2, tags->>'c3' c3, fields->>'c4' c4, fields->>'c5' c5, fields->>'c6' c6, fields->>'c7' c7, fields->>'c8' c8 FROM ft2 t1) t1 LEFT JOIN (SELECT (fields->>'C 1')::int c1, (fields->>'c2')::int c2, tags->>'c3' c3, fields->>'c4' c4, fields->>'c5' c5, fields->>'c6' c6, fields->>'c7' c7, fields->>'c8' c8 FROM ft2 t2) t2 ON ((t1.c1)::int = (t2.c1)::int) LEFT JOIN (SELECT (fields->>'c1')::int c1, (fields->>'c2')::int c2, tags->>'c3' c3 FROM ft4 t3) t3 ON ((t2.c1)::int = (t3.c1)::int) OFFSET 10 LIMIT 10; ---Testcase 103: +--Testcase 122: SELECT t1.c1, t2.c2, t3.c3 FROM (SELECT (fields->>'C 1')::int c1, (fields->>'c2')::int c2, tags->>'c3' c3, fields->>'c4' c4, fields->>'c5' c5, fields->>'c6' c6, fields->>'c7' c7, fields->>'c8' c8 FROM ft2 t1) t1 LEFT JOIN (SELECT (fields->>'C 1')::int c1, (fields->>'c2')::int c2, tags->>'c3' c3, fields->>'c4' c4, fields->>'c5' c5, fields->>'c6' c6, fields->>'c7' c7, fields->>'c8' c8 FROM ft2 t2) t2 ON ((t1.c1)::int = (t2.c1)::int) LEFT JOIN (SELECT (fields->>'c1')::int c1, (fields->>'c2')::int c2, tags->>'c3' c3 FROM ft4 t3) t3 ON ((t2.c1)::int = (t3.c1)::int) ORDER BY (t1.c1)::int OFFSET 10 LIMIT 10; -- left outer join + placement of clauses. -- clauses within the nullable side are not pulled up, but top level clause on -- non-nullable side is pushed into non-nullable side ---Testcase 104: +--Testcase 123: EXPLAIN (VERBOSE, COSTS OFF) SELECT t1.c1, t1.c2, (t2.fields->>'c1')::int c1, (t2.fields->>'c2')::int c2 FROM (SELECT (fields->>'c1')::int c1, (fields->>'c2')::int c2, tags->>'c3' c3 FROM ft4 t1) t1 LEFT JOIN (SELECT * FROM ft5 t2 WHERE (fields->>'c1')::int < 10) t2 ON ((t1.c1)::int = (t2.fields->>'c1')::int) WHERE (t1.c1)::int < 10; ---Testcase 105: +--Testcase 124: SELECT t1.c1, t1.c2, (t2.fields->>'c1')::int c1, (t2.fields->>'c2')::int c2 FROM (SELECT (fields->>'c1')::int c1, (fields->>'c2')::int c2, tags->>'c3' c3 FROM ft4 t1) t1 LEFT JOIN (SELECT * FROM ft5 t2 WHERE (fields->>'c1')::int < 10) t2 ON ((t1.c1)::int = (t2.fields->>'c1')::int) WHERE (t1.c1)::int < 10; -- clauses within the nullable side are not pulled up, but the top level clause -- on nullable side is not pushed down into nullable side ---Testcase 106: +--Testcase 125: EXPLAIN (VERBOSE, COSTS OFF) SELECT t1.c1, t1.c2, (t2.fields->>'c1')::int c1, (t2.fields->>'c2')::int c2 FROM (SELECT (fields->>'c1')::int c1, (fields->>'c2')::int c2, tags->>'c3' c3 FROM ft4 t1) t1 LEFT JOIN (SELECT * FROM ft5 t2 WHERE (fields->>'c1')::int < 10) t2 ON ((t1.c1)::int = (t2.fields->>'c1')::int) WHERE ((t2.fields->>'c1')::int < 10 OR (t2.fields->>'c1')::int IS NULL) AND (t1.c1)::int < 10; ---Testcase 107: +--Testcase 126: SELECT t1.c1, t1.c2, (t2.fields->>'c1')::int c1, (t2.fields->>'c2')::int c2 FROM (SELECT (fields->>'c1')::int c1, (fields->>'c2')::int c2, tags->>'c3' c3 FROM ft4 t1) t1 LEFT JOIN (SELECT * FROM ft5 t2 WHERE (fields->>'c1')::int < 10) t2 ON ((t1.c1)::int = (t2.fields->>'c1')::int) WHERE ((t2.fields->>'c1')::int < 10 OR (t2.fields->>'c1')::int IS NULL) AND (t1.c1)::int < 10; -- right outer join ---Testcase 108: +--Testcase 127: EXPLAIN (VERBOSE, COSTS OFF) SELECT t1.c1, t2.c1 FROM (SELECT (fields->>'c1')::int c1, (fields->>'c2')::int c2, tags->>'c3' c3 FROM ft5 t1) t1 RIGHT JOIN (SELECT (fields->>'c1')::int c1, (fields->>'c2')::int c2, tags->>'c3' c3 FROM ft4 t2) t2 ON ((t1.c1)::int = (t2.c1)::int) ORDER BY (t2.c1)::int, (t1.c1)::int OFFSET 10 LIMIT 10; ---Testcase 109: +--Testcase 128: SELECT t1.c1, t2.c1 FROM (SELECT (fields->>'c1')::int c1, (fields->>'c2')::int c2, tags->>'c3' c3 FROM ft5 t1) t1 RIGHT JOIN (SELECT (fields->>'c1')::int c1, (fields->>'c2')::int c2, tags->>'c3' c3 FROM ft4 t2) t2 ON ((t1.c1)::int = (t2.c1)::int) ORDER BY (t2.c1)::int, (t1.c1)::int OFFSET 10 LIMIT 10; -- right outer join three tables ---Testcase 110: +--Testcase 129: EXPLAIN (VERBOSE, COSTS OFF) SELECT t1.c1, t2.c2, t3.c3 FROM (SELECT (fields->>'C 1')::int c1, (fields->>'c2')::int c2, tags->>'c3' c3, fields->>'c4' c4, fields->>'c5' c5, fields->>'c6' c6, fields->>'c7' c7, fields->>'c8' c8 FROM ft2 t1) t1 RIGHT JOIN (SELECT (fields->>'C 1')::int c1, (fields->>'c2')::int c2, tags->>'c3' c3, fields->>'c4' c4, fields->>'c5' c5, fields->>'c6' c6, fields->>'c7' c7, fields->>'c8' c8 FROM ft2 t2) t2 ON ((t1.c1)::int = (t2.c1)::int) RIGHT JOIN (SELECT (fields->>'c1')::int c1, (fields->>'c2')::int c2, tags->>'c3' c3 FROM ft4 t3) t3 ON ((t2.c1)::int = (t3.c1)::int) OFFSET 10 LIMIT 10; ---Testcase 111: +--Testcase 130: SELECT t1.c1, t2.c2, t3.c3 FROM (SELECT (fields->>'C 1')::int c1, (fields->>'c2')::int c2, tags->>'c3' c3, fields->>'c4' c4, fields->>'c5' c5, fields->>'c6' c6, fields->>'c7' c7, fields->>'c8' c8 FROM ft2 t1) t1 RIGHT JOIN (SELECT (fields->>'C 1')::int c1, (fields->>'c2')::int c2, tags->>'c3' c3, fields->>'c4' c4, fields->>'c5' c5, fields->>'c6' c6, fields->>'c7' c7, fields->>'c8' c8 FROM ft2 t2) t2 ON ((t1.c1)::int = (t2.c1)::int) RIGHT JOIN (SELECT (fields->>'c1')::int c1, (fields->>'c2')::int c2, tags->>'c3' c3 FROM ft4 t3) t3 ON ((t2.c1)::int = (t3.c1)::int) OFFSET 10 LIMIT 10; -- full outer join ---Testcase 112: +--Testcase 131: EXPLAIN (VERBOSE, COSTS OFF) SELECT t1.c1, t2.c1 FROM (SELECT (fields->>'c1')::int c1, (fields->>'c2')::int c2, tags->>'c3' c3 FROM ft4 t1) t1 FULL JOIN (SELECT (fields->>'c1')::int c1, (fields->>'c2')::int c2, tags->>'c3' c3 FROM ft5 t2) t2 ON ((t1.c1)::int = (t2.c1)::int) ORDER BY (t1.c1)::int, (t2.c1)::int OFFSET 45 LIMIT 10; ---Testcase 113: +--Testcase 132: SELECT t1.c1, t2.c1 FROM (SELECT (fields->>'c1')::int c1, (fields->>'c2')::int c2, tags->>'c3' c3 FROM ft4 t1) t1 FULL JOIN (SELECT (fields->>'c1')::int c1, (fields->>'c2')::int c2, tags->>'c3' c3 FROM ft5 t2) t2 ON ((t1.c1)::int = (t2.c1)::int) ORDER BY (t1.c1)::int, (t2.c1)::int OFFSET 45 LIMIT 10; -- full outer join with restrictions on the joining relations -- a. the joining relations are both base relations ---Testcase 114: +--Testcase 133: EXPLAIN (VERBOSE, COSTS OFF) SELECT t1.c1, t2.c1 FROM (SELECT (fields->>'c1')::int c1 FROM ft4 t1 WHERE (fields->>'c1')::int between 50 and 60) t1 FULL JOIN (SELECT (fields->>'c1')::int c1 FROM ft5 t2 WHERE (fields->>'c1')::int between 50 and 60) t2 ON ((t1.c1)::int = (t2.c1)::int) ORDER BY (t1.c1)::int, (t2.c1)::int; ---Testcase 115: +--Testcase 134: SELECT t1.c1, t2.c1 FROM (SELECT (fields->>'c1')::int c1 FROM ft4 t1 WHERE (fields->>'c1')::int between 50 and 60) t1 FULL JOIN (SELECT (fields->>'c1')::int c1 FROM ft5 t2 WHERE (fields->>'c1')::int between 50 and 60) t2 ON ((t1.c1)::int = (t2.c1)::int) ORDER BY (t1.c1)::int, (t2.c1)::int; ---Testcase 116: +--Testcase 135: EXPLAIN (VERBOSE, COSTS OFF) SELECT 1 FROM (SELECT (fields->>'c1')::int c1 FROM ft4 t1 WHERE (fields->>'c1')::int between 50 and 60) t1 FULL JOIN (SELECT (fields->>'c1')::int c1 FROM ft5 t2 WHERE (fields->>'c1')::int between 50 and 60) t2 ON (TRUE) OFFSET 10 LIMIT 10; ---Testcase 117: +--Testcase 136: SELECT 1 FROM (SELECT (fields->>'c1')::int c1 FROM ft4 t1 WHERE (fields->>'c1')::int between 50 and 60) t1 FULL JOIN (SELECT (fields->>'c1')::int c1 FROM ft5 t2 WHERE (fields->>'c1')::int between 50 and 60) t2 ON (TRUE) OFFSET 10 LIMIT 10; -- b. one of the joining relations is a base relation and the other is a join -- relation ---Testcase 118: +--Testcase 137: EXPLAIN (VERBOSE, COSTS OFF) -SELECT t1.c1, ss.a, ss.b FROM (SELECT (fields->>'c1')::int c1 FROM ft4 t1 WHERE (fields->>'c1')::int between 50 and 60) t1 FULL JOIN (SELECT (t2.c1)::int, (t3.c1)::int FROM (SELECT (fields->>'c1')::int c1, (fields->>'c2')::int c2, tags->>'c3' c3 FROM ft4 t2) t2 LEFT JOIN (SELECT fields->>'c1' c1, fields->>'c2' c2, tags->>'c3' c3 FROM ft5) t3 ON ((t2.c1)::int = (t3.c1)::int) WHERE ((t2.c1)::int between 50 and 60)) ss(a, b) ON ((t1.c1)::int = ss.a) ORDER BY (t1.c1)::int, ss.a, ss.b; ---Testcase 119: -SELECT t1.c1, ss.a, ss.b FROM (SELECT (fields->>'c1')::int c1 FROM ft4 t1 WHERE (fields->>'c1')::int between 50 and 60) t1 FULL JOIN (SELECT (t2.c1)::int, (t3.c1)::int FROM (SELECT (fields->>'c1')::int c1, (fields->>'c2')::int c2, tags->>'c3' c3 FROM ft4 t2) t2 LEFT JOIN (SELECT fields->>'c1' c1, fields->>'c2' c2, tags->>'c3' c3 FROM ft5) t3 ON ((t2.c1)::int = (t3.c1)::int) WHERE ((t2.c1)::int between 50 and 60)) ss(a, b) ON ((t1.c1)::int = ss.a) ORDER BY (t1.c1)::int, ss.a, ss.b; +SELECT t1.c1, ss.a, ss.b FROM (SELECT (fields->>'c1')::int c1 FROM ft4 t1 WHERE (fields->>'c1')::int between 50 and 60) t1 FULL JOIN (SELECT (t2.c1)::int, (t3.c1)::int FROM (SELECT (fields->>'c1')::int c1, (fields->>'c2')::int c2, tags->>'c3' c3 FROM ft4 t2) t2 LEFT JOIN (SELECT (fields->>'c1')::int c1, fields->>'c2' c2, tags->>'c3' c3 FROM ft5 t3) t3 ON ((t2.c1)::int = (t3.c1)::int) WHERE ((t2.c1)::int between 50 and 60)) ss(a, b) ON ((t1.c1)::int = ss.a) ORDER BY (t1.c1)::int, ss.a, ss.b; +--Testcase 138: +SELECT t1.c1, ss.a, ss.b FROM (SELECT (fields->>'c1')::int c1 FROM ft4 t1 WHERE (fields->>'c1')::int between 50 and 60) t1 FULL JOIN (SELECT (t2.c1)::int, (t3.c1)::int FROM (SELECT (fields->>'c1')::int c1, (fields->>'c2')::int c2, tags->>'c3' c3 FROM ft4 t2) t2 LEFT JOIN (SELECT (fields->>'c1')::int c1, fields->>'c2' c2, tags->>'c3' c3 FROM ft5 t3) t3 ON ((t2.c1)::int = (t3.c1)::int) WHERE ((t2.c1)::int between 50 and 60)) ss(a, b) ON ((t1.c1)::int = ss.a) ORDER BY (t1.c1)::int, ss.a, ss.b; -- c. test deparsing the remote query as nested subqueries ---Testcase 120: +--Testcase 139: EXPLAIN (VERBOSE, COSTS OFF) SELECT t1.c1, ss.a, ss.b FROM (SELECT (fields->>'c1')::int c1 FROM ft4 t1 WHERE (fields->>'c1')::int between 50 and 60) t1 FULL JOIN (SELECT (t2.c1)::int, (t3.c1)::int FROM (SELECT (fields->>'c1')::int c1 FROM ft4 t2 WHERE (fields->>'c1')::int between 50 and 60) t2 FULL JOIN (SELECT (fields->>'c1')::int c1 FROM ft5 t3 WHERE (fields->>'c1')::int between 50 and 60) t3 ON ((t2.c1)::int = (t3.c1)::int) WHERE (t2.c1)::int IS NULL OR (t2.c1)::int IS NOT NULL) ss(a, b) ON ((t1.c1)::int = ss.a) ORDER BY (t1.c1)::int, ss.a, ss.b; ---Testcase 121: +--Testcase 140: SELECT t1.c1, ss.a, ss.b FROM (SELECT (fields->>'c1')::int c1 FROM ft4 t1 WHERE (fields->>'c1')::int between 50 and 60) t1 FULL JOIN (SELECT (t2.c1)::int, (t3.c1)::int FROM (SELECT (fields->>'c1')::int c1 FROM ft4 t2 WHERE (fields->>'c1')::int between 50 and 60) t2 FULL JOIN (SELECT (fields->>'c1')::int c1 FROM ft5 t3 WHERE (fields->>'c1')::int between 50 and 60) t3 ON ((t2.c1)::int = (t3.c1)::int) WHERE (t2.c1)::int IS NULL OR (t2.c1)::int IS NOT NULL) ss(a, b) ON ((t1.c1)::int = ss.a) ORDER BY (t1.c1)::int, ss.a, ss.b; -- d. test deparsing rowmarked relations as subqueries ---Testcase 122: +--Testcase 141: EXPLAIN (VERBOSE, COSTS OFF) SELECT t1.c1, ss.a, ss.b FROM (SELECT (fields->>'c1')::int c1 FROM "S 1"."T 3" t1 WHERE (fields->>'c1')::int = 50) t1 INNER JOIN (SELECT (t2.c1)::int, (t3.c1)::int FROM (SELECT (fields->>'c1')::int c1 FROM ft4 t2 WHERE (fields->>'c1')::int between 50 and 60) t2 FULL JOIN (SELECT (fields->>'c1')::int c1 FROM ft5 t3 WHERE (fields->>'c1')::int between 50 and 60) t3 ON ((t2.c1)::int = (t3.c1)::int) WHERE (t2.c1)::int IS NULL OR (t2.c1)::int IS NOT NULL) ss(a, b) ON (TRUE) ORDER BY (t1.c1)::int, ss.a, ss.b FOR UPDATE OF t1; ---Testcase 123: +--Testcase 142: SELECT t1.c1, ss.a, ss.b FROM (SELECT (fields->>'c1')::int c1 FROM "S 1"."T 3" t1 WHERE (fields->>'c1')::int = 50) t1 INNER JOIN (SELECT (t2.c1)::int, (t3.c1)::int FROM (SELECT (fields->>'c1')::int c1 FROM ft4 t2 WHERE (fields->>'c1')::int between 50 and 60) t2 FULL JOIN (SELECT (fields->>'c1')::int c1 FROM ft5 t3 WHERE (fields->>'c1')::int between 50 and 60) t3 ON ((t2.c1)::int = (t3.c1)::int) WHERE (t2.c1)::int IS NULL OR (t2.c1)::int IS NOT NULL) ss(a, b) ON (TRUE) ORDER BY (t1.c1)::int, ss.a, ss.b FOR UPDATE OF t1; -- full outer join + inner join ---Testcase 124: +--Testcase 143: EXPLAIN (VERBOSE, COSTS OFF) SELECT t1.c1, t2.c1, t3.c1 FROM (SELECT (fields->>'c1')::int c1, (fields->>'c2')::int c2, tags->>'c3' c3 FROM ft4 t1) t1 INNER JOIN (SELECT (fields->>'c1')::int c1, (fields->>'c2')::int c2, tags->>'c3' c3 FROM ft5 t2) t2 ON ((t1.c1)::int = (t2.c1)::int + 1 and (t1.c1)::int between 50 and 60) FULL JOIN (SELECT (fields->>'c1')::int c1, (fields->>'c2')::int c2, tags->>'c3' c3 FROM ft4 t3) t3 ON ((t2.c1)::int = (t3.c1)::int) ORDER BY (t1.c1)::int, (t2.c1)::int, (t3.c1)::int LIMIT 10; ---Testcase 125: +--Testcase 144: SELECT t1.c1, t2.c1, t3.c1 FROM (SELECT (fields->>'c1')::int c1, (fields->>'c2')::int c2, tags->>'c3' c3 FROM ft4 t1) t1 INNER JOIN (SELECT (fields->>'c1')::int c1, (fields->>'c2')::int c2, tags->>'c3' c3 FROM ft5 t2) t2 ON ((t1.c1)::int = (t2.c1)::int + 1 and (t1.c1)::int between 50 and 60) FULL JOIN (SELECT (fields->>'c1')::int c1, (fields->>'c2')::int c2, tags->>'c3' c3 FROM ft4 t3) t3 ON ((t2.c1)::int = (t3.c1)::int) ORDER BY (t1.c1)::int, (t2.c1)::int, (t3.c1)::int LIMIT 10; -- full outer join three tables ---Testcase 126: +--Testcase 145: EXPLAIN (VERBOSE, COSTS OFF) SELECT t1.c1, t2.c2, t3.c3 FROM (SELECT (fields->>'C 1')::int c1, (fields->>'c2')::int c2, tags->>'c3' c3, fields->>'c4' c4, fields->>'c5' c5, fields->>'c6' c6, fields->>'c7' c7, fields->>'c8' c8 FROM ft2 t1) t1 FULL JOIN (SELECT (fields->>'C 1')::int c1, (fields->>'c2')::int c2, tags->>'c3' c3, fields->>'c4' c4, fields->>'c5' c5, fields->>'c6' c6, fields->>'c7' c7, fields->>'c8' c8 FROM ft2 t2) t2 ON ((t1.c1)::int = (t2.c1)::int) FULL JOIN (SELECT (fields->>'c1')::int c1, (fields->>'c2')::int c2, tags->>'c3' c3 FROM ft4 t3) t3 ON ((t2.c1)::int = (t3.c1)::int) OFFSET 10 LIMIT 10; ---Testcase 127: +--Testcase 146: SELECT t1.c1, t2.c2, t3.c3 FROM (SELECT (fields->>'C 1')::int c1, (fields->>'c2')::int c2, tags->>'c3' c3, fields->>'c4' c4, fields->>'c5' c5, fields->>'c6' c6, fields->>'c7' c7, fields->>'c8' c8 FROM ft2 t1) t1 FULL JOIN (SELECT (fields->>'C 1')::int c1, (fields->>'c2')::int c2, tags->>'c3' c3, fields->>'c4' c4, fields->>'c5' c5, fields->>'c6' c6, fields->>'c7' c7, fields->>'c8' c8 FROM ft2 t2) t2 ON ((t1.c1)::int = (t2.c1)::int) FULL JOIN (SELECT (fields->>'c1')::int c1, (fields->>'c2')::int c2, tags->>'c3' c3 FROM ft4 t3) t3 ON ((t2.c1)::int = (t3.c1)::int) ORDER BY (t1.c1)::int OFFSET 10 LIMIT 10; -- full outer join + right outer join ---Testcase 128: +--Testcase 147: EXPLAIN (VERBOSE, COSTS OFF) SELECT t1.c1, t2.c2, t3.c3 FROM (SELECT (fields->>'C 1')::int c1, (fields->>'c2')::int c2, tags->>'c3' c3, fields->>'c4' c4, fields->>'c5' c5, fields->>'c6' c6, fields->>'c7' c7, fields->>'c8' c8 FROM ft2 t1) t1 FULL JOIN (SELECT (fields->>'C 1')::int c1, (fields->>'c2')::int c2, tags->>'c3' c3, fields->>'c4' c4, fields->>'c5' c5, fields->>'c6' c6, fields->>'c7' c7, fields->>'c8' c8 FROM ft2 t2) t2 ON ((t1.c1)::int = (t2.c1)::int) RIGHT JOIN (SELECT (fields->>'c1')::int c1, (fields->>'c2')::int c2, tags->>'c3' c3 FROM ft4 t3) t3 ON ((t2.c1)::int = (t3.c1)::int) OFFSET 10 LIMIT 10; ---Testcase 129: +--Testcase 148: SELECT t1.c1, t2.c2, t3.c3 FROM (SELECT (fields->>'C 1')::int c1, (fields->>'c2')::int c2, tags->>'c3' c3, fields->>'c4' c4, fields->>'c5' c5, fields->>'c6' c6, fields->>'c7' c7, fields->>'c8' c8 FROM ft2 t1) t1 FULL JOIN (SELECT (fields->>'C 1')::int c1, (fields->>'c2')::int c2, tags->>'c3' c3, fields->>'c4' c4, fields->>'c5' c5, fields->>'c6' c6, fields->>'c7' c7, fields->>'c8' c8 FROM ft2 t2) t2 ON ((t1.c1)::int = (t2.c1)::int) RIGHT JOIN (SELECT (fields->>'c1')::int c1, (fields->>'c2')::int c2, tags->>'c3' c3 FROM ft4 t3) t3 ON ((t2.c1)::int = (t3.c1)::int) OFFSET 10 LIMIT 10; -- right outer join + full outer join ---Testcase 130: +--Testcase 149: EXPLAIN (VERBOSE, COSTS OFF) SELECT t1.c1, t2.c2, t3.c3 FROM (SELECT (fields->>'C 1')::int c1, (fields->>'c2')::int c2, tags->>'c3' c3, fields->>'c4' c4, fields->>'c5' c5, fields->>'c6' c6, fields->>'c7' c7, fields->>'c8' c8 FROM ft2 t1) t1 RIGHT JOIN (SELECT (fields->>'C 1')::int c1, (fields->>'c2')::int c2, tags->>'c3' c3, fields->>'c4' c4, fields->>'c5' c5, fields->>'c6' c6, fields->>'c7' c7, fields->>'c8' c8 FROM ft2 t2) t2 ON ((t1.c1)::int = (t2.c1)::int) FULL JOIN (SELECT (fields->>'c1')::int c1, (fields->>'c2')::int c2, tags->>'c3' c3 FROM ft4 t3) t3 ON ((t2.c1)::int = (t3.c1)::int) OFFSET 10 LIMIT 10; ---Testcase 131: +--Testcase 150: SELECT t1.c1, t2.c2, t3.c3 FROM (SELECT (fields->>'C 1')::int c1, (fields->>'c2')::int c2, tags->>'c3' c3, fields->>'c4' c4, fields->>'c5' c5, fields->>'c6' c6, fields->>'c7' c7, fields->>'c8' c8 FROM ft2 t1) t1 RIGHT JOIN (SELECT (fields->>'C 1')::int c1, (fields->>'c2')::int c2, tags->>'c3' c3, fields->>'c4' c4, fields->>'c5' c5, fields->>'c6' c6, fields->>'c7' c7, fields->>'c8' c8 FROM ft2 t2) t2 ON ((t1.c1)::int = (t2.c1)::int) FULL JOIN (SELECT (fields->>'c1')::int c1, (fields->>'c2')::int c2, tags->>'c3' c3 FROM ft4 t3) t3 ON ((t2.c1)::int = (t3.c1)::int) ORDER BY (t1.c1)::int OFFSET 10 LIMIT 10; -- full outer join + left outer join ---Testcase 132: +--Testcase 151: EXPLAIN (VERBOSE, COSTS OFF) SELECT t1.c1, t2.c2, t3.c3 FROM (SELECT (fields->>'C 1')::int c1, (fields->>'c2')::int c2, tags->>'c3' c3, fields->>'c4' c4, fields->>'c5' c5, fields->>'c6' c6, fields->>'c7' c7, fields->>'c8' c8 FROM ft2 t1) t1 FULL JOIN (SELECT (fields->>'C 1')::int c1, (fields->>'c2')::int c2, tags->>'c3' c3, fields->>'c4' c4, fields->>'c5' c5, fields->>'c6' c6, fields->>'c7' c7, fields->>'c8' c8 FROM ft2 t2) t2 ON ((t1.c1)::int = (t2.c1)::int) LEFT JOIN (SELECT (fields->>'c1')::int c1, (fields->>'c2')::int c2, tags->>'c3' c3 FROM ft4 t3) t3 ON ((t2.c1)::int = (t3.c1)::int) OFFSET 10 LIMIT 10; ---Testcase 133: +--Testcase 152: SELECT t1.c1, t2.c2, t3.c3 FROM (SELECT (fields->>'C 1')::int c1, (fields->>'c2')::int c2, tags->>'c3' c3, fields->>'c4' c4, fields->>'c5' c5, fields->>'c6' c6, fields->>'c7' c7, fields->>'c8' c8 FROM ft2 t1) t1 FULL JOIN (SELECT (fields->>'C 1')::int c1, (fields->>'c2')::int c2, tags->>'c3' c3, fields->>'c4' c4, fields->>'c5' c5, fields->>'c6' c6, fields->>'c7' c7, fields->>'c8' c8 FROM ft2 t2) t2 ON ((t1.c1)::int = (t2.c1)::int) LEFT JOIN (SELECT (fields->>'c1')::int c1, (fields->>'c2')::int c2, tags->>'c3' c3 FROM ft4 t3) t3 ON ((t2.c1)::int = (t3.c1)::int) ORDER BY (t1.c1)::int OFFSET 10 LIMIT 10; -- left outer join + full outer join ---Testcase 134: +--Testcase 153: EXPLAIN (VERBOSE, COSTS OFF) SELECT t1.c1, t2.c2, t3.c3 FROM (SELECT (fields->>'C 1')::int c1, (fields->>'c2')::int c2, tags->>'c3' c3, fields->>'c4' c4, fields->>'c5' c5, fields->>'c6' c6, fields->>'c7' c7, fields->>'c8' c8 FROM ft2 t1) t1 LEFT JOIN (SELECT (fields->>'C 1')::int c1, (fields->>'c2')::int c2, tags->>'c3' c3, fields->>'c4' c4, fields->>'c5' c5, fields->>'c6' c6, fields->>'c7' c7, fields->>'c8' c8 FROM ft2 t2) t2 ON ((t1.c1)::int = (t2.c1)::int) FULL JOIN (SELECT (fields->>'c1')::int c1, (fields->>'c2')::int c2, tags->>'c3' c3 FROM ft4 t3) t3 ON ((t2.c1)::int = (t3.c1)::int) OFFSET 10 LIMIT 10; ---Testcase 135: +--Testcase 154: SELECT t1.c1, t2.c2, t3.c3 FROM (SELECT (fields->>'C 1')::int c1, (fields->>'c2')::int c2, tags->>'c3' c3, fields->>'c4' c4, fields->>'c5' c5, fields->>'c6' c6, fields->>'c7' c7, fields->>'c8' c8 FROM ft2 t1) t1 LEFT JOIN (SELECT (fields->>'C 1')::int c1, (fields->>'c2')::int c2, tags->>'c3' c3, fields->>'c4' c4, fields->>'c5' c5, fields->>'c6' c6, fields->>'c7' c7, fields->>'c8' c8 FROM ft2 t2) t2 ON ((t1.c1)::int = (t2.c1)::int) FULL JOIN (SELECT (fields->>'c1')::int c1, (fields->>'c2')::int c2, tags->>'c3' c3 FROM ft4 t3) t3 ON ((t2.c1)::int = (t3.c1)::int) ORDER BY (t1.c1)::int OFFSET 10 LIMIT 10; +--Testcase 155: +SET enable_memoize TO off; -- right outer join + left outer join ---Testcase 136: +--Testcase 156: EXPLAIN (VERBOSE, COSTS OFF) SELECT t1.c1, t2.c2, t3.c3 FROM (SELECT (fields->>'C 1')::int c1, (fields->>'c2')::int c2, tags->>'c3' c3, fields->>'c4' c4, fields->>'c5' c5, fields->>'c6' c6, fields->>'c7' c7, fields->>'c8' c8 FROM ft2 t1) t1 RIGHT JOIN (SELECT (fields->>'C 1')::int c1, (fields->>'c2')::int c2, tags->>'c3' c3, fields->>'c4' c4, fields->>'c5' c5, fields->>'c6' c6, fields->>'c7' c7, fields->>'c8' c8 FROM ft2 t2) t2 ON ((t1.c1)::int = (t2.c1)::int) LEFT JOIN (SELECT (fields->>'c1')::int c1, (fields->>'c2')::int c2, tags->>'c3' c3 FROM ft4 t3) t3 ON ((t2.c1)::int = (t3.c1)::int) OFFSET 10 LIMIT 10; ---Testcase 137: +--Testcase 157: SELECT t1.c1, t2.c2, t3.c3 FROM (SELECT (fields->>'C 1')::int c1, (fields->>'c2')::int c2, tags->>'c3' c3, fields->>'c4' c4, fields->>'c5' c5, fields->>'c6' c6, fields->>'c7' c7, fields->>'c8' c8 FROM ft2 t1) t1 RIGHT JOIN (SELECT (fields->>'C 1')::int c1, (fields->>'c2')::int c2, tags->>'c3' c3, fields->>'c4' c4, fields->>'c5' c5, fields->>'c6' c6, fields->>'c7' c7, fields->>'c8' c8 FROM ft2 t2) t2 ON ((t1.c1)::int = (t2.c1)::int) LEFT JOIN (SELECT (fields->>'c1')::int c1, (fields->>'c2')::int c2, tags->>'c3' c3 FROM ft4 t3) t3 ON ((t2.c1)::int = (t3.c1)::int) ORDER BY (t1.c1)::int OFFSET 10 LIMIT 10; +--Testcase 158: +RESET enable_memoize; -- left outer join + right outer join ---Testcase 138: +--Testcase 159: EXPLAIN (VERBOSE, COSTS OFF) SELECT t1.c1, t2.c2, t3.c3 FROM (SELECT (fields->>'C 1')::int c1, (fields->>'c2')::int c2, tags->>'c3' c3, fields->>'c4' c4, fields->>'c5' c5, fields->>'c6' c6, fields->>'c7' c7, fields->>'c8' c8 FROM ft2 t1) t1 LEFT JOIN (SELECT (fields->>'C 1')::int c1, (fields->>'c2')::int c2, tags->>'c3' c3, fields->>'c4' c4, fields->>'c5' c5, fields->>'c6' c6, fields->>'c7' c7, fields->>'c8' c8 FROM ft2 t2) t2 ON ((t1.c1)::int = (t2.c1)::int) RIGHT JOIN (SELECT (fields->>'c1')::int c1, (fields->>'c2')::int c2, tags->>'c3' c3 FROM ft4 t3) t3 ON ((t2.c1)::int = (t3.c1)::int) OFFSET 10 LIMIT 10; ---Testcase 139: +--Testcase 160: SELECT t1.c1, t2.c2, t3.c3 FROM (SELECT (fields->>'C 1')::int c1, (fields->>'c2')::int c2, tags->>'c3' c3, fields->>'c4' c4, fields->>'c5' c5, fields->>'c6' c6, fields->>'c7' c7, fields->>'c8' c8 FROM ft2 t1) t1 LEFT JOIN (SELECT (fields->>'C 1')::int c1, (fields->>'c2')::int c2, tags->>'c3' c3, fields->>'c4' c4, fields->>'c5' c5, fields->>'c6' c6, fields->>'c7' c7, fields->>'c8' c8 FROM ft2 t2) t2 ON ((t1.c1)::int = (t2.c1)::int) RIGHT JOIN (SELECT (fields->>'c1')::int c1, (fields->>'c2')::int c2, tags->>'c3' c3 FROM ft4 t3) t3 ON ((t2.c1)::int = (t3.c1)::int) ORDER BY (t1.c1)::int OFFSET 10 LIMIT 10; -- full outer join + WHERE clause, only matched rows ---Testcase 140: +--Testcase 161: EXPLAIN (VERBOSE, COSTS OFF) SELECT t1.c1, t2.c1 FROM (SELECT (fields->>'c1')::int c1, (fields->>'c2')::int c2, tags->>'c3' c3 FROM ft4 t1) t1 FULL JOIN (SELECT (fields->>'c1')::int c1, (fields->>'c2')::int c2, tags->>'c3' c3 FROM ft5 t2) t2 ON ((t1.c1)::int = (t2.c1)::int) WHERE ((t1.c1)::int = (t2.c1)::int OR (t1.c1)::int IS NULL) ORDER BY (t1.c1)::int, (t2.c1)::int OFFSET 10 LIMIT 10; ---Testcase 141: +--Testcase 162: SELECT t1.c1, t2.c1 FROM (SELECT (fields->>'c1')::int c1, (fields->>'c2')::int c2, tags->>'c3' c3 FROM ft4 t1) t1 FULL JOIN (SELECT (fields->>'c1')::int c1, (fields->>'c2')::int c2, tags->>'c3' c3 FROM ft5 t2) t2 ON ((t1.c1)::int = (t2.c1)::int) WHERE ((t1.c1)::int = (t2.c1)::int OR (t1.c1)::int IS NULL) ORDER BY (t1.c1)::int, (t2.c1)::int OFFSET 10 LIMIT 10; -- full outer join + WHERE clause with shippable extensions set ---Testcase 142: +--Testcase 163: EXPLAIN (VERBOSE, COSTS OFF) SELECT t1.c1, t2.c2, t1.c3 FROM (SELECT (fields->>'C 1')::int c1, (fields->>'c2')::int c2, tags->>'c3' c3, fields->>'c4' c4, fields->>'c5' c5, fields->>'c6' c6, fields->>'c7' c7, fields->>'c8' c8 FROM ft1 t1) t1 FULL JOIN (SELECT (fields->>'C 1')::int c1, (fields->>'c2')::int c2, tags->>'c3' c3, fields->>'c4' c4, fields->>'c5' c5, fields->>'c6' c6, fields->>'c7' c7, fields->>'c8' c8 FROM ft2 t2) t2 ON ((t1.c1)::int = (t2.c1)::int) WHERE influxdb_fdw_abs((t1.c1)::int) > 0 OFFSET 10 LIMIT 10; -- skip, influxdb does not have option 'extensions' @@ -636,187 +741,239 @@ SELECT t1.c1, t2.c2, t1.c3 FROM (SELECT (fields->>'C 1')::int c1, (fields->>'c2' -- ALTER SERVER loopback OPTIONS (ADD extensions 'influxdb_fdw'); -- join two tables with FOR UPDATE clause -- tests whole-row reference for row marks ---Testcase 143: +--Testcase 164: EXPLAIN (VERBOSE, COSTS OFF) SELECT t1.c1, t2.c1 FROM (SELECT (fields->>'C 1')::int c1, (fields->>'c2')::int c2, tags->>'c3' c3, fields->>'c4' c4, fields->>'c5' c5, fields->>'c6' c6, fields->>'c7' c7, fields->>'c8' c8 FROM ft1 t1) t1 JOIN (SELECT (fields->>'C 1')::int c1, (fields->>'c2')::int c2, tags->>'c3' c3, fields->>'c4' c4, fields->>'c5' c5, fields->>'c6' c6, fields->>'c7' c7, fields->>'c8' c8 FROM ft2 t2) t2 ON ((t1.c1)::int = (t2.c1)::int) ORDER BY t1.c3, (t1.c1)::int OFFSET 100 LIMIT 10 FOR UPDATE OF t1; ---Testcase 144: +--Testcase 165: SELECT t1.c1, t2.c1 FROM (SELECT (fields->>'C 1')::int c1, (fields->>'c2')::int c2, tags->>'c3' c3, fields->>'c4' c4, fields->>'c5' c5, fields->>'c6' c6, fields->>'c7' c7, fields->>'c8' c8 FROM ft1 t1) t1 JOIN (SELECT (fields->>'C 1')::int c1, (fields->>'c2')::int c2, tags->>'c3' c3, fields->>'c4' c4, fields->>'c5' c5, fields->>'c6' c6, fields->>'c7' c7, fields->>'c8' c8 FROM ft2 t2) t2 ON ((t1.c1)::int = (t2.c1)::int) ORDER BY t1.c3, (t1.c1)::int OFFSET 100 LIMIT 10 FOR UPDATE OF t1; ---Testcase 145: +--Testcase 166: EXPLAIN (VERBOSE, COSTS OFF) SELECT t1.c1, t2.c1 FROM (SELECT (fields->>'C 1')::int c1, (fields->>'c2')::int c2, tags->>'c3' c3, fields->>'c4' c4, fields->>'c5' c5, fields->>'c6' c6, fields->>'c7' c7, fields->>'c8' c8 FROM ft1 t1) t1 JOIN (SELECT (fields->>'C 1')::int c1, (fields->>'c2')::int c2, tags->>'c3' c3, fields->>'c4' c4, fields->>'c5' c5, fields->>'c6' c6, fields->>'c7' c7, fields->>'c8' c8 FROM ft2 t2) t2 ON ((t1.c1)::int = (t2.c1)::int) ORDER BY t1.c3, (t1.c1)::int OFFSET 100 LIMIT 10 FOR UPDATE; ---Testcase 146: +--Testcase 167: SELECT t1.c1, t2.c1 FROM (SELECT (fields->>'C 1')::int c1, (fields->>'c2')::int c2, tags->>'c3' c3, fields->>'c4' c4, fields->>'c5' c5, fields->>'c6' c6, fields->>'c7' c7, fields->>'c8' c8 FROM ft1 t1) t1 JOIN (SELECT (fields->>'C 1')::int c1, (fields->>'c2')::int c2, tags->>'c3' c3, fields->>'c4' c4, fields->>'c5' c5, fields->>'c6' c6, fields->>'c7' c7, fields->>'c8' c8 FROM ft2 t2) t2 ON ((t1.c1)::int = (t2.c1)::int) ORDER BY t1.c3, (t1.c1)::int OFFSET 100 LIMIT 10 FOR UPDATE; -- join two tables with FOR SHARE clause ---Testcase 147: +--Testcase 168: EXPLAIN (VERBOSE, COSTS OFF) SELECT t1.c1, t2.c1 FROM (SELECT (fields->>'C 1')::int c1, (fields->>'c2')::int c2, tags->>'c3' c3, fields->>'c4' c4, fields->>'c5' c5, fields->>'c6' c6, fields->>'c7' c7, fields->>'c8' c8 FROM ft1 t1) t1 JOIN (SELECT (fields->>'C 1')::int c1, (fields->>'c2')::int c2, tags->>'c3' c3, fields->>'c4' c4, fields->>'c5' c5, fields->>'c6' c6, fields->>'c7' c7, fields->>'c8' c8 FROM ft2 t2) t2 ON ((t1.c1)::int = (t2.c1)::int) ORDER BY t1.c3, (t1.c1)::int OFFSET 100 LIMIT 10 FOR SHARE OF t1; ---Testcase 148: +--Testcase 169: SELECT t1.c1, t2.c1 FROM (SELECT (fields->>'C 1')::int c1, (fields->>'c2')::int c2, tags->>'c3' c3, fields->>'c4' c4, fields->>'c5' c5, fields->>'c6' c6, fields->>'c7' c7, fields->>'c8' c8 FROM ft1 t1) t1 JOIN (SELECT (fields->>'C 1')::int c1, (fields->>'c2')::int c2, tags->>'c3' c3, fields->>'c4' c4, fields->>'c5' c5, fields->>'c6' c6, fields->>'c7' c7, fields->>'c8' c8 FROM ft2 t2) t2 ON ((t1.c1)::int = (t2.c1)::int) ORDER BY t1.c3, (t1.c1)::int OFFSET 100 LIMIT 10 FOR SHARE OF t1; ---Testcase 149: +--Testcase 170: EXPLAIN (VERBOSE, COSTS OFF) SELECT t1.c1, t2.c1 FROM (SELECT (fields->>'C 1')::int c1, (fields->>'c2')::int c2, tags->>'c3' c3, fields->>'c4' c4, fields->>'c5' c5, fields->>'c6' c6, fields->>'c7' c7, fields->>'c8' c8 FROM ft1 t1) t1 JOIN (SELECT (fields->>'C 1')::int c1, (fields->>'c2')::int c2, tags->>'c3' c3, fields->>'c4' c4, fields->>'c5' c5, fields->>'c6' c6, fields->>'c7' c7, fields->>'c8' c8 FROM ft2 t2) t2 ON ((t1.c1)::int = (t2.c1)::int) ORDER BY t1.c3, (t1.c1)::int OFFSET 100 LIMIT 10 FOR SHARE; ---Testcase 150: +--Testcase 171: SELECT t1.c1, t2.c1 FROM (SELECT (fields->>'C 1')::int c1, (fields->>'c2')::int c2, tags->>'c3' c3, fields->>'c4' c4, fields->>'c5' c5, fields->>'c6' c6, fields->>'c7' c7, fields->>'c8' c8 FROM ft1 t1) t1 JOIN (SELECT (fields->>'C 1')::int c1, (fields->>'c2')::int c2, tags->>'c3' c3, fields->>'c4' c4, fields->>'c5' c5, fields->>'c6' c6, fields->>'c7' c7, fields->>'c8' c8 FROM ft2 t2) t2 ON ((t1.c1)::int = (t2.c1)::int) ORDER BY t1.c3, (t1.c1)::int OFFSET 100 LIMIT 10 FOR SHARE; -- join in CTE ---Testcase 151: +--Testcase 172: EXPLAIN (VERBOSE, COSTS OFF) WITH t (c1_1, c1_3, c2_1) AS MATERIALIZED (SELECT t1.c1, t1.c3, t2.c1 FROM (SELECT (fields->>'C 1')::int c1, (fields->>'c2')::int c2, tags->>'c3' c3, fields->>'c4' c4, fields->>'c5' c5, fields->>'c6' c6, fields->>'c7' c7, fields->>'c8' c8 FROM ft1 t1) t1 JOIN (SELECT (fields->>'C 1')::int c1, (fields->>'c2')::int c2, tags->>'c3' c3, fields->>'c4' c4, fields->>'c5' c5, fields->>'c6' c6, fields->>'c7' c7, fields->>'c8' c8 FROM ft2 t2) t2 ON ((t1.c1)::int = (t2.c1)::int)) SELECT c1_1, c2_1 FROM t ORDER BY c1_3, c1_1 OFFSET 100 LIMIT 10; ---Testcase 152: +--Testcase 173: WITH t (c1_1, c1_3, c2_1) AS MATERIALIZED (SELECT t1.c1, t1.c3, t2.c1 FROM (SELECT (fields->>'C 1')::int c1, (fields->>'c2')::int c2, tags->>'c3' c3, fields->>'c4' c4, fields->>'c5' c5, fields->>'c6' c6, fields->>'c7' c7, fields->>'c8' c8 FROM ft1 t1) t1 JOIN (SELECT (fields->>'C 1')::int c1, (fields->>'c2')::int c2, tags->>'c3' c3, fields->>'c4' c4, fields->>'c5' c5, fields->>'c6' c6, fields->>'c7' c7, fields->>'c8' c8 FROM ft2 t2) t2 ON ((t1.c1)::int = (t2.c1)::int)) SELECT c1_1, c2_1 FROM t ORDER BY c1_3, c1_1 OFFSET 100 LIMIT 10; -- ctid with whole-row reference ---Testcase 153: +--Testcase 174: EXPLAIN (VERBOSE, COSTS OFF) SELECT t1.ctid, t1, t2, t1.c1 FROM (SELECT ctid, fields->>'C 1' c1, fields->>'c2' c2, tags->>'c3' c3, fields->>'c4' c4, fields->>'c5' c5, fields->>'c6' c6, fields->>'c7' c7, fields->>'c8' c8 FROM ft1 t1) t1 JOIN (SELECT (fields->>'C 1')::int c1, (fields->>'c2')::int c2, tags->>'c3' c3, fields->>'c4' c4, fields->>'c5' c5, fields->>'c6' c6, fields->>'c7' c7, fields->>'c8' c8 FROM ft2 t2) t2 ON ((t1.c1)::int = (t2.c1)::int) ORDER BY t1.c3, (t1.c1)::int OFFSET 100 LIMIT 10; -- SEMI JOIN, not pushed down ---Testcase 154: +--Testcase 175: EXPLAIN (VERBOSE, COSTS OFF) SELECT (t1.fields->>'C 1')::int c1 FROM ft1 t1 WHERE EXISTS (SELECT 1 FROM ft2 t2 WHERE (t1.fields->>'C 1')::int = (t2.fields->>'C 1')::int) ORDER BY (t1.fields->>'C 1')::int OFFSET 100 LIMIT 10; ---Testcase 155: +--Testcase 176: SELECT (t1.fields->>'C 1')::int c1 FROM ft1 t1 WHERE EXISTS (SELECT 1 FROM ft2 t2 WHERE (t1.fields->>'C 1')::int = (t2.fields->>'C 1')::int) ORDER BY (t1.fields->>'C 1')::int OFFSET 100 LIMIT 10; -- ANTI JOIN, not pushed down ---Testcase 156: +--Testcase 177: EXPLAIN (VERBOSE, COSTS OFF) SELECT (t1.fields->>'C 1')::int c1 FROM ft1 t1 WHERE NOT EXISTS (SELECT 1 FROM ft2 t2 WHERE (t1.fields->>'C 1')::int = (t2.fields->>'c2')::int) ORDER BY (t1.fields->>'C 1')::int OFFSET 100 LIMIT 10; ---Testcase 157: +--Testcase 178: SELECT (t1.fields->>'C 1')::int c1 FROM ft1 t1 WHERE NOT EXISTS (SELECT 1 FROM ft2 t2 WHERE (t1.fields->>'C 1')::int = (t2.fields->>'c2')::int) ORDER BY (t1.fields->>'C 1')::int OFFSET 100 LIMIT 10; -- CROSS JOIN can be pushed down ---Testcase 158: +--Testcase 179: EXPLAIN (VERBOSE, COSTS OFF) SELECT t1.c1, t2.c1 FROM (SELECT (fields->>'C 1')::int c1, (fields->>'c2')::int c2, tags->>'c3' c3, fields->>'c4' c4, fields->>'c5' c5, fields->>'c6' c6, fields->>'c7' c7, fields->>'c8' c8 FROM ft1 t1) t1 CROSS JOIN (SELECT (fields->>'C 1')::int c1, (fields->>'c2')::int c2, tags->>'c3' c3, fields->>'c4' c4, fields->>'c5' c5, fields->>'c6' c6, fields->>'c7' c7, fields->>'c8' c8 FROM ft2 t2) t2 ORDER BY (t1.c1)::int, (t2.c1)::int OFFSET 100 LIMIT 10; ---Testcase 159: +--Testcase 180: SELECT t1.c1, t2.c1 FROM (SELECT (fields->>'C 1')::int c1, (fields->>'c2')::int c2, tags->>'c3' c3, fields->>'c4' c4, fields->>'c5' c5, fields->>'c6' c6, fields->>'c7' c7, fields->>'c8' c8 FROM ft1 t1) t1 CROSS JOIN (SELECT (fields->>'C 1')::int c1, (fields->>'c2')::int c2, tags->>'c3' c3, fields->>'c4' c4, fields->>'c5' c5, fields->>'c6' c6, fields->>'c7' c7, fields->>'c8' c8 FROM ft2 t2) t2 ORDER BY (t1.c1)::int, (t2.c1)::int OFFSET 100 LIMIT 10; -- different server, not pushed down. No result expected. ---Testcase 160: +--Testcase 181: EXPLAIN (VERBOSE, COSTS OFF) SELECT t1.c1, t2.c1 FROM (SELECT (fields->>'c1')::int c1, (fields->>'c2')::int c2, tags->>'c3' c3 FROM ft5 t1) t1 JOIN (SELECT (fields->>'c1')::int c1, (fields->>'c2')::int c2, tags->>'c3' c3 FROM ft6 t2) t2 ON ((t1.c1)::int = (t2.c1)::int) ORDER BY (t1.c1)::int, (t2.c1)::int OFFSET 100 LIMIT 10; ---Testcase 161: +--Testcase 182: SELECT t1.c1, t2.c1 FROM (SELECT (fields->>'c1')::int c1, (fields->>'c2')::int c2, tags->>'c3' c3 FROM ft5 t1) t1 JOIN (SELECT (fields->>'c1')::int c1, (fields->>'c2')::int c2, tags->>'c3' c3 FROM ft6 t2) t2 ON ((t1.c1)::int = (t2.c1)::int) ORDER BY (t1.c1)::int, (t2.c1)::int OFFSET 100 LIMIT 10; -- unsafe join conditions (c8 has a UDT), not pushed down. Practically a CROSS -- JOIN since c8 in both tables has same value. ---Testcase 162: +--Testcase 183: EXPLAIN (VERBOSE, COSTS OFF) SELECT t1.c1, t2.c1 FROM (SELECT (fields->>'C 1')::int c1, (fields->>'c2')::int c2, tags->>'c3' c3, fields->>'c4' c4, fields->>'c5' c5, fields->>'c6' c6, fields->>'c7' c7, fields->>'c8' c8 FROM ft1 t1) t1 LEFT JOIN (SELECT (fields->>'C 1')::int c1, (fields->>'c2')::int c2, tags->>'c3' c3, fields->>'c4' c4, fields->>'c5' c5, fields->>'c6' c6, fields->>'c7' c7, fields->>'c8' c8 FROM ft2 t2) t2 ON (t1.c8 = t2.c8) ORDER BY (t1.c1)::int, (t2.c1)::int OFFSET 100 LIMIT 10; ---Testcase 163: +--Testcase 184: SELECT t1.c1, t2.c1 FROM (SELECT (fields->>'C 1')::int c1, (fields->>'c2')::int c2, tags->>'c3' c3, fields->>'c4' c4, fields->>'c5' c5, fields->>'c6' c6, fields->>'c7' c7, fields->>'c8' c8 FROM ft1 t1) t1 LEFT JOIN (SELECT (fields->>'C 1')::int c1, (fields->>'c2')::int c2, tags->>'c3' c3, fields->>'c4' c4, fields->>'c5' c5, fields->>'c6' c6, fields->>'c7' c7, fields->>'c8' c8 FROM ft2 t2) t2 ON (t1.c8 = t2.c8) ORDER BY (t1.c1)::int, (t2.c1)::int OFFSET 100 LIMIT 10; -- unsafe conditions on one side (c8 has a UDT), not pushed down. ---Testcase 164: +--Testcase 185: EXPLAIN (VERBOSE, COSTS OFF) SELECT t1.c1, t2.c1 FROM (SELECT (fields->>'C 1')::int c1, (fields->>'c2')::int c2, tags->>'c3' c3, fields->>'c4' c4, fields->>'c5' c5, fields->>'c6' c6, fields->>'c7' c7, fields->>'c8' c8 FROM ft1 t1) t1 LEFT JOIN (SELECT (fields->>'C 1')::int c1, (fields->>'c2')::int c2, tags->>'c3' c3, fields->>'c4' c4, fields->>'c5' c5, fields->>'c6' c6, fields->>'c7' c7, fields->>'c8' c8 FROM ft2 t2) t2 ON ((t1.c1)::int = (t2.c1)::int) WHERE t1.c8 = 'foo' ORDER BY t1.c3, (t1.c1)::int OFFSET 100 LIMIT 10; ---Testcase 165: +--Testcase 186: SELECT t1.c1, t2.c1 FROM (SELECT (fields->>'C 1')::int c1, (fields->>'c2')::int c2, tags->>'c3' c3, fields->>'c4' c4, fields->>'c5' c5, fields->>'c6' c6, fields->>'c7' c7, fields->>'c8' c8 FROM ft1 t1) t1 LEFT JOIN (SELECT (fields->>'C 1')::int c1, (fields->>'c2')::int c2, tags->>'c3' c3, fields->>'c4' c4, fields->>'c5' c5, fields->>'c6' c6, fields->>'c7' c7, fields->>'c8' c8 FROM ft2 t2) t2 ON ((t1.c1)::int = (t2.c1)::int) WHERE t1.c8 = 'foo' ORDER BY t1.c3, (t1.c1)::int OFFSET 100 LIMIT 10; -- join where unsafe to pushdown condition in WHERE clause has a column not -- in the SELECT clause. In this test unsafe clause needs to have column -- references from both joining sides so that the clause is not pushed down -- into one of the joining sides. ---Testcase 166: +--Testcase 187: EXPLAIN (VERBOSE, COSTS OFF) SELECT t1.c1, t2.c1 FROM (SELECT (fields->>'C 1')::int c1, (fields->>'c2')::int c2, tags->>'c3' c3, fields->>'c4' c4, fields->>'c5' c5, fields->>'c6' c6, fields->>'c7' c7, fields->>'c8' c8 FROM ft1 t1) t1 JOIN (SELECT (fields->>'C 1')::int c1, (fields->>'c2')::int c2, tags->>'c3' c3, fields->>'c4' c4, fields->>'c5' c5, fields->>'c6' c6, fields->>'c7' c7, fields->>'c8' c8 FROM ft2 t2) t2 ON ((t1.c1)::int = (t2.c1)::int) WHERE t1.c8 = t2.c8 ORDER BY t1.c3, (t1.c1)::int OFFSET 100 LIMIT 10; ---Testcase 167: +--Testcase 188: SELECT t1.c1, t2.c1 FROM (SELECT (fields->>'C 1')::int c1, (fields->>'c2')::int c2, tags->>'c3' c3, fields->>'c4' c4, fields->>'c5' c5, fields->>'c6' c6, fields->>'c7' c7, fields->>'c8' c8 FROM ft1 t1) t1 JOIN (SELECT (fields->>'C 1')::int c1, (fields->>'c2')::int c2, tags->>'c3' c3, fields->>'c4' c4, fields->>'c5' c5, fields->>'c6' c6, fields->>'c7' c7, fields->>'c8' c8 FROM ft2 t2) t2 ON ((t1.c1)::int = (t2.c1)::int) WHERE t1.c8 = t2.c8 ORDER BY t1.c3, (t1.c1)::int OFFSET 100 LIMIT 10; -- Aggregate after UNION, for testing setrefs ---Testcase 168: +--Testcase 189: EXPLAIN (VERBOSE, COSTS OFF) SELECT t1c1, avg(t1c1 + t2c1) FROM (SELECT (t1.c1)::int, (t2.c1)::int FROM (SELECT (fields->>'C 1')::int c1, (fields->>'c2')::int c2, tags->>'c3' c3, fields->>'c4' c4, fields->>'c5' c5, fields->>'c6' c6, fields->>'c7' c7, fields->>'c8' c8 FROM ft1 t1) t1 JOIN (SELECT (fields->>'C 1')::int c1, (fields->>'c2')::int c2, tags->>'c3' c3, fields->>'c4' c4, fields->>'c5' c5, fields->>'c6' c6, fields->>'c7' c7, fields->>'c8' c8 FROM ft2 t2) t2 ON ((t1.c1)::int = (t2.c1)::int) UNION SELECT (t1.c1)::int, (t2.c1)::int FROM (SELECT (fields->>'C 1')::int c1, (fields->>'c2')::int c2, tags->>'c3' c3, fields->>'c4' c4, fields->>'c5' c5, fields->>'c6' c6, fields->>'c7' c7, fields->>'c8' c8 FROM ft1 t1) t1 JOIN (SELECT (fields->>'C 1')::int c1, (fields->>'c2')::int c2, tags->>'c3' c3, fields->>'c4' c4, fields->>'c5' c5, fields->>'c6' c6, fields->>'c7' c7, fields->>'c8' c8 FROM ft2 t2) t2 ON ((t1.c1)::int = (t2.c1)::int)) AS t (t1c1, t2c1) GROUP BY t1c1 ORDER BY t1c1 OFFSET 100 LIMIT 10; ---Testcase 169: +--Testcase 190: SELECT t1c1, avg(t1c1 + t2c1) FROM (SELECT (t1.c1)::int, (t2.c1)::int FROM (SELECT (fields->>'C 1')::int c1, (fields->>'c2')::int c2, tags->>'c3' c3, fields->>'c4' c4, fields->>'c5' c5, fields->>'c6' c6, fields->>'c7' c7, fields->>'c8' c8 FROM ft1 t1) t1 JOIN (SELECT (fields->>'C 1')::int c1, (fields->>'c2')::int c2, tags->>'c3' c3, fields->>'c4' c4, fields->>'c5' c5, fields->>'c6' c6, fields->>'c7' c7, fields->>'c8' c8 FROM ft2 t2) t2 ON ((t1.c1)::int = (t2.c1)::int) UNION SELECT (t1.c1)::int, (t2.c1)::int FROM (SELECT (fields->>'C 1')::int c1, (fields->>'c2')::int c2, tags->>'c3' c3, fields->>'c4' c4, fields->>'c5' c5, fields->>'c6' c6, fields->>'c7' c7, fields->>'c8' c8 FROM ft1 t1) t1 JOIN (SELECT (fields->>'C 1')::int c1, (fields->>'c2')::int c2, tags->>'c3' c3, fields->>'c4' c4, fields->>'c5' c5, fields->>'c6' c6, fields->>'c7' c7, fields->>'c8' c8 FROM ft2 t2) t2 ON ((t1.c1)::int = (t2.c1)::int)) AS t (t1c1, t2c1) GROUP BY t1c1 ORDER BY t1c1 OFFSET 100 LIMIT 10; -- join with lateral reference ---Testcase 170: +--Testcase 191: EXPLAIN (VERBOSE, COSTS OFF) SELECT t1."C 1" FROM (SELECT (fields->>'C 1')::int "C 1", (fields->>'c2')::int c2, tags->>'c3' c3, fields->>'c4' c4, fields->>'c5' c5, fields->>'c6' c6, fields->>'c7' c7, fields->>'c8' c8 FROM "S 1"."T 1" t1) t1, LATERAL (SELECT DISTINCT t2.fields->>'C 1', t3.fields->>'C 1' FROM ft1 t2, ft2 t3 WHERE (t2.fields->>'C 1')::int = (t3.fields->>'C 1')::int AND (t2.fields->>'c2')::int = (t1.c2)::int) q ORDER BY (t1."C 1")::int OFFSET 10 LIMIT 10; ---Testcase 171: +--Testcase 192: SELECT t1."C 1" FROM (SELECT (fields->>'C 1')::int "C 1", (fields->>'c2')::int c2, tags->>'c3' c3, fields->>'c4' c4, fields->>'c5' c5, fields->>'c6' c6, fields->>'c7' c7, fields->>'c8' c8 FROM "S 1"."T 1" t1) t1, LATERAL (SELECT DISTINCT t2.fields->>'C 1', t3.fields->>'C 1' FROM ft1 t2, ft2 t3 WHERE (t2.fields->>'C 1')::int = (t3.fields->>'C 1')::int AND (t2.fields->>'c2')::int = (t1.c2)::int) q ORDER BY (t1."C 1")::int OFFSET 10 LIMIT 10; +-- join with pseudoconstant quals, not pushed down. +EXPLAIN (VERBOSE, COSTS OFF) +SELECT t1.c1, t2.c1 FROM (SELECT (fields->>'C 1')::int c1, (fields->>'c2')::int c2, tags->>'c3' c3, fields->>'c4' c4, fields->>'c5' c5, fields->>'c6' c6, fields->>'c7' c7, fields->>'c8' c8 FROM ft1) t1 JOIN (SELECT (fields->>'C 1')::int c1, (fields->>'c2')::int c2, tags->>'c3' c3, fields->>'c4' c4, fields->>'c5' c5, fields->>'c6' c6, fields->>'c7' c7, fields->>'c8' c8 FROM ft2) t2 ON (t1.c1 = t2.c1 AND CURRENT_USER = SESSION_USER) ORDER BY t1.c3, t1.c1 OFFSET 100 LIMIT 10; -- non-Var items in targetlist of the nullable rel of a join preventing -- push-down in some cases -- unable to push {ft1, ft2} ---Testcase 172: +--Testcase 193: EXPLAIN (VERBOSE, COSTS OFF) SELECT q.a, (ft2.fields->>'C 1')::int c1 FROM (SELECT 13 FROM ft1 WHERE (fields->>'C 1')::int = 13) q(a) RIGHT JOIN ft2 ON (q.a = (ft2.fields->>'C 1')::int) WHERE (ft2.fields->>'C 1')::int BETWEEN 10 AND 15; ---Testcase 173: +--Testcase 194: SELECT q.a, (ft2.fields->>'C 1')::int c1 FROM (SELECT 13 FROM ft1 WHERE (fields->>'C 1')::int = 13) q(a) RIGHT JOIN ft2 ON (q.a = (ft2.fields->>'C 1')::int) WHERE (ft2.fields->>'C 1')::int BETWEEN 10 AND 15; -- ok to push {ft1, ft2} but not {ft1, ft2, ft4} ---Testcase 174: +--Testcase 195: EXPLAIN (VERBOSE, COSTS OFF) SELECT (ft4.fields->>'c1')::int c1, q.* FROM ft4 LEFT JOIN (SELECT 13, (ft1.fields->>'C 1')::int, (ft2.fields->>'C 1')::int FROM ft1 RIGHT JOIN ft2 ON ((ft1.fields->>'C 1')::int = (ft2.fields->>'C 1')::int) WHERE (ft1.fields->>'C 1')::int = 12) q(a, b, c) ON ((ft4.fields->>'c1')::int = q.b) WHERE (ft4.fields->>'c1')::int BETWEEN 10 AND 15; ---Testcase 175: +--Testcase 196: SELECT (ft4.fields->>'c1')::int c1, q.* FROM ft4 LEFT JOIN (SELECT 13, (ft1.fields->>'C 1')::int, (ft2.fields->>'C 1')::int FROM ft1 RIGHT JOIN ft2 ON ((ft1.fields->>'C 1')::int = (ft2.fields->>'C 1')::int) WHERE (ft1.fields->>'C 1')::int = 12) q(a, b, c) ON ((ft4.fields->>'c1')::int = q.b) WHERE (ft4.fields->>'c1')::int BETWEEN 10 AND 15 ORDER BY (ft4.fields->>'c1')::int; -- join with nullable side with some columns with null values -- influxdb_fdw does not support UPDATE -- UPDATE ft5 SET c3 = null where c1 % 9 = 0; ---Testcase 176: +--Testcase 197: EXPLAIN (VERBOSE, COSTS OFF) SELECT ft5, (ft5.fields->>'c1')::int c1, (ft5.fields->>'c2')::int c2, ft5.tags->>'c3' c3, (ft4.fields->>'c1')::int c1, (ft4.fields->>'c2')::int c2 FROM ft5 left join ft4 on (ft5.fields->>'c1')::int = (ft4.fields->>'c1')::int WHERE (ft4.fields->>'c1')::int BETWEEN 10 and 30 ORDER BY (ft5.fields->>'c1')::int, (ft4.fields->>'c1')::int; ---Testcase 177: +--Testcase 198: SELECT ft5, (ft5.fields->>'c1')::int c1, (ft5.fields->>'c2')::int c2, ft5.tags->>'c3' c3, (ft4.fields->>'c1')::int c1, (ft4.fields->>'c2')::int c2 FROM ft5 left join ft4 on (ft5.fields->>'c1')::int = (ft4.fields->>'c1')::int WHERE (ft4.fields->>'c1')::int BETWEEN 10 and 30 ORDER BY (ft5.fields->>'c1')::int, (ft4.fields->>'c1')::int; -- multi-way join involving multiple merge joins -- (this case used to have EPQ-related planning problems) ---Testcase 178: +--Testcase 199: CREATE FOREIGN TABLE local_tbl (fields jsonb OPTIONS(fields 'true')) SERVER influxdb_svr OPTIONS (table 'local_tbl', schemaless 'true'); +--Testcase 794: CREATE FOREIGN TABLE local_tbl_nsc (c1 int NOT NULL, c2 int NOT NULL, c3 text) SERVER influxdb_svr OPTIONS (table 'local_tbl'); ---Testcase 179: +--Testcase 200: INSERT INTO local_tbl_nsc SELECT id, id % 10, to_char(id, 'FM0000') FROM generate_series(1, 1000) id; --ANALYZE local_tbl; +--Testcase 201: SET enable_nestloop TO false; +--Testcase 202: SET enable_hashjoin TO false; ---Testcase 180: +--Testcase 203: EXPLAIN (VERBOSE, COSTS OFF) SELECT * FROM ft1, ft2, ft4, ft5, local_tbl WHERE (ft1.fields->>'C 1')::int = (ft2.fields->>'C 1')::int AND (ft1.fields->>'c2')::int = (ft4.fields->>'c1')::int AND (ft1.fields->>'c2')::int = (ft5.fields->>'c1')::int AND (ft1.fields->>'c2')::int = (local_tbl.fields->>'c1')::int AND (ft1.fields->>'C 1')::int < 100 AND (ft2.fields->>'C 1')::int < 100 ORDER BY (ft1.fields->>'C 1')::int FOR UPDATE; ---Testcase 181: +--Testcase 204: SELECT * FROM ft1, ft2, ft4, ft5, local_tbl WHERE (ft1.fields->>'C 1')::int = (ft2.fields->>'C 1')::int AND (ft1.fields->>'c2')::int = (ft4.fields->>'c1')::int AND (ft1.fields->>'c2')::int = (ft5.fields->>'c1')::int AND (ft1.fields->>'c2')::int = (local_tbl.fields->>'c1')::int AND (ft1.fields->>'C 1')::int < 100 AND (ft2.fields->>'C 1')::int < 100 ORDER BY (ft1.fields->>'C 1')::int FOR UPDATE; +--Testcase 205: RESET enable_nestloop; +--Testcase 206: RESET enable_hashjoin; ---Testcase 182: + +-- test that add_paths_with_pathkeys_for_rel() arranges for the epq_path to +-- return columns needed by the parent ForeignScan node +--Testcase 867: +EXPLAIN (VERBOSE, COSTS OFF) +SELECT * FROM local_tbl LEFT JOIN (SELECT ft1.*, COALESCE(ft1.tags->>'c3' || (ft2.tags->>'c3')::text, 'foobar') FROM ft1 INNER JOIN ft2 ON (ft1.fields->>'C 1' = ft2.fields->>'C 1' AND (ft1.fields->>'C 1')::int < 100)) ss ON (local_tbl.fields->>'c1' = ss.fields->>'C 1') ORDER BY local_tbl.fields->>'c1' FOR UPDATE OF local_tbl; + +-- ALTER SERVER loopback OPTIONS (DROP extensions); +-- ALTER SERVER loopback OPTIONS (ADD fdw_startup_cost '10000.0'); +--Testcase 868: +EXPLAIN (VERBOSE, COSTS OFF) +SELECT * FROM local_tbl LEFT JOIN (SELECT ft1.* FROM ft1 INNER JOIN ft2 ON ((ft1.fields->>'C 1')::int = (ft2.fields->>'C 1')::int AND (ft1.fields->>'C 1')::int < 100 AND ((ft1.fields->>'C 1')::int - influxdb_fdw_abs((ft2.fields->>'C 1')::int)) = 0)) ss ON (local_tbl.fields->>'c3' = ss.tags->>'c3') ORDER BY local_tbl.fields->>'c1' FOR UPDATE OF local_tbl; +-- ALTER SERVER loopback OPTIONS (DROP fdw_startup_cost); +-- ALTER SERVER loopback OPTIONS (ADD extensions 'postgres_fdw'); + +--Testcase 207: DELETE FROM local_tbl_nsc; +--Testcase 795: DROP FOREIGN TABLE local_tbl; +--Testcase 796: DROP FOREIGN TABLE local_tbl_nsc; -- check join pushdown in situations where multiple userids are involved ---Testcase 183: +--Testcase 208: CREATE ROLE regress_view_owner SUPERUSER; ---Testcase 184: +--Testcase 209: CREATE USER MAPPING FOR regress_view_owner SERVER influxdb_svr OPTIONS (:AUTHENTICATION); GRANT SELECT ON ft4 TO regress_view_owner; GRANT SELECT ON ft5 TO regress_view_owner; ---Testcase 185: +--Testcase 210: CREATE VIEW v4 AS SELECT * FROM ft4; ---Testcase 186: +--Testcase 211: CREATE VIEW v5 AS SELECT * FROM ft5; +--Testcase 212: ALTER VIEW v5 OWNER TO regress_view_owner; ---Testcase 187: +--Testcase 213: EXPLAIN (VERBOSE, COSTS OFF) SELECT t1.c1, t2.c2 FROM (SELECT (fields->>'c1')::int c1, (fields->>'c2')::int c2, tags->>'c3' c3 FROM v4 t1) t1 LEFT JOIN (SELECT (fields->>'c1')::int c1, (fields->>'c2')::int c2, tags->>'c3' c3 FROM v5 t2) t2 ON ((t1.c1)::int = (t2.c1)::int) ORDER BY (t1.c1)::int, (t2.c1)::int OFFSET 10 LIMIT 10; -- can't be pushed down, different view owners ---Testcase 188: +--Testcase 214: SELECT t1.c1, t2.c2 FROM (SELECT (fields->>'c1')::int c1, (fields->>'c2')::int c2, tags->>'c3' c3 FROM v4 t1) t1 LEFT JOIN (SELECT (fields->>'c1')::int c1, (fields->>'c2')::int c2, tags->>'c3' c3 FROM v5 t2) t2 ON ((t1.c1)::int = (t2.c1)::int) ORDER BY (t1.c1)::int, (t2.c1)::int OFFSET 10 LIMIT 10; +--Testcase 215: ALTER VIEW v4 OWNER TO regress_view_owner; ---Testcase 189: +--Testcase 216: EXPLAIN (VERBOSE, COSTS OFF) SELECT t1.c1, t2.c2 FROM (SELECT (fields->>'c1')::int c1, (fields->>'c2')::int c2, tags->>'c3' c3 FROM v4 t1) t1 LEFT JOIN (SELECT (fields->>'c1')::int c1, (fields->>'c2')::int c2, tags->>'c3' c3 FROM v5 t2) t2 ON ((t1.c1)::int = (t2.c1)::int) ORDER BY (t1.c1)::int, (t2.c1)::int OFFSET 10 LIMIT 10; -- can be pushed down ---Testcase 190: +--Testcase 217: SELECT t1.c1, t2.c2 FROM (SELECT (fields->>'c1')::int c1, (fields->>'c2')::int c2, tags->>'c3' c3 FROM v4 t1) t1 LEFT JOIN (SELECT (fields->>'c1')::int c1, (fields->>'c2')::int c2, tags->>'c3' c3 FROM v5 t2) t2 ON ((t1.c1)::int = (t2.c1)::int) ORDER BY (t1.c1)::int, (t2.c1)::int OFFSET 10 LIMIT 10; ---Testcase 191: +--Testcase 218: EXPLAIN (VERBOSE, COSTS OFF) SELECT t1.c1, t2.c2 FROM (SELECT (fields->>'c1')::int c1, (fields->>'c2')::int c2, tags->>'c3' c3 FROM v4 t1) t1 LEFT JOIN (SELECT (fields->>'c1')::int c1, (fields->>'c2')::int c2, tags->>'c3' c3 FROM ft5 t2) t2 ON ((t1.c1)::int = (t2.c1)::int) ORDER BY (t1.c1)::int, (t2.c1)::int OFFSET 10 LIMIT 10; -- can't be pushed down, view owner not current user ---Testcase 192: +--Testcase 219: SELECT t1.c1, t2.c2 FROM (SELECT (fields->>'c1')::int c1, (fields->>'c2')::int c2, tags->>'c3' c3 FROM v4 t1) t1 LEFT JOIN (SELECT (fields->>'c1')::int c1, (fields->>'c2')::int c2, tags->>'c3' c3 FROM ft5 t2) t2 ON ((t1.c1)::int = (t2.c1)::int) ORDER BY (t1.c1)::int, (t2.c1)::int OFFSET 10 LIMIT 10; +--Testcase 220: ALTER VIEW v4 OWNER TO CURRENT_USER; ---Testcase 193: +--Testcase 221: EXPLAIN (VERBOSE, COSTS OFF) SELECT t1.c1, t2.c2 FROM (SELECT (fields->>'c1')::int c1, (fields->>'c2')::int c2, tags->>'c3' c3 FROM v4 t1) t1 LEFT JOIN (SELECT (fields->>'c1')::int c1, (fields->>'c2')::int c2, tags->>'c3' c3 FROM ft5 t2) t2 ON ((t1.c1)::int = (t2.c1)::int) ORDER BY (t1.c1)::int, (t2.c1)::int OFFSET 10 LIMIT 10; -- can be pushed down ---Testcase 194: +--Testcase 222: SELECT t1.c1, t2.c2 FROM (SELECT (fields->>'c1')::int c1, (fields->>'c2')::int c2, tags->>'c3' c3 FROM v4 t1) t1 LEFT JOIN (SELECT (fields->>'c1')::int c1, (fields->>'c2')::int c2, tags->>'c3' c3 FROM ft5 t2) t2 ON ((t1.c1)::int = (t2.c1)::int) ORDER BY (t1.c1)::int, (t2.c1)::int OFFSET 10 LIMIT 10; +--Testcase 223: ALTER VIEW v4 OWNER TO regress_view_owner; +-- ==================================================================== +-- Check that userid to use when querying the remote table is correctly +-- propagated into foreign rels present in subqueries under an UNION ALL +-- ==================================================================== +CREATE ROLE regress_view_owner_another; +ALTER VIEW v4 OWNER TO regress_view_owner_another; +GRANT SELECT ON ft4 TO regress_view_owner_another; +-- ALTER FOREIGN TABLE ft4 OPTIONS (ADD use_remote_estimate 'true'); +-- The following should query the remote backing table of ft4 as user +-- regress_view_owner_another, the view owner, though it fails as expected +-- due to the lack of a user mapping for that user. +EXPLAIN (VERBOSE, COSTS OFF) SELECT * FROM v4; +-- Likewise, but with the query under an UNION ALL +EXPLAIN (VERBOSE, COSTS OFF) SELECT * FROM (SELECT * FROM v4 UNION ALL SELECT * FROM v4); +-- Should not get that error once a user mapping is created +CREATE USER MAPPING FOR regress_view_owner_another SERVER influxdb_svr OPTIONS (:AUTHENTICATION); +EXPLAIN (VERBOSE, COSTS OFF) SELECT * FROM v4; +EXPLAIN (VERBOSE, COSTS OFF) SELECT * FROM (SELECT * FROM v4 UNION ALL SELECT * FROM v4); +DROP USER MAPPING FOR regress_view_owner_another SERVER influxdb_svr; +DROP OWNED BY regress_view_owner_another; +DROP ROLE regress_view_owner_another; +-- ALTER FOREIGN TABLE ft4 OPTIONS (SET use_remote_estimate 'false'); + -- cleanup ---Testcase 195: +--Testcase 224: DROP OWNED BY regress_view_owner; ---Testcase 196: +--Testcase 225: DROP ROLE regress_view_owner; @@ -825,238 +982,246 @@ DROP ROLE regress_view_owner; -- =================================================================== -- Simple aggregates ---Testcase 197: +--Testcase 226: explain (verbose, costs off) select count(fields->>'c6'), sum((fields->>'C 1')::int), avg((fields->>'C 1')::int), min((fields->>'c2')::int), max((fields->>'C 1')::int), stddev((fields->>'c2')::int), sum((fields->>'C 1')::int) * (random() <= 1)::int as sum2 from ft1 where (fields->>'c2')::int < 5 group by fields->>'c2' order by 1, 2; ---Testcase 198: +--Testcase 227: select count(fields->>'c6'), sum((fields->>'C 1')::int), avg((fields->>'C 1')::int), min((fields->>'c2')::int), max((fields->>'C 1')::int), stddev((fields->>'c2')::int), sum((fields->>'C 1')::int) * (random() <= 1)::int as sum2 from ft1 where (fields->>'c2')::int < 5 group by fields->>'c2' order by 1, 2; ---Testcase 199: +--Testcase 228: explain (verbose, costs off) select count(fields->>'c6'), sum((fields->>'C 1')::int), avg((fields->>'C 1')::int), min((fields->>'c2')::int), max((fields->>'C 1')::int), stddev((fields->>'c2')::int), sum((fields->>'C 1')::int) * (random() <= 1)::int as sum2 from ft1 where (fields->>'c2')::int < 5 group by fields->>'c2' order by 1, 2 limit 1; ---Testcase 200: +--Testcase 229: select count(fields->>'c6'), sum((fields->>'C 1')::int), avg((fields->>'C 1')::int), min((fields->>'c2')::int), max((fields->>'C 1')::int), stddev((fields->>'c2')::int), sum((fields->>'C 1')::int) * (random() <= 1)::int as sum2 from ft1 where (fields->>'c2')::int < 5 group by fields->>'c2' order by 1, 2 limit 1; -- Aggregate is not pushed down as aggregation contains random() ---Testcase 201: +--Testcase 230: explain (verbose, costs off) select sum((fields->>'C 1')::int * (random() <= 1)::int) as sum, avg((fields->>'C 1')::int) from ft1; -- Aggregate over join query ---Testcase 202: +--Testcase 231: explain (verbose, costs off) select count(*), sum((t1.c1)::int), avg((t2.c1)::int) from (SELECT (fields->>'C 1')::int c1, (fields->>'c2')::int c2, tags->>'c3' c3, fields->>'c4' c4, fields->>'c5' c5, fields->>'c6' c6, fields->>'c7' c7, fields->>'c8' c8 FROM ft1 t1) t1 inner join (SELECT (fields->>'C 1')::int c1, (fields->>'c2')::int c2, tags->>'c3' c3, fields->>'c4' c4, fields->>'c5' c5, fields->>'c6' c6, fields->>'c7' c7, fields->>'c8' c8 FROM ft1 t2) t2 on ((t1.c2)::int = (t2.c2)::int) where (t1.c2)::int = 6; ---Testcase 203: +--Testcase 232: select count(*), sum((t1.c1)::int), avg((t2.c1)::int) from (SELECT (fields->>'C 1')::int c1, (fields->>'c2')::int c2, tags->>'c3' c3, fields->>'c4' c4, fields->>'c5' c5, fields->>'c6' c6, fields->>'c7' c7, fields->>'c8' c8 FROM ft1 t1) t1 inner join (SELECT (fields->>'C 1')::int c1, (fields->>'c2')::int c2, tags->>'c3' c3, fields->>'c4' c4, fields->>'c5' c5, fields->>'c6' c6, fields->>'c7' c7, fields->>'c8' c8 FROM ft1 t2) t2 on ((t1.c2)::int = (t2.c2)::int) where (t1.c2)::int = 6; -- Not pushed down due to local conditions present in underneath input rel ---Testcase 204: +--Testcase 233: explain (verbose, costs off) select sum((t1.c1)::int), count((t2.c1)::int) from (SELECT (fields->>'C 1')::int c1, (fields->>'c2')::int c2, tags->>'c3' c3, fields->>'c4' c4, fields->>'c5' c5, fields->>'c6' c6, fields->>'c7' c7, fields->>'c8' c8 FROM ft1 t1) t1 inner join (SELECT (fields->>'C 1')::int c1, (fields->>'c2')::int c2, tags->>'c3' c3, fields->>'c4' c4, fields->>'c5' c5, fields->>'c6' c6, fields->>'c7' c7, fields->>'c8' c8 FROM ft2 t2) t2 on ((t1.c1)::int = (t2.c1)::int) where (((t1.c1)::int * (t2.c1)::int)/((t1.c1)::int * (t2.c1)::int)) * random() <= 1; -- GROUP BY clause having expressions ---Testcase 205: +--Testcase 234: explain (verbose, costs off) select (fields->>'c2')::int/2, sum((fields->>'c2')::int) * ((fields->>'c2')::int/2) from ft1 group by (fields->>'c2')::int/2 order by (fields->>'c2')::int/2; ---Testcase 206: +--Testcase 235: select (fields->>'c2')::int/2, sum((fields->>'c2')::int) * ((fields->>'c2')::int/2) from ft1 group by (fields->>'c2')::int/2 order by (fields->>'c2')::int/2; -- Aggregates in subquery are pushed down. ---Testcase 207: +set enable_incremental_sort = off; +--Testcase 236: explain (verbose, costs off) select count(x.a), sum(x.a) from (select (fields->>'c2')::int a, sum((fields->>'C 1')::int) b from ft1 group by fields->>'c2', sqrt((fields->>'C 1')::int) order by 1, 2) x; ---Testcase 208: +--Testcase 237: select count(x.a), sum(x.a) from (select (fields->>'c2')::int a, sum((fields->>'C 1')::int) b from ft1 group by fields->>'c2', sqrt((fields->>'C 1')::int) order by 1, 2) x; +reset enable_incremental_sort; -- Aggregate is still pushed down by taking unshippable expression out ---Testcase 209: +--Testcase 238: explain (verbose, costs off) select (fields->>'c2')::int * (random() <= 1)::int as sum1, sum((fields->>'C 1')::int) * (fields->>'c2')::int as sum2 from ft1 group by fields->>'c2' order by 1, 2; ---Testcase 210: +--Testcase 239: select (fields->>'c2')::int * (random() <= 1)::int as sum1, sum((fields->>'C 1')::int) * (fields->>'c2')::int as sum2 from ft1 group by fields->>'c2' order by 1, 2; -- Aggregate with unshippable GROUP BY clause are not pushed ---Testcase 211: +--Testcase 240: explain (verbose, costs off) select (fields->>'c2')::int * (random() <= 1)::int as c2 from ft2 group by (fields->>'c2')::int * (random() <= 1)::int order by 1; -- GROUP BY clause in various forms, cardinal, alias and constant expression ---Testcase 212: +--Testcase 241: explain (verbose, costs off) select count(fields->>'c2') w, fields->>'c2' x, 5 y, 7.0 z from ft1 group by 2, y, 9.0::int order by 2; ---Testcase 213: +--Testcase 242: select count(fields->>'c2') w, fields->>'c2' x, 5 y, 7.0 z from ft1 group by 2, y, 9.0::int order by 2; -- GROUP BY clause referring to same column multiple times -- Also, ORDER BY contains an aggregate function ---Testcase 214: +--Testcase 243: explain (verbose, costs off) select (fields->>'c2')::int c2, (fields->>'c2')::int c2 from ft1 where (fields->>'c2')::int > 6 group by 1, 2 order by sum((fields->>'C 1')::int); ---Testcase 215: +--Testcase 244: select (fields->>'c2')::int c2, (fields->>'c2')::int c2 from ft1 where (fields->>'c2')::int > 6 group by 1, 2 order by sum((fields->>'C 1')::int); -- Testing HAVING clause shippability ---Testcase 216: +--Testcase 245: explain (verbose, costs off) select(fields->>'c2')::int c2, sum((fields->>'C 1')::int) from ft2 group by fields->>'c2' having avg((fields->>'C 1')::int) < 500 and sum((fields->>'C 1')::int) < 49800 order by (fields->>'c2')::int; ---Testcase 217: +--Testcase 246: select(fields->>'c2')::int c2, sum((fields->>'C 1')::int) from ft2 group by fields->>'c2' having avg((fields->>'C 1')::int) < 500 and sum((fields->>'C 1')::int) < 49800 order by (fields->>'c2')::int; -- Unshippable HAVING clause will be evaluated locally, and other qual in HAVING clause is pushed down ---Testcase 218: +--Testcase 247: explain (verbose, costs off) select count(*) from (select time, count((fields->>'C 1')::int) from ft1 group by time, sqrt((fields->>'c2')::int) having (avg((fields->>'C 1')::int) / avg((fields->>'C 1')::int)) * random() <= 1 and avg((fields->>'C 1')::int) < 500) x; ---Testcase 219: +--Testcase 248: select count(*) from (select time, count((fields->>'C 1')::int) from ft1 group by time, sqrt((fields->>'c2')::int) having (avg((fields->>'C 1')::int) / avg((fields->>'C 1')::int)) * random() <= 1 and avg((fields->>'C 1')::int) < 500) x; -- Aggregate in HAVING clause is not pushable, and thus aggregation is not pushed down ---Testcase 220: +--Testcase 249: explain (verbose, costs off) select sum((fields->>'C 1')::int) from ft1 group by fields->>'c2' having avg((fields->>'C 1')::int * (random() <= 1)::int) > 100 order by 1; -- Remote aggregate in combination with a local Param (for the output -- of an initplan) can be trouble, per bug #15781 ---Testcase 221: +--Testcase 250: explain (verbose, costs off) select exists(select 1 from pg_enum), sum((fields->>'C 1')::int) from ft1; ---Testcase 222: +--Testcase 251: select exists(select 1 from pg_enum), sum((fields->>'C 1')::int) from ft1; ---Testcase 223: +--Testcase 252: explain (verbose, costs off) select exists(select 1 from pg_enum), sum((fields->>'C 1')::int) from ft1 group by 1; ---Testcase 224: +--Testcase 253: select exists(select 1 from pg_enum), sum((fields->>'C 1')::int) from ft1 group by 1; -- Testing ORDER BY, DISTINCT, FILTER, Ordered-sets and VARIADIC within aggregates -- ORDER BY within aggregate, same column used to order ---Testcase 225: +--Testcase 254: explain (verbose, costs off) select array_agg((fields->>'C 1')::int order by (fields->>'C 1')::int) from ft1 where (fields->>'C 1')::int < 100 group by fields->>'c2' order by 1; ---Testcase 226: +--Testcase 255: select array_agg((fields->>'C 1')::int order by (fields->>'C 1')::int) from ft1 where (fields->>'C 1')::int < 100 group by fields->>'c2' order by 1; -- ORDER BY within aggregate, different column used to order also using DESC ---Testcase 227: +--Testcase 256: explain (verbose, costs off) select array_agg(time order by (fields->>'C 1')::int desc) from ft2 where (fields->>'c2')::int = 6 and (fields->>'C 1')::int < 50; ---Testcase 228: +--Testcase 257: select array_agg(time order by (fields->>'C 1')::int desc) from ft2 where (fields->>'c2')::int = 6 and (fields->>'C 1')::int < 50; -- DISTINCT within aggregate ---Testcase 229: +--Testcase 258: explain (verbose, costs off) select array_agg(distinct ((t1.c1)::int)%5) from (SELECT (fields->>'c1')::int c1, (fields->>'c2')::int c2, tags->>'c3' c3 FROM ft4 t1) t1 full join (SELECT (fields->>'c1')::int c1, (fields->>'c2')::int c2, tags->>'c3' c3 FROM ft5 t2) t2 on ((t1.c1)::int = (t2.c1)::int) where (t1.c1)::int < 20 or ((t1.c1)::int is null and (t2.c1)::int < 5) group by ((t2.c1)::int)%3 order by 1; ---Testcase 230: +--Testcase 259: select array_agg(distinct ((t1.c1)::int)%5) from (SELECT (fields->>'c1')::int c1, (fields->>'c2')::int c2, tags->>'c3' c3 FROM ft4 t1) t1 full join (SELECT (fields->>'c1')::int c1, (fields->>'c2')::int c2, tags->>'c3' c3 FROM ft5 t2) t2 on ((t1.c1)::int = (t2.c1)::int) where (t1.c1)::int < 20 or ((t1.c1)::int is null and (t2.c1)::int < 5) group by ((t2.c1)::int)%3 order by 1; -- DISTINCT combined with ORDER BY within aggregate ---Testcase 231: +--Testcase 260: explain (verbose, costs off) select array_agg(distinct ((t1.c1)::int)%5 order by ((t1.c1)::int)%5) from (SELECT (fields->>'c1')::int c1, (fields->>'c2')::int c2, tags->>'c3' c3 FROM ft4 t1) t1 full join (SELECT (fields->>'c1')::int c1, (fields->>'c2')::int c2, tags->>'c3' c3 FROM ft5 t2) t2 on ((t1.c1)::int = (t2.c1)::int) where (t1.c1)::int < 20 or ((t1.c1)::int is null and (t2.c1)::int < 5) group by ((t2.c1)::int)%3 order by 1; ---Testcase 232: +--Testcase 261: select array_agg(distinct ((t1.c1)::int)%5 order by ((t1.c1)::int)%5) from (SELECT (fields->>'c1')::int c1, (fields->>'c2')::int c2, tags->>'c3' c3 FROM ft4 t1) t1 full join (SELECT (fields->>'c1')::int c1, (fields->>'c2')::int c2, tags->>'c3' c3 FROM ft5 t2) t2 on ((t1.c1)::int = (t2.c1)::int) where (t1.c1)::int < 20 or ((t1.c1)::int is null and (t2.c1)::int < 5) group by ((t2.c1)::int)%3 order by 1; ---Testcase 233: +--Testcase 262: explain (verbose, costs off) select array_agg(distinct ((t1.c1)::int)%5 order by ((t1.c1)::int)%5 desc nulls last) from (SELECT (fields->>'c1')::int c1, (fields->>'c2')::int c2, tags->>'c3' c3 FROM ft4 t1) t1 full join (SELECT (fields->>'c1')::int c1, (fields->>'c2')::int c2, tags->>'c3' c3 FROM ft5 t2) t2 on ((t1.c1)::int = (t2.c1)::int) where (t1.c1)::int < 20 or ((t1.c1)::int is null and (t2.c1)::int < 5) group by ((t2.c1)::int)%3 order by 1; ---Testcase 234: +--Testcase 263: select array_agg(distinct ((t1.c1)::int)%5 order by ((t1.c1)::int)%5 desc nulls last) from (SELECT (fields->>'c1')::int c1, (fields->>'c2')::int c2, tags->>'c3' c3 FROM ft4 t1) t1 full join (SELECT (fields->>'c1')::int c1, (fields->>'c2')::int c2, tags->>'c3' c3 FROM ft5 t2) t2 on ((t1.c1)::int = (t2.c1)::int) where (t1.c1)::int < 20 or ((t1.c1)::int is null and (t2.c1)::int < 5) group by ((t2.c1)::int)%3 order by 1; -- FILTER within aggregate ---Testcase 235: +--Testcase 264: explain (verbose, costs off) select sum((fields->>'C 1')::int) filter (where (fields->>'C 1')::int < 100 and (fields->>'c2')::int > 5) from ft1 group by fields->>'c2' order by 1 nulls last; ---Testcase 236: +--Testcase 265: select sum((fields->>'C 1')::int) filter (where (fields->>'C 1')::int < 100 and (fields->>'c2')::int > 5) from ft1 group by fields->>'c2' order by 1 nulls last; -- DISTINCT, ORDER BY and FILTER within aggregate ---Testcase 237: +--Testcase 266: explain (verbose, costs off) select sum((fields->>'C 1')::int%3), sum(distinct (fields->>'C 1')::int%3 order by (fields->>'C 1')::int%3) filter (where (fields->>'C 1')::int%3 < 2), (fields->>'c2')::int c2 from ft1 where (fields->>'c2')::int = 6 group by fields->>'c2'; ---Testcase 238: +--Testcase 267: select sum((fields->>'C 1')::int%3), sum(distinct (fields->>'C 1')::int%3 order by (fields->>'C 1')::int%3) filter (where (fields->>'C 1')::int%3 < 2), (fields->>'c2')::int c2 from ft1 where (fields->>'c2')::int = 6 group by fields->>'c2'; -- Outer query is aggregation query ---Testcase 239: +--Testcase 268: explain (verbose, costs off) select distinct (select count(*) filter (where (t2.fields->>'c2')::int = 6 and (t2.fields->>'C 1')::int < 10) from ft1 t1 where (t1.fields->>'C 1')::int = 6) from ft2 t2 where (t2.fields->>'c2')::int % 6 = 0 order by 1; ---Testcase 240: +--Testcase 269: select distinct (select count(*) filter (where (t2.fields->>'c2')::int = 6 and (t2.fields->>'C 1')::int < 10) from ft1 t1 where (t1.fields->>'C 1')::int = 6) from ft2 t2 where (t2.fields->>'c2')::int % 6 = 0 order by 1; -- Inner query is aggregation query ---Testcase 241: +--Testcase 270: explain (verbose, costs off) select distinct (select count(t1.fields->>'C 1') filter (where (t2.fields->>'c2')::int = 6 and (t2.fields->>'C 1')::int < 10) from ft1 t1 where (t1.fields->>'C 1')::int = 6) from ft2 t2 where (t2.fields->>'c2')::int % 6 = 0 order by 1; ---Testcase 242: +--Testcase 271: select distinct (select count(t1.fields->>'C 1') filter (where (t2.fields->>'c2')::int = 6 and (t2.fields->>'C 1')::int < 10) from ft1 t1 where (t1.fields->>'C 1')::int = 6) from ft2 t2 where (t2.fields->>'c2')::int % 6 = 0 order by 1; -- Aggregate not pushed down as FILTER condition is not pushable ---Testcase 243: +--Testcase 272: explain (verbose, costs off) select sum((fields->>'C 1')::int) filter (where ((fields->>'C 1')::int / (fields->>'C 1')::int) * random() <= 1) from ft1 group by fields->>'c2' order by 1; ---Testcase 244: +--Testcase 273: explain (verbose, costs off) select sum((fields->>'c2')::int) filter (where (fields->>'c2')::int in (select (fields->>'c2')::int from ft1 where (fields->>'c2')::int < 5)) from ft1; -- Ordered-sets within aggregate ---Testcase 245: +--Testcase 274: explain (verbose, costs off) select (fields->>'c2')::int c2, rank('10'::varchar) within group (order by fields->>'c6'), percentile_cont((fields->>'c2')::int/10::numeric) within group (order by (fields->>'C 1')::int) from ft1 where (fields->>'c2')::int < 10 group by fields->>'c2' having percentile_cont((fields->>'c2')::int/10::numeric) within group (order by (fields->>'C 1')::int) < 500 order by (fields->>'c2')::int; ---Testcase 246: +--Testcase 275: select (fields->>'c2')::int c2, rank('10'::varchar) within group (order by fields->>'c6'), percentile_cont((fields->>'c2')::int/10::numeric) within group (order by (fields->>'C 1')::int) from ft1 where (fields->>'c2')::int < 10 group by fields->>'c2' having percentile_cont((fields->>'c2')::int/10::numeric) within group (order by (fields->>'C 1')::int) < 500 order by (fields->>'c2')::int; -- Using multiple arguments within aggregates ---Testcase 247: +--Testcase 276: explain (verbose, costs off) select (fields->>'C 1')::int c1, rank(fields->>'C 1', fields->>'c2') within group (order by fields->>'C 1', fields->>'c2') from ft1 group by fields->>'C 1', fields->>'c2' having (fields->>'C 1')::int = 6 order by 1; ---Testcase 248: +--Testcase 277: select (fields->>'C 1')::int c1, rank(fields->>'C 1', fields->>'c2') within group (order by fields->>'C 1', fields->>'c2') from ft1 group by fields->>'C 1', fields->>'c2' having (fields->>'C 1')::int = 6 order by 1; -- User defined function for user defined aggregate, VARIADIC ---Testcase 249: +--Testcase 278: 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)'; ---Testcase 250: +--Testcase 279: create aggregate least_agg(variadic items anyarray) ( stype = anyelement, sfunc = least_accum ); -- Disable hash aggregation for plan stability. +--Testcase 280: set enable_hashagg to false; -- Not pushed down due to user defined aggregate ---Testcase 251: +--Testcase 281: explain (verbose, costs off) select (fields->>'c2')::int c2, least_agg((fields->>'C 1')::int) from ft1 group by fields->>'c2' order by (fields->>'c2')::int; -- Add function and aggregate into extension +--Testcase 282: alter extension influxdb_fdw add function least_accum(anyelement, variadic anyarray); +--Testcase 283: alter extension influxdb_fdw add aggregate least_agg(variadic items anyarray); -- Now aggregate will be pushed. Aggregate will display VARIADIC argument. ---Testcase 252: +--Testcase 284: explain (verbose, costs off) select (fields->>'c2')::int c2, least_agg((fields->>'C 1')::int) from ft1 where (fields->>'c2')::int < 100 group by fields->>'c2' order by (fields->>'c2')::int; ---Testcase 253: +--Testcase 285: select (fields->>'c2')::int c2, least_agg((fields->>'C 1')::int) from ft1 where (fields->>'c2')::int < 100 group by fields->>'c2' order by (fields->>'c2')::int; -- Remove function and aggregate from extension +--Testcase 286: alter extension influxdb_fdw drop function least_accum(anyelement, variadic anyarray); +--Testcase 287: alter extension influxdb_fdw drop aggregate least_agg(variadic items anyarray); -- Not pushed down as we have dropped objects from extension. ---Testcase 254: +--Testcase 288: explain (verbose, costs off) select (fields->>'c2')::int c2, least_agg((fields->>'C 1')::int) from ft1 group by fields->>'c2' order by (fields->>'c2')::int; -- Cleanup +--Testcase 289: reset enable_hashagg; ---Testcase 255: +--Testcase 290: drop aggregate least_agg(variadic items anyarray); ---Testcase 256: +--Testcase 291: drop function least_accum(anyelement, variadic anyarray); @@ -1065,35 +1230,35 @@ drop function least_accum(anyelement, variadic anyarray); -- operator class. Create those and then add them in extension. Note that -- user defined objects are considered unshippable unless they are part of -- the extension. ---Testcase 257: +--Testcase 292: create operator public.<^ ( leftarg = int4, rightarg = int4, procedure = int4eq ); ---Testcase 258: +--Testcase 293: create operator public.=^ ( leftarg = int4, rightarg = int4, procedure = int4lt ); ---Testcase 259: +--Testcase 294: create operator public.>^ ( leftarg = int4, rightarg = int4, procedure = int4gt ); ---Testcase 260: +--Testcase 295: create operator family my_op_family using btree; ---Testcase 261: +--Testcase 296: create function my_op_cmp(a int, b int) returns int as $$begin return btint4cmp(a, b); end $$ language plpgsql; ---Testcase 262: +--Testcase 297: create operator class my_op_class for type int using btree family my_op_family as operator 1 public.<^, operator 3 public.=^, @@ -1102,102 +1267,129 @@ create operator class my_op_class for type int using btree family my_op_family a -- This will not be pushed as user defined sort operator is not part of the -- extension yet. ---Testcase 263: +--Testcase 298: explain (verbose, costs off) select array_agg((fields->>'C 1')::int order by (fields->>'C 1')::int using operator(public.<^)) from ft2 where (fields->>'c2')::int = 6 and (fields->>'C 1')::int < 100 group by fields->>'c2'; +-- This should not be pushed either. +--Testcase 766: +explain (verbose, costs off) +select * from ft2 order by (fields->>'C 1')::int using operator(public.<^); + -- Update local stats on ft2 --ANALYZE ft2; -- Add into extension +--Testcase 299: alter extension influxdb_fdw add operator class my_op_class using btree; +--Testcase 300: alter extension influxdb_fdw add function my_op_cmp(a int, b int); +--Testcase 301: alter extension influxdb_fdw add operator family my_op_family using btree; +--Testcase 302: alter extension influxdb_fdw add operator public.<^(int, int); +--Testcase 303: alter extension influxdb_fdw add operator public.=^(int, int); +--Testcase 304: alter extension influxdb_fdw add operator public.>^(int, int); -- Now this will be pushed as sort operator is part of the extension. ---Testcase 264: +-- alter server loopback options (add fdw_tuple_cost '0.5'); +--Testcase 305: explain (verbose, costs off) select array_agg((fields->>'C 1')::int order by (fields->>'C 1')::int using operator(public.<^)) from ft2 where (fields->>'c2')::int = 6 and (fields->>'C 1')::int < 100 group by fields->>'c2'; ---Testcase 265: +--Testcase 306: select array_agg((fields->>'C 1')::int order by (fields->>'C 1')::int using operator(public.<^)) from ft2 where (fields->>'c2')::int = 6 and (fields->>'C 1')::int < 100 group by fields->>'c2'; +-- alter server loopback options (drop fdw_tuple_cost); + +-- This should be pushed too. +-- Influx not support user-defined operator +--Testcase 767: +explain (verbose, costs off) +select * from ft2 order by (fields->>'C 1')::int using operator(public.<^); -- Remove from extension +--Testcase 307: alter extension influxdb_fdw drop operator class my_op_class using btree; +--Testcase 308: alter extension influxdb_fdw drop function my_op_cmp(a int, b int); +--Testcase 309: alter extension influxdb_fdw drop operator family my_op_family using btree; +--Testcase 310: alter extension influxdb_fdw drop operator public.<^(int, int); +--Testcase 311: alter extension influxdb_fdw drop operator public.=^(int, int); +--Testcase 312: alter extension influxdb_fdw drop operator public.>^(int, int); -- This will not be pushed as sort operator is now removed from the extension. ---Testcase 266: +--Testcase 313: explain (verbose, costs off) select array_agg((fields->>'C 1')::int order by (fields->>'C 1')::int using operator(public.<^)) from ft2 where (fields->>'c2')::int = 6 and (fields->>'C 1')::int < 100 group by fields->>'c2'; -- Cleanup ---Testcase 267: +--Testcase 314: drop operator class my_op_class using btree; ---Testcase 268: +--Testcase 315: drop function my_op_cmp(a int, b int); ---Testcase 269: +--Testcase 316: drop operator family my_op_family using btree; ---Testcase 270: +--Testcase 317: drop operator public.>^(int, int); ---Testcase 271: +--Testcase 318: drop operator public.=^(int, int); ---Testcase 272: +--Testcase 319: drop operator public.<^(int, int); -- Input relation to aggregate push down hook is not safe to pushdown and thus -- the aggregate cannot be pushed down to foreign server. ---Testcase 273: +--Testcase 320: explain (verbose, costs off) select count(t1.c3) from ((SELECT fields->>'C 1' c1, fields->>'c2' c2, tags->>'c3' c3, fields->>'c4' c4, fields->>'c5' c5, fields->>'c6' c6, fields->>'c7' c7, fields->>'c8' c8 FROM ft2)) t1 left join ((SELECT fields->>'C 1' c1, fields->>'c2' c2, tags->>'c3' c3, fields->>'c4' c4, fields->>'c5' c5, fields->>'c6' c6, fields->>'c7' c7, fields->>'c8' c8 FROM ft2)) t2 on ((t1.c1)::int = random() * (t2.c2)::int); -- Subquery in FROM clause having aggregate ---Testcase 274: +--Testcase 321: explain (verbose, costs off) select count(*), x.b from ft1, (select (fields->>'c2')::int a, sum((fields->>'C 1')::int) b from ft1 group by fields->>'c2') x where (ft1.fields->>'c2')::int = x.a group by x.b order by 1, 2; ---Testcase 275: +--Testcase 322: select count(*), x.b from ft1, (select (fields->>'c2')::int a, sum((fields->>'C 1')::int) b from ft1 group by fields->>'c2') x where (ft1.fields->>'c2')::int = x.a group by x.b order by 1, 2; -- FULL join with IS NULL check in HAVING ---Testcase 276: +--Testcase 323: explain (verbose, costs off) select avg((t1.c1)::int), sum((t2.c1)::int) from (SELECT (fields->>'c1')::int c1, (fields->>'c2')::int c2, tags->>'c3' c3 FROM ft4 t1) t1 full join (SELECT (fields->>'c1')::int c1, (fields->>'c2')::int c2, tags->>'c3' c3 FROM ft5 t2) t2 on ((t1.c1)::int = (t2.c1)::int) group by t2.c1 having (avg((t1.c1)::int) is null and sum((t2.c1)::int) < 10) or sum((t2.c1)::int) is null order by 1 nulls last, 2; ---Testcase 277: +--Testcase 324: select avg((t1.c1)::int), sum((t2.c1)::int) from (SELECT (fields->>'c1')::int c1, (fields->>'c2')::int c2, tags->>'c3' c3 FROM ft4 t1) t1 full join (SELECT (fields->>'c1')::int c1, (fields->>'c2')::int c2, tags->>'c3' c3 FROM ft5 t2) t2 on ((t1.c1)::int = (t2.c1)::int) group by t2.c1 having (avg((t1.c1)::int) is null and sum((t2.c1)::int) < 10) or sum((t2.c1)::int) is null order by 1 nulls last, 2; -- Aggregate over FULL join needing to deparse the joining relations as -- subqueries. ---Testcase 278: +--Testcase 325: explain (verbose, costs off) select count(*), sum((t1.c1)::int), avg((t2.c1)::int) from (SELECT (fields->>'c1')::int c1 FROM ft4 t1 WHERE (fields->>'c1')::int between 50 and 60) t1 full join (SELECT (fields->>'c1')::int c1 FROM ft5 t2 WHERE (fields->>'c1')::int between 50 and 60) t2 on ((t1.c1)::int = (t2.c1)::int); ---Testcase 279: +--Testcase 326: select count(*), sum((t1.c1)::int), avg((t2.c1)::int) from (SELECT (fields->>'c1')::int c1 FROM ft4 t1 WHERE (fields->>'c1')::int between 50 and 60) t1 full join (SELECT (fields->>'c1')::int c1 FROM ft5 t2 WHERE (fields->>'c1')::int between 50 and 60) t2 on ((t1.c1)::int = (t2.c1)::int); -- ORDER BY expression is part of the target list but not pushed down to -- foreign server. ---Testcase 280: +--Testcase 327: explain (verbose, costs off) select sum((fields->>'c2')::int) * (random() <= 1)::int as sum from ft1 order by 1; ---Testcase 281: +--Testcase 328: select sum((fields->>'c2')::int) * (random() <= 1)::int as sum from ft1 order by 1; -- LATERAL join, with parameterization +--Testcase 329: set enable_hashagg to false; ---Testcase 282: +--Testcase 330: explain (verbose, costs off) select (fields->>'c2')::int c2, sum from "S 1"."T 1" t1, lateral (select sum((t2.fields->>'C 1')::int + (t1.fields->>'C 1')::int) sum from ft2 t2 group by t2.fields->>'C 1') qry where (t1.fields->>'c2')::int * 2 = qry.sum and (t1.fields->>'c2')::int < 3 and (t1.fields->>'C 1')::int < 100 order by 1; ---Testcase 283: +--Testcase 331: select (fields->>'c2')::int c2, sum from "S 1"."T 1" t1, lateral (select sum((t2.fields->>'C 1')::int + (t1.fields->>'C 1')::int) sum from ft2 t2 group by t2.fields->>'C 1') qry where (t1.fields->>'c2')::int * 2 = qry.sum and (t1.fields->>'c2')::int < 3 and (t1.fields->>'C 1')::int < 100 order by 1; +--Testcase 332: reset enable_hashagg; -- bug #15613: bad plan for foreign table scan with lateral reference ---Testcase 284: +--Testcase 333: EXPLAIN (VERBOSE, COSTS OFF) SELECT (ref_0.fields->>'c2')::int c2, subq_1.* FROM @@ -1211,7 +1403,7 @@ FROM WHERE (ref_0.fields->>'C 1')::int < 10 AND subq_1.c3 = '00001' ORDER BY (ref_0.fields->>'C 1')::int; ---Testcase 285: +--Testcase 334: SELECT (ref_0.fields->>'c2')::int c2, subq_1.* FROM "S 1"."T 1" AS ref_0, @@ -1225,58 +1417,58 @@ WHERE (ref_0.fields->>'C 1')::int < 10 AND subq_1.c3 = '00001' ORDER BY (ref_0.fields->>'C 1')::int; -- Check with placeHolderVars ---Testcase 286: +--Testcase 335: explain (verbose, costs off) select sum(q.a), count(q.b) from ft4 left join (select 13, avg((ft1.fields->>'C 1')::int), sum((ft2.fields->>'C 1')::int) from ft1 right join ft2 on ((ft1.fields->>'C 1')::int = (ft2.fields->>'C 1')::int)) q(a, b, c) on ((ft4.fields->>'c1')::int <= q.b); ---Testcase 287: +--Testcase 336: select sum(q.a), count(q.b) from ft4 left join (select 13, avg((ft1.fields->>'C 1')::int), sum((ft2.fields->>'C 1')::int) from ft1 right join ft2 on ((ft1.fields->>'C 1')::int = (ft2.fields->>'C 1')::int)) q(a, b, c) on ((ft4.fields->>'c1')::int <= q.b); -- Not supported cases -- Grouping sets ---Testcase 288: +--Testcase 337: explain (verbose, costs off) select (fields->>'c2')::int c2, sum((fields->>'C 1')::int) from ft1 where (fields->>'c2')::int < 3 group by rollup((fields->>'c2')::int) order by 1 nulls last; ---Testcase 289: +--Testcase 338: select (fields->>'c2')::int c2, sum((fields->>'C 1')::int) from ft1 where (fields->>'c2')::int < 3 group by rollup((fields->>'c2')::int) order by 1 nulls last; ---Testcase 290: +--Testcase 339: explain (verbose, costs off) select (fields->>'c2')::int c2, sum((fields->>'C 1')::int) from ft1 where (fields->>'c2')::int < 3 group by cube((fields->>'c2')::int) order by 1 nulls last; ---Testcase 291: +--Testcase 340: select (fields->>'c2')::int c2, sum((fields->>'C 1')::int) from ft1 where (fields->>'c2')::int < 3 group by cube((fields->>'c2')::int) order by 1 nulls last; ---Testcase 292: +--Testcase 341: explain (verbose, costs off) select (fields->>'c2')::int c2, fields->>'c6' c6, sum((fields->>'C 1')::int) from ft1 where (fields->>'c2')::int < 3 group by grouping sets(fields->>'c2', fields->>'c6') order by 1 nulls last, 2 nulls last; ---Testcase 293: +--Testcase 342: select (fields->>'c2')::int c2, fields->>'c6' c6, sum((fields->>'C 1')::int) from ft1 where (fields->>'c2')::int < 3 group by grouping sets(fields->>'c2', fields->>'c6') order by 1 nulls last, 2 nulls last; ---Testcase 294: +--Testcase 343: explain (verbose, costs off) select (fields->>'c2')::int c2, sum((fields->>'C 1')::int), grouping(fields->>'c2') from ft1 where (fields->>'c2')::int < 3 group by fields->>'c2' order by 1 nulls last; ---Testcase 295: +--Testcase 344: select (fields->>'c2')::int c2, sum((fields->>'C 1')::int), grouping(fields->>'c2') from ft1 where (fields->>'c2')::int < 3 group by fields->>'c2' order by 1 nulls last; -- DISTINCT itself is not pushed down, whereas underneath aggregate is pushed ---Testcase 296: +--Testcase 345: explain (verbose, costs off) select distinct sum((fields->>'C 1')::int)/1000 s from ft2 where (fields->>'c2')::int < 6 group by fields->>'c2' order by 1; ---Testcase 297: +--Testcase 346: select distinct sum((fields->>'C 1')::int)/1000 s from ft2 where (fields->>'c2')::int < 6 group by fields->>'c2' order by 1; -- WindowAgg ---Testcase 298: +--Testcase 347: explain (verbose, costs off) select (fields->>'c2')::int c2, sum((fields->>'c2')::int), count((fields->>'c2')::int) over (partition by (fields->>'c2')::int%2) from ft2 where (fields->>'c2')::int < 10 group by fields->>'c2' order by 1; ---Testcase 299: +--Testcase 348: select (fields->>'c2')::int c2, sum((fields->>'c2')::int), count((fields->>'c2')::int) over (partition by (fields->>'c2')::int%2) from ft2 where (fields->>'c2')::int < 10 group by fields->>'c2' order by 1; ---Testcase 300: +--Testcase 349: explain (verbose, costs off) select (fields->>'c2')::int c2, array_agg((fields->>'c2')::int) over (partition by (fields->>'c2')::int%2 order by (fields->>'c2')::int desc) from ft1 where (fields->>'c2')::int < 10 group by fields->>'c2' order by 1; ---Testcase 301: +--Testcase 350: select (fields->>'c2')::int c2, array_agg((fields->>'c2')::int) over (partition by (fields->>'c2')::int%2 order by (fields->>'c2')::int desc) from ft1 where (fields->>'c2')::int < 10 group by fields->>'c2' order by 1; ---Testcase 302: +--Testcase 351: explain (verbose, costs off) select (fields->>'c2')::int c2, array_agg((fields->>'c2')::int) over (partition by (fields->>'c2')::int%2 order by (fields->>'c2')::int range between current row and unbounded following) from ft1 where (fields->>'c2')::int < 10 group by fields->>'c2' order by 1; ---Testcase 303: +--Testcase 352: select (fields->>'c2')::int c2, array_agg((fields->>'c2')::int) over (partition by (fields->>'c2')::int%2 order by (fields->>'c2')::int range between current row and unbounded following) from ft1 where (fields->>'c2')::int < 10 group by fields->>'c2' order by 1; @@ -1284,97 +1476,99 @@ select (fields->>'c2')::int c2, array_agg((fields->>'c2')::int) over (partition -- parameterized queries -- =================================================================== -- simple join ---Testcase 304: +--Testcase 353: PREPARE st1(int, int) AS SELECT t1.tags->>'c3' c3, t2.tags->>'c3' c3 FROM ft1 t1, ft2 t2 WHERE (t1.fields->>'C 1')::int = $1 AND (t2.fields->>'C 1')::int = $2; ---Testcase 305: +--Testcase 354: EXPLAIN (VERBOSE, COSTS OFF) EXECUTE st1(1, 2); ---Testcase 306: +--Testcase 355: EXECUTE st1(1, 1); ---Testcase 307: +--Testcase 356: EXECUTE st1(101, 101); -- subquery using stable function (can't be sent to remote) ---Testcase 308: +--Testcase 357: PREPARE st2(int) AS SELECT * FROM ft1 t1 WHERE (t1.fields->>'C 1')::int < $2 AND t1.tags->>'c3' IN (SELECT tags->>'c3' FROM ft2 t2 WHERE (fields->>'C 1')::int > $1 AND date(time) = '1970-01-17'::date) ORDER BY (fields->>'C 1')::int; ---Testcase 309: +--Testcase 358: EXPLAIN (VERBOSE, COSTS OFF) EXECUTE st2(10, 20); ---Testcase 310: +--Testcase 359: EXECUTE st2(10, 20); ---Testcase 311: +--Testcase 360: EXECUTE st2(101, 121); -- subquery using immutable function (can be sent to remote) ---Testcase 312: +--Testcase 361: PREPARE st3(int) AS SELECT * FROM ft1 t1 WHERE (t1.fields->>'C 1')::int < $2 AND t1.tags->>'c3' IN (SELECT tags->>'c3' FROM ft2 t2 WHERE (fields->>'C 1')::int > $1 AND date(time) = '1970-01-17'::date) ORDER BY (fields->>'C 1')::int; ---Testcase 313: +--Testcase 362: EXPLAIN (VERBOSE, COSTS OFF) EXECUTE st3(10, 20); ---Testcase 314: +--Testcase 363: EXECUTE st3(10, 20); ---Testcase 315: +--Testcase 364: EXECUTE st3(20, 30); -- custom plan should be chosen initially ---Testcase 316: +--Testcase 365: PREPARE st4(int) AS SELECT * FROM ft1 t1 WHERE (t1.fields->>'C 1')::int = $1; ---Testcase 317: +--Testcase 366: EXPLAIN (VERBOSE, COSTS OFF) EXECUTE st4(1); ---Testcase 318: +--Testcase 367: EXPLAIN (VERBOSE, COSTS OFF) EXECUTE st4(1); ---Testcase 319: +--Testcase 368: EXPLAIN (VERBOSE, COSTS OFF) EXECUTE st4(1); ---Testcase 320: +--Testcase 369: EXPLAIN (VERBOSE, COSTS OFF) EXECUTE st4(1); ---Testcase 321: +--Testcase 370: EXPLAIN (VERBOSE, COSTS OFF) EXECUTE st4(1); -- once we try it enough times, should switch to generic plan ---Testcase 322: +--Testcase 371: EXPLAIN (VERBOSE, COSTS OFF) EXECUTE st4(1); -- value of $1 should not be sent to remote ---Testcase 323: +--Testcase 372: PREPARE st5(text,int) AS SELECT * FROM ft1 t1 WHERE fields->>'c8' = $1 and (fields->>'C 1')::int = $2; ---Testcase 324: +--Testcase 373: EXPLAIN (VERBOSE, COSTS OFF) EXECUTE st5('foo', 1); ---Testcase 325: +--Testcase 374: EXPLAIN (VERBOSE, COSTS OFF) EXECUTE st5('foo', 1); ---Testcase 326: +--Testcase 375: EXPLAIN (VERBOSE, COSTS OFF) EXECUTE st5('foo', 1); ---Testcase 327: +--Testcase 376: EXPLAIN (VERBOSE, COSTS OFF) EXECUTE st5('foo', 1); ---Testcase 328: +--Testcase 377: EXPLAIN (VERBOSE, COSTS OFF) EXECUTE st5('foo', 1); ---Testcase 329: +--Testcase 378: EXPLAIN (VERBOSE, COSTS OFF) EXECUTE st5('foo', 1); ---Testcase 330: +--Testcase 379: EXECUTE st5('foo', 1); -- altering FDW options requires replanning ---Testcase 331: +--Testcase 380: PREPARE st6 AS SELECT * FROM ft1 t1 WHERE (t1.fields->>'C 1')::int = (t1.fields->>'c2')::int; ---Testcase 332: +--Testcase 381: EXPLAIN (VERBOSE, COSTS OFF) EXECUTE st6; ---Testcase 333: +--Testcase 382: PREPARE st7 AS INSERT INTO ft1_nsc (c1,c2,c3) VALUES (1001,101,'foo'); ---Testcase 334: +--Testcase 383: EXPLAIN (VERBOSE, COSTS OFF) EXECUTE st7; ---Testcase 335: +--Testcase 384: INSERT INTO "S 1".s1t0 SELECT * FROM "S 1".s1t1; +--Testcase 385: ALTER FOREIGN TABLE ft1 OPTIONS (SET table 'T0'); ---Testcase 336: +--Testcase 386: EXPLAIN (VERBOSE, COSTS OFF) EXECUTE st6; ---Testcase 337: +--Testcase 387: EXECUTE st6; ---Testcase 338: +--Testcase 388: EXPLAIN (VERBOSE, COSTS OFF) EXECUTE st7; ---Testcase 339: +--Testcase 389: DELETE FROM "S 1".s1t0; +--Testcase 390: ALTER FOREIGN TABLE ft1 OPTIONS (SET table 'T1'); ---Testcase 340: +--Testcase 391: PREPARE st8 AS SELECT count(tags->>'c3') FROM ft1 t1 WHERE (t1.fields->>'C 1')::int === (t1.fields->>'c2')::int; ---Testcase 341: +--Testcase 392: EXPLAIN (VERBOSE, COSTS OFF) EXECUTE st8; -- Skip, influxdb_fdw does not support extensions -- ALTER SERVER loopback OPTIONS (DROP extensions); ---Testcase 342: +--Testcase 393: EXPLAIN (VERBOSE, COSTS OFF) EXECUTE st8; ---Testcase 343: +--Testcase 394: EXECUTE st8; -- ALTER SERVER loopback OPTIONS (ADD extensions 'influxdb_fdw'); @@ -1389,59 +1583,113 @@ DEALLOCATE st7; DEALLOCATE st8; -- System columns, except ctid and oid, should not be sent to remote ---Testcase 344: +--Testcase 395: EXPLAIN (VERBOSE, COSTS OFF) SELECT * FROM ft1 t1 WHERE t1.tableoid = 'pg_class'::regclass LIMIT 1; ---Testcase 345: +--Testcase 396: SELECT * FROM ft1 t1 WHERE t1.tableoid = 'ft1'::regclass ORDER BY (fields->>'C 1')::int LIMIT 1; ---Testcase 346: +--Testcase 397: EXPLAIN (VERBOSE, COSTS OFF) SELECT tableoid::regclass, * FROM ft1 t1 LIMIT 1; ---Testcase 347: +--Testcase 398: SELECT tableoid::regclass, * FROM ft1 t1 ORDER BY (fields->>'C 1')::int LIMIT 1; ---Testcase 348: +--Testcase 399: EXPLAIN (VERBOSE, COSTS OFF) SELECT * FROM ft1 t1 WHERE t1.ctid = '(0,2)'; ---Testcase 349: +--Testcase 400: SELECT * FROM ft1 t1 WHERE t1.ctid = '(0,2)'; ---Testcase 350: +--Testcase 401: EXPLAIN (VERBOSE, COSTS OFF) SELECT ctid, * FROM ft1 t1 LIMIT 1; ---Testcase 351: +--Testcase 402: SELECT ctid, * FROM ft1 t1 ORDER BY (fields->>'C 1')::int LIMIT 1; -- =================================================================== -- used in PL/pgSQL function -- =================================================================== ---Testcase 352: +--Testcase 403: CREATE OR REPLACE FUNCTION f_test(p_c1 int) RETURNS int AS $$ DECLARE v_c1 int; BEGIN ---Testcase 353: +--Testcase 404: SELECT fields->>'C 1' INTO v_c1 FROM ft1 WHERE (fields->>'C 1')::int = p_c1 LIMIT 1; PERFORM fields->>'C 1' FROM ft1 WHERE (fields->>'C 1')::int = p_c1 AND p_c1 = v_c1 LIMIT 1; RETURN v_c1; END; $$ LANGUAGE plpgsql; ---Testcase 354: +--Testcase 405: SELECT f_test(100); ---Testcase 355: +--Testcase 406: DROP FUNCTION f_test(int); +-- =================================================================== +-- REINDEX +-- =================================================================== +-- remote table is not created here +--Testcase 407: +CREATE FOREIGN TABLE reindex_foreign (fields jsonb OPTIONS(fields 'true')) SERVER influxdb_svr2 OPTIONS (table 'reindex_local', schemaless 'true'); +REINDEX TABLE reindex_foreign; -- error +REINDEX TABLE CONCURRENTLY reindex_foreign; -- error +--Testcase 408: +DROP FOREIGN TABLE reindex_foreign; +-- partitions and foreign tables +--Testcase 409: +CREATE TABLE reind_fdw_parent (c1 int) PARTITION BY RANGE (c1); +--Testcase 410: +CREATE TABLE reind_fdw_0_10 PARTITION OF reind_fdw_parent + FOR VALUES FROM (0) TO (10); +--Testcase 411: +CREATE FOREIGN TABLE reind_fdw_10_20 PARTITION OF reind_fdw_parent + FOR VALUES FROM (10) TO (20) + SERVER influxdb_svr OPTIONS (table 'reind_local_10_20'); +REINDEX TABLE reind_fdw_parent; -- ok +REINDEX TABLE CONCURRENTLY reind_fdw_parent; -- ok +--Testcase 412: +DROP TABLE reind_fdw_parent; + -- =================================================================== -- conversion error -- =================================================================== +--Testcase 413: --ALTER FOREIGN TABLE ft1 ALTER COLUMN c8 TYPE int; ---Testcase 356: ---SELECT * FROM ft1 WHERE c1 = 1; -- ERROR ---Testcase 357: ---SELECT ft1.c1, ft2.c2, ft1.c8 FROM ft1, ft2 WHERE ft1.c1 = ft2.c1 AND ft1.c1 = 1; -- ERROR ---Testcase 358: ---SELECT ft1.c1, ft2.c2, ft1 FROM ft1, ft2 WHERE ft1.c1 = ft2.c1 AND ft1.c1 = 1; -- ERROR ---Testcase 359: +--Testcase 414: +--SELECT * FROM ft1 ftx(x1,x2,x3,x4,x6,x7,x8) WHERE x1 = 1; -- ERROR +--Testcase 415: +--SELECT ftx.x1, ft2.c2, ftx.x8 FROM ft1 ftx(x1,x2,x3,x4,x6,x7,x8), ft2 +-- WHERE ftx.x1 = (ft2.fields->>'C 1')::int AND ftx.x1 = 1; -- ERROR +--Testcase 416: +--SELECT ftx.x1, ft2.c2, ftx FROM ft1 ftx(x1,x2,x3,x4,x6,x7,x8), ft2 +-- WHERE ftx.x1 = (ft2.fields->>'C 1')::int AND ftx.x1 = 1; -- ERROR +--Testcase 417: --SELECT sum(c2), array_agg(c8) FROM ft1 GROUP BY c8; -- ERROR ---ALTER FOREIGN TABLE ft1 ALTER COLUMN c8 TYPE text; +-- ANALYZE ft1; -- ERROR +--ALTER FOREIGN TABLE ft1 ALTER COLUMN c8 TYPE user_enum; + +-- =================================================================== +-- local type can be different from remote type in some cases, +-- in particular if similarly-named operators do equivalent things +-- =================================================================== +--Testcase 768: +EXPLAIN (VERBOSE, COSTS OFF) +SELECT * FROM ft1 WHERE (fields->>'c8')::text = 'foo' LIMIT 1; +--Testcase 769: +SELECT * FROM ft1 WHERE (fields->>'c8')::text = 'foo' LIMIT 1; +--Testcase 770: +EXPLAIN (VERBOSE, COSTS OFF) +SELECT * FROM ft1 WHERE 'foo' = (fields->>'c8')::text LIMIT 1; +--Testcase 771: +SELECT * FROM ft1 WHERE 'foo' = (fields->>'c8')::text LIMIT 1; +-- we declared c8 to be text locally, but it's still the same type on +-- the remote which will balk if we try to do anything incompatible +-- with that remote type +-- Can not create user define type in InfluxDB. +-- Type c8 of foreign table ft1 and remote table T1 are +-- match. These case below not error with influxdb_fdw. +--Testcase 772: +SELECT * FROM ft1 WHERE (fields->>'c8')::text LIKE 'foo' LIMIT 1; -- ERROR +--Testcase 773: +SELECT * FROM ft1 WHERE ((fields->>'c8')::text)::text LIKE 'foo' LIMIT 1; -- ERROR; cast not pushed down /* -- influxdb_fdw does not support transactions @@ -1467,33 +1715,33 @@ COMMIT; -- =================================================================== -- test handling of collations -- =================================================================== ---Testcase 360: +--Testcase 419: create foreign table loct3 (fields jsonb OPTIONS(fields 'true')) SERVER influxdb_svr OPTIONS (table 'loct3', schemaless 'true'); ---Testcase 361: +--Testcase 420: create foreign table ft3 (fields jsonb OPTIONS(fields 'true')) SERVER influxdb_svr OPTIONS (table 'loct3', schemaless 'true'); -- can be sent to remote ---Testcase 362: +--Testcase 421: explain (verbose, costs off) select * from ft3 where fields->>'f1' = 'foo'; ---Testcase 363: +--Testcase 422: explain (verbose, costs off) select * from ft3 where fields->>'f1' COLLATE "C" = 'foo'; ---Testcase 364: +--Testcase 423: explain (verbose, costs off) select * from ft3 where fields->>'f2' = 'foo'; ---Testcase 365: +--Testcase 424: explain (verbose, costs off) select * from ft3 where fields->>'f3' = 'foo'; ---Testcase 366: +--Testcase 425: explain (verbose, costs off) select * from ft3 f, loct3 l where f.fields->>'f3' = l.fields->>'f3' and l.fields->>'f1' = 'foo'; -- can't be sent to remote ---Testcase 367: +--Testcase 426: explain (verbose, costs off) select * from ft3 where fields->>'f1' COLLATE "POSIX" = 'foo'; ---Testcase 368: +--Testcase 427: explain (verbose, costs off) select * from ft3 where fields->>'f1' = 'foo' COLLATE "C"; ---Testcase 369: +--Testcase 428: explain (verbose, costs off) select * from ft3 where fields->>'f2' COLLATE "C" = 'foo'; ---Testcase 370: +--Testcase 429: explain (verbose, costs off) select * from ft3 where fields->>'f2' = 'foo' COLLATE "C"; ---Testcase 371: +--Testcase 430: explain (verbose, costs off) select * from ft3 f, loct3 l where f.fields->>'f3' = l.fields->>'f3' COLLATE "POSIX" and l.fields->>'f1' = 'foo'; @@ -1501,16 +1749,16 @@ explain (verbose, costs off) select * from ft3 f, loct3 l -- =================================================================== -- test writable foreign table stuff -- =================================================================== ---Testcase 372: +--Testcase 431: EXPLAIN (verbose, costs off) INSERT INTO ft2_nsc (c1,c2,c3) SELECT c1+1000,c2+100, c3 || c3 FROM ft2_nsc ORDER BY c1 LIMIT 20; ---Testcase 373: +--Testcase 432: INSERT INTO ft2_nsc (c1,c2,c3) SELECT c1+1000,c2+100, c3 || c3 FROM ft2_nsc ORDER BY c1 LIMIT 20; ---Testcase 374: +--Testcase 433: INSERT INTO ft2_nsc (c1,c2,c3) VALUES (1101,201,'aaa'), (1102,202,'bbb'), (1103,203,'ccc'); ---Testcase 375: +--Testcase 434: SELECT (fields->>'C 1')::int c1, (fields->>'c2')::int c2, tags->>'c3' c3, fields->>'c6' c6, fields->>'c7' c7, fields->>'c8' c8 FROM ft2 WHERE (fields->>'c2')::int > 200; ---Testcase 376: +--Testcase 435: INSERT INTO ft2_nsc (c1,c2,c3) VALUES (1104,204,'ddd'), (1105,205,'eee'); --EXPLAIN (verbose, costs off) --UPDATE ft2 SET c2 = c2 + 300, c3 = c3 || '_update3' WHERE c1 % 10 = 3; -- can be pushed down @@ -1523,44 +1771,44 @@ INSERT INTO ft2_nsc (c1,c2,c3) VALUES (1104,204,'ddd'), (1105,205,'eee'); -- FROM ft1 WHERE ft1.c1 = ft2.c2 AND ft1.c1 % 10 = 9; -- can be pushed down --UPDATE ft2 SET c2 = ft2.c2 + 500, c3 = ft2.c3 || '_update9', c7 = DEFAULT -- FROM ft1 WHERE ft1.c1 = ft2.c2 AND ft1.c1 % 10 = 9; ---Testcase 377: +--Testcase 436: EXPLAIN (verbose, costs off) DELETE FROM ft2_nsc WHERE c1 % 10 = 5; -- can be pushed down ---Testcase 378: +--Testcase 437: SELECT (fields->>'C 1')::int c1 FROM ft2 WHERE (fields->>'C 1')::int % 10 = 5 ORDER BY (fields->>'C 1')::int; ---Testcase 379: +--Testcase 438: DELETE FROM ft2_nsc WHERE c1 % 10 = 5; ---Testcase 380: +--Testcase 439: SELECT (fields->>'C 1')::int c1 FROM ft2 WHERE (fields->>'C 1')::int % 10 = 5; ---Testcase 381: +--Testcase 440: EXPLAIN (verbose, costs off) DELETE FROM ft2_nsc USING ft1_nsc WHERE ft1_nsc.c1 = ft2_nsc.c2 AND ft1_nsc.c1 % 10 = 2; ---Testcase 382: +--Testcase 441: DELETE FROM ft2_nsc USING ft1_nsc WHERE ft1_nsc.c1 = ft2_nsc.c2 AND ft1_nsc.c1 % 10 = 2; ---Testcase 383: +--Testcase 442: SELECT (fields->>'C 1')::int c1, (fields->>'c2')::int c2, tags->>'c3' c3 FROM ft2 ORDER BY (fields->>'C 1')::int; ---Testcase 384: +--Testcase 443: EXPLAIN (verbose, costs off) INSERT INTO ft2_nsc (c1,c2,c3) VALUES (1200,999,'foo'); ---Testcase 385: +--Testcase 444: INSERT INTO ft2_nsc (c1,c2,c3) VALUES (1200,999,'foo'); ---Testcase 386: +--Testcase 445: SELECT (fields->>'C 1')::int c1 FROM ft2 WHERE (fields->>'C 1')::int = 1200 AND (fields->>'c2')::int = 999; --EXPLAIN (verbose, costs off) --UPDATE ft2 SET c3 = 'bar' WHERE c1 = 1200 RETURNING tableoid::regclass; -- can be pushed down --UPDATE ft2 SET c3 = 'bar' WHERE c1 = 1200 RETURNING tableoid::regclass; ---Testcase 387: +--Testcase 446: EXPLAIN (verbose, costs off) DELETE FROM ft2_nsc WHERE c1 = 1200; ---Testcase 388: +--Testcase 447: SELECT (fields->>'C 1')::int c1 FROM ft2 WHERE (fields->>'C 1')::int = 1200; ---Testcase 389: +--Testcase 448: DELETE FROM ft2_nsc WHERE c1 = 1200; ---Testcase 390: +--Testcase 449: SELECT (fields->>'C 1')::int c1 FROM ft2 WHERE (fields->>'C 1')::int = 1200; -- Test UPDATE/DELETE with RETURNING on a three-table join ---Testcase 391: +--Testcase 450: INSERT INTO ft2_nsc (c1,c2,c3) SELECT id, id - 1200, to_char(id, 'FM00000') FROM generate_series(1201, 1300) id; --EXPLAIN (verbose, costs off) @@ -1572,24 +1820,24 @@ INSERT INTO ft2_nsc (c1,c2,c3) -- FROM ft4 INNER JOIN ft5 ON (ft4.c1 = ft5.c1) -- WHERE ft2.c1 > 1200 AND ft2.c2 = ft4.c1 -- RETURNING ft2, ft2.*, ft4, ft4.*; ---Testcase 392: +--Testcase 451: EXPLAIN (verbose, costs off) DELETE FROM ft2_nsc USING ft4_nsc LEFT JOIN ft5_nsc ON (ft4_nsc.c1 = ft5_nsc.c1) - WHERE ft2_nsc.c1 > 1200 AND ft2_nsc.c1 % 10 = 0 AND ft2_nsc.c2 = ft4_nsc.c1; -- can be pushed down ---Testcase 393: + WHERE ft2_nsc.c1 > 1200 AND ft2_nsc.c1 % 10 = 0 AND ft2_nsc.c2 = ft4_nsc.c1; -- can be pushed down +--Testcase 452: SELECT 100 FROM ft2, ft4 LEFT JOIN ft5 ON ((ft4.fields->>'c1')::int = (ft5.fields->>'c1')::int) WHERE (ft2.fields->>'C 1')::int > 1200 AND (ft2.fields->>'C 1')::int % 10 = 0 AND (ft2.fields->>'c2')::int = (ft4.fields->>'c1')::int; ---Testcase 394: +--Testcase 453: DELETE FROM ft2_nsc USING ft4_nsc LEFT JOIN ft5_nsc ON (ft4_nsc.c1 = ft5_nsc.c1) WHERE ft2_nsc.c1 > 1200 AND ft2_nsc.c1 % 10 = 0 AND ft2_nsc.c2 = ft4_nsc.c1; ---Testcase 395: +--Testcase 454: SELECT 100 FROM ft2, ft4 LEFT JOIN ft5 ON ((ft4.fields->>'c1')::int = (ft5.fields->>'c1')::int) WHERE (ft2.fields->>'C 1')::int > 1200 AND (ft2.fields->>'C 1')::int % 10 = 0 AND (ft2.fields->>'c2')::int = (ft4.fields->>'c1')::int; ---Testcase 396: +--Testcase 455: DELETE FROM ft2_nsc WHERE ft2_nsc.c1 > 1200; -- Test UPDATE with a MULTIEXPR sub-select @@ -1612,9 +1860,17 @@ DELETE FROM ft2_nsc WHERE ft2_nsc.c1 > 1200; -- WHERE targ--et.c1 = src.c1 --) WHERE c1 > 1100; +-- Test UPDATE involving a join that can be pushed down, +-- but a SET clause that can't be +-- EXPLAIN (VERBOSE, COSTS OFF) +-- UPDATE ft2 d SET c2 = CASE WHEN random() >= 0 THEN d.c2 ELSE 0 END +-- FROM ft2 AS t WHERE d.c1 = t.c1 AND d.c1 > 1000; +-- UPDATE ft2 d SET c2 = CASE WHEN random() >= 0 THEN d.c2 ELSE 0 END +-- FROM ft2 AS t WHERE d.c1 = t.c1 AND d.c1 > 1000; + -- Test UPDATE/DELETE with WHERE or JOIN/ON conditions containing -- user-defined operators/functions ---Testcase 397: +--Testcase 456: INSERT INTO ft2_nsc (c1,c2,c3) SELECT id, id % 10, to_char(id, 'FM00000') FROM generate_series(2001, 2010) id; --EXPLAIN (verbose, costs off) @@ -1629,58 +1885,59 @@ INSERT INTO ft2_nsc (c1,c2,c3) -- FROM ft4 INNER JOIN ft5 ON (ft4.c1 = ft5.c1) -- WHERE ft2.c1 > 2000 AND ft2.c2 === ft4.c1 -- RETURNING ft2.*, ft4.*, ft5.*; ---Testcase 398: +--Testcase 457: EXPLAIN (verbose, costs off) DELETE FROM ft2_nsc USING ft4_nsc INNER JOIN ft5_nsc ON (ft4_nsc.c1 === ft5_nsc.c1) WHERE ft2_nsc.c1 > 2000 AND ft2_nsc.c2 = ft4_nsc.c1; -- can't be pushed down ---Testcase 399: +--Testcase 458: SELECT (ft2.fields->>'C 1')::int c1, (ft2.fields->>'c2')::int c2, ft2.tags->>'c3' c3 FROM ft2, ft4 INNER JOIN ft5 ON ((ft4.fields->>'c1')::int === (ft5.fields->>'c1')::int) WHERE (ft2.fields->>'C 1')::int > 2000 AND (ft2.fields->>'c2')::int = (ft4.fields->>'c1')::int; ---Testcase 400: +--Testcase 459: DELETE FROM ft2_nsc USING ft4_nsc INNER JOIN ft5_nsc ON (ft4_nsc.c1 === ft5_nsc.c1) - WHERE ft2_nsc.c1 > 2000 AND ft2_nsc.c2 = ft4_nsc.c1; ---Testcase 401: + WHERE ft2_nsc.c1 > 2000 AND ft2_nsc.c2 = ft4_nsc.c1; +--Testcase 460: SELECT (ft2.fields->>'C 1')::int c1, (ft2.fields->>'c2')::int c2, ft2.tags->>'c3' c3 FROM ft2, ft4 INNER JOIN ft5 ON ((ft4.fields->>'c1')::int === (ft5.fields->>'c1')::int) WHERE (ft2.fields->>'C 1')::int > 2000 AND (ft2.fields->>'c2')::int = (ft4.fields->>'c1')::int; ---Testcase 402: +--Testcase 461: DELETE FROM ft2_nsc WHERE ft2_nsc.c1 > 2000; -- Test that trigger on remote table works as expected ---Testcase 403: +--Testcase 462: CREATE OR REPLACE FUNCTION "S 1".F_BRTRIG() RETURNS trigger AS $$ BEGIN NEW.c3 = NEW.c3 || '_trig_update'; RETURN NEW; END; $$ LANGUAGE plpgsql; ---Testcase 404: +--Testcase 463: CREATE TRIGGER t1_br_insert BEFORE INSERT OR UPDATE ON "S 1".s1t1 FOR EACH ROW EXECUTE PROCEDURE "S 1".F_BRTRIG(); ---Testcase 405: +--Testcase 464: INSERT INTO ft2_nsc (c1,c2,c3) VALUES (1208, 818, 'fff'); ---Testcase 406: +--Testcase 465: SELECT (fields->>'C 1')::int c1, (fields->>'c2')::int c2, tags->>'c3' c3, fields->>'c6' c6, fields->>'c7' c7, fields->>'c8' c8 FROM ft2 WHERE (fields->>'C 1')::int = 1208; ---Testcase 407: +--Testcase 466: INSERT INTO ft2_nsc (c1,c2,c3,c6) VALUES (1218, 818, 'ggg', '(--;'); ---Testcase 408: +--Testcase 467: SELECT (fields->>'C 1')::int c1, (fields->>'c2')::int c2, tags->>'c3' c3, fields->>'c6' c6, fields->>'c7' c7, fields->>'c8' c8 FROM ft2 WHERE (fields->>'C 1')::int = 1218; --UPDATE ft2 SET c2 = c2 + 600 WHERE c1 % 10 = 8 AND c1 < 1200 RETURNING *; -- Test errors thrown on remote side during update +--Testcase 468: ALTER TABLE "S 1"."T 1" ADD CONSTRAINT c2positive CHECK ((fields->>'c2')::int >= 0); -- influxdb_fdw does not support key, ON CONFLICT --INSERT INTO ft1(c1, c2) VALUES(11, 12); -- duplicate key ---Testcase 409: +--Testcase 469: INSERT INTO ft1_nsc(c1, c2) VALUES(11, 12) ON CONFLICT DO NOTHING; -- works ---Testcase 410: +--Testcase 470: INSERT INTO ft1_nsc(c1, c2) VALUES(11, 12) ON CONFLICT (c1, c2) DO NOTHING; -- unsupported ---Testcase 411: +--Testcase 471: INSERT INTO ft1_nsc(c1, c2) VALUES(11, 12) ON CONFLICT (c1, c2) DO UPDATE SET c3 = 'ffg'; -- unsupported --INSERT INTO ft1(c1, c2) VALUES(1111, -2); -- c2positive --UPDATE ft1 SET c2 = -c2 WHERE c1 = 1; -- c2positive @@ -1721,19 +1978,19 @@ select c2, count(*) from "S 1"."T 1" where c2 < 500 group by 1 order by 1; -- Above DMLs add data with c6 as NULL in ft1, so test ORDER BY NULLS LAST and NULLs -- FIRST behavior here. -- ORDER BY DESC NULLS LAST options ---Testcase 412: +--Testcase 472: EXPLAIN (VERBOSE, COSTS OFF) SELECT * FROM ft1 ORDER BY fields->>'c6' DESC NULLS LAST, (fields->>'C 1')::int OFFSET 795 LIMIT 10; ---Testcase 413: +--Testcase 473: SELECT (fields->>'C 1')::int c1, (fields->>'c2')::int c2, tags->>'c3' c3, fields->>'c6' c6, fields->>'c7' c7, fields->>'c8' c8 FROM ft1 ORDER BY fields->>'c6' DESC NULLS LAST, (fields->>'C 1')::int OFFSET 795 LIMIT 10; -- ORDER BY DESC NULLS FIRST options ---Testcase 414: +--Testcase 474: EXPLAIN (VERBOSE, COSTS OFF) SELECT * FROM ft1 ORDER BY fields->>'c6' DESC NULLS FIRST, (fields->>'C 1')::int OFFSET 15 LIMIT 10; ---Testcase 415: +--Testcase 475: SELECT (fields->>'C 1')::int c1, (fields->>'c2')::int c2, tags->>'c3' c3, fields->>'c6' c6, fields->>'c7' c7, fields->>'c8' c8 FROM ft1 ORDER BY fields->>'c6' DESC NULLS FIRST, (fields->>'C 1')::int OFFSET 15 LIMIT 10; -- ORDER BY ASC NULLS FIRST options ---Testcase 416: +--Testcase 476: EXPLAIN (VERBOSE, COSTS OFF) SELECT * FROM ft1 ORDER BY fields->>'c6' ASC NULLS FIRST, (fields->>'C 1')::int OFFSET 15 LIMIT 10; ---Testcase 417: +--Testcase 477: SELECT (fields->>'C 1')::int c1, (fields->>'c2')::int c2, tags->>'c3' c3, fields->>'c6' c6, fields->>'c7' c7, fields->>'c8' c8 FROM ft1 ORDER BY fields->>'c6' ASC NULLS FIRST, (fields->>'C 1')::int OFFSET 15 LIMIT 10; -- =================================================================== @@ -1741,39 +1998,47 @@ SELECT (fields->>'C 1')::int c1, (fields->>'c2')::int c2, tags->>'c3' c3, fields -- =================================================================== -- Consistent check constraints provide consistent results +--Testcase 478: ALTER FOREIGN TABLE ft1 ADD CONSTRAINT ft1_c2positive CHECK ((fields->>'c2')::int >= 0); ---Testcase 418: +--Testcase 479: EXPLAIN (VERBOSE, COSTS OFF) SELECT count(*) FROM ft1 WHERE (fields->>'c2')::int < 0; -- InfluxDB return null value because it does not have any record. ---Testcase 419: +--Testcase 480: SELECT count(*) FROM ft1 WHERE (fields->>'c2')::int < 0; +--Testcase 481: SET constraint_exclusion = 'on'; ---Testcase 420: +--Testcase 482: EXPLAIN (VERBOSE, COSTS OFF) SELECT count(*) FROM ft1 WHERE (fields->>'c2')::int < 0; ---Testcase 421: +--Testcase 483: SELECT count(*) FROM ft1 WHERE (fields->>'c2')::int < 0; +--Testcase 484: RESET constraint_exclusion; -- check constraint is enforced on the remote side, not locally -- INSERT INTO ft1(c1, c2) VALUES(1111, -2); -- c2positive -- UPDATE ft1 SET c2 = -c2 WHERE c1 = 1; -- c2positive +--Testcase 485: ALTER FOREIGN TABLE ft1 DROP CONSTRAINT ft1_c2positive; -- But inconsistent check constraints provide inconsistent results +--Testcase 486: ALTER FOREIGN TABLE ft1 ADD CONSTRAINT ft1_c2negative CHECK ((fields->>'c2')::int < 0); ---Testcase 422: +--Testcase 487: EXPLAIN (VERBOSE, COSTS OFF) SELECT count(*) FROM ft1 WHERE (fields->>'c2')::int >= 0; ---Testcase 423: +--Testcase 488: SELECT count(*) FROM ft1 WHERE (fields->>'c2')::int >= 0; +--Testcase 489: SET constraint_exclusion = 'on'; ---Testcase 424: +--Testcase 490: EXPLAIN (VERBOSE, COSTS OFF) SELECT count(*) FROM ft1 WHERE (fields->>'c2')::int >= 0; ---Testcase 425: +--Testcase 491: SELECT count(*) FROM ft1 WHERE (fields->>'c2')::int >= 0; +--Testcase 492: RESET constraint_exclusion; -- local check constraint is not actually enforced ---Testcase 426: +--Testcase 493: INSERT INTO ft1_nsc(c1, c2) VALUES(1111, 2); -- UPDATE ft1 SET c2 = c2 + 1 WHERE c1 = 1; +--Testcase 494: ALTER FOREIGN TABLE ft1 DROP CONSTRAINT ft1_c2negative; -- influxdb_fdw does not support this feature @@ -1781,36 +2046,38 @@ ALTER FOREIGN TABLE ft1 DROP CONSTRAINT ft1_c2negative; -- test WITH CHECK OPTION constraints -- =================================================================== ---Testcase 427: +--Testcase 495: CREATE FUNCTION row_before_insupd_trigfunc() RETURNS trigger AS $$BEGIN NEW.a := NEW.a + 10; RETURN NEW; END$$ LANGUAGE plpgsql; ---Testcase 428: +--Testcase 496: CREATE FOREIGN TABLE base_tbl (fields jsonb OPTIONS(fields 'true')) SERVER influxdb_svr OPTIONS (table 'base_tbl', schemaless 'true'); --ALTER FOREIGN TABLE base_tbl SET (autovacuum_enabled = 'false'); +--Testcase 797: CREATE FOREIGN TABLE base_tbl_nsc (a int, b int) SERVER influxdb_svr OPTIONS (table 'base_tbl'); ---Testcase 429: +--Testcase 497: CREATE TRIGGER row_before_insupd_trigger BEFORE INSERT OR UPDATE ON base_tbl_nsc FOR EACH ROW EXECUTE PROCEDURE row_before_insupd_trigfunc(); ---Testcase 430: +--Testcase 498: CREATE FOREIGN TABLE foreign_tbl (fields jsonb OPTIONS(fields 'true')) SERVER influxdb_svr OPTIONS (table 'base_tbl', schemaless 'true'); ---Testcase 431: +--Testcase 499: CREATE VIEW rw_view AS SELECT * FROM base_tbl WHERE (fields->>'a')::int < (fields->>'b')::int WITH CHECK OPTION; +--Testcase 798: CREATE VIEW rw_view_nsc AS SELECT * FROM base_tbl_nsc WHERE a < b WITH CHECK OPTION; ---Testcase 432: +--Testcase 500: \d+ rw_view ---Testcase 433: +--Testcase 501: EXPLAIN (VERBOSE, COSTS OFF) INSERT INTO rw_view_nsc VALUES (0, 5); ---Testcase 434: +--Testcase 502: INSERT INTO rw_view_nsc VALUES (0, 5); -- should fail ---Testcase 435: +--Testcase 503: EXPLAIN (VERBOSE, COSTS OFF) INSERT INTO rw_view_nsc VALUES (0, 15); ---Testcase 436: +--Testcase 504: INSERT INTO rw_view_nsc VALUES (0, 15); -- ok ---Testcase 437: +--Testcase 505: SELECT * FROM foreign_tbl; --EXPLAIN (VERBOSE, COSTS OFF) @@ -1821,48 +2088,66 @@ SELECT * FROM foreign_tbl; --UPDATE rw_view SET b = b + 15; -- ok --SELECT * FROM foreign_tbl; ---Testcase 438: +-- We don't allow batch insert when there are any WCO constraints +ALTER SERVER influxdb_svr OPTIONS (ADD batch_size '10'); +--Testcase 869: +EXPLAIN (VERBOSE, COSTS OFF) +INSERT INTO rw_view VALUES (0, 15), (0, 5); +--Testcase 870: +INSERT INTO rw_view VALUES (0, 15), (0, 5); -- should fail +--Testcase 871: +SELECT * FROM foreign_tbl; +ALTER SERVER influxdb_svr OPTIONS (DROP batch_size); + +--Testcase 506: DELETE FROM foreign_tbl; +--Testcase 799: DROP FOREIGN TABLE foreign_tbl CASCADE; ---Testcase 439: +--Testcase 507: DROP TRIGGER row_before_insupd_trigger ON base_tbl_nsc; ---Testcase 440: +--Testcase 508: DROP FOREIGN TABLE base_tbl CASCADE; +--Testcase 800: DROP FOREIGN TABLE base_tbl_nsc CASCADE; - -- influxdb_fdw does not support partitions -- test WCO for partitions ---Testcase 441: +--Testcase 509: CREATE FOREIGN TABLE child_tbl (fields jsonb OPTIONS(fields 'true')) SERVER influxdb_svr OPTIONS (table 'child_tbl', schemaless 'true'); --ALTER FOREIGN TABLE child_tbl SET (autovacuum_enabled = 'false'); +--Testcase 801: CREATE FOREIGN TABLE child_tbl_nsc (a int, b int) SERVER influxdb_svr OPTIONS (table 'child_tbl'); ---Testcase 442: +--Testcase 510: CREATE TRIGGER row_before_insupd_trigger BEFORE INSERT OR UPDATE ON child_tbl_nsc FOR EACH ROW EXECUTE PROCEDURE row_before_insupd_trigfunc(); ---Testcase 443: +--Testcase 511: CREATE FOREIGN TABLE foreign_tbl (fields jsonb OPTIONS(fields 'true')) SERVER influxdb_svr OPTIONS (table 'child_tbl', schemaless 'true'); - ---Testcase 444: +--Testcase 512: CREATE TABLE parent_tbl (a int, b int) PARTITION BY RANGE(a); +--Testcase 513: +ALTER TABLE parent_tbl ATTACH PARTITION child_tbl_nsc FOR VALUES FROM (0) TO (100); +-- Detach and re-attach once, to stress the concurrent detach case. +--Testcase 774: +ALTER TABLE parent_tbl DETACH PARTITION child_tbl_nsc CONCURRENTLY; +--Testcase 775: ALTER TABLE parent_tbl ATTACH PARTITION child_tbl_nsc FOR VALUES FROM (0) TO (100); ---Testcase 445: +--Testcase 514: CREATE VIEW rw_view AS SELECT * FROM parent_tbl WHERE a < b WITH CHECK OPTION; ---Testcase 446: +--Testcase 515: \d+ rw_view ---Testcase 447: +--Testcase 516: EXPLAIN (VERBOSE, COSTS OFF) INSERT INTO rw_view VALUES (0, 5); ---Testcase 448: +--Testcase 517: INSERT INTO rw_view VALUES (0, 5); -- should fail ---Testcase 449: +--Testcase 518: EXPLAIN (VERBOSE, COSTS OFF) INSERT INTO rw_view VALUES (0, 15); ---Testcase 450: +--Testcase 519: INSERT INTO rw_view VALUES (0, 15); -- ok ---Testcase 451: +--Testcase 520: SELECT * FROM foreign_tbl; --EXPLAIN (VERBOSE, COSTS OFF) @@ -1873,77 +2158,175 @@ SELECT * FROM foreign_tbl; --UPDATE rw_view SET b = b + 15; -- ok --SELECT * FROM foreign_tbl; ---Testcase 452: +-- We don't allow batch insert when there are any WCO constraints +ALTER SERVER influxdb_svr OPTIONS (ADD batch_size '10'); +--Testcase 872: +EXPLAIN (VERBOSE, COSTS OFF) +INSERT INTO rw_view VALUES (0, 15), (0, 5); +--Testcase 873: +INSERT INTO rw_view VALUES (0, 15), (0, 5); -- should fail +--Testcase 874: +SELECT * FROM foreign_tbl; +ALTER SERVER influxdb_svr OPTIONS (DROP batch_size); + +--Testcase 521: DROP FOREIGN TABLE foreign_tbl CASCADE; ---Testcase 453: +--Testcase 522: DROP TRIGGER row_before_insupd_trigger ON child_tbl_nsc; ---Testcase 454: +--Testcase 523: DROP FOREIGN TABLE child_tbl CASCADE; +--Testcase 802: DROP FOREIGN TABLE child_tbl_nsc CASCADE; ---Testcase 455: +--Testcase 524: DROP TABLE parent_tbl CASCADE; ---Testcase 456: +--Testcase 525: DROP FUNCTION row_before_insupd_trigfunc; +-- Try a more complex permutation of WCO where there are multiple levels of +-- partitioned tables with columns not all in the same order +CREATE TABLE parent_tbl (a int, b text, c numeric) PARTITION BY RANGE(a); +CREATE TABLE sub_parent (c numeric, a int, b text) PARTITION BY RANGE(a); +ALTER TABLE parent_tbl ATTACH PARTITION sub_parent FOR VALUES FROM (1) TO (10); +CREATE TABLE child_local (b text, c numeric, a int); +CREATE FOREIGN TABLE child_foreign_nsc (b text, c numeric, a int) + SERVER influxdb_svr OPTIONS (table 'child_local'); +CREATE FOREIGN TABLE child_foreign (fields jsonb OPTIONS(fields 'true')) SERVER influxdb_svr OPTIONS (table 'child_local', schemaless 'true'); +ALTER TABLE sub_parent ATTACH PARTITION child_foreign_nsc FOR VALUES FROM (1) TO (10); +CREATE VIEW rw_view AS SELECT * FROM parent_tbl WHERE a < 5 WITH CHECK OPTION; + +-- Not support partition insert +INSERT INTO parent_tbl (a) VALUES(1),(5); +-- UPDATE is not supported +EXPLAIN (VERBOSE, COSTS OFF) +UPDATE rw_view SET b = 'text', c = 123.456; +-- UPDATE is not supported +UPDATE rw_view SET b = 'text', c = 123.456; +SELECT * FROM parent_tbl ORDER BY a; + +DROP VIEW rw_view; +DROP TABLE child_local; +DROP FOREIGN TABLE child_foreign; +DROP FOREIGN TABLE child_foreign_nsc; +DROP TABLE sub_parent; +DROP TABLE parent_tbl; + -- =================================================================== -- test serial columns (ie, sequence-based defaults) -- =================================================================== ---Testcase 457: +--Testcase 526: create foreign table loc1 (fields jsonb OPTIONS(fields 'true')) SERVER influxdb_svr OPTIONS (table 'loc1', schemaless 'true'); --alter foreign table loc1 set (autovacuum_enabled = 'false'); +--Testcase 803: create foreign table loc1_nsc (f1 serial, f2 text) server influxdb_svr options(table 'loc1'); ---Testcase 458: +--Testcase 527: create foreign table rem1 (fields jsonb OPTIONS(fields 'true')) SERVER influxdb_svr OPTIONS (table 'loc1', schemaless 'true'); +--Testcase 804: create foreign table rem1_nsc (f1 serial, f2 text) server influxdb_svr options(table 'loc1'); ---Testcase 459: +--Testcase 528: select pg_catalog.setval('rem1_nsc_f1_seq', 10, false); ---Testcase 460: +--Testcase 529: insert into loc1_nsc(f2) values('hi'); ---Testcase 461: +--Testcase 530: insert into rem1_nsc(f2) values('hi remote'); ---Testcase 462: +--Testcase 531: insert into loc1_nsc(f2) values('bye'); ---Testcase 463: +--Testcase 532: insert into rem1_nsc(f2) values('bye remote'); ---Testcase 464: +--Testcase 533: select * from loc1; ---Testcase 465: +--Testcase 534: select * from rem1; -- =================================================================== -- test generated columns -- =================================================================== ---Testcase 466: +--Testcase 535: create foreign table gloc1 (fields jsonb OPTIONS(fields 'true')) SERVER influxdb_svr OPTIONS (table 'gloc1', schemaless 'true'); --alter foreign table gloc1 set (autovacuum_enabled = 'false'); -create foreign table gloc1_nsc (a int, b int generated always as (a * 2) stored) +--Testcase 805: +create foreign table gloc1_nsc ( + a int, + b int generated always as (a * 2) stored) server influxdb_svr options(table 'gloc1'); ---Testcase 467: +--Testcase 536: create foreign table grem1 (fields jsonb OPTIONS(fields 'true')) SERVER influxdb_svr OPTIONS (table 'gloc1', schemaless 'true'); +--Testcase 806: create foreign table grem1_nsc ( a int, b int generated always as (a * 2) stored) server influxdb_svr options(table 'gloc1'); ---Testcase 468: +--Testcase 537: +explain (verbose, costs off) insert into grem1_nsc (a) values (1), (22); +--Testcase 765: +insert into grem1_nsc (a) values (1), (22); +--explain (verbose, costs off) --update grem1 set a = 22 where a = 2; ---Testcase 469: +--update grem1 set a = 22 where a = 2; +--Testcase 538: +select * from gloc1; +--Testcase 539: +select * from grem1; +--Testcase 766: +delete from grem1_nsc; + +/* +-- InfluxDB FDW does not support partition insert +-- test copy from +copy grem1 from stdin; +1 +2 +\. select * from gloc1; ---Testcase 470: select * from grem1; +delete from grem1; +*/ --- Clean up: +-- test batch insert +--Testcase 767: +alter server influxdb_svr options (add batch_size '10'); +--Testcase 768: +explain (verbose, costs off) +insert into grem1_nsc (a) values (1), (2); +--Testcase 769: +insert into grem1_nsc (a) values (1), (2); +--Testcase 770: +select * from gloc1; +--Testcase 771: +select * from grem1; +--Testcase 772: delete from grem1_nsc; +-- batch insert with foreign partitions. +-- This schema uses two partitions, one local and one remote with a modulo +-- to loop across all of them in batches. +create table tab_batch_local (id int, data text); +insert into tab_batch_local select i, 'test'|| i from generate_series(1, 45) i; +create table tab_batch_sharded (id int, data text) partition by hash(id); +create table tab_batch_sharded_p0 partition of tab_batch_sharded + for values with (modulus 2, remainder 0); +create table tab_batch_sharded_p1_remote (id int, data text); +create foreign table tab_batch_sharded_p1 partition of tab_batch_sharded + for values with (modulus 2, remainder 1) + server influxdb_svr options (table 'tab_batch_sharded_p1_remote'); +-- Not support partition insert +insert into tab_batch_sharded select * from tab_batch_local; +select count(*) from tab_batch_sharded; +drop table tab_batch_local; +drop table tab_batch_sharded; +drop foreign table tab_batch_sharded_p1_remote; +drop foreign table tab_batch_sharded_p1; +--Testcase 773: +alter server influxdb_svr options (drop batch_size); -- =================================================================== -- test local triggers -- =================================================================== -- Trigger functions "borrowed" from triggers regress test. ---Testcase 471: +--Testcase 540: CREATE FUNCTION trigger_func() RETURNS trigger LANGUAGE plpgsql AS $$ BEGIN RAISE NOTICE 'trigger_func(%) called: action = %, when = %, level = %', @@ -1951,14 +2334,14 @@ BEGIN RETURN NULL; END;$$; ---Testcase 472: -CREATE TRIGGER trig_stmt_before BEFORE DELETE OR INSERT OR UPDATE ON rem1_nsc +--Testcase 541: +CREATE TRIGGER trig_stmt_before BEFORE DELETE OR INSERT OR UPDATE OR TRUNCATE ON rem1_nsc FOR EACH STATEMENT EXECUTE PROCEDURE trigger_func(); ---Testcase 473: -CREATE TRIGGER trig_stmt_after AFTER DELETE OR INSERT OR UPDATE ON rem1_nsc +--Testcase 542: +CREATE TRIGGER trig_stmt_after AFTER DELETE OR INSERT OR UPDATE OR TRUNCATE ON rem1_nsc FOR EACH STATEMENT EXECUTE PROCEDURE trigger_func(); ---Testcase 474: +--Testcase 543: CREATE OR REPLACE FUNCTION trigger_data() RETURNS trigger LANGUAGE plpgsql AS $$ @@ -1999,71 +2382,72 @@ end; $$; -- Test basic functionality ---Testcase 475: +--Testcase 544: CREATE TRIGGER trig_row_before BEFORE INSERT OR UPDATE OR DELETE ON rem1_nsc FOR EACH ROW EXECUTE PROCEDURE trigger_data(23,'skidoo'); ---Testcase 476: +--Testcase 545: CREATE TRIGGER trig_row_after AFTER INSERT OR UPDATE OR DELETE ON rem1_nsc FOR EACH ROW EXECUTE PROCEDURE trigger_data(23,'skidoo'); ---Testcase 477: +--Testcase 546: delete from rem1_nsc; ---Testcase 478: +--Testcase 547: insert into rem1_nsc values(1,'insert'); --update rem1 set f2 = 'update' where f1 = 1; --update rem1 set f2 = f2 || f2; +--truncate rem1; -- cleanup ---Testcase 479: +--Testcase 548: DROP TRIGGER trig_row_before ON rem1_nsc; ---Testcase 480: +--Testcase 549: DROP TRIGGER trig_row_after ON rem1_nsc; ---Testcase 481: +--Testcase 550: DROP TRIGGER trig_stmt_before ON rem1_nsc; ---Testcase 482: +--Testcase 551: DROP TRIGGER trig_stmt_after ON rem1_nsc; ---Testcase 483: +--Testcase 552: DELETE from rem1_nsc; -- Test multiple AFTER ROW triggers on a foreign table ---Testcase 484: +--Testcase 553: CREATE TRIGGER trig_row_after1 AFTER INSERT OR UPDATE OR DELETE ON rem1_nsc FOR EACH ROW EXECUTE PROCEDURE trigger_data(23,'skidoo'); ---Testcase 485: +--Testcase 554: CREATE TRIGGER trig_row_after2 AFTER INSERT OR UPDATE OR DELETE ON rem1_nsc FOR EACH ROW EXECUTE PROCEDURE trigger_data(23,'skidoo'); ---Testcase 486: +--Testcase 555: insert into rem1_nsc values(1,'insert'); --update rem1 set f2 = 'update' where f1 = 1; --update rem1 set f2 = f2 || f2; ---Testcase 487: +--Testcase 556: delete from rem1_nsc; -- cleanup ---Testcase 488: +--Testcase 557: DROP TRIGGER trig_row_after1 ON rem1_nsc; ---Testcase 489: +--Testcase 558: DROP TRIGGER trig_row_after2 ON rem1_nsc; -- Test WHEN conditions ---Testcase 490: +--Testcase 559: CREATE TRIGGER trig_row_before_insupd BEFORE INSERT OR UPDATE ON rem1_nsc FOR EACH ROW WHEN (NEW.f2 like '%update%') EXECUTE PROCEDURE trigger_data(23,'skidoo'); ---Testcase 491: +--Testcase 560: CREATE TRIGGER trig_row_after_insupd AFTER INSERT OR UPDATE ON rem1_nsc FOR EACH ROW @@ -2071,23 +2455,23 @@ WHEN (NEW.f2 like '%update%') EXECUTE PROCEDURE trigger_data(23,'skidoo'); -- Insert or update not matching: nothing happens ---Testcase 492: +--Testcase 561: INSERT INTO rem1_nsc values(1, 'insert'); --UPDATE rem1 set f2 = 'test'; -- Insert or update matching: triggers are fired ---Testcase 493: +--Testcase 562: INSERT INTO rem1_nsc values(2, 'update'); --UPDATE rem1 set f2 = 'update update' where f1 = '2'; ---Testcase 494: +--Testcase 563: CREATE TRIGGER trig_row_before_delete BEFORE DELETE ON rem1_nsc FOR EACH ROW WHEN (OLD.f2 like '%update%') EXECUTE PROCEDURE trigger_data(23,'skidoo'); ---Testcase 495: +--Testcase 564: CREATE TRIGGER trig_row_after_delete AFTER DELETE ON rem1_nsc FOR EACH ROW @@ -2095,23 +2479,23 @@ WHEN (OLD.f2 like '%update%') EXECUTE PROCEDURE trigger_data(23,'skidoo'); -- Trigger is fired for f1=2, not for f1=1 ---Testcase 496: +--Testcase 565: DELETE FROM rem1_nsc; -- cleanup ---Testcase 497: +--Testcase 566: DROP TRIGGER trig_row_before_insupd ON rem1_nsc; ---Testcase 498: +--Testcase 567: DROP TRIGGER trig_row_after_insupd ON rem1_nsc; ---Testcase 499: +--Testcase 568: DROP TRIGGER trig_row_before_delete ON rem1_nsc; ---Testcase 500: +--Testcase 569: DROP TRIGGER trig_row_after_delete ON rem1_nsc; -- Test various RETURN statements in BEFORE triggers. ---Testcase 501: +--Testcase 570: CREATE FUNCTION trig_row_before_insupdate() RETURNS TRIGGER AS $$ BEGIN NEW.f2 := NEW.f2 || ' triggered !'; @@ -2119,21 +2503,21 @@ CREATE FUNCTION trig_row_before_insupdate() RETURNS TRIGGER AS $$ END $$ language plpgsql; ---Testcase 502: +--Testcase 571: CREATE TRIGGER trig_row_before_insupd BEFORE INSERT OR UPDATE ON rem1_nsc FOR EACH ROW EXECUTE PROCEDURE trig_row_before_insupdate(); -- The new values should have 'triggered' appended ---Testcase 503: +--Testcase 572: INSERT INTO rem1_nsc values(1, 'insert'); ---Testcase 504: +--Testcase 573: SELECT * from loc1; ---Testcase 505: +--Testcase 574: INSERT INTO rem1_nsc values(2, 'insert'); ---Testcase 506: +--Testcase 575: SELECT fields->>'f2' f2 FROM rem1 WHERE (fields->>'f1')::int = 2; ---Testcase 507: +--Testcase 576: SELECT * from loc1; --UPDATE rem1 set f2 = ''; --SELECT * from loc1; @@ -2145,358 +2529,401 @@ SELECT * from loc1; --UPDATE rem1 set f1 = 10; --SELECT * from loc1; ---Testcase 508: +--Testcase 577: DELETE FROM rem1_nsc; -- Add a second trigger, to check that the changes are propagated correctly -- from trigger to trigger ---Testcase 509: +--Testcase 578: CREATE TRIGGER trig_row_before_insupd2 BEFORE INSERT OR UPDATE ON rem1_nsc FOR EACH ROW EXECUTE PROCEDURE trig_row_before_insupdate(); ---Testcase 510: +--Testcase 579: INSERT INTO rem1_nsc values(1, 'insert'); ---Testcase 511: +--Testcase 580: SELECT * from loc1; ---Testcase 512: +--Testcase 581: INSERT INTO rem1_nsc values(2, 'insert'); ---Testcase 513: +--Testcase 582: SELECT fields->>'f2' f2 FROM rem1 WHERE (fields->>'f1')::int = 2; ---Testcase 514: +--Testcase 583: SELECT * from loc1; --UPDATE rem1 set f2 = ''; --SELECT * from loc1; --UPDATE rem1 set f2 = 'skidoo' RETURNING f2; --SELECT * from loc1; ---Testcase 515: +--Testcase 584: DROP TRIGGER trig_row_before_insupd ON rem1_nsc; ---Testcase 516: +--Testcase 585: DROP TRIGGER trig_row_before_insupd2 ON rem1_nsc; ---Testcase 517: +--Testcase 586: DELETE from rem1_nsc; ---Testcase 518: +--Testcase 587: INSERT INTO rem1_nsc VALUES (1, 'test'); -- Test with a trigger returning NULL ---Testcase 519: +--Testcase 588: CREATE FUNCTION trig_null() RETURNS TRIGGER AS $$ BEGIN RETURN NULL; END $$ language plpgsql; ---Testcase 520: +--Testcase 589: CREATE TRIGGER trig_null BEFORE INSERT OR UPDATE OR DELETE ON rem1_nsc FOR EACH ROW EXECUTE PROCEDURE trig_null(); -- Nothing should have changed. ---Testcase 521: +--Testcase 590: INSERT INTO rem1_nsc VALUES (2, 'test2'); ---Testcase 522: +--Testcase 591: SELECT * from loc1; --UPDATE rem1 SET f2 = 'test2'; --SELECT * from loc1; ---Testcase 523: +--Testcase 592: DELETE from rem1_nsc; ---Testcase 524: +--Testcase 593: SELECT * from loc1; ---Testcase 525: +--Testcase 594: DROP TRIGGER trig_null ON rem1_nsc; ---Testcase 526: +--Testcase 595: DELETE from rem1_nsc; -- Test a combination of local and remote triggers ---Testcase 527: +--Testcase 596: CREATE TRIGGER trig_row_before BEFORE INSERT OR UPDATE OR DELETE ON rem1_nsc FOR EACH ROW EXECUTE PROCEDURE trigger_data(23,'skidoo'); ---Testcase 528: +--Testcase 597: CREATE TRIGGER trig_row_after AFTER INSERT OR UPDATE OR DELETE ON rem1_nsc FOR EACH ROW EXECUTE PROCEDURE trigger_data(23,'skidoo'); ---Testcase 529: +--Testcase 598: CREATE TRIGGER trig_local_before BEFORE INSERT OR UPDATE ON loc1_nsc FOR EACH ROW EXECUTE PROCEDURE trig_row_before_insupdate(); ---Testcase 530: +--Testcase 599: INSERT INTO rem1_nsc(f2) VALUES ('test'); --UPDATE rem1 SET f2 = 'testo'; -- Test returning a system attribute ---Testcase 531: +--Testcase 600: INSERT INTO rem1_nsc(f2) VALUES ('test'); ---Testcase 532: +--Testcase 601: SELECT * FROM rem1 WHERE fields->>'f2' = 'test'; -- cleanup ---Testcase 533: +--Testcase 602: DROP TRIGGER trig_row_before ON rem1_nsc; ---Testcase 534: +--Testcase 603: DROP TRIGGER trig_row_after ON rem1_nsc; ---Testcase 535: +--Testcase 604: DROP TRIGGER trig_local_before ON loc1_nsc; -- Test direct foreign table modification functionality +--Testcase 774: +EXPLAIN (verbose, costs off) +DELETE FROM rem1_nsc; -- can be pushed down +--Testcase 775: +EXPLAIN (verbose, costs off) +DELETE FROM rem1_nsc WHERE false; -- currently can't be pushed down -- Test with statement-level triggers ---Testcase 536: +--Testcase 605: CREATE TRIGGER trig_stmt_before BEFORE DELETE OR INSERT OR UPDATE ON rem1_nsc FOR EACH STATEMENT EXECUTE PROCEDURE trigger_func(); --EXPLAIN (verbose, costs off) --UPDATE rem1 set f2 = ''; -- can be pushed down ---Testcase 537: +--Testcase 606: EXPLAIN (verbose, costs off) DELETE FROM rem1_nsc; -- can be pushed down ---Testcase 538: +--Testcase 607: DROP TRIGGER trig_stmt_before ON rem1_nsc; ---Testcase 539: +--Testcase 608: CREATE TRIGGER trig_stmt_after AFTER DELETE OR INSERT OR UPDATE ON rem1_nsc FOR EACH STATEMENT EXECUTE PROCEDURE trigger_func(); --EXPLAIN (verbose, costs off) --UPDATE rem1 set f2 = ''; -- can be pushed down ---Testcase 540: +--Testcase 609: EXPLAIN (verbose, costs off) DELETE FROM rem1_nsc; -- can be pushed down ---Testcase 541: +--Testcase 610: DROP TRIGGER trig_stmt_after ON rem1_nsc; -- Test with row-level ON INSERT triggers ---Testcase 542: +--Testcase 611: CREATE TRIGGER trig_row_before_insert BEFORE INSERT ON rem1_nsc FOR EACH ROW EXECUTE PROCEDURE trigger_data(23,'skidoo'); --EXPLAIN (verbose, costs off) --UPDATE rem1 set f2 = ''; -- can be pushed down ---Testcase 543: +--Testcase 612: EXPLAIN (verbose, costs off) DELETE FROM rem1_nsc; -- can be pushed down ---Testcase 544: +--Testcase 613: DROP TRIGGER trig_row_before_insert ON rem1_nsc; ---Testcase 545: +--Testcase 614: CREATE TRIGGER trig_row_after_insert AFTER INSERT ON rem1_nsc FOR EACH ROW EXECUTE PROCEDURE trigger_data(23,'skidoo'); --EXPLAIN (verbose, costs off) --UPDATE rem1 set f2 = ''; -- can be pushed down ---Testcase 546: +--Testcase 615: EXPLAIN (verbose, costs off) DELETE FROM rem1_nsc; -- can be pushed down ---Testcase 547: +--Testcase 616: DROP TRIGGER trig_row_after_insert ON rem1_nsc; -- Test with row-level ON UPDATE triggers ---Testcase 548: +--Testcase 617: CREATE TRIGGER trig_row_before_update BEFORE UPDATE ON rem1_nsc FOR EACH ROW EXECUTE PROCEDURE trigger_data(23,'skidoo'); --EXPLAIN (verbose, costs off) --UPDATE rem1 set f2 = ''; -- can't be pushed down ---Testcase 549: +--Testcase 618: EXPLAIN (verbose, costs off) DELETE FROM rem1_nsc; -- can be pushed down ---Testcase 550: +--Testcase 619: DROP TRIGGER trig_row_before_update ON rem1_nsc; ---Testcase 551: +--Testcase 620: CREATE TRIGGER trig_row_after_update AFTER UPDATE ON rem1_nsc FOR EACH ROW EXECUTE PROCEDURE trigger_data(23,'skidoo'); --EXPLAIN (verbose, costs off) --UPDATE rem1 set f2 = ''; -- can't be pushed down ---Testcase 552: +--Testcase 621: EXPLAIN (verbose, costs off) DELETE FROM rem1_nsc; -- can be pushed down ---Testcase 553: +--Testcase 622: DROP TRIGGER trig_row_after_update ON rem1_nsc; -- Test with row-level ON DELETE triggers ---Testcase 554: +--Testcase 623: CREATE TRIGGER trig_row_before_delete BEFORE DELETE ON rem1_nsc FOR EACH ROW EXECUTE PROCEDURE trigger_data(23,'skidoo'); --EXPLAIN (verbose, costs off) --UPDATE rem1 set f2 = ''; -- can be pushed down ---Testcase 555: +--Testcase 624: EXPLAIN (verbose, costs off) DELETE FROM rem1_nsc; -- can't be pushed down ---Testcase 556: +--Testcase 625: DROP TRIGGER trig_row_before_delete ON rem1_nsc; ---Testcase 557: +--Testcase 626: CREATE TRIGGER trig_row_after_delete AFTER DELETE ON rem1_nsc FOR EACH ROW EXECUTE PROCEDURE trigger_data(23,'skidoo'); --EXPLAIN (verbose, costs off) --UPDATE rem1 set f2 = ''; -- can be pushed down ---Testcase 558: +--Testcase 627: EXPLAIN (verbose, costs off) DELETE FROM rem1_nsc; -- can't be pushed down ---Testcase 559: +--Testcase 628: DROP TRIGGER trig_row_after_delete ON rem1_nsc; -- =================================================================== -- test inheritance features -- =================================================================== ---Testcase 560: +--Testcase 629: CREATE TABLE a (aa TEXT); --CREATE TABLE loct (aa TEXT, bb TEXT); +--Testcase 630: ALTER TABLE a SET (autovacuum_enabled = 'false'); --ALTER TABLE loct SET (autovacuum_enabled = 'false'); -- Because influxdb_fdw does not support UPDATE, to test locally -- we create local table. ---Testcase 561: +--Testcase 631: CREATE TABLE b (bb TEXT) INHERITS (a); ---Testcase 562: +--Testcase 632: INSERT INTO a(aa) VALUES('aaa'); ---Testcase 563: +--Testcase 633: INSERT INTO a(aa) VALUES('aaaa'); ---Testcase 564: +--Testcase 634: INSERT INTO a(aa) VALUES('aaaaa'); ---Testcase 565: +--Testcase 635: INSERT INTO b(aa) VALUES('bbb'); ---Testcase 566: +--Testcase 636: INSERT INTO b(aa) VALUES('bbbb'); ---Testcase 567: +--Testcase 637: INSERT INTO b(aa) VALUES('bbbbb'); ---Testcase 568: +--Testcase 638: SELECT tableoid::regclass, * FROM a; ---Testcase 569: +--Testcase 639: SELECT tableoid::regclass, * FROM b; ---Testcase 570: +--Testcase 640: SELECT tableoid::regclass, * FROM ONLY a; ---Testcase 571: +--Testcase 641: UPDATE a SET aa = 'zzzzzz' WHERE aa LIKE 'aaaa%'; ---Testcase 572: +--Testcase 642: SELECT tableoid::regclass, * FROM a; ---Testcase 573: +--Testcase 643: SELECT tableoid::regclass, * FROM b; ---Testcase 574: +--Testcase 644: SELECT tableoid::regclass, * FROM ONLY a; ---Testcase 575: +--Testcase 645: UPDATE b SET aa = 'new'; ---Testcase 576: +--Testcase 646: SELECT tableoid::regclass, * FROM a; ---Testcase 577: +--Testcase 647: SELECT tableoid::regclass, * FROM b; ---Testcase 578: +--Testcase 648: SELECT tableoid::regclass, * FROM ONLY a; ---Testcase 579: +--Testcase 649: UPDATE a SET aa = 'newtoo'; ---Testcase 580: +--Testcase 650: SELECT tableoid::regclass, * FROM a; ---Testcase 581: +--Testcase 651: SELECT tableoid::regclass, * FROM b; ---Testcase 582: +--Testcase 652: SELECT tableoid::regclass, * FROM ONLY a; ---Testcase 583: +--Testcase 653: DELETE FROM a; ---Testcase 584: +--Testcase 654: SELECT tableoid::regclass, * FROM a; ---Testcase 585: +--Testcase 655: SELECT tableoid::regclass, * FROM b; ---Testcase 586: +--Testcase 656: SELECT tableoid::regclass, * FROM ONLY a; ---Testcase 587: +--Testcase 657: DROP TABLE a CASCADE; --DROP TABLE loct; -- Check SELECT FOR UPDATE/SHARE with an inherited source table ---Testcase 588: +--Testcase 658: create foreign table loct1 (fields jsonb OPTIONS(fields 'true')) SERVER influxdb_svr OPTIONS (table 'loct1', schemaless 'true'); +--Testcase 807: create foreign table loct1_nsc (f1 int, f2 int, f3 int) server influxdb_svr options(table 'loct1'); ---Testcase 589: +--Testcase 659: create foreign table loct2 (fields jsonb OPTIONS(fields 'true')) SERVER influxdb_svr OPTIONS (table 'loct2', schemaless 'true'); +--Testcase 808: create foreign table loct2_nsc (f1 int, f2 int, f3 int) server influxdb_svr options(table 'loct2'); + --alter table loct1 set (autovacuum_enabled = 'false'); --alter table loct2 set (autovacuum_enabled = 'false'); ---Testcase 590: +--Testcase 660: create foreign table foo (fields jsonb OPTIONS(fields 'true')) SERVER influxdb_svr OPTIONS (table 'foo', schemaless 'true'); +--Testcase 809: create foreign table foo_nsc (f1 int, f2 int) server influxdb_svr options (table 'foo'); ---Testcase 591: +--Testcase 661: create foreign table foo2 (fields jsonb OPTIONS(fields 'true')) inherits (foo) server influxdb_svr options (table 'loct1', schemaless 'true'); +--Testcase 810: create foreign table foo2_nsc (f3 int) inherits (foo_nsc) server influxdb_svr options (table 'loct1'); ---Testcase 592: +--Testcase 662: create foreign table bar (fields jsonb OPTIONS(fields 'true')) server influxdb_svr options (table 'bar', schemaless 'true'); +--Testcase 811: create foreign table bar_nsc (f1 int, f2 int) server influxdb_svr options (table 'bar'); ---Testcase 593: +--Testcase 663: create foreign table bar2 (fields jsonb OPTIONS(fields 'true')) inherits (bar) server influxdb_svr options (table 'loct2', schemaless 'true'); +--Testcase 812: create foreign table bar2_nsc (f3 int) inherits (bar_nsc) server influxdb_svr options (table 'loct2'); --alter table foo set (autovacuum_enabled = 'false'); --alter table bar set (autovacuum_enabled = 'false'); ---Testcase 594: +--Testcase 664: insert into foo_nsc values(1,1); ---Testcase 595: +--Testcase 665: insert into foo_nsc values(3,3); ---Testcase 596: +--Testcase 666: insert into foo2_nsc values(2,2,2); ---Testcase 597: +--Testcase 667: insert into foo2_nsc values(4,4,4); ---Testcase 598: +--Testcase 668: insert into bar_nsc values(1,11); ---Testcase 599: +--Testcase 669: insert into bar_nsc values(2,22); ---Testcase 600: +--Testcase 670: insert into bar_nsc values(6,66); ---Testcase 601: +--Testcase 671: insert into bar2_nsc values(3,33,33); ---Testcase 602: +--Testcase 672: insert into bar2_nsc values(4,44,44); ---Testcase 603: +--Testcase 673: insert into bar2_nsc values(7,77,77); ---Testcase 604: +--Testcase 674: explain (verbose, costs off) select * from bar where fields->>'f1' in (select fields->>'f1' from foo); ---Testcase 605: +--Testcase 675: select * from bar where fields->>'f1' in (select fields->>'f1' from foo); ---Testcase 606: +--Testcase 676: explain (verbose, costs off) select * from bar where fields->>'f1' in (select fields->>'f1' from foo); ---Testcase 607: +--Testcase 677: select * from bar where fields->>'f1' in (select fields->>'f1' from foo); +-- Now check SELECT FOR UPDATE/SHARE with an inherited source table, +-- where the parent is itself a foreign table +--Testcase 678: +create foreign table foo2child (fields jsonb OPTIONS(fields 'true')) inherits (foo2) + server influxdb_svr options (table 'loct4', schemaless 'true'); + +--Testcase 679: +explain (verbose, costs off) +select * from bar where fields->>'f1' in (select fields->>'f1' from foo2) for share; +--Testcase 680: +select * from bar where fields->>'f1' in (select fields->>'f1' from foo2) for share; + +--Testcase 681: +drop foreign table foo2child; + +-- And with a local child relation of the foreign table parent +--Testcase 682: +create foreign table foo2child (fields jsonb OPTIONS(fields 'true')) inherits (foo2) + server influxdb_svr options (table 'foo2child', schemaless 'true'); + +--Testcase 683: +explain (verbose, costs off) +select * from bar where fields->>'f1' in (select fields->>'f1' from foo2) for share; +--Testcase 684: +select * from bar where fields->>'f1' in (select fields->>'f1' from foo2) for share; + +--Testcase 685: +drop foreign table foo2child; + /* -- influxdb_fdw does not support UPDATE -- Check UPDATE with inherited target and an inherited source table @@ -2642,6 +3069,10 @@ select tableoid::regclass, * FROM remp2; delete from itrtest; +-- MERGE ought to fail cleanly +merge into itrtest using (select 1, 'foo') as source on (true) + when matched then do nothing; + create unique index loct1_idx on loct1 (a); -- DO NOTHING without an inference specification is supported @@ -2808,6 +3239,28 @@ copy remp1 from stdin; select tableoid::regclass, * FROM remp1; +delete from ctrtest; + +-- Test copy tuple routing with the batch_size option enabled +alter server loopback options (add batch_size '2'); + +copy ctrtest from stdin; +1 foo +1 bar +2 baz +2 qux +1 test1 +2 test2 +\. + +select tableoid::regclass, * FROM ctrtest; +select tableoid::regclass, * FROM remp1; +select tableoid::regclass, * FROM remp2; + +delete from ctrtest; + +alter server loopback options (drop batch_size); + drop table ctrtest; drop table loct1; drop table loct2; @@ -2946,63 +3399,254 @@ drop trigger rem2_trig_row_before on rem2; drop trigger rem2_trig_row_after on rem2; drop trigger loc2_trig_row_before_insert on loc2; -delete from rem2; +delete from rem2; + +-- test COPY FROM with foreign table created in the same transaction +create table loc3 (f1 int, f2 text); +begin; +create foreign table rem3 (f1 int, f2 text) + server loopback options(table_name 'loc3'); +copy rem3 from stdin; +1 foo +2 bar +\. +commit; +select * from rem3; +drop foreign table rem3; +drop table loc3; + +-- Test COPY FROM with the batch_size option enabled +alter server loopback options (add batch_size '2'); + +-- Test basic functionality +copy rem2 from stdin; +1 foo +2 bar +3 baz +\. +select * from rem2; + +delete from rem2; + +-- Test check constraints +alter table loc2 add constraint loc2_f1positive check (f1 >= 0); +alter foreign table rem2 add constraint rem2_f1positive check (f1 >= 0); + +-- check constraint is enforced on the remote side, not locally +copy rem2 from stdin; +1 foo +2 bar +3 baz +\. +copy rem2 from stdin; -- ERROR +-1 xyzzy +\. +select * from rem2; + +alter foreign table rem2 drop constraint rem2_f1positive; +alter table loc2 drop constraint loc2_f1positive; + +delete from rem2; + +-- Test remote triggers +create trigger trig_row_before_insert before insert on loc2 + for each row execute procedure trig_row_before_insupdate(); + +-- The new values are concatenated with ' triggered !' +copy rem2 from stdin; +1 foo +2 bar +3 baz +\. +select * from rem2; + +drop trigger trig_row_before_insert on loc2; + +delete from rem2; + +create trigger trig_null before insert on loc2 + for each row execute procedure trig_null(); + +-- Nothing happens +copy rem2 from stdin; +1 foo +2 bar +3 baz +\. +select * from rem2; + +drop trigger trig_null on loc2; + +delete from rem2; + +-- Check with zero-column foreign table; batch insert will be disabled +alter table loc2 drop column f1; +alter table loc2 drop column f2; +alter table rem2 drop column f1; +alter table rem2 drop column f2; +copy rem2 from stdin; + + + +\. +select * from rem2; + +delete from rem2; + +alter server loopback options (drop batch_size); +*/ + +/* +-- Skip test because influxdb does not support TRUNCATE +-- =================================================================== +-- test for TRUNCATE +-- =================================================================== +CREATE TABLE tru_rtable0 (id int primary key); +CREATE FOREIGN TABLE tru_ftable (id int) + SERVER loopback OPTIONS (table_name 'tru_rtable0'); +INSERT INTO tru_rtable0 (SELECT x FROM generate_series(1,10) x); + +CREATE TABLE tru_ptable (id int) PARTITION BY HASH(id); +CREATE TABLE tru_ptable__p0 PARTITION OF tru_ptable + FOR VALUES WITH (MODULUS 2, REMAINDER 0); +CREATE TABLE tru_rtable1 (id int primary key); +CREATE FOREIGN TABLE tru_ftable__p1 PARTITION OF tru_ptable + FOR VALUES WITH (MODULUS 2, REMAINDER 1) + SERVER loopback OPTIONS (table_name 'tru_rtable1'); +INSERT INTO tru_ptable (SELECT x FROM generate_series(11,20) x); + +CREATE TABLE tru_pk_table(id int primary key); +CREATE TABLE tru_fk_table(fkey int references tru_pk_table(id)); +INSERT INTO tru_pk_table (SELECT x FROM generate_series(1,10) x); +INSERT INTO tru_fk_table (SELECT x % 10 + 1 FROM generate_series(5,25) x); +CREATE FOREIGN TABLE tru_pk_ftable (id int) + SERVER loopback OPTIONS (table_name 'tru_pk_table'); + +CREATE TABLE tru_rtable_parent (id int); +CREATE TABLE tru_rtable_child (id int); +CREATE FOREIGN TABLE tru_ftable_parent (id int) + SERVER loopback OPTIONS (table_name 'tru_rtable_parent'); +CREATE FOREIGN TABLE tru_ftable_child () INHERITS (tru_ftable_parent) + SERVER loopback OPTIONS (table_name 'tru_rtable_child'); +INSERT INTO tru_rtable_parent (SELECT x FROM generate_series(1,8) x); +INSERT INTO tru_rtable_child (SELECT x FROM generate_series(10, 18) x); + +-- normal truncate +SELECT sum(id) FROM tru_ftable; -- 55 +TRUNCATE tru_ftable; +SELECT count(*) FROM tru_rtable0; -- 0 +SELECT count(*) FROM tru_ftable; -- 0 + +-- 'truncatable' option +ALTER SERVER loopback OPTIONS (ADD truncatable 'false'); +TRUNCATE tru_ftable; -- error +ALTER FOREIGN TABLE tru_ftable OPTIONS (ADD truncatable 'true'); +TRUNCATE tru_ftable; -- accepted +ALTER FOREIGN TABLE tru_ftable OPTIONS (SET truncatable 'false'); +TRUNCATE tru_ftable; -- error +ALTER SERVER loopback OPTIONS (DROP truncatable); +ALTER FOREIGN TABLE tru_ftable OPTIONS (SET truncatable 'false'); +TRUNCATE tru_ftable; -- error +ALTER FOREIGN TABLE tru_ftable OPTIONS (SET truncatable 'true'); +TRUNCATE tru_ftable; -- accepted + +-- partitioned table with both local and foreign tables as partitions +SELECT sum(id) FROM tru_ptable; -- 155 +TRUNCATE tru_ptable; +SELECT count(*) FROM tru_ptable; -- 0 +SELECT count(*) FROM tru_ptable__p0; -- 0 +SELECT count(*) FROM tru_ftable__p1; -- 0 +SELECT count(*) FROM tru_rtable1; -- 0 + +-- 'CASCADE' option +SELECT sum(id) FROM tru_pk_ftable; -- 55 +TRUNCATE tru_pk_ftable; -- failed by FK reference +TRUNCATE tru_pk_ftable CASCADE; +SELECT count(*) FROM tru_pk_ftable; -- 0 +SELECT count(*) FROM tru_fk_table; -- also truncated,0 + +-- truncate two tables at a command +INSERT INTO tru_ftable (SELECT x FROM generate_series(1,8) x); +INSERT INTO tru_pk_ftable (SELECT x FROM generate_series(3,10) x); +SELECT count(*) from tru_ftable; -- 8 +SELECT count(*) from tru_pk_ftable; -- 8 +TRUNCATE tru_ftable, tru_pk_ftable CASCADE; +SELECT count(*) from tru_ftable; -- 0 +SELECT count(*) from tru_pk_ftable; -- 0 + +-- truncate with ONLY clause +-- Since ONLY is specified, the table tru_ftable_child that inherits +-- tru_ftable_parent locally is not truncated. +TRUNCATE ONLY tru_ftable_parent; +SELECT sum(id) FROM tru_ftable_parent; -- 126 +TRUNCATE tru_ftable_parent; +SELECT count(*) FROM tru_ftable_parent; -- 0 + +-- in case when remote table has inherited children +CREATE TABLE tru_rtable0_child () INHERITS (tru_rtable0); +INSERT INTO tru_rtable0 (SELECT x FROM generate_series(5,9) x); +INSERT INTO tru_rtable0_child (SELECT x FROM generate_series(10,14) x); +SELECT sum(id) FROM tru_ftable; -- 95 + +-- Both parent and child tables in the foreign server are truncated +-- even though ONLY is specified because ONLY has no effect +-- when truncating a foreign table. +TRUNCATE ONLY tru_ftable; +SELECT count(*) FROM tru_ftable; -- 0 + +INSERT INTO tru_rtable0 (SELECT x FROM generate_series(21,25) x); +INSERT INTO tru_rtable0_child (SELECT x FROM generate_series(26,30) x); +SELECT sum(id) FROM tru_ftable; -- 255 +TRUNCATE tru_ftable; -- truncate both of parent and child +SELECT count(*) FROM tru_ftable; -- 0 --- test COPY FROM with foreign table created in the same transaction -create table loc3 (f1 int, f2 text); -begin; -create foreign table rem3 (f1 int, f2 text) - server loopback options(table_name 'loc3'); -copy rem3 from stdin; -1 foo -2 bar -\. -commit; -select * from rem3; -drop foreign table rem3; -drop table loc3; +-- cleanup +DROP FOREIGN TABLE tru_ftable_parent, tru_ftable_child, tru_pk_ftable,tru_ftable__p1,tru_ftable; +DROP TABLE tru_rtable0, tru_rtable1, tru_ptable, tru_ptable__p0, tru_pk_table, tru_fk_table, +tru_rtable_parent,tru_rtable_child, tru_rtable0_child; */ + -- =================================================================== -- test IMPORT FOREIGN SCHEMA -- =================================================================== ---Testcase 608: +--Testcase 686: CREATE SCHEMA import_influx1; IMPORT FOREIGN SCHEMA public FROM SERVER influxdb_svr INTO import_influx1 OPTIONS (schemaless 'true'); ---Testcase 609: +--Testcase 687: \det+ import_influx1.* ---Testcase 610: +--Testcase 688: \d import_influx1.* -- Options ---Testcase 611: +--Testcase 689: CREATE SCHEMA import_influx2; IMPORT FOREIGN SCHEMA public FROM SERVER influxdb_svr INTO import_influx2 OPTIONS (import_default 'true', schemaless 'true'); ---Testcase 612: +--Testcase 690: \det+ import_influx2.* ---Testcase 613: +--Testcase 691: \d import_influx2.* ---Testcase 614: +--Testcase 692: CREATE SCHEMA import_influx3; IMPORT FOREIGN SCHEMA public FROM SERVER influxdb_svr INTO import_influx3 OPTIONS (import_collate 'false', import_not_null 'false', schemaless 'true'); ---Testcase 615: +--Testcase 693: \det+ import_influx3.* ---Testcase 616: +--Testcase 694: \d import_influx3.* -- Check LIMIT TO and EXCEPT ---Testcase 617: +--Testcase 695: CREATE SCHEMA import_influx4; IMPORT FOREIGN SCHEMA public LIMIT TO ("T1", loct, nonesuch) FROM SERVER influxdb_svr INTO import_influx4 OPTIONS (schemaless 'true'); ---Testcase 618: +--Testcase 696: \det+ import_influx4.* IMPORT FOREIGN SCHEMA public EXCEPT ("T1", loct, nonesuch) FROM SERVER influxdb_svr INTO import_influx4 OPTIONS (schemaless 'true'); ---Testcase 619: +--Testcase 697: \det+ import_influx4.* -- Assorted error cases @@ -3214,22 +3858,24 @@ $d$; CREATE USER MAPPING FOR public SERVER loopback_nopw; CREATE USER MAPPING FOR CURRENT_USER SERVER loopback_nopw; -CREATE FOREIGN TABLE ft1_nopw ( +CREATE FOREIGN TABLE pg_temp.ft1_nopw ( c1 int NOT NULL, c2 int NOT NULL, c3 text, c4 timestamptz, - c5 timestamp, + c5 timestamptz, c6 varchar(10), c7 char(10) default 'ft1', c8 user_enum ) SERVER loopback_nopw OPTIONS (schema_name 'public', table_name 'ft1'); -SELECT * FROM ft1_nopw LIMIT 1; +SELECT 1 FROM ft1_nopw LIMIT 1; -- If we add a password to the connstr it'll fail, because we don't allow passwords -- in connstrs only in user mappings. +ALTER SERVER loopback_nopw OPTIONS (ADD password 'dummypw'); + DO $d$ BEGIN EXECUTE $$ALTER SERVER loopback_nopw OPTIONS (ADD password 'dummypw')$$; @@ -3243,13 +3889,13 @@ $d$; ALTER USER MAPPING FOR CURRENT_USER SERVER loopback_nopw OPTIONS (ADD password 'dummypw'); -SELECT * FROM ft1_nopw LIMIT 1; +SELECT 1 FROM ft1_nopw LIMIT 1; -- Unpriv user cannot make the mapping passwordless ALTER USER MAPPING FOR CURRENT_USER SERVER loopback_nopw OPTIONS (ADD password_required 'false'); -SELECT * FROM ft1_nopw LIMIT 1; +SELECT 1 FROM ft1_nopw LIMIT 1; RESET ROLE; @@ -3259,7 +3905,7 @@ ALTER USER MAPPING FOR regress_nosuper SERVER loopback_nopw OPTIONS (ADD passwor SET ROLE regress_nosuper; -- Should finally work now -SELECT * FROM ft1_nopw LIMIT 1; +SELECT 1 FROM ft1_nopw LIMIT 1; -- unpriv user also cannot set sslcert / sslkey on the user mapping -- first set password_required so we see the right error messages @@ -3273,13 +3919,13 @@ DROP USER MAPPING FOR CURRENT_USER SERVER loopback_nopw; -- This will fail again as it'll resolve the user mapping for public, which -- lacks password_required=false -SELECT * FROM ft1_nopw LIMIT 1; +SELECT 1 FROM ft1_nopw LIMIT 1; RESET ROLE; -- The user mapping for public is passwordless and lacks the password_required=false -- mapping option, but will work because the current user is a superuser. -SELECT * FROM ft1_nopw LIMIT 1; +SELECT 1 FROM ft1_nopw LIMIT 1; -- cleanup DROP USER MAPPING FOR public SERVER loopback_nopw; @@ -3290,58 +3936,1091 @@ DROP ROLE regress_nosuper; -- influxdb_fdw does not support transactions -- Two-phase transactions are not supported. --BEGIN; ---Testcase 620: +--Testcase 698: SELECT count(*) FROM ft1; -- error here --PREPARE TRANSACTION 'fdw_tpc'; --ROLLBACK; +/* +-- Influxdb_fdw does not use connection, and does not support connection functions +-- =================================================================== +-- reestablish new connection +-- =================================================================== + +-- Change application_name of remote connection to special one +-- so that we can easily terminate the connection later. +ALTER SERVER loopback OPTIONS (application_name 'fdw_retry_check'); + +-- Make sure we have a remote connection. +SELECT 1 FROM ft1 LIMIT 1; + +-- Terminate the remote connection and wait for the termination to complete. +-- (If a cache flush happens, the remote connection might have already been +-- dropped; so code this step in a way that doesn't fail if no connection.) +DO $$ BEGIN +PERFORM pg_terminate_backend(pid, 180000) FROM pg_stat_activity + WHERE application_name = 'fdw_retry_check'; +END $$; + +-- This query should detect the broken connection when starting new remote +-- transaction, reestablish new connection, and then succeed. +BEGIN; +SELECT 1 FROM ft1 LIMIT 1; + +-- If we detect the broken connection when starting a new remote +-- subtransaction, we should fail instead of establishing a new connection. +-- Terminate the remote connection and wait for the termination to complete. +DO $$ BEGIN +PERFORM pg_terminate_backend(pid, 180000) FROM pg_stat_activity + WHERE application_name = 'fdw_retry_check'; +END $$; +SAVEPOINT s; +-- The text of the error might vary across platforms, so only show SQLSTATE. +\set VERBOSITY sqlstate +SELECT 1 FROM ft1 LIMIT 1; -- should fail +\set VERBOSITY default +COMMIT; + +-- ============================================================================= +-- test connection invalidation cases and postgres_fdw_get_connections function +-- ============================================================================= +-- Let's ensure to close all the existing cached connections. +SELECT 1 FROM postgres_fdw_disconnect_all(); +-- No cached connections, so no records should be output. +SELECT server_name FROM postgres_fdw_get_connections() ORDER BY 1; +-- This test case is for closing the connection in pgfdw_xact_callback +BEGIN; +-- Connection xact depth becomes 1 i.e. the connection is in midst of the xact. +SELECT 1 FROM ft1 LIMIT 1; +SELECT 1 FROM ft7 LIMIT 1; +-- List all the existing cached connections. loopback and loopback3 should be +-- output. +SELECT server_name FROM postgres_fdw_get_connections() ORDER BY 1; +-- Connections are not closed at the end of the alter and drop statements. +-- That's because the connections are in midst of this xact, +-- they are just marked as invalid in pgfdw_inval_callback. +ALTER SERVER loopback OPTIONS (ADD use_remote_estimate 'off'); +DROP SERVER loopback3 CASCADE; +-- List all the existing cached connections. loopback and loopback3 +-- should be output as invalid connections. Also the server name for +-- loopback3 should be NULL because the server was dropped. +SELECT * FROM postgres_fdw_get_connections() ORDER BY 1; +-- The invalid connections get closed in pgfdw_xact_callback during commit. +COMMIT; +-- All cached connections were closed while committing above xact, so no +-- records should be output. +SELECT server_name FROM postgres_fdw_get_connections() ORDER BY 1; + +-- ======================================================================= +-- test postgres_fdw_disconnect and postgres_fdw_disconnect_all functions +-- ======================================================================= +BEGIN; +-- Ensure to cache loopback connection. +SELECT 1 FROM ft1 LIMIT 1; +-- Ensure to cache loopback2 connection. +SELECT 1 FROM ft6 LIMIT 1; +-- List all the existing cached connections. loopback and loopback2 should be +-- output. +SELECT server_name FROM postgres_fdw_get_connections() ORDER BY 1; +-- Issue a warning and return false as loopback connection is still in use and +-- can not be closed. +SELECT postgres_fdw_disconnect('loopback'); +-- List all the existing cached connections. loopback and loopback2 should be +-- output. +SELECT server_name FROM postgres_fdw_get_connections() ORDER BY 1; +-- Return false as connections are still in use, warnings are issued. +-- But disable warnings temporarily because the order of them is not stable. +SET client_min_messages = 'ERROR'; +SELECT postgres_fdw_disconnect_all(); +RESET client_min_messages; +COMMIT; +-- Ensure that loopback2 connection is closed. +SELECT 1 FROM postgres_fdw_disconnect('loopback2'); +SELECT server_name FROM postgres_fdw_get_connections() WHERE server_name = 'loopback2'; +-- Return false as loopback2 connection is closed already. +SELECT postgres_fdw_disconnect('loopback2'); +-- Return an error as there is no foreign server with given name. +SELECT postgres_fdw_disconnect('unknownserver'); +-- Let's ensure to close all the existing cached connections. +SELECT 1 FROM postgres_fdw_disconnect_all(); +-- No cached connections, so no records should be output. +SELECT server_name FROM postgres_fdw_get_connections() ORDER BY 1; + +-- ============================================================================= +-- test case for having multiple cached connections for a foreign server +-- ============================================================================= +CREATE ROLE regress_multi_conn_user1 SUPERUSER; +CREATE ROLE regress_multi_conn_user2 SUPERUSER; +CREATE USER MAPPING FOR regress_multi_conn_user1 SERVER loopback; +CREATE USER MAPPING FOR regress_multi_conn_user2 SERVER loopback; + +BEGIN; +-- Will cache loopback connection with user mapping for regress_multi_conn_user1 +SET ROLE regress_multi_conn_user1; +SELECT 1 FROM ft1 LIMIT 1; +RESET ROLE; + +-- Will cache loopback connection with user mapping for regress_multi_conn_user2 +SET ROLE regress_multi_conn_user2; +SELECT 1 FROM ft1 LIMIT 1; +RESET ROLE; + +-- Should output two connections for loopback server +SELECT server_name FROM postgres_fdw_get_connections() ORDER BY 1; +COMMIT; +-- Let's ensure to close all the existing cached connections. +SELECT 1 FROM postgres_fdw_disconnect_all(); +-- No cached connections, so no records should be output. +SELECT server_name FROM postgres_fdw_get_connections() ORDER BY 1; + +-- Clean up +DROP USER MAPPING FOR regress_multi_conn_user1 SERVER loopback; +DROP USER MAPPING FOR regress_multi_conn_user2 SERVER loopback; +DROP ROLE regress_multi_conn_user1; +DROP ROLE regress_multi_conn_user2; + +-- =================================================================== +-- Test foreign server level option keep_connections +-- =================================================================== +-- By default, the connections associated with foreign server are cached i.e. +-- keep_connections option is on. Set it to off. +ALTER SERVER loopback OPTIONS (keep_connections 'off'); +-- connection to loopback server is closed at the end of xact +-- as keep_connections was set to off. +SELECT 1 FROM ft1 LIMIT 1; +-- No cached connections, so no records should be output. +SELECT server_name FROM postgres_fdw_get_connections() ORDER BY 1; +ALTER SERVER loopback OPTIONS (SET keep_connections 'on'); +*/ + +-- =================================================================== +-- batch insert +-- =================================================================== + +BEGIN; + +--Testcase 699: +CREATE SERVER batch10 FOREIGN DATA WRAPPER influxdb_fdw + OPTIONS(dbname 'postdb', :SERVER, batch_size '10' ); + +--Testcase 700: +SELECT count(*) +FROM pg_foreign_server +WHERE srvname = 'batch10' +AND srvoptions @> array['batch_size=10']; + +--Testcase 701: +ALTER SERVER batch10 OPTIONS( SET batch_size '20' ); + +--Testcase 702: +SELECT count(*) +FROM pg_foreign_server +WHERE srvname = 'batch10' +AND srvoptions @> array['batch_size=10']; + +--Testcase 703: +SELECT count(*) +FROM pg_foreign_server +WHERE srvname = 'batch10' +AND srvoptions @> array['batch_size=20']; + +--Testcase 704: +CREATE FOREIGN TABLE table30 (fields jsonb OPTIONS(fields 'true')) + server batch10 options ( batch_size '30', schemaless 'true'); + +--Testcase 705: +SELECT COUNT(*) +FROM pg_foreign_table +WHERE ftrelid = 'table30'::regclass +AND ftoptions @> array['batch_size=30']; + +--Testcase 706: +ALTER FOREIGN TABLE table30 OPTIONS ( SET batch_size '40'); + +--Testcase 707: +SELECT COUNT(*) +FROM pg_foreign_table +WHERE ftrelid = 'table30'::regclass +AND ftoptions @> array['batch_size=30']; + +--Testcase 708: +SELECT COUNT(*) +FROM pg_foreign_table +WHERE ftrelid = 'table30'::regclass +AND ftoptions @> array['batch_size=40']; + +ROLLBACK; + +--Testcase 709: +CREATE FOREIGN TABLE batch_table (fields jsonb OPTIONS(fields 'true')) + SERVER influxdb_svr options (schemaless 'true'); +--Testcase 813: +CREATE FOREIGN TABLE batch_table_nsc ( x int ) SERVER influxdb_svr OPTIONS (table 'batch_table'); +--Testcase 710: +CREATE FOREIGN TABLE ftable (fields jsonb OPTIONS(fields 'true')) + SERVER influxdb_svr options ( table 'batch_table', batch_size '10', schemaless 'true'); +--Testcase 814: +CREATE FOREIGN TABLE ftable_nsc ( x int ) SERVER influxdb_svr OPTIONS ( table 'batch_table', batch_size '10' ); +--Testcase 711: +EXPLAIN (VERBOSE, COSTS OFF) INSERT INTO ftable_nsc SELECT * FROM generate_series(1, 10) i; +--Testcase 712: +INSERT INTO ftable_nsc SELECT * FROM generate_series(1, 10) i; +--Testcase 713: +INSERT INTO ftable_nsc SELECT * FROM generate_series(11, 31) i; +--Testcase 714: +INSERT INTO ftable_nsc VALUES (32); +--Testcase 715: +INSERT INTO ftable_nsc VALUES (33), (34); +--Testcase 721: +SELECT COUNT(*) FROM ftable; +--Testcase 722: +DELETE FROM batch_table_nsc; +--Testcase 723: +DROP FOREIGN TABLE ftable; +--Testcase 817: +DROP FOREIGN TABLE ftable_nsc; + +-- Disable batch insert +--Testcase 724: +CREATE FOREIGN TABLE ftable (fields jsonb OPTIONS(fields 'true')) + SERVER influxdb_svr OPTIONS ( table 'batch_table', batch_size '1', schemaless 'true' ); +--Testcase 818: +CREATE FOREIGN TABLE ftable_nsc ( x int ) SERVER influxdb_svr OPTIONS ( table 'batch_table', batch_size '1' ); +--Testcase 725: +EXPLAIN (VERBOSE, COSTS OFF) INSERT INTO ftable_nsc VALUES (1), (2); +--Testcase 726: +INSERT INTO ftable_nsc VALUES (1), (2); +--Testcase 727: +SELECT COUNT(*) FROM ftable; + +-- Disable batch inserting into foreign tables with BEFORE ROW INSERT triggers +-- even if the batch_size option is enabled. +--Testcase 776: +ALTER FOREIGN TABLE ftable OPTIONS ( SET batch_size '10' ); +--Testcase 777: +CREATE TRIGGER trig_row_before BEFORE INSERT ON ftable_nsc +FOR EACH ROW EXECUTE PROCEDURE trigger_data(23,'skidoo'); +--Testcase 778: +EXPLAIN (VERBOSE, COSTS OFF) INSERT INTO ftable_nsc VALUES (3), (4); +--Testcase 779: +INSERT INTO ftable_nsc VALUES (3), (4); +--Testcase 780: +SELECT COUNT(*) FROM ftable; + +-- Clean up +--Testcase 781: +DROP TRIGGER trig_row_before ON ftable_nsc; + +--Testcase 728: +DROP FOREIGN TABLE ftable; +--Testcase 819: +DROP FOREIGN TABLE ftable_nsc; +--Testcase 729: +DELETE FROM batch_table_nsc; +--Testcase 820: +DROP FOREIGN TABLE batch_table; +--Testcase 821: +DROP FOREIGN TABLE batch_table_nsc; + +-- influxdb_fdw does not support partition insert +-- Use partitioning +--Testcase 730: +CREATE TABLE batch_table ( x int ) PARTITION BY HASH (x); + +--Testcase 731: +CREATE TABLE batch_table_p0 (LIKE batch_table); +--Testcase 732: +CREATE FOREIGN TABLE batch_table_p0f + PARTITION OF batch_table + FOR VALUES WITH (MODULUS 3, REMAINDER 0) + SERVER influxdb_svr + OPTIONS (table 'batch_table_p0', batch_size '10', schemaless 'true'); + +--Testcase 733: +CREATE TABLE batch_table_p1 (LIKE batch_table); +--Testcase 734: +CREATE FOREIGN TABLE batch_table_p1f + PARTITION OF batch_table + FOR VALUES WITH (MODULUS 3, REMAINDER 1) + SERVER influxdb_svr + OPTIONS (table 'batch_table_p1', batch_size '1', schemaless 'true'); + +--Testcase 735: +CREATE TABLE batch_table_p2 + PARTITION OF batch_table + FOR VALUES WITH (MODULUS 3, REMAINDER 2); + +--Testcase 736: +INSERT INTO batch_table SELECT * FROM generate_series(1, 66) i; +--Testcase 737: +SELECT COUNT(*) FROM batch_table; + +-- Clean up +DROP TABLE batch_table; +DROP TABLE batch_table_p0; +DROP TABLE batch_table_p1; + +-- Check that batched mode also works for some inserts made during +-- cross-partition updates +--Testcase 738: +CREATE TABLE batch_cp_upd_test (a int) PARTITION BY LIST (a); +--Testcase 739: +CREATE TABLE batch_cp_upd_test1 (LIKE batch_cp_upd_test); +--Testcase 740: +CREATE FOREIGN TABLE batch_cp_upd_test1_f + PARTITION OF batch_cp_upd_test + FOR VALUES IN (1) + SERVER influxdb_svr + OPTIONS (table 'batch_cp_upd_test1', batch_size '10', schemaless 'true'); +--Testcase 741: +CREATE TABLE batch_cp_upd_test2 PARTITION OF batch_cp_upd_test + FOR VALUES IN (2); +--Testcase 742: +CREATE TABLE batch_cp_upd_test3 (LIKE batch_cp_upd_test); +CREATE FOREIGN TABLE batch_cp_upd_test3_f + PARTITION OF batch_cp_upd_test + FOR VALUES IN (3) + SERVER influxdb_svr + OPTIONS (table 'batch_cp_upd_test3', batch_size '1'); + +-- Create statement triggers on remote tables that "log" any INSERTs +-- performed on them. +CREATE TABLE cmdlog (cmd text); +CREATE FUNCTION log_stmt() RETURNS TRIGGER LANGUAGE plpgsql AS $$ + BEGIN INSERT INTO public.cmdlog VALUES (TG_OP || ' on ' || TG_RELNAME); RETURN NULL; END; +$$; +CREATE TRIGGER stmt_trig AFTER INSERT ON batch_cp_upd_test1 + FOR EACH STATEMENT EXECUTE FUNCTION log_stmt(); +CREATE TRIGGER stmt_trig AFTER INSERT ON batch_cp_upd_test3 + FOR EACH STATEMENT EXECUTE FUNCTION log_stmt(); + +-- This update moves rows from the local partition 'batch_cp_upd_test2' to the +-- foreign partition 'batch_cp_upd_test1', one that has insert batching +-- enabled, so a single INSERT for both rows. +INSERT INTO batch_cp_upd_test VALUES (2), (2); +-- influxdb_fdw does not support update +-- UPDATE batch_cp_upd_test t SET a = 1 FROM (VALUES (1), (2)) s(a) WHERE t.a = s.a AND s.a = 2; + +-- This one moves rows from the local partition 'batch_cp_upd_test2' to the +-- foreign partition 'batch_cp_upd_test2', one that has insert batching +-- disabled, so separate INSERTs for the two rows. +INSERT INTO batch_cp_upd_test VALUES (2), (2); +-- UPDATE batch_cp_upd_test t SET a = 3 FROM (VALUES (1), (2)) s(a) WHERE t.a = s.a AND s.a = 2; + +SELECT tableoid::regclass, * FROM batch_cp_upd_test ORDER BY 1; + +-- Should see 1 INSERT on batch_cp_upd_test1 and 2 on batch_cp_upd_test3 as +-- described above. +SELECT * FROM cmdlog ORDER BY 1; + +-- Clean up +DROP TABLE batch_cp_upd_test; +DROP TABLE batch_cp_upd_test1; +DROP TABLE batch_cp_upd_test3; +DROP TABLE cmdlog; +DROP FUNCTION log_stmt(); + +-- influxdb_fdw does not support partition insert +-- Use partitioning +--Testcase 745: +ALTER SERVER influxdb_svr OPTIONS (ADD batch_size '10'); + +--Testcase 746: +CREATE TABLE batch_table ( x int, field1 text, field2 text) PARTITION BY HASH (x); + +--Testcase 747: +CREATE TABLE batch_table_p0 (LIKE batch_table); +--Testcase 748: +ALTER TABLE batch_table_p0 ADD CONSTRAINT p0_pkey PRIMARY KEY (x); +--Testcase 749: +CREATE FOREIGN TABLE batch_table_p0f + PARTITION OF batch_table + FOR VALUES WITH (MODULUS 2, REMAINDER 0) + SERVER influxdb_svr + OPTIONS (table 'batch_table_p0', schemaless 'true'); + +--Testcase 750: +CREATE TABLE batch_table_p1 (LIKE batch_table); +--Testcase 751: +ALTER TABLE batch_table_p1 ADD CONSTRAINT p1_pkey PRIMARY KEY (x); +--Testcase 752: +CREATE FOREIGN TABLE batch_table_p1f + PARTITION OF batch_table + FOR VALUES WITH (MODULUS 2, REMAINDER 1) + SERVER influxdb_svr + OPTIONS (table 'batch_table_p1', schemaless 'true'); + +--Testcase 753: +INSERT INTO batch_table SELECT i, 'test'||i, 'test'|| i FROM generate_series(1, 50) i; +--Testcase 754: +SELECT COUNT(*) FROM batch_table; +--Testcase 755: +SELECT * FROM batch_table ORDER BY x; + +-- Clean up +DROP TABLE batch_table; +DROP TABLE batch_table_p0; +DROP TABLE batch_table_p1; + +--Testcase 756: +ALTER SERVER influxdb_svr OPTIONS (DROP batch_size); + +-- Test that pending inserts are handled properly when needed +CREATE TABLE batch_table (a text, b int); +CREATE FOREIGN TABLE ftable_nsc (a text, b int) + SERVER influxdb_svr + OPTIONS (table 'batch_table', batch_size '2'); +CREATE FOREIGN TABLE ftable (fields jsonb OPTIONS(fields 'true')) + SERVER influxdb_svr OPTIONS ( table 'batch_table', batch_size '2', schemaless 'true' ); +CREATE TABLE ltable (a text, b int); +CREATE FUNCTION ftable_rowcount_trigf() RETURNS trigger LANGUAGE plpgsql AS +$$ +begin + raise notice '%: there are % rows in ftable', + TG_NAME, (SELECT count(*) FROM ftable); + if TG_OP = 'DELETE' then + return OLD; + else + return NEW; + end if; +end; +$$; +CREATE TRIGGER ftable_rowcount_trigger +BEFORE INSERT OR UPDATE OR DELETE ON ltable +FOR EACH ROW EXECUTE PROCEDURE ftable_rowcount_trigf(); + +WITH t AS ( + INSERT INTO ltable VALUES ('AAA', 42), ('BBB', 42) RETURNING * +) +INSERT INTO ftable_nsc SELECT * FROM t; + +SELECT * FROM ltable; +SELECT * FROM ftable; +DELETE FROM ftable; + +WITH t AS ( + UPDATE ltable SET b = b + 100 RETURNING * +) +INSERT INTO ftable_nsc SELECT * FROM t; + +SELECT * FROM ltable; +SELECT * FROM ftable; +DELETE FROM ftable; + +WITH t AS ( + DELETE FROM ltable RETURNING * +) +INSERT INTO ftable_nsc SELECT * FROM t; + +SELECT * FROM ltable; +SELECT * FROM ftable; +DELETE FROM ftable; + +-- Clean up +DROP FOREIGN TABLE ftable_nsc; +DROP FOREIGN TABLE ftable; +DROP TABLE batch_table; +DROP TRIGGER ftable_rowcount_trigger ON ltable; +DROP TABLE ltable; + +CREATE TABLE parent (a text, b int) PARTITION BY LIST (a); +CREATE TABLE batch_table (a text, b int); +CREATE FOREIGN TABLE ftable + PARTITION OF parent + FOR VALUES IN ('AAA') + SERVER influxdb_svr + OPTIONS (table 'batch_table', batch_size '2'); +CREATE TABLE ltable + PARTITION OF parent + FOR VALUES IN ('BBB'); +CREATE TRIGGER ftable_rowcount_trigger +BEFORE INSERT ON ltable +FOR EACH ROW EXECUTE PROCEDURE ftable_rowcount_trigf(); + +-- Not support partition insert +INSERT INTO parent VALUES ('AAA', 42), ('BBB', 42), ('AAA', 42), ('BBB', 42); + +SELECT tableoid::regclass, * FROM parent; + +-- Clean up +DROP FOREIGN TABLE ftable; +DROP TABLE batch_table; +DROP TRIGGER ftable_rowcount_trigger ON ltable; +DROP TABLE ltable; +DROP TABLE parent; +DROP FUNCTION ftable_rowcount_trigf; + +/* InfluxDB does not support partition table +-- =================================================================== +-- test asynchronous execution +-- =================================================================== + +ALTER SERVER loopback OPTIONS (DROP extensions); +ALTER SERVER loopback OPTIONS (ADD async_capable 'true'); +ALTER SERVER loopback2 OPTIONS (ADD async_capable 'true'); + +CREATE TABLE async_pt (a int, b int, c text) PARTITION BY RANGE (a); +CREATE TABLE base_tbl1 (a int, b int, c text); +CREATE TABLE base_tbl2 (a int, b int, c text); +CREATE FOREIGN TABLE async_p1 PARTITION OF async_pt FOR VALUES FROM (1000) TO (2000) + SERVER loopback OPTIONS (table_name 'base_tbl1'); +CREATE FOREIGN TABLE async_p2 PARTITION OF async_pt FOR VALUES FROM (2000) TO (3000) + SERVER loopback2 OPTIONS (table_name 'base_tbl2'); +INSERT INTO async_p1 SELECT 1000 + i, i, to_char(i, 'FM0000') FROM generate_series(0, 999, 5) i; +INSERT INTO async_p2 SELECT 2000 + i, i, to_char(i, 'FM0000') FROM generate_series(0, 999, 5) i; +ANALYZE async_pt; + +-- simple queries +CREATE TABLE result_tbl (a int, b int, c text); + +EXPLAIN (VERBOSE, COSTS OFF) +INSERT INTO result_tbl SELECT * FROM async_pt WHERE b % 100 = 0; +INSERT INTO result_tbl SELECT * FROM async_pt WHERE b % 100 = 0; + +SELECT * FROM result_tbl ORDER BY a; +DELETE FROM result_tbl; + +EXPLAIN (VERBOSE, COSTS OFF) +INSERT INTO result_tbl SELECT * FROM async_pt WHERE b === 505; +INSERT INTO result_tbl SELECT * FROM async_pt WHERE b === 505; + +SELECT * FROM result_tbl ORDER BY a; +DELETE FROM result_tbl; + +EXPLAIN (VERBOSE, COSTS OFF) +INSERT INTO result_tbl SELECT a, b, 'AAA' || c FROM async_pt WHERE b === 505; +INSERT INTO result_tbl SELECT a, b, 'AAA' || c FROM async_pt WHERE b === 505; + +SELECT * FROM result_tbl ORDER BY a; +DELETE FROM result_tbl; + +-- Check case where multiple partitions use the same connection +CREATE TABLE base_tbl3 (a int, b int, c text); +CREATE FOREIGN TABLE async_p3 PARTITION OF async_pt FOR VALUES FROM (3000) TO (4000) + SERVER loopback2 OPTIONS (table_name 'base_tbl3'); +INSERT INTO async_p3 SELECT 3000 + i, i, to_char(i, 'FM0000') FROM generate_series(0, 999, 5) i; +ANALYZE async_pt; + +EXPLAIN (VERBOSE, COSTS OFF) +INSERT INTO result_tbl SELECT * FROM async_pt WHERE b === 505; +INSERT INTO result_tbl SELECT * FROM async_pt WHERE b === 505; + +SELECT * FROM result_tbl ORDER BY a; +DELETE FROM result_tbl; + +DROP FOREIGN TABLE async_p3; +DROP TABLE base_tbl3; + +-- Check case where the partitioned table has local/remote partitions +CREATE TABLE async_p3 PARTITION OF async_pt FOR VALUES FROM (3000) TO (4000); +INSERT INTO async_p3 SELECT 3000 + i, i, to_char(i, 'FM0000') FROM generate_series(0, 999, 5) i; +ANALYZE async_pt; + +EXPLAIN (VERBOSE, COSTS OFF) +INSERT INTO result_tbl SELECT * FROM async_pt WHERE b === 505; +INSERT INTO result_tbl SELECT * FROM async_pt WHERE b === 505; + +SELECT * FROM result_tbl ORDER BY a; +DELETE FROM result_tbl; + +-- partitionwise joins +SET enable_partitionwise_join TO true; + +CREATE TABLE join_tbl (a1 int, b1 int, c1 text, a2 int, b2 int, c2 text); + +EXPLAIN (VERBOSE, COSTS OFF) +INSERT INTO join_tbl SELECT * FROM async_pt t1, async_pt t2 WHERE t1.a = t2.a AND t1.b = t2.b AND t1.b % 100 = 0; +INSERT INTO join_tbl SELECT * FROM async_pt t1, async_pt t2 WHERE t1.a = t2.a AND t1.b = t2.b AND t1.b % 100 = 0; + +SELECT * FROM join_tbl ORDER BY a1; +DELETE FROM join_tbl; + +EXPLAIN (VERBOSE, COSTS OFF) +INSERT INTO join_tbl SELECT t1.a, t1.b, 'AAA' || t1.c, t2.a, t2.b, 'AAA' || t2.c FROM async_pt t1, async_pt t2 WHERE t1.a = t2.a AND t1.b = t2.b AND t1.b % 100 = 0; +INSERT INTO join_tbl SELECT t1.a, t1.b, 'AAA' || t1.c, t2.a, t2.b, 'AAA' || t2.c FROM async_pt t1, async_pt t2 WHERE t1.a = t2.a AND t1.b = t2.b AND t1.b % 100 = 0; + +SELECT * FROM join_tbl ORDER BY a1; +DELETE FROM join_tbl; + +RESET enable_partitionwise_join; + +-- Test rescan of an async Append node with do_exec_prune=false +SET enable_hashjoin TO false; + +EXPLAIN (VERBOSE, COSTS OFF) +INSERT INTO join_tbl SELECT * FROM async_p1 t1, async_pt t2 WHERE t1.a = t2.a AND t1.b = t2.b AND t1.b % 100 = 0; +INSERT INTO join_tbl SELECT * FROM async_p1 t1, async_pt t2 WHERE t1.a = t2.a AND t1.b = t2.b AND t1.b % 100 = 0; + +SELECT * FROM join_tbl ORDER BY a1; +DELETE FROM join_tbl; + +RESET enable_hashjoin; + +-- Test interaction of async execution with plan-time partition pruning +EXPLAIN (VERBOSE, COSTS OFF) +SELECT * FROM async_pt WHERE a < 3000; + +EXPLAIN (VERBOSE, COSTS OFF) +SELECT * FROM async_pt WHERE a < 2000; + +-- Test interaction of async execution with run-time partition pruning +SET plan_cache_mode TO force_generic_plan; + +PREPARE async_pt_query (int, int) AS + INSERT INTO result_tbl SELECT * FROM async_pt WHERE a < $1 AND b === $2; + +EXPLAIN (VERBOSE, COSTS OFF) +EXECUTE async_pt_query (3000, 505); +EXECUTE async_pt_query (3000, 505); + +SELECT * FROM result_tbl ORDER BY a; +DELETE FROM result_tbl; + +EXPLAIN (VERBOSE, COSTS OFF) +EXECUTE async_pt_query (2000, 505); +EXECUTE async_pt_query (2000, 505); + +SELECT * FROM result_tbl ORDER BY a; +DELETE FROM result_tbl; + +RESET plan_cache_mode; + +CREATE TABLE local_tbl(a int, b int, c text); +INSERT INTO local_tbl VALUES (1505, 505, 'foo'), (2505, 505, 'bar'); +ANALYZE local_tbl; + +CREATE INDEX base_tbl1_idx ON base_tbl1 (a); +CREATE INDEX base_tbl2_idx ON base_tbl2 (a); +CREATE INDEX async_p3_idx ON async_p3 (a); +ANALYZE base_tbl1; +ANALYZE base_tbl2; +ANALYZE async_p3; + +ALTER FOREIGN TABLE async_p1 OPTIONS (use_remote_estimate 'true'); +ALTER FOREIGN TABLE async_p2 OPTIONS (use_remote_estimate 'true'); + +EXPLAIN (VERBOSE, COSTS OFF) +SELECT * FROM local_tbl, async_pt WHERE local_tbl.a = async_pt.a AND local_tbl.c = 'bar'; +EXPLAIN (ANALYZE, COSTS OFF, SUMMARY OFF, TIMING OFF) +SELECT * FROM local_tbl, async_pt WHERE local_tbl.a = async_pt.a AND local_tbl.c = 'bar'; +SELECT * FROM local_tbl, async_pt WHERE local_tbl.a = async_pt.a AND local_tbl.c = 'bar'; + +ALTER FOREIGN TABLE async_p1 OPTIONS (DROP use_remote_estimate); +ALTER FOREIGN TABLE async_p2 OPTIONS (DROP use_remote_estimate); + +DROP TABLE local_tbl; +DROP INDEX base_tbl1_idx; +DROP INDEX base_tbl2_idx; +DROP INDEX async_p3_idx; + +-- UNION queries +EXPLAIN (VERBOSE, COSTS OFF) +INSERT INTO result_tbl +(SELECT a, b, 'AAA' || c FROM async_p1 ORDER BY a LIMIT 10) +UNION +(SELECT a, b, 'AAA' || c FROM async_p2 WHERE b < 10); +INSERT INTO result_tbl +(SELECT a, b, 'AAA' || c FROM async_p1 ORDER BY a LIMIT 10) +UNION +(SELECT a, b, 'AAA' || c FROM async_p2 WHERE b < 10); + +SELECT * FROM result_tbl ORDER BY a; +DELETE FROM result_tbl; + +EXPLAIN (VERBOSE, COSTS OFF) +INSERT INTO result_tbl +(SELECT a, b, 'AAA' || c FROM async_p1 ORDER BY a LIMIT 10) +UNION ALL +(SELECT a, b, 'AAA' || c FROM async_p2 WHERE b < 10); +INSERT INTO result_tbl +(SELECT a, b, 'AAA' || c FROM async_p1 ORDER BY a LIMIT 10) +UNION ALL +(SELECT a, b, 'AAA' || c FROM async_p2 WHERE b < 10); + +SELECT * FROM result_tbl ORDER BY a; +DELETE FROM result_tbl; + +-- Disable async execution if we use gating Result nodes for pseudoconstant +-- quals +EXPLAIN (VERBOSE, COSTS OFF) +SELECT * FROM async_pt WHERE CURRENT_USER = SESSION_USER; + +EXPLAIN (VERBOSE, COSTS OFF) +(SELECT * FROM async_p1 WHERE CURRENT_USER = SESSION_USER) +UNION ALL +(SELECT * FROM async_p2 WHERE CURRENT_USER = SESSION_USER); + +EXPLAIN (VERBOSE, COSTS OFF) +SELECT * FROM ((SELECT * FROM async_p1 WHERE b < 10) UNION ALL (SELECT * FROM async_p2 WHERE b < 10)) s WHERE CURRENT_USER = SESSION_USER; + +-- Test that pending requests are processed properly +SET enable_mergejoin TO false; +SET enable_hashjoin TO false; + +EXPLAIN (VERBOSE, COSTS OFF) +SELECT * FROM async_pt t1, async_p2 t2 WHERE t1.a = t2.a AND t1.b === 505; +SELECT * FROM async_pt t1, async_p2 t2 WHERE t1.a = t2.a AND t1.b === 505; + +CREATE TABLE local_tbl (a int, b int, c text); +INSERT INTO local_tbl VALUES (1505, 505, 'foo'); +ANALYZE local_tbl; + +EXPLAIN (VERBOSE, COSTS OFF) +SELECT * FROM local_tbl t1 LEFT JOIN (SELECT *, (SELECT count(*) FROM async_pt WHERE a < 3000) FROM async_pt WHERE a < 3000) t2 ON t1.a = t2.a; +EXPLAIN (ANALYZE, COSTS OFF, SUMMARY OFF, TIMING OFF) +SELECT * FROM local_tbl t1 LEFT JOIN (SELECT *, (SELECT count(*) FROM async_pt WHERE a < 3000) FROM async_pt WHERE a < 3000) t2 ON t1.a = t2.a; +SELECT * FROM local_tbl t1 LEFT JOIN (SELECT *, (SELECT count(*) FROM async_pt WHERE a < 3000) FROM async_pt WHERE a < 3000) t2 ON t1.a = t2.a; + +EXPLAIN (VERBOSE, COSTS OFF) +SELECT * FROM async_pt t1 WHERE t1.b === 505 LIMIT 1; +EXPLAIN (ANALYZE, COSTS OFF, SUMMARY OFF, TIMING OFF) +SELECT * FROM async_pt t1 WHERE t1.b === 505 LIMIT 1; +SELECT * FROM async_pt t1 WHERE t1.b === 505 LIMIT 1; + +-- Check with foreign modify +CREATE TABLE base_tbl3 (a int, b int, c text); +CREATE FOREIGN TABLE remote_tbl (a int, b int, c text) + SERVER loopback OPTIONS (table_name 'base_tbl3'); +INSERT INTO remote_tbl VALUES (2505, 505, 'bar'); + +CREATE TABLE base_tbl4 (a int, b int, c text); +CREATE FOREIGN TABLE insert_tbl (a int, b int, c text) + SERVER loopback OPTIONS (table_name 'base_tbl4'); + +EXPLAIN (VERBOSE, COSTS OFF) +INSERT INTO insert_tbl (SELECT * FROM local_tbl UNION ALL SELECT * FROM remote_tbl); +INSERT INTO insert_tbl (SELECT * FROM local_tbl UNION ALL SELECT * FROM remote_tbl); + +SELECT * FROM insert_tbl ORDER BY a; + +-- Check with direct modify +EXPLAIN (VERBOSE, COSTS OFF) +WITH t AS (UPDATE remote_tbl SET c = c || c RETURNING *) +INSERT INTO join_tbl SELECT * FROM async_pt LEFT JOIN t ON (async_pt.a = t.a AND async_pt.b = t.b) WHERE async_pt.b === 505; +WITH t AS (UPDATE remote_tbl SET c = c || c RETURNING *) +INSERT INTO join_tbl SELECT * FROM async_pt LEFT JOIN t ON (async_pt.a = t.a AND async_pt.b = t.b) WHERE async_pt.b === 505; + +SELECT * FROM join_tbl ORDER BY a1; +DELETE FROM join_tbl; + +DROP TABLE local_tbl; +DROP FOREIGN TABLE remote_tbl; +DROP FOREIGN TABLE insert_tbl; +DROP TABLE base_tbl3; +DROP TABLE base_tbl4; + +RESET enable_mergejoin; +RESET enable_hashjoin; + +-- Test that UPDATE/DELETE with inherited target works with async_capable enabled +EXPLAIN (VERBOSE, COSTS OFF) +UPDATE async_pt SET c = c || c WHERE b = 0 RETURNING *; +UPDATE async_pt SET c = c || c WHERE b = 0 RETURNING *; +EXPLAIN (VERBOSE, COSTS OFF) +DELETE FROM async_pt WHERE b = 0 RETURNING *; +DELETE FROM async_pt WHERE b = 0 RETURNING *; + +-- Check EXPLAIN ANALYZE for a query that scans empty partitions asynchronously +DELETE FROM async_p1; +DELETE FROM async_p2; +DELETE FROM async_p3; + +EXPLAIN (ANALYZE, COSTS OFF, SUMMARY OFF, TIMING OFF) +SELECT * FROM async_pt; + +-- Clean up +DROP TABLE async_pt; +DROP TABLE base_tbl1; +DROP TABLE base_tbl2; +DROP TABLE result_tbl; +DROP TABLE join_tbl; + +-- Test that an asynchronous fetch is processed before restarting the scan in +-- ReScanForeignScan +CREATE TABLE base_tbl (a int, b int); +INSERT INTO base_tbl VALUES (1, 11), (2, 22), (3, 33); +CREATE FOREIGN TABLE foreign_tbl (b int) + SERVER loopback OPTIONS (table_name 'base_tbl'); +CREATE FOREIGN TABLE foreign_tbl2 () INHERITS (foreign_tbl) + SERVER loopback OPTIONS (table_name 'base_tbl'); + +EXPLAIN (VERBOSE, COSTS OFF) +SELECT a FROM base_tbl WHERE a IN (SELECT a FROM foreign_tbl); +SELECT a FROM base_tbl WHERE a IN (SELECT a FROM foreign_tbl); + +-- Clean up +DROP FOREIGN TABLE foreign_tbl CASCADE; +DROP TABLE base_tbl; + +ALTER SERVER loopback OPTIONS (DROP async_capable); +ALTER SERVER loopback2 OPTIONS (DROP async_capable); +*/ + +-- =================================================================== +-- test invalid server, foreign table and foreign data wrapper options +-- =================================================================== +/* +-- InfluxDB FDW does not have these options +-- Invalid fdw_startup_cost option +CREATE SERVER inv_scst FOREIGN DATA WRAPPER postgres_fdw + OPTIONS(fdw_startup_cost '100$%$#$#'); +-- Invalid fdw_tuple_cost option +CREATE SERVER inv_scst FOREIGN DATA WRAPPER postgres_fdw + OPTIONS(fdw_tuple_cost '100$%$#$#'); +-- Invalid fetch_size option +CREATE FOREIGN TABLE inv_fsz (c1 int ) + SERVER loopback OPTIONS (fetch_size '100$%$#$#'); +*/ +-- Invalid batch_size option +--Testcase 776: +CREATE FOREIGN TABLE inv_bsz (fields jsonb OPTIONS(fields 'true')) + SERVER influxdb_svr OPTIONS (batch_size '100$%$#$#', schemaless 'true'); + +-- No option is allowed to be specified at foreign data wrapper level +--Testcase 782: +ALTER FOREIGN DATA WRAPPER influxdb_fdw OPTIONS (nonexistent 'fdw'); + +/* +-- =================================================================== +-- application_name is an option in libpq of postgres +-- so Influxdb_fdw not support application_name. +-- test postgres_fdw.application_name GUC +-- =================================================================== +-- To avoid race conditions in checking the remote session's application_name, +-- use this view to make the remote session itself read its application_name. +CREATE VIEW my_application_name AS + SELECT application_name FROM pg_stat_activity WHERE pid = pg_backend_pid(); + +CREATE FOREIGN TABLE remote_application_name (application_name text) + SERVER loopback2 + OPTIONS (schema_name 'public', table_name 'my_application_name'); + +SELECT count(*) FROM remote_application_name; + +-- Specify escape sequences in application_name option of a server +-- object so as to test that they are replaced with status information +-- expectedly. Note that we are also relying on ALTER SERVER to force +-- the remote session to be restarted with its new application name. +-- +-- Since pg_stat_activity.application_name may be truncated to less than +-- NAMEDATALEN characters, note that substring() needs to be used +-- at the condition of test query to make sure that the string consisting +-- of database name and process ID is also less than that. +ALTER SERVER loopback2 OPTIONS (application_name 'fdw_%d%p'); +SELECT count(*) FROM remote_application_name + WHERE application_name = + substring('fdw_' || current_database() || pg_backend_pid() for + current_setting('max_identifier_length')::int); + +-- postgres_fdw.application_name overrides application_name option +-- of a server object if both settings are present. +ALTER SERVER loopback2 OPTIONS (SET application_name 'fdw_wrong'); +SET postgres_fdw.application_name TO 'fdw_%a%u%%'; +SELECT count(*) FROM remote_application_name + WHERE application_name = + substring('fdw_' || current_setting('application_name') || + CURRENT_USER || '%' for current_setting('max_identifier_length')::int); +RESET postgres_fdw.application_name; + +-- Test %c (session ID) and %C (cluster name) escape sequences. +ALTER SERVER loopback2 OPTIONS (SET application_name 'fdw_%C%c'); +SELECT count(*) FROM remote_application_name + WHERE application_name = + substring('fdw_' || current_setting('cluster_name') || + to_hex(trunc(EXTRACT(EPOCH FROM (SELECT backend_start FROM + pg_stat_get_activity(pg_backend_pid()))))::integer) || '.' || + to_hex(pg_backend_pid()) + for current_setting('max_identifier_length')::int); + +-- Clean up. +DROP FOREIGN TABLE remote_application_name; +DROP VIEW my_application_name; + +-- =================================================================== +-- test parallel commit and parallel abort +-- =================================================================== +ALTER SERVER loopback OPTIONS (ADD parallel_commit 'true'); +ALTER SERVER loopback OPTIONS (ADD parallel_abort 'true'); +ALTER SERVER loopback2 OPTIONS (ADD parallel_commit 'true'); +ALTER SERVER loopback2 OPTIONS (ADD parallel_abort 'true') + +CREATE TABLE ploc1 (f1 int, f2 text); +CREATE FOREIGN TABLE prem1 (f1 int, f2 text) + SERVER loopback OPTIONS (table_name 'ploc1'); +CREATE TABLE ploc2 (f1 int, f2 text); +CREATE FOREIGN TABLE prem2 (f1 int, f2 text) + SERVER loopback2 OPTIONS (table_name 'ploc2'); + +BEGIN; +INSERT INTO prem1 VALUES (101, 'foo'); +INSERT INTO prem2 VALUES (201, 'bar'); +COMMIT; +SELECT * FROM prem1; +SELECT * FROM prem2; + +BEGIN; +SAVEPOINT s; +INSERT INTO prem1 VALUES (102, 'foofoo'); +INSERT INTO prem2 VALUES (202, 'barbar'); +RELEASE SAVEPOINT s; +COMMIT; +SELECT * FROM prem1; +SELECT * FROM prem2; + +-- This tests executing DEALLOCATE ALL against foreign servers in parallel +-- during pre-commit +BEGIN; +SAVEPOINT s; +INSERT INTO prem1 VALUES (103, 'baz'); +INSERT INTO prem2 VALUES (203, 'qux'); +ROLLBACK TO SAVEPOINT s; +RELEASE SAVEPOINT s; +INSERT INTO prem1 VALUES (104, 'bazbaz'); +INSERT INTO prem2 VALUES (204, 'quxqux'); +COMMIT; +SELECT * FROM prem1; +SELECT * FROM prem2; + +BEGIN; +INSERT INTO prem1 VALUES (105, 'test1'); +INSERT INTO prem2 VALUES (205, 'test2'); +ABORT; +SELECT * FROM prem1; +SELECT * FROM prem2; + +-- This tests executing DEALLOCATE ALL against foreign servers in parallel +-- during post-abort +BEGIN; +SAVEPOINT s; +INSERT INTO prem1 VALUES (105, 'test1'); +INSERT INTO prem2 VALUES (205, 'test2'); +ROLLBACK TO SAVEPOINT s; +RELEASE SAVEPOINT s; +INSERT INTO prem1 VALUES (105, 'test1'); +INSERT INTO prem2 VALUES (205, 'test2'); +ABORT; +SELECT * FROM prem1; +SELECT * FROM prem2; + +ALTER SERVER loopback OPTIONS (DROP parallel_commit); +ALTER SERVER loopback OPTIONS (DROP parallel_abort); +ALTER SERVER loopback2 OPTIONS (DROP parallel_commit); +ALTER SERVER loopback2 OPTIONS (DROP parallel_abort); + +-- =================================================================== +-- test for ANALYZE sampling +-- =================================================================== + +CREATE TABLE analyze_table (id int, a text, b bigint); + +CREATE FOREIGN TABLE analyze_ftable (id int, a text, b bigint) + SERVER loopback OPTIONS (table_name 'analyze_rtable1'); + +INSERT INTO analyze_table (SELECT x FROM generate_series(1,1000) x); +ANALYZE analyze_table; + +SET default_statistics_target = 10; +ANALYZE analyze_table; + +ALTER SERVER loopback OPTIONS (analyze_sampling 'invalid'); + +ALTER SERVER loopback OPTIONS (analyze_sampling 'auto'); +ANALYZE analyze_table; + +ALTER SERVER loopback OPTIONS (SET analyze_sampling 'system'); +ANALYZE analyze_table; + +ALTER SERVER loopback OPTIONS (SET analyze_sampling 'bernoulli'); +ANALYZE analyze_table; + +ALTER SERVER loopback OPTIONS (SET analyze_sampling 'random'); +ANALYZE analyze_table; + +ALTER SERVER loopback OPTIONS (SET analyze_sampling 'off'); +ANALYZE analyze_table; + +-- cleanup +DROP FOREIGN TABLE analyze_ftable; +DROP TABLE analyze_table; +*/ -- Clean-up +--Testcase 822: DELETE FROM ft1_nsc; +--Testcase 823: DELETE FROM ft2_nsc; +--Testcase 824: DELETE FROM ft4_nsc; +--Testcase 825: DELETE FROM ft5_nsc; +--Testcase 826: DELETE FROM foo_nsc; +--Testcase 827: DELETE FROM bar_nsc; +--Testcase 828: DELETE FROM loct1_nsc; +--Testcase 829: DELETE FROM loct2_nsc; +--Testcase 830: DELETE FROM rem1_nsc; +--Testcase 831: DROP FOREIGN TABLE foo_nsc cascade; +--Testcase 832: DROP FOREIGN TABLE bar_nsc cascade; +--Testcase 833: DROP FOREIGN TABLE loct1_nsc; +--Testcase 834: DROP FOREIGN TABLE loct2_nsc; +--Testcase 835: DROP FOREIGN TABLE "S 1".s1t0; +--Testcase 836: DROP FOREIGN TABLE "S 1".s1t1; +--Testcase 837: DROP FOREIGN TABLE "S 1".s1t2; +--Testcase 838: DROP FOREIGN TABLE "S 1".s1t3; +--Testcase 839: DROP FOREIGN TABLE "S 1".s1t4; +--Testcase 840: DROP FOREIGN TABLE ft1_nsc; +--Testcase 841: DROP FOREIGN TABLE ft2_nsc; +--Testcase 842: DROP FOREIGN TABLE ft4_nsc; +--Testcase 843: DROP FOREIGN TABLE ft5_nsc; +--Testcase 844: DROP TYPE IF EXISTS user_enum; +--Testcase 845: DROP SCHEMA IF EXISTS "S 1" CASCADE; +--Testcase 846: DROP FUNCTION IF EXISTS trigger_func(); +--Testcase 847: DROP FUNCTION IF EXISTS trig_row_before_insupdate(); +--Testcase 848: DROP FUNCTION IF EXISTS trig_null(); +--Testcase 849: DROP SCHEMA IF EXISTS import_influx1 CASCADE; +--Testcase 850: DROP SCHEMA IF EXISTS import_influx2 CASCADE; +--Testcase 851: DROP SCHEMA IF EXISTS import_influx3 CASCADE; +--Testcase 852: DROP SCHEMA IF EXISTS import_influx4 CASCADE; ---Testcase 621: +--Testcase 758: DROP USER MAPPING FOR public SERVER testserver1; ---Testcase 622: +--Testcase 759: DROP USER MAPPING FOR CURRENT_USER SERVER influxdb_svr; ---Testcase 623: +--Testcase 760: DROP USER MAPPING FOR CURRENT_USER SERVER influxdb_svr2; ---Testcase 624: +--Testcase 761: DROP SERVER testserver1 CASCADE; ---Testcase 625: +--Testcase 762: DROP SERVER influxdb_svr CASCADE; ---Testcase 626: +--Testcase 763: DROP SERVER influxdb_svr2 CASCADE; ---Testcase 627: +--Testcase 764: DROP EXTENSION influxdb_fdw; diff --git a/sql/14.5/schemaless/extra/insert.sql b/sql/16.0/schemaless/extra/insert.sql similarity index 99% rename from sql/14.5/schemaless/extra/insert.sql rename to sql/16.0/schemaless/extra/insert.sql index c124911..ee755a6 100644 --- a/sql/14.5/schemaless/extra/insert.sql +++ b/sql/16.0/schemaless/extra/insert.sql @@ -15,6 +15,7 @@ CREATE USER MAPPING FOR CURRENT_USER SERVER influxdb_svr OPTIONS (:AUTHENTICATIO -- --Testcase 4: CREATE FOREIGN TABLE inserttest (fields jsonb OPTIONS (fields 'true')) SERVER influxdb_svr OPTIONS (schemaless 'true'); +--Testcase 24: CREATE FOREIGN TABLE inserttest_nsc (col1 int4, col2 int4 NOT NULL, col3 text default 'testing') SERVER influxdb_svr OPTIONS(table 'inserttest'); --Testcase 5: insert into inserttest_nsc (col1, col2, col3) values (DEFAULT, DEFAULT, DEFAULT); @@ -66,8 +67,11 @@ select (fields->>'col1')::int4 col1, (fields->>'col2')::int4 col2, char_length(f --Testcase 20: -- Clean up: +--Testcase 25: delete from inserttest_nsc; +--Testcase 26: drop foreign table inserttest; +--Testcase 27: drop foreign table inserttest_nsc; /* -- skip, influxdb does not support create table with WITH option diff --git a/sql/11.17/schemaless/extra/join.sql b/sql/16.0/schemaless/extra/join.sql similarity index 83% rename from sql/11.17/schemaless/extra/join.sql rename to sql/16.0/schemaless/extra/join.sql index f35384f..4257c12 100644 --- a/sql/11.17/schemaless/extra/join.sql +++ b/sql/16.0/schemaless/extra/join.sql @@ -23,6 +23,7 @@ CREATE USER MAPPING FOR CURRENT_USER SERVER influxdb_svr OPTIONS (:AUTHENTICATIO CREATE FOREIGN TABLE J1_TBL ( fields jsonb OPTIONS (fields 'true') ) SERVER influxdb_svr OPTIONS(schemaless 'true'); +--Testcase 575: CREATE FOREIGN TABLE j1_tbl_nsc ( i integer, j integer, @@ -32,6 +33,7 @@ CREATE FOREIGN TABLE j1_tbl_nsc ( CREATE FOREIGN TABLE J2_TBL ( fields jsonb OPTIONS (fields 'true') ) SERVER influxdb_svr OPTIONS(schemaless 'true'); +--Testcase 576: CREATE FOREIGN TABLE j2_tbl_nsc ( i integer, k integer @@ -76,12 +78,20 @@ INSERT INTO j2_tbl_nsc VALUES (0, NULL); --INSERT INTO J2_TBL VALUES (NULL, NULL); --Testcase 24: INSERT INTO j2_tbl_nsc VALUES (NULL, 0); + +--Testcase 560: +CREATE FOREIGN TABLE onek ( + fields jsonb OPTIONS (fields 'true') +) SERVER influxdb_svr OPTIONS(schemaless 'true'); + --Testcase 25: CREATE FOREIGN TABLE tenk1 ( fields jsonb OPTIONS (fields 'true') ) SERVER influxdb_svr OPTIONS (table 'tenk', schemaless 'true'); + --Does not support on Postgres 12 --ALTER TABLE tenk1 SET WITH OIDS; + --Testcase 26: CREATE FOREIGN TABLE tenk2 ( fields jsonb OPTIONS (fields 'true') @@ -205,26 +215,48 @@ SELECT * FROM (SELECT (fields->>'i')::int i, (fields->>'j')::int j, fields->>'t' t FROM J1_TBL) t1 (a, b, c) JOIN (SELECT (fields->>'i')::int i, (fields->>'k')::int k FROM J2_TBL) t2 (a, b) USING (b) ORDER BY b, t1.a; +-- test join using aliases +--Testcase 49: +SELECT * FROM (SELECT (fields->>'i')::int i, (fields->>'j')::int j, fields->>'t' t FROM J1_TBL) J1_TBL JOIN (SELECT (fields->>'i')::int i, (fields->>'k')::int k FROM J2_TBL) J2_TBL USING (i) WHERE J1_TBL.t = 'one'; -- ok +--Testcase 50: +SELECT * FROM (SELECT (fields->>'i')::int i, (fields->>'j')::int j, fields->>'t' t FROM J1_TBL) J1_TBL JOIN (SELECT (fields->>'i')::int i, (fields->>'k')::int k FROM J2_TBL) J2_TBL USING (i) AS x WHERE J1_TBL.t = 'one'; -- ok +--Testcase 51: +SELECT * FROM ((SELECT (fields->>'i')::int i, (fields->>'j')::int j, fields->>'t' t FROM J1_TBL) J1_TBL JOIN (SELECT (fields->>'i')::int i, (fields->>'k')::int k FROM J2_TBL) J2_TBL USING (i)) AS x WHERE J1_TBL.t = 'one'; -- error +--Testcase 52: +SELECT * FROM (SELECT (fields->>'i')::int i, (fields->>'j')::int j, fields->>'t' t FROM J1_TBL) J1_TBL JOIN (SELECT (fields->>'i')::int i, (fields->>'k')::int k FROM J2_TBL) J2_TBL USING (i) AS x WHERE x.i::int = 1; -- ok +--Testcase 53: +SELECT * FROM (SELECT (fields->>'i')::int i, (fields->>'j')::int j, fields->>'t' t FROM J1_TBL) J1_TBL JOIN (SELECT (fields->>'i')::int i, (fields->>'k')::int k FROM J2_TBL) J2_TBL USING (i) AS x WHERE x.t = 'one'; -- error +--Testcase 54: +SELECT * FROM ((SELECT (fields->>'i')::int i, (fields->>'j')::int j, fields->>'t' t FROM J1_TBL) J1_TBL JOIN (SELECT (fields->>'i')::int i, (fields->>'k')::int k FROM J2_TBL) J2_TBL USING (i) AS x) AS xx WHERE x.i::int = 1; -- error (XXX could use better hint) +--Testcase 55: +SELECT * FROM (SELECT (fields->>'i')::int i,(fields->>'j')::int j,fields->>'t' t FROM J1_TBL) a1 JOIN (SELECT (fields->>'i')::int i,(fields->>'k')::int k FROM J2_TBL) a2 USING (i) AS a1; -- error +--Testcase 56: +SELECT x.* FROM (SELECT (fields->>'i')::int i, (fields->>'j')::int j, fields->>'t' t FROM J1_TBL) J1_TBL JOIN (SELECT (fields->>'i')::int i, (fields->>'k')::int k FROM J2_TBL) J2_TBL USING (i) AS x WHERE J1_TBL.t = 'one'; +--Testcase 57: +SELECT ROW(x.*) FROM (SELECT (fields->>'i')::int i, (fields->>'j')::int j, fields->>'t' t FROM J1_TBL) J1_TBL JOIN (SELECT (fields->>'i')::int i, (fields->>'k')::int k FROM J2_TBL) J2_TBL USING (i) AS x WHERE J1_TBL.t = 'one'; +--Testcase 58: +SELECT row_to_json(x.*) FROM (SELECT (fields->>'i')::int i, (fields->>'j')::int j, fields->>'t' t FROM J1_TBL) J1_TBL JOIN (SELECT (fields->>'i')::int i, (fields->>'k')::int k FROM J2_TBL) J2_TBL USING (i) AS x WHERE J1_TBL.t = 'one'; + -- -- NATURAL JOIN -- Inner equi-join on all columns with the same name -- ---Testcase 49: +--Testcase 59: SELECT * FROM (SELECT (fields->>'i')::int i,(fields->>'j')::int j,fields->>'t' t FROM J1_TBL) J1_TBL NATURAL JOIN (SELECT (fields->>'i')::int i,(fields->>'k')::int k FROM J2_TBL) J2_TBL; ---Testcase 50: +--Testcase 60: SELECT * FROM (SELECT (fields->>'i')::int i, (fields->>'j')::int j, fields->>'t' t FROM J1_TBL) t1 (a, b, c) NATURAL JOIN (SELECT (fields->>'i')::int i, (fields->>'k')::int k FROM J2_TBL) t2 (a, d); ---Testcase 51: +--Testcase 61: SELECT * FROM (SELECT (fields->>'i')::int i, (fields->>'j')::int j, fields->>'t' t FROM J1_TBL) t1 (a, b, c) NATURAL JOIN (SELECT (fields->>'i')::int i, (fields->>'k')::int k FROM J2_TBL) t2 (d, a); -- mismatch number of columns -- currently, Postgres will fill in with underlying names ---Testcase 52: +--Testcase 62: SELECT * FROM (SELECT (fields->>'i')::int i,(fields->>'j')::int j,fields->>'t' t FROM J1_TBL) t1 (a, b) NATURAL JOIN (SELECT (fields->>'i')::int i,(fields->>'k')::int k FROM J2_TBL) t2 (a); @@ -233,11 +265,11 @@ SELECT * -- Inner joins (equi-joins) -- ---Testcase 53: +--Testcase 63: SELECT * FROM (SELECT (fields->>'i')::int i,(fields->>'j')::int j,fields->>'t' t FROM J1_TBL) J1_TBL JOIN (select (fields->>'i')::int i, (fields->>'k')::int k from J2_TBL) J2_TBL ON ((J1_TBL.i)::bigint = (J2_TBL.i)::bigint); ---Testcase 54: +--Testcase 64: SELECT * FROM (SELECT (fields->>'i')::int i,(fields->>'j')::int j,fields->>'t' t FROM J1_TBL) J1_TBL JOIN (select (fields->>'i')::int i, (fields->>'k')::int k from J2_TBL) J2_TBL ON ((J1_TBL.i)::bigint = (J2_TBL.k)::bigint); @@ -246,7 +278,7 @@ SELECT * -- Non-equi-joins -- ---Testcase 55: +--Testcase 65: SELECT * FROM (select (fields->>'i')::int i, (fields->>'j')::int j,fields->>'t' t from J1_TBL) J1_TBL JOIN (select (fields->>'i')::int i, (fields->>'k')::int k from J2_TBL) J2_TBL ON ((J1_TBL.i)::bigint <= (J2_TBL.k)::bigint) ORDER BY J1_TBL.i, J1_TBL.j, J1_TBL.t, J2_TBL.i, J2_TBL.k; @@ -256,46 +288,46 @@ SELECT * -- Note that OUTER is a noise word -- ---Testcase 56: +--Testcase 66: SELECT * FROM (SELECT (fields->>'i')::int i, (fields->>'j')::int j ,fields->>'t' t FROM J1_TBL) J1_TBL LEFT OUTER JOIN (SELECT (fields->>'i')::int i,(fields->>'k')::int k FROM J2_TBL) J2_TBL USING (i) ORDER BY i, k, t; ---Testcase 57: +--Testcase 67: SELECT * FROM (SELECT (fields->>'i')::int i,(fields->>'j')::int j,fields->>'t' t FROM J1_TBL) J1_TBL LEFT JOIN (SELECT (fields->>'i')::int i,(fields->>'k')::int k FROM J2_TBL) J2_TBL USING (i) ORDER BY i::int, k, t; ---Testcase 58: +--Testcase 68: SELECT * FROM (SELECT (fields->>'i')::int i,(fields->>'j')::int j,fields->>'t' t FROM J1_TBL) J1_TBL RIGHT OUTER JOIN (SELECT (fields->>'i')::int i,(fields->>'k')::int k FROM J2_TBL) J2_TBL USING (i); ---Testcase 59: +--Testcase 69: SELECT * FROM (SELECT (fields->>'i')::int i,(fields->>'j')::int j,fields->>'t' t FROM J1_TBL) J1_TBL RIGHT JOIN (SELECT (fields->>'i')::int i,(fields->>'k')::int k FROM J2_TBL) J2_TBL USING (i); ---Testcase 60: +--Testcase 70: SELECT * FROM (SELECT (fields->>'i')::int i,(fields->>'j')::int j,fields->>'t' t FROM J1_TBL) J1_TBL FULL OUTER JOIN (SELECT (fields->>'i')::int i,(fields->>'k')::int k FROM J2_TBL) J2_TBL USING (i) ORDER BY i::int, k, t; ---Testcase 61: +--Testcase 71: SELECT * FROM (SELECT (fields->>'i')::int i,(fields->>'j')::int j,fields->>'t' t FROM J1_TBL) J1_TBL FULL JOIN (SELECT (fields->>'i')::int i,(fields->>'k')::int k FROM J2_TBL) J2_TBL USING (i) ORDER BY i::int, k, t; ---Testcase 62: +--Testcase 72: SELECT * FROM (SELECT (fields->>'i')::int i,(fields->>'j')::int j,fields->>'t' t FROM J1_TBL) J1_TBL LEFT JOIN (SELECT (fields->>'i')::int i,(fields->>'k')::int k FROM J2_TBL) J2_TBL USING (i) WHERE (k)::int = 1; ---Testcase 63: +--Testcase 73: SELECT * FROM (SELECT (fields->>'i')::int i,(fields->>'j')::int j,fields->>'t' t FROM J1_TBL) J1_TBL LEFT JOIN (SELECT (fields->>'i')::int i,(fields->>'k')::int k FROM J2_TBL) J2_TBL USING (i) WHERE (i)::int = 1; -- -- semijoin selectivity for <> -- ---Testcase 64: +--Testcase 74: explain (costs off) select * from (select (fields->>'f1')::int4 f1 from INT4_TBL i4) i4, (select (fields->>'unique1')::int4 unique1, (fields->>'unique2')::int4 unique2, (fields->>'two')::int4 two, (fields->>'four')::int4 four, (fields->>'ten')::int4 ten, (fields->>'twenty')::int4 twenty, (fields->>'hundred')::int4 hundred, (fields->>'thousand')::int4 thousand, (fields->>'twothousand')::int4 twothousand, (fields->>'fivethous')::int4 fivethous, (fields->>'tenthous')::int4 tenthous, (fields->>'odd')::int4 odd, (fields->>'even')::int4 even, (fields->>'stringu1')::name stringu1, (fields->>'stringu2')::name stringu2, (fields->>'string4')::name string4 from tenk1 a) a where exists(select * from (select (fields->>'unique1')::int4 unique1, (fields->>'unique2')::int4 unique2, (fields->>'two')::int4 two, (fields->>'four')::int4 four, (fields->>'ten')::int4 ten, (fields->>'twenty')::int4 twenty, (fields->>'hundred')::int4 hundred, (fields->>'thousand')::int4 thousand, (fields->>'twothousand')::int4 twothousand, (fields->>'fivethous')::int4 fivethous, (fields->>'tenthous')::int4 tenthous, (fields->>'odd')::int4 odd, (fields->>'even')::int4 even, (fields->>'stringu1')::name stringu1, (fields->>'stringu2')::name stringu2, (fields->>'string4')::name string4 from tenk1 b) b @@ -311,30 +343,33 @@ where exists(select * from (select (fields->>'unique1')::int4 unique1, (fields-> -- Multiway full join -- ---Testcase 65: +--Testcase 75: CREATE FOREIGN TABLE t1 (fields jsonb OPTIONS (fields 'true')) SERVER influxdb_svr OPTIONS(schemaless 'true'); +--Testcase 577: CREATE FOREIGN TABLE t1_nsc (name TEXT, n INTEGER) SERVER influxdb_svr OPTIONS (table 't1'); ---Testcase 66: +--Testcase 76: CREATE FOREIGN TABLE t2 (fields jsonb OPTIONS (fields 'true')) SERVER influxdb_svr OPTIONS(schemaless 'true'); +--Testcase 578: CREATE FOREIGN TABLE t2_nsc (name TEXT, n INTEGER) SERVER influxdb_svr OPTIONS (table 't2'); ---Testcase 67: +--Testcase 77: CREATE FOREIGN TABLE t3 (fields jsonb OPTIONS (fields 'true')) SERVER influxdb_svr OPTIONS(schemaless 'true'); +--Testcase 579: CREATE FOREIGN TABLE t3_nsc (name TEXT, n INTEGER) SERVER influxdb_svr OPTIONS (table 't3'); ---Testcase 68: +--Testcase 78: INSERT INTO t1_nsc VALUES ( 'bb', 11 ); ---Testcase 69: +--Testcase 79: INSERT INTO t2_nsc VALUES ( 'bb', 12 ); ---Testcase 70: +--Testcase 80: INSERT INTO t2_nsc VALUES ( 'cc', 22 ); ---Testcase 71: +--Testcase 81: INSERT INTO t2_nsc VALUES ( 'ee', 42 ); ---Testcase 72: +--Testcase 82: INSERT INTO t3_nsc VALUES ( 'bb', 13 ); ---Testcase 73: +--Testcase 83: INSERT INTO t3_nsc VALUES ( 'cc', 23 ); ---Testcase 74: +--Testcase 84: INSERT INTO t3_nsc VALUES ( 'dd', 33 ); ---Testcase 75: +--Testcase 85: SELECT * FROM (select fields->>'name' "name", (fields->>'n')::int n from t1) t1 FULL JOIN (select fields->>'name' "name", (fields->>'n')::int n from t2) t2 USING (name) FULL JOIN (select fields->>'name' "name", (fields->>'n')::int n from t3) t3 USING (name); -- @@ -342,21 +377,21 @@ SELECT * FROM (select fields->>'name' "name", (fields->>'n')::int n from t1) t1 -- -- Basic cases (we expect planner to pull up the subquery here) ---Testcase 76: +--Testcase 86: SELECT * FROM (SELECT * FROM (select fields->>'name' "name", (fields->>'n')::int n from t2) t2) as s2 INNER JOIN (SELECT * FROM (select fields->>'name' "name", (fields->>'n')::int n from t3) t3) s3 USING (name); ---Testcase 77: +--Testcase 87: SELECT * FROM (SELECT * FROM (select fields->>'name' "name", (fields->>'n')::int n from t2) t2) as s2 LEFT JOIN (SELECT * FROM (select fields->>'name' "name", (fields->>'n')::int n from t3) t3) s3 USING (name); ---Testcase 78: +--Testcase 88: SELECT * FROM (SELECT * FROM (select fields->>'name' "name", (fields->>'n')::int n from t2) t2) as s2 FULL JOIN @@ -365,25 +400,25 @@ USING (name); -- Cases with non-nullable expressions in subquery results; -- make sure these go to null as expected ---Testcase 79: +--Testcase 89: SELECT * FROM (SELECT fields->>'name' "name", (fields->>'n')::int as s2_n, 2 as s2_2 FROM t2) as s2 NATURAL INNER JOIN (SELECT fields->>'name' "name", (fields->>'n')::int as s3_n, 3 as s3_2 FROM t3) s3; ---Testcase 80: +--Testcase 90: SELECT * FROM (SELECT fields->>'name' "name", (fields->>'n')::int as s2_n, 2 as s2_2 FROM t2) as s2 NATURAL LEFT JOIN (SELECT fields->>'name' "name", (fields->>'n')::int as s3_n, 3 as s3_2 FROM t3) s3; ---Testcase 81: +--Testcase 91: SELECT * FROM (SELECT fields->>'name' "name", (fields->>'n')::int as s2_n, 2 as s2_2 FROM t2) as s2 NATURAL FULL JOIN (SELECT fields->>'name' "name", (fields->>'n')::int as s3_n, 3 as s3_2 FROM t3) s3; ---Testcase 82: +--Testcase 92: SELECT * FROM (SELECT fields->>'name' "name", (fields->>'n')::int as s1_n, 1 as s1_1 FROM t1) as s1 NATURAL INNER JOIN @@ -391,7 +426,7 @@ NATURAL INNER JOIN NATURAL INNER JOIN (SELECT fields->>'name' "name", (fields->>'n')::int as s3_n, 3 as s3_2 FROM t3) s3; ---Testcase 83: +--Testcase 93: SELECT * FROM (SELECT fields->>'name' "name", (fields->>'n')::int as s1_n, 1 as s1_1 FROM t1) as s1 NATURAL FULL JOIN @@ -399,7 +434,7 @@ NATURAL FULL JOIN NATURAL FULL JOIN (SELECT fields->>'name' "name", (fields->>'n')::int as s3_n, 3 as s3_2 FROM t3) s3; ---Testcase 84: +--Testcase 94: SELECT * FROM (SELECT fields->>'name' "name", (fields->>'n')::int as s1_n FROM t1) as s1 NATURAL FULL JOIN @@ -409,7 +444,7 @@ NATURAL FULL JOIN (SELECT fields->>'name' "name", (fields->>'n')::int as s3_n FROM t3) as s3 ) ss2; ---Testcase 85: +--Testcase 95: SELECT * FROM (SELECT fields->>'name' "name", (fields->>'n')::int as s1_n FROM t1) as s1 NATURAL FULL JOIN @@ -420,7 +455,7 @@ NATURAL FULL JOIN ) ss2; -- Constants as join keys can also be problematic ---Testcase 86: +--Testcase 96: SELECT * FROM (SELECT fields->>'name' "name", (fields->>'n')::int as s1_n FROM t1) as s1 FULL JOIN @@ -430,60 +465,62 @@ ON ((s1_n)::int = (s2_n)::int); -- Test for propagation of nullability constraints into sub-joins ---Testcase 87: +--Testcase 97: create foreign table x (fields jsonb OPTIONS (fields 'true')) server influxdb_svr OPTIONS(schemaless 'true'); +--Testcase 580: create foreign table x_nsc (x1 int, x2 int) server influxdb_svr OPTIONS (table 'x'); ---Testcase 88: +--Testcase 98: insert into x_nsc values (1,11); ---Testcase 89: +--Testcase 99: insert into x_nsc values (2,22); ---Testcase 90: +--Testcase 100: insert into x_nsc values (3,null); ---Testcase 91: +--Testcase 101: insert into x_nsc values (4,44); ---Testcase 92: +--Testcase 102: insert into x_nsc values (5,null); ---Testcase 93: +--Testcase 103: create foreign table y (fields jsonb OPTIONS (fields 'true')) server influxdb_svr OPTIONS(schemaless 'true'); +--Testcase 581: create foreign table y_nsc (y1 int, y2 int) server influxdb_svr OPTIONS (table 'y'); ---Testcase 94: +--Testcase 104: insert into y_nsc values (1,111); ---Testcase 95: +--Testcase 105: insert into y_nsc values (2,222); ---Testcase 96: +--Testcase 106: insert into y_nsc values (3,333); ---Testcase 97: +--Testcase 107: insert into y_nsc values (4,null); ---Testcase 98: +--Testcase 108: select * from x; ---Testcase 99: +--Testcase 109: select * from y; ---Testcase 100: +--Testcase 110: select * from (select (fields->>'x1')::int x1, (fields->>'x2')::int x2 from x) x left join (select (fields->>'y1')::int y1, (fields->>'y2')::int y2 from y) y on (x1::int = y1::int and x2 is not null); ---Testcase 101: +--Testcase 111: select * from (select (fields->>'x1')::int x1, (fields->>'x2')::int x2 from x) x left join (select (fields->>'y1')::int y1, (fields->>'y2')::int y2 from y) y on (x1::int = y1::int and y2 is not null); ---Testcase 102: +--Testcase 112: select * from ((select (fields->>'x1')::int x1, (fields->>'x2')::int x2 from x) x left join (select (fields->>'y1')::int y1, (fields->>'y2')::int y2 from y) y on (x1::int = y1::int)) left join (select (fields->>'x1')::int x1, (fields->>'x2')::int x2 from x) xx(xx1,xx2) on (x1::int = xx1::int); ---Testcase 103: +--Testcase 113: select * from ((select (fields->>'x1')::int x1, (fields->>'x2')::int x2 from x) x left join (select (fields->>'y1')::int y1, (fields->>'y2')::int y2 from y) y on (x1::int = y1::int)) left join (select (fields->>'x1')::int x1, (fields->>'x2')::int x2 from x) xx(xx1,xx2) on (x1::int = xx1::int and x2 is not null); ---Testcase 104: +--Testcase 114: select * from ((select (fields->>'x1')::int x1, (fields->>'x2')::int x2 from x) x left join (select (fields->>'y1')::int y1, (fields->>'y2')::int y2 from y) y on (x1::int = y1::int)) left join (select (fields->>'x1')::int x1, (fields->>'x2')::int x2 from x) xx(xx1,xx2) on (x1::int = xx1::int and y2 is not null); ---Testcase 105: +--Testcase 115: select * from ((select (fields->>'x1')::int x1, (fields->>'x2')::int x2 from x) x left join (select (fields->>'y1')::int y1, (fields->>'y2')::int y2 from y) y on (x1::int = y1::int)) left join (select (fields->>'x1')::int x1, (fields->>'x2')::int x2 from x) xx(xx1,xx2) on (x1::int = xx1::int and xx2 is not null); -- these should NOT give the same answers as above ---Testcase 106: +--Testcase 116: select * from ((select (fields->>'x1')::int x1, (fields->>'x2')::int x2 from x) x left join (select (fields->>'y1')::int y1, (fields->>'y2')::int y2 from y) y on (x1::int = y1::int)) left join (select (fields->>'x1')::int x1, (fields->>'x2')::int x2 from x) xx(xx1,xx2) on (x1::int = xx1::int) where (x2 is not null); ---Testcase 107: +--Testcase 117: select * from ((select (fields->>'x1')::int x1, (fields->>'x2')::int x2 from x) x left join (select (fields->>'y1')::int y1, (fields->>'y2')::int y2 from y) y on (x1::int = y1::int)) left join (select (fields->>'x1')::int x1, (fields->>'x2')::int x2 from x) xx(xx1,xx2) on (x1::int = xx1::int) where (y2 is not null); ---Testcase 108: +--Testcase 118: select * from ((select (fields->>'x1')::int x1, (fields->>'x2')::int x2 from x) x left join (select (fields->>'y1')::int y1, (fields->>'y2')::int y2 from y) y on (x1::int = y1::int)) left join (select (fields->>'x1')::int x1, (fields->>'x2')::int x2 from x) xx(xx1,xx2) on (x1::int = xx1::int) where (xx2 is not null); @@ -491,7 +528,7 @@ on (x1::int = xx1::int) where (xx2 is not null); -- regression test: check for bug with propagation of implied equality -- to outside an IN -- ---Testcase 109: +--Testcase 119: select count(*) from (select (fields->>'unique1')::int4 unique1, (fields->>'unique2')::int4 unique2, (fields->>'two')::int4 two, (fields->>'four')::int4 four, (fields->>'ten')::int4 ten, (fields->>'twenty')::int4 twenty, (fields->>'hundred')::int4 hundred, (fields->>'thousand')::int4 thousand, (fields->>'twothousand')::int4 twothousand, (fields->>'fivethous')::int4 fivethous, (fields->>'tenthous')::int4 tenthous, (fields->>'odd')::int4 odd, (fields->>'even')::int4 even, (fields->>'stringu1')::name stringu1, (fields->>'stringu2')::name stringu2, (fields->>'string4')::name string4 from tenk1) a where unique1 in (select unique1 from (select (fields->>'unique1')::int4 unique1, (fields->>'unique2')::int4 unique2, (fields->>'two')::int4 two, (fields->>'four')::int4 four, (fields->>'ten')::int4 ten, (fields->>'twenty')::int4 twenty, (fields->>'hundred')::int4 hundred, (fields->>'thousand')::int4 thousand, (fields->>'twothousand')::int4 twothousand, (fields->>'fivethous')::int4 fivethous, (fields->>'tenthous')::int4 tenthous, (fields->>'odd')::int4 odd, (fields->>'even')::int4 even, (fields->>'stringu1')::name stringu1, (fields->>'stringu2')::name stringu2, (fields->>'string4')::name string4 from tenk1) b join (select (fields->>'unique1')::int4 unique1, (fields->>'unique2')::int4 unique2, (fields->>'two')::int4 two, (fields->>'four')::int4 four, (fields->>'ten')::int4 ten, (fields->>'twenty')::int4 twenty, (fields->>'hundred')::int4 hundred, (fields->>'thousand')::int4 thousand, (fields->>'twothousand')::int4 twothousand, (fields->>'fivethous')::int4 fivethous, (fields->>'tenthous')::int4 tenthous, (fields->>'odd')::int4 odd, (fields->>'even')::int4 even, (fields->>'stringu1')::name stringu1, (fields->>'stringu2')::name stringu2, (fields->>'string4')::name string4 from tenk1) c using (unique1) where b.unique2::int4 = 42); @@ -500,7 +537,7 @@ select count(*) from (select (fields->>'unique1')::int4 unique1, (fields->>'uniq -- regression test: check for failure to generate a plan with multiple -- degenerate IN clauses -- ---Testcase 110: +--Testcase 120: select count(*) from (select (fields->>'unique1')::int4 unique1, (fields->>'unique2')::int4 unique2, (fields->>'two')::int4 two, (fields->>'four')::int4 four, (fields->>'ten')::int4 ten, (fields->>'twenty')::int4 twenty, (fields->>'hundred')::int4 hundred, (fields->>'thousand')::int4 thousand, (fields->>'twothousand')::int4 twothousand, (fields->>'fivethous')::int4 fivethous, (fields->>'tenthous')::int4 tenthous, (fields->>'odd')::int4 odd, (fields->>'even')::int4 even, (fields->>'stringu1')::name stringu1, (fields->>'stringu2')::name stringu2, (fields->>'string4')::name string4 from tenk1) x where (x.unique1)::int4 in (select (a.fields->>'f1')::int4 from int4_tbl a,float8_tbl b where (a.fields->>'f1')::int4=(b.fields->>'f1')::float8) and (x.unique1)::int4 = 0 and @@ -508,11 +545,11 @@ select count(*) from (select (fields->>'unique1')::int4 unique1, (fields->>'uniq -- try that with GEQO too begin; ---Testcase 111: +--Testcase 121: set geqo = on; ---Testcase 112: +--Testcase 122: set geqo_threshold = 2; ---Testcase 113: +--Testcase 123: select count(*) from (select (fields->>'unique1')::int4 unique1, (fields->>'unique2')::int4 unique2, (fields->>'two')::int4 two, (fields->>'four')::int4 four, (fields->>'ten')::int4 ten, (fields->>'twenty')::int4 twenty, (fields->>'hundred')::int4 hundred, (fields->>'thousand')::int4 thousand, (fields->>'twothousand')::int4 twothousand, (fields->>'fivethous')::int4 fivethous, (fields->>'tenthous')::int4 tenthous, (fields->>'odd')::int4 odd, (fields->>'even')::int4 even, (fields->>'stringu1')::name stringu1, (fields->>'stringu2')::name stringu2, (fields->>'string4')::name string4 from tenk1) x where (x.unique1)::int4 in (select a.f1 from (select (fields->>'f1')::int4 f1 from INT4_TBL) a,(select (fields->>'f1')::float8 f1 from FLOAT8_TBL) b where a.f1::int4=b.f1::float8) and (x.unique1)::int4 = 0 and @@ -522,41 +559,41 @@ rollback; -- -- regression test: be sure we cope with proven-dummy append rels -- ---Testcase 114: -create table b (aa int, bb int); +--Testcase 124: +CREATE FOREIGN TABLE b_star(fields jsonb OPTIONS (fields 'true')) SERVER influxdb_svr OPTIONS(schemaless 'true'); ---Testcase 115: +--Testcase 125: explain (costs off) -select aa, bb, tenk1.unique1::int, tenk1.unique1::int - from (select (fields->>'unique1')::int unique1, fields->>'unique2' unique2, fields->>'two' two, fields->>'four' four, fields->>'ten' ten, fields->>'twenty' twenty, fields->>'hundred' hundred, fields->>'thousand' thousand, fields->>'twothousand' twothousand, fields->>'fivethous' fivethous, fields->>'tenthous' tenthous, fields->>'odd' odd, fields->>'even' even, fields->>'stringu1' stringu1, fields->>'stringu2' stringu2, fields->>'string4' string4 from tenk1) tenk1 right join b on aa = tenk1.unique1::int - where bb < bb and bb is null; +select b_star.aa::int4, bb, tenk1.unique1::int, tenk1.unique1::int + from (select (fields->>'unique1')::int unique1, fields->>'unique2' unique2, fields->>'two' two, fields->>'four' four, fields->>'ten' ten, fields->>'twenty' twenty, fields->>'hundred' hundred, fields->>'thousand' thousand, fields->>'twothousand' twothousand, fields->>'fivethous' fivethous, fields->>'tenthous' tenthous, fields->>'odd' odd, fields->>'even' even, fields->>'stringu1' stringu1, fields->>'stringu2' stringu2, fields->>'string4' string4 from tenk1) tenk1 right join (select (fields->>'class')::char class, (fields->>'aa')::int4 aa, fields->>'bb' bb, (fields->>'a')::int4 a from b_star) b_star on b_star.aa::int4 = tenk1.unique1::int + where b_star.bb < b_star.bb and b_star.bb is null; ---Testcase 116: -select aa, bb, tenk1.unique1::int, tenk1.unique1::int - from (select (fields->>'unique1')::int unique1, fields->>'unique2' unique2, fields->>'two' two, fields->>'four' four, fields->>'ten' ten, fields->>'twenty' twenty, fields->>'hundred' hundred, fields->>'thousand' thousand, fields->>'twothousand' twothousand, fields->>'fivethous' fivethous, fields->>'tenthous' tenthous, fields->>'odd' odd, fields->>'even' even, fields->>'stringu1' stringu1, fields->>'stringu2' stringu2, fields->>'string4' string4 from tenk1) tenk1 right join b on aa = tenk1.unique1::int - where bb < bb and bb is null; +--Testcase 126: +select b_star.aa::int4, bb, tenk1.unique1::int, tenk1.unique1::int + from (select (fields->>'unique1')::int unique1, fields->>'unique2' unique2, fields->>'two' two, fields->>'four' four, fields->>'ten' ten, fields->>'twenty' twenty, fields->>'hundred' hundred, fields->>'thousand' thousand, fields->>'twothousand' twothousand, fields->>'fivethous' fivethous, fields->>'tenthous' tenthous, fields->>'odd' odd, fields->>'even' even, fields->>'stringu1' stringu1, fields->>'stringu2' stringu2, fields->>'string4' string4 from tenk1) tenk1 right join (select (fields->>'class')::char class, (fields->>'aa')::int4 aa, fields->>'bb' bb, (fields->>'a')::int4 a from b_star) b_star on b_star.aa::int4 = tenk1.unique1::int + where b_star.bb < b_star.bb and b_star.bb is null; ---Testcase 117: -drop table b; +--Testcase 127: +drop foreign table b_star; -- -- regression test: check handling of empty-FROM subquery underneath outer join -- ---Testcase 118: +--Testcase 128: explain (costs off) select (i1.fields->>'q1')::int8 q1, (i1.fields->>'q2')::int8 q2, (i2.fields->>'q1')::int8 q1, (i2.fields->>'q2')::int8 q2, x from int8_tbl i1 left join (int8_tbl i2 join (select 123 as x) ss on (i2.fields->>'q1')::int8 = x) on (i1.fields->>'q2')::int8 = (i2.fields->>'q2')::int8 order by 1, 2; ---Testcase 119: +--Testcase 129: select (i1.fields->>'q1')::int8 q1, (i1.fields->>'q2')::int8 q2, (i2.fields->>'q1')::int8 q1, (i2.fields->>'q2')::int8 q2, x from int8_tbl i1 left join (int8_tbl i2 join (select 123 as x) ss on (i2.fields->>'q1')::int8 = x) on (i1.fields->>'q2')::int8= (i2.fields->>'q2')::int8 order by 1, 2; -- --- regression test: check a case where join_clause_is_movable_into() gives --- an imprecise result, causing an assertion failure +-- regression test: check a case where join_clause_is_movable_into() +-- used to give an imprecise result, causing an assertion failure -- ---Testcase 120: +--Testcase 130: select count(*) from (select (t3.fields->>'tenthous')::int4 as x1, coalesce((t1.fields->>'stringu1')::name, (t2.fields->>'stringu1')::name) as x2 @@ -571,7 +608,7 @@ where (t4.fields->>'thousand')::int4 = (t5.fields->>'unique1')::int4 and ss.x1 = -- regression test: check a case where we formerly missed including an EC -- enforcement clause because it was expected to be handled at scan level -- ---Testcase 121: +--Testcase 131: explain (costs off) select a.f1, b.f1, (t.fields->>'thousand')::int4 thousand, (t.fields->>'tenhous')::int4 tenthous from tenk1 t, @@ -579,25 +616,134 @@ select a.f1, b.f1, (t.fields->>'thousand')::int4 thousand, (t.fields->>'tenhous' (select sum((fields->>'f1')::int4) as f1 from int4_tbl i4b) b where b.f1 = (t.fields->>'thousand')::int4 and a.f1 = b.f1 and (a.f1+b.f1+999) = (t.fields->>'tenthous')::int4; ---Testcase 122: +--Testcase 132: select a.f1, b.f1, (t.fields->>'thousand')::int4 thousand, (t.fields->>'tenhous')::int4 tenthous from tenk1 t, (select sum((fields->>'f1')::int4)+1 as f1 from int4_tbl i4a) a, (select sum((fields->>'f1')::int4) as f1 from int4_tbl i4b) b where b.f1 = (t.fields->>'thousand')::int4 and a.f1 = b.f1 and (a.f1+b.f1+999) = (t.fields->>'tenthous')::int4; +-- +-- checks for correct handling of quals in multiway outer joins +-- +explain (costs off) +select (t1.fields->>'f1')::int4 as f1 +from int4_tbl t1, int4_tbl t2 + left join int4_tbl t3 on (t3.fields->>'f1')::int4 > 0 + left join int4_tbl t4 on (t3.fields->>'f1')::int4 > 1 +where (t4.fields->>'f1')::int4 is null; + +select (t1.fields->>'f1')::int4 as f1 +from int4_tbl t1, int4_tbl t2 + left join int4_tbl t3 on (t3.fields->>'f1')::int4 > 0 + left join int4_tbl t4 on (t3.fields->>'f1')::int4 > 1 +where (t4.fields->>'f1')::int4 is null; + +explain (costs off) +select * +from int4_tbl t1 left join int4_tbl t2 on true + left join int4_tbl t3 on (t2.fields->>'f1')::int4 > 0 + left join int4_tbl t4 on (t3.fields->>'f1')::int4 > 0; + +explain (costs off) +select * from onek t1 + left join onek t2 on (t1.fields->>'unique1')::int4 = (t2.fields->>'unique1')::int4 + left join onek t3 on (t2.fields->>'unique1')::int4 != (t3.fields->>'unique1')::int4 + left join onek t4 on (t3.fields->>'unique1')::int4 = (t4.fields->>'unique1')::int4; + +explain (costs off) +select * from int4_tbl t1 + left join (select now() from int4_tbl t2 + left join int4_tbl t3 on (t2.fields->>'f1')::int4 = (t3.fields->>'f1')::int4 + left join int4_tbl t4 on (t3.fields->>'f1')::int4 = (t4.fields->>'f1')::int4) s on true + inner join int4_tbl t5 on true; + +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.fields->>'f1')::int4 = (t3.fields->>'f1')::int4; + +explain (costs off) +select * from int4_tbl t1 + left join int4_tbl t2 on true + left join int4_tbl t3 on (t2.fields->>'f1')::int4 = (t3.fields->>'f1')::int4 + left join int4_tbl t4 on (t3.fields->>'f1')::int4 != (t4.fields->>'f1')::int4; + +explain (costs off) +select * from int4_tbl t1 + left join (int4_tbl t2 left join int4_tbl t3 on (t2.fields->>'f1')::int4 > 0) on (t2.fields->>'f1')::int4 > 1 + left join int4_tbl t4 on (t2.fields->>'f1')::int4 > 2 and (t3.fields->>'f1')::int4 > 3 +where (t1.fields->>'f1')::int4 = coalesce((t2.fields->>'f1')::int4, 1); + +explain (costs off) +select * from int4_tbl t1 + left join ((select (t2.fields->>'f1')::int4 as f1 from int4_tbl t2 + left join int4_tbl t3 on (t2.fields->>'f1')::int4 > 0 + where (t3.fields->>'f1')::int4 is null) s + left join tenk1 t4 on s.f1 > 1) + on s.f1 = (t1.fields->>'f1')::int4; + +explain (costs off) +select * from int4_tbl t1 + left join ((select (t2.fields->>'f1')::int4 as f1 from int4_tbl t2 + left join int4_tbl t3 on (t2.fields->>'f1')::int4 > 0 + where (t2.fields->>'f1')::int4 <> coalesce((t3.fields->>'f1')::int4, -1)) s + left join tenk1 t4 on s.f1 > 1) + on s.f1 = (t1.fields->>'f1')::int4; + +explain (costs off) +select * from onek t1 + left join onek t2 on (t1.fields->>'unique1')::int4 = (t2.fields->>'unique1')::int4 + left join onek t3 on (t2.fields->>'unique1')::int4 = (t3.fields->>'unique1')::int4 + left join onek t4 on (t3.fields->>'unique1')::int4 = (t4.fields->>'unique1')::int4 and (t2.fields->>'unique2')::int4 = (t4.fields->>'unique2')::int4; + +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.fields->>'q1')::int4 = (t5.fields->>'q1')::int4 +on (t2.fields->>'q2')::int4 = 123; + +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.fields->>'q1')::int4 = (t2.fields->>'q1')::int4 offset 0) s + on (t2.fields->>'q1')::int4 = 1; + +explain (costs off) +select * from int8_tbl t1 + left join int8_tbl t2 on true + left join lateral + (select * from generate_series((t2.fields->>'q1')::int4, 100)) s + on (t2.fields->>'q1')::int4 = 1; + +explain (costs off) +select * from int8_tbl t1 + left join int8_tbl t2 on true + left join lateral + (select (t2.fields->>'q1')::int4 from int8_tbl t3) s + on (t2.fields->>'q1')::int4 = 1; + +explain (costs off) +select * from onek t1 + left join onek t2 on true + left join lateral + (select * from onek t3 where (t3.fields->>'two')::int4 = (t2.fields->>'two')::int4 offset 0) s + on (t2.fields->>'unique1')::int4 = 1; + -- -- check a case where we formerly got confused by conflicting sort orders -- in redundant merge join path keys -- ---Testcase 123: +--Testcase 133: explain (costs off) select * from (SELECT (fields->>'i')::int i,(fields->>'j')::int j,fields->>'t' t FROM J1_TBL j1_tbl) j1_tbl full join (select * from (select (fields->>'i')::int i, (fields->>'k')::int k from J2_TBL j2_tbl) j2_tbl order by (j2_tbl.i)::int desc, (j2_tbl.k)::int asc) j2_tbl on (j1_tbl.i)::int = (j2_tbl.i)::int and (j1_tbl.i)::int = (j2_tbl.k)::int; ---Testcase 124: +--Testcase 134: select * from (select (fields->>'i')::int i, (fields->>'j')::int j,fields->>'t' t from J1_TBL j1_tbl) j1_tbl full join (select * from (select (fields->>'i')::int i, (fields->>'k')::int k from J2_TBL j2_tbl) j2_tbl order by (j2_tbl.i)::int desc, (j2_tbl.k)::int asc) j2_tbl @@ -606,7 +752,7 @@ select * from -- -- a different check for handling of redundant sort keys in merge joins -- ---Testcase 125: +--Testcase 135: explain (costs off) select count(*) from (select * from tenk1 x order by (x.fields->>'thousand')::int4, (x.fields->>'twothousand')::int4, (x.fields->>'fivethous')::int4) x @@ -614,207 +760,308 @@ select count(*) from (select * from tenk1 y order by (y.fields->>'unique2')::int4) y on (x.fields->>'thousand')::int4 = (y.fields->>'unique2')::int4 and (x.fields->>'twothousand')::int4 = (y.fields->>'hundred')::int4 and (x.fields->>'fivethous')::int4 = (y.fields->>'unique2')::int4; ---Testcase 126: +--Testcase 136: select count(*) from (select * from tenk1 x order by (x.fields->>'thousand')::int4, (x.fields->>'twothousand')::int4, (x.fields->>'fivethous')::int4) x left join (select * from tenk1 y order by (y.fields->>'unique2')::int4) y on (x.fields->>'thousand')::int4 = (y.fields->>'unique2')::int4 and (x.fields->>'twothousand')::int4 = (y.fields->>'hundred')::int4 and (x.fields->>'fivethous')::int4 = (y.fields->>'unique2')::int4; +set enable_hashjoin = 0; +set enable_nestloop = 0; +set enable_hashagg = 0; + +-- +-- 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.fields->>'thousand')::int4 as thousand, (x.fields->>'twothousand')::int4 as twothousand, count(*) +from tenk1 x inner join tenk1 y on (x.fields->>'thousand')::int4 = (y.fields->>'thousand')::int4 +group by (x.fields->>'thousand'), (x.fields->>'twothousand') +order by (x.fields->>'thousand') desc, (x.fields->>'twothousand'); + +reset enable_hashagg; +reset enable_nestloop; +reset enable_hashjoin; -- -- Clean up -- ---Testcase 127: +--Testcase 137: DELETE FROM t1_nsc; ---Testcase 128: +--Testcase 138: DELETE FROM t2_nsc; ---Testcase 129: +--Testcase 139: DELETE FROM t3_nsc; ---Testcase 130: +--Testcase 140: DROP FOREIGN TABLE t1; +--Testcase 582: DROP FOREIGN TABLE t1_nsc; ---Testcase 131: +--Testcase 141: DROP FOREIGN TABLE t2; +--Testcase 583: DROP FOREIGN TABLE t2_nsc; ---Testcase 132: +--Testcase 142: DROP FOREIGN TABLE t3; +--Testcase 584: DROP FOREIGN TABLE t3_nsc; ---Testcase 133: +--Testcase 143: DELETE FROM j1_tbl_nsc; +--Testcase 585: DROP FOREIGN TABLE J1_TBL; +--Testcase 586: DROP FOREIGN TABLE j1_tbl_nsc; ---Testcase 134: +--Testcase 144: DELETE FROM j2_tbl_nsc; +--Testcase 587: DROP FOREIGN TABLE J2_TBL; +--Testcase 588: DROP FOREIGN TABLE j2_tbl_nsc; +--Testcase 589: DELETE FROM x_nsc; +--Testcase 590: DELETE FROM y_nsc; +--Testcase 591: DROP FOREIGN TABLE x_nsc; +--Testcase 592: DROP FOREIGN TABLE y_nsc; -- Both DELETE and UPDATE allow the specification of additional tables -- to "join" against to determine which rows should be modified. ---Testcase 135: +--Testcase 145: CREATE FOREIGN TABLE t1 (fields jsonb OPTIONS (fields 'true')) SERVER influxdb_svr OPTIONS(schemaless 'true'); +--Testcase 593: CREATE FOREIGN TABLE t1_nsc (a int, b int) SERVER influxdb_svr OPTIONS (table 't1'); ---Testcase 136: +--Testcase 146: CREATE FOREIGN TABLE t2 (fields jsonb OPTIONS (fields 'true')) SERVER influxdb_svr OPTIONS(schemaless 'true'); +--Testcase 594: CREATE FOREIGN TABLE t2_nsc (a int, b int) SERVER influxdb_svr OPTIONS (table 't2'); ---Testcase 137: +--Testcase 147: CREATE FOREIGN TABLE t3 (fields jsonb OPTIONS (fields 'true')) SERVER influxdb_svr OPTIONS(schemaless 'true'); +--Testcase 595: CREATE FOREIGN TABLE t3_nsc (x int, y int) SERVER influxdb_svr OPTIONS (table 't3'); ---Testcase 138: +--Testcase 148: INSERT INTO t1_nsc VALUES (5, 10); ---Testcase 139: +--Testcase 149: INSERT INTO t1_nsc VALUES (15, 20); ---Testcase 140: +--Testcase 150: INSERT INTO t1_nsc VALUES (100, 100); ---Testcase 141: +--Testcase 151: INSERT INTO t1_nsc VALUES (200, 1000); ---Testcase 142: +--Testcase 152: INSERT INTO t2_nsc VALUES (200, 2000); ---Testcase 143: +--Testcase 153: INSERT INTO t3_nsc VALUES (5, 20); ---Testcase 144: +--Testcase 154: INSERT INTO t3_nsc VALUES (6, 7); ---Testcase 145: +--Testcase 155: INSERT INTO t3_nsc VALUES (7, 8); ---Testcase 146: +--Testcase 156: INSERT INTO t3_nsc VALUES (500, 100); ---Testcase 147: +--Testcase 157: ALTER TABLE t3 ADD time timestamp; ALTER TABLE t3_nsc ADD time timestamp; ---Testcase 148: +--Testcase 158: SELECT (fields->>'x')::int x, (fields->>'y')::int y FROM t3; ---Testcase 149: +--Testcase 159: DELETE FROM t3_nsc USING t1_nsc table1 WHERE t3_nsc.x = table1.a; ---Testcase 150: +--Testcase 160: SELECT (fields->>'x')::int x, (fields->>'y')::int y FROM t3; ---Testcase 151: +--Testcase 161: DELETE FROM t3_nsc USING t1_nsc JOIN t2_nsc USING (a) WHERE t3_nsc.x > t1_nsc.a; ---Testcase 152: +--Testcase 162: SELECT (fields->>'x')::int x, (fields->>'y')::int y FROM t3; ---Testcase 153: +--Testcase 163: DELETE FROM t3_nsc USING t3_nsc t3_other WHERE t3_nsc.x = t3_other.x AND t3_nsc.y = t3_other.y; ---Testcase 154: +--Testcase 164: SELECT (fields->>'x')::int x, (fields->>'y')::int y FROM t3; -- Test join against inheritance tree ---Testcase 155: +--Testcase 165: create temp table t2a () inherits (t2); ---Testcase 156: +--Testcase 166: insert into t2a values ('{"a": "200", "b": "2001"}'); ---Testcase 157: +--Testcase 167: select * from (select (fields->>'a')::int a, (fields->>'b')::int b from t1) t1 left join (select (fields->>'a')::int a, (fields->>'b')::int b from t2) t2 on (t1.a::int = t2.a::int); -- Test matching of column name with wrong alias ---Testcase 158: +--Testcase 168: select t1.x from (select (fields->>'a')::int a, (fields->>'b')::int b from t1) t1 join (select (fields->>'x')::int x, (fields->>'y')::int y from t3) t3 on (t1.a::int = t3.x::int); -- Test matching of locking clause with wrong alias +--Testcase 666: select t1.*, t2.*, unnamed_join.* from (select (fields->>'a')::int a, (fields->>'b')::int b from t1) t1 join (select (fields->>'a')::int a, (fields->>'b')::int b from t2) t2 on (t1.a::int = t2.a::int), t3 as unnamed_join for update of unnamed_join; +--Testcase 667: +select foo.*, unnamed_join.* from + (select (fields->>'a')::int a, (fields->>'b')::int b from t1) t1 join (select (fields->>'a')::int a, (fields->>'b')::int b from t2) t2 using (a) as foo, t3 as unnamed_join + for update of unnamed_join; + +--Testcase 668: +select foo.*, unnamed_join.* from + (select (fields->>'a')::int a, (fields->>'b')::int b from t1) t1 join (select (fields->>'a')::int a, (fields->>'b')::int b from t2) t2 using (a) as foo, t3 as unnamed_join + for update of foo; + +--Testcase 669: +select bar.*, unnamed_join.* from + ((select (fields->>'a')::int a, (fields->>'b')::int b from t1) t1 join (select (fields->>'a')::int a, (fields->>'b')::int b from t2) t2 using (a) as foo) as bar, t3 as unnamed_join + for update of foo; + +--Testcase 670: +select bar.*, unnamed_join.* from + ((select (fields->>'a')::int a, (fields->>'b')::int b from t1) t1 join (select (fields->>'a')::int a, (fields->>'b')::int b from t2) t2 using (a) as foo) as bar, t3 as unnamed_join + for update of bar; + -- -- regression test for 8.1 merge right join bug -- ---Testcase 159: +--Testcase 169: CREATE FOREIGN TABLE tt1 ( fields jsonb OPTIONS (fields 'true') ) SERVER influxdb_svr OPTIONS(schemaless 'true'); +--Testcase 596: CREATE FOREIGN TABLE tt1_nsc ( tt1_id int4, joincol int4 ) SERVER influxdb_svr OPTIONS (table 'tt1'); ---Testcase 160: +--Testcase 170: INSERT INTO tt1_nsc VALUES (1, 11); ---Testcase 161: +--Testcase 171: INSERT INTO tt1_nsc VALUES (2, NULL); ---Testcase 162: +--Testcase 172: CREATE FOREIGN TABLE tt2 ( fields jsonb OPTIONS (fields 'true') ) SERVER influxdb_svr OPTIONS(schemaless 'true'); +--Testcase 597: CREATE FOREIGN TABLE tt2_nsc ( tt2_id int4, joincol int4 ) SERVER influxdb_svr OPTIONS (table 'tt2'); ---Testcase 163: +--Testcase 173: INSERT INTO tt2_nsc VALUES (21, 11); ---Testcase 164: +--Testcase 174: INSERT INTO tt2_nsc VALUES (22, 11); ---Testcase 165: +--Testcase 175: set enable_hashjoin to off; ---Testcase 166: +--Testcase 176: set enable_nestloop to off; -- these should give the same results ---Testcase 167: +--Testcase 177: select tt1.*, tt2.* from (select (fields->>'tt1_id')::int4 tt1_id, (fields->>'joincol')::int4 joincol from tt1) tt1 left join (select (fields->>'tt2_id')::int4 tt2_id, (fields->>'joincol')::int4 joincol from tt2) tt2 on tt1.joincol::int4 = tt2.joincol::int4; ---Testcase 168: +--Testcase 178: select tt1.*, tt2.* from (select (fields->>'tt2_id')::int4 tt2_id, (fields->>'joincol')::int4 joincol from tt2) tt2 right join (select (fields->>'tt1_id')::int4 tt1_id, (fields->>'joincol')::int4 joincol from tt1) tt1 on tt1.joincol::int4 = tt2.joincol::int4; ---Testcase 169: +--Testcase 179: reset enable_hashjoin; ---Testcase 170: +--Testcase 180: reset enable_nestloop; -- -- regression test for bug #13908 (hash join with skew tuples & nbatch increase) -- ---Testcase 171: +--Testcase 181: set work_mem to '64kB'; ---Testcase 172: +--Testcase 182: set enable_mergejoin to off; +--Testcase 183: +set enable_memoize to off; ---Testcase 173: +--Testcase 184: explain (costs off) select count(*) from tenk1 a, tenk1 b where ((a.fields->>'hundred')::int4 = (b.fields->>'thousand')::int4) and ((b.fields->>'fivethous')::int4 % 10) < 10; ---Testcase 174: +--Testcase 185: select count(*) from tenk1 a, tenk1 b where ((a.fields->>'hundred')::int4 = (b.fields->>'thousand')::int4) and ((b.fields->>'fivethous')::int4 % 10) < 10; ---Testcase 175: +--Testcase 186: reset work_mem; ---Testcase 176: +--Testcase 187: reset enable_mergejoin; +--Testcase 188: +reset enable_memoize; -- -- regression test for 8.2 bug with improper re-ordering of left joins -- ---Testcase 177: +--Testcase 189: create foreign table tt3(fields jsonb OPTIONS (fields 'true')) server influxdb_svr OPTIONS(schemaless 'true'); +--Testcase 598: create foreign table tt3_nsc(f1 int, f2 text) server influxdb_svr OPTIONS (table 'tt3'); ---Testcase 178: +--Testcase 190: insert into tt3_nsc select x, repeat('xyzzy', 100) from generate_series(1,10000) x; ---Testcase 179: +--Testcase 191: create foreign table tt4(fields jsonb OPTIONS (fields 'true')) server influxdb_svr OPTIONS(schemaless 'true'); +--Testcase 599: create foreign table tt4_nsc(f1 int) server influxdb_svr OPTIONS (table 'tt4'); ---Testcase 180: +--Testcase 192: insert into tt4_nsc values (0),(1),(9999); ---Testcase 181: -SELECT (a.fields->>'f1')::int f1 +set enable_nestloop to off; + +EXPLAIN (COSTS OFF) +SELECT (a.fields->>'f1')::int4 as f1 FROM tt4 a LEFT JOIN ( - SELECT (b.fields->>'f1')::int f1 - FROM tt3 b LEFT JOIN tt3 c ON ((b.fields->>'f1')::int = (c.fields->>'f1')::int) - WHERE c.fields->>'f1' IS NULL -) AS d ON ((a.fields->>'f1')::int = (d.f1)::int) -WHERE d.f1 IS NULL; + SELECT (b.fields->>'f1')::int4 as f1 + FROM tt3 b LEFT JOIN tt3 c ON ((b.fields->>'f1')::int4 = (c.fields->>'f1')::int4) + WHERE COALESCE((c.fields->>'f1')::int4, 0) = 0 +) AS d ON ((a.fields->>'f1')::int4 = d.f1) +WHERE COALESCE(d.f1, 0) = 0 +ORDER BY 1; + +SELECT (a.fields->>'f1')::int4 as f1 +FROM tt4 a +LEFT JOIN ( + SELECT (b.fields->>'f1')::int4 as f1 + FROM tt3 b LEFT JOIN tt3 c ON ((b.fields->>'f1')::int4 = (c.fields->>'f1')::int4) + WHERE COALESCE((c.fields->>'f1')::int4, 0) = 0 +) AS d ON ((a.fields->>'f1')::int4 = d.f1) +WHERE COALESCE(d.f1, 0) = 0 +ORDER BY 1; + +reset enable_nestloop; + +-- +-- basic semijoin and antijoin recognition tests +-- + +explain (costs off) +select a.* from tenk1 a +where (a.fields->>'unique1')::int4 in (select (b.fields->>'unique2')::int4 from tenk1 b); + +-- sadly, this is not an antijoin +explain (costs off) +select a.* from tenk1 a +where (a.fields->>'unique1')::int4 not in (select (b.fields->>'unique2')::int4 from tenk1 b); + +explain (costs off) +select a.* from tenk1 a +where exists (select 1 from tenk1 b where (a.fields->>'unique1')::int4 = (b.fields->>'unique2')::int4); + +explain (costs off) +select a.* from tenk1 a +where not exists (select 1 from tenk1 b where (a.fields->>'unique1')::int4 = (b.fields->>'unique2')::int4); + +explain (costs off) +select a.* from tenk1 a left join tenk1 b on (a.fields->>'unique1')::int4 = (b.fields->>'unique2')::int4 +where (b.fields->>'unique2')::int4 is null; -- -- regression test for proper handling of outer joins within antijoins -- ---Testcase 182: +--Testcase 194: create foreign table tt4x(fields jsonb OPTIONS (fields 'true')) server influxdb_svr OPTIONS(schemaless 'true'); ---Testcase 183: +--Testcase 195: explain (costs off) select * from tt4x t1 where not exists ( @@ -830,48 +1077,52 @@ where not exists ( -- regression test for problems of the sort depicted in bug #3494 -- ---Testcase 184: +--Testcase 196: create foreign table tt5(fields jsonb OPTIONS (fields 'true')) server influxdb_svr OPTIONS(schemaless 'true'); +--Testcase 600: create foreign table tt5_nsc(f1 int, f2 int) server influxdb_svr OPTIONS (table 'tt5'); ---Testcase 185: +--Testcase 197: create foreign table tt6(fields jsonb OPTIONS (fields 'true')) server influxdb_svr OPTIONS(schemaless 'true'); +--Testcase 601: create foreign table tt6_nsc(f1 int, f2 int) server influxdb_svr OPTIONS (table 'tt6'); ---Testcase 186: +--Testcase 198: insert into tt5_nsc values(1, 10); ---Testcase 187: +--Testcase 199: insert into tt5_nsc values(1, 11); ---Testcase 188: +--Testcase 200: insert into tt6_nsc values(1, 9); ---Testcase 189: +--Testcase 201: insert into tt6_nsc values(1, 2); ---Testcase 190: +--Testcase 202: insert into tt6_nsc values(2, 9); ---Testcase 191: +--Testcase 203: select * from (select (fields->>'f1')::int f1, (fields->>'f2')::int f2 from tt5) tt5,(select (fields->>'f1')::int f1, (fields->>'f2')::int f2 from tt6) tt6 where (tt5.f1)::int = (tt6.f1)::int and (tt5.f1)::int = (tt5.f2)::int - (tt6.f2)::int; -- -- regression test for problems of the sort depicted in bug #3588 -- ---Testcase 192: +--Testcase 204: create foreign table xx (fields jsonb OPTIONS (fields 'true')) server influxdb_svr OPTIONS(schemaless 'true'); +--Testcase 602: create foreign table xx_nsc (pkxx int) server influxdb_svr OPTIONS (table 'xx'); ---Testcase 193: +--Testcase 205: create foreign table yy (fields jsonb OPTIONS (fields 'true')) server influxdb_svr OPTIONS(schemaless 'true'); +--Testcase 603: create foreign table yy_nsc (pkyy int, pkxx int) server influxdb_svr OPTIONS (table 'yy'); ---Testcase 194: +--Testcase 206: insert into xx_nsc values (1); ---Testcase 195: +--Testcase 207: insert into xx_nsc values (2); ---Testcase 196: +--Testcase 208: insert into xx_nsc values (3); ---Testcase 197: +--Testcase 209: insert into yy_nsc values (101, 1); ---Testcase 198: +--Testcase 210: insert into yy_nsc values (201, 2); ---Testcase 199: +--Testcase 211: insert into yy_nsc values (301, NULL); ---Testcase 200: +--Testcase 212: select (yy.fields->>'pkyy')::int as yy_pkyy, (yy.fields->>'pkxx')::int as yy_pkxx, (yya.fields->>'pkyy')::int as yya_pkyy, (xxa.fields->>'pkxx')::int as xxa_pkxx, (xxb.fields->>'pkxx')::int as xxb_pkxx from yy @@ -884,28 +1135,30 @@ from yy -- (as seen in early 8.2.x releases) -- ---Testcase 201: +--Testcase 213: create foreign table zt1 (fields jsonb OPTIONS (fields 'true')) server influxdb_svr OPTIONS(schemaless 'true'); +--Testcase 604: create foreign table zt1_nsc (f1 int) server influxdb_svr OPTIONS (table 'zt1'); ---Testcase 202: +--Testcase 214: create foreign table zt2 (fields jsonb OPTIONS (fields 'true')) server influxdb_svr OPTIONS(schemaless 'true'); +--Testcase 605: create foreign table zt2_nsc (f2 int) server influxdb_svr OPTIONS (table 'zt2'); ---Testcase 203: +--Testcase 215: create foreign table zt3 (fields jsonb OPTIONS (fields 'true')) server influxdb_svr OPTIONS(schemaless 'true'); ---Testcase 204: +--Testcase 216: insert into zt1_nsc values(53); ---Testcase 205: +--Testcase 217: insert into zt2_nsc values(53); ---Testcase 206: +--Testcase 218: select * from (select (fields->>'f2')::int f2 from zt2) zt2 left join (select (fields->>'f3')::int f3 from zt3) zt3 on (f2::int = f3::int) left join (select (fields->>'f1')::int f1 from zt1) zt1 on (f3::int = f1::int) where (f2)::int = 53; ---Testcase 207: +--Testcase 219: create temp view zv1 as select *,'dummy'::text AS junk from zt1; ---Testcase 208: +--Testcase 220: select * from (select (fields->>'f2')::int f2 from zt2) zt2 left join (select (fields->>'f3')::int f3 from zt3) zt3 on (f2::int = f3::int) left join zv1 on (f3::int = (zv1.fields->>'f1')::int) @@ -916,7 +1169,7 @@ where (f2)::int = 53; -- (as seen in early 8.3.x releases) -- ---Testcase 209: +--Testcase 221: select a.unique2, a.ten, b.tenthous, b.unique2, b.hundred from (select (fields->>'unique1')::int4 unique1, (fields->>'unique2')::int4 unique2, (fields->>'two')::int4 two, (fields->>'four')::int4 four, (fields->>'ten')::int4 ten, (fields->>'twenty')::int4 twenty, (fields->>'hundred')::int4 hundred, (fields->>'thousand')::int4 thousand, (fields->>'twothousand')::int4 twothousand, (fields->>'fivethous')::int4 fivethous, (fields->>'tenthous')::int4 tenthous, (fields->>'odd')::int4 odd, (fields->>'even')::int4 even, (fields->>'stringu1')::name stringu1, (fields->>'stringu2')::name stringu2, (fields->>'string4')::name string4 from tenk1) a left join (select (fields->>'unique1')::int4 unique1, (fields->>'unique2')::int4 unique2, (fields->>'two')::int4 two, (fields->>'four')::int4 four, (fields->>'ten')::int4 ten, (fields->>'twenty')::int4 twenty, (fields->>'hundred')::int4 hundred, (fields->>'thousand')::int4 thousand, (fields->>'twothousand')::int4 twothousand, (fields->>'fivethous')::int4 fivethous, (fields->>'tenthous')::int4 tenthous, (fields->>'odd')::int4 odd, (fields->>'even')::int4 even, (fields->>'stringu1')::name stringu1, (fields->>'stringu2')::name stringu2, (fields->>'string4')::name string4 from tenk1) b on a.unique2 = b.tenthous where (a.unique1)::int4 = 42 and @@ -925,14 +1178,14 @@ where (a.unique1)::int4 = 42 and -- -- test proper positioning of one-time quals in EXISTS (8.4devel bug) -- ---Testcase 210: +--Testcase 222: prepare foo(bool) as select count(*) from (select (fields->>'unique1')::int4 unique1, (fields->>'unique2')::int4 unique2, (fields->>'two')::int4 two, (fields->>'four')::int4 four, (fields->>'ten')::int4 ten, (fields->>'twenty')::int4 twenty, (fields->>'hundred')::int4 hundred, (fields->>'thousand')::int4 thousand, (fields->>'twothousand')::int4 twothousand, (fields->>'fivethous')::int4 fivethous, (fields->>'tenthous')::int4 tenthous, (fields->>'odd')::int4 odd, (fields->>'even')::int4 even, (fields->>'stringu1')::name stringu1, (fields->>'stringu2')::name stringu2, (fields->>'string4')::name string4 from tenk1) a left join (select (fields->>'unique1')::int4 unique1, (fields->>'unique2')::int4 unique2, (fields->>'two')::int4 two, (fields->>'four')::int4 four, (fields->>'ten')::int4 ten, (fields->>'twenty')::int4 twenty, (fields->>'hundred')::int4 hundred, (fields->>'thousand')::int4 thousand, (fields->>'twothousand')::int4 twothousand, (fields->>'fivethous')::int4 fivethous, (fields->>'tenthous')::int4 tenthous, (fields->>'odd')::int4 odd, (fields->>'even')::int4 even, (fields->>'stringu1')::name stringu1, (fields->>'stringu2')::name stringu2, (fields->>'string4')::name string4 from tenk1) b on ((a.unique2)::int4 = (b.unique1)::int4 and exists (select 1 from (select (fields->>'unique1')::int4 unique1, (fields->>'unique2')::int4 unique2, (fields->>'two')::int4 two, (fields->>'four')::int4 four, (fields->>'ten')::int4 ten, (fields->>'twenty')::int4 twenty, (fields->>'hundred')::int4 hundred, (fields->>'thousand')::int4 thousand, (fields->>'twothousand')::int4 twothousand, (fields->>'fivethous')::int4 fivethous, (fields->>'tenthous')::int4 tenthous, (fields->>'odd')::int4 odd, (fields->>'even')::int4 even, (fields->>'stringu1')::name stringu1, (fields->>'stringu2')::name stringu2, (fields->>'string4')::name string4 from tenk1) c where (c.thousand)::int4 = (b.unique2)::int4 and $1)); ---Testcase 211: +--Testcase 223: execute foo(true); ---Testcase 212: +--Testcase 224: execute foo(false); -- @@ -941,24 +1194,24 @@ execute foo(false); begin; ---Testcase 213: +--Testcase 225: set enable_mergejoin = 1; ---Testcase 214: +--Testcase 226: set enable_hashjoin = 0; ---Testcase 215: +--Testcase 227: set enable_nestloop = 0; ---Testcase 216: +--Testcase 228: create foreign table a (fields jsonb OPTIONS (fields 'true')) server influxdb_svr OPTIONS(schemaless 'true'); ---Testcase 217: +--Testcase 229: create foreign table b (fields jsonb OPTIONS (fields 'true')) server influxdb_svr OPTIONS(schemaless 'true'); ---Testcase 218: +--Testcase 230: select * from (select (fields->>'i')::int i from a) a left join (select (fields->>'x')::int x, (fields->>'y')::int y from b) b on i::int = x::int and i::int = y::int and x::int = i::int; ---Testcase 219: +--Testcase 231: DROP FOREIGN TABLE a; ---Testcase 220: +--Testcase 232: DROP FOREIGN TABLE b; rollback; @@ -967,24 +1220,24 @@ rollback; -- begin; ---Testcase 221: +--Testcase 233: create type mycomptype as (id int, v bigint); ---Testcase 222: +--Testcase 234: create temp table tidv (idv mycomptype); ---Testcase 223: +--Testcase 235: create index on tidv (idv); ---Testcase 224: +--Testcase 236: explain (costs off) select a.idv, b.idv from tidv a, tidv b where a.idv = b.idv; ---Testcase 225: +--Testcase 237: set enable_mergejoin = 0; ---Testcase 226: +--Testcase 238: set enable_hashjoin = 0; ---Testcase 227: +--Testcase 239: explain (costs off) select a.idv, b.idv from tidv a, tidv b where a.idv = b.idv; @@ -993,22 +1246,22 @@ rollback; -- -- test NULL behavior of whole-row Vars, per bug #5025 -- ---Testcase 228: +--Testcase 240: select t1.q2, count(t2.*) from (select (fields->>'q1')::int8 q1, (fields->>'q2')::int8 q2 from INT8_TBL) t1 left join (select (fields->>'q1')::int8 q1, (fields->>'q2')::int8 q2 from INT8_TBL) t2 on (t1.q2 = t2.q1) group by t1.q2 order by 1; ---Testcase 229: +--Testcase 241: select (t1.fields->>'q2')::int8 q2, count(t2.*) from int8_tbl t1 left join (select * from int8_tbl) t2 on ((t1.fields->>'q2')::int8 = (t2.fields->>'q1')::int8) group by t1.fields->>'q2' order by 1; ---Testcase 230: +--Testcase 242: select (t1.fields->>'q2')::int8 q2, count(t2.*) from int8_tbl t1 left join (select * from int8_tbl offset 0) t2 on ((t1.fields->>'q2')::int8 = (t2.fields->>'q1')::int8) group by t1.fields->>'q2' order by 1; ---Testcase 231: +--Testcase 243: select (t1.fields->>'q2')::int8 q2, count(t2.*) from int8_tbl t1 left join (select (fields->>'q1')::int8 q1, case when (fields->>'q2')::int8=1 then 1 else (fields->>'q2')::int8 end as q2 from int8_tbl) t2 @@ -1020,44 +1273,47 @@ group by t1.fields->>'q2' order by 1; -- begin; ---Testcase 232: +--Testcase 244: create foreign table a ( fields jsonb OPTIONS (fields 'true') ) server influxdb_svr OPTIONS(schemaless 'true'); +--Testcase 606: create foreign table a_nsc ( code char ) server influxdb_svr OPTIONS (table 'a'); ---Testcase 233: +--Testcase 245: create foreign table b ( fields jsonb OPTIONS (fields 'true') ) server influxdb_svr OPTIONS(schemaless 'true'); +--Testcase 607: create foreign table b_nsc ( a char, num integer ) server influxdb_svr OPTIONS (table 'b'); ---Testcase 234: +--Testcase 246: create foreign table c ( fields jsonb OPTIONS (fields 'true') ) server influxdb_svr OPTIONS(schemaless 'true'); +--Testcase 608: create foreign table c_nsc ( name char, a char ) server influxdb_svr OPTIONS (table 'c'); ---Testcase 235: +--Testcase 247: insert into a_nsc (code) values ('p'); ---Testcase 236: +--Testcase 248: insert into a_nsc (code) values ('q'); ---Testcase 237: +--Testcase 249: insert into b_nsc (a, num) values ('p', 1); ---Testcase 238: +--Testcase 250: insert into b_nsc (a, num) values ('p', 2); ---Testcase 239: +--Testcase 251: insert into c_nsc (name, a) values ('A', 'p'); ---Testcase 240: +--Testcase 252: insert into c_nsc (name, a) values ('B', 'q'); ---Testcase 241: +--Testcase 253: insert into c_nsc (name, a) values ('C', null); ---Testcase 242: +--Testcase 254: select c.name, ss.code, ss.b_cnt, ss.const from (select fields->>'name' "name", fields->>'a' a from c) c left join (select a.code, coalesce(b_grp.cnt, 0) as b_cnt, -1 as const @@ -1068,20 +1324,23 @@ from (select fields->>'name' "name", fields->>'a' a from c) c left join on (c.a = ss.code) order by c.name; ---Testcase 243: +--Testcase 255: DELETE FROM a_nsc; ---Testcase 244: +--Testcase 256: DELETE FROM b_nsc; ---Testcase 245: +--Testcase 257: DELETE FROM c_nsc; ---Testcase 246: +--Testcase 258: DROP FOREIGN TABLE a; +--Testcase 609: DROP FOREIGN TABLE a_nsc; ---Testcase 247: +--Testcase 259: DROP FOREIGN TABLE b; +--Testcase 610: DROP FOREIGN TABLE b_nsc; ---Testcase 248: +--Testcase 260: DROP FOREIGN TABLE c; +--Testcase 611: DROP FOREIGN TABLE c_nsc; rollback; @@ -1089,7 +1348,7 @@ rollback; -- test incorrect handling of placeholders that only appear in targetlists, -- per bug #6154 -- ---Testcase 249: +--Testcase 261: SELECT * FROM ( SELECT 1 as key1 ) sub1 LEFT JOIN @@ -1107,7 +1366,7 @@ LEFT JOIN ON sub1.key1 = sub2.key3; -- test the path using join aliases, too ---Testcase 250: +--Testcase 262: SELECT * FROM ( SELECT 1 as key1 ) sub1 LEFT JOIN @@ -1128,7 +1387,7 @@ ON sub1.key1 = sub2.key3; -- test case where a PlaceHolderVar is used as a nestloop parameter -- ---Testcase 251: +--Testcase 263: EXPLAIN (COSTS OFF) SELECT qq, (fields->>'unique1')::int4 unique1 FROM @@ -1138,7 +1397,7 @@ SELECT qq, (fields->>'unique1')::int4 unique1 USING (qq) INNER JOIN tenk1 c ON qq = (fields->>'unique2')::int4; ---Testcase 252: +--Testcase 264: SELECT qq, (fields->>'unique1')::int4 unique1 FROM ( SELECT COALESCE((fields->>'q1')::int8, 0) AS qq FROM int8_tbl a ) AS ss1 @@ -1151,53 +1410,56 @@ SELECT qq, (fields->>'unique1')::int4 unique1 -- nested nestloops can require nested PlaceHolderVars -- ---Testcase 253: +--Testcase 265: create foreign table nt1 ( fields jsonb OPTIONS (fields 'true') ) server influxdb_svr OPTIONS(schemaless 'true'); +--Testcase 612: create foreign table nt1_nsc ( id int, a1 boolean, a2 boolean ) server influxdb_svr OPTIONS (table 'nt1'); ---Testcase 254: +--Testcase 266: create foreign table nt2 ( fields jsonb OPTIONS (fields 'true') ) server influxdb_svr OPTIONS(schemaless 'true'); +--Testcase 613: create foreign table nt2_nsc ( id int, nt1_id int, b1 boolean, b2 boolean ) server influxdb_svr OPTIONS (table 'nt2'); ---Testcase 255: +--Testcase 267: create foreign table nt3 ( fields jsonb OPTIONS (fields 'true') ) server influxdb_svr OPTIONS(schemaless 'true'); +--Testcase 614: create foreign table nt3_nsc ( id int, nt2_id int, c1 boolean ) server influxdb_svr OPTIONS (table 'nt3'); ---Testcase 256: +--Testcase 268: insert into nt1_nsc values (1,true,true); ---Testcase 257: +--Testcase 269: insert into nt1_nsc values (2,true,false); ---Testcase 258: +--Testcase 270: insert into nt1_nsc values (3,false,false); ---Testcase 259: +--Testcase 271: insert into nt2_nsc values (1,1,true,true); ---Testcase 260: +--Testcase 272: insert into nt2_nsc values (2,2,true,false); ---Testcase 261: +--Testcase 273: insert into nt2_nsc values (3,3,false,false); ---Testcase 262: +--Testcase 274: insert into nt3_nsc values (1,1,true); ---Testcase 263: +--Testcase 275: insert into nt3_nsc values (2,2,false); ---Testcase 264: +--Testcase 276: insert into nt3_nsc values (3,3,true); ---Testcase 265: +--Testcase 277: explain (costs off) select (nt3.fields->>'id')::int id from nt3 as nt3 @@ -1211,7 +1473,7 @@ from nt3 as nt3 on ss2.id = (nt3.fields->>'nt2_id')::int where (nt3.fields->>'id')::int = 1 and ss2.b3; ---Testcase 266: +--Testcase 278: select (nt3.fields->>'id')::int id from nt3 as nt3 left join @@ -1228,7 +1490,7 @@ where (nt3.fields->>'id')::int = 1 and ss2.b3; -- test case where a PlaceHolderVar is propagated into a subquery -- ---Testcase 267: +--Testcase 279: explain (costs off) select * from (select (fields->>'q1')::int8 q1, (fields->>'q2')::int8 q2 from INT8_TBL t1) t1 left join @@ -1238,7 +1500,7 @@ where 1 = (select 1 from (select (fields->>'q1')::int8 q1, (fields->>'q2')::int8 q2 from INT8_TBL t3) t3 where ss.y is not null limit 1) order by 1,2; ---Testcase 268: +--Testcase 280: select * from (select (fields->>'q1')::int8 q1, (fields->>'q2')::int8 q2 from INT8_TBL t1) t1 left join (select q1 as x, 42 as y from (select (fields->>'q1')::int8 q1, (fields->>'q2')::int8 q2 from INT8_TBL t2) t2) ss @@ -1251,7 +1513,7 @@ order by 1,2; -- variant where a PlaceHolderVar is needed at a join, but not above the join -- ---Testcase 269: +--Testcase 281: explain (costs off) select * from (select (fields->>'f1')::int4 f1 from INT4_TBL i41) as i41, @@ -1264,7 +1526,7 @@ select * from where ss1.loc = ss1.lat) as ss2 where i41.f1 > 0; ---Testcase 270: +--Testcase 282: select * from (select (fields->>'f1')::int4 f1 from INT4_TBL i41) as i41, lateral @@ -1279,28 +1541,28 @@ where i41.f1 > 0; -- -- test the corner cases FULL JOIN ON TRUE and FULL JOIN ON FALSE -- ---Testcase 271: +--Testcase 283: select * from (select (fields->>'f1')::int4 f1 from INT4_TBL) a full join (select (fields->>'f1')::int4 f1 from INT4_TBL) b on true; ---Testcase 272: +--Testcase 284: select * from (select (fields->>'f1')::int4 f1 from INT4_TBL) a full join (select (fields->>'f1')::int4 f1 from INT4_TBL) b on false; -- -- test for ability to use a cartesian join when necessary -- ---Testcase 273: +--Testcase 285: create foreign table q1 (fields jsonb OPTIONS (fields 'true')) server influxdb_svr OPTIONS(schemaless 'true'); ---Testcase 274: +--Testcase 286: create foreign table q2 (fields jsonb OPTIONS (fields 'true')) server influxdb_svr OPTIONS(schemaless 'true'); ---Testcase 275: +--Testcase 287: explain (costs off) select * from (select (fields->>'unique1')::int4 unique1, (fields->>'unique2')::int4 unique2, (fields->>'two')::int4 two, (fields->>'four')::int4 four, (fields->>'ten')::int4 ten, (fields->>'twenty')::int4 twenty, (fields->>'hundred')::int4 hundred, (fields->>'thousand')::int4 thousand, (fields->>'twothousand')::int4 twothousand, (fields->>'fivethous')::int4 fivethous, (fields->>'tenthous')::int4 tenthous, (fields->>'odd')::int4 odd, (fields->>'even')::int4 even, (fields->>'stringu1')::name stringu1, (fields->>'stringu2')::name stringu2, (fields->>'string4')::name string4 from tenk1) tenk1 join (select (fields->>'f1')::int4 f1 from INT4_TBL) INT4_TBL on (f1)::int = (twothousand)::int, (select (fields->>'q1')::int q1 from q1) q1, (select (fields->>'q2')::int q2 from q2) q2 where (q1)::int = thousand::int or (q2)::int = thousand::int; ---Testcase 276: +--Testcase 288: explain (costs off) select * from (select (fields->>'unique1')::int4 unique1, (fields->>'unique2')::int4 unique2, (fields->>'two')::int4 two, (fields->>'four')::int4 four, (fields->>'ten')::int4 ten, (fields->>'twenty')::int4 twenty, (fields->>'hundred')::int4 hundred, (fields->>'thousand')::int4 thousand, (fields->>'twothousand')::int4 twothousand, (fields->>'fivethous')::int4 fivethous, (fields->>'tenthous')::int4 tenthous, (fields->>'odd')::int4 odd, (fields->>'even')::int4 even, (fields->>'stringu1')::name stringu1, (fields->>'stringu2')::name stringu2, (fields->>'string4')::name string4 from tenk1) tenk1 join (select (fields->>'f1')::int4 f1 from INT4_TBL) INT4_TBL on (f1)::int = (twothousand)::int, @@ -1311,7 +1573,7 @@ where (thousand)::int = ((q1)::int + (q2)::int); -- test ability to generate a suitable plan for a star-schema query -- ---Testcase 277: +--Testcase 289: explain (costs off) select * from (select (fields->>'unique1')::int4 unique1, (fields->>'unique2')::int4 unique2, (fields->>'two')::int4 two, (fields->>'four')::int4 four, (fields->>'ten')::int4 ten, (fields->>'twenty')::int4 twenty, (fields->>'hundred')::int4 hundred, (fields->>'thousand')::int4 thousand, (fields->>'twothousand')::int4 twothousand, (fields->>'fivethous')::int4 fivethous, (fields->>'tenthous')::int4 tenthous, (fields->>'odd')::int4 odd, (fields->>'even')::int4 even, (fields->>'stringu1')::name stringu1, (fields->>'stringu2')::name stringu2, (fields->>'string4')::name string4 from tenk1 tenk1) tenk1, (select (fields->>'q1')::int8 q1, (fields->>'q2')::int8 q2 from INT8_TBL a) a, (select (fields->>'q1')::int8 q1, (fields->>'q2')::int8 q2 from INT8_TBL b) b @@ -1321,7 +1583,7 @@ where thousand::int4 = a.q1::int8 and tenthous::int4 = b.q1::int8 and a.q2::int8 -- test a corner case in which we shouldn't apply the star-schema optimization -- ---Testcase 278: +--Testcase 290: explain (costs off) select (t1.fields->>'unique2')::int4 unique2, (t1.fields->>'stringu1')::name stringu1, (t2.fields->>'unique1')::int4 unique1, (t2.fields->>'stringu2')::name stringu2 from tenk1 t1 @@ -1336,7 +1598,7 @@ select (t1.fields->>'unique2')::int4 unique2, (t1.fields->>'stringu1')::name str on ((subq1.y1)::int4 = (t2.fields->>'unique1')::int4) where (t1.fields->>'unique2')::int4 < 42 and (t1.fields->>'stringu1')::name > t2.fields->>'stringu2'; ---Testcase 279: +--Testcase 291: select (t1.fields->>'unique2')::int4 unique2, (t1.fields->>'stringu1')::name stringu1, (t2.fields->>'unique1')::int4 unique1, (t2.fields->>'stringu2')::name stringu2 from tenk1 t1 inner join int4_tbl i1 @@ -1352,7 +1614,7 @@ where (t1.fields->>'unique2')::int4 < 42 and (t1.fields->>'stringu1')::name > t2 -- variant that isn't quite a star-schema case ---Testcase 280: +--Testcase 292: select ss1.d1 from tenk1 as t1 inner join tenk1 as t2 @@ -1371,7 +1633,7 @@ where (t1.fields->>'unique1')::int4 < (i4.fields->>'f1')::int4; -- this variant is foldable by the remove-useless-RESULT-RTEs code ---Testcase 281: +--Testcase 293: explain (costs off) select (t1.fields->>'unique2')::int4 unique2, (t1.fields->>'stringu1')::name stringu1, (t2.fields->>'unique1')::int4 unique1, (t2.fields->>'stringu2')::name stringu2 from tenk1 t1 @@ -1386,7 +1648,7 @@ select (t1.fields->>'unique2')::int4 unique2, (t1.fields->>'stringu1')::name str on (subq1.y1 = (t2.fields->>'unique1')::int4) where (t1.fields->>'unique2')::int4 < 42 and (t1.fields->>'stringu1')::name > (t2.fields->>'stringu2')::name; ---Testcase 282: +--Testcase 294: select (t1.fields->>'unique2')::int4 unique2, (t1.fields->>'stringu1')::name stringu1, (t2.fields->>'unique1')::int4 unique1, (t2.fields->>'stringu2')::name stringu2 from tenk1 t1 inner join int4_tbl i1 @@ -1402,18 +1664,18 @@ where (t1.fields->>'unique2')::int4 < 42 and (t1.fields->>'stringu1')::name > (t -- Here's a variant that we can't fold too aggressively, though, -- or we end up with noplace to evaluate the lateral PHV ---Testcase 283: +--Testcase 295: 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; ---Testcase 284: +--Testcase 296: 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; -- Test proper handling of appendrel PHVs during useless-RTE removal ---Testcase 285: +--Testcase 297: explain (costs off) select * from (select 0 as z) as t1 @@ -1425,7 +1687,7 @@ select * from select a as b) as t3 where b; ---Testcase 286: +--Testcase 298: select * from (select 0 as z) as t1 left join @@ -1436,56 +1698,85 @@ select * from select a as b) as t3 where b; +-- 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 ); + +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 ); + +-- 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; + +-- 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; + -- -- test inlining of immutable functions -- ---Testcase 287: +--Testcase 299: create function f_immutable_int4(i integer) returns integer as $$ begin return i; end; $$ language plpgsql immutable; -- check optimization of function scan with join ---Testcase 288: +--Testcase 300: explain (costs off) select (fields->>'unique1')::int4 unique1 from tenk1, (select * from f_immutable_int4(1) x) x where x = (fields->>'unique1')::int4; ---Testcase 289: +--Testcase 301: explain (verbose, costs off) select (fields->>'unique1')::int4 unique1, x.* from tenk1, (select *, random() from f_immutable_int4(1) x) x where x = (fields->>'unique1')::int4; ---Testcase 290: +--Testcase 302: explain (costs off) select (fields->>'unique1')::int4 unique1 from tenk1, f_immutable_int4(1) x where x = (fields->>'unique1')::int4; ---Testcase 291: +--Testcase 303: explain (costs off) select (fields->>'unique1')::int4 unique1 from tenk1, lateral f_immutable_int4(1) x where x = (fields->>'unique1')::int4; ---Testcase 292: +--Testcase 569: +explain (costs off) +select (fields->>'unique1')::int4 unique1 from tenk1, lateral f_immutable_int4(1) x where x in (select 17); + +--Testcase 304: explain (costs off) select (fields->>'unique1')::int4 unique1, x from tenk1 join f_immutable_int4(1) x on (fields->>'unique1')::int4 = x; ---Testcase 293: +--Testcase 305: explain (costs off) select (fields->>'unique1')::int4 unique1, x from tenk1 left join f_immutable_int4(1) x on (fields->>'unique1')::int4 = x; ---Testcase 294: +--Testcase 306: explain (costs off) select (fields->>'unique1')::int4 unique1, x from tenk1 right join f_immutable_int4(1) x on (fields->>'unique1')::int4 = x; ---Testcase 295: +--Testcase 307: explain (costs off) select (fields->>'unique1')::int4 unique1, x from tenk1 full join f_immutable_int4(1) x on (fields->>'unique1')::int4 = x; -- check that pullup of a const function allows further const-folding ---Testcase 296: +--Testcase 308: explain (costs off) select (fields->>'unique1')::int4 unique1 from tenk1, f_immutable_int4(1) x where x = 42; -- test inlining of immutable functions with PlaceHolderVars ---Testcase 297: +--Testcase 309: explain (costs off) select (nt3.fields->>'id')::int id from nt3 as nt3 @@ -1499,34 +1790,34 @@ from nt3 as nt3 on (ss2.fields->>'id')::int = (nt3.fields->>'nt2_id')::int where (nt3.fields->>'id')::int = 1 and (ss2.b3)::boolean; ---Testcase 298: +--Testcase 310: drop function f_immutable_int4(int); -- test inlining when function returns composite ---Testcase 299: +--Testcase 311: create function mki8(bigint, bigint) returns int8_tbl as $$select row('{"q1" : ' || cast($1 as text) || ', "q2" : ' || cast($2 as text) || '}')::int8_tbl$$ language sql; ---Testcase 300: +--Testcase 312: create function mki4(int) returns int4_tbl as $$select row('{"f1" : ' || cast($1 as text) || '}')::int4_tbl$$ language sql; ---Testcase 301: +--Testcase 313: explain (verbose, costs off) select * from mki8(1, 2); ---Testcase 302: +--Testcase 314: select * from mki8(1, 2); ---Testcase 303: +--Testcase 315: explain (verbose, costs off) select * from mki4(42); ---Testcase 304: +--Testcase 316: select * from mki4(42); ---Testcase 305: +--Testcase 317: drop function mki8(bigint, bigint); ---Testcase 306: +--Testcase 318: drop function mki4(int); -- @@ -1534,15 +1825,15 @@ drop function mki4(int); -- (we used to only do this for indexable clauses) -- ---Testcase 307: +--Testcase 319: explain (costs off) select * from (select (fields->>'unique1')::int4 unique1, (fields->>'unique2')::int4 unique2, (fields->>'two')::int4 two, (fields->>'four')::int4 four, (fields->>'ten')::int4 ten, (fields->>'twenty')::int4 twenty, (fields->>'hundred')::int4 hundred, (fields->>'thousand')::int4 thousand, (fields->>'twothousand')::int4 twothousand, (fields->>'fivethous')::int4 fivethous, (fields->>'tenthous')::int4 tenthous, (fields->>'odd')::int4 odd, (fields->>'even')::int4 even, (fields->>'stringu1')::name stringu1, (fields->>'stringu2')::name stringu2, (fields->>'string4')::name string4 from tenk1 a) a join (select (fields->>'unique1')::int4 unique1, (fields->>'unique2')::int4 unique2, (fields->>'two')::int4 two, (fields->>'four')::int4 four, (fields->>'ten')::int4 ten, (fields->>'twenty')::int4 twenty, (fields->>'hundred')::int4 hundred, (fields->>'thousand')::int4 thousand, (fields->>'twothousand')::int4 twothousand, (fields->>'fivethous')::int4 fivethous, (fields->>'tenthous')::int4 tenthous, (fields->>'odd')::int4 odd, (fields->>'even')::int4 even, (fields->>'stringu1')::name stringu1, (fields->>'stringu2')::name stringu2, (fields->>'string4')::name string4 from tenk1 b) b on ((a.unique1)::int4 = 1 and (b.unique1)::int4 = 2) or ((a.unique2)::int4 = 3 and (b.hundred)::int4 = 4); ---Testcase 308: +--Testcase 320: explain (costs off) select * from (select (fields->>'unique1')::int4 unique1, (fields->>'unique2')::int4 unique2, (fields->>'two')::int4 two, (fields->>'four')::int4 four, (fields->>'ten')::int4 ten, (fields->>'twenty')::int4 twenty, (fields->>'hundred')::int4 hundred, (fields->>'thousand')::int4 thousand, (fields->>'twothousand')::int4 twothousand, (fields->>'fivethous')::int4 fivethous, (fields->>'tenthous')::int4 tenthous, (fields->>'odd')::int4 odd, (fields->>'even')::int4 even, (fields->>'stringu1')::name stringu1, (fields->>'stringu2')::name stringu2, (fields->>'string4')::name string4 from tenk1 a) a join (select (fields->>'unique1')::int4 unique1, (fields->>'unique2')::int4 unique2, (fields->>'two')::int4 two, (fields->>'four')::int4 four, (fields->>'ten')::int4 ten, (fields->>'twenty')::int4 twenty, (fields->>'hundred')::int4 hundred, (fields->>'thousand')::int4 thousand, (fields->>'twothousand')::int4 twothousand, (fields->>'fivethous')::int4 fivethous, (fields->>'tenthous')::int4 tenthous, (fields->>'odd')::int4 odd, (fields->>'even')::int4 even, (fields->>'stringu1')::name stringu1, (fields->>'stringu2')::name stringu2, (fields->>'string4')::name string4 from tenk1 b) b on ((a.unique1)::int4 = 1 and (b.unique1)::int4 = 2) or ((a.unique2)::int4 = 3 and (b.ten)::int4 = 4); ---Testcase 309: +--Testcase 321: explain (costs off) select * from (select (fields->>'unique1')::int4 unique1, (fields->>'unique2')::int4 unique2, (fields->>'two')::int4 two, (fields->>'four')::int4 four, (fields->>'ten')::int4 ten, (fields->>'twenty')::int4 twenty, (fields->>'hundred')::int4 hundred, (fields->>'thousand')::int4 thousand, (fields->>'twothousand')::int4 twothousand, (fields->>'fivethous')::int4 fivethous, (fields->>'tenthous')::int4 tenthous, (fields->>'odd')::int4 odd, (fields->>'even')::int4 even, (fields->>'stringu1')::name stringu1, (fields->>'stringu2')::name stringu2, (fields->>'string4')::name string4 from tenk1 a) a join (select (fields->>'unique1')::int4 unique1, (fields->>'unique2')::int4 unique2, (fields->>'two')::int4 two, (fields->>'four')::int4 four, (fields->>'ten')::int4 ten, (fields->>'twenty')::int4 twenty, (fields->>'hundred')::int4 hundred, (fields->>'thousand')::int4 thousand, (fields->>'twothousand')::int4 twothousand, (fields->>'fivethous')::int4 fivethous, (fields->>'tenthous')::int4 tenthous, (fields->>'odd')::int4 odd, (fields->>'even')::int4 even, (fields->>'stringu1')::name stringu1, (fields->>'stringu2')::name stringu2, (fields->>'string4')::name string4 from tenk1 b) b on ((a.unique1)::int4 = 1 and (b.unique1)::int4 = 2) or @@ -1552,34 +1843,34 @@ select * from (select (fields->>'unique1')::int4 unique1, (fields->>'unique2'):: -- test placement of movable quals in a parameterized join tree -- ---Testcase 310: +--Testcase 322: explain (costs off) select * from (select (fields->>'unique1')::int4 unique1, (fields->>'unique2')::int4 unique2, (fields->>'two')::int4 two, (fields->>'four')::int4 four, (fields->>'ten')::int4 ten, (fields->>'twenty')::int4 twenty, (fields->>'hundred')::int4 hundred, (fields->>'thousand')::int4 thousand, (fields->>'twothousand')::int4 twothousand, (fields->>'fivethous')::int4 fivethous, (fields->>'tenthous')::int4 tenthous, (fields->>'odd')::int4 odd, (fields->>'even')::int4 even, (fields->>'stringu1')::name stringu1, (fields->>'stringu2')::name stringu2, (fields->>'string4')::name string4 from tenk1 t1) t1 left join ((select (fields->>'unique1')::int4 unique1, (fields->>'unique2')::int4 unique2, (fields->>'two')::int4 two, (fields->>'four')::int4 four, (fields->>'ten')::int4 ten, (fields->>'twenty')::int4 twenty, (fields->>'hundred')::int4 hundred, (fields->>'thousand')::int4 thousand, (fields->>'twothousand')::int4 twothousand, (fields->>'fivethous')::int4 fivethous, (fields->>'tenthous')::int4 tenthous, (fields->>'odd')::int4 odd, (fields->>'even')::int4 even, (fields->>'stringu1')::name stringu1, (fields->>'stringu2')::name stringu2, (fields->>'string4')::name string4 from tenk1 t2) t2 join (select (fields->>'unique1')::int4 unique1, (fields->>'unique2')::int4 unique2, (fields->>'two')::int4 two, (fields->>'four')::int4 four, (fields->>'ten')::int4 ten, (fields->>'twenty')::int4 twenty, (fields->>'hundred')::int4 hundred, (fields->>'thousand')::int4 thousand, (fields->>'twothousand')::int4 twothousand, (fields->>'fivethous')::int4 fivethous, (fields->>'tenthous')::int4 tenthous, (fields->>'odd')::int4 odd, (fields->>'even')::int4 even, (fields->>'stringu1')::name stringu1, (fields->>'stringu2')::name stringu2, (fields->>'string4')::name string4 from tenk1 t3) t3 on (t2.thousand)::int4 = (t3.unique2)::int4) on (t1.hundred)::int4 = (t2.hundred)::int4 and (t1.ten)::int4 = (t3.ten)::int4 where (t1.unique1)::int4 = 1; ---Testcase 311: +--Testcase 323: explain (costs off) select * from (select (fields->>'unique1')::int4 unique1, (fields->>'unique2')::int4 unique2, (fields->>'two')::int4 two, (fields->>'four')::int4 four, (fields->>'ten')::int4 ten, (fields->>'twenty')::int4 twenty, (fields->>'hundred')::int4 hundred, (fields->>'thousand')::int4 thousand, (fields->>'twothousand')::int4 twothousand, (fields->>'fivethous')::int4 fivethous, (fields->>'tenthous')::int4 tenthous, (fields->>'odd')::int4 odd, (fields->>'even')::int4 even, (fields->>'stringu1')::name stringu1, (fields->>'stringu2')::name stringu2, (fields->>'string4')::name string4 from tenk1 t1) t1 left join ((select (fields->>'unique1')::int4 unique1, (fields->>'unique2')::int4 unique2, (fields->>'two')::int4 two, (fields->>'four')::int4 four, (fields->>'ten')::int4 ten, (fields->>'twenty')::int4 twenty, (fields->>'hundred')::int4 hundred, (fields->>'thousand')::int4 thousand, (fields->>'twothousand')::int4 twothousand, (fields->>'fivethous')::int4 fivethous, (fields->>'tenthous')::int4 tenthous, (fields->>'odd')::int4 odd, (fields->>'even')::int4 even, (fields->>'stringu1')::name stringu1, (fields->>'stringu2')::name stringu2, (fields->>'string4')::name string4 from tenk1 t2) t2 join (select (fields->>'unique1')::int4 unique1, (fields->>'unique2')::int4 unique2, (fields->>'two')::int4 two, (fields->>'four')::int4 four, (fields->>'ten')::int4 ten, (fields->>'twenty')::int4 twenty, (fields->>'hundred')::int4 hundred, (fields->>'thousand')::int4 thousand, (fields->>'twothousand')::int4 twothousand, (fields->>'fivethous')::int4 fivethous, (fields->>'tenthous')::int4 tenthous, (fields->>'odd')::int4 odd, (fields->>'even')::int4 even, (fields->>'stringu1')::name stringu1, (fields->>'stringu2')::name stringu2, (fields->>'string4')::name string4 from tenk1 t3) t3 on (t2.thousand)::int4 = (t3.unique2)::int4) on (t1.hundred)::int4 = (t2.hundred)::int4 and (t1.ten)::int4 + (t2.ten)::int4 = (t3.ten)::int4 where (t1.unique1)::int4 = 1; ---Testcase 312: +--Testcase 324: explain (costs off) select count(*) from (select (fields->>'unique1')::int4 unique1, (fields->>'unique2')::int4 unique2, (fields->>'two')::int4 two, (fields->>'four')::int4 four, (fields->>'ten')::int4 ten, (fields->>'twenty')::int4 twenty, (fields->>'hundred')::int4 hundred, (fields->>'thousand')::int4 thousand, (fields->>'twothousand')::int4 twothousand, (fields->>'fivethous')::int4 fivethous, (fields->>'tenthous')::int4 tenthous, (fields->>'odd')::int4 odd, (fields->>'even')::int4 even, (fields->>'stringu1')::name stringu1, (fields->>'stringu2')::name stringu2, (fields->>'string4')::name string4 from tenk1 a) a join (select (fields->>'unique1')::int4 unique1, (fields->>'unique2')::int4 unique2, (fields->>'two')::int4 two, (fields->>'four')::int4 four, (fields->>'ten')::int4 ten, (fields->>'twenty')::int4 twenty, (fields->>'hundred')::int4 hundred, (fields->>'thousand')::int4 thousand, (fields->>'twothousand')::int4 twothousand, (fields->>'fivethous')::int4 fivethous, (fields->>'tenthous')::int4 tenthous, (fields->>'odd')::int4 odd, (fields->>'even')::int4 even, (fields->>'stringu1')::name stringu1, (fields->>'stringu2')::name stringu2, (fields->>'string4')::name string4 from tenk1 b) b on (a.unique1)::int4 = (b.unique2)::int4 left join (select (fields->>'unique1')::int4 unique1, (fields->>'unique2')::int4 unique2, (fields->>'two')::int4 two, (fields->>'four')::int4 four, (fields->>'ten')::int4 ten, (fields->>'twenty')::int4 twenty, (fields->>'hundred')::int4 hundred, (fields->>'thousand')::int4 thousand, (fields->>'twothousand')::int4 twothousand, (fields->>'fivethous')::int4 fivethous, (fields->>'tenthous')::int4 tenthous, (fields->>'odd')::int4 odd, (fields->>'even')::int4 even, (fields->>'stringu1')::name stringu1, (fields->>'stringu2')::name stringu2, (fields->>'string4')::name string4 from tenk1 c) c on (a.unique2)::int4 = (b.unique1)::int4 and (c.thousand)::int4 = (a.thousand)::int4 join (select (fields->>'f1')::int4 f1 from INT4_TBL) INT4_TBL on (b.thousand)::int4 = (f1)::int4; ---Testcase 313: +--Testcase 325: select count(*) from (select (fields->>'unique1')::int4 unique1, (fields->>'unique2')::int4 unique2, (fields->>'two')::int4 two, (fields->>'four')::int4 four, (fields->>'ten')::int4 ten, (fields->>'twenty')::int4 twenty, (fields->>'hundred')::int4 hundred, (fields->>'thousand')::int4 thousand, (fields->>'twothousand')::int4 twothousand, (fields->>'fivethous')::int4 fivethous, (fields->>'tenthous')::int4 tenthous, (fields->>'odd')::int4 odd, (fields->>'even')::int4 even, (fields->>'stringu1')::name stringu1, (fields->>'stringu2')::name stringu2, (fields->>'string4')::name string4 from tenk1 a) a join (select (fields->>'unique1')::int4 unique1, (fields->>'unique2')::int4 unique2, (fields->>'two')::int4 two, (fields->>'four')::int4 four, (fields->>'ten')::int4 ten, (fields->>'twenty')::int4 twenty, (fields->>'hundred')::int4 hundred, (fields->>'thousand')::int4 thousand, (fields->>'twothousand')::int4 twothousand, (fields->>'fivethous')::int4 fivethous, (fields->>'tenthous')::int4 tenthous, (fields->>'odd')::int4 odd, (fields->>'even')::int4 even, (fields->>'stringu1')::name stringu1, (fields->>'stringu2')::name stringu2, (fields->>'string4')::name string4 from tenk1 b) b on (a.unique1)::int4 = (b.unique2)::int4 left join (select (fields->>'unique1')::int4 unique1, (fields->>'unique2')::int4 unique2, (fields->>'two')::int4 two, (fields->>'four')::int4 four, (fields->>'ten')::int4 ten, (fields->>'twenty')::int4 twenty, (fields->>'hundred')::int4 hundred, (fields->>'thousand')::int4 thousand, (fields->>'twothousand')::int4 twothousand, (fields->>'fivethous')::int4 fivethous, (fields->>'tenthous')::int4 tenthous, (fields->>'odd')::int4 odd, (fields->>'even')::int4 even, (fields->>'stringu1')::name stringu1, (fields->>'stringu2')::name stringu2, (fields->>'string4')::name string4 from tenk1 c) c on (a.unique2)::int4 = (b.unique1)::int4 and (c.thousand)::int4 = (a.thousand)::int4 join int4_tbl on (b.thousand)::int4 = (fields->>'f1')::int4; ---Testcase 314: +--Testcase 326: explain (costs off) select (b.fields->>'unique1')::int4 unique1 from tenk1 a join tenk1 b on (a.fields->>'unique1')::int4 = (b.fields->>'unique2')::int4 @@ -1588,7 +1879,7 @@ select (b.fields->>'unique1')::int4 unique1 from right join int4_tbl i2 on (i2.fields->>'f1')::int4 = (b.fields->>'tenthous')::int4 order by 1; ---Testcase 315: +--Testcase 327: select (b.fields->>'unique1')::int4 unique1 from tenk1 a join tenk1 b on (a.fields->>'unique1')::int4 = (b.fields->>'unique2')::int4 left join tenk1 c on (b.fields->>'unique1')::int4 = 42 and (c.fields->>'thousand')::int4 = (a.fields->>'thousand')::int4 @@ -1596,7 +1887,7 @@ select (b.fields->>'unique1')::int4 unique1 from right join int4_tbl i2 on (i2.fields->>'f1')::int4 = (b.fields->>'tenthous')::int4 order by 1; ---Testcase 316: +--Testcase 328: explain (costs off) select * from ( @@ -1606,7 +1897,7 @@ select * from where fault = 122 order by fault; ---Testcase 317: +--Testcase 329: select * from ( select unique1, q1, coalesce((unique1)::int4, -1) + (q1)::int8 as fault @@ -1615,14 +1906,14 @@ select * from where fault = 122 order by fault; ---Testcase 318: +--Testcase 330: 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; ---Testcase 319: +--Testcase 331: 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 @@ -1632,24 +1923,24 @@ left join unnest(v1ys) as u1(u1y) on u1y = v2y; -- test handling of potential equivalence clauses above outer joins -- ---Testcase 320: +--Testcase 332: explain (costs off) select q1, unique2, thousand, hundred from (select (fields->>'q1')::int8 q1, (fields->>'q2')::int8 q2 from INT8_TBL a) a left join (select (fields->>'unique1')::int4 unique1, (fields->>'unique2')::int4 unique2, (fields->>'two')::int4 two, (fields->>'four')::int4 four, (fields->>'ten')::int4 ten, (fields->>'twenty')::int4 twenty, (fields->>'hundred')::int4 hundred, (fields->>'thousand')::int4 thousand, (fields->>'twothousand')::int4 twothousand, (fields->>'fivethous')::int4 fivethous, (fields->>'tenthous')::int4 tenthous, (fields->>'odd')::int4 odd, (fields->>'even')::int4 even, (fields->>'stringu1')::name stringu1, (fields->>'stringu2')::name stringu2, (fields->>'string4')::name string4 from tenk1 b) b on (q1)::int8 = (unique2)::int4 where coalesce((thousand)::int4,123) = (q1)::int8 and (q1)::int8 = coalesce((hundred)::int4,123); ---Testcase 321: +--Testcase 333: select q1, unique2, thousand, hundred from (select (fields->>'q1')::int8 q1, (fields->>'q2')::int8 q2 from INT8_TBL a) a left join (select (fields->>'unique1')::int4 unique1, (fields->>'unique2')::int4 unique2, (fields->>'two')::int4 two, (fields->>'four')::int4 four, (fields->>'ten')::int4 ten, (fields->>'twenty')::int4 twenty, (fields->>'hundred')::int4 hundred, (fields->>'thousand')::int4 thousand, (fields->>'twothousand')::int4 twothousand, (fields->>'fivethous')::int4 fivethous, (fields->>'tenthous')::int4 tenthous, (fields->>'odd')::int4 odd, (fields->>'even')::int4 even, (fields->>'stringu1')::name stringu1, (fields->>'stringu2')::name stringu2, (fields->>'string4')::name string4 from tenk1 b) b on (q1)::int8 = (unique2)::int4 where coalesce((thousand)::int4,123) = (q1)::int8 and (q1)::int8 = coalesce((hundred)::int4,123); ---Testcase 322: +--Testcase 334: explain (costs off) select f1, unique2, case when (unique2)::int4 is null then (f1)::int4 else 0 end from (select (fields->>'f1')::int4 f1 from INT4_TBL a) a left join (select (fields->>'unique1')::int4 unique1, (fields->>'unique2')::int4 unique2, (fields->>'two')::int4 two, (fields->>'four')::int4 four, (fields->>'ten')::int4 ten, (fields->>'twenty')::int4 twenty, (fields->>'hundred')::int4 hundred, (fields->>'thousand')::int4 thousand, (fields->>'twothousand')::int4 twothousand, (fields->>'fivethous')::int4 fivethous, (fields->>'tenthous')::int4 tenthous, (fields->>'odd')::int4 odd, (fields->>'even')::int4 even, (fields->>'stringu1')::name stringu1, (fields->>'stringu2')::name stringu2, (fields->>'string4')::name string4 from tenk1 b) b on (f1)::int4 = (unique2)::int4 where (case when (unique2)::int4 is null then (f1)::int4 else 0 end) = 0; ---Testcase 323: +--Testcase 335: select f1, unique2, case when (unique2)::int4 is null then (f1)::int4 else 0 end from (select (fields->>'f1')::int4 f1 from INT4_TBL a) a left join (select (fields->>'unique1')::int4 unique1, (fields->>'unique2')::int4 unique2, (fields->>'two')::int4 two, (fields->>'four')::int4 four, (fields->>'ten')::int4 ten, (fields->>'twenty')::int4 twenty, (fields->>'hundred')::int4 hundred, (fields->>'thousand')::int4 thousand, (fields->>'twothousand')::int4 twothousand, (fields->>'fivethous')::int4 fivethous, (fields->>'tenthous')::int4 tenthous, (fields->>'odd')::int4 odd, (fields->>'even')::int4 even, (fields->>'stringu1')::name stringu1, (fields->>'stringu2')::name stringu2, (fields->>'string4')::name string4 from tenk1 b) b on (f1)::int4 = (unique2)::int4 where (case when (unique2)::int4 is null then (f1)::int4 else 0 end) = 0; @@ -1658,22 +1949,31 @@ select f1, unique2, case when (unique2)::int4 is null then (f1)::int4 else 0 end -- another case with equivalence clauses above outer joins (bug #8591) -- ---Testcase 324: +--Testcase 336: explain (costs off) select (a.fields->>'unique1')::int4 unique1, (b.fields->>'unique1')::int4 unique1, (c.fields->>'unique1')::int4 unique1, coalesce((b.fields->>'twothousand')::int4, (a.fields->>'twothousand')::int4) from tenk1 a left join tenk1 b on (b.fields->>'thousand')::int4 = (a.fields->>'unique1')::int4 left join tenk1 c on (c.fields->>'unique2')::int4 = coalesce((b.fields->>'twothousand')::int4, (a.fields->>'twothousand')::int4) where (a.fields->>'unique2')::int4 < 10 and coalesce((b.fields->>'twothousand')::int4, (a.fields->>'twothousand')::int4) = 44; ---Testcase 325: +--Testcase 337: select (a.fields->>'unique1')::int4 unique1, (b.fields->>'unique1')::int4 unique1, (c.fields->>'unique1')::int4 unique1, coalesce((b.fields->>'twothousand')::int4, (a.fields->>'twothousand')::int4) from tenk1 a left join tenk1 b on (b.fields->>'thousand')::int4 = (a.fields->>'unique1')::int4 left join tenk1 c on (c.fields->>'unique2')::int4 = coalesce((b.fields->>'twothousand')::int4, (a.fields->>'twothousand')::int4) where (a.fields->>'unique2')::int4 < 10 and coalesce((b.fields->>'twothousand')::int4, (a.fields->>'twothousand')::int4) = 44; +-- related case + +explain (costs off) +select * from int8_tbl t1 left join int8_tbl t2 on (t1.fields->>'q2')::int8 = (t2.fields->>'q1')::int8, + lateral (select * from int8_tbl t3 where (t2.fields->>'q1')::int8 = (t2.fields->>'q2')::int8) ss; + +select * from int8_tbl t1 left join int8_tbl t2 on (t1.fields->>'q2')::int8 = (t2.fields->>'q1')::int8, + lateral (select * from int8_tbl t3 where (t2.fields->>'q1')::int8 = (t2.fields->>'q2')::int8) ss; + -- -- check handling of join aliases when flattening multiple levels of subquery -- ---Testcase 326: +--Testcase 338: 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) @@ -1688,7 +1988,7 @@ left join ) foo3 using (join_key); ---Testcase 327: +--Testcase 339: select foo1.join_key as foo1_id, foo3.join_key AS foo3_id, bug_field from (values (0),(1)) foo1(join_key) left join @@ -1702,13 +2002,37 @@ left join ) foo3 using (join_key); +-- +-- check handling of a variable-free join alias +-- +explain (verbose, costs off) +select * from +int4_tbl i0 left join +( (select (fields->>'f1')::int4 f1, 123 as x from int4_tbl i1) ss1 + left join + (select (fields->>'q1') q1, (fields->>'q2') q2, (fields->>'q2')::int4 as x from int8_tbl i2) ss2 + using (x) +) ss0 +on ((i0.fields->>'f1')::int4 = ss0.f1) +order by (i0.fields->>'f1')::int4, x; + +select * from +int4_tbl i0 left join +( (select (fields->>'f1')::int4 f1, 123 as x from int4_tbl i1) ss1 + left join + (select (fields->>'q1') q1, (fields->>'q2') q2, (fields->>'q2')::int4 as x from int8_tbl i2) ss2 + using (x) +) ss0 +on ((i0.fields->>'f1')::int4 = ss0.f1) +order by (i0.fields->>'f1')::int4, x; + -- -- test successful handling of nested outer joins with degenerate join quals -- ---Testcase 328: +--Testcase 340: create foreign table text_tbl(fields jsonb OPTIONS (fields 'true')) server influxdb_svr OPTIONS(schemaless 'true'); ---Testcase 329: +--Testcase 341: explain (verbose, costs off) select t1.* from (select fields->>'f1' f1 from text_tbl t1) t1 @@ -1721,7 +2045,7 @@ select t1.* from left join int4_tbl i4 on ((i8.fields->>'q2')::int8 = (i4.fields->>'f1')::int4); ---Testcase 330: +--Testcase 342: select t1.* from (select fields->>'f1' f1 from text_tbl t1) t1 left join (select *, '***'::text as d1 from int8_tbl i8b1) b1 @@ -1733,11 +2057,11 @@ select t1.* from left join int4_tbl i4 on ((i8.fields->>'q2')::int8 = (i4.fields->>'f1')::int4); ---Testcase 331: +--Testcase 343: explain (verbose, costs off) select t1.* from (select fields->>'f1' f1 from text_tbl t1) t1 - left join (select *, '***'::text as d1 from (select (fields->>'q1')::int8 q1, (fields->>'q2')::int8 q2 from INT8_TBL i8b1) i8b1) b1 + left join (select *, '***'::text as d1 from (select (fields->>'q1')::int8 q1, (fields->>'q2')::int8 q2 from INT8_TBL i8b1) i8b1 ) b1 left join (select (fields->>'q1')::int8 q1, (fields->>'q2')::int8 q2 from INT8_TBL i8) i8 left join (select *, null::int as d2 from (select (fields->>'q1')::int8 q1, (fields->>'q2')::int8 q2 from INT8_TBL i8b2) i8b2, (select (fields->>'f1')::int4 f1 from INT4_TBL i4b2) i4b2) b2 on ((i8.q1)::int8 = (b2.q1)::int8) @@ -1746,7 +2070,7 @@ select t1.* from left join (select (fields->>'f1')::int4 f1 from INT4_TBL i4) i4 on ((i8.q2)::int8 = (i4.f1)::int4); ---Testcase 332: +--Testcase 344: select t1.* from (select fields->>'f1' f1 from text_tbl t1) t1 left join (select *, '***'::text as d1 from (select (fields->>'q1')::int8 q1, (fields->>'q2')::int8 q2 from INT8_TBL i8b1) i8b1) b1 @@ -1758,7 +2082,7 @@ select t1.* from left join (select (fields->>'f1')::int4 f1 from INT4_TBL i4) i4 on ((i8.q2)::int8 = (i4.f1)::int4); ---Testcase 333: +--Testcase 345: explain (verbose, costs off) select t1.* from (select fields->>'f1' f1 from text_tbl t1) t1 @@ -1772,7 +2096,7 @@ select t1.* from left join (select (fields->>'f1')::int4 f1 from INT4_TBL i4) i4 on ((i8.q2)::int8 = (i4.f1)::int4); ---Testcase 334: +--Testcase 346: select t1.* from (select fields->>'f1' f1 from text_tbl t1) t1 left join (select *, '***'::text as d1 from (select (fields->>'q1')::int8 q1, (fields->>'q2')::int8 q2 from INT8_TBL i8b1) i8b1) b1 @@ -1785,7 +2109,7 @@ select t1.* from left join (select (fields->>'f1')::int4 f1 from INT4_TBL i4) i4 on ((i8.q2)::int8 = (i4.f1)::int4); ---Testcase 335: +--Testcase 347: explain (verbose, costs off) select * from (select fields->>'f1' f1 from text_tbl t1) t1 @@ -1796,7 +2120,7 @@ select * from left join (select (fields->>'f1')::int4 f1 from INT4_TBL i4) i4 on i8.q1 = i4.f1; ---Testcase 336: +--Testcase 348: select * from (select fields->>'f1' f1 from text_tbl t1) t1 inner join (select (fields->>'q1')::int8 q1, fields->>'q2' q2 from INT8_TBL i8) i8 @@ -1806,11 +2130,32 @@ select * from left join (select (fields->>'f1')::int4 f1 from INT4_TBL i4) i4 on i8.q1 = i4.f1; +-- 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; + +-- 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.fields->>'f1')::int4 is not null + left join (select 1 as a) ss1 on null + join int4_tbl i42 on ss1.a is null or (i8.fields->>'q1')::int8 <> (i8.fields->>'q2')::int8 + right join (select 2 as b) ss2 + on ss2.b < (i4.fields->>'f1')::int4; + -- -- test for appropriate join order in the presence of lateral references -- ---Testcase 337: +--Testcase 349: explain (verbose, costs off) select * from (select fields->>'f1' f1 from text_tbl t1) t1 @@ -1819,7 +2164,7 @@ select * from lateral (select i8.q1, t2.fields->>'f1' f1 from text_tbl t2 limit 1) as ss where t1.f1 = ss.f1; ---Testcase 338: +--Testcase 350: select * from (select fields->>'f1' f1 from text_tbl t1) t1 left join (select (fields->>'q1')::int8 q1, (fields->>'q2')::int8 q2 from INT8_TBL i8) i8 @@ -1827,7 +2172,7 @@ select * from lateral (select i8.q1, t2.fields->>'f1' f1 from text_tbl t2 limit 1) as ss where t1.f1 = ss.f1; ---Testcase 339: +--Testcase 351: explain (verbose, costs off) select * from (select fields->>'f1' f1 from text_tbl t1) t1 @@ -1837,7 +2182,7 @@ select * from lateral (select ss1.* from text_tbl t3 limit 1) as ss2 where t1.f1 = ss2.f1; ---Testcase 340: +--Testcase 352: select * from (select fields->>'f1' f1 from text_tbl t1) t1 left join (select (fields->>'q1')::int8 q1, (fields->>'q2')::int8 q2 from INT8_TBL i8) i8 @@ -1846,7 +2191,7 @@ select * from lateral (select ss1.* from text_tbl t3 limit 1) as ss2 where t1.f1 = ss2.f1; ---Testcase 341: +--Testcase 353: explain (verbose, costs off) select 1 from text_tbl as tt1 @@ -1856,7 +2201,7 @@ select 1 from lateral (select tt4.fields->>'f1' as c0 from text_tbl as tt5 limit 1) as ss1 where tt1.fields->>'f1' = ss1.c0; ---Testcase 342: +--Testcase 354: select 1 from text_tbl as tt1 inner join text_tbl as tt2 on (tt1.fields->>'f1' = 'foo') @@ -1865,11 +2210,50 @@ select 1 from lateral (select tt4.fields->>'f1' as c0 from text_tbl as tt5 limit 1) as ss1 where tt1.fields->>'f1' = ss1.c0; +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 (x1.fields->>'f1')::int4 = (x2.fields->>'q1')::int8) as ss1 + right join (select 1 as z) as ss2 on true) + on false, + lateral (select (i4.fields->>'f1')::int4 f1, ss1.n from int8_tbl as i8 limit 1) as ss3; + +select 1 from + int4_tbl as i4 + inner join + ((select 42 as n from int4_tbl x1 left join int8_tbl x2 on (x1.fields->>'f1')::int4 = (x2.fields->>'q1')::int8) as ss1 + right join (select 1 as z) as ss2 on true) + on false, + lateral (select (i4.fields->>'f1')::int4 f1, ss1.n from int8_tbl as i8 limit 1) as ss3; + +-- +-- check a case where we formerly generated invalid parameterized paths +-- + +begin; + +CREATE FOREIGN TABLE temp_t (fields jsonb OPTIONS (fields 'true')) SERVER influxdb_svr OPTIONS(schemaless 'true'); + +explain (costs off) +select 1 from (select (temp_t.fields->>'a')::int4 a FROM temp_t) t1 + join lateral (select t1.a from (select 1) foo offset 0) as s1 on true + join + (select 1 from (select (temp_t.fields->>'a')::int4 a FROM temp_t) t2 + inner join ((select (temp_t.fields->>'a')::int4 a FROM temp_t) t3 + left join ((select (temp_t.fields->>'a')::int4 a FROM temp_t) t4 left join (select (temp_t.fields->>'a')::int4 a FROM temp_t) t5 on t4.a = 1) + on t3.a = t4.a) + on false + where t3.a = coalesce(t5.a,1)) as s2 + on true; + +rollback; + -- -- check a case in which a PlaceHolderVar forces join order -- ---Testcase 343: +--Testcase 355: explain (verbose, costs off) select ss2.* from (select (fields->>'f1')::int4 f1 from INT4_TBL) i41 @@ -1881,7 +2265,7 @@ select ss2.* from lateral (select i41.*, i8.*, ss1.* from text_tbl limit 1) ss2 where (ss1.c2)::int8 = 0; ---Testcase 344: +--Testcase 356: select ss2.* from (select (fields->>'f1')::int4 f1 from INT4_TBL) i41 left join (select (fields->>'q1')::int8 q1, (fields->>'q2')::int8 q2 from INT8_TBL) i8 @@ -1896,7 +2280,7 @@ where (ss1.c2)::int8 = 0; -- test successful handling of full join underneath left join (bug #14105) -- ---Testcase 345: +--Testcase 357: explain (costs off) select * from (select 1 as id) as xx @@ -1904,7 +2288,7 @@ select * from ((select (fields->>'unique1')::int4 unique1, (fields->>'unique2')::int4 unique2, (fields->>'two')::int4 two, (fields->>'four')::int4 four, (fields->>'ten')::int4 ten, (fields->>'twenty')::int4 twenty, (fields->>'hundred')::int4 hundred, (fields->>'thousand')::int4 thousand, (fields->>'twothousand')::int4 twothousand, (fields->>'fivethous')::int4 fivethous, (fields->>'tenthous')::int4 tenthous, (fields->>'odd')::int4 odd, (fields->>'even')::int4 even, (fields->>'stringu1')::name stringu1, (fields->>'stringu2')::name stringu2, (fields->>'string4')::name string4 from tenk1 a1) as a1 full join (select 1 as id) as yy on ((a1.unique1)::int4 = yy.id)) on (xx.id = coalesce(yy.id)); ---Testcase 346: +--Testcase 358: select * from (select 1 as id) as xx left join @@ -1915,11 +2299,11 @@ select * from -- test ability to push constants through outer join clauses -- ---Testcase 347: +--Testcase 359: explain (costs off) select * from (select (fields->>'f1')::int4 f1 from INT4_TBL a) a left join (select (fields->>'unique1')::int4 unique1, (fields->>'unique2')::int4 unique2, (fields->>'two')::int4 two, (fields->>'four')::int4 four, (fields->>'ten')::int4 ten, (fields->>'twenty')::int4 twenty, (fields->>'hundred')::int4 hundred, (fields->>'thousand')::int4 thousand, (fields->>'twothousand')::int4 twothousand, (fields->>'fivethous')::int4 fivethous, (fields->>'tenthous')::int4 tenthous, (fields->>'odd')::int4 odd, (fields->>'even')::int4 even, (fields->>'stringu1')::name stringu1, (fields->>'stringu2')::name stringu2, (fields->>'string4')::name string4 from tenk1 b) b on (f1)::int4 = (unique2)::int4 where (f1)::int4 = 0; ---Testcase 348: +--Testcase 360: explain (costs off) select * from (select (fields->>'unique1')::int4 unique1, (fields->>'unique2')::int4 unique2, (fields->>'two')::int4 two, (fields->>'four')::int4 four, (fields->>'ten')::int4 ten, (fields->>'twenty')::int4 twenty, (fields->>'hundred')::int4 hundred, (fields->>'thousand')::int4 thousand, (fields->>'twothousand')::int4 twothousand, (fields->>'fivethous')::int4 fivethous, (fields->>'tenthous')::int4 tenthous, (fields->>'odd')::int4 odd, (fields->>'even')::int4 even, (fields->>'stringu1')::name stringu1, (fields->>'stringu2')::name stringu2, (fields->>'string4')::name string4 from tenk1 a) a full join (select (fields->>'unique1')::int4 unique1, (fields->>'unique2')::int4 unique2, (fields->>'two')::int4 two, (fields->>'four')::int4 four, (fields->>'ten')::int4 ten, (fields->>'twenty')::int4 twenty, (fields->>'hundred')::int4 hundred, (fields->>'thousand')::int4 thousand, (fields->>'twothousand')::int4 twothousand, (fields->>'fivethous')::int4 fivethous, (fields->>'tenthous')::int4 tenthous, (fields->>'odd')::int4 odd, (fields->>'even')::int4 even, (fields->>'stringu1')::name stringu1, (fields->>'stringu2')::name stringu2, (fields->>'string4')::name string4 from tenk1 b) b using(unique2) where (unique2)::int4 = 42; @@ -1929,78 +2313,233 @@ explain (costs off) -- we force a mergejoin so that coalesce(b.q1, 1) appears as a join input -- ---Testcase 349: +--Testcase 361: set enable_hashjoin to off; ---Testcase 350: +--Testcase 362: set enable_nestloop to off; ---Testcase 351: +--Testcase 363: explain (verbose, costs off) select (a.fields->>'q2')::int8 q2, (b.fields->>'q1')::int8 q1 from int8_tbl a left join int8_tbl b on (a.fields->>'q2')::int8 = coalesce((b.fields->>'q1')::int8, 1) where coalesce((b.fields->>'q1')::int8, 1) > 0; ---Testcase 352: +--Testcase 364: select (a.fields->>'q2')::int8 q2, (b.fields->>'q1')::int8 q1 from int8_tbl a left join int8_tbl b on (a.fields->>'q2')::int8 = coalesce((b.fields->>'q1')::int8, 1) where coalesce((b.fields->>'q1')::int8, 1) > 0; ---Testcase 353: +--Testcase 365: reset enable_hashjoin; ---Testcase 354: +--Testcase 366: reset enable_nestloop; +-- +-- test join strength reduction with a SubPlan providing the proof +-- + +explain (costs off) +select (a.fields->>'unique1') unique1, (b.fields->>'unique2') unique2 + from onek a left join onek b on (a.fields->>'unique1')::int4 = (b.fields->>'unique2')::int4 + where (b.fields->>'unique2')::int4 = any (select (fields->>'q1')::int8 from int8_tbl c where (c.fields->>'q1')::int8 < (b.fields->>'unique1')::int4); + +select (a.fields->>'unique1') unique1, (b.fields->>'unique2') unique2 + from onek a left join onek b on (a.fields->>'unique1')::int4 = (b.fields->>'unique2')::int4 + where (b.fields->>'unique2')::int4 = any (select (fields->>'q1')::int8 from int8_tbl c where (c.fields->>'q1')::int8 < (b.fields->>'unique1')::int4); + +-- +-- test full-join strength reduction +-- + +explain (costs off) +select a.fields->>'unique1' unique1, b.fields->>'unique2' unique2 + from onek a full join onek b on (a.fields->>'unique1')::int4 = (b.fields->>'unique2')::int4 + where (a.fields->>'unique1')::int4 = 42; + +select a.fields->>'unique1' unique1, b.fields->>'unique2' unique2 + from onek a full join onek b on (a.fields->>'unique1')::int4 = (b.fields->>'unique2')::int4 + where (a.fields->>'unique1')::int4 = 42; + +explain (costs off) +select a.fields->>'unique1' unique1, b.fields->>'unique2' unique2 + from onek a full join onek b on (a.fields->>'unique1')::int4 = (b.fields->>'unique2')::int4 + where (b.fields->>'unique2')::int4 = 43; + +select a.fields->>'unique1' unique1, b.fields->>'unique2' unique2 + from onek a full join onek b on (a.fields->>'unique1')::int4 = (b.fields->>'unique2')::int4 + where (b.fields->>'unique2')::int4 = 43; + +explain (costs off) +select a.fields->>'unique1', b.fields->>'unique2' + from onek a full join onek b on (a.fields->>'unique1')::int4 = (b.fields->>'unique2')::int4 + where (a.fields->>'unique1')::int4 = 42 and (b.fields->>'unique2')::int4 = 42; + +select a.fields->>'unique1', b.fields->>'unique2' + from onek a full join onek b on (a.fields->>'unique1')::int4 = (b.fields->>'unique2')::int4 + where (a.fields->>'unique1')::int4 = 42 and (b.fields->>'unique2')::int4 = 42; + +-- +-- 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 (i81.fields->>'q2')::int8=v1) ss1 +full join + (select * from (values(456,2)) w(v1,v2) join int8_tbl i82 on (i82.fields->>'q2')::int8=v1) ss2 +on true; + +select * from + (select * from int8_tbl i81 join (values(123,2)) v(v1,v2) on (i81.fields->>'q2')::int8=v1) ss1 +full join + (select * from (values(456,2)) w(v1,v2) join int8_tbl i82 on (i82.fields->>'q2')::int8=v1) ss2 +on true; + -- -- test join removal -- begin; ---Testcase 355: +--Testcase 367: CREATE FOREIGN TABLE a (fields jsonb OPTIONS (fields 'true')) SERVER influxdb_svr OPTIONS(schemaless 'true'); +--Testcase 615: CREATE FOREIGN TABLE a_nsc (id int, b_id int) SERVER influxdb_svr OPTIONS (table 'a'); ---Testcase 356: +--Testcase 368: CREATE FOREIGN TABLE b (fields jsonb OPTIONS (fields 'true')) SERVER influxdb_svr OPTIONS(schemaless 'true'); +--Testcase 616: CREATE FOREIGN TABLE b_nsc (id int, c_id int) SERVER influxdb_svr OPTIONS (table 'b'); ---Testcase 357: +--Testcase 369: CREATE FOREIGN TABLE c (fields jsonb OPTIONS (fields 'true')) SERVER influxdb_svr OPTIONS(schemaless 'true'); +--Testcase 617: CREATE FOREIGN TABLE c_nsc (id int) SERVER influxdb_svr OPTIONS (table 'c'); ---Testcase 358: +--Testcase 370: CREATE FOREIGN TABLE d (fields jsonb OPTIONS (fields 'true')) SERVER influxdb_svr OPTIONS(schemaless 'true'); +--Testcase 618: CREATE FOREIGN TABLE d_nsc (a int, b int) SERVER influxdb_svr OPTIONS (table 'd'); ---Testcase 359: +--Testcase 371: INSERT INTO a_nsc VALUES (0, 0), (1, NULL); ---Testcase 360: +--Testcase 372: INSERT INTO b_nsc VALUES (0, 0), (1, NULL); ---Testcase 361: +--Testcase 373: INSERT INTO c_nsc VALUES (0), (1); ---Testcase 362: +--Testcase 374: INSERT INTO d_nsc VALUES (1,3), (2,2), (3,1); -- all three cases should be optimizable into a simple seqscan ---Testcase 363: +--Testcase 375: explain (costs off) SELECT a.* FROM (select (fields->>'id')::int id, (fields->>'b_id')::int b_id from a) a LEFT JOIN (select (fields->>'id')::int id, (fields->>'c_id')::int c_id from b) b ON a.b_id = b.id; ---Testcase 364: +--Testcase 376: explain (costs off) SELECT b.* FROM (select (fields->>'id')::int id, (fields->>'c_id')::int c_id from b) b LEFT JOIN (select (fields->>'id')::int id from c) c ON b.c_id = c.id; ---Testcase 365: +--Testcase 377: explain (costs off) SELECT a.* FROM (select (fields->>'id')::int id, (fields->>'b_id')::int b_id from a) a LEFT JOIN ((select (fields->>'id')::int id, (fields->>'c_id')::int c_id from b) b left join (select (fields->>'id')::int id from c) c on b.c_id = c.id) ON (a.b_id = b.id); -- check optimization of outer join within another special join ---Testcase 366: +--Testcase 378: explain (costs off) select (fields->>'id')::int id from a where (fields->>'id')::int in ( select (b.fields->>'id')::int from b left join c on (b.fields->>'id')::int = (c.fields->>'id')::int ); +-- check optimization with oddly-nested outer joins +explain (costs off) +select a1.fields->>'id' id from + (a a1 left join a a2 on true) + left join + (a a3 left join a a4 on (a3.fields->>'id')::int = (a4.fields->>'id')::int) + on (a2.fields->>'id')::int = (a3.fields->>'id')::int; + +explain (costs off) +select a1.fields->>'id' id from + (a a1 left join a a2 on (a1.fields->>'id')::int = (a2.fields->>'id')::int) + left join + (a a3 left join a a4 on (a3.fields->>'id')::int = (a4.fields->>'id')::int) + on (a2.fields->>'id')::int = (a3.fields->>'id')::int; + +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.fields->>'id')::int = (t4.fields->>'id')::int and (t2.fields->>'id')::int = (t3.fields->>'id')::int; + +-- 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.fields->>'f1')::int = (t4.fields->>'f1')::int + left join ((select null as f1 from int4_tbl as t6) as ss1 + inner join int8_tbl as t7 on null) + on (t5.fields->>'q1')::int = (t7.fields->>'q2')::int) + on false; + +-- 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.fields->>'f1')::int = (t4.fields->>'f1')::int + left join ((select t6.fields->>'f1' f1 from int4_tbl as t6) as ss1 + inner join int8_tbl as t7 on null) + on (t5.fields->>'q1')::int = (t7.fields->>'q2')::int) + on false; + +-- per further discussion of bug #17781 +explain (costs off) +select ss1.x +from (select (i4.fields->>'f1')::int4/2 as x from int4_tbl i4 left join a on (a.fields->>'id')::int4 = (i4.fields->>'f1')::int4) ss1 + right join int8_tbl i8 on true +where current_user is not null; -- 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.fields->>'q1')::int8 > (t3.fields->>'unique1')::int8) + on (t1.fields->>'q2')::int8 = (t2.fields->>'q2')::int8 + left join onek t4 + on (t2.fields->>'q2')::int8 < (t3.fields->>'unique2')::int8; + +-- 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.fields->>'q2')::int8 = (t4.fields->>'q2')::int8) +on (t1.fields->>'q1')::int8 = (t2.fields->>'q1')::int8; + +-- 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.fields->>'q1')::int8-(t3.fields->>'q2')::int8) = 0 and ((t2.fields->>'q1')::int8-(t3.fields->>'q2')::int8) = 1 + left join int8_tbl t4 on (t2.fields->>'q2')::int8 = (t4.fields->>'q2')::int8) +on (t1.fields->>'q1')::int8 = (t2.fields->>'q1')::int8; + +-- 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.fields->>'f1')::int4 = 1 + left join int8_tbl t4 on (t2.fields->>'q2')::int8 = (t4.fields->>'q2')::int8) + on (t1.fields->>'q1')::int8 = (t2.fields->>'q1')::int8 +) from int4_tbl x0; + -- check that join removal works for a left join when joining a subquery -- that is guaranteed to be unique by its GROUP BY clause ---Testcase 367: +--Testcase 379: explain (costs off) select d.* from (select (fields->>'a')::int a, (fields->>'b')::int b from d) d left join (select * from (select (fields->>'id')::int id, (fields->>'c_id')::int c_id from b) b group by b.id, b.c_id) s on (d.a)::int = (s.id)::int and (d.b)::int = (s.c_id)::int; -- similarly, but keying off a DISTINCT clause ---Testcase 368: +--Testcase 380: explain (costs off) select d.* from (select (fields->>'a')::int a, (fields->>'b')::int b from d) d left join (select distinct * from (select (fields->>'id')::int id, (fields->>'c_id')::int c_id from b) b) s on (d.a)::int = (s.id)::int and (d.b)::int = (s.c_id)::int; @@ -2009,102 +2548,126 @@ select d.* from (select (fields->>'a')::int a, (fields->>'b')::int b from d) d l -- 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.) ---Testcase 369: +--Testcase 381: explain (costs off) select d.* from (select (fields->>'a')::int a, (fields->>'b')::int b from d) d left join (select * from (select (fields->>'id')::int id, (fields->>'c_id')::int c_id from b) b group by b.id, b.c_id) s on (d.a)::int = (s.id)::int; -- similarly, but keying off a DISTINCT clause ---Testcase 370: +--Testcase 382: explain (costs off) select d.* from (select (fields->>'a')::int a, (fields->>'b')::int b from d) d left join (select distinct * from (select (fields->>'id')::int id, (fields->>'c_id')::int c_id from b) b) s on (d.a)::int = (s.id)::int; +-- join removal is not possible here +explain (costs off) +select 1 from a t1 + left join (a t2 left join a t3 on (t2.fields->>'id')::int = 1) on (t2.fields->>'id')::int = 1; + -- check join removal works when uniqueness of the join condition is enforced -- by a UNION ---Testcase 371: +--Testcase 383: explain (costs off) select d.* from (select (fields->>'a')::int a, (fields->>'b')::int b from d) d left join (select (fields->>'id')::int id from a union select (fields->>'id')::int id from b) s on (d.a)::int = (s.id)::int; -- check join removal with a cross-type comparison operator ---Testcase 372: +--Testcase 384: explain (costs off) select i8.* from (select (fields->>'q1')::int8 q1, (fields->>'q2')::int8 q2 from INT8_TBL i8) i8 left join (select (fields->>'f1')::int f1 from int4_tbl group by (fields->>'f1')::int) i4 on (i8.q1)::int8 = (i4.f1)::int4; -- check join removal with lateral references ---Testcase 373: +--Testcase 385: explain (costs off) select 1 from (select (a.fields->>'id')::int id FROM a left join b on (a.fields->>'b_id')::int = (b.fields->>'id')::int) q, lateral generate_series(1, (q.id)::int) gs(i) where (q.id)::int = (gs.i)::int; ---Testcase 374: +-- check join removal within RHS of an outer join +explain (costs off) +select c.fields->>'id', ss.a from c + left join (select d.fields->>'a' a from onerow, d left join b on (d.fields->>'a')::int = (b.fields->>'id')::int) ss + on (c.fields->>'id')::int = ss.a::int; + +CREATE TEMP TABLE parted_b (id int PRIMARY KEY) partition by range(id); +CREATE TEMP TABLE parted_b1 partition of parted_b for values from (0) to (10); + +-- test join removals on a partitioned table +explain (costs off) +select a.* from a left join parted_b pb on (a.fields->>'b_id')::int = pb.id; + +--Testcase 386: DELETE FROM a_nsc; ---Testcase 375: +--Testcase 387: DELETE FROM b_nsc; ---Testcase 376: +--Testcase 388: DELETE FROM c_nsc; ---Testcase 377: +--Testcase 389: DELETE FROM d_nsc; ---Testcase 378: +--Testcase 390: DROP FOREIGN TABLE a; +--Testcase 619: DROP FOREIGN TABLE a_nsc; ---Testcase 379: +--Testcase 391: DROP FOREIGN TABLE b; +--Testcase 620: DROP FOREIGN TABLE b_nsc; ---Testcase 380: +--Testcase 392: DROP FOREIGN TABLE c; +--Testcase 621: DROP FOREIGN TABLE c_nsc; ---Testcase 381: +--Testcase 393: DROP FOREIGN TABLE d; +--Testcase 622: DROP FOREIGN TABLE d_nsc; rollback; ---Testcase 382: +--Testcase 394: create foreign table parent (fields jsonb OPTIONS (fields 'true')) server influxdb_svr OPTIONS(schemaless 'true'); +--Testcase 623: create foreign table parent_nsc (k int, pd int) server influxdb_svr OPTIONS (table 'parent'); ---Testcase 383: +--Testcase 395: create foreign table child (fields jsonb OPTIONS (fields 'true')) server influxdb_svr OPTIONS(schemaless 'true'); +--Testcase 624: create foreign table child_nsc (k int, cd int) server influxdb_svr OPTIONS (table 'child'); ---Testcase 384: +--Testcase 396: insert into parent_nsc values (1, 10), (2, 20), (3, 30); ---Testcase 385: +--Testcase 397: insert into child_nsc values (1, 100), (4, 400); -- this case is optimizable ---Testcase 386: +--Testcase 398: select p.* from (select (fields->>'k')::int k, (fields->>'pd')::int pd from parent p) p left join (select (fields->>'k')::int k, (fields->>'cd')::int cd from child c) c on ((p.k)::int = (c.k)::int); ---Testcase 387: +--Testcase 399: explain (costs off) select p.* from (select (fields->>'k')::int k, (fields->>'pd')::int pd from parent p) p left join (select (fields->>'k')::int k, (fields->>'cd')::int cd from child c) c on ((p.k)::int = (c.k)::int); -- this case is not ---Testcase 388: +--Testcase 400: select p.*, linked from (select (fields->>'k')::int k, (fields->>'pd')::int pd from parent p) p left join (select c.*, true as linked from (select (fields->>'k')::int k, (fields->>'cd')::int cd from child c) c) as ss on (p.k = ss.k); ---Testcase 389: +--Testcase 401: explain (costs off) select p.*, linked from (select (fields->>'k')::int k, (fields->>'pd')::int pd from parent p) p left join (select c.*, true as linked from (select (fields->>'k')::int k, (fields->>'cd')::int cd from child c) c) as ss on (p.k = ss.k); -- check for a 9.0rc1 bug: join removal breaks pseudoconstant qual handling ---Testcase 390: +--Testcase 402: select p.* from (select (fields->>'k')::int k, (fields->>'pd')::int pd from parent) p left join (select (fields->>'k')::int k, (fields->>'cd')::int cd from child) c on ((p.k)::int = (c.k)::int) where (p.k)::int = 1 and (p.k)::int = 2; ---Testcase 391: +--Testcase 403: explain (costs off) select p.* from (select (fields->>'k')::int k, (fields->>'pd')::int pd from parent) p left join (select (fields->>'k')::int k, (fields->>'cd')::int cd from child) c on ((p.k)::int = (c.k)::int) where (p.k)::int = 1 and (p.k)::int = 2; ---Testcase 392: +--Testcase 404: select p.* from ((select (fields->>'k')::int k, (fields->>'pd')::int pd from parent) p left join (select (fields->>'k')::int k, (fields->>'cd')::int cd from child) c on ((p.k)::int = (c.k)::int)) join (select (fields->>'k')::int k, (fields->>'pd')::int pd from parent) x on (p.k)::int = (x.k)::int where (p.k)::int = 1 and (p.k)::int = 2; ---Testcase 393: +--Testcase 405: explain (costs off) select p.* from ((select (fields->>'k')::int k, (fields->>'pd')::int pd from parent) p left join (select (fields->>'k')::int k, (fields->>'cd')::int cd from child) c on ((p.k)::int = (c.k)::int)) join (select (fields->>'k')::int k, (fields->>'pd')::int pd from parent) x on (p.k)::int = (x.k)::int @@ -2113,42 +2676,47 @@ select p.* from -- bug 5255: this is not optimizable by join removal begin; ---Testcase 394: +--Testcase 406: CREATE FOREIGN TABLE a (fields jsonb OPTIONS (fields 'true')) SERVER influxdb_svr OPTIONS(schemaless 'true'); +--Testcase 625: CREATE FOREIGN TABLE a_nsc (id int) SERVER influxdb_svr OPTIONS (table 'a'); ---Testcase 395: +--Testcase 407: CREATE FOREIGN TABLE b (fields jsonb OPTIONS (fields 'true')) SERVER influxdb_svr OPTIONS(schemaless 'true'); +--Testcase 626: CREATE FOREIGN TABLE b_nsc (id int, a_id int) SERVER influxdb_svr OPTIONS (table 'b'); ---Testcase 396: +--Testcase 408: INSERT INTO a_nsc VALUES (0), (1); ---Testcase 397: +--Testcase 409: INSERT INTO b_nsc VALUES (0, 0), (1, NULL); ---Testcase 398: +--Testcase 410: SELECT * FROM (select (fields->>'id')::int id, (fields->>'a_id')::int a_id from b) b LEFT JOIN (select (fields->>'id')::int id from a) a ON ((b.a_id)::int = (a.id)::int) WHERE ((a.id)::int IS NULL OR (a.id)::int > 0); ---Testcase 399: +--Testcase 411: SELECT b.* FROM (select (fields->>'id')::int id, (fields->>'a_id')::int a_id from b) b LEFT JOIN (select (fields->>'id')::int id from a) a ON ((b.a_id)::int = (a.id)::int) WHERE ((a.id)::int IS NULL OR (a.id)::int > 0); ---Testcase 400: +--Testcase 412: DELETE FROM a_nsc; ---Testcase 401: +--Testcase 413: DELETE FROM b_nsc; ---Testcase 402: +--Testcase 414: DROP FOREIGN TABLE a; +--Testcase 627: DROP FOREIGN TABLE a_nsc; ---Testcase 403: +--Testcase 415: DROP FOREIGN TABLE b; +--Testcase 628: DROP FOREIGN TABLE b_nsc; rollback; -- another join removal bug: this is not optimizable, either begin; ---Testcase 404: +--Testcase 416: create foreign table innertab (fields jsonb OPTIONS (fields 'true')) server influxdb_svr OPTIONS(schemaless 'true'); +--Testcase 629: create foreign table innertab_nsc (id int8, dat1 int8) server influxdb_svr OPTIONS (table 'innertab'); ---Testcase 405: +--Testcase 417: insert into innertab_nsc values(123, 42); ---Testcase 406: +--Testcase 418: SELECT * FROM (SELECT 1 AS x) ss1 LEFT JOIN @@ -2156,9 +2724,35 @@ SELECT * FROM FROM (select (fields->>'q1')::int8 q1, (fields->>'q2')::int8 q2 from INT8_TBL) int8_tbl LEFT JOIN (select (fields->>'id')::int id, (fields->>'dat1')::int dat1 from innertab) innertab ON (q2)::int8 = (id)::int) ss2 ON true; +-- join removal bug #17769: can't remove if there's a pushed-down reference +EXPLAIN (COSTS OFF) +SELECT q2 FROM + (SELECT (int8_tbl.fields->>'q1')::int8 q1, (int8_tbl.fields->>'q2')::int8 q2, (innertab.fields->>'id')::int id, (innertab.fields->>'dat1')::int dat1 + FROM int8_tbl LEFT JOIN innertab ON (int8_tbl.fields->>'q2')::int8 = (innertab.fields->>'id')::int) ss + WHERE COALESCE(dat1, 0) = q1; + +-- join removal bug #17773: otherwise-removable PHV appears in a qual condition +EXPLAIN (VERBOSE, COSTS OFF) +SELECT q2 FROM + (SELECT (int8_tbl.fields->>'q2')::int8 q2, 'constant'::text AS x + FROM int8_tbl LEFT JOIN innertab ON (int8_tbl.fields->>'q2')::int8 = (innertab.fields->>'id')::int) ss + RIGHT JOIN int4_tbl ON NULL + WHERE x >= x; + +-- join removal bug #17786: check that OR conditions are cleaned up +EXPLAIN (COSTS OFF) +SELECT (int4_tbl.fields->>'f1'), x +FROM int4_tbl + JOIN ((SELECT 42 AS x FROM int8_tbl LEFT JOIN innertab ON (int8_tbl.fields->>'q1')::int8 = (innertab.fields->>'id')::int) AS ss1 + RIGHT JOIN tenk1 ON NULL) + ON (tenk1.fields->>'unique1')::int = ss1.x OR (tenk1.fields->>'unique2')::int = ss1.x; + -- Clean up +--Testcase 630: DELETE FROM innertab_nsc; +--Testcase 631: DROP FOREIGN TABLE innertab; +--Testcase 632: DROP FOREIGN TABLE innertab_nsc; rollback; @@ -2166,10 +2760,10 @@ rollback; -- another join removal bug: we must clean up correctly when removing a PHV begin; ---Testcase 407: +--Testcase 419: create foreign table uniquetbl (fields jsonb OPTIONS (fields 'true')) server influxdb_svr OPTIONS(schemaless 'true'); ---Testcase 408: +--Testcase 420: explain (costs off) select t1.* from (select fields->>'f1' f1 from uniquetbl t1) as t1 @@ -2178,7 +2772,7 @@ select t1.* from left join (select fields->>'f1' f1 from uniquetbl t3) t3 on t2.d1 = t3.f1; ---Testcase 409: +--Testcase 421: explain (costs off) select t0.* from @@ -2192,7 +2786,7 @@ from on t0.f1 = ss.case1 where ss.stringu2 !~* ss.case1; ---Testcase 410: +--Testcase 422: select t0.* from (select fields->>'f1' f1 from text_tbl t0) t0 @@ -2207,8 +2801,68 @@ where ss.stringu2 !~* ss.case1; rollback; +-- another join removal bug: we must clean up EquivalenceClasses too +begin; + +create foreign table t (fields jsonb OPTIONS (fields 'true')) server influxdb_svr OPTIONS (table 't1_eq_class', schemaless 'true'); +create foreign table t_tmp (a int) server influxdb_svr OPTIONS (table 't1_eq_class'); +insert into t_tmp values (1); + +explain (costs off) +select 1 +from (select (fields->>'a')::int as a from t) t1 + left join (select 2 as c + from (select (fields->>'a')::int as a from t) t2 left join (select (fields->>'a')::int as a from t) t3 on t2.a = t3.a) s + on true +where t1.a = s.c; + +select 1 +from (select (fields->>'a')::int as a from t) t1 + left join (select 2 as c + from (select (fields->>'a')::int as a from t) t2 left join (select (fields->>'a')::int as a from t) t3 on t2.a = t3.a) s + on true +where t1.a = s.c; + +rollback; + +-- test cases where we can remove a join, but not a PHV computed at it +begin; + +create foreign table t (fields jsonb OPTIONS (fields 'true')) server influxdb_svr OPTIONS (table 't2_eq_class', schemaless 'true'); +create foreign table t_tmp (a int, b int) server influxdb_svr OPTIONS (table 't2_eq_class'); +insert into t_tmp values (1,1), (2,2); + +explain (costs off) +select 1 +from (select (fields->>'a')::int as a, (fields->>'b')::int as b from t) t1 + left join (select t2.a, 1 as c + from (select (fields->>'a')::int as a, (fields->>'b')::int as b from t) t2 left join (select (fields->>'a')::int as a, (fields->>'b')::int as b from t) t3 on t2.a = t3.a) s + on true + left join (select (fields->>'a')::int as a, (fields->>'b')::int as b from t) t4 on true +where s.a < s.c; + +explain (costs off) +select t1.a, s.* +from (select (fields->>'a')::int as a, (fields->>'b')::int as b from t) t1 + left join lateral (select t2.a, coalesce(t1.a, 1) as c + from (select (fields->>'a')::int as a, (fields->>'b')::int as b from t) t2 left join (select (fields->>'a')::int as a, (fields->>'b')::int as b from t) t3 on t2.a = t3.a) s + on true + left join (select (fields->>'a')::int as a, (fields->>'b')::int as b from t) t4 on true +where s.a < s.c; + +select t1.a, s.* +from (select (fields->>'a')::int as a, (fields->>'b')::int as b from t) t1 + left join lateral (select t2.a, coalesce(t1.a, 1) as c + from (select (fields->>'a')::int as a, (fields->>'b')::int as b from t) t2 left join (select (fields->>'a')::int as a, (fields->>'b')::int as b from t) t3 on t2.a = t3.a) s + on true + left join (select (fields->>'a')::int as a, (fields->>'b')::int as b from t) t4 on true +where s.a < s.c; + +rollback; + + -- test case to expose miscomputation of required relid set for a PHV ---Testcase 411: +--Testcase 423: explain (verbose, costs off) select i8.*, ss.v, (t.fields->>'unique2')::int4 unique2 from (select (fields->>'q1')::int8 q1, (fields->>'q2')::int8 q2 from INT8_TBL i8) i8 @@ -2217,7 +2871,7 @@ select i8.*, ss.v, (t.fields->>'unique2')::int4 unique2 left join tenk1 t on (t.fields->>'unique2')::int4 = (ss.v)::int4 where q2::int8 = 456; ---Testcase 412: +--Testcase 424: select i8.*, ss.v, (t.fields->>'unique2')::int4 unique2 from (select (fields->>'q1')::int8 q1, (fields->>'q2')::int8 q2 from INT8_TBL i8) i8 left join int4_tbl i4 on (i4.fields->>'f1')::int4 = 1 @@ -2225,15 +2879,37 @@ select i8.*, ss.v, (t.fields->>'unique2')::int4 unique2 left join tenk1 t on (t.fields->>'unique2')::int4 = (ss.v)::int4 where q2::int8 = 456; +-- InfluxDB does not support partition table, create local table for test +-- and check a related issue where we miscompute required relids for +-- a PHV that's been translated to a child rel +--Testcase 570: +create temp table parttbl (a integer primary key) partition by range (a); +--Testcase 571: +create temp table parttbl1 partition of parttbl for values from (1) to (100); +--Testcase 572: +insert into parttbl values (11), (12); +--Testcase 573: +explain (costs off) +select * from + (select *, 12 as phv from parttbl) as ss + right join (select (fields->>'f1')::int4 f1 from int4_tbl) int4_tbl on true +where ss.a = ss.phv and f1 = 0; + +--Testcase 574: +select * from + (select *, 12 as phv from parttbl) as ss + right join (select (fields->>'f1')::int4 f1 from int4_tbl) int4_tbl on true +where ss.a = ss.phv and f1 = 0; + -- bug #8444: we've historically allowed duplicate aliases within aliased JOINs ---Testcase 413: +--Testcase 425: select * from (select (fields->>'q1')::int8 q1, (fields->>'q2')::int8 q2 from INT8_TBL) x join ((select (fields->>'f1')::int4 f1 from INT4_TBL) x cross join (select (fields->>'f1')::int4 f1 from INT4_TBL) y) j on q1 = f1; -- error ---Testcase 414: +--Testcase 426: select * from (select (fields->>'q1')::int8 q1, (fields->>'q2')::int8 q2 from INT8_TBL) x join ((select (fields->>'f1')::int4 f1 from INT4_TBL) x cross join (select (fields->>'f1')::int4 f1 from INT4_TBL) y) j on q1 = y.f1; -- error ---Testcase 415: +--Testcase 427: select * from (select (fields->>'q1')::int8 q1, (fields->>'q2')::int8 q2 from INT8_TBL) x join ((select (fields->>'f1')::int4 f1 from INT4_TBL) x cross join (select (fields->>'f1')::int4 f1 from INT4_TBL) y(ff)) j on q1 = f1; -- ok @@ -2241,236 +2917,244 @@ select * from -- Test hints given on incorrect column references are useful -- ---Testcase 416: -select( t1.ffields->>'unique1')::int4 unique1 from +--Testcase 428: +select (t1.ffields->>'unique1')::int4 unique1 from tenk1 t1 join tenk2 t2 on (t1.fields->>'two')::int4 = (t2.fields->>'two')::int4; -- error, prefer "t1" suggestion ---Testcase 417: +--Testcase 429: select (t2.ffields->>'unique1')::int4 unique1 from tenk1 t1 join tenk2 t2 on (t1.fields->>'two')::int4 = (t2.fields->>'two')::int4; -- error, prefer "t2" suggestion ---Testcase 418: +--Testcase 430: select (ffields->>'unique1')::int4 unique1 from tenk1 t1 join tenk2 t2 on (t1.fields->>'two')::int4 = (t2.fields->>'two')::int4; -- error, suggest both at once +select (ffields->>'ctid')::int4 ctid from + tenk1 t1 join tenk2 t2 on (t1.fields->>'two')::int4 = (t2.fields->>'two')::int4; -- error, need qualification -- -- Take care to reference the correct RTE -- ---Testcase 556: +--Testcase 431: 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'; +-- Test bug in rangetable flattening +explain (verbose, costs off) +select 1 from + (select * from int8_tbl where (int8_tbl.fields->>'q1')::int8 <> (select 42) offset 0) ss +where false; + -- -- Test LATERAL -- ---Testcase 419: +--Testcase 432: select unique2, x.* from (select (fields->>'unique1')::int4 unique1, (fields->>'unique2')::int4 unique2, fields->>'two' two, fields->>'four' four, fields->>'ten' ten, fields->>'twenty' twenty, fields->>'hundred' hundred, fields->>'thousand' thousand, fields->>'twothousand' twothousand, fields->>'fivethous' fivethous, fields->>'tenthous' tenthous, fields->>'odd' odd, fields->>'even' even, fields->>'stringu1' stringu1, fields->>'stringu2' stringu2, fields->>'string4' string4 from tenk1 a) a, lateral (select * from (select (fields->>'f1')::int4 f1 from INT4_TBL b) b where f1 = a.unique1) x; ---Testcase 420: +--Testcase 433: explain (costs off) select unique2, x.* from (select (fields->>'unique1')::int4 unique1, (fields->>'unique2')::int4 unique2, fields->>'two' two, fields->>'four' four, fields->>'ten' ten, fields->>'twenty' twenty, fields->>'hundred' hundred, fields->>'thousand' thousand, fields->>'twothousand' twothousand, fields->>'fivethous' fivethous, fields->>'tenthous' tenthous, fields->>'odd' odd, fields->>'even' even, fields->>'stringu1' stringu1, fields->>'stringu2' stringu2, fields->>'string4' string4 from tenk1 a) a, lateral (select * from (select (fields->>'f1')::int4 f1 from INT4_TBL b) b where f1 = a.unique1) x; ---Testcase 421: +--Testcase 434: select unique2, x.* from (select (fields->>'f1')::int4 f1 from INT4_TBL x) x, lateral (select (fields->>'unique2')::int4 unique2 from tenk1 where f1 = (fields->>'unique1')::int4) ss; ---Testcase 422: +--Testcase 435: explain (costs off) select unique2, x.* from (select (fields->>'f1')::int4 f1 from INT4_TBL x) x, lateral (select (fields->>'unique2')::int4 unique2 from tenk1 where f1 = (fields->>'unique1')::int4) ss; ---Testcase 423: +--Testcase 436: explain (costs off) select unique2, x.* from (select (fields->>'f1')::int4 f1 from INT4_TBL x) x cross join lateral (select (fields->>'unique2')::int4 unique2 from tenk1 where f1 = (fields->>'unique1')::int4) ss; ---Testcase 424: +--Testcase 437: select unique2, x.* from (select (fields->>'f1')::int4 f1 from INT4_TBL x) x left join lateral (select (fields->>'unique1')::int4 unique1, (fields->>'unique2')::int4 unique2 from tenk1 where f1 = (fields->>'unique1')::int4) ss on true; ---Testcase 425: +--Testcase 438: explain (costs off) select unique2, x.* from (select (fields->>'f1')::int4 f1 from INT4_TBL x) x left join lateral (select (fields->>'unique1')::int4 unique1, (fields->>'unique2')::int4 unique2 from tenk1 where f1 = (fields->>'unique1')::int4) ss on true; -- check scoping of lateral versus parent references -- the first of these should return int8_tbl.q2, the second int8_tbl.q1 ---Testcase 426: +--Testcase 439: select *, (select r from (select q1 as q2) x, (select q2 as r) y) from (select (fields->>'q1')::int8 q1, (fields->>'q2')::int8 q2 from INT8_TBL) int8_tbl; ---Testcase 427: +--Testcase 440: select *, (select r from (select q1 as q2) x, lateral (select q2 as r) y) from (select (fields->>'q1')::int8 q1, (fields->>'q2')::int8 q2 from INT8_TBL) int8_tbl; -- lateral with function in FROM ---Testcase 428: +--Testcase 441: select count(*) from tenk1 a, lateral generate_series(1, (fields->>'two')::int4) g; ---Testcase 429: +--Testcase 442: explain (costs off) select count(*) from tenk1 a, lateral generate_series(1, (fields->>'two')::int4) g; ---Testcase 430: +--Testcase 443: explain (costs off) select count(*) from tenk1 a cross join lateral generate_series(1,(fields->>'two')::int4) g; -- don't need the explicit LATERAL keyword for functions ---Testcase 431: +--Testcase 444: explain (costs off) select count(*) from tenk1 a, generate_series(1,(fields->>'two')::int4) g; -- lateral with UNION ALL subselect ---Testcase 432: +--Testcase 445: explain (costs off) select * from generate_series(100,200) g, lateral (select * from (select (fields->>'q1')::int8 q1, (fields->>'q2')::int8 q2 from INT8_TBL a) a where g = (q1)::int8 union all select * from (select (fields->>'q1')::int8 q1, (fields->>'q2')::int8 q2 from INT8_TBL b) b where g = (q2)::int8) ss; ---Testcase 433: +--Testcase 446: select * from generate_series(100,200) g, lateral (select * from (select (fields->>'q1')::int8 q1, (fields->>'q2')::int8 q2 from INT8_TBL a) a where g = (q1)::int8 union all select * from (select (fields->>'q1')::int8 q1, (fields->>'q2')::int8 q2 from INT8_TBL b) b where g = (q2)::int8) ss; -- lateral with VALUES ---Testcase 434: +--Testcase 447: explain (costs off) select count(*) from tenk1 a, tenk1 b join lateral (values(a.fields->>'unique1')) ss(x) on b.fields->>'unique2' = ss.x; ---Testcase 435: +--Testcase 448: select count(*) from tenk1 a, tenk1 b join lateral (values(a.fields->>'unique1')) ss(x) on b.fields->>'unique2' = ss.x; -- lateral with VALUES, no flattening possible ---Testcase 436: +--Testcase 449: explain (costs off) select count(*) from tenk1 a, tenk1 b join lateral (values((a.fields->>'unique1')::int4),(-1)) ss(x) on (b.fields->>'unique2')::int4 = (ss.x)::int; ---Testcase 437: +--Testcase 450: select count(*) from tenk1 a, tenk1 b join lateral (values((a.fields->>'unique1')::int4),(-1)) ss(x) on (b.fields->>'unique2')::int4 = (ss.x)::int; -- lateral injecting a strange outer join condition ---Testcase 438: +--Testcase 451: explain (costs off) select * from (select (fields->>'q1')::int8 q1, (fields->>'q2')::int8 q2 from INT8_TBL a) a, (select (fields->>'q1')::int8 q1, (fields->>'q2')::int8 q2 from INT8_TBL x) x left join lateral (select a.q1 from (select (fields->>'f1')::int4 f1 from INT4_TBL y) y) ss(z) on x.q2 = ss.z order by (a.q1)::int8, (a.q2)::int8, (x.q1)::int8, (x.q2)::int8, (ss.z)::int8; ---Testcase 439: +--Testcase 452: select * from (select (fields->>'q1')::int8 q1, (fields->>'q2')::int8 q2 from INT8_TBL a) a, (select (fields->>'q1')::int8 q1, (fields->>'q2')::int8 q2 from INT8_TBL x) x left join lateral (select a.q1 from (select (fields->>'f1')::int4 f1 from INT4_TBL y) y) ss(z) on x.q2 = ss.z order by (a.q1)::int8, (a.q2)::int8, (x.q1)::int8, (x.q2)::int8, (ss.z)::int8; -- lateral reference to a join alias variable ---Testcase 440: +--Testcase 453: select * from (select (fields->>'f1')::int4/2 as x from int4_tbl) ss1 join (select (fields->>'f1')::int4 f1 from INT4_TBL) i4 on x::int4 = (f1)::int4, lateral (select x) ss2(y); ---Testcase 441: +--Testcase 454: select * from (select (fields->>'f1')::int4 as x from int4_tbl) ss1 join (select (fields->>'f1')::int4 f1 from INT4_TBL) i4 on x::int4 = (f1)::int4, lateral (values(x)) ss2(y); ---Testcase 442: +--Testcase 455: select * from ((select (fields->>'f1')::int4/2 as x from int4_tbl) ss1 join (select (fields->>'f1')::int4 f1 from INT4_TBL) i4 on x::int4 = (f1)::int4) j, lateral (select x) ss2(y); -- lateral references requiring pullup ---Testcase 443: +--Testcase 456: select * from (values(1)) x(lb), lateral generate_series(lb,4) x4; ---Testcase 444: +--Testcase 457: select * from (select (fields->>'f1')::int4/1000000000 from int4_tbl) x(lb), lateral generate_series(lb,4) x4; ---Testcase 445: +--Testcase 458: select * from (values(1)) x(lb), lateral (values(lb)) y(lbcopy); ---Testcase 446: +--Testcase 459: select * from (values(1)) x(lb), lateral (select lb from int4_tbl) y(lbcopy); ---Testcase 447: +--Testcase 460: select * from (select (fields->>'q1')::int8 q1, (fields->>'q2')::int8 q2 from INT8_TBL) x left join (select (fields->>'q1')::int8 q1,coalesce((fields->>'q2')::int8,0) q2 from int8_tbl) y on x.q2 = y.q1, lateral (values(x.q1,y.q1,y.q2)) v(xq1,yq1,yq2) ORDER BY xq1, yq1, yq2; ---Testcase 448: +--Testcase 461: select * from (select (fields->>'q1')::int8 q1, (fields->>'q2')::int8 q2 from INT8_TBL) x left join (select (fields->>'q1')::int8 q1,coalesce((fields->>'q2')::int8,0) q2 from int8_tbl) y on x.q2 = y.q1, lateral (select x.q1,y.q1,y.q2) v(xq1,yq1,yq2) ORDER BY xq1, yq1, yq2; ---Testcase 449: +--Testcase 462: select x.* from (select (fields->>'q1')::int8 q1, (fields->>'q2')::int8 q2 from INT8_TBL) x left join (select (fields->>'q1')::int8 q1,coalesce((fields->>'q2')::int8,0) q2 from int8_tbl) y on x.q2 = y.q1, lateral (select x.q1,y.q1,y.q2) v(xq1,yq1,yq2) ORDER BY xq1, yq1, yq2; ---Testcase 450: +--Testcase 463: select v.* from (int8_tbl x left join (select (fields->>'q1')::int8 q1,coalesce((fields->>'q2')::int8,0) q2 from int8_tbl) y on (x.fields->>'q2')::int8 = y.q1) left join int4_tbl z on (z.fields->>'f1')::int8 = (x.fields->>'q2')::int8, lateral (select (x.fields->>'q1')::int8,(y.q1)::int8 union all select (x.fields->>'q2')::int8,(y.q2)::int8) v(vx,vy); ---Testcase 451: +--Testcase 464: select v.* from (int8_tbl x left join (select (fields->>'q1')::int8 q1,(select coalesce((fields->>'q2')::int8,0)) q2 from int8_tbl) y on (x.fields->>'q2')::int8 = y.q1) left join int4_tbl z on (z.fields->>'f1')::int8 = (x.fields->>'q2')::int8, lateral (select (x.fields->>'q1')::int8,(y.q1)::int8 union all select (x.fields->>'q2')::int8,(y.q2)::int8) v(vx,vy); ---Testcase 452: +--Testcase 465: select v.* from (int8_tbl x left join (select (fields->>'q1')::int8 q1,(select coalesce((fields->>'q2')::int8,0)) q2 from int8_tbl) y on (x.fields->>'q2')::int8 = y.q1) left join int4_tbl z on (z.fields->>'f1')::int8 = (x.fields->>'q2')::int8, - lateral (select (x.fields->>'q1')::int8,(y.q1)::int8 from onerow union all select (x.fields->>'q2')::int8,(y.q2)::int8 from onerow) v(vx,vy); + lateral (select (x.fields->>'q1')::int8,(y.q1)::int8 from onerow union all select (x.fields->>'q2')::int8,(y.q2)::int8 from onerow) v(vx,vy); ---Testcase 453: +--Testcase 466: explain (verbose, costs off) select * from (select (fields->>'q1')::int8 q1, (fields->>'q2')::int8 q2 from INT8_TBL a) a left join lateral (select *, a.q2 as x from (select (fields->>'q1')::int8 q1, (fields->>'q2')::int8 q2 from INT8_TBL b) b) ss on a.q2 = ss.q1; ---Testcase 454: +--Testcase 467: select * from (select (fields->>'q1')::int8 q1, (fields->>'q2')::int8 q2 from INT8_TBL a) a left join lateral (select *, a.q2 as x from (select (fields->>'q1')::int8 q1, (fields->>'q2')::int8 q2 from INT8_TBL b) b) ss on a.q2 = ss.q1; ---Testcase 455: +--Testcase 468: explain (verbose, costs off) select * from (select (fields->>'q1')::int8 q1, (fields->>'q2')::int8 q2 from INT8_TBL a) a left join lateral (select *, coalesce((a.q2)::int8, 42) as x from (select (fields->>'q1')::int8 q1, (fields->>'q2')::int8 q2 from INT8_TBL b) b) ss on a.q2 = ss.q1; ---Testcase 456: +--Testcase 469: select * from (select (fields->>'q1')::int8 q1, (fields->>'q2')::int8 q2 from INT8_TBL a) a left join lateral (select *, coalesce((a.q2)::int8, 42) as x from (select (fields->>'q1')::int8 q1, (fields->>'q2')::int8 q2 from INT8_TBL b) b) ss on a.q2 = ss.q1; -- lateral can result in join conditions appearing below their -- real semantic level ---Testcase 457: +--Testcase 470: explain (verbose, costs off) select * from (select (fields->>'f1')::int4 f1 from INT4_TBL i) i left join lateral (select * from (select (fields->>'f1')::int2 f1 from INT2_TBL j) j where i.f1 = j.f1) k on true; ---Testcase 458: +--Testcase 471: select * from (select (fields->>'f1')::int4 f1 from INT4_TBL i) i left join lateral (select * from (select (fields->>'f1')::int2 f1 from INT2_TBL j) j where i.f1 = j.f1) k on true; ---Testcase 459: +--Testcase 472: explain (verbose, costs off) select * from (select (fields->>'f1')::int4 f1 from INT4_TBL i) i left join lateral (select coalesce(i) from (select (fields->>'f1')::int2 f1 from INT2_TBL j) j where i.f1 = j.f1) k on true; ---Testcase 460: +--Testcase 473: select * from (select (fields->>'f1')::int4 f1 from INT4_TBL i) i left join lateral (select coalesce(i) from (select (fields->>'f1')::int2 f1 from INT2_TBL j) j where i.f1 = j.f1) k on true; ---Testcase 461: +--Testcase 474: explain (verbose, costs off) select * from (select (fields->>'f1')::int4 f1 from INT4_TBL a) a, lateral ( select * from (select (fields->>'f1')::int4 f1 from INT4_TBL b) b left join (select (fields->>'q1')::int8 q1, (fields->>'q2')::int8 q2 from INT8_TBL c) c on (b.f1 = q1 and a.f1 = q2) ) ss; ---Testcase 462: +--Testcase 475: select * from (select (fields->>'f1')::int4 f1 from INT4_TBL a) a, lateral ( select * from (select (fields->>'f1')::int4 f1 from INT4_TBL b) b left join (select (fields->>'q1')::int8 q1, (fields->>'q2')::int8 q2 from INT8_TBL c) c on (b.f1 = q1 and a.f1 = q2) ) ss; -- lateral reference in a PlaceHolderVar evaluated at join level ---Testcase 463: +--Testcase 476: explain (verbose, costs off) select * from - (select (fields->>'q1')::int8 q1, (fields->>'q2')::int8 q2 from INT8_TBL a) a left join lateral - (select (b.fields->>'q1')::int8 as bq1, (c.fields->>'q1')::int8 as cq1, least(a.q1,(b.fields->>'q1')::int8,(c.fields->>'q1')::int8) from + (select (fields->>'q1')::int8 q1, (fields->>'q2')::int8 q2 from INT8_TBL) a left join lateral + (select (b.fields->>'q1')::int8 as bq1, (c.fields->>'q1')::int8 as cq1, least(a.q1,(b.fields->>'q1')::int8,(c.fields->>'q1')::int8) from int8_tbl b cross join int8_tbl c) ss on a.q2 = ss.bq1; ---Testcase 464: +--Testcase 477: select * from - (select (fields->>'q1')::int8 q1, (fields->>'q2')::int8 q2 from INT8_TBL a) a left join lateral + (select (fields->>'q1')::int8 q1, (fields->>'q2')::int8 q2 from INT8_TBL) a left join lateral (select (b.fields->>'q1')::int8 as bq1, (c.fields->>'q1')::int8 as cq1, least(a.q1,(b.fields->>'q1')::int8,(c.fields->>'q1')::int8) from int8_tbl b cross join int8_tbl c) ss on a.q2 = ss.bq1; -- case requiring nested PlaceHolderVars ---Testcase 465: +--Testcase 478: explain (verbose, costs off) select * from (select (fields->>'q1')::int8 q1, (fields->>'q2')::int8 q2 from INT8_TBL c) c left join ( @@ -2482,7 +3166,7 @@ select * from lateral (select ss2.y offset 0) ss3; -- case that breaks the old ph_may_need optimization ---Testcase 466: +--Testcase 479: explain (verbose, costs off) select c.*,a.*,ss1.q1,ss2.q1,ss3.* from (select (fields->>'q1')::int8 q1, (fields->>'q2')::int8 q2 from INT8_TBL c) c left join ( @@ -2496,7 +3180,7 @@ select c.*,a.*,ss1.q1,ss2.q1,ss3.* from lateral (select * from (select (fields->>'f1')::int4 f1 from INT4_TBL i) i where (ss2.y)::int8 > (f1)::int4) ss3; -- check processing of postponed quals (bug #9041) ---Testcase 467: +--Testcase 480: explain (verbose, costs off) select * from (select 1 as x offset 0) x cross join (select 2 as y offset 0) y @@ -2504,18 +3188,24 @@ select * from select * from (select 3 as z offset 0) z where z.z = x.x ) zz on zz.z = y.y; +-- 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.fields->>'f1')::int = 1 + inner join (int4_tbl t4 left join int4_tbl t5 on true) on true) ss; + -- check dummy rels with lateral references (bug #15694) ---Testcase 468: +--Testcase 481: explain (verbose, costs off) select * from (select (fields->>'q1')::int8 q1, (fields->>'q2')::int8 q2 from INT8_TBL i8) i8 left join lateral (select *, i8.q2 from (select (fields->>'f1')::int4 f1 from INT4_TBL int4_tbl) int4_tbl where false) ss on true; ---Testcase 469: +--Testcase 482: explain (verbose, costs off) select * from (select (fields->>'q1')::int8 q1, (fields->>'q2')::int8 q2 from INT8_TBL i8) i8 left join lateral (select *, i8.q2 from (select (fields->>'f1')::int4 f1 from INT4_TBL i1) i1, (select (fields->>'f1')::int4 f1 from INT4_TBL i2) i2 where false) ss on true; -- check handling of nested appendrels inside LATERAL ---Testcase 470: +--Testcase 483: select * from ((select 2 as v) union all (select 3 as v)) as q1 cross join lateral @@ -2526,17 +3216,18 @@ select * from ) as q2; -- check the number of columns specified +--Testcase 665: SELECT * FROM ((SELECT fields->>'q1', fields->>'q2' FROM int8_tbl) i cross join (SELECT fields->>'f1' FROM int4_tbl) j) ss(a,b,c,d); -- check we don't try to do a unique-ified semijoin with LATERAL ---Testcase 471: +--Testcase 484: explain (verbose, costs off) select * from (values (0,9998), (1,1000)) v(id,x), lateral (select (fields->>'f1')::int4 f1 from INT4_TBL where (fields->>'f1')::int4 = any (select (fields->>'unique1')::int4 from tenk1 where (fields->>'unique2')::int4 = v.x offset 0)) ss; ---Testcase 472: +--Testcase 485: select * from (values (0,9998), (1,1000)) v(id,x), lateral (select (fields->>'f1')::int4 f1 from INT4_TBL @@ -2545,7 +3236,7 @@ select * from -- check proper extParam/allParam handling (this isn't exactly a LATERAL issue, -- but we can make the test case much more compact with LATERAL) ---Testcase 473: +--Testcase 486: explain (verbose, costs off) select * from (values (0), (1)) v(id), lateral (select * from (select (fields->>'q1')::int8 q1, (fields->>'q2')::int8 q2 from INT8_TBL) t1, @@ -2556,7 +3247,7 @@ lateral (select * from (select (fields->>'q1')::int8 q1, (fields->>'q2')::int8 q and (select v.id=0)) offset 0) ss2) ss where (t1.q1)::int8 = (ss.q2)::int8) ss0; ---Testcase 474: +--Testcase 487: select * from (values (0), (1)) v(id), lateral (select * from (select (fields->>'q1')::int8 q1, (fields->>'q2')::int8 q2 from INT8_TBL) t1, lateral (select * from @@ -2567,50 +3258,50 @@ lateral (select * from (select (fields->>'q1')::int8 q1, (fields->>'q2')::int8 q where t1.q1 = ss.q2) ss0; -- test some error cases where LATERAL should have been used but wasn't ---Testcase 475: +--Testcase 488: select (fields->>'f1')::int4 f1,(fields->>'g')::int4 g from int4_tbl a, (select fields->>'f1' as g) ss; ---Testcase 476: +--Testcase 489: select (fields->>'f1')::int4 f1,(fields->>'g')::int4 g from int4_tbl a, (select a.fields->>'f1' as g) ss; ---Testcase 477: +--Testcase 490: select (fields->>'f1')::int4 f1,(fields->>'g')::int4 g from int4_tbl a cross join (select fields->>'f1' as g) ss; ---Testcase 478: +--Testcase 491: select (fields->>'f1')::int4 f1,(fields->>'g')::int4 g from int4_tbl a cross join (select a.fields->>'f1' as g) ss; -- SQL:2008 says the left table is in scope but illegal to access here ---Testcase 479: +--Testcase 492: select (fields->>'f1')::int4 f1,(fields->>'g')::int4 g from int4_tbl a right join lateral generate_series(0, (a.fields->>'f1')::int4) g on true; ---Testcase 480: +--Testcase 493: select (fields->>'f1')::int4 f1,(fields->>'g')::int4 g from int4_tbl a full join lateral generate_series(0, (a.fields->>'f1')::int4) g on true; -- check we complain about ambiguous table references ---Testcase 481: +--Testcase 494: select * from (select (fields->>'q1')::int8 q1, (fields->>'q2')::int8 q2 from INT8_TBL) x cross join ((select (fields->>'f1')::int4 f1 from INT4_TBL) x cross join lateral (select x.f1) ss); -- LATERAL can be used to put an aggregate into the FROM clause of its query ---Testcase 482: +--Testcase 495: select 1 from tenk1 a, lateral (select max((a.fields->>'unique1')::int4) from int4_tbl b) ss; -- check behavior of LATERAL in UPDATE/DELETE ---Testcase 483: +--Testcase 496: create temp table xx1 as select fields->>'f1' as x1, -(fields->>'f1')::int4 as x2 from int4_tbl; -- error, can't do this: ---Testcase 484: +--Testcase 497: update xx1 set x2 = f1 from (select * from (select (fields->>'f1')::int4 f1 from INT4_TBL) int4_tbl where f1 = x1) ss; ---Testcase 485: +--Testcase 498: update xx1 set x2 = f1 from (select * from (select (fields->>'f1')::int4 f1 from INT4_TBL) int4_tbl where f1 = xx1.x1) ss; -- can't do it even with LATERAL: ---Testcase 486: +--Testcase 499: update xx1 set x2 = f1 from lateral (select * from (select (fields->>'f1')::int4 f1 from INT4_TBL) int4_tbl where f1 = x1) ss; -- we might in future allow something like this, but for now it's an error: ---Testcase 487: +--Testcase 500: update xx1 set x2 = f1 from xx1, lateral (select * from (select (fields->>'f1')::int4 f1 from INT4_TBL) int4_tbl where f1 = x1) ss; -- also errors: ---Testcase 488: +--Testcase 501: delete from xx1 using (select * from (select (fields->>'f1')::int4 f1 from INT4_TBL) int4_tbl where f1 = x1) ss; ---Testcase 489: +--Testcase 502: delete from xx1 using (select * from (select (fields->>'f1')::int4 f1 from INT4_TBL) int4_tbl where f1 = xx1.x1) ss; ---Testcase 490: +--Testcase 503: delete from xx1 using lateral (select * from (select (fields->>'f1')::int4 f1 from INT4_TBL) int4_tbl where f1 = x1) ss; /* @@ -2674,17 +3365,19 @@ rollback; begin; ---Testcase 491: +--Testcase 504: create foreign table fkest (fields jsonb OPTIONS (fields 'true')) server influxdb_svr OPTIONS(schemaless 'true'); +--Testcase 633: create foreign table fkest_nsc (a int, b int, c int) server influxdb_svr OPTIONS (table 'fkest'); ---Testcase 492: +--Testcase 505: create foreign table fkest1 (fields jsonb OPTIONS (fields 'true')) server influxdb_svr OPTIONS(schemaless 'true'); +--Testcase 634: create foreign table fkest1_nsc (a int, b int) server influxdb_svr OPTIONS (table 'fkest1'); ---Testcase 493: +--Testcase 506: insert into fkest_nsc select x/10, x%10, x from generate_series(1,1000) x; ---Testcase 494: +--Testcase 507: insert into fkest1_nsc select x/10, x%10 from generate_series(1,1000) x; ---Testcase 495: +--Testcase 508: explain (costs off) select * from (select (fields->>'a')::int a, (fields->>'b')::int b, (fields->>'c')::int c from fkest f) f @@ -2699,214 +3392,228 @@ rollback; -- test planner's ability to mark joins as unique -- ---Testcase 496: +--Testcase 509: create foreign table j1 (fields jsonb OPTIONS (fields 'true')) server influxdb_svr OPTIONS(schemaless 'true'); +--Testcase 635: create foreign table j1_nsc (id int) server influxdb_svr OPTIONS (table 'j1'); ---Testcase 497: +--Testcase 510: create foreign table j2 (fields jsonb OPTIONS (fields 'true')) server influxdb_svr OPTIONS(schemaless 'true'); +--Testcase 636: create foreign table j2_nsc (id int) server influxdb_svr OPTIONS (table 'j2'); ---Testcase 498: +--Testcase 511: create foreign table j3 (fields jsonb OPTIONS (fields 'true')) server influxdb_svr OPTIONS(schemaless 'true'); +--Testcase 637: create foreign table j3_nsc (id int) server influxdb_svr OPTIONS (table 'j3'); ---Testcase 499: +--Testcase 512: insert into j1_nsc values(1),(2),(3); ---Testcase 500: +--Testcase 513: insert into j2_nsc values(1),(2),(3); ---Testcase 501: +--Testcase 514: insert into j3_nsc values(1),(1); -- ensure join is properly marked as unique ---Testcase 502: +--Testcase 515: explain (verbose, costs off) select * from (select (fields->>'id')::int id from j1) j1 inner join (select (fields->>'id')::int id from j2) j2 on (j1.id)::int = (j2.id)::int; -- ensure join is not unique when not an equi-join ---Testcase 503: +--Testcase 516: explain (verbose, costs off) select * from (select (fields->>'id')::int id from j1) j1 inner join (select (fields->>'id')::int id from j2) j2 on (j1.id)::int > (j2.id)::int; -- ensure non-unique rel is not chosen as inner ---Testcase 504: +--Testcase 517: explain (verbose, costs off) select * from (select (fields->>'id')::int id from j1) j1 inner join (select (fields->>'id')::int id from j3) j3 on (j1.id)::int = (j3.id)::int; -- ensure left join is marked as unique ---Testcase 505: +--Testcase 518: explain (verbose, costs off) select * from (select (fields->>'id')::int id from j1) j1 left join (select (fields->>'id')::int id from j2) j2 on (j1.id)::int = (j2.id)::int; -- ensure right join is marked as unique ---Testcase 506: +--Testcase 519: explain (verbose, costs off) select * from (select (fields->>'id')::int id from j1) j1 right join (select (fields->>'id')::int id from j2) j2 on (j1.id)::int = (j2.id)::int; -- ensure full join is marked as unique ---Testcase 507: +--Testcase 520: explain (verbose, costs off) select * from (select (fields->>'id')::int id from j1) j1 full join (select (fields->>'id')::int id from j2) j2 on (j1.id)::int = (j2.id)::int; -- a clauseless (cross) join can't be unique ---Testcase 508: +--Testcase 521: explain (verbose, costs off) select * from (select (fields->>'id')::int id from j1) j1 cross join (select (fields->>'id')::int id from j2) j2; -- ensure a natural join is marked as unique ---Testcase 509: +--Testcase 522: explain (verbose, costs off) select * from (select (fields->>'id')::int id from j1) j1 natural join (select (fields->>'id')::int id from j2) j2; -- ensure a distinct clause allows the inner to become unique ---Testcase 510: +--Testcase 523: explain (verbose, costs off) select * from (select (fields->>'id')::int id from j1 j1) j1 inner join (select distinct (fields->>'id')::int id from j3 j3) j3 on (j1.id)::int = (j3.id)::int; -- ensure group by clause allows the inner to become unique ---Testcase 511: +--Testcase 524: explain (verbose, costs off) select * from (select (fields->>'id')::int id from j1 j1) j1 inner join (select (fields->>'id')::int id from j3 j3 group by fields->>'id') j3 on (j1.id)::int = (j3.id)::int; ---Testcase 512: +--Testcase 525: delete from j1_nsc; ---Testcase 513: +--Testcase 526: delete from j2_nsc; ---Testcase 514: +--Testcase 527: delete from j3_nsc; ---Testcase 515: +--Testcase 528: drop foreign table j1; +--Testcase 638: drop foreign table j1_nsc; ---Testcase 516: +--Testcase 529: drop foreign table j2; +--Testcase 639: drop foreign table j2_nsc; ---Testcase 517: +--Testcase 530: drop foreign table j3; +--Testcase 640: drop foreign table j3_nsc; -- test more complex permutations of unique joins ---Testcase 518: +--Testcase 531: create foreign table j1 (fields jsonb OPTIONS (fields 'true')) server influxdb_svr OPTIONS(schemaless 'true'); +--Testcase 641: create foreign table j1_nsc (id1 int, id2 int) server influxdb_svr OPTIONS (table 'j1'); ---Testcase 519: +--Testcase 532: create foreign table j2 (fields jsonb OPTIONS (fields 'true')) server influxdb_svr OPTIONS(schemaless 'true'); +--Testcase 642: create foreign table j2_nsc (id1 int, id2 int) server influxdb_svr OPTIONS (table 'j2'); ---Testcase 520: +--Testcase 533: create foreign table j3 (fields jsonb OPTIONS (fields 'true')) server influxdb_svr OPTIONS(schemaless 'true'); +--Testcase 643: create foreign table j3_nsc (id1 int, id2 int) server influxdb_svr OPTIONS (table 'j3'); ---Testcase 521: +--Testcase 534: insert into j1_nsc values(1,1),(1,2); ---Testcase 522: +--Testcase 535: insert into j2_nsc values(1,1); ---Testcase 523: +--Testcase 536: insert into j3_nsc values(1,1); -- ensure there's no unique join when not all columns which are part of the -- unique index are seen in the join clause ---Testcase 524: +--Testcase 537: explain (verbose, costs off) select * from (select (fields->>'id1')::int id1, (fields->>'id2')::int id2 from j1) j1 inner join (select (fields->>'id1')::int id1, (fields->>'id2')::int id2 from j2) j2 on (j1.id1)::int = (j2.id1)::int; -- ensure proper unique detection with multiple join quals ---Testcase 525: +--Testcase 538: explain (verbose, costs off) select * from (select (fields->>'id1')::int id1, (fields->>'id2')::int id2 from j1) j1 inner join (select (fields->>'id1')::int id1, (fields->>'id2')::int id2 from j2) j2 on (j1.id1)::int = (j2.id1)::int and (j1.id2)::int = (j2.id2)::int; -- ensure we don't detect the join to be unique when quals are not part of the -- join condition ---Testcase 526: +--Testcase 539: explain (verbose, costs off) select * from (select (fields->>'id1')::int id1, (fields->>'id2')::int id2 from j1) j1 inner join (select (fields->>'id1')::int id1, (fields->>'id2')::int id2 from j2) j2 on (j1.id1)::int = (j2.id1)::int where (j1.id2)::int = 1; -- as above, but for left joins. ---Testcase 527: +--Testcase 540: explain (verbose, costs off) select * from (select (fields->>'id1')::int id1, (fields->>'id2')::int id2 from j1) j1 left join (select (fields->>'id1')::int id1, (fields->>'id2')::int id2 from j2) j2 on (j1.id1)::int = (j2.id1)::int where (j1.id2)::int = 1; +-- create unique index j1_id2_idx on j1(id2) where id2 is not null; + +-- ensure we don't use a partial unique index as unique proofs +explain (verbose, costs off) +select * from (select (fields->>'id2')::int id2 from j1) j1 +inner join (select (fields->>'id2')::int id2 from j2) j2 on (j1.id2)::int = (j2.id2)::int; + +-- drop index j1_id2_idx; + -- 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. ---Testcase 528: +--Testcase 541: set enable_nestloop to 0; ---Testcase 529: +--Testcase 542: set enable_hashjoin to 0; ---Testcase 530: +--Testcase 543: set enable_sort to 0; - -- create indexes that will be preferred over the PKs to perform the join --create index j1_id1_idx on j1 (id1) where id1 % 1000 = 1; --create index j2_id1_idx on j2 (id1) where id1 % 1000 = 1; -- need an additional row in j2, if we want j2_id1_idx to be preferred ---Testcase 531: +--Testcase 544: insert into j2_nsc values(1,2); --analyze j2; ---Testcase 532: +--Testcase 545: explain (costs off) select * from (select (fields->>'id1')::int id1, (fields->>'id2')::int id2 from j1) j1 inner join (select (fields->>'id1')::int id1, (fields->>'id2')::int id2 from j2) j2 on j1.id1 = j2.id1 and j1.id2 = j2.id2 where (j1.id1)::int % 1000 = 1 and (j2.id1)::int % 1000 = 1; ---Testcase 533: +--Testcase 546: select * from (select (fields->>'id1')::int id1, (fields->>'id2')::int id2 from j1) j1 inner join (select (fields->>'id1')::int id1, (fields->>'id2')::int id2 from j2) j2 on j1.id1 = j2.id1 and j1.id2 = j2.id2 where (j1.id1)::int % 1000 = 1 and (j2.id1)::int % 1000 = 1; -- Exercise array keys mark/restore B-Tree code ---Testcase 534: +--Testcase 547: explain (costs off) select * from (select (fields->>'id1')::int id1, (fields->>'id2')::int id2 from j1) j1 inner join (select (fields->>'id1')::int id1, (fields->>'id2')::int id2 from j2) j2 on j1.id1 = j2.id1 and j1.id2 = j2.id2 where (j1.id1)::int % 1000 = 1 and (j2.id1)::int % 1000 = 1 and (j2.id1)::int = any (array[1]); ---Testcase 535: +--Testcase 548: select * from (select (fields->>'id1')::int id1, (fields->>'id2')::int id2 from j1) j1 inner join (select (fields->>'id1')::int id1, (fields->>'id2')::int id2 from j2) j2 on j1.id1 = j2.id1 and j1.id2 = j2.id2 where (j1.id1)::int % 1000 = 1 and (j2.id1)::int % 1000 = 1 and (j2.id1)::int = any (array[1]); -- Exercise array keys "find extreme element" B-Tree code ---Testcase 536: +--Testcase 549: explain (costs off) select * from (select (fields->>'id1')::int id1, (fields->>'id2')::int id2 from j1) j1 inner join (select (fields->>'id1')::int id1, (fields->>'id2')::int id2 from j2) j2 on j1.id1 = j2.id1 and j1.id2 = j2.id2 where (j1.id1)::int % 1000 = 1 and (j2.id1)::int % 1000 = 1 and (j2.id1)::int >= any (array[1,5]); ---Testcase 537: +--Testcase 550: select * from (select (fields->>'id1')::int id1, (fields->>'id2')::int id2 from j1) j1 inner join (select (fields->>'id1')::int id1, (fields->>'id2')::int id2 from j2) j2 on j1.id1 = j2.id1 and j1.id2 = j2.id2 where (j1.id1)::int % 1000 = 1 and (j2.id1)::int % 1000 = 1 and (j2.id1)::int >= any (array[1,5]); ---Testcase 538: +--Testcase 551: reset enable_nestloop; ---Testcase 539: +--Testcase 552: reset enable_hashjoin; ---Testcase 540: +--Testcase 553: reset enable_sort; ---Testcase 541: +--Testcase 554: delete from j1_nsc; ---Testcase 542: +--Testcase 555: delete from j2_nsc; ---Testcase 543: +--Testcase 556: delete from j3_nsc; ---Testcase 544: +--Testcase 557: drop foreign table j1; +--Testcase 644: drop foreign table j1_nsc; ---Testcase 545: +--Testcase 558: drop foreign table j2; +--Testcase 645: drop foreign table j2_nsc; ---Testcase 546: +--Testcase 559: drop foreign table j3; +--Testcase 646: drop foreign table j3_nsc; -- check that semijoin inner is not seen as unique for a portion of the outerrel ---Testcase 547: -CREATE FOREIGN TABLE onek ( - fields jsonb OPTIONS (fields 'true') -) SERVER influxdb_svr OPTIONS(schemaless 'true'); - --- check that semijoin inner is not seen as unique for a portion of the outerrel ---Testcase 548: +--Testcase 561: explain (verbose, costs off) select (t1.fields->>'unique1')::int4 unique1, (t2.fields->>'hundred')::int4 hundred from onek t1, tenk1 t2 @@ -2915,13 +3622,13 @@ where exists (select 1 from tenk1 t3 and (t1.fields->>'unique1')::int4 < 1; -- ... unless it actually is unique ---Testcase 549: +--Testcase 562: create table j3 as select (fields->>'unique1')::int4 unique1, (fields->>'tenthous')::int4 tenthous from onek; vacuum analyze j3; ---Testcase 550: +--Testcase 563: create unique index on j3(unique1, tenthous); ---Testcase 551: +--Testcase 564: explain (verbose, costs off) select (t1.fields->>'unique1')::int4 unique1, (t2.fields->>'hundred')::int4 hundred from onek t1, tenk1 t2 @@ -2929,27 +3636,45 @@ where exists (select 1 from j3 where j3.unique1 = (t1.fields->>'unique1')::int4 and j3.tenthous = (t2.fields->>'hundred')::int4) and (t1.fields->>'unique1')::int4 < 1; ---Testcase 552: +--Testcase 565: drop table j3; -- Clean up +--Testcase 647: DELETE FROM t1_nsc; +--Testcase 648: DELETE FROM t2_nsc; +--Testcase 649: DELETE FROM t3_nsc; +--Testcase 650: DELETE FROM tt1_nsc; +--Testcase 651: DELETE FROM tt2_nsc; +--Testcase 652: DELETE FROM tt3_nsc; +--Testcase 653: DELETE FROM tt4_nsc; +--Testcase 654: DELETE FROM tt5_nsc; +--Testcase 655: DELETE FROM tt6_nsc; +--Testcase 656: DELETE FROM xx_nsc; +--Testcase 657: DELETE FROM yy_nsc; +--Testcase 658: DELETE FROM zt1_nsc; +--Testcase 659: DELETE FROM zt2_nsc; +--Testcase 660: DELETE FROM nt1_nsc; +--Testcase 661: DELETE FROM nt2_nsc; +--Testcase 662: DELETE FROM nt3_nsc; +--Testcase 663: DELETE FROM parent_nsc; +--Testcase 664: DELETE FROM child_nsc; DO $d$ @@ -2963,9 +3688,9 @@ begin end; $d$; ---Testcase 553: +--Testcase 566: DROP USER MAPPING FOR CURRENT_USER SERVER influxdb_svr; ---Testcase 554: +--Testcase 567: DROP SERVER influxdb_svr CASCADE; ---Testcase 555: +--Testcase 568: DROP EXTENSION influxdb_fdw; diff --git a/sql/13.8/schemaless/extra/limit.sql b/sql/16.0/schemaless/extra/limit.sql similarity index 97% rename from sql/13.8/schemaless/extra/limit.sql rename to sql/16.0/schemaless/extra/limit.sql index 38ed4d2..ed60cfa 100644 --- a/sql/13.8/schemaless/extra/limit.sql +++ b/sql/16.0/schemaless/extra/limit.sql @@ -2,163 +2,160 @@ \ir sql/parameters.conf \set ECHO all ---Testcase 51: +--Testcase 1: CREATE EXTENSION influxdb_fdw; ---Testcase 52: +--Testcase 2: CREATE SERVER influxdb_svr FOREIGN DATA WRAPPER influxdb_fdw OPTIONS (dbname 'coredb', :SERVER); ---Testcase 53: +--Testcase 3: CREATE USER MAPPING FOR CURRENT_USER SERVER influxdb_svr OPTIONS (:AUTHENTICATION); --- import time column as timestamp and text type --- IMPORT FOREIGN SCHEMA influxdb_schema FROM SERVER influxdb_svr INTO public; - -- -- LIMIT -- Check the LIMIT/OFFSET feature of SELECT -- ---Testcase 54: +--Testcase 4: CREATE FOREIGN TABLE onek ( fields jsonb OPTIONS (fields 'true') ) SERVER influxdb_svr OPTIONS (schemaless 'true'); ---Testcase 55: +--Testcase 5: CREATE FOREIGN TABLE int8_tbl(fields jsonb OPTIONS (fields 'true')) SERVER influxdb_svr OPTIONS (schemaless 'true'); ---Testcase 56: +--Testcase 6: CREATE FOREIGN TABLE tenk1 ( fields jsonb OPTIONS (fields 'true') ) SERVER influxdb_svr OPTIONS (table 'tenk', schemaless 'true'); ---Testcase 1: +--Testcase 7: SELECT ''::text AS two, (fields->>'unique1')::int4 unique1, (fields->>'unique2')::int4 unique2, (fields->>'stringu1')::name stringu1 FROM onek WHERE (fields->>'unique1')::int4 > 50 ORDER BY (fields->>'unique1')::int4 LIMIT 2; ---Testcase 2: +--Testcase 8: SELECT ''::text AS five, (fields->>'unique1')::int4 unique1, (fields->>'unique2')::int4 unique2, (fields->>'stringu1')::name stringu1 FROM onek WHERE (fields->>'unique1')::int4 > 60 ORDER BY (fields->>'unique1')::int4 LIMIT 5; ---Testcase 3: +--Testcase 9: SELECT ''::text AS two, (fields->>'unique1')::int4 unique1, (fields->>'unique2')::int4 unique2, (fields->>'stringu1')::name stringu1 FROM onek WHERE (fields->>'unique1')::int4 > 60 AND (fields->>'unique1')::int4 < 63 ORDER BY (fields->>'unique1')::int4 LIMIT 5; ---Testcase 4: +--Testcase 10: SELECT ''::text AS three, (fields->>'unique1')::int4 unique1, (fields->>'unique2')::int4 unique2, (fields->>'stringu1')::name stringu1 FROM onek WHERE (fields->>'unique1')::int4 > 100 ORDER BY (fields->>'unique1')::int4 LIMIT 3 OFFSET 20; ---Testcase 5: +--Testcase 11: SELECT ''::text AS zero, (fields->>'unique1')::int4 unique1, (fields->>'unique2')::int4 unique2, (fields->>'stringu1')::name stringu1 FROM onek WHERE (fields->>'unique1')::int4 < 50 ORDER BY (fields->>'unique1')::int4 DESC LIMIT 8 OFFSET 99; ---Testcase 6: +--Testcase 12: SELECT ''::text AS eleven, (fields->>'unique1')::int4 unique1, (fields->>'unique2')::int4 unique2, (fields->>'stringu1')::name stringu1 FROM onek WHERE (fields->>'unique1')::int4 < 50 ORDER BY (fields->>'unique1')::int4 DESC LIMIT 20 OFFSET 39; ---Testcase 7: +--Testcase 13: SELECT ''::text AS ten, (fields->>'unique1')::int4 unique1, (fields->>'unique2')::int4 unique2, (fields->>'stringu1')::name stringu1 FROM onek ORDER BY (fields->>'unique1')::int4 OFFSET 990; ---Testcase 8: +--Testcase 14: SELECT ''::text AS five, (fields->>'unique1')::int4 unique1, (fields->>'unique2')::int4 unique2, (fields->>'stringu1')::name stringu1 FROM onek ORDER BY (fields->>'unique1')::int4 OFFSET 990 LIMIT 5; ---Testcase 9: +--Testcase 15: SELECT ''::text AS five, (fields->>'unique1')::int4 unique1, (fields->>'unique2')::int4 unique2, (fields->>'stringu1')::name stringu1 FROM onek ORDER BY (fields->>'unique1')::int4 LIMIT 5 OFFSET 900; -- Test null limit and offset. The planner would discard a simple null -- constant, so to ensure executor is exercised, do this: ---Testcase 10: +--Testcase 16: select * from int8_tbl limit (case when random() < 0.5 then null::bigint end); ---Testcase 11: +--Testcase 17: select * from int8_tbl offset (case when random() < 0.5 then null::bigint end); -- Test assorted cases involving backwards fetch from a LIMIT plan node begin; declare c1 scroll cursor for select * from int8_tbl limit 10; ---Testcase 12: +--Testcase 18: fetch all in c1; ---Testcase 13: +--Testcase 19: fetch 1 in c1; ---Testcase 14: +--Testcase 20: fetch backward 1 in c1; ---Testcase 15: +--Testcase 21: fetch backward all in c1; ---Testcase 16: +--Testcase 22: fetch backward 1 in c1; ---Testcase 17: +--Testcase 23: fetch all in c1; declare c2 scroll cursor for select * from int8_tbl limit 3; ---Testcase 18: +--Testcase 24: fetch all in c2; ---Testcase 19: +--Testcase 25: fetch 1 in c2; ---Testcase 20: +--Testcase 26: fetch backward 1 in c2; ---Testcase 21: +--Testcase 27: fetch backward all in c2; ---Testcase 22: +--Testcase 28: fetch backward 1 in c2; ---Testcase 23: +--Testcase 29: fetch all in c2; declare c3 scroll cursor for select * from int8_tbl offset 3; ---Testcase 24: +--Testcase 30: fetch all in c3; ---Testcase 25: +--Testcase 31: fetch 1 in c3; ---Testcase 26: +--Testcase 32: fetch backward 1 in c3; ---Testcase 27: +--Testcase 33: fetch backward all in c3; ---Testcase 28: +--Testcase 34: fetch backward 1 in c3; ---Testcase 29: +--Testcase 35: fetch all in c3; declare c4 scroll cursor for select * from int8_tbl offset 10; ---Testcase 30: +--Testcase 36: fetch all in c4; ---Testcase 31: +--Testcase 37: fetch 1 in c4; ---Testcase 32: +--Testcase 38: fetch backward 1 in c4; ---Testcase 33: +--Testcase 39: fetch backward all in c4; ---Testcase 34: +--Testcase 40: fetch backward 1 in c4; ---Testcase 35: +--Testcase 41: fetch all in c4; declare c5 scroll cursor for select * from int8_tbl order by (fields->>'q1')::int8 fetch first 2 rows with ties; ---Testcase 57: +--Testcase 42: fetch all in c5; ---Testcase 58: +--Testcase 43: fetch 1 in c5; ---Testcase 59: +--Testcase 44: fetch backward 1 in c5; ---Testcase 60: +--Testcase 45: fetch backward 1 in c5; ---Testcase 61: +--Testcase 46: fetch all in c5; ---Testcase 62: +--Testcase 47: fetch backward all in c5; ---Testcase 63: +--Testcase 48: fetch all in c5; ---Testcase 64: +--Testcase 49: fetch backward all in c5; rollback; -- Stress test for variable LIMIT in conjunction with bounded-heap sorting ---Testcase 65: +--Testcase 50: CREATE FOREIGN TABLE generate_series4(fields jsonb OPTIONS (fields 'true')) SERVER influxdb_svr OPTIONS (schemaless 'true'); ---Testcase 36: +--Testcase 51: SELECT (SELECT (fields->>'a')::int a FROM (VALUES (1)) AS x, @@ -171,65 +168,65 @@ SELECT -- with ORDER BY and LIMIT. -- ---Testcase 66: +--Testcase 52: create temp sequence testseq; ---Testcase 37: +--Testcase 53: explain (verbose, costs off) select (fields->>'unique1')::int4 unique1, (fields->>'unique2')::int4 unique2, nextval('testseq') from tenk1 order by (fields->>'unique2')::int4 limit 10; ---Testcase 38: +--Testcase 54: select (fields->>'unique1')::int4 unique1, (fields->>'unique2')::int4 unique2, nextval('testseq') from tenk1 order by (fields->>'unique2')::int4 limit 10; ---Testcase 39: +--Testcase 55: select currval('testseq'); ---Testcase 40: +--Testcase 56: explain (verbose, costs off) select (fields->>'unique1')::int4 unique1, (fields->>'unique2')::int4 unique2, nextval('testseq') from tenk1 order by (fields->>'tenthous')::int4 limit 10; ---Testcase 41: +--Testcase 57: select(fields->>'unique1')::int4 unique1, (fields->>'unique2')::int4 unique2, nextval('testseq') from tenk1 order by (fields->>'tenthous')::int4 limit 10; ---Testcase 42: +--Testcase 58: select currval('testseq'); ---Testcase 43: +--Testcase 59: explain (verbose, costs off) select (fields->>'unique1')::int4 unique1, (fields->>'unique2')::int4 unique2, generate_series(1,10) from tenk1 order by (fields->>'unique2')::int4 limit 7; ---Testcase 44: +--Testcase 60: select (fields->>'unique1')::int4 unique1, (fields->>'unique2')::int4 unique2, generate_series(1,10) from tenk1 order by (fields->>'unique2')::int4 limit 7; ---Testcase 45: +--Testcase 61: explain (verbose, costs off) select (fields->>'unique1')::int4 unique1, (fields->>'unique2')::int4 unique2, generate_series(1,10) from tenk1 order by (fields->>'tenthous')::int4 limit 7; ---Testcase 46: +--Testcase 62: select (fields->>'unique1')::int4 unique1, (fields->>'unique2')::int4 unique2, generate_series(1,10) from tenk1 order by (fields->>'tenthous')::int4 limit 7; -- use of random() is to keep planner from folding the expressions together ---Testcase 47: +--Testcase 63: explain (verbose, costs off) select generate_series(0,2) as s1, generate_series((random()*.1)::int,2) as s2; ---Testcase 48: +--Testcase 64: select generate_series(0,2) as s1, generate_series((random()*.1)::int,2) as s2; ---Testcase 49: +--Testcase 65: explain (verbose, costs off) select generate_series(0,2) as s1, generate_series((random()*.1)::int,2) as s2 order by s2 desc; ---Testcase 50: +--Testcase 66: select generate_series(0,2) as s1, generate_series((random()*.1)::int,2) as s2 order by s2 desc; @@ -268,6 +265,12 @@ SELECT (fields->>'thousand')::int4 thousand FROM onek WHERE (fields->>'thousand')::int4 < 5 ORDER BY (fields->>'thousand')::int4 FETCH FIRST 2 ROW ONLY; +-- SKIP LOCKED and WITH TIES are incompatible +--Testcase 90: +SELECT (fields->>'thousand')::int4 thousand + FROM onek WHERE (fields->>'thousand')::int4 < 5 + ORDER BY (fields->>'thousand')::int4 FETCH FIRST 1 ROW WITH TIES FOR UPDATE SKIP LOCKED; + -- should fail --Testcase 73: SELECT ''::text AS two, (fields->>'unique1')::int4 unique1, (fields->>'unique2')::int4 unique2, (fields->>'stringu1')::name stringu1 diff --git a/sql/13.8/schemaless/extra/prepare.sql b/sql/16.0/schemaless/extra/prepare.sql similarity index 84% rename from sql/13.8/schemaless/extra/prepare.sql rename to sql/16.0/schemaless/extra/prepare.sql index e27524d..58ccb9f 100644 --- a/sql/13.8/schemaless/extra/prepare.sql +++ b/sql/16.0/schemaless/extra/prepare.sql @@ -5,16 +5,16 @@ \ir sql/parameters.conf \set ECHO all ---Testcase 27: +--Testcase 1: CREATE EXTENSION influxdb_fdw; ---Testcase 28: +--Testcase 2: CREATE SERVER influxdb_svr FOREIGN DATA WRAPPER influxdb_fdw OPTIONS (dbname 'coredb', :SERVER); ---Testcase 29: +--Testcase 3: CREATE USER MAPPING FOR CURRENT_USER SERVER influxdb_svr OPTIONS (:AUTHENTICATION); ---Testcase 30: +--Testcase 4: CREATE FOREIGN TABLE tenk1 ( fields jsonb OPTIONS (fields 'true') ) SERVER influxdb_svr OPTIONS (table 'tenk', schemaless 'true'); @@ -22,116 +22,121 @@ CREATE FOREIGN TABLE tenk1 ( -- Does not support this command -- ALTER TABLE tenk1 SET WITH OIDS; ---Testcase 31: +--Testcase 5: CREATE FOREIGN TABLE road ( fields jsonb OPTIONS (fields 'true') ) SERVER influxdb_svr OPTIONS (schemaless 'true'); ---Testcase 32: +--Testcase 6: CREATE FOREIGN TABLE road_tmp (fields jsonb OPTIONS (fields 'true')) SERVER influxdb_svr OPTIONS (schemaless 'true'); ---Testcase 1: -SELECT name, statement, parameter_types FROM pg_prepared_statements; +--Testcase 7: +SELECT name, statement, parameter_types, result_types FROM pg_prepared_statements; ---Testcase 2: +--Testcase 8: PREPARE q1 AS SELECT (fields->>'a')::int AS a FROM road_tmp; ---Testcase 3: +--Testcase 9: EXECUTE q1; ---Testcase 4: -SELECT name, statement, parameter_types FROM pg_prepared_statements; +--Testcase 10: +SELECT name, statement, parameter_types, result_types FROM pg_prepared_statements; -- should fail ---Testcase 5: +--Testcase 11: PREPARE q1 AS SELECT (fields->>'b')::int b FROM road_tmp; -- should succeed DEALLOCATE q1; ---Testcase 6: +--Testcase 12: PREPARE q1 AS SELECT (fields->>'b')::int b FROM road_tmp; ---Testcase 7: +--Testcase 13: EXECUTE q1; ---Testcase 8: +--Testcase 14: PREPARE q2 AS SELECT (fields->>'b')::int AS b FROM road_tmp; ---Testcase 9: -SELECT name, statement, parameter_types FROM pg_prepared_statements; +--Testcase 15: +SELECT name, statement, parameter_types, result_types FROM pg_prepared_statements; -- sql92 syntax DEALLOCATE PREPARE q1; ---Testcase 10: -SELECT name, statement, parameter_types FROM pg_prepared_statements; +--Testcase 16: +SELECT name, statement, parameter_types, result_types FROM pg_prepared_statements; DEALLOCATE PREPARE q2; -- the view should return the empty set again ---Testcase 11: -SELECT name, statement, parameter_types FROM pg_prepared_statements; +--Testcase 17: +SELECT name, statement, parameter_types, result_types FROM pg_prepared_statements; -- parameterized queries ---Testcase 12: +--Testcase 18: PREPARE q2(text) AS SELECT datname, datistemplate, datallowconn FROM pg_database WHERE datname = $1; ---Testcase 13: +--Testcase 19: EXECUTE q2('postgres'); ---Testcase 14: +--Testcase 20: PREPARE q3(text, int, float, boolean, smallint) AS SELECT * FROM tenk1 WHERE fields->>'string4' = $1 AND ((fields->>'four')::int = $2 OR (fields->>'ten')::int = $3::bigint OR true = $4 OR (fields->>'odd')::int = $5::int) ORDER BY (fields->>'unique1')::int; ---Testcase 15: +--Testcase 21: EXECUTE q3('AAAAxx', 5::smallint, 10.5::float, false, 4::bigint); -- too few params ---Testcase 16: +--Testcase 22: EXECUTE q3('bool'); -- too many params ---Testcase 17: +--Testcase 23: EXECUTE q3('bytea', 5::smallint, 10.5::float, false, 4::bigint, true); -- wrong param types ---Testcase 18: +--Testcase 24: EXECUTE q3(5::smallint, 10.5::float, false, 4::bigint, 'bytea'); -- invalid type ---Testcase 19: +--Testcase 25: PREPARE q4(nonexistenttype) AS SELECT $1; -- create table as execute ---Testcase 20: +--Testcase 26: PREPARE q5(int, text) AS SELECT * FROM tenk1 WHERE (fields->>'unique1')::int = $1 OR fields->>'stringu1' = $2 ORDER BY (fields->>'unique1')::int; ---Testcase 33: +--Testcase 27: CREATE TEMPORARY TABLE q5_prep_results AS EXECUTE q5(200, 'DTAAAA'); ---Testcase 21: +--Testcase 28: SELECT * FROM q5_prep_results; ---Testcase 34: +--Testcase 29: CREATE TEMPORARY TABLE q5_prep_nodata AS EXECUTE q5(200, 'DTAAAA') WITH NO DATA; ---Testcase 22: +--Testcase 30: SELECT * FROM q5_prep_nodata; -- unknown or unspecified parameter types: should succeed ---Testcase 23: +--Testcase 31: PREPARE q6 AS SELECT * FROM tenk1 WHERE (fields->>'unique1')::int = $1 AND fields->>'stringu1' = $2; ---Testcase 24: +--Testcase 32: PREPARE q7(unknown) AS SELECT * FROM road WHERE fields->>'thepath' = $1; ---Testcase 25: -SELECT name, statement, parameter_types FROM pg_prepared_statements +-- influxdb does not update +-- DML statements +-- PREPARE q8 AS +-- UPDATE tenk1 SET fields->>'stringu1' = $2 WHERE fields->>'unique1' = $1; + +--Testcase 33: +SELECT name, statement, parameter_types, result_types FROM pg_prepared_statements ORDER BY name; -- test DEALLOCATE ALL; DEALLOCATE ALL; ---Testcase 26: +--Testcase 34: SELECT name, statement, parameter_types FROM pg_prepared_statements ORDER BY name; diff --git a/sql/13.8/schemaless/extra/select.sql b/sql/16.0/schemaless/extra/select.sql similarity index 95% rename from sql/13.8/schemaless/extra/select.sql rename to sql/16.0/schemaless/extra/select.sql index fa7029b..acbfe80 100644 --- a/sql/13.8/schemaless/extra/select.sql +++ b/sql/16.0/schemaless/extra/select.sql @@ -5,49 +5,49 @@ \ir sql/parameters.conf \set ECHO all ---Testcase 52: +--Testcase 1: CREATE EXTENSION influxdb_fdw; ---Testcase 53: +--Testcase 2: CREATE SERVER influxdb_svr FOREIGN DATA WRAPPER influxdb_fdw OPTIONS (dbname 'coredb', :SERVER); ---Testcase 54: +--Testcase 3: CREATE USER MAPPING FOR CURRENT_USER SERVER influxdb_svr OPTIONS (:AUTHENTICATION); ---Testcase 55: +--Testcase 4: CREATE FOREIGN TABLE onek ( fields jsonb OPTIONS (fields 'true') ) SERVER influxdb_svr OPTIONS (schemaless 'true'); ---Testcase 56: +--Testcase 5: CREATE FOREIGN TABLE onek2 ( fields jsonb OPTIONS (fields 'true') ) SERVER influxdb_svr OPTIONS (table 'onek', schemaless 'true'); ---Testcase 57: +--Testcase 6: CREATE FOREIGN TABLE INT8_TBL ( fields jsonb OPTIONS (fields 'true') ) SERVER influxdb_svr OPTIONS (schemaless 'true'); ---Testcase 58: +--Testcase 7: CREATE FOREIGN TABLE person ( fields jsonb OPTIONS (fields 'true') ) SERVER influxdb_svr OPTIONS (schemaless 'true'); ---Testcase 59: +--Testcase 8: CREATE FOREIGN TABLE emp ( fields jsonb OPTIONS (fields 'true') ) INHERITS (person) SERVER influxdb_svr OPTIONS (schemaless 'true'); ---Testcase 60: +--Testcase 9: CREATE FOREIGN TABLE student ( fields jsonb OPTIONS (fields 'true') ) INHERITS (person) SERVER influxdb_svr OPTIONS (schemaless 'true'); ---Testcase 61: +--Testcase 10: CREATE FOREIGN TABLE stud_emp ( fields jsonb OPTIONS (fields 'true') ) INHERITS (emp, student) SERVER influxdb_svr OPTIONS (schemaless 'true'); @@ -55,7 +55,7 @@ CREATE FOREIGN TABLE stud_emp ( -- btree index -- awk '{if($1<10){print;}else{next;}}' onek.data | sort +0n -1 -- ---Testcase 1: +--Testcase 11: SELECT * FROM onek WHERE (onek.fields->>'unique1')::int4 < 10 ORDER BY (onek.fields->>'unique1')::int4; @@ -63,7 +63,7 @@ SELECT * FROM onek -- -- awk '{if($1<20){print $1,$14;}else{next;}}' onek.data | sort +0nr -1 -- ---Testcase 2: +--Testcase 12: SELECT (onek.fields->>'unique1')::int4 unique1, (onek.fields->>'stringu1')::name stringu1 FROM onek WHERE (onek.fields->>'unique1')::int4 < 20 ORDER BY (onek.fields->>'unique1')::int4 using >; @@ -71,7 +71,7 @@ SELECT (onek.fields->>'unique1')::int4 unique1, (onek.fields->>'stringu1')::name -- -- awk '{if($1>980){print $1,$14;}else{next;}}' onek.data | sort +1d -2 -- ---Testcase 3: +--Testcase 13: SELECT (onek.fields->>'unique1')::int4 unique1, (onek.fields->>'stringu1')::name stringu1 FROM onek WHERE (onek.fields->>'unique1')::int4 > 980 ORDER BY (fields->>'stringu1')::name using <; @@ -80,7 +80,7 @@ SELECT (onek.fields->>'unique1')::int4 unique1, (onek.fields->>'stringu1')::name -- awk '{if($1>980){print $1,$16;}else{next;}}' onek.data | -- sort +1d -2 +0nr -1 -- ---Testcase 4: +--Testcase 14: SELECT (onek.fields->>'unique1')::int4 unique1, (onek.fields->>'string4')::name string4 FROM onek WHERE (onek.fields->>'unique1')::int4 > 980 ORDER BY (fields->>'string4')::name using <, (fields->>'unique1')::int4 using >; @@ -89,7 +89,7 @@ SELECT (onek.fields->>'unique1')::int4 unique1, (onek.fields->>'string4')::name -- awk '{if($1>980){print $1,$16;}else{next;}}' onek.data | -- sort +1dr -2 +0n -1 -- ---Testcase 5: +--Testcase 15: SELECT (onek.fields->>'unique1')::int4 unique1, (onek.fields->>'string4')::name string4 FROM onek WHERE (onek.fields->>'unique1')::int4 > 980 ORDER BY (fields->>'string4')::name using >, (fields->>'unique1')::int4 using <; @@ -98,7 +98,7 @@ SELECT (onek.fields->>'unique1')::int4 unique1, (onek.fields->>'string4')::name -- awk '{if($1<20){print $1,$16;}else{next;}}' onek.data | -- sort +0nr -1 +1d -2 -- ---Testcase 6: +--Testcase 16: SELECT (onek.fields->>'unique1')::int4 unique1, (onek.fields->>'string4')::name string4 FROM onek WHERE (onek.fields->>'unique1')::int4 < 20 ORDER BY (fields->>'unique1')::int4 using >, (fields->>'string4')::name using <; @@ -107,7 +107,7 @@ SELECT (onek.fields->>'unique1')::int4 unique1, (onek.fields->>'string4')::name -- awk '{if($1<20){print $1,$16;}else{next;}}' onek.data | -- sort +0n -1 +1dr -2 -- ---Testcase 7: +--Testcase 17: SELECT (onek.fields->>'unique1')::int4 unique1, (onek.fields->>'string4')::name string4 FROM onek WHERE (onek.fields->>'unique1')::int4 < 20 ORDER BY (fields->>'unique1')::int4 using <, (fields->>'string4')::name using >; @@ -121,20 +121,23 @@ SELECT (onek.fields->>'unique1')::int4 unique1, (onek.fields->>'string4')::name -- -- ANALYZE onek2; +--Testcase 18: SET enable_seqscan TO off; +--Testcase 19: SET enable_bitmapscan TO off; +--Testcase 20: SET enable_sort TO off; -- -- awk '{if($1<10){print $0;}else{next;}}' onek.data | sort +0n -1 -- ---Testcase 8: +--Testcase 21: SELECT onek2.* FROM onek2 WHERE (onek2.fields->>'unique1')::int4 < 10 order by 1; -- -- awk '{if($1<20){print $1,$14;}else{next;}}' onek.data | sort +0nr -1 -- ---Testcase 9: +--Testcase 22: SELECT (onek2.fields->>'unique1')::int4 unique1, (onek2.fields->>'stringu1')::name stringu1 FROM onek2 WHERE (onek2.fields->>'unique1')::int4 < 20 ORDER BY (fields->>'unique1')::int4 using >; @@ -142,19 +145,22 @@ SELECT (onek2.fields->>'unique1')::int4 unique1, (onek2.fields->>'stringu1')::na -- -- awk '{if($1>980){print $1,$14;}else{next;}}' onek.data | sort +1d -2 -- ---Testcase 10: +--Testcase 23: SELECT (onek2.fields->>'unique1')::int4 unique1, (onek2.fields->>'stringu1')::name stringu1 FROM onek2 WHERE (onek2.fields->>'unique1')::int4 > 980 order by 1; +--Testcase 24: RESET enable_seqscan; +--Testcase 25: RESET enable_bitmapscan; +--Testcase 26: RESET enable_sort; ---Testcase 11: -SELECT (fields->>'two')::int4 two, (fields->>'stringu1')::name stringu1, (fields->>'ten')::int4 ten, (fields->>'string4')::name string4 - INTO TABLE tmp - FROM onek; +--Testcase 27: +--SELECT (fields->>'two')::int4 two, (fields->>'stringu1')::name stringu1, (fields->>'ten')::int4 ten, (fields->>'string4')::name string4 +-- INTO TABLE tmp +-- FROM onek; -- -- awk '{print $1,$2;}' person.data | @@ -163,7 +169,7 @@ SELECT (fields->>'two')::int4 two, (fields->>'stringu1')::name stringu1, (fields -- awk 'BEGIN{FS=" ";}{if(NF!=2){print $4,$5;}else{print;}}' - stud_emp.data -- -- SELECT name, age FROM person*; ??? check if different ---Testcase 12: +--Testcase 28: SELECT p.fields->>'name' "name", (p.fields->>'age')::int4 age FROM person* p; -- @@ -173,29 +179,29 @@ SELECT p.fields->>'name' "name", (p.fields->>'age')::int4 age FROM person* p; -- awk 'BEGIN{FS=" ";}{if(NF!=1){print $4,$5;}else{print;}}' - stud_emp.data | -- sort +1nr -2 -- ---Testcase 13: +--Testcase 29: SELECT p.fields->>'name' "name", (p.fields->>'age')::int4 age FROM person* p ORDER BY (fields->>'age')::int4 using >, fields->>'name'; -- -- Test some cases involving whole-row Var referencing a subquery -- ---Testcase 14: +--Testcase 30: select foo from (select 1 offset 0) as foo; ---Testcase 15: +--Testcase 31: select foo from (select null offset 0) as foo; ---Testcase 16: +--Testcase 32: select foo from (select 'xyzzy',1,null offset 0) as foo; -- -- Test VALUES lists -- ---Testcase 17: +--Testcase 33: select * from onek, (values(147, 'RFAAAA'), (931, 'VJAAAA')) as v (i, j) WHERE (onek.fields->>'unique1')::int4 = v.i and (onek.fields->>'stringu1')::name = v.j; -- a more complex case -- looks like we're coding lisp :-) ---Testcase 18: +--Testcase 34: select * from onek, (values ((select i from (values(10000), (2), (389), (1000), (2000), ((select 10029))) as foo(i) @@ -203,38 +209,47 @@ select * from onek, where (onek.fields->>'unique1')::int4 = bar.i; -- try VALUES in a subquery ---Testcase 19: +--Testcase 35: select * from onek where ((fields->>'unique1')::int4,(fields->>'ten')::int4) in (values (1,1), (20,0), (99,9), (17,99)) order by (fields->>'unique1')::int4; -- VALUES is also legal as a standalone query or a set-operation member ---Testcase 20: +--Testcase 36: VALUES (1,2), (3,4+4), (7,77.7); ---Testcase 21: +--Testcase 37: VALUES (1,2), (3,4+4), (7,77.7) UNION ALL SELECT 2+2, 57 UNION ALL SELECT (fields->>'q1')::int8, (fields->>'q2')::int8 FROM int8_tbl; +-- -- corner case: VALUES with no columns +-- InfluxDB not support table with no columns. +-- --Testcase 79: +-- CREATE FOREIGN TABLE nocols() SERVER influxdb_svr; +-- --Testcase 80: +-- INSERT INTO nocols DEFAULT VALUES; +-- --Testcase 81: +-- SELECT * FROM nocols n, LATERAL (VALUES(n.*)) v; + -- -- Test ORDER BY options -- ---Testcase 62: +--Testcase 38: CREATE FOREIGN TABLE foo (fields jsonb OPTIONS (fields 'true')) SERVER influxdb_svr OPTIONS (schemaless 'true'); ---Testcase 22: +--Testcase 39: SELECT * FROM foo ORDER BY (fields->>'f1')::int; ---Testcase 23: +--Testcase 40: SELECT * FROM foo ORDER BY (fields->>'f1')::int ASC; -- same thing ---Testcase 24: +--Testcase 41: SELECT * FROM foo ORDER BY (fields->>'f1')::int NULLS FIRST; ---Testcase 25: +--Testcase 42: SELECT * FROM foo ORDER BY (fields->>'f1')::int DESC; ---Testcase 26: +--Testcase 43: SELECT * FROM foo ORDER BY (fields->>'f1')::int DESC NULLS LAST; -- check if indexscans do the right things @@ -267,64 +282,66 @@ SELECT * FROM foo ORDER BY (fields->>'f1')::int DESC NULLS LAST; -- -- partial index is usable ---Testcase 27: +--Testcase 44: explain (costs off) select * from onek2 where (fields->>'unique2')::int4 = 11 and (fields->>'stringu1')::name = 'ATAAAA'; ---Testcase 28: +--Testcase 45: select * from onek2 where (fields->>'unique2')::int4 = 11 and (fields->>'stringu1')::name = 'ATAAAA'; -- actually run the query with an analyze to use the partial index ---Testcase 63: +--Testcase 46: explain (costs off, analyze on, timing off, summary off) select * from onek2 where (fields->>'unique2')::int4 = 11 and (fields->>'stringu1')::name = 'ATAAAA'; ---Testcase 30: +--Testcase 47: explain (costs off) select (fields->>'unique2')::int4 unique2 from onek2 where (fields->>'unique2')::int4 = 11 and (fields->>'stringu1')::name = 'ATAAAA'; ---Testcase 31: +--Testcase 48: select (fields->>'unique2')::int4 unique2 from onek2 where (fields->>'unique2')::int4 = 11 and (fields->>'stringu1')::name = 'ATAAAA'; -- partial index predicate implies clause, so no need for retest ---Testcase 32: +--Testcase 49: explain (costs off) select * from onek2 where (fields->>'unique2')::int4 = 11 and (fields->>'stringu1')::name < 'B'; ---Testcase 33: +--Testcase 50: select * from onek2 where (fields->>'unique2')::int4 = 11 and (fields->>'stringu1')::name < 'B'; ---Testcase 34: +--Testcase 51: explain (costs off) select (fields->>'unique2')::int4 unique2 from onek2 where (fields->>'unique2')::int4 = 11 and (fields->>'stringu1')::name < 'B'; ---Testcase 35: +--Testcase 52: select (fields->>'unique2')::int4 unique2 from onek2 where (fields->>'unique2')::int4 = 11 and (fields->>'stringu1')::name < 'B'; -- but if it's an update target, must retest anyway ---Testcase 36: +--Testcase 53: explain (costs off) select (fields->>'unique2')::int4 unique2 from onek2 where (fields->>'unique2')::int4 = 11 and (fields->>'stringu1')::name < 'B' for update; ---Testcase 37: +--Testcase 54: select (fields->>'unique2')::int4 unique2 from onek2 where (fields->>'unique2')::int4 = 11 and (fields->>'stringu1')::name < 'B' for update; -- partial index is not applicable ---Testcase 38: +--Testcase 55: explain (costs off) select (fields->>'unique2')::int4 unique2 from onek2 where (fields->>'unique2')::int4 = 11 and (fields->>'stringu1')::name < 'C'; ---Testcase 39: +--Testcase 56: select (fields->>'unique2')::int4 unique2 from onek2 where (fields->>'unique2')::int4 = 11 and (fields->>'stringu1')::name < 'C'; -- partial index implies clause, but bitmap scan must recheck predicate anyway +--Testcase 57: SET enable_indexscan TO off; ---Testcase 40: +--Testcase 58: explain (costs off) select (fields->>'unique2')::int4 unique2 from onek2 where (fields->>'unique2')::int4 = 11 and (fields->>'stringu1')::name < 'B'; ---Testcase 41: +--Testcase 59: select (fields->>'unique2')::int4 unique2 from onek2 where (fields->>'unique2')::int4 = 11 and (fields->>'stringu1')::name < 'B'; +--Testcase 60: RESET enable_indexscan; -- check multi-index cases too ---Testcase 42: +--Testcase 61: explain (costs off) select (fields->>'unique1')::int4 unique1, (fields->>'unique2')::int4 unique2 from onek2 where ((fields->>'unique2')::int4 = 11 or (fields->>'unique1')::int4 = 0) and (fields->>'stringu1')::name < 'B'; ---Testcase 43: +--Testcase 62: select (fields->>'unique1')::int4 unique1, (fields->>'unique2')::int4 unique2 from onek2 where ((fields->>'unique2')::int4 = 11 or (fields->>'unique1')::int4 = 0) and (fields->>'stringu1')::name < 'B'; ---Testcase 44: +--Testcase 63: explain (costs off) select (fields->>'unique1')::int4 unique1, (fields->>'unique2')::int4 unique2 from onek2 where ((fields->>'unique2')::int4 = 11 and (fields->>'stringu1')::name < 'B') or (fields->>'unique1')::int4 = 0; ---Testcase 45: +--Testcase 64: select (fields->>'unique1')::int4 unique1, (fields->>'unique2')::int4 unique2 from onek2 where ((fields->>'unique2')::int4 = 11 and (fields->>'stringu1')::name < 'B') or (fields->>'unique1')::int4 = 0; @@ -333,47 +350,47 @@ select (fields->>'unique1')::int4 unique1, (fields->>'unique2')::int4 unique2 fr -- -- ORDER BY on a constant doesn't really need any sorting ---Testcase 46: +--Testcase 65: SELECT 1 AS x ORDER BY x; -- But ORDER BY on a set-valued expression does ---Testcase 64: +--Testcase 66: create function sillysrf(int) returns setof int as 'values (1),(10),(2),($1)' language sql immutable; ---Testcase 47: +--Testcase 67: select sillysrf(42); ---Testcase 48: +--Testcase 68: select sillysrf(-1) order by 1; ---Testcase 65: +--Testcase 69: drop function sillysrf(int); -- X = X isn't a no-op, it's effectively X IS NOT NULL assuming = is strict -- (see bug #5084) ---Testcase 49: +--Testcase 70: select * from (values (2),(null),(1)) v(k) where k = k order by k; ---Testcase 50: +--Testcase 71: select * from (values (2),(null),(1)) v(k) where k = k; -- Test partitioned tables with no partitions, which should be handled the -- same as the non-inheritance case when expanding its RTE. ---Testcase 66: +--Testcase 72: create table list_parted_tbl (a int,b int) partition by list (a); ---Testcase 67: +--Testcase 73: create table list_parted_tbl1 partition of list_parted_tbl for values in (1) partition by list(b); ---Testcase 51: +--Testcase 74: explain (costs off) select * from list_parted_tbl; ---Testcase 68: +--Testcase 75: drop table list_parted_tbl; -- Clean up: -DROP TABLE IF EXISTS tmp; +--DROP TABLE IF EXISTS tmp; ---Testcase 69: +--Testcase 76: DROP USER MAPPING FOR CURRENT_USER SERVER influxdb_svr; ---Testcase 70: +--Testcase 77: DROP SERVER influxdb_svr CASCADE; ---Testcase 71: +--Testcase 78: DROP EXTENSION influxdb_fdw; diff --git a/sql/14.5/schemaless/extra/select_having.sql b/sql/16.0/schemaless/extra/select_having.sql similarity index 98% rename from sql/14.5/schemaless/extra/select_having.sql rename to sql/16.0/schemaless/extra/select_having.sql index 8cef2e2..43e66b7 100644 --- a/sql/14.5/schemaless/extra/select_having.sql +++ b/sql/16.0/schemaless/extra/select_having.sql @@ -16,6 +16,7 @@ CREATE USER MAPPING FOR CURRENT_USER SERVER influxdb_svr OPTIONS (:AUTHENTICATIO --Testcase 4: CREATE FOREIGN TABLE test_having (fields jsonb OPTIONS (fields 'true')) SERVER influxdb_svr OPTIONS (schemaless 'true'); +--Testcase 30: CREATE FOREIGN TABLE test_having_nsc (a int, b int, c char(8), d char) SERVER influxdb_svr OPTIONS (table 'test_having'); --Testcase 5: INSERT INTO test_having_nsc VALUES (0, 1, 'XXXX', 'A'); @@ -82,8 +83,11 @@ SELECT 1 AS one FROM test_having WHERE 1/(fields->>'a')::int = 1 HAVING 1 < 2; --Testcase 26: -- Clean up: +--Testcase 31: DELETE FROM test_having_nsc; +--Testcase 32: DROP FOREIGN TABLE test_having; +--Testcase 33: DROP FOREIGN TABLE test_having_nsc; --Testcase 27: DROP USER MAPPING FOR CURRENT_USER SERVER influxdb_svr; diff --git a/sql/14.5/schemaless/influxdb_fdw.sql b/sql/16.0/schemaless/influxdb_fdw.sql similarity index 99% rename from sql/14.5/schemaless/influxdb_fdw.sql rename to sql/16.0/schemaless/influxdb_fdw.sql index 03c1399..032e45e 100644 --- a/sql/14.5/schemaless/influxdb_fdw.sql +++ b/sql/16.0/schemaless/influxdb_fdw.sql @@ -485,6 +485,7 @@ DROP FOREIGN TABLE tx; -- test INSERT, DELETE IMPORT FOREIGN SCHEMA public FROM SERVER server1 INTO public OPTIONS(import_time_text 'true', schemaless 'true'); +--Testcase 204: CREATE FOREIGN TABLE cpu_nsc (time timestamp with time zone, time_text text, tag1 text, tag2 text, value1 int, value2 float, value3 text, value4 boolean) SERVER server1 OPTIONS (table 'cpu', tags 'tag1, tag2'); --Testcase 164: SELECT * FROM cpu; @@ -592,6 +593,7 @@ SELECT * FROM cpu; --Testcase 201: DROP FOREIGN TABLE cpu_nsc; +--Testcase 205: DROP USER MAPPING FOR CURRENT_USER SERVER server1; --Testcase 202: DROP SERVER server1 CASCADE; diff --git a/sql/15.0/schemaless/init.sql b/sql/16.0/schemaless/init.sql similarity index 100% rename from sql/15.0/schemaless/init.sql rename to sql/16.0/schemaless/init.sql diff --git a/sql/15.0/schemaless/schemaless.sql b/sql/16.0/schemaless/schemaless.sql similarity index 100% rename from sql/15.0/schemaless/schemaless.sql rename to sql/16.0/schemaless/schemaless.sql diff --git a/sql/15.0/schemaless/selectfunc.sql b/sql/16.0/schemaless/selectfunc.sql similarity index 100% rename from sql/15.0/schemaless/selectfunc.sql rename to sql/16.0/schemaless/selectfunc.sql diff --git a/sql/15.0/selectfunc.sql b/sql/16.0/selectfunc.sql similarity index 100% rename from sql/15.0/selectfunc.sql rename to sql/16.0/selectfunc.sql diff --git a/test.sh b/test.sh index 96c4c3a..0417b91 100755 --- a/test.sh +++ b/test.sh @@ -1,5 +1,12 @@ #! /bin/bash +# Usage: +# ./test.sh -- using GO CLIENT + Postgres versions +# ./test.sh --CXX_V1 -- using CXX V1 + Postgres versions +# ./test.sh --CXX_V2 -- using CXX V2 + Postgres versions +# +# *Note: If using CXX, we need to use gcc 7 (source /opt/rh/devtoolset-7/enable) + sed -i 's/REGRESS =.*/REGRESS = aggregate influxdb_fdw selectfunc extra\/join extra\/limit extra\/aggregates extra\/insert extra\/prepare extra\/select_having extra\/select extra\/influxdb_fdw_post schemaless\/aggregate schemaless\/influxdb_fdw schemaless\/selectfunc schemaless\/schemaless schemaless\/extra\/join schemaless\/extra\/limit schemaless\/extra\/aggregates schemaless\/extra\/prepare schemaless\/extra\/select_having schemaless\/extra\/insert schemaless\/extra\/select schemaless\/extra\/influxdb_fdw_post schemaless\/add_fields schemaless\/add_tags schemaless\/add_multi_key /' Makefile if [[ "--CXX_V1" == $1 ]]; then