From 43c8e51510b274a648f6919d183d44cfa6d7ce6d Mon Sep 17 00:00:00 2001 From: Sven Klemm Date: Thu, 19 May 2022 08:03:50 +0200 Subject: [PATCH] Fix Var handling for Vars of different level in constify_now This patch fixes the constify_now optimization to ignore Vars of different level. Previously this could potentially lead to an assertion failure cause the varno of that varno might be bigger than the number of entries in the rangetable. Found by sqlsmith. --- src/planner/constify_now.c | 2 ++ src/planner/planner.c | 2 +- tsl/test/shared/expected/constify_now-12.out | 18 ++++++++++++++++++ tsl/test/shared/expected/constify_now-13.out | 18 ++++++++++++++++++ tsl/test/shared/expected/constify_now-14.out | 18 ++++++++++++++++++ tsl/test/shared/sql/constify_now.sql.in | 9 +++++++++ 6 files changed, 66 insertions(+), 1 deletion(-) diff --git a/src/planner/constify_now.c b/src/planner/constify_now.c index 787fe7010..cdc4d50af 100644 --- a/src/planner/constify_now.c +++ b/src/planner/constify_now.c @@ -60,6 +60,8 @@ is_valid_now_expr(OpExpr *op, List *rtable) * because that will be the time column. */ Var *var = linitial_node(Var, op->args); + if (var->varlevelsup != 0) + return false; Assert(var->varno <= list_length(rtable)); RangeTblEntry *rte = list_nth(rtable, var->varno - 1); diff --git a/src/planner/planner.c b/src/planner/planner.c index 6f6c23ce1..bb8824662 100644 --- a/src/planner/planner.c +++ b/src/planner/planner.c @@ -293,7 +293,7 @@ preprocess_query(Node *node, PreprocessQueryContext *context) if (node == NULL) return false; - if (ts_guc_enable_now_constify && IsA(node, FromExpr)) + if (IsA(node, FromExpr) && ts_guc_enable_optimizations && ts_guc_enable_now_constify) { FromExpr *from = castNode(FromExpr, node); if (from->quals) diff --git a/tsl/test/shared/expected/constify_now-12.out b/tsl/test/shared/expected/constify_now-12.out index 15fde5b0a..026657d2f 100644 --- a/tsl/test/shared/expected/constify_now-12.out +++ b/tsl/test/shared/expected/constify_now-12.out @@ -469,3 +469,21 @@ EXECUTE p1; (2 rows) DROP TABLE prep_const_now; +-- test outer var references dont trip up constify_now +-- no optimization is done in this case +:PREFIX SELECT * FROM + metrics_tstz m1 + INNER JOIN metrics_tstz as m2 on (true) +WHERE + EXISTS (SELECT * FROM metrics_tstz AS m3 WHERE m2.time > now()); +QUERY PLAN + Nested Loop + -> Seq Scan on _hyper_X_X_chunk m1 + -> Materialize + -> Nested Loop Semi Join + -> Index Scan using _hyper_X_X_chunk_metrics_tstz_time_idx on _hyper_X_X_chunk m2 + Index Cond: ("time" > now()) + -> Materialize + -> Seq Scan on _hyper_X_X_chunk m3 +(8 rows) + diff --git a/tsl/test/shared/expected/constify_now-13.out b/tsl/test/shared/expected/constify_now-13.out index e58454f4d..bd3b050db 100644 --- a/tsl/test/shared/expected/constify_now-13.out +++ b/tsl/test/shared/expected/constify_now-13.out @@ -469,3 +469,21 @@ EXECUTE p1; (2 rows) DROP TABLE prep_const_now; +-- test outer var references dont trip up constify_now +-- no optimization is done in this case +:PREFIX SELECT * FROM + metrics_tstz m1 + INNER JOIN metrics_tstz as m2 on (true) +WHERE + EXISTS (SELECT * FROM metrics_tstz AS m3 WHERE m2.time > now()); +QUERY PLAN + Nested Loop + -> Seq Scan on _hyper_X_X_chunk m1 + -> Materialize + -> Nested Loop Semi Join + -> Index Scan using _hyper_X_X_chunk_metrics_tstz_time_idx on _hyper_X_X_chunk m2 + Index Cond: ("time" > now()) + -> Materialize + -> Seq Scan on _hyper_X_X_chunk m3 +(8 rows) + diff --git a/tsl/test/shared/expected/constify_now-14.out b/tsl/test/shared/expected/constify_now-14.out index 21b082141..fcd8276e7 100644 --- a/tsl/test/shared/expected/constify_now-14.out +++ b/tsl/test/shared/expected/constify_now-14.out @@ -468,3 +468,21 @@ EXECUTE p1; (2 rows) DROP TABLE prep_const_now; +-- test outer var references dont trip up constify_now +-- no optimization is done in this case +:PREFIX SELECT * FROM + metrics_tstz m1 + INNER JOIN metrics_tstz as m2 on (true) +WHERE + EXISTS (SELECT * FROM metrics_tstz AS m3 WHERE m2.time > now()); +QUERY PLAN + Nested Loop + -> Seq Scan on _hyper_X_X_chunk m1 + -> Materialize + -> Nested Loop Semi Join + -> Index Scan using _hyper_X_X_chunk_metrics_tstz_time_idx on _hyper_X_X_chunk m2 + Index Cond: ("time" > now()) + -> Materialize + -> Seq Scan on _hyper_X_X_chunk m3 +(8 rows) + diff --git a/tsl/test/shared/sql/constify_now.sql.in b/tsl/test/shared/sql/constify_now.sql.in index b5f5b7df7..454e1eb5a 100644 --- a/tsl/test/shared/sql/constify_now.sql.in +++ b/tsl/test/shared/sql/constify_now.sql.in @@ -104,3 +104,12 @@ SET timescaledb.current_timestamp_mock TO '3002-01-01'; EXECUTE p1; DROP TABLE prep_const_now; + +-- test outer var references dont trip up constify_now +-- no optimization is done in this case +:PREFIX SELECT * FROM + metrics_tstz m1 + INNER JOIN metrics_tstz as m2 on (true) +WHERE + EXISTS (SELECT * FROM metrics_tstz AS m3 WHERE m2.time > now()); +