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.
This commit is contained in:
Sven Klemm 2022-05-19 08:03:50 +02:00 committed by Sven Klemm
parent 5193af7396
commit 43c8e51510
6 changed files with 66 additions and 1 deletions

View File

@ -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);

View File

@ -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)

View File

@ -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)

View File

@ -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)

View File

@ -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)

View File

@ -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());