diff --git a/.github/gh_matrix_builder.py b/.github/gh_matrix_builder.py index 4dcc0469ae0..6a12090059d 100755 --- a/.github/gh_matrix_builder.py +++ b/.github/gh_matrix_builder.py @@ -153,9 +153,9 @@ def macos_config(overrides): "snapshot": "snapshot", "tsdb_build_args": "-DASSERTIONS=ON -DREQUIRE_ALL_TESTS=ON -DEXPERIMENTAL=ON", # below tests are tracked as part of #4838 - "installcheck_args": "SKIPS='003_connections_privs 001_simple_multinode 004_multinode_rdwr_1pc dist_hypertable-15 bgw_custom cagg_dump dist_move_chunk' " + "installcheck_args": "SKIPS='003_connections_privs 001_simple_multinode 004_multinode_rdwr_1pc bgw_custom cagg_dump dist_move_chunk' " # below tests are tracked as part of #4835 - "IGNORES='telemetry_stats dist_query dist_partial_agg plan_hashagg partialize_finalize dist_fetcher_type dist_remote_error jit-15 " + "IGNORES='telemetry_stats dist_query dist_partial_agg plan_hashagg partialize_finalize dist_fetcher_type " # below tests are tracked as part of #4837 "remote_txn'", } diff --git a/test/expected/query-15.out b/test/expected/query-15.out index df166c09edb..cdec6fdd222 100644 --- a/test/expected/query-15.out +++ b/test/expected/query-15.out @@ -293,14 +293,16 @@ BEGIN; :PREFIX SELECT time_bucket('1 minute', time, INTERVAL '30 seconds') t, avg(series_0), min(series_1), trunc(avg(series_2)::numeric,5) FROM hyper_1 GROUP BY t ORDER BY t DESC limit 2; - QUERY PLAN ------------------------------------------------------------------------------------------------------------------------------------- + QUERY PLAN +--------------------------------------------------------------------------------------------------------- Limit -> GroupAggregate - Group Key: ((time_bucket('@ 1 min'::interval, (_hyper_1_1_chunk."time" - '@ 30 secs'::interval)) + '@ 30 secs'::interval)) + Group Key: (time_bucket('@ 1 min'::interval, hyper_1."time", '@ 30 secs'::interval)) -> Result - -> Index Scan using _hyper_1_1_chunk_time_plain on _hyper_1_1_chunk -(5 rows) + -> Custom Scan (ChunkAppend) on hyper_1 + Order: time_bucket('@ 1 min'::interval, hyper_1."time", '@ 30 secs'::interval) DESC + -> Index Scan using _hyper_1_1_chunk_time_plain on _hyper_1_1_chunk +(7 rows) :PREFIX SELECT time_bucket('1 minute', time - INTERVAL '30 seconds') t, avg(series_0), min(series_1), trunc(avg(series_2)::numeric,5) FROM hyper_1 GROUP BY t ORDER BY t DESC limit 2; diff --git a/tsl/src/planner.c b/tsl/src/planner.c index eed75fcf9a9..027aace26df 100644 --- a/tsl/src/planner.c +++ b/tsl/src/planner.c @@ -315,11 +315,37 @@ tsl_create_distributed_insert_path(PlannerInfo *root, ModifyTablePath *mtpath, I if (rte->rtekind == RTE_SUBQUERY) { distributed = false; - if (distributed_rtes_walker((Node *) rte->subquery, &distributed) && - distributed) + Node *jtnode = (Node *) root->parse->jointree; + if (IsA(jtnode, FromExpr)) { - copy_possible = false; - break; + FromExpr *f = (FromExpr *) jtnode; + ListCell *l; + foreach (l, f->fromlist) + { + Node *n = (Node *) lfirst(l); + if (IsA(n, RangeTblRef)) + { + RangeTblEntry *r = + planner_rt_fetch(((RangeTblRef *) n)->rtindex, root); + switch (r->rtekind) + { + case RTE_RELATION: + distributed_rtes_walker((Node *) r, &distributed); + break; + case RTE_SUBQUERY: + distributed_rtes_walker((Node *) r->subquery, + &distributed); + break; + default: + break; + } + if (distributed) + { + copy_possible = false; + break; + } + } + } } } } diff --git a/tsl/test/expected/dist_hypertable-15.out b/tsl/test/expected/dist_hypertable-15.out index 6ef3fe20383..cd057e61e8c 100644 --- a/tsl/test/expected/dist_hypertable-15.out +++ b/tsl/test/expected/dist_hypertable-15.out @@ -609,8 +609,8 @@ EXPLAIN (VERBOSE, COSTS FALSE) SELECT time_bucket('3 hours', time) AS time, device, avg(temp) AS avg_temp FROM disttable GROUP BY 1, 2 ORDER BY 1; - QUERY PLAN ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- + QUERY PLAN +---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- GroupAggregate Output: (time_bucket('@ 3 hours'::interval, disttable."time")), disttable.device, avg(disttable.temp) Group Key: (time_bucket('@ 3 hours'::interval, disttable."time")), disttable.device @@ -618,22 +618,28 @@ ORDER BY 1; Output: (time_bucket('@ 3 hours'::interval, disttable."time")), disttable.device, disttable.temp -> Merge Append Sort Key: (time_bucket('@ 3 hours'::interval, disttable_1."time")), disttable_1.device - -> Custom Scan (DataNodeScan) on public.disttable disttable_1 + -> Result Output: time_bucket('@ 3 hours'::interval, disttable_1."time"), disttable_1.device, disttable_1.temp - Data node: db_dist_hypertable_1 - Chunks: _dist_hyper_1_1_chunk, _dist_hyper_1_4_chunk - Remote SQL: SELECT "time", device, temp FROM public.disttable WHERE _timescaledb_internal.chunks_in(public.disttable.*, ARRAY[1, 2]) ORDER BY public.time_bucket('03:00:00'::interval, "time") ASC NULLS LAST, device ASC NULLS LAST - -> Custom Scan (DataNodeScan) on public.disttable disttable_2 + -> Custom Scan (DataNodeScan) on public.disttable disttable_1 + Output: disttable_1."time", disttable_1.device, disttable_1.temp + Data node: db_dist_hypertable_1 + Chunks: _dist_hyper_1_1_chunk, _dist_hyper_1_4_chunk + Remote SQL: SELECT "time", device, temp FROM public.disttable WHERE _timescaledb_internal.chunks_in(public.disttable.*, ARRAY[1, 2]) ORDER BY public.time_bucket('03:00:00'::interval, "time") ASC NULLS LAST, device ASC NULLS LAST + -> Result Output: time_bucket('@ 3 hours'::interval, disttable_2."time"), disttable_2.device, disttable_2.temp - Data node: db_dist_hypertable_2 - Chunks: _dist_hyper_1_3_chunk, _dist_hyper_1_5_chunk - Remote SQL: SELECT "time", device, temp FROM public.disttable WHERE _timescaledb_internal.chunks_in(public.disttable.*, ARRAY[1, 2]) ORDER BY public.time_bucket('03:00:00'::interval, "time") ASC NULLS LAST, device ASC NULLS LAST - -> Custom Scan (DataNodeScan) on public.disttable disttable_3 + -> Custom Scan (DataNodeScan) on public.disttable disttable_2 + Output: disttable_2."time", disttable_2.device, disttable_2.temp + Data node: db_dist_hypertable_2 + Chunks: _dist_hyper_1_3_chunk, _dist_hyper_1_5_chunk + Remote SQL: SELECT "time", device, temp FROM public.disttable WHERE _timescaledb_internal.chunks_in(public.disttable.*, ARRAY[1, 2]) ORDER BY public.time_bucket('03:00:00'::interval, "time") ASC NULLS LAST, device ASC NULLS LAST + -> Result Output: time_bucket('@ 3 hours'::interval, disttable_3."time"), disttable_3.device, disttable_3.temp - Data node: db_dist_hypertable_3 - Chunks: _dist_hyper_1_2_chunk, _dist_hyper_1_6_chunk - Remote SQL: SELECT "time", device, temp FROM public.disttable WHERE _timescaledb_internal.chunks_in(public.disttable.*, ARRAY[1, 2]) ORDER BY public.time_bucket('03:00:00'::interval, "time") ASC NULLS LAST, device ASC NULLS LAST -(22 rows) + -> Custom Scan (DataNodeScan) on public.disttable disttable_3 + Output: disttable_3."time", disttable_3.device, disttable_3.temp + Data node: db_dist_hypertable_3 + Chunks: _dist_hyper_1_2_chunk, _dist_hyper_1_6_chunk + Remote SQL: SELECT "time", device, temp FROM public.disttable WHERE _timescaledb_internal.chunks_in(public.disttable.*, ARRAY[1, 2]) ORDER BY public.time_bucket('03:00:00'::interval, "time") ASC NULLS LAST, device ASC NULLS LAST +(28 rows) -- Execute some queries on the frontend and return the results SELECT * FROM disttable; @@ -2143,13 +2149,13 @@ SELECT * FROM _timescaledb_catalog.hypertable; (3 rows) SELECT * FROM _timescaledb_catalog.dimension; - id | hypertable_id | column_name | column_type | aligned | num_slices | partitioning_func_schema | partitioning_func | interval_length | integer_now_func_schema | integer_now_func -----+---------------+------------------+--------------------------+---------+------------+--------------------------+--------------------+-----------------+-------------------------+------------------ - 1 | 1 | time | timestamp with time zone | t | | | | 604800000000 | | - 2 | 1 | device | integer | f | 3 | _timescaledb_internal | get_partition_hash | | | - 3 | 2 | time | timestamp with time zone | t | | | | 604800000000 | | - 5 | 4 | time Col %#^#@$# | timestamp with time zone | t | | | | 604800000000 | | - 6 | 4 | __region | text | f | 4 | _timescaledb_internal | get_partition_hash | | | + id | hypertable_id | column_name | column_type | aligned | num_slices | partitioning_func_schema | partitioning_func | interval_length | compress_interval_length | integer_now_func_schema | integer_now_func +----+---------------+------------------+--------------------------+---------+------------+--------------------------+--------------------+-----------------+--------------------------+-------------------------+------------------ + 1 | 1 | time | timestamp with time zone | t | | | | 604800000000 | | | + 2 | 1 | device | integer | f | 3 | _timescaledb_internal | get_partition_hash | | | | + 3 | 2 | time | timestamp with time zone | t | | | | 604800000000 | | | + 5 | 4 | time Col %#^#@$# | timestamp with time zone | t | | | | 604800000000 | | | + 6 | 4 | __region | text | f | 4 | _timescaledb_internal | get_partition_hash | | | | (5 rows) SELECT * FROM test.show_triggers('"Table\\Schema"."Param_Table"'); @@ -2178,13 +2184,13 @@ id|schema_name |table_name |associated_schema_name|associated_table_prefix| NOTICE: [db_dist_hypertable_1]: SELECT * FROM _timescaledb_catalog.dimension NOTICE: [db_dist_hypertable_1]: -id|hypertable_id|column_name |column_type |aligned|num_slices|partitioning_func_schema|partitioning_func |interval_length|integer_now_func_schema|integer_now_func ---+-------------+----------------+------------------------+-------+----------+------------------------+------------------+---------------+-----------------------+---------------- - 1| 1|time |timestamp with time zone|t | | | | 604800000000| | - 2| 1|device |integer |f | 3|_timescaledb_internal |get_partition_hash| | | - 3| 2|time |timestamp with time zone|t | | | | 604800000000| | - 4| 3|time Col %#^#@$#|timestamp with time zone|t | | | | 604800000000| | - 5| 3|__region |text |f | 4|_timescaledb_internal |get_partition_hash| | | +id|hypertable_id|column_name |column_type |aligned|num_slices|partitioning_func_schema|partitioning_func |interval_length|compress_interval_length|integer_now_func_schema|integer_now_func +--+-------------+----------------+------------------------+-------+----------+------------------------+------------------+---------------+------------------------+-----------------------+---------------- + 1| 1|time |timestamp with time zone|t | | | | 604800000000| | | + 2| 1|device |integer |f | 3|_timescaledb_internal |get_partition_hash| | | | + 3| 2|time |timestamp with time zone|t | | | | 604800000000| | | + 4| 3|time Col %#^#@$#|timestamp with time zone|t | | | | 604800000000| | | + 5| 3|__region |text |f | 4|_timescaledb_internal |get_partition_hash| | | | (5 rows) @@ -2212,13 +2218,13 @@ id|schema_name |table_name |associated_schema_name|associated_table_prefix| NOTICE: [db_dist_hypertable_2]: SELECT * FROM _timescaledb_catalog.dimension NOTICE: [db_dist_hypertable_2]: -id|hypertable_id|column_name |column_type |aligned|num_slices|partitioning_func_schema|partitioning_func |interval_length|integer_now_func_schema|integer_now_func ---+-------------+----------------+------------------------+-------+----------+------------------------+------------------+---------------+-----------------------+---------------- - 1| 1|time |timestamp with time zone|t | | | | 604800000000| | - 2| 1|device |integer |f | 3|_timescaledb_internal |get_partition_hash| | | - 3| 2|time |timestamp with time zone|t | | | | 604800000000| | - 6| 4|time Col %#^#@$#|timestamp with time zone|t | | | | 604800000000| | - 7| 4|__region |text |f | 4|_timescaledb_internal |get_partition_hash| | | +id|hypertable_id|column_name |column_type |aligned|num_slices|partitioning_func_schema|partitioning_func |interval_length|compress_interval_length|integer_now_func_schema|integer_now_func +--+-------------+----------------+------------------------+-------+----------+------------------------+------------------+---------------+------------------------+-----------------------+---------------- + 1| 1|time |timestamp with time zone|t | | | | 604800000000| | | + 2| 1|device |integer |f | 3|_timescaledb_internal |get_partition_hash| | | | + 3| 2|time |timestamp with time zone|t | | | | 604800000000| | | + 6| 4|time Col %#^#@$#|timestamp with time zone|t | | | | 604800000000| | | + 7| 4|__region |text |f | 4|_timescaledb_internal |get_partition_hash| | | | (5 rows) @@ -2246,13 +2252,13 @@ id|schema_name |table_name |associated_schema_name|associated_table_prefix| NOTICE: [db_dist_hypertable_3]: SELECT * FROM _timescaledb_catalog.dimension NOTICE: [db_dist_hypertable_3]: -id|hypertable_id|column_name |column_type |aligned|num_slices|partitioning_func_schema|partitioning_func |interval_length|integer_now_func_schema|integer_now_func ---+-------------+----------------+------------------------+-------+----------+------------------------+------------------+---------------+-----------------------+---------------- - 1| 1|time |timestamp with time zone|t | | | | 604800000000| | - 2| 1|device |integer |f | 3|_timescaledb_internal |get_partition_hash| | | - 3| 2|time |timestamp with time zone|t | | | | 604800000000| | - 4| 3|time Col %#^#@$#|timestamp with time zone|t | | | | 604800000000| | - 5| 3|__region |text |f | 4|_timescaledb_internal |get_partition_hash| | | +id|hypertable_id|column_name |column_type |aligned|num_slices|partitioning_func_schema|partitioning_func |interval_length|compress_interval_length|integer_now_func_schema|integer_now_func +--+-------------+----------------+------------------------+-------+----------+------------------------+------------------+---------------+------------------------+-----------------------+---------------- + 1| 1|time |timestamp with time zone|t | | | | 604800000000| | | + 2| 1|device |integer |f | 3|_timescaledb_internal |get_partition_hash| | | | + 3| 2|time |timestamp with time zone|t | | | | 604800000000| | | + 4| 3|time Col %#^#@$#|timestamp with time zone|t | | | | 604800000000| | | + 5| 3|__region |text |f | 4|_timescaledb_internal |get_partition_hash| | | | (5 rows) @@ -2374,17 +2380,17 @@ SELECT * FROM dimented_table ORDER BY time; (1 row) SELECT * FROM _timescaledb_catalog.dimension; - id | hypertable_id | column_name | column_type | aligned | num_slices | partitioning_func_schema | partitioning_func | interval_length | integer_now_func_schema | integer_now_func -----+---------------+------------------+--------------------------+---------+------------+--------------------------+-----------------------+-----------------+-------------------------+------------------ - 1 | 1 | time | timestamp with time zone | t | | | | 604800000000 | | - 2 | 1 | device | integer | f | 3 | _timescaledb_internal | get_partition_hash | | | - 3 | 2 | time | timestamp with time zone | t | | | | 604800000000 | | - 5 | 4 | time Col %#^#@$# | timestamp with time zone | t | | | | 604800000000 | | - 6 | 4 | __region | text | f | 2 | _timescaledb_internal | get_partition_hash | | | - 7 | 5 | time | timestamp with time zone | t | | | | 604800000000 | | - 8 | 5 | column1 | integer | f | 4 | _timescaledb_internal | get_partition_hash | | | - 9 | 5 | column2 | timestamp with time zone | t | | | | 604800000000 | | - 10 | 5 | column3 | integer | f | 4 | _timescaledb_internal | get_partition_for_key | | | + id | hypertable_id | column_name | column_type | aligned | num_slices | partitioning_func_schema | partitioning_func | interval_length | compress_interval_length | integer_now_func_schema | integer_now_func +----+---------------+------------------+--------------------------+---------+------------+--------------------------+-----------------------+-----------------+--------------------------+-------------------------+------------------ + 1 | 1 | time | timestamp with time zone | t | | | | 604800000000 | | | + 2 | 1 | device | integer | f | 3 | _timescaledb_internal | get_partition_hash | | | | + 3 | 2 | time | timestamp with time zone | t | | | | 604800000000 | | | + 5 | 4 | time Col %#^#@$# | timestamp with time zone | t | | | | 604800000000 | | | + 6 | 4 | __region | text | f | 2 | _timescaledb_internal | get_partition_hash | | | | + 7 | 5 | time | timestamp with time zone | t | | | | 604800000000 | | | + 8 | 5 | column1 | integer | f | 4 | _timescaledb_internal | get_partition_hash | | | | + 9 | 5 | column2 | timestamp with time zone | t | | | | 604800000000 | | | + 10 | 5 | column3 | integer | f | 4 | _timescaledb_internal | get_partition_for_key | | | | (9 rows) SELECT * FROM attach_data_node(:'DATA_NODE_2', 'dimented_table'); @@ -2394,17 +2400,17 @@ SELECT * FROM attach_data_node(:'DATA_NODE_2', 'dimented_table'); (1 row) SELECT * FROM _timescaledb_catalog.dimension; - id | hypertable_id | column_name | column_type | aligned | num_slices | partitioning_func_schema | partitioning_func | interval_length | integer_now_func_schema | integer_now_func -----+---------------+------------------+--------------------------+---------+------------+--------------------------+-----------------------+-----------------+-------------------------+------------------ - 1 | 1 | time | timestamp with time zone | t | | | | 604800000000 | | - 2 | 1 | device | integer | f | 3 | _timescaledb_internal | get_partition_hash | | | - 3 | 2 | time | timestamp with time zone | t | | | | 604800000000 | | - 5 | 4 | time Col %#^#@$# | timestamp with time zone | t | | | | 604800000000 | | - 6 | 4 | __region | text | f | 2 | _timescaledb_internal | get_partition_hash | | | - 7 | 5 | time | timestamp with time zone | t | | | | 604800000000 | | - 8 | 5 | column1 | integer | f | 4 | _timescaledb_internal | get_partition_hash | | | - 9 | 5 | column2 | timestamp with time zone | t | | | | 604800000000 | | - 10 | 5 | column3 | integer | f | 4 | _timescaledb_internal | get_partition_for_key | | | + id | hypertable_id | column_name | column_type | aligned | num_slices | partitioning_func_schema | partitioning_func | interval_length | compress_interval_length | integer_now_func_schema | integer_now_func +----+---------------+------------------+--------------------------+---------+------------+--------------------------+-----------------------+-----------------+--------------------------+-------------------------+------------------ + 1 | 1 | time | timestamp with time zone | t | | | | 604800000000 | | | + 2 | 1 | device | integer | f | 3 | _timescaledb_internal | get_partition_hash | | | | + 3 | 2 | time | timestamp with time zone | t | | | | 604800000000 | | | + 5 | 4 | time Col %#^#@$# | timestamp with time zone | t | | | | 604800000000 | | | + 6 | 4 | __region | text | f | 2 | _timescaledb_internal | get_partition_hash | | | | + 7 | 5 | time | timestamp with time zone | t | | | | 604800000000 | | | + 8 | 5 | column1 | integer | f | 4 | _timescaledb_internal | get_partition_hash | | | | + 9 | 5 | column2 | timestamp with time zone | t | | | | 604800000000 | | | + 10 | 5 | column3 | integer | f | 4 | _timescaledb_internal | get_partition_for_key | | | | (9 rows) -- ensure data node has new dimensions @@ -2414,47 +2420,47 @@ $$); NOTICE: [db_dist_hypertable_1]: SELECT * FROM _timescaledb_catalog.dimension NOTICE: [db_dist_hypertable_1]: -id|hypertable_id|column_name |column_type |aligned|num_slices|partitioning_func_schema|partitioning_func |interval_length|integer_now_func_schema|integer_now_func ---+-------------+----------------+------------------------+-------+----------+------------------------+---------------------+---------------+-----------------------+---------------- - 1| 1|time |timestamp with time zone|t | | | | 604800000000| | - 2| 1|device |integer |f | 3|_timescaledb_internal |get_partition_hash | | | - 3| 2|time |timestamp with time zone|t | | | | 604800000000| | - 4| 3|time Col %#^#@$#|timestamp with time zone|t | | | | 604800000000| | - 5| 3|__region |text |f | 4|_timescaledb_internal |get_partition_hash | | | - 6| 4|time |timestamp with time zone|t | | | | 604800000000| | - 7| 4|column1 |integer |f | 4|_timescaledb_internal |get_partition_hash | | | - 8| 4|column2 |timestamp with time zone|t | | | | 604800000000| | - 9| 4|column3 |integer |f | 4|_timescaledb_internal |get_partition_for_key| | | +id|hypertable_id|column_name |column_type |aligned|num_slices|partitioning_func_schema|partitioning_func |interval_length|compress_interval_length|integer_now_func_schema|integer_now_func +--+-------------+----------------+------------------------+-------+----------+------------------------+---------------------+---------------+------------------------+-----------------------+---------------- + 1| 1|time |timestamp with time zone|t | | | | 604800000000| | | + 2| 1|device |integer |f | 3|_timescaledb_internal |get_partition_hash | | | | + 3| 2|time |timestamp with time zone|t | | | | 604800000000| | | + 4| 3|time Col %#^#@$#|timestamp with time zone|t | | | | 604800000000| | | + 5| 3|__region |text |f | 4|_timescaledb_internal |get_partition_hash | | | | + 6| 4|time |timestamp with time zone|t | | | | 604800000000| | | + 7| 4|column1 |integer |f | 4|_timescaledb_internal |get_partition_hash | | | | + 8| 4|column2 |timestamp with time zone|t | | | | 604800000000| | | + 9| 4|column3 |integer |f | 4|_timescaledb_internal |get_partition_for_key| | | | (9 rows) NOTICE: [db_dist_hypertable_2]: SELECT * FROM _timescaledb_catalog.dimension NOTICE: [db_dist_hypertable_2]: -id|hypertable_id|column_name |column_type |aligned|num_slices|partitioning_func_schema|partitioning_func |interval_length|integer_now_func_schema|integer_now_func ---+-------------+----------------+------------------------+-------+----------+------------------------+---------------------+---------------+-----------------------+---------------- - 1| 1|time |timestamp with time zone|t | | | | 604800000000| | - 2| 1|device |integer |f | 3|_timescaledb_internal |get_partition_hash | | | - 3| 2|time |timestamp with time zone|t | | | | 604800000000| | - 6| 4|time Col %#^#@$#|timestamp with time zone|t | | | | 604800000000| | - 7| 4|__region |text |f | 4|_timescaledb_internal |get_partition_hash | | | - 8| 5|time |timestamp with time zone|t | | | | 604800000000| | - 9| 5|column1 |integer |f | 4|_timescaledb_internal |get_partition_hash | | | -10| 5|column2 |timestamp with time zone|t | | | | 604800000000| | -11| 5|column3 |integer |f | 4|_timescaledb_internal |get_partition_for_key| | | +id|hypertable_id|column_name |column_type |aligned|num_slices|partitioning_func_schema|partitioning_func |interval_length|compress_interval_length|integer_now_func_schema|integer_now_func +--+-------------+----------------+------------------------+-------+----------+------------------------+---------------------+---------------+------------------------+-----------------------+---------------- + 1| 1|time |timestamp with time zone|t | | | | 604800000000| | | + 2| 1|device |integer |f | 3|_timescaledb_internal |get_partition_hash | | | | + 3| 2|time |timestamp with time zone|t | | | | 604800000000| | | + 6| 4|time Col %#^#@$#|timestamp with time zone|t | | | | 604800000000| | | + 7| 4|__region |text |f | 4|_timescaledb_internal |get_partition_hash | | | | + 8| 5|time |timestamp with time zone|t | | | | 604800000000| | | + 9| 5|column1 |integer |f | 4|_timescaledb_internal |get_partition_hash | | | | +10| 5|column2 |timestamp with time zone|t | | | | 604800000000| | | +11| 5|column3 |integer |f | 4|_timescaledb_internal |get_partition_for_key| | | | (9 rows) NOTICE: [db_dist_hypertable_3]: SELECT * FROM _timescaledb_catalog.dimension NOTICE: [db_dist_hypertable_3]: -id|hypertable_id|column_name |column_type |aligned|num_slices|partitioning_func_schema|partitioning_func |interval_length|integer_now_func_schema|integer_now_func ---+-------------+----------------+------------------------+-------+----------+------------------------+------------------+---------------+-----------------------+---------------- - 1| 1|time |timestamp with time zone|t | | | | 604800000000| | - 2| 1|device |integer |f | 3|_timescaledb_internal |get_partition_hash| | | - 3| 2|time |timestamp with time zone|t | | | | 604800000000| | - 4| 3|time Col %#^#@$#|timestamp with time zone|t | | | | 604800000000| | - 5| 3|__region |text |f | 4|_timescaledb_internal |get_partition_hash| | | +id|hypertable_id|column_name |column_type |aligned|num_slices|partitioning_func_schema|partitioning_func |interval_length|compress_interval_length|integer_now_func_schema|integer_now_func +--+-------------+----------------+------------------------+-------+----------+------------------------+------------------+---------------+------------------------+-----------------------+---------------- + 1| 1|time |timestamp with time zone|t | | | | 604800000000| | | + 2| 1|device |integer |f | 3|_timescaledb_internal |get_partition_hash| | | | + 3| 2|time |timestamp with time zone|t | | | | 604800000000| | | + 4| 3|time Col %#^#@$#|timestamp with time zone|t | | | | 604800000000| | | + 5| 3|__region |text |f | 4|_timescaledb_internal |get_partition_hash| | | | (5 rows) @@ -3427,9 +3433,9 @@ NOTICE: [db_dist_hypertable_1]: SELECT d.* FROM _timescaledb_catalog.hypertable h, _timescaledb_catalog.dimension d WHERE h.id = d.hypertable_id AND h.table_name = 'disttable' NOTICE: [db_dist_hypertable_1]: -id|hypertable_id|column_name|column_type|aligned|num_slices|partitioning_func_schema|partitioning_func|interval_length|integer_now_func_schema|integer_now_func ---+-------------+-----------+-----------+-------+----------+------------------------+-----------------+---------------+-----------------------+---------------- -20| 11|time |bigint |t | | | | 1000000| | +id|hypertable_id|column_name|column_type|aligned|num_slices|partitioning_func_schema|partitioning_func|interval_length|compress_interval_length|integer_now_func_schema|integer_now_func +--+-------------+-----------+-----------+-------+----------+------------------------+-----------------+---------------+------------------------+-----------------------+---------------- +20| 11|time |bigint |t | | | | 1000000| | | (1 row) @@ -3437,9 +3443,9 @@ NOTICE: [db_dist_hypertable_2]: SELECT d.* FROM _timescaledb_catalog.hypertable h, _timescaledb_catalog.dimension d WHERE h.id = d.hypertable_id AND h.table_name = 'disttable' NOTICE: [db_dist_hypertable_2]: -id|hypertable_id|column_name|column_type|aligned|num_slices|partitioning_func_schema|partitioning_func|interval_length|integer_now_func_schema|integer_now_func ---+-------------+-----------+-----------+-------+----------+------------------------+-----------------+---------------+-----------------------+---------------- -20| 11|time |bigint |t | | | | 1000000| | +id|hypertable_id|column_name|column_type|aligned|num_slices|partitioning_func_schema|partitioning_func|interval_length|compress_interval_length|integer_now_func_schema|integer_now_func +--+-------------+-----------+-----------+-------+----------+------------------------+-----------------+---------------+------------------------+-----------------------+---------------- +20| 11|time |bigint |t | | | | 1000000| | | (1 row) @@ -3447,9 +3453,9 @@ NOTICE: [db_dist_hypertable_3]: SELECT d.* FROM _timescaledb_catalog.hypertable h, _timescaledb_catalog.dimension d WHERE h.id = d.hypertable_id AND h.table_name = 'disttable' NOTICE: [db_dist_hypertable_3]: -id|hypertable_id|column_name|column_type|aligned|num_slices|partitioning_func_schema|partitioning_func|interval_length|integer_now_func_schema|integer_now_func ---+-------------+-----------+-----------+-------+----------+------------------------+-----------------+---------------+-----------------------+---------------- -14| 9|time |bigint |t | | | | 1000000| | +id|hypertable_id|column_name|column_type|aligned|num_slices|partitioning_func_schema|partitioning_func|interval_length|compress_interval_length|integer_now_func_schema|integer_now_func +--+-------------+-----------+-----------+-------+----------+------------------------+-----------------+---------------+------------------------+-----------------------+---------------- +14| 9|time |bigint |t | | | | 1000000| | | (1 row) @@ -3477,10 +3483,10 @@ NOTICE: [db_dist_hypertable_1]: SELECT d.* FROM _timescaledb_catalog.hypertable h, _timescaledb_catalog.dimension d WHERE h.id = d.hypertable_id AND h.table_name = 'disttable' NOTICE: [db_dist_hypertable_1]: -id|hypertable_id|column_name|column_type|aligned|num_slices|partitioning_func_schema|partitioning_func |interval_length|integer_now_func_schema|integer_now_func ---+-------------+-----------+-----------+-------+----------+------------------------+------------------+---------------+-----------------------+---------------- -21| 11|device |integer |f | 1|_timescaledb_internal |get_partition_hash| | | -20| 11|time |bigint |t | | | | 1000000| | +id|hypertable_id|column_name|column_type|aligned|num_slices|partitioning_func_schema|partitioning_func |interval_length|compress_interval_length|integer_now_func_schema|integer_now_func +--+-------------+-----------+-----------+-------+----------+------------------------+------------------+---------------+------------------------+-----------------------+---------------- +21| 11|device |integer |f | 1|_timescaledb_internal |get_partition_hash| | | | +20| 11|time |bigint |t | | | | 1000000| | | (2 rows) @@ -3488,10 +3494,10 @@ NOTICE: [db_dist_hypertable_2]: SELECT d.* FROM _timescaledb_catalog.hypertable h, _timescaledb_catalog.dimension d WHERE h.id = d.hypertable_id AND h.table_name = 'disttable' NOTICE: [db_dist_hypertable_2]: -id|hypertable_id|column_name|column_type|aligned|num_slices|partitioning_func_schema|partitioning_func |interval_length|integer_now_func_schema|integer_now_func ---+-------------+-----------+-----------+-------+----------+------------------------+------------------+---------------+-----------------------+---------------- -21| 11|device |integer |f | 1|_timescaledb_internal |get_partition_hash| | | -20| 11|time |bigint |t | | | | 1000000| | +id|hypertable_id|column_name|column_type|aligned|num_slices|partitioning_func_schema|partitioning_func |interval_length|compress_interval_length|integer_now_func_schema|integer_now_func +--+-------------+-----------+-----------+-------+----------+------------------------+------------------+---------------+------------------------+-----------------------+---------------- +21| 11|device |integer |f | 1|_timescaledb_internal |get_partition_hash| | | | +20| 11|time |bigint |t | | | | 1000000| | | (2 rows) @@ -3499,10 +3505,10 @@ NOTICE: [db_dist_hypertable_3]: SELECT d.* FROM _timescaledb_catalog.hypertable h, _timescaledb_catalog.dimension d WHERE h.id = d.hypertable_id AND h.table_name = 'disttable' NOTICE: [db_dist_hypertable_3]: -id|hypertable_id|column_name|column_type|aligned|num_slices|partitioning_func_schema|partitioning_func |interval_length|integer_now_func_schema|integer_now_func ---+-------------+-----------+-----------+-------+----------+------------------------+------------------+---------------+-----------------------+---------------- -15| 9|device |integer |f | 1|_timescaledb_internal |get_partition_hash| | | -14| 9|time |bigint |t | | | | 1000000| | +id|hypertable_id|column_name|column_type|aligned|num_slices|partitioning_func_schema|partitioning_func |interval_length|compress_interval_length|integer_now_func_schema|integer_now_func +--+-------------+-----------+-----------+-------+----------+------------------------+------------------+---------------+------------------------+-----------------------+---------------- +15| 9|device |integer |f | 1|_timescaledb_internal |get_partition_hash| | | | +14| 9|time |bigint |t | | | | 1000000| | | (2 rows) @@ -3543,10 +3549,10 @@ NOTICE: [db_dist_hypertable_1]: SELECT d.* FROM _timescaledb_catalog.hypertable h, _timescaledb_catalog.dimension d WHERE h.id = d.hypertable_id AND h.table_name = 'disttable' NOTICE: [db_dist_hypertable_1]: -id|hypertable_id|column_name|column_type|aligned|num_slices|partitioning_func_schema|partitioning_func |interval_length|integer_now_func_schema|integer_now_func ---+-------------+-----------+-----------+-------+----------+------------------------+------------------+---------------+-----------------------+---------------- -21| 11|device |integer |f | 3|_timescaledb_internal |get_partition_hash| | | -20| 11|time |bigint |t | | | | 2000000000|public |dummy_now +id|hypertable_id|column_name|column_type|aligned|num_slices|partitioning_func_schema|partitioning_func |interval_length|compress_interval_length|integer_now_func_schema|integer_now_func +--+-------------+-----------+-----------+-------+----------+------------------------+------------------+---------------+------------------------+-----------------------+---------------- +21| 11|device |integer |f | 3|_timescaledb_internal |get_partition_hash| | | | +20| 11|time |bigint |t | | | | 2000000000| |public |dummy_now (2 rows) @@ -3554,10 +3560,10 @@ NOTICE: [db_dist_hypertable_2]: SELECT d.* FROM _timescaledb_catalog.hypertable h, _timescaledb_catalog.dimension d WHERE h.id = d.hypertable_id AND h.table_name = 'disttable' NOTICE: [db_dist_hypertable_2]: -id|hypertable_id|column_name|column_type|aligned|num_slices|partitioning_func_schema|partitioning_func |interval_length|integer_now_func_schema|integer_now_func ---+-------------+-----------+-----------+-------+----------+------------------------+------------------+---------------+-----------------------+---------------- -21| 11|device |integer |f | 3|_timescaledb_internal |get_partition_hash| | | -20| 11|time |bigint |t | | | | 2000000000|public |dummy_now +id|hypertable_id|column_name|column_type|aligned|num_slices|partitioning_func_schema|partitioning_func |interval_length|compress_interval_length|integer_now_func_schema|integer_now_func +--+-------------+-----------+-----------+-------+----------+------------------------+------------------+---------------+------------------------+-----------------------+---------------- +21| 11|device |integer |f | 3|_timescaledb_internal |get_partition_hash| | | | +20| 11|time |bigint |t | | | | 2000000000| |public |dummy_now (2 rows) @@ -3565,10 +3571,10 @@ NOTICE: [db_dist_hypertable_3]: SELECT d.* FROM _timescaledb_catalog.hypertable h, _timescaledb_catalog.dimension d WHERE h.id = d.hypertable_id AND h.table_name = 'disttable' NOTICE: [db_dist_hypertable_3]: -id|hypertable_id|column_name|column_type|aligned|num_slices|partitioning_func_schema|partitioning_func |interval_length|integer_now_func_schema|integer_now_func ---+-------------+-----------+-----------+-------+----------+------------------------+------------------+---------------+-----------------------+---------------- -15| 9|device |integer |f | 3|_timescaledb_internal |get_partition_hash| | | -14| 9|time |bigint |t | | | | 2000000000|public |dummy_now +id|hypertable_id|column_name|column_type|aligned|num_slices|partitioning_func_schema|partitioning_func |interval_length|compress_interval_length|integer_now_func_schema|integer_now_func +--+-------------+-----------+-----------+-------+----------+------------------------+------------------+---------------+------------------------+-----------------------+---------------- +15| 9|device |integer |f | 3|_timescaledb_internal |get_partition_hash| | | | +14| 9|time |bigint |t | | | | 2000000000| |public |dummy_now (2 rows) @@ -3876,8 +3882,8 @@ ORDER BY 1; ------------------------------+--------+---------- Sun Jan 01 07:00:00 2017 PST | 1 | 1.65 Mon Jan 02 04:00:00 2017 PST | 2 | 1.4 - Mon Jan 02 07:00:00 2017 PST | 1 | 1.3 Mon Jan 02 07:00:00 2017 PST | 2 | 1.6 + Mon Jan 02 07:00:00 2017 PST | 1 | 1.3 Tue Jan 03 01:00:00 2017 PST | 3 | 3 Sat Jan 13 01:00:00 2018 PST | 2 | 1.4 Sat Jan 13 04:00:00 2018 PST | 2 | 3 @@ -5313,8 +5319,8 @@ RESET timescaledb.remote_data_fetcher; EXPLAIN (COSTS OFF) INSERT INTO disttable (time, device, temp_c) SELECT time, device, temp_c FROM disttable; - QUERY PLAN ------------------------------------------------------------------------------------ + QUERY PLAN +----------------------------------------------------------------------------------------- Custom Scan (HypertableModify) Insert on distributed hypertable disttable -> Insert on disttable @@ -5322,10 +5328,13 @@ SELECT time, device, temp_c FROM disttable; Batch size: 1000 -> Custom Scan (ChunkDispatch) -> Append - -> Custom Scan (DataNodeScan) on disttable disttable_2 - -> Custom Scan (DataNodeScan) on disttable disttable_3 - -> Custom Scan (DataNodeScan) on disttable disttable_4 -(10 rows) + -> Result + -> Custom Scan (DataNodeScan) on disttable disttable_2 + -> Result + -> Custom Scan (DataNodeScan) on disttable disttable_3 + -> Result + -> Custom Scan (DataNodeScan) on disttable disttable_4 +(13 rows) EXPLAIN (COSTS OFF) INSERT INTO disttable (time, device, temp_c) @@ -5350,8 +5359,8 @@ SELECT time, device, temp_c FROM disttable LIMIT 1; EXPLAIN (COSTS OFF) INSERT INTO disttable (time, device, temp_c) SELECT time, device, temp_c FROM disttable RETURNING *; - QUERY PLAN ------------------------------------------------------------------------------------ + QUERY PLAN +----------------------------------------------------------------------------------------- Custom Scan (HypertableModify) Insert on distributed hypertable disttable -> Insert on disttable @@ -5359,10 +5368,13 @@ SELECT time, device, temp_c FROM disttable RETURNING *; Batch size: 1000 -> Custom Scan (ChunkDispatch) -> Append - -> Custom Scan (DataNodeScan) on disttable disttable_2 - -> Custom Scan (DataNodeScan) on disttable disttable_3 - -> Custom Scan (DataNodeScan) on disttable disttable_4 -(10 rows) + -> Result + -> Custom Scan (DataNodeScan) on disttable disttable_2 + -> Result + -> Custom Scan (DataNodeScan) on disttable disttable_3 + -> Result + -> Custom Scan (DataNodeScan) on disttable disttable_4 +(13 rows) INSERT INTO disttable (time, device, temp_c) SELECT time, device, temp_c FROM disttable; @@ -5841,36 +5853,40 @@ WHERE time > x + (x = x)::int -- stable * (x = '2018-01-02 11:00:00'::timestamp)::int -- immutable * INTERVAL '1 hour'; - QUERY PLAN ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- + QUERY PLAN +--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- Custom Scan (AsyncAppend) Output: test_tz."time", test_tz.v, (('Tue Jan 02 11:00:00 2018 -01'::timestamp with time zone)::timestamp without time zone) -> Append - -> Custom Scan (DataNodeScan) on public.test_tz test_tz_1 + -> Result Output: test_tz_1."time", test_tz_1.v, ('Tue Jan 02 11:00:00 2018 -01'::timestamp with time zone)::timestamp without time zone - Data node: db_dist_hypertable_1 - Chunks: _dist_hyper_31_97_chunk - Remote SQL: SELECT "time", v FROM public.test_tz WHERE _timescaledb_internal.chunks_in(public.test_tz.*, ARRAY[45]) AND (("time" > '2018-01-02 12:00:00'::timestamp without time zone)) - Remote EXPLAIN: - Index Scan using _dist_hyper_31_97_chunk_test_tz_time_idx on _timescaledb_internal._dist_hyper_31_97_chunk - Output: _dist_hyper_31_97_chunk."time", _dist_hyper_31_97_chunk.v - Index Cond: (_dist_hyper_31_97_chunk."time" > '2018-01-02 12:00:00'::timestamp without time zone) + -> Custom Scan (DataNodeScan) on public.test_tz test_tz_1 + Output: test_tz_1."time", test_tz_1.v + Data node: db_dist_hypertable_1 + Chunks: _dist_hyper_31_97_chunk + Remote SQL: SELECT "time", v FROM public.test_tz WHERE _timescaledb_internal.chunks_in(public.test_tz.*, ARRAY[45]) AND (("time" > '2018-01-02 12:00:00'::timestamp without time zone)) + Remote EXPLAIN: + Index Scan using _dist_hyper_31_97_chunk_test_tz_time_idx on _timescaledb_internal._dist_hyper_31_97_chunk + Output: _dist_hyper_31_97_chunk."time", _dist_hyper_31_97_chunk.v + Index Cond: (_dist_hyper_31_97_chunk."time" > '2018-01-02 12:00:00'::timestamp without time zone) - -> Custom Scan (DataNodeScan) on public.test_tz test_tz_2 + -> Result Output: test_tz_2."time", test_tz_2.v, ('Tue Jan 02 11:00:00 2018 -01'::timestamp with time zone)::timestamp without time zone - Data node: db_dist_hypertable_2 - Chunks: _dist_hyper_31_95_chunk, _dist_hyper_31_96_chunk, _dist_hyper_31_98_chunk - Remote SQL: SELECT "time", v FROM public.test_tz WHERE _timescaledb_internal.chunks_in(public.test_tz.*, ARRAY[43, 44, 45]) AND (("time" > '2018-01-02 12:00:00'::timestamp without time zone)) - Remote EXPLAIN: - Append - -> Index Scan using _dist_hyper_31_95_chunk_test_tz_time_idx on _timescaledb_internal._dist_hyper_31_95_chunk - Output: _dist_hyper_31_95_chunk."time", _dist_hyper_31_95_chunk.v - Index Cond: (_dist_hyper_31_95_chunk."time" > '2018-01-02 12:00:00'::timestamp without time zone) - -> Index Scan using _dist_hyper_31_98_chunk_test_tz_time_idx on _timescaledb_internal._dist_hyper_31_98_chunk - Output: _dist_hyper_31_98_chunk."time", _dist_hyper_31_98_chunk.v - Index Cond: (_dist_hyper_31_98_chunk."time" > '2018-01-02 12:00:00'::timestamp without time zone) + -> Custom Scan (DataNodeScan) on public.test_tz test_tz_2 + Output: test_tz_2."time", test_tz_2.v + Data node: db_dist_hypertable_2 + Chunks: _dist_hyper_31_95_chunk, _dist_hyper_31_96_chunk, _dist_hyper_31_98_chunk + Remote SQL: SELECT "time", v FROM public.test_tz WHERE _timescaledb_internal.chunks_in(public.test_tz.*, ARRAY[43, 44, 45]) AND (("time" > '2018-01-02 12:00:00'::timestamp without time zone)) + Remote EXPLAIN: + Append + -> Index Scan using _dist_hyper_31_95_chunk_test_tz_time_idx on _timescaledb_internal._dist_hyper_31_95_chunk + Output: _dist_hyper_31_95_chunk."time", _dist_hyper_31_95_chunk.v + Index Cond: (_dist_hyper_31_95_chunk."time" > '2018-01-02 12:00:00'::timestamp without time zone) + -> Index Scan using _dist_hyper_31_98_chunk_test_tz_time_idx on _timescaledb_internal._dist_hyper_31_98_chunk + Output: _dist_hyper_31_98_chunk."time", _dist_hyper_31_98_chunk.v + Index Cond: (_dist_hyper_31_98_chunk."time" > '2018-01-02 12:00:00'::timestamp without time zone) -(27 rows) +(31 rows) -- Reference value for the above test. WITH dummy AS (SELECT '2018-01-02 12:00:00 +00'::timestamptz::timestamp x) diff --git a/tsl/test/expected/jit-15.out b/tsl/test/expected/jit-15.out index 068fbead735..4e6671db876 100644 --- a/tsl/test/expected/jit-15.out +++ b/tsl/test/expected/jit-15.out @@ -206,15 +206,17 @@ SELECT * FROM jit_device_summary WHERE metric_spread = 1800 ORDER BY bucket DESC Output: (time_bucket('@ 1 hour'::interval, jit_test_contagg.observation_time)), jit_test_contagg.device_id, avg(jit_test_contagg.metric), (max(jit_test_contagg.metric) - min(jit_test_contagg.metric)) Group Key: time_bucket('@ 1 hour'::interval, jit_test_contagg.observation_time), jit_test_contagg.device_id Filter: ((max(jit_test_contagg.metric) - min(jit_test_contagg.metric)) = '1800'::double precision) - -> Custom Scan (ChunkAppend) on public.jit_test_contagg + -> Result Output: time_bucket('@ 1 hour'::interval, jit_test_contagg.observation_time), jit_test_contagg.device_id, jit_test_contagg.metric - Startup Exclusion: true - Runtime Exclusion: false - Chunks excluded during startup: 4 - -> Index Scan using _hyper_3_5_chunk_jit_test_contagg_observation_time_idx on _timescaledb_internal._hyper_3_5_chunk - Output: _hyper_3_5_chunk.observation_time, _hyper_3_5_chunk.device_id, _hyper_3_5_chunk.metric - Index Cond: (_hyper_3_5_chunk.observation_time >= COALESCE(_timescaledb_internal.to_timestamp(_timescaledb_internal.cagg_watermark(4)), '-infinity'::timestamp with time zone)) -(27 rows) + -> Custom Scan (ChunkAppend) on public.jit_test_contagg + Output: jit_test_contagg.observation_time, jit_test_contagg.device_id, jit_test_contagg.metric + Startup Exclusion: true + Runtime Exclusion: false + Chunks excluded during startup: 4 + -> Index Scan using _hyper_3_5_chunk_jit_test_contagg_observation_time_idx on _timescaledb_internal._hyper_3_5_chunk + Output: _hyper_3_5_chunk.observation_time, _hyper_3_5_chunk.device_id, _hyper_3_5_chunk.metric + Index Cond: (_hyper_3_5_chunk.observation_time >= COALESCE(_timescaledb_internal.to_timestamp(_timescaledb_internal.cagg_watermark(4)), '-infinity'::timestamp with time zone)) +(29 rows) -- generate the results into two different files \set ECHO errors diff --git a/tsl/test/shared/expected/dist_remote_error.out b/tsl/test/shared/expected/dist_remote_error-12.out similarity index 100% rename from tsl/test/shared/expected/dist_remote_error.out rename to tsl/test/shared/expected/dist_remote_error-12.out diff --git a/tsl/test/shared/expected/dist_remote_error-13.out b/tsl/test/shared/expected/dist_remote_error-13.out new file mode 100644 index 00000000000..4acbf5f0168 --- /dev/null +++ b/tsl/test/shared/expected/dist_remote_error-13.out @@ -0,0 +1,229 @@ +-- This file and its contents are licensed under the Timescale License. +-- Please see the included NOTICE for copyright information and +-- LICENSE-TIMESCALE for a copy of the license. +-- Import setup file to data nodes. +\unset ECHO +-- Disable SSL to get stable error output across versions. SSL adds some output +-- that changed in PG 14. +set timescaledb.debug_enable_ssl to off; +set client_min_messages to error; +SET timescaledb.hide_data_node_name_in_errors = 'on'; +-- A relatively big table on one data node +create table metrics_dist_remote_error(like metrics_dist); +select table_name from create_distributed_hypertable('metrics_dist_remote_error', 'time', 'device_id', + data_nodes => '{"data_node_1"}'); + table_name + metrics_dist_remote_error +(1 row) + +insert into metrics_dist_remote_error select * from metrics_dist order by metrics_dist limit 20000; +-- The error messages vary wildly between the Postgres versions, dependent on +-- the particular behavior of libqp in this or that case. The purpose of this +-- test is not to solidify this accidental behavior, but to merely exercise the +-- error handling code to make sure it doesn't have fatal errors. Unfortunately, +-- there is no way to suppress error output from a psql script. +set client_min_messages to ERROR; +\set ON_ERROR_STOP off +set timescaledb.remote_data_fetcher = 'copy'; +explain (analyze, verbose, costs off, timing off, summary off) +select 1 from metrics_dist_remote_error where ts_debug_shippable_error_after_n_rows(0, device_id)::int != 0; +ERROR: []: debug point: requested to error out after 0 rows, 1 rows seen +explain (analyze, verbose, costs off, timing off, summary off) +select 1 from metrics_dist_remote_error where ts_debug_shippable_error_after_n_rows(1, device_id)::int != 0; +ERROR: []: debug point: requested to error out after 1 rows, 1 rows seen +explain (analyze, verbose, costs off, timing off, summary off) +select 1 from metrics_dist_remote_error where ts_debug_shippable_error_after_n_rows(2, device_id)::int != 0; +ERROR: []: debug point: requested to error out after 2 rows, 2 rows seen +explain (analyze, verbose, costs off, timing off, summary off) +select 1 from metrics_dist_remote_error where ts_debug_shippable_error_after_n_rows(701, device_id)::int != 0; +ERROR: []: debug point: requested to error out after 701 rows, 701 rows seen +explain (analyze, verbose, costs off, timing off, summary off) +select 1 from metrics_dist_remote_error where ts_debug_shippable_error_after_n_rows(10000, device_id)::int != 0; +ERROR: []: debug point: requested to error out after 10000 rows, 10000 rows seen +explain (analyze, verbose, costs off, timing off, summary off) +select 1 from metrics_dist_remote_error where ts_debug_shippable_error_after_n_rows(16384, device_id)::int != 0; +ERROR: []: debug point: requested to error out after 16384 rows, 16384 rows seen +explain (analyze, verbose, costs off, timing off, summary off) +select 1 from metrics_dist_remote_error where ts_debug_shippable_error_after_n_rows(10000000, device_id)::int != 0; +QUERY PLAN + Custom Scan (DataNodeScan) on public.metrics_dist_remote_error (actual rows=20000 loops=1) + Output: 1 + Data node: data_node_1 + Fetcher Type: COPY + Chunks: _dist_hyper_X_X_chunk, _dist_hyper_X_X_chunk + Remote SQL: SELECT NULL FROM public.metrics_dist_remote_error WHERE _timescaledb_internal.chunks_in(public.metrics_dist_remote_error.*, ARRAY[..]) AND ((public.ts_debug_shippable_error_after_n_rows(10000000, device_id) <> 0)) +(6 rows) + +-- We don't test fatal errors here, because PG versions before 14 are unable to +-- report them properly to the access node, so we get different errors in these +-- versions. +-- Now test the same with the cursor fetcher. +set timescaledb.remote_data_fetcher = 'cursor'; +explain (analyze, verbose, costs off, timing off, summary off) +select 1 from metrics_dist_remote_error where ts_debug_shippable_error_after_n_rows(0, device_id)::int != 0; +ERROR: []: debug point: requested to error out after 0 rows, 1 rows seen +explain (analyze, verbose, costs off, timing off, summary off) +select 1 from metrics_dist_remote_error where ts_debug_shippable_error_after_n_rows(1, device_id)::int != 0; +ERROR: []: debug point: requested to error out after 1 rows, 1 rows seen +explain (analyze, verbose, costs off, timing off, summary off) +select 1 from metrics_dist_remote_error where ts_debug_shippable_error_after_n_rows(2, device_id)::int != 0; +ERROR: []: debug point: requested to error out after 2 rows, 2 rows seen +explain (analyze, verbose, costs off, timing off, summary off) +select 1 from metrics_dist_remote_error where ts_debug_shippable_error_after_n_rows(701, device_id)::int != 0; +ERROR: []: debug point: requested to error out after 701 rows, 701 rows seen +explain (analyze, verbose, costs off, timing off, summary off) +select 1 from metrics_dist_remote_error where ts_debug_shippable_error_after_n_rows(10000, device_id)::int != 0; +ERROR: []: debug point: requested to error out after 10000 rows, 10000 rows seen +explain (analyze, verbose, costs off, timing off, summary off) +select 1 from metrics_dist_remote_error where ts_debug_shippable_error_after_n_rows(10000000, device_id)::int != 0; +QUERY PLAN + Custom Scan (DataNodeScan) on public.metrics_dist_remote_error (actual rows=20000 loops=1) + Output: 1 + Data node: data_node_1 + Fetcher Type: Cursor + Chunks: _dist_hyper_X_X_chunk, _dist_hyper_X_X_chunk + Remote SQL: SELECT NULL FROM public.metrics_dist_remote_error WHERE _timescaledb_internal.chunks_in(public.metrics_dist_remote_error.*, ARRAY[..]) AND ((public.ts_debug_shippable_error_after_n_rows(10000000, device_id) <> 0)) +(6 rows) + +-- Table with broken send for a data type. +create table metrics_dist_bs(like metrics_dist); +alter table metrics_dist_bs alter column v0 type bs; +select table_name from create_distributed_hypertable('metrics_dist_bs', + 'time', 'device_id'); + table_name + metrics_dist_bs +(1 row) + +set timescaledb.enable_connection_binary_data to off; +insert into metrics_dist_bs + select * from metrics_dist_remote_error; +set timescaledb.enable_connection_binary_data to on; +explain (analyze, verbose, costs off, timing off, summary off) +select * from metrics_dist_bs; +ERROR: []: debug point: requested to error out after 7103 rows, 7103 rows seen +drop table metrics_dist_bs; +-- Table with broken receive for a data type. +create table metrics_dist_br(like metrics_dist); +alter table metrics_dist_br alter column v0 type br; +select table_name from create_distributed_hypertable('metrics_dist_br', + 'time', 'device_id'); + table_name + metrics_dist_br +(1 row) + +select hypertable_name, replication_factor from timescaledb_information.hypertables +where hypertable_name = 'metrics_dist_br'; + hypertable_name | replication_factor +-----------------+-------------------- + metrics_dist_br | 1 +(1 row) + +-- Test that INSERT and COPY fail on data nodes. +-- Note that we use the text format for the COPY input, so that the access node +-- doesn't call `recv` and fail by itself. It's going to use binary format for +-- transfer to data nodes regardless of the input format. +set timescaledb.dist_copy_transfer_format = 'binary'; +-- First, create the reference. +\copy (select * from metrics_dist_remote_error) to 'dist_remote_error.text' with (format text); +-- We have to test various interleavings of COPY and INSERT to check that +-- one can recover from connection failure states introduced by another. +\copy metrics_dist_br from 'dist_remote_error.text' with (format text); +ERROR: []: debug point: requested to error out after 7103 rows, 7103 rows seen +\copy metrics_dist_br from 'dist_remote_error.text' with (format text); +ERROR: []: debug point: requested to error out after 7103 rows, 7103 rows seen +insert into metrics_dist_br select * from metrics_dist_remote_error; +ERROR: []: debug point: requested to error out after 7103 rows, 7103 rows seen +insert into metrics_dist_br select * from metrics_dist_remote_error; +ERROR: []: debug point: requested to error out after 7103 rows, 7103 rows seen +\copy metrics_dist_br from 'dist_remote_error.text' with (format text); +ERROR: []: debug point: requested to error out after 7103 rows, 7103 rows seen +-- Fail at different points +set timescaledb.debug_broken_sendrecv_throw_after = 1; +\copy metrics_dist_br from 'dist_remote_error.text' with (format text); +ERROR: []: debug point: requested to error out after 1 rows, 1 rows seen +set timescaledb.debug_broken_sendrecv_throw_after = 2; +\copy metrics_dist_br from 'dist_remote_error.text' with (format text); +ERROR: []: debug point: requested to error out after 2 rows, 2 rows seen +set timescaledb.debug_broken_sendrecv_throw_after = 1023; +\copy metrics_dist_br from 'dist_remote_error.text' with (format text); +ERROR: []: debug point: requested to error out after 1023 rows, 1023 rows seen +set timescaledb.debug_broken_sendrecv_throw_after = 1024; +\copy metrics_dist_br from 'dist_remote_error.text' with (format text); +ERROR: []: debug point: requested to error out after 1024 rows, 1024 rows seen +set timescaledb.debug_broken_sendrecv_throw_after = 1025; +\copy metrics_dist_br from 'dist_remote_error.text' with (format text); +ERROR: []: debug point: requested to error out after 1025 rows, 1025 rows seen +reset timescaledb.debug_broken_sendrecv_throw_after; +-- Same with different replication factor +truncate metrics_dist_br; +select set_replication_factor('metrics_dist_br', 2); + set_replication_factor + +(1 row) + +select hypertable_name, replication_factor from timescaledb_information.hypertables +where hypertable_name = 'metrics_dist_br'; + hypertable_name | replication_factor +-----------------+-------------------- + metrics_dist_br | 2 +(1 row) + +\copy metrics_dist_br from 'dist_remote_error.text' with (format text); +ERROR: []: debug point: requested to error out after 7103 rows, 7103 rows seen +\copy metrics_dist_br from 'dist_remote_error.text' with (format text); +ERROR: []: debug point: requested to error out after 7103 rows, 7103 rows seen +insert into metrics_dist_br select * from metrics_dist_remote_error; +ERROR: []: debug point: requested to error out after 7103 rows, 7103 rows seen +insert into metrics_dist_br select * from metrics_dist_remote_error; +ERROR: []: debug point: requested to error out after 7103 rows, 7103 rows seen +set timescaledb.debug_broken_sendrecv_throw_after = 1; +\copy metrics_dist_br from 'dist_remote_error.text' with (format text); +ERROR: []: debug point: requested to error out after 1 rows, 1 rows seen +set timescaledb.debug_broken_sendrecv_throw_after = 2; +\copy metrics_dist_br from 'dist_remote_error.text' with (format text); +ERROR: []: debug point: requested to error out after 2 rows, 2 rows seen +set timescaledb.debug_broken_sendrecv_throw_after = 1023; +\copy metrics_dist_br from 'dist_remote_error.text' with (format text); +ERROR: []: debug point: requested to error out after 1023 rows, 1023 rows seen +set timescaledb.debug_broken_sendrecv_throw_after = 1024; +\copy metrics_dist_br from 'dist_remote_error.text' with (format text); +ERROR: []: debug point: requested to error out after 1024 rows, 1024 rows seen +set timescaledb.debug_broken_sendrecv_throw_after = 1025; +\copy metrics_dist_br from 'dist_remote_error.text' with (format text); +ERROR: []: debug point: requested to error out after 1025 rows, 1025 rows seen +-- Should succeed with text format for data transfer. +set timescaledb.dist_copy_transfer_format = 'text'; +\copy metrics_dist_br from 'dist_remote_error.text' with (format text); +-- Final check. +set timescaledb.enable_connection_binary_data = false; +select count(*) from metrics_dist_br; + count + 20000 +(1 row) + +set timescaledb.enable_connection_binary_data = true; +reset timescaledb.debug_broken_sendrecv_throw_after; +drop table metrics_dist_br; +-- Table with sleepy receive for a data type, to improve coverage of the waiting +-- code on the access node. +create table metrics_dist_bl(like metrics_dist); +alter table metrics_dist_bl alter column v0 type bl; +select table_name from create_distributed_hypertable('metrics_dist_bl', + 'time', 'device_id'); + table_name + metrics_dist_bl +(1 row) + +-- We're using sleepy recv function, so need the binary transfer format for it +-- to be called on the data nodes. +set timescaledb.dist_copy_transfer_format = 'binary'; +-- Test INSERT and COPY with slow data node. +\copy metrics_dist_bl from 'dist_remote_error.text' with (format text); +insert into metrics_dist_bl select * from metrics_dist_remote_error; +select count(*) from metrics_dist_bl; + count + 40000 +(1 row) + +drop table metrics_dist_bl; +drop table metrics_dist_remote_error; diff --git a/tsl/test/shared/expected/dist_remote_error-14.out b/tsl/test/shared/expected/dist_remote_error-14.out new file mode 100644 index 00000000000..4acbf5f0168 --- /dev/null +++ b/tsl/test/shared/expected/dist_remote_error-14.out @@ -0,0 +1,229 @@ +-- This file and its contents are licensed under the Timescale License. +-- Please see the included NOTICE for copyright information and +-- LICENSE-TIMESCALE for a copy of the license. +-- Import setup file to data nodes. +\unset ECHO +-- Disable SSL to get stable error output across versions. SSL adds some output +-- that changed in PG 14. +set timescaledb.debug_enable_ssl to off; +set client_min_messages to error; +SET timescaledb.hide_data_node_name_in_errors = 'on'; +-- A relatively big table on one data node +create table metrics_dist_remote_error(like metrics_dist); +select table_name from create_distributed_hypertable('metrics_dist_remote_error', 'time', 'device_id', + data_nodes => '{"data_node_1"}'); + table_name + metrics_dist_remote_error +(1 row) + +insert into metrics_dist_remote_error select * from metrics_dist order by metrics_dist limit 20000; +-- The error messages vary wildly between the Postgres versions, dependent on +-- the particular behavior of libqp in this or that case. The purpose of this +-- test is not to solidify this accidental behavior, but to merely exercise the +-- error handling code to make sure it doesn't have fatal errors. Unfortunately, +-- there is no way to suppress error output from a psql script. +set client_min_messages to ERROR; +\set ON_ERROR_STOP off +set timescaledb.remote_data_fetcher = 'copy'; +explain (analyze, verbose, costs off, timing off, summary off) +select 1 from metrics_dist_remote_error where ts_debug_shippable_error_after_n_rows(0, device_id)::int != 0; +ERROR: []: debug point: requested to error out after 0 rows, 1 rows seen +explain (analyze, verbose, costs off, timing off, summary off) +select 1 from metrics_dist_remote_error where ts_debug_shippable_error_after_n_rows(1, device_id)::int != 0; +ERROR: []: debug point: requested to error out after 1 rows, 1 rows seen +explain (analyze, verbose, costs off, timing off, summary off) +select 1 from metrics_dist_remote_error where ts_debug_shippable_error_after_n_rows(2, device_id)::int != 0; +ERROR: []: debug point: requested to error out after 2 rows, 2 rows seen +explain (analyze, verbose, costs off, timing off, summary off) +select 1 from metrics_dist_remote_error where ts_debug_shippable_error_after_n_rows(701, device_id)::int != 0; +ERROR: []: debug point: requested to error out after 701 rows, 701 rows seen +explain (analyze, verbose, costs off, timing off, summary off) +select 1 from metrics_dist_remote_error where ts_debug_shippable_error_after_n_rows(10000, device_id)::int != 0; +ERROR: []: debug point: requested to error out after 10000 rows, 10000 rows seen +explain (analyze, verbose, costs off, timing off, summary off) +select 1 from metrics_dist_remote_error where ts_debug_shippable_error_after_n_rows(16384, device_id)::int != 0; +ERROR: []: debug point: requested to error out after 16384 rows, 16384 rows seen +explain (analyze, verbose, costs off, timing off, summary off) +select 1 from metrics_dist_remote_error where ts_debug_shippable_error_after_n_rows(10000000, device_id)::int != 0; +QUERY PLAN + Custom Scan (DataNodeScan) on public.metrics_dist_remote_error (actual rows=20000 loops=1) + Output: 1 + Data node: data_node_1 + Fetcher Type: COPY + Chunks: _dist_hyper_X_X_chunk, _dist_hyper_X_X_chunk + Remote SQL: SELECT NULL FROM public.metrics_dist_remote_error WHERE _timescaledb_internal.chunks_in(public.metrics_dist_remote_error.*, ARRAY[..]) AND ((public.ts_debug_shippable_error_after_n_rows(10000000, device_id) <> 0)) +(6 rows) + +-- We don't test fatal errors here, because PG versions before 14 are unable to +-- report them properly to the access node, so we get different errors in these +-- versions. +-- Now test the same with the cursor fetcher. +set timescaledb.remote_data_fetcher = 'cursor'; +explain (analyze, verbose, costs off, timing off, summary off) +select 1 from metrics_dist_remote_error where ts_debug_shippable_error_after_n_rows(0, device_id)::int != 0; +ERROR: []: debug point: requested to error out after 0 rows, 1 rows seen +explain (analyze, verbose, costs off, timing off, summary off) +select 1 from metrics_dist_remote_error where ts_debug_shippable_error_after_n_rows(1, device_id)::int != 0; +ERROR: []: debug point: requested to error out after 1 rows, 1 rows seen +explain (analyze, verbose, costs off, timing off, summary off) +select 1 from metrics_dist_remote_error where ts_debug_shippable_error_after_n_rows(2, device_id)::int != 0; +ERROR: []: debug point: requested to error out after 2 rows, 2 rows seen +explain (analyze, verbose, costs off, timing off, summary off) +select 1 from metrics_dist_remote_error where ts_debug_shippable_error_after_n_rows(701, device_id)::int != 0; +ERROR: []: debug point: requested to error out after 701 rows, 701 rows seen +explain (analyze, verbose, costs off, timing off, summary off) +select 1 from metrics_dist_remote_error where ts_debug_shippable_error_after_n_rows(10000, device_id)::int != 0; +ERROR: []: debug point: requested to error out after 10000 rows, 10000 rows seen +explain (analyze, verbose, costs off, timing off, summary off) +select 1 from metrics_dist_remote_error where ts_debug_shippable_error_after_n_rows(10000000, device_id)::int != 0; +QUERY PLAN + Custom Scan (DataNodeScan) on public.metrics_dist_remote_error (actual rows=20000 loops=1) + Output: 1 + Data node: data_node_1 + Fetcher Type: Cursor + Chunks: _dist_hyper_X_X_chunk, _dist_hyper_X_X_chunk + Remote SQL: SELECT NULL FROM public.metrics_dist_remote_error WHERE _timescaledb_internal.chunks_in(public.metrics_dist_remote_error.*, ARRAY[..]) AND ((public.ts_debug_shippable_error_after_n_rows(10000000, device_id) <> 0)) +(6 rows) + +-- Table with broken send for a data type. +create table metrics_dist_bs(like metrics_dist); +alter table metrics_dist_bs alter column v0 type bs; +select table_name from create_distributed_hypertable('metrics_dist_bs', + 'time', 'device_id'); + table_name + metrics_dist_bs +(1 row) + +set timescaledb.enable_connection_binary_data to off; +insert into metrics_dist_bs + select * from metrics_dist_remote_error; +set timescaledb.enable_connection_binary_data to on; +explain (analyze, verbose, costs off, timing off, summary off) +select * from metrics_dist_bs; +ERROR: []: debug point: requested to error out after 7103 rows, 7103 rows seen +drop table metrics_dist_bs; +-- Table with broken receive for a data type. +create table metrics_dist_br(like metrics_dist); +alter table metrics_dist_br alter column v0 type br; +select table_name from create_distributed_hypertable('metrics_dist_br', + 'time', 'device_id'); + table_name + metrics_dist_br +(1 row) + +select hypertable_name, replication_factor from timescaledb_information.hypertables +where hypertable_name = 'metrics_dist_br'; + hypertable_name | replication_factor +-----------------+-------------------- + metrics_dist_br | 1 +(1 row) + +-- Test that INSERT and COPY fail on data nodes. +-- Note that we use the text format for the COPY input, so that the access node +-- doesn't call `recv` and fail by itself. It's going to use binary format for +-- transfer to data nodes regardless of the input format. +set timescaledb.dist_copy_transfer_format = 'binary'; +-- First, create the reference. +\copy (select * from metrics_dist_remote_error) to 'dist_remote_error.text' with (format text); +-- We have to test various interleavings of COPY and INSERT to check that +-- one can recover from connection failure states introduced by another. +\copy metrics_dist_br from 'dist_remote_error.text' with (format text); +ERROR: []: debug point: requested to error out after 7103 rows, 7103 rows seen +\copy metrics_dist_br from 'dist_remote_error.text' with (format text); +ERROR: []: debug point: requested to error out after 7103 rows, 7103 rows seen +insert into metrics_dist_br select * from metrics_dist_remote_error; +ERROR: []: debug point: requested to error out after 7103 rows, 7103 rows seen +insert into metrics_dist_br select * from metrics_dist_remote_error; +ERROR: []: debug point: requested to error out after 7103 rows, 7103 rows seen +\copy metrics_dist_br from 'dist_remote_error.text' with (format text); +ERROR: []: debug point: requested to error out after 7103 rows, 7103 rows seen +-- Fail at different points +set timescaledb.debug_broken_sendrecv_throw_after = 1; +\copy metrics_dist_br from 'dist_remote_error.text' with (format text); +ERROR: []: debug point: requested to error out after 1 rows, 1 rows seen +set timescaledb.debug_broken_sendrecv_throw_after = 2; +\copy metrics_dist_br from 'dist_remote_error.text' with (format text); +ERROR: []: debug point: requested to error out after 2 rows, 2 rows seen +set timescaledb.debug_broken_sendrecv_throw_after = 1023; +\copy metrics_dist_br from 'dist_remote_error.text' with (format text); +ERROR: []: debug point: requested to error out after 1023 rows, 1023 rows seen +set timescaledb.debug_broken_sendrecv_throw_after = 1024; +\copy metrics_dist_br from 'dist_remote_error.text' with (format text); +ERROR: []: debug point: requested to error out after 1024 rows, 1024 rows seen +set timescaledb.debug_broken_sendrecv_throw_after = 1025; +\copy metrics_dist_br from 'dist_remote_error.text' with (format text); +ERROR: []: debug point: requested to error out after 1025 rows, 1025 rows seen +reset timescaledb.debug_broken_sendrecv_throw_after; +-- Same with different replication factor +truncate metrics_dist_br; +select set_replication_factor('metrics_dist_br', 2); + set_replication_factor + +(1 row) + +select hypertable_name, replication_factor from timescaledb_information.hypertables +where hypertable_name = 'metrics_dist_br'; + hypertable_name | replication_factor +-----------------+-------------------- + metrics_dist_br | 2 +(1 row) + +\copy metrics_dist_br from 'dist_remote_error.text' with (format text); +ERROR: []: debug point: requested to error out after 7103 rows, 7103 rows seen +\copy metrics_dist_br from 'dist_remote_error.text' with (format text); +ERROR: []: debug point: requested to error out after 7103 rows, 7103 rows seen +insert into metrics_dist_br select * from metrics_dist_remote_error; +ERROR: []: debug point: requested to error out after 7103 rows, 7103 rows seen +insert into metrics_dist_br select * from metrics_dist_remote_error; +ERROR: []: debug point: requested to error out after 7103 rows, 7103 rows seen +set timescaledb.debug_broken_sendrecv_throw_after = 1; +\copy metrics_dist_br from 'dist_remote_error.text' with (format text); +ERROR: []: debug point: requested to error out after 1 rows, 1 rows seen +set timescaledb.debug_broken_sendrecv_throw_after = 2; +\copy metrics_dist_br from 'dist_remote_error.text' with (format text); +ERROR: []: debug point: requested to error out after 2 rows, 2 rows seen +set timescaledb.debug_broken_sendrecv_throw_after = 1023; +\copy metrics_dist_br from 'dist_remote_error.text' with (format text); +ERROR: []: debug point: requested to error out after 1023 rows, 1023 rows seen +set timescaledb.debug_broken_sendrecv_throw_after = 1024; +\copy metrics_dist_br from 'dist_remote_error.text' with (format text); +ERROR: []: debug point: requested to error out after 1024 rows, 1024 rows seen +set timescaledb.debug_broken_sendrecv_throw_after = 1025; +\copy metrics_dist_br from 'dist_remote_error.text' with (format text); +ERROR: []: debug point: requested to error out after 1025 rows, 1025 rows seen +-- Should succeed with text format for data transfer. +set timescaledb.dist_copy_transfer_format = 'text'; +\copy metrics_dist_br from 'dist_remote_error.text' with (format text); +-- Final check. +set timescaledb.enable_connection_binary_data = false; +select count(*) from metrics_dist_br; + count + 20000 +(1 row) + +set timescaledb.enable_connection_binary_data = true; +reset timescaledb.debug_broken_sendrecv_throw_after; +drop table metrics_dist_br; +-- Table with sleepy receive for a data type, to improve coverage of the waiting +-- code on the access node. +create table metrics_dist_bl(like metrics_dist); +alter table metrics_dist_bl alter column v0 type bl; +select table_name from create_distributed_hypertable('metrics_dist_bl', + 'time', 'device_id'); + table_name + metrics_dist_bl +(1 row) + +-- We're using sleepy recv function, so need the binary transfer format for it +-- to be called on the data nodes. +set timescaledb.dist_copy_transfer_format = 'binary'; +-- Test INSERT and COPY with slow data node. +\copy metrics_dist_bl from 'dist_remote_error.text' with (format text); +insert into metrics_dist_bl select * from metrics_dist_remote_error; +select count(*) from metrics_dist_bl; + count + 40000 +(1 row) + +drop table metrics_dist_bl; +drop table metrics_dist_remote_error; diff --git a/tsl/test/shared/expected/dist_remote_error-15.out b/tsl/test/shared/expected/dist_remote_error-15.out new file mode 100644 index 00000000000..007beacda86 --- /dev/null +++ b/tsl/test/shared/expected/dist_remote_error-15.out @@ -0,0 +1,231 @@ +-- This file and its contents are licensed under the Timescale License. +-- Please see the included NOTICE for copyright information and +-- LICENSE-TIMESCALE for a copy of the license. +-- Import setup file to data nodes. +\unset ECHO +-- Disable SSL to get stable error output across versions. SSL adds some output +-- that changed in PG 14. +set timescaledb.debug_enable_ssl to off; +set client_min_messages to error; +SET timescaledb.hide_data_node_name_in_errors = 'on'; +-- A relatively big table on one data node +create table metrics_dist_remote_error(like metrics_dist); +select table_name from create_distributed_hypertable('metrics_dist_remote_error', 'time', 'device_id', + data_nodes => '{"data_node_1"}'); + table_name + metrics_dist_remote_error +(1 row) + +insert into metrics_dist_remote_error select * from metrics_dist order by metrics_dist limit 20000; +-- The error messages vary wildly between the Postgres versions, dependent on +-- the particular behavior of libqp in this or that case. The purpose of this +-- test is not to solidify this accidental behavior, but to merely exercise the +-- error handling code to make sure it doesn't have fatal errors. Unfortunately, +-- there is no way to suppress error output from a psql script. +set client_min_messages to ERROR; +\set ON_ERROR_STOP off +set timescaledb.remote_data_fetcher = 'copy'; +explain (analyze, verbose, costs off, timing off, summary off) +select 1 from metrics_dist_remote_error where ts_debug_shippable_error_after_n_rows(0, device_id)::int != 0; +ERROR: []: debug point: requested to error out after 0 rows, 1 rows seen +explain (analyze, verbose, costs off, timing off, summary off) +select 1 from metrics_dist_remote_error where ts_debug_shippable_error_after_n_rows(1, device_id)::int != 0; +ERROR: []: debug point: requested to error out after 1 rows, 1 rows seen +explain (analyze, verbose, costs off, timing off, summary off) +select 1 from metrics_dist_remote_error where ts_debug_shippable_error_after_n_rows(2, device_id)::int != 0; +ERROR: []: debug point: requested to error out after 2 rows, 2 rows seen +explain (analyze, verbose, costs off, timing off, summary off) +select 1 from metrics_dist_remote_error where ts_debug_shippable_error_after_n_rows(701, device_id)::int != 0; +ERROR: []: debug point: requested to error out after 701 rows, 701 rows seen +explain (analyze, verbose, costs off, timing off, summary off) +select 1 from metrics_dist_remote_error where ts_debug_shippable_error_after_n_rows(10000, device_id)::int != 0; +ERROR: []: debug point: requested to error out after 10000 rows, 10000 rows seen +explain (analyze, verbose, costs off, timing off, summary off) +select 1 from metrics_dist_remote_error where ts_debug_shippable_error_after_n_rows(16384, device_id)::int != 0; +ERROR: []: debug point: requested to error out after 16384 rows, 16384 rows seen +explain (analyze, verbose, costs off, timing off, summary off) +select 1 from metrics_dist_remote_error where ts_debug_shippable_error_after_n_rows(10000000, device_id)::int != 0; +QUERY PLAN + Result (actual rows=20000 loops=1) + Output: 1 + -> Custom Scan (DataNodeScan) on public.metrics_dist_remote_error (actual rows=20000 loops=1) + Data node: data_node_1 + Fetcher Type: COPY + Chunks: _dist_hyper_X_X_chunk, _dist_hyper_X_X_chunk + Remote SQL: SELECT NULL FROM public.metrics_dist_remote_error WHERE _timescaledb_internal.chunks_in(public.metrics_dist_remote_error.*, ARRAY[..]) AND ((public.ts_debug_shippable_error_after_n_rows(10000000, device_id) <> 0)) +(7 rows) + +-- We don't test fatal errors here, because PG versions before 14 are unable to +-- report them properly to the access node, so we get different errors in these +-- versions. +-- Now test the same with the cursor fetcher. +set timescaledb.remote_data_fetcher = 'cursor'; +explain (analyze, verbose, costs off, timing off, summary off) +select 1 from metrics_dist_remote_error where ts_debug_shippable_error_after_n_rows(0, device_id)::int != 0; +ERROR: []: debug point: requested to error out after 0 rows, 1 rows seen +explain (analyze, verbose, costs off, timing off, summary off) +select 1 from metrics_dist_remote_error where ts_debug_shippable_error_after_n_rows(1, device_id)::int != 0; +ERROR: []: debug point: requested to error out after 1 rows, 1 rows seen +explain (analyze, verbose, costs off, timing off, summary off) +select 1 from metrics_dist_remote_error where ts_debug_shippable_error_after_n_rows(2, device_id)::int != 0; +ERROR: []: debug point: requested to error out after 2 rows, 2 rows seen +explain (analyze, verbose, costs off, timing off, summary off) +select 1 from metrics_dist_remote_error where ts_debug_shippable_error_after_n_rows(701, device_id)::int != 0; +ERROR: []: debug point: requested to error out after 701 rows, 701 rows seen +explain (analyze, verbose, costs off, timing off, summary off) +select 1 from metrics_dist_remote_error where ts_debug_shippable_error_after_n_rows(10000, device_id)::int != 0; +ERROR: []: debug point: requested to error out after 10000 rows, 10000 rows seen +explain (analyze, verbose, costs off, timing off, summary off) +select 1 from metrics_dist_remote_error where ts_debug_shippable_error_after_n_rows(10000000, device_id)::int != 0; +QUERY PLAN + Result (actual rows=20000 loops=1) + Output: 1 + -> Custom Scan (DataNodeScan) on public.metrics_dist_remote_error (actual rows=20000 loops=1) + Data node: data_node_1 + Fetcher Type: Cursor + Chunks: _dist_hyper_X_X_chunk, _dist_hyper_X_X_chunk + Remote SQL: SELECT NULL FROM public.metrics_dist_remote_error WHERE _timescaledb_internal.chunks_in(public.metrics_dist_remote_error.*, ARRAY[..]) AND ((public.ts_debug_shippable_error_after_n_rows(10000000, device_id) <> 0)) +(7 rows) + +-- Table with broken send for a data type. +create table metrics_dist_bs(like metrics_dist); +alter table metrics_dist_bs alter column v0 type bs; +select table_name from create_distributed_hypertable('metrics_dist_bs', + 'time', 'device_id'); + table_name + metrics_dist_bs +(1 row) + +set timescaledb.enable_connection_binary_data to off; +insert into metrics_dist_bs + select * from metrics_dist_remote_error; +set timescaledb.enable_connection_binary_data to on; +explain (analyze, verbose, costs off, timing off, summary off) +select * from metrics_dist_bs; +ERROR: []: debug point: requested to error out after 7103 rows, 7103 rows seen +drop table metrics_dist_bs; +-- Table with broken receive for a data type. +create table metrics_dist_br(like metrics_dist); +alter table metrics_dist_br alter column v0 type br; +select table_name from create_distributed_hypertable('metrics_dist_br', + 'time', 'device_id'); + table_name + metrics_dist_br +(1 row) + +select hypertable_name, replication_factor from timescaledb_information.hypertables +where hypertable_name = 'metrics_dist_br'; + hypertable_name | replication_factor +-----------------+-------------------- + metrics_dist_br | 1 +(1 row) + +-- Test that INSERT and COPY fail on data nodes. +-- Note that we use the text format for the COPY input, so that the access node +-- doesn't call `recv` and fail by itself. It's going to use binary format for +-- transfer to data nodes regardless of the input format. +set timescaledb.dist_copy_transfer_format = 'binary'; +-- First, create the reference. +\copy (select * from metrics_dist_remote_error) to 'dist_remote_error.text' with (format text); +-- We have to test various interleavings of COPY and INSERT to check that +-- one can recover from connection failure states introduced by another. +\copy metrics_dist_br from 'dist_remote_error.text' with (format text); +ERROR: []: debug point: requested to error out after 7103 rows, 7103 rows seen +\copy metrics_dist_br from 'dist_remote_error.text' with (format text); +ERROR: []: debug point: requested to error out after 7103 rows, 7103 rows seen +insert into metrics_dist_br select * from metrics_dist_remote_error; +ERROR: []: debug point: requested to error out after 7103 rows, 7103 rows seen +insert into metrics_dist_br select * from metrics_dist_remote_error; +ERROR: []: debug point: requested to error out after 7103 rows, 7103 rows seen +\copy metrics_dist_br from 'dist_remote_error.text' with (format text); +ERROR: []: debug point: requested to error out after 7103 rows, 7103 rows seen +-- Fail at different points +set timescaledb.debug_broken_sendrecv_throw_after = 1; +\copy metrics_dist_br from 'dist_remote_error.text' with (format text); +ERROR: []: debug point: requested to error out after 1 rows, 1 rows seen +set timescaledb.debug_broken_sendrecv_throw_after = 2; +\copy metrics_dist_br from 'dist_remote_error.text' with (format text); +ERROR: []: debug point: requested to error out after 2 rows, 2 rows seen +set timescaledb.debug_broken_sendrecv_throw_after = 1023; +\copy metrics_dist_br from 'dist_remote_error.text' with (format text); +ERROR: []: debug point: requested to error out after 1023 rows, 1023 rows seen +set timescaledb.debug_broken_sendrecv_throw_after = 1024; +\copy metrics_dist_br from 'dist_remote_error.text' with (format text); +ERROR: []: debug point: requested to error out after 1024 rows, 1024 rows seen +set timescaledb.debug_broken_sendrecv_throw_after = 1025; +\copy metrics_dist_br from 'dist_remote_error.text' with (format text); +ERROR: []: debug point: requested to error out after 1025 rows, 1025 rows seen +reset timescaledb.debug_broken_sendrecv_throw_after; +-- Same with different replication factor +truncate metrics_dist_br; +select set_replication_factor('metrics_dist_br', 2); + set_replication_factor + +(1 row) + +select hypertable_name, replication_factor from timescaledb_information.hypertables +where hypertable_name = 'metrics_dist_br'; + hypertable_name | replication_factor +-----------------+-------------------- + metrics_dist_br | 2 +(1 row) + +\copy metrics_dist_br from 'dist_remote_error.text' with (format text); +ERROR: []: debug point: requested to error out after 7103 rows, 7103 rows seen +\copy metrics_dist_br from 'dist_remote_error.text' with (format text); +ERROR: []: debug point: requested to error out after 7103 rows, 7103 rows seen +insert into metrics_dist_br select * from metrics_dist_remote_error; +ERROR: []: debug point: requested to error out after 7103 rows, 7103 rows seen +insert into metrics_dist_br select * from metrics_dist_remote_error; +ERROR: []: debug point: requested to error out after 7103 rows, 7103 rows seen +set timescaledb.debug_broken_sendrecv_throw_after = 1; +\copy metrics_dist_br from 'dist_remote_error.text' with (format text); +ERROR: []: debug point: requested to error out after 1 rows, 1 rows seen +set timescaledb.debug_broken_sendrecv_throw_after = 2; +\copy metrics_dist_br from 'dist_remote_error.text' with (format text); +ERROR: []: debug point: requested to error out after 2 rows, 2 rows seen +set timescaledb.debug_broken_sendrecv_throw_after = 1023; +\copy metrics_dist_br from 'dist_remote_error.text' with (format text); +ERROR: []: debug point: requested to error out after 1023 rows, 1023 rows seen +set timescaledb.debug_broken_sendrecv_throw_after = 1024; +\copy metrics_dist_br from 'dist_remote_error.text' with (format text); +ERROR: []: debug point: requested to error out after 1024 rows, 1024 rows seen +set timescaledb.debug_broken_sendrecv_throw_after = 1025; +\copy metrics_dist_br from 'dist_remote_error.text' with (format text); +ERROR: []: debug point: requested to error out after 1025 rows, 1025 rows seen +-- Should succeed with text format for data transfer. +set timescaledb.dist_copy_transfer_format = 'text'; +\copy metrics_dist_br from 'dist_remote_error.text' with (format text); +-- Final check. +set timescaledb.enable_connection_binary_data = false; +select count(*) from metrics_dist_br; + count + 20000 +(1 row) + +set timescaledb.enable_connection_binary_data = true; +reset timescaledb.debug_broken_sendrecv_throw_after; +drop table metrics_dist_br; +-- Table with sleepy receive for a data type, to improve coverage of the waiting +-- code on the access node. +create table metrics_dist_bl(like metrics_dist); +alter table metrics_dist_bl alter column v0 type bl; +select table_name from create_distributed_hypertable('metrics_dist_bl', + 'time', 'device_id'); + table_name + metrics_dist_bl +(1 row) + +-- We're using sleepy recv function, so need the binary transfer format for it +-- to be called on the data nodes. +set timescaledb.dist_copy_transfer_format = 'binary'; +-- Test INSERT and COPY with slow data node. +\copy metrics_dist_bl from 'dist_remote_error.text' with (format text); +insert into metrics_dist_bl select * from metrics_dist_remote_error; +select count(*) from metrics_dist_bl; + count + 40000 +(1 row) + +drop table metrics_dist_bl; +drop table metrics_dist_remote_error; diff --git a/tsl/test/shared/sql/CMakeLists.txt b/tsl/test/shared/sql/CMakeLists.txt index d8f8b43ce6a..f81c2ac613d 100644 --- a/tsl/test/shared/sql/CMakeLists.txt +++ b/tsl/test/shared/sql/CMakeLists.txt @@ -27,9 +27,10 @@ if((${PG_VERSION_MAJOR} GREATER_EQUAL "14")) endif() if(CMAKE_BUILD_TYPE MATCHES Debug) - list(APPEND TEST_FILES_SHARED dist_parallel_agg.sql dist_remote_error.sql - timestamp_limits.sql with_clause_parser.sql) - list(APPEND TEST_TEMPLATES_SHARED constify_now.sql.in space_constraint.sql.in) + list(APPEND TEST_FILES_SHARED dist_parallel_agg.sql timestamp_limits.sql + with_clause_parser.sql) + list(APPEND TEST_TEMPLATES_SHARED constify_now.sql.in space_constraint.sql.in + dist_remote_error.sql.in) endif(CMAKE_BUILD_TYPE MATCHES Debug) # Regression tests that vary with PostgreSQL version. Generated test files are diff --git a/tsl/test/shared/sql/dist_remote_error.sql b/tsl/test/shared/sql/dist_remote_error.sql.in similarity index 100% rename from tsl/test/shared/sql/dist_remote_error.sql rename to tsl/test/shared/sql/dist_remote_error.sql.in