From 315adba6d814a56f7e6bbe681ab357fc90fb4dd3 Mon Sep 17 00:00:00 2001 From: Patrick Decat Date: Fri, 20 Jun 2025 12:35:37 +0200 Subject: [PATCH 1/2] fix: support PostgreSQL 17 --- fdw/fdw.c | 8 +++++++- fdw/query.c | 3 +++ 2 files changed, 10 insertions(+), 1 deletion(-) diff --git a/fdw/fdw.c b/fdw/fdw.c index f620198b..1cf879c8 100644 --- a/fdw/fdw.c +++ b/fdw/fdw.c @@ -264,7 +264,10 @@ static void fdwGetForeignPaths(PlannerInfo *root, RelOptInfo *baserel, Oid forei NIL, /* no pathkeys */ NULL, NULL, - (void *)fdw_private)); +#if PG_VERSION_NUM >= 170000 + NULL, +#endif + (void *)fdw_private)); /* Add each ForeignPath previously found */ foreach (lc, paths) @@ -284,6 +287,9 @@ static void fdwGetForeignPaths(PlannerInfo *root, RelOptInfo *baserel, Oid forei path->path.startup_cost, path->path.total_cost, apply_pathkeys, NULL, NULL, +#if PG_VERSION_NUM >= 170000 + NULL, +#endif (void *)fdw_private); newpath->path.param_info = path->path.param_info; add_path(baserel, (Path *)newpath); diff --git a/fdw/query.c b/fdw/query.c index 7452e6ca..05fcf6e4 100644 --- a/fdw/query.c +++ b/fdw/query.c @@ -538,6 +538,9 @@ findPaths(PlannerInfo *root, RelOptInfo *baserel, List *possiblePaths, NULL, #if PG_VERSION_NUM >= 90500 NULL, +#endif +#if PG_VERSION_NUM >= 170000 + NULL, #endif NULL); From ddd68609fee452c657ef72425d9b004d35c21407 Mon Sep 17 00:00:00 2001 From: Patrick Decat Date: Tue, 8 Jul 2025 11:23:59 +0200 Subject: [PATCH 2/2] fix: use extract_actual_clauses to properly handle RestrictInfo nodes --- fdw/logging.c | 11 ++++-- fdw/query.c | 102 +++++++++++++++++++++++++++++++++++++------------- 2 files changed, 83 insertions(+), 30 deletions(-) diff --git a/fdw/logging.c b/fdw/logging.c index 2c93b060..12dfed8c 100644 --- a/fdw/logging.c +++ b/fdw/logging.c @@ -57,12 +57,17 @@ char* tagTypeToString(NodeTag type) "T_JoinExpr", "T_FromExpr", "T_OnConflictExpr", - "T_IntoClause" + "T_IntoClause", + "T_RestrictInfo" /* Add RestrictInfo for PostgreSQL v16+ compatibility */ }; int idx = (int)type - (int)T_Alias; if (idx < sizeof(tagNames) / sizeof(tagNames[0])){ return tagNames[idx]; } - return ""; -} \ No newline at end of file + /* DEBUG: Log unknown node types for PostgreSQL v16+ compatibility debugging */ + static char unknown_type_buf[64]; + snprintf(unknown_type_buf, sizeof(unknown_type_buf), "T_Unknown_%d", (int)type); + return unknown_type_buf; + +} diff --git a/fdw/query.c b/fdw/query.c index 05fcf6e4..e6674ed3 100644 --- a/fdw/query.c +++ b/fdw/query.c @@ -41,6 +41,7 @@ List *clausesInvolvingAttr(Index relid, AttrNumber attnum, Expr *fdw_get_em_expr(EquivalenceClass *ec, RelOptInfo *rel); + /* * The list of needed columns (represented by their respective vars) * is pulled from: @@ -59,30 +60,61 @@ extractColumns(List *reltargetlist, List *restrictinfolist) List *targetcolumns; Node *node = (Node *)lfirst(lc); - targetcolumns = pull_var_clause(node, + elog(DEBUG1, "DEBUG: Processing node in target list (nodeTag=%d)", nodeTag(node)); + + /* Check if this is a RestrictInfo node and handle it properly */ + if (IsA(node, RestrictInfo)) + { + List *actual_clauses = extract_actual_clauses(list_make1(node), false); + ListCell *clause_lc; + + foreach (clause_lc, actual_clauses) + { + Node *clause = (Node *)lfirst(clause_lc); + List *clause_vars = pull_var_clause(clause, #if PG_VERSION_NUM >= 90600 - PVC_RECURSE_AGGREGATES | - PVC_RECURSE_PLACEHOLDERS); + PVC_RECURSE_AGGREGATES | PVC_RECURSE_PLACEHOLDERS); #else - PVC_RECURSE_AGGREGATES, - PVC_RECURSE_PLACEHOLDERS); + PVC_RECURSE_AGGREGATES, PVC_RECURSE_PLACEHOLDERS); #endif - columns = list_union(columns, targetcolumns); + columns = list_union(columns, clause_vars); + } + } + else + { + /* For non-RestrictInfo nodes, call pull_var_clause directly */ + targetcolumns = pull_var_clause(node, +#if PG_VERSION_NUM >= 90600 + PVC_RECURSE_AGGREGATES | PVC_RECURSE_PLACEHOLDERS); +#else + PVC_RECURSE_AGGREGATES, PVC_RECURSE_PLACEHOLDERS); +#endif + columns = list_union(columns, targetcolumns); + } i++; } - foreach (lc, restrictinfolist) + /* Use extract_actual_clauses to properly handle RestrictInfo nodes */ + if (restrictinfolist != NIL) { - List *targetcolumns; - RestrictInfo *node = (RestrictInfo *)lfirst(lc); - targetcolumns = pull_var_clause((Node *)node->clause, + List *actual_clauses = extract_actual_clauses(restrictinfolist, false); + ListCell *clause_lc; + + elog(DEBUG1, "DEBUG: Processing %d actual clauses from restrictinfo list", list_length(actual_clauses)); + + foreach (clause_lc, actual_clauses) + { + List *targetcolumns; + Node *clause = (Node *)lfirst(clause_lc); + + elog(DEBUG1, "DEBUG: Processing actual clause (nodeTag=%d)", nodeTag(clause)); + targetcolumns = pull_var_clause(clause, #if PG_VERSION_NUM >= 90600 - PVC_RECURSE_AGGREGATES | - PVC_RECURSE_PLACEHOLDERS); + PVC_RECURSE_AGGREGATES | PVC_RECURSE_PLACEHOLDERS); #else - PVC_RECURSE_AGGREGATES, - PVC_RECURSE_PLACEHOLDERS); + PVC_RECURSE_AGGREGATES, PVC_RECURSE_PLACEHOLDERS); #endif - columns = list_union(columns, targetcolumns); + columns = list_union(columns, targetcolumns); + } } return columns; } @@ -151,6 +183,10 @@ unnestClause(Node *node) return (Node *)((RelabelType *)node)->arg; case T_ArrayCoerceExpr: return (Node *)((ArrayCoerceExpr *)node)->arg; +#if PG_VERSION_NUM >= 160000 + case T_RestrictInfo: + return (Node *)((RestrictInfo *)node)->clause; +#endif default: return node; } @@ -341,23 +377,35 @@ colnameFromVar(Var *var, PlannerInfo *root, FdwPlanState *planstate) */ bool isAttrInRestrictInfo(Index relid, AttrNumber attno, RestrictInfo *restrictinfo) { - List *vars = pull_var_clause((Node *)restrictinfo->clause, -#if PG_VERSION_NUM >= 90600 - PVC_RECURSE_AGGREGATES | - PVC_RECURSE_PLACEHOLDERS); -#else - PVC_RECURSE_AGGREGATES, - PVC_RECURSE_PLACEHOLDERS); -#endif + List *vars; ListCell *lc; + List *actual_clauses; + ListCell *clause_lc; + + elog(DEBUG1, "DEBUG: isAttrInRestrictInfo using extract_actual_clauses (clause nodeTag=%d)", nodeTag((Node *)restrictinfo->clause)); + + /* Use extract_actual_clauses to properly handle RestrictInfo */ + actual_clauses = extract_actual_clauses(list_make1(restrictinfo), false); - foreach (lc, vars) + foreach (clause_lc, actual_clauses) { - Var *var = (Var *)lfirst(lc); + Node *clause = (Node *)lfirst(clause_lc); - if (var->varno == relid && var->varattno == attno) + vars = pull_var_clause(clause, +#if PG_VERSION_NUM >= 90600 + PVC_RECURSE_AGGREGATES | PVC_RECURSE_PLACEHOLDERS); +#else + PVC_RECURSE_AGGREGATES, PVC_RECURSE_PLACEHOLDERS); +#endif + + foreach (lc, vars) { - return true; + Var *var = (Var *)lfirst(lc); + + if (var->varno == relid && var->varattno == attno) + { + return true; + } } } return false;