From 46008e62d95774f5f20a54af1d0173a53affda54 Mon Sep 17 00:00:00 2001 From: liuxiaoyu Date: Tue, 7 Apr 2026 10:09:13 +0800 Subject: [PATCH 1/4] fix: support filter pushdown for numeric columns with integer constants When a numeric column is compared with an integer constant (e.g., biz_dt = 20260331), PostgreSQL wraps the constant in an implicit type cast FuncExpr (int4 -> numeric). The filter extraction code only recognized plain Const nodes, causing these filters to be dropped and resulting in full table scans on the source. Use eval_const_expressions() to evaluate implicit cast expressions back to plain Const nodes before filter extraction. --- fdw/pxf_filter.c | 19 +++ .../expected/FDW_FilterPushDownTest.out | 110 +++++++++++++++++- regression/expected/FilterPushDownTest.out | 110 +++++++++++++++++- regression/sql/FDW_FilterPushDownTest.sql | 14 +++ regression/sql/FilterPushDownTest.sql | 7 ++ 5 files changed, 256 insertions(+), 4 deletions(-) diff --git a/fdw/pxf_filter.c b/fdw/pxf_filter.c index b57575cfa..b33313c6c 100644 --- a/fdw/pxf_filter.c +++ b/fdw/pxf_filter.c @@ -852,6 +852,25 @@ OpExprToPxfFilter(OpExpr *expr, PxfFilterDesc *filter) } } + /* + * Try to evaluate constant expressions in operands. + * This handles implicit type casts where PostgreSQL wraps a constant + * in a FuncExpr (e.g., int4 -> numeric cast when comparing a numeric + * column with an integer constant). Evaluating these gives us back a + * plain Const node that we can serialize for filter pushdown. + */ + if (!IsA(leftop, Var) && !IsA(leftop, Const)) + { + Node *simplified = eval_const_expressions(NULL, leftop); + if (IsA(simplified, Const)) + leftop = simplified; + } + if (!IsA(rightop, Var) && !IsA(rightop, Const)) + { + Node *simplified = eval_const_expressions(NULL, rightop); + if (IsA(simplified, Const)) + rightop = simplified; + } /* arguments must be VAR and CONST */ if (IsA(leftop, Var) && IsA(rightop, Const)) diff --git a/regression/expected/FDW_FilterPushDownTest.out b/regression/expected/FDW_FilterPushDownTest.out index 172ede4d4..b61bcad4f 100644 --- a/regression/expected/FDW_FilterPushDownTest.out +++ b/regression/expected/FDW_FilterPushDownTest.out @@ -486,9 +486,62 @@ SELECT * FROM test_filter WHERE c3 IS NOT NULL ORDER BY t0, a1; | 0 | t | 0.01 | AA | AA | a3o9 (9 rows) +-- test numeric predicates with integer constant (cross-type pushdown) +SELECT * FROM test_filter WHERE c3 > 1 ORDER BY t0, a1; + t0 | a1 | b2 | c3 | d4 | e5 | filtervalue +----+----+----+------+----+----+---------------- + B | | f | 1.11 | BB | BB | a3c1700s1d1o2 + C | 2 | | 2.21 | CC | CC | a3c1700s1d1o2 + E | 4 | t | 4.41 | | EE | a3c1700s1d1o2 + F | 5 | f | 5.51 | FF | | a3c1700s1d1o2 + G | 6 | t | 6.61 | GG | GG | a3c1700s1d1o2 + H | 7 | f | 7.71 | HH | HH | a3c1700s1d1o2 + I | 8 | t | 8.81 | II | II | a3c1700s1d1o2 + J | 9 | f | 9.91 | JJ | JJ | a3c1700s1d1o2 +(8 rows) + +SELECT * FROM test_filter WHERE c3 <= 2 ORDER BY t0, a1; + t0 | a1 | b2 | c3 | d4 | e5 | filtervalue +----+----+----+------+----+----+---------------- + B | | f | 1.11 | BB | BB | a3c1700s1d2o3 + | 0 | t | 0.01 | AA | AA | a3c1700s1d2o3 +(2 rows) + +SELECT * FROM test_filter WHERE c3 >= 5 ORDER BY t0, a1; + t0 | a1 | b2 | c3 | d4 | e5 | filtervalue +----+----+----+------+----+----+---------------- + F | 5 | f | 5.51 | FF | | a3c1700s1d5o4 + G | 6 | t | 6.61 | GG | GG | a3c1700s1d5o4 + H | 7 | f | 7.71 | HH | HH | a3c1700s1d5o4 + I | 8 | t | 8.81 | II | II | a3c1700s1d5o4 + J | 9 | f | 9.91 | JJ | JJ | a3c1700s1d5o4 +(5 rows) + +SELECT * FROM test_filter WHERE c3 <> 5 ORDER BY t0, a1; + t0 | a1 | b2 | c3 | d4 | e5 | filtervalue +----+----+----+------+----+----+---------------- + B | | f | 1.11 | BB | BB | a3c1700s1d5o6 + C | 2 | | 2.21 | CC | CC | a3c1700s1d5o6 + E | 4 | t | 4.41 | | EE | a3c1700s1d5o6 + F | 5 | f | 5.51 | FF | | a3c1700s1d5o6 + G | 6 | t | 6.61 | GG | GG | a3c1700s1d5o6 + H | 7 | f | 7.71 | HH | HH | a3c1700s1d5o6 + I | 8 | t | 8.81 | II | II | a3c1700s1d5o6 + J | 9 | f | 9.91 | JJ | JJ | a3c1700s1d5o6 + | 0 | t | 0.01 | AA | AA | a3c1700s1d5o6 +(9 rows) + +SELECT * FROM test_filter WHERE c3 BETWEEN 1 AND 5 ORDER BY t0, a1; + t0 | a1 | b2 | c3 | d4 | e5 | filtervalue +----+----+----+------+----+----+------------------------------------ + B | | f | 1.11 | BB | BB | a3c1700s1d1o4a3c1700s1d5o3l0 + C | 2 | | 2.21 | CC | CC | a3c1700s1d1o4a3c1700s1d5o3l0 + E | 4 | t | 4.41 | | EE | a3c1700s1d1o4a3c1700s1d5o3l0 +(3 rows) + -- test char predicates SELECT * FROM test_filter WHERE d4 = 'BB' ORDER BY t0, a1; - t0 | a1 | b2 | c3 | d4 | e5 | filtervalue + t0 | a1 | b2 | c3 | d4 | e5 | filtervalue ----+----+----+------+----+----+---------------- B | | f | 1.11 | BB | BB | a4c1042s2dBBo5 (1 row) @@ -1222,9 +1275,62 @@ SELECT * FROM test_filter WHERE c3 IS NOT NULL ORDER BY t0, a1; | 0 | t | 0.01 | AA | AA | a3o9 (9 rows) +-- test numeric predicates with integer constant (cross-type pushdown) +SELECT * FROM test_filter WHERE c3 > 1 ORDER BY t0, a1; + t0 | a1 | b2 | c3 | d4 | e5 | filtervalue +----+----+----+------+----+----+---------------- + B | | f | 1.11 | BB | BB | a3c1700s1d1o2 + C | 2 | | 2.21 | CC | CC | a3c1700s1d1o2 + E | 4 | t | 4.41 | | EE | a3c1700s1d1o2 + F | 5 | f | 5.51 | FF | | a3c1700s1d1o2 + G | 6 | t | 6.61 | GG | GG | a3c1700s1d1o2 + H | 7 | f | 7.71 | HH | HH | a3c1700s1d1o2 + I | 8 | t | 8.81 | II | II | a3c1700s1d1o2 + J | 9 | f | 9.91 | JJ | JJ | a3c1700s1d1o2 +(8 rows) + +SELECT * FROM test_filter WHERE c3 <= 2 ORDER BY t0, a1; + t0 | a1 | b2 | c3 | d4 | e5 | filtervalue +----+----+----+------+----+----+---------------- + B | | f | 1.11 | BB | BB | a3c1700s1d2o3 + | 0 | t | 0.01 | AA | AA | a3c1700s1d2o3 +(2 rows) + +SELECT * FROM test_filter WHERE c3 >= 5 ORDER BY t0, a1; + t0 | a1 | b2 | c3 | d4 | e5 | filtervalue +----+----+----+------+----+----+---------------- + F | 5 | f | 5.51 | FF | | a3c1700s1d5o4 + G | 6 | t | 6.61 | GG | GG | a3c1700s1d5o4 + H | 7 | f | 7.71 | HH | HH | a3c1700s1d5o4 + I | 8 | t | 8.81 | II | II | a3c1700s1d5o4 + J | 9 | f | 9.91 | JJ | JJ | a3c1700s1d5o4 +(5 rows) + +SELECT * FROM test_filter WHERE c3 <> 5 ORDER BY t0, a1; + t0 | a1 | b2 | c3 | d4 | e5 | filtervalue +----+----+----+------+----+----+---------------- + B | | f | 1.11 | BB | BB | a3c1700s1d5o6 + C | 2 | | 2.21 | CC | CC | a3c1700s1d5o6 + E | 4 | t | 4.41 | | EE | a3c1700s1d5o6 + F | 5 | f | 5.51 | FF | | a3c1700s1d5o6 + G | 6 | t | 6.61 | GG | GG | a3c1700s1d5o6 + H | 7 | f | 7.71 | HH | HH | a3c1700s1d5o6 + I | 8 | t | 8.81 | II | II | a3c1700s1d5o6 + J | 9 | f | 9.91 | JJ | JJ | a3c1700s1d5o6 + | 0 | t | 0.01 | AA | AA | a3c1700s1d5o6 +(9 rows) + +SELECT * FROM test_filter WHERE c3 BETWEEN 1 AND 5 ORDER BY t0, a1; + t0 | a1 | b2 | c3 | d4 | e5 | filtervalue +----+----+----+------+----+----+------------------------------------ + B | | f | 1.11 | BB | BB | a3c1700s1d1o4a3c1700s1d5o3l0 + C | 2 | | 2.21 | CC | CC | a3c1700s1d1o4a3c1700s1d5o3l0 + E | 4 | t | 4.41 | | EE | a3c1700s1d1o4a3c1700s1d5o3l0 +(3 rows) + -- test char predicates SELECT * FROM test_filter WHERE d4 = 'BB' ORDER BY t0, a1; - t0 | a1 | b2 | c3 | d4 | e5 | filtervalue + t0 | a1 | b2 | c3 | d4 | e5 | filtervalue ----+----+----+------+----+----+---------------- B | | f | 1.11 | BB | BB | a4c1042s2dBBo5 (1 row) diff --git a/regression/expected/FilterPushDownTest.out b/regression/expected/FilterPushDownTest.out index 1d98bd4ed..64497c847 100644 --- a/regression/expected/FilterPushDownTest.out +++ b/regression/expected/FilterPushDownTest.out @@ -483,9 +483,62 @@ SELECT * FROM test_filter WHERE c3 IS NOT NULL ORDER BY t0, a1; | 0 | t | 0.01 | AA | AA | a3o9 (9 rows) +-- test numeric predicates with integer constant (cross-type pushdown) +SELECT * FROM test_filter WHERE c3 > 1 ORDER BY t0, a1; + t0 | a1 | b2 | c3 | d4 | e5 | filtervalue +----+----+----+------+----+----+---------------- + B | | f | 1.11 | BB | BB | a3c1700s1d1o2 + C | 2 | | 2.21 | CC | CC | a3c1700s1d1o2 + E | 4 | t | 4.41 | | EE | a3c1700s1d1o2 + F | 5 | f | 5.51 | FF | | a3c1700s1d1o2 + G | 6 | t | 6.61 | GG | GG | a3c1700s1d1o2 + H | 7 | f | 7.71 | HH | HH | a3c1700s1d1o2 + I | 8 | t | 8.81 | II | II | a3c1700s1d1o2 + J | 9 | f | 9.91 | JJ | JJ | a3c1700s1d1o2 +(8 rows) + +SELECT * FROM test_filter WHERE c3 <= 2 ORDER BY t0, a1; + t0 | a1 | b2 | c3 | d4 | e5 | filtervalue +----+----+----+------+----+----+---------------- + B | | f | 1.11 | BB | BB | a3c1700s1d2o3 + | 0 | t | 0.01 | AA | AA | a3c1700s1d2o3 +(2 rows) + +SELECT * FROM test_filter WHERE c3 >= 5 ORDER BY t0, a1; + t0 | a1 | b2 | c3 | d4 | e5 | filtervalue +----+----+----+------+----+----+---------------- + F | 5 | f | 5.51 | FF | | a3c1700s1d5o4 + G | 6 | t | 6.61 | GG | GG | a3c1700s1d5o4 + H | 7 | f | 7.71 | HH | HH | a3c1700s1d5o4 + I | 8 | t | 8.81 | II | II | a3c1700s1d5o4 + J | 9 | f | 9.91 | JJ | JJ | a3c1700s1d5o4 +(5 rows) + +SELECT * FROM test_filter WHERE c3 <> 5 ORDER BY t0, a1; + t0 | a1 | b2 | c3 | d4 | e5 | filtervalue +----+----+----+------+----+----+---------------- + B | | f | 1.11 | BB | BB | a3c1700s1d5o6 + C | 2 | | 2.21 | CC | CC | a3c1700s1d5o6 + E | 4 | t | 4.41 | | EE | a3c1700s1d5o6 + F | 5 | f | 5.51 | FF | | a3c1700s1d5o6 + G | 6 | t | 6.61 | GG | GG | a3c1700s1d5o6 + H | 7 | f | 7.71 | HH | HH | a3c1700s1d5o6 + I | 8 | t | 8.81 | II | II | a3c1700s1d5o6 + J | 9 | f | 9.91 | JJ | JJ | a3c1700s1d5o6 + | 0 | t | 0.01 | AA | AA | a3c1700s1d5o6 +(9 rows) + +SELECT * FROM test_filter WHERE c3 BETWEEN 1 AND 5 ORDER BY t0, a1; + t0 | a1 | b2 | c3 | d4 | e5 | filtervalue +----+----+----+------+----+----+------------------------------------ + B | | f | 1.11 | BB | BB | a3c1700s1d1o4a3c1700s1d5o3l0 + C | 2 | | 2.21 | CC | CC | a3c1700s1d1o4a3c1700s1d5o3l0 + E | 4 | t | 4.41 | | EE | a3c1700s1d1o4a3c1700s1d5o3l0 +(3 rows) + -- test char predicates SELECT * FROM test_filter WHERE d4 = 'BB' ORDER BY t0, a1; - t0 | a1 | b2 | c3 | d4 | e5 | filtervalue + t0 | a1 | b2 | c3 | d4 | e5 | filtervalue ----+----+----+------+----+----+---------------- B | | f | 1.11 | BB | BB | a4c1042s2dBBo5 (1 row) @@ -1219,9 +1272,62 @@ SELECT * FROM test_filter WHERE c3 IS NOT NULL ORDER BY t0, a1; | 0 | t | 0.01 | AA | AA | a3o8l2 (9 rows) +-- test numeric predicates with integer constant (cross-type pushdown) +SELECT * FROM test_filter WHERE c3 > 1 ORDER BY t0, a1; + t0 | a1 | b2 | c3 | d4 | e5 | filtervalue +----+----+----+------+----+----+---------------- + B | | f | 1.11 | BB | BB | a3c1700s1d1o2 + C | 2 | | 2.21 | CC | CC | a3c1700s1d1o2 + E | 4 | t | 4.41 | | EE | a3c1700s1d1o2 + F | 5 | f | 5.51 | FF | | a3c1700s1d1o2 + G | 6 | t | 6.61 | GG | GG | a3c1700s1d1o2 + H | 7 | f | 7.71 | HH | HH | a3c1700s1d1o2 + I | 8 | t | 8.81 | II | II | a3c1700s1d1o2 + J | 9 | f | 9.91 | JJ | JJ | a3c1700s1d1o2 +(8 rows) + +SELECT * FROM test_filter WHERE c3 <= 2 ORDER BY t0, a1; + t0 | a1 | b2 | c3 | d4 | e5 | filtervalue +----+----+----+------+----+----+---------------- + B | | f | 1.11 | BB | BB | a3c1700s1d2o3 + | 0 | t | 0.01 | AA | AA | a3c1700s1d2o3 +(2 rows) + +SELECT * FROM test_filter WHERE c3 >= 5 ORDER BY t0, a1; + t0 | a1 | b2 | c3 | d4 | e5 | filtervalue +----+----+----+------+----+----+---------------- + F | 5 | f | 5.51 | FF | | a3c1700s1d5o4 + G | 6 | t | 6.61 | GG | GG | a3c1700s1d5o4 + H | 7 | f | 7.71 | HH | HH | a3c1700s1d5o4 + I | 8 | t | 8.81 | II | II | a3c1700s1d5o4 + J | 9 | f | 9.91 | JJ | JJ | a3c1700s1d5o4 +(5 rows) + +SELECT * FROM test_filter WHERE c3 <> 5 ORDER BY t0, a1; + t0 | a1 | b2 | c3 | d4 | e5 | filtervalue +----+----+----+------+----+----+---------------- + B | | f | 1.11 | BB | BB | a3c1700s1d5o6 + C | 2 | | 2.21 | CC | CC | a3c1700s1d5o6 + E | 4 | t | 4.41 | | EE | a3c1700s1d5o6 + F | 5 | f | 5.51 | FF | | a3c1700s1d5o6 + G | 6 | t | 6.61 | GG | GG | a3c1700s1d5o6 + H | 7 | f | 7.71 | HH | HH | a3c1700s1d5o6 + I | 8 | t | 8.81 | II | II | a3c1700s1d5o6 + J | 9 | f | 9.91 | JJ | JJ | a3c1700s1d5o6 + | 0 | t | 0.01 | AA | AA | a3c1700s1d5o6 +(9 rows) + +SELECT * FROM test_filter WHERE c3 BETWEEN 1 AND 5 ORDER BY t0, a1; + t0 | a1 | b2 | c3 | d4 | e5 | filtervalue +----+----+----+------+----+----+------------------------------------ + B | | f | 1.11 | BB | BB | a3c1700s1d1o4a3c1700s1d5o3l0 + C | 2 | | 2.21 | CC | CC | a3c1700s1d1o4a3c1700s1d5o3l0 + E | 4 | t | 4.41 | | EE | a3c1700s1d1o4a3c1700s1d5o3l0 +(3 rows) + -- test char predicates SELECT * FROM test_filter WHERE d4 = 'BB' ORDER BY t0, a1; - t0 | a1 | b2 | c3 | d4 | e5 | filtervalue + t0 | a1 | b2 | c3 | d4 | e5 | filtervalue ----+----+----+------+----+----+---------------- B | | f | 1.11 | BB | BB | a4c1042s2dBBo5 (1 row) diff --git a/regression/sql/FDW_FilterPushDownTest.sql b/regression/sql/FDW_FilterPushDownTest.sql index 7135658c2..42436cacf 100644 --- a/regression/sql/FDW_FilterPushDownTest.sql +++ b/regression/sql/FDW_FilterPushDownTest.sql @@ -84,6 +84,13 @@ SELECT * FROM test_filter WHERE c3 NOT BETWEEN 1.11 AND 4.41 ORDER BY t0, a1; SELECT * FROM test_filter WHERE c3 IS NULL ORDER BY t0, a1; SELECT * FROM test_filter WHERE c3 IS NOT NULL ORDER BY t0, a1; +-- test numeric predicates with integer constant (cross-type pushdown) +SELECT * FROM test_filter WHERE c3 > 1 ORDER BY t0, a1; +SELECT * FROM test_filter WHERE c3 <= 2 ORDER BY t0, a1; +SELECT * FROM test_filter WHERE c3 >= 5 ORDER BY t0, a1; +SELECT * FROM test_filter WHERE c3 <> 5 ORDER BY t0, a1; +SELECT * FROM test_filter WHERE c3 BETWEEN 1 AND 5 ORDER BY t0, a1; + -- test char predicates SELECT * FROM test_filter WHERE d4 = 'BB' ORDER BY t0, a1; SELECT * FROM test_filter WHERE d4 = 'BB ' ORDER BY t0, a1; @@ -178,6 +185,13 @@ SELECT * FROM test_filter WHERE c3 NOT BETWEEN 1.11 AND 4.41 ORDER BY t0, a1; SELECT * FROM test_filter WHERE c3 IS NULL ORDER BY t0, a1; SELECT * FROM test_filter WHERE c3 IS NOT NULL ORDER BY t0, a1; +-- test numeric predicates with integer constant (cross-type pushdown) +SELECT * FROM test_filter WHERE c3 > 1 ORDER BY t0, a1; +SELECT * FROM test_filter WHERE c3 <= 2 ORDER BY t0, a1; +SELECT * FROM test_filter WHERE c3 >= 5 ORDER BY t0, a1; +SELECT * FROM test_filter WHERE c3 <> 5 ORDER BY t0, a1; +SELECT * FROM test_filter WHERE c3 BETWEEN 1 AND 5 ORDER BY t0, a1; + -- test char predicates SELECT * FROM test_filter WHERE d4 = 'BB' ORDER BY t0, a1; SELECT * FROM test_filter WHERE d4 = 'BB ' ORDER BY t0, a1; diff --git a/regression/sql/FilterPushDownTest.sql b/regression/sql/FilterPushDownTest.sql index 4697ef9f3..2903cb84b 100644 --- a/regression/sql/FilterPushDownTest.sql +++ b/regression/sql/FilterPushDownTest.sql @@ -80,6 +80,13 @@ SELECT * FROM test_filter WHERE c3 NOT BETWEEN 1.11 AND 4.41 ORDER BY t0, a1; SELECT * FROM test_filter WHERE c3 IS NULL ORDER BY t0, a1; SELECT * FROM test_filter WHERE c3 IS NOT NULL ORDER BY t0, a1; +-- test numeric predicates with integer constant (cross-type pushdown) +SELECT * FROM test_filter WHERE c3 > 1 ORDER BY t0, a1; +SELECT * FROM test_filter WHERE c3 <= 2 ORDER BY t0, a1; +SELECT * FROM test_filter WHERE c3 >= 5 ORDER BY t0, a1; +SELECT * FROM test_filter WHERE c3 <> 5 ORDER BY t0, a1; +SELECT * FROM test_filter WHERE c3 BETWEEN 1 AND 5 ORDER BY t0, a1; + -- test char predicates SELECT * FROM test_filter WHERE d4 = 'BB' ORDER BY t0, a1; SELECT * FROM test_filter WHERE d4 = 'BB ' ORDER BY t0, a1; From f30507490b7693c91f66f2627db126e0fb4e6df5 Mon Sep 17 00:00:00 2001 From: liuxiaoyu Date: Fri, 10 Apr 2026 18:46:45 +0800 Subject: [PATCH 2/4] fix: apply same numeric filter pushdown fix to external table path The previous commit fixed fdw/pxf_filter.c but the external table code path (external-table/src/pxffilters.c) has the same issue in opexpr_to_pxffilter(). Apply the same eval_const_expressions() fix to handle implicit type casts on constants. --- external-table/src/pxffilters.c | 20 ++++++++++++++++++++ 1 file changed, 20 insertions(+) diff --git a/external-table/src/pxffilters.c b/external-table/src/pxffilters.c index 3ef0f062b..c054bf3ba 100644 --- a/external-table/src/pxffilters.c +++ b/external-table/src/pxffilters.c @@ -775,6 +775,26 @@ opexpr_to_pxffilter(OpExpr *expr, PxfFilterDesc * filter) } } + /* + * Try to evaluate constant expressions in operands. + * This handles implicit type casts where PostgreSQL wraps a constant + * in a FuncExpr (e.g., int4 -> numeric cast when comparing a numeric + * column with an integer constant). Evaluating these gives us back a + * plain Const node that we can serialize for filter pushdown. + */ + if (!IsA(leftop, Var) && !IsA(leftop, Const)) + { + Node *simplified = eval_const_expressions(NULL, leftop); + if (IsA(simplified, Const)) + leftop = simplified; + } + if (!IsA(rightop, Var) && !IsA(rightop, Const)) + { + Node *simplified = eval_const_expressions(NULL, rightop); + if (IsA(simplified, Const)) + rightop = simplified; + } + /* arguments must be VAR and CONST */ if (IsA(leftop, Var) && IsA(rightop, Const)) { From 4485f801301330c53bf5d559767425776c0c75e0 Mon Sep 17 00:00:00 2001 From: MisterRaindrop <278811821@qq.com> Date: Thu, 16 Apr 2026 19:16:36 +0800 Subject: [PATCH 3/4] fix --- external-table/src/pxffilters.c | 1 + fdw/pxf_filter.c | 1 + 2 files changed, 2 insertions(+) diff --git a/external-table/src/pxffilters.c b/external-table/src/pxffilters.c index c054bf3ba..7f8a21a45 100644 --- a/external-table/src/pxffilters.c +++ b/external-table/src/pxffilters.c @@ -26,6 +26,7 @@ #include "catalog/pg_operator.h" #include "optimizer/clauses.h" +#include "optimizer/optimizer.h" #include "parser/parse_expr.h" #include "utils/builtins.h" #include "utils/guc.h" diff --git a/fdw/pxf_filter.c b/fdw/pxf_filter.c index b33313c6c..1e7ec4645 100644 --- a/fdw/pxf_filter.c +++ b/fdw/pxf_filter.c @@ -24,6 +24,7 @@ #include "catalog/pg_operator.h" #include "optimizer/clauses.h" +#include "optimizer/optimizer.h" #include "parser/parse_expr.h" #include "utils/builtins.h" #include "utils/guc.h" From afc63eb31c8dd2c1a765f4a0769baacc472298ca Mon Sep 17 00:00:00 2001 From: MisterRaindrop <278811821@qq.com> Date: Fri, 17 Apr 2026 18:53:32 +0800 Subject: [PATCH 4/4] test: add equality and less-than cases for numeric cross-type pushdown MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Extend FilterPushDownTest / FDW_FilterPushDownTest regression suites with c3 = 5 and c3 < 5 to exercise the '=' and '<' operators with an integer constant against a numeric column — the original scenario behind the pushdown fix (biz_dt = 20260331) was previously only covered for >, <=, >=, <> and BETWEEN. Also sync FilterPushDownTest.sql to include the int-const block in both test segments, matching the expected output. --- .../expected/FDW_FilterPushDownTest.out | 28 +++++++++++++++++++ regression/expected/FilterPushDownTest.out | 28 +++++++++++++++++++ regression/sql/FDW_FilterPushDownTest.sql | 4 +++ regression/sql/FilterPushDownTest.sql | 11 ++++++++ 4 files changed, 71 insertions(+) diff --git a/regression/expected/FDW_FilterPushDownTest.out b/regression/expected/FDW_FilterPushDownTest.out index b61bcad4f..15da050b5 100644 --- a/regression/expected/FDW_FilterPushDownTest.out +++ b/regression/expected/FDW_FilterPushDownTest.out @@ -487,6 +487,20 @@ SELECT * FROM test_filter WHERE c3 IS NOT NULL ORDER BY t0, a1; (9 rows) -- test numeric predicates with integer constant (cross-type pushdown) +SELECT * FROM test_filter WHERE c3 = 5 ORDER BY t0, a1; + t0 | a1 | b2 | c3 | d4 | e5 | filtervalue +----+----+----+----+----+----+------------- +(0 rows) + +SELECT * FROM test_filter WHERE c3 < 5 ORDER BY t0, a1; + t0 | a1 | b2 | c3 | d4 | e5 | filtervalue +----+----+----+------+----+----+---------------- + B | | f | 1.11 | BB | BB | a3c1700s1d5o1 + C | 2 | | 2.21 | CC | CC | a3c1700s1d5o1 + E | 4 | t | 4.41 | | EE | a3c1700s1d5o1 + | 0 | t | 0.01 | AA | AA | a3c1700s1d5o1 +(4 rows) + SELECT * FROM test_filter WHERE c3 > 1 ORDER BY t0, a1; t0 | a1 | b2 | c3 | d4 | e5 | filtervalue ----+----+----+------+----+----+---------------- @@ -1276,6 +1290,20 @@ SELECT * FROM test_filter WHERE c3 IS NOT NULL ORDER BY t0, a1; (9 rows) -- test numeric predicates with integer constant (cross-type pushdown) +SELECT * FROM test_filter WHERE c3 = 5 ORDER BY t0, a1; + t0 | a1 | b2 | c3 | d4 | e5 | filtervalue +----+----+----+----+----+----+------------- +(0 rows) + +SELECT * FROM test_filter WHERE c3 < 5 ORDER BY t0, a1; + t0 | a1 | b2 | c3 | d4 | e5 | filtervalue +----+----+----+------+----+----+---------------- + B | | f | 1.11 | BB | BB | a3c1700s1d5o1 + C | 2 | | 2.21 | CC | CC | a3c1700s1d5o1 + E | 4 | t | 4.41 | | EE | a3c1700s1d5o1 + | 0 | t | 0.01 | AA | AA | a3c1700s1d5o1 +(4 rows) + SELECT * FROM test_filter WHERE c3 > 1 ORDER BY t0, a1; t0 | a1 | b2 | c3 | d4 | e5 | filtervalue ----+----+----+------+----+----+---------------- diff --git a/regression/expected/FilterPushDownTest.out b/regression/expected/FilterPushDownTest.out index 64497c847..f24d814bd 100644 --- a/regression/expected/FilterPushDownTest.out +++ b/regression/expected/FilterPushDownTest.out @@ -484,6 +484,20 @@ SELECT * FROM test_filter WHERE c3 IS NOT NULL ORDER BY t0, a1; (9 rows) -- test numeric predicates with integer constant (cross-type pushdown) +SELECT * FROM test_filter WHERE c3 = 5 ORDER BY t0, a1; + t0 | a1 | b2 | c3 | d4 | e5 | filtervalue +----+----+----+----+----+----+------------- +(0 rows) + +SELECT * FROM test_filter WHERE c3 < 5 ORDER BY t0, a1; + t0 | a1 | b2 | c3 | d4 | e5 | filtervalue +----+----+----+------+----+----+---------------- + B | | f | 1.11 | BB | BB | a3c1700s1d5o1 + C | 2 | | 2.21 | CC | CC | a3c1700s1d5o1 + E | 4 | t | 4.41 | | EE | a3c1700s1d5o1 + | 0 | t | 0.01 | AA | AA | a3c1700s1d5o1 +(4 rows) + SELECT * FROM test_filter WHERE c3 > 1 ORDER BY t0, a1; t0 | a1 | b2 | c3 | d4 | e5 | filtervalue ----+----+----+------+----+----+---------------- @@ -1273,6 +1287,20 @@ SELECT * FROM test_filter WHERE c3 IS NOT NULL ORDER BY t0, a1; (9 rows) -- test numeric predicates with integer constant (cross-type pushdown) +SELECT * FROM test_filter WHERE c3 = 5 ORDER BY t0, a1; + t0 | a1 | b2 | c3 | d4 | e5 | filtervalue +----+----+----+----+----+----+------------- +(0 rows) + +SELECT * FROM test_filter WHERE c3 < 5 ORDER BY t0, a1; + t0 | a1 | b2 | c3 | d4 | e5 | filtervalue +----+----+----+------+----+----+---------------- + B | | f | 1.11 | BB | BB | a3c1700s1d5o1 + C | 2 | | 2.21 | CC | CC | a3c1700s1d5o1 + E | 4 | t | 4.41 | | EE | a3c1700s1d5o1 + | 0 | t | 0.01 | AA | AA | a3c1700s1d5o1 +(4 rows) + SELECT * FROM test_filter WHERE c3 > 1 ORDER BY t0, a1; t0 | a1 | b2 | c3 | d4 | e5 | filtervalue ----+----+----+------+----+----+---------------- diff --git a/regression/sql/FDW_FilterPushDownTest.sql b/regression/sql/FDW_FilterPushDownTest.sql index 42436cacf..8b184b068 100644 --- a/regression/sql/FDW_FilterPushDownTest.sql +++ b/regression/sql/FDW_FilterPushDownTest.sql @@ -85,6 +85,8 @@ SELECT * FROM test_filter WHERE c3 IS NULL ORDER BY t0, a1; SELECT * FROM test_filter WHERE c3 IS NOT NULL ORDER BY t0, a1; -- test numeric predicates with integer constant (cross-type pushdown) +SELECT * FROM test_filter WHERE c3 = 5 ORDER BY t0, a1; +SELECT * FROM test_filter WHERE c3 < 5 ORDER BY t0, a1; SELECT * FROM test_filter WHERE c3 > 1 ORDER BY t0, a1; SELECT * FROM test_filter WHERE c3 <= 2 ORDER BY t0, a1; SELECT * FROM test_filter WHERE c3 >= 5 ORDER BY t0, a1; @@ -186,6 +188,8 @@ SELECT * FROM test_filter WHERE c3 IS NULL ORDER BY t0, a1; SELECT * FROM test_filter WHERE c3 IS NOT NULL ORDER BY t0, a1; -- test numeric predicates with integer constant (cross-type pushdown) +SELECT * FROM test_filter WHERE c3 = 5 ORDER BY t0, a1; +SELECT * FROM test_filter WHERE c3 < 5 ORDER BY t0, a1; SELECT * FROM test_filter WHERE c3 > 1 ORDER BY t0, a1; SELECT * FROM test_filter WHERE c3 <= 2 ORDER BY t0, a1; SELECT * FROM test_filter WHERE c3 >= 5 ORDER BY t0, a1; diff --git a/regression/sql/FilterPushDownTest.sql b/regression/sql/FilterPushDownTest.sql index 2903cb84b..2d5d6fc01 100644 --- a/regression/sql/FilterPushDownTest.sql +++ b/regression/sql/FilterPushDownTest.sql @@ -81,6 +81,8 @@ SELECT * FROM test_filter WHERE c3 IS NULL ORDER BY t0, a1; SELECT * FROM test_filter WHERE c3 IS NOT NULL ORDER BY t0, a1; -- test numeric predicates with integer constant (cross-type pushdown) +SELECT * FROM test_filter WHERE c3 = 5 ORDER BY t0, a1; +SELECT * FROM test_filter WHERE c3 < 5 ORDER BY t0, a1; SELECT * FROM test_filter WHERE c3 > 1 ORDER BY t0, a1; SELECT * FROM test_filter WHERE c3 <= 2 ORDER BY t0, a1; SELECT * FROM test_filter WHERE c3 >= 5 ORDER BY t0, a1; @@ -181,6 +183,15 @@ SELECT * FROM test_filter WHERE c3 NOT BETWEEN 1.11 AND 4.41 ORDER BY t0, a1; SELECT * FROM test_filter WHERE c3 IS NULL ORDER BY t0, a1; SELECT * FROM test_filter WHERE c3 IS NOT NULL ORDER BY t0, a1; +-- test numeric predicates with integer constant (cross-type pushdown) +SELECT * FROM test_filter WHERE c3 = 5 ORDER BY t0, a1; +SELECT * FROM test_filter WHERE c3 < 5 ORDER BY t0, a1; +SELECT * FROM test_filter WHERE c3 > 1 ORDER BY t0, a1; +SELECT * FROM test_filter WHERE c3 <= 2 ORDER BY t0, a1; +SELECT * FROM test_filter WHERE c3 >= 5 ORDER BY t0, a1; +SELECT * FROM test_filter WHERE c3 <> 5 ORDER BY t0, a1; +SELECT * FROM test_filter WHERE c3 BETWEEN 1 AND 5 ORDER BY t0, a1; + -- test char predicates SELECT * FROM test_filter WHERE d4 = 'BB' ORDER BY t0, a1; SELECT * FROM test_filter WHERE d4 = 'BB ' ORDER BY t0, a1;