diff --git a/tsl/src/nodes/decompress_chunk/compressed_batch.c b/tsl/src/nodes/decompress_chunk/compressed_batch.c index 326a031f5d6..576c59f9010 100644 --- a/tsl/src/nodes/decompress_chunk/compressed_batch.c +++ b/tsl/src/nodes/decompress_chunk/compressed_batch.c @@ -103,6 +103,8 @@ apply_vector_quals(DecompressChunkState *chunk_state, DecompressBatchState *batc /* For now we only support "Var ? Const" predicates. */ OpExpr *oe = castNode(OpExpr, lfirst(lc)); Var *var = castNode(Var, linitial(oe->args)); + Ensure(IsA(lsecond(oe->args), Const), + "failed to evaluate runtime constant in vectorized filter"); Const *constnode = castNode(Const, lsecond(oe->args)); /* diff --git a/tsl/src/nodes/decompress_chunk/exec.c b/tsl/src/nodes/decompress_chunk/exec.c index 2a6cec9de60..b94dc44b255 100644 --- a/tsl/src/nodes/decompress_chunk/exec.c +++ b/tsl/src/nodes/decompress_chunk/exec.c @@ -11,6 +11,7 @@ #include #include #include +#include #include #include #include @@ -479,6 +480,19 @@ decompress_chunk_begin(CustomScanState *node, EState *estate, int eflags) { elog(ERROR, "debug: batch sorted merge is required but not used"); } + + /* Constify stable expressions in vectorized predicates. */ + PlannerGlobal glob = { + .boundParams = node->ss.ps.state->es_param_list_info, + }; + PlannerInfo root = { + .glob = &glob, + }; + ListCell *lc; + foreach (lc, chunk_state->vectorized_quals) + { + lfirst(lc) = estimate_expression_value(&root, (Node *) lfirst(lc)); + } } /* diff --git a/tsl/src/nodes/decompress_chunk/planner.c b/tsl/src/nodes/decompress_chunk/planner.c index 443c4345ea4..3405628ea32 100644 --- a/tsl/src/nodes/decompress_chunk/planner.c +++ b/tsl/src/nodes/decompress_chunk/planner.c @@ -391,6 +391,43 @@ find_attr_pos_in_tlist(List *targetlist, AttrNumber pos) pg_unreachable(); } +static bool +contains_volatile_functions_checker(Oid func_id, void *context) +{ + return (func_volatile(func_id) == PROVOLATILE_VOLATILE); +} + +static bool +is_not_runtime_constant_walker(Node *node, void *context) +{ + switch (nodeTag(node)) + { + case T_Var: + case T_Param: + case T_PlaceHolderVar: + return true; + default: + if (check_functions_in_node(node, + contains_volatile_functions_checker, + /* context = */ NULL)) + { + return true; + } + return expression_tree_walker(node, + is_not_runtime_constant_walker, + /* context = */ NULL); + } +} + +static bool +is_not_runtime_constant(Node *node) +{ + bool result = expression_tree_walker(node, + is_not_runtime_constant_walker, + /* context = */ NULL); + return result; +} + static bool qual_is_vectorizable(DecompressChunkPath *path, Node *qual) { @@ -407,7 +444,7 @@ qual_is_vectorizable(DecompressChunkPath *path, Node *qual) return false; } - if (IsA(lsecond(o->args), Var) && IsA(linitial(o->args), Const)) + if (IsA(lsecond(o->args), Var)) { /* Try to commute the operator if the constant is on the right. */ Oid commutator_opno = get_commutator(o->opno); @@ -423,7 +460,7 @@ qual_is_vectorizable(DecompressChunkPath *path, Node *qual) } } - if (!IsA(linitial(o->args), Var) || !IsA(lsecond(o->args), Const)) + if (!IsA(linitial(o->args), Var) || is_not_runtime_constant(lsecond(o->args))) { return false; }