Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
26 changes: 16 additions & 10 deletions .github/workflows/buildimage.yml
Original file line number Diff line number Diff line change
Expand Up @@ -21,8 +21,10 @@ jobs:
name: Build for Darwin x86_64
runs-on: macos-15-intel
steps:
- name: Install PostgreSQL@14
run: brew install --force postgresql@14
- name: Install PostgreSQL@18
run: |-
brew install --force postgresql@18
echo "$(brew --prefix postgresql@18)/bin" >> "$GITHUB_PATH"

- name: PGConfig
run: |-
Expand Down Expand Up @@ -112,6 +114,7 @@ jobs:

- name: gzip the steampipe_postgres_fdw.so
run: |-
if [ -f build-Darwin/steampipe_postgres_fdw.dylib ]; then mv build-Darwin/steampipe_postgres_fdw.dylib build-Darwin/steampipe_postgres_fdw.so; fi
gzip build-Darwin/steampipe_postgres_fdw.so
mv build-Darwin/steampipe_postgres_fdw.so.gz build-Darwin/steampipe_postgres_fdw.so.darwin_amd64.gz

Expand Down Expand Up @@ -140,8 +143,10 @@ jobs:
name: Build for Darwin ARM64
runs-on: macos-latest
steps:
- name: Install PostgreSQL@14
run: brew install --force postgresql@14
- name: Install PostgreSQL@18
run: |-
brew install --force postgresql@18
echo "$(brew --prefix postgresql@18)/bin" >> "$GITHUB_PATH"

- name: PGConfig
run: |-
Expand Down Expand Up @@ -231,6 +236,7 @@ jobs:

- name: gzip the steampipe_postgres_fdw.so
run: |-
if [ -f build-Darwin/steampipe_postgres_fdw.dylib ]; then mv build-Darwin/steampipe_postgres_fdw.dylib build-Darwin/steampipe_postgres_fdw.so; fi
gzip build-Darwin/steampipe_postgres_fdw.so
mv build-Darwin/steampipe_postgres_fdw.so.gz build-Darwin/steampipe_postgres_fdw.so.darwin_arm64.gz

Expand Down Expand Up @@ -280,9 +286,9 @@ jobs:
sudo env ACCEPT_EULA=Y apt-get update
sudo env ACCEPT_EULA=Y apt-get upgrade

- name: Install PostgreSQL14 Dev
- name: Install PostgreSQL18 Dev
run: |-
sudo apt-get -y install postgresql-server-dev-14
sudo apt-get -y install postgresql-server-dev-18

- name: Find stuff and set env
run: |-
Expand All @@ -293,7 +299,7 @@ jobs:
export PATH=$(pg_config --bindir):$PATH
export PGXS=$(pg_config --pgxs)

export SERVER_LIB=$(pg_config --includedir)/14/server
export SERVER_LIB=$(pg_config --includedir)/18/server
export INTERNAL_LIB=$(pg_config --includedir)/internal

export CFLAGS="$(pg_config --cflags) -I${SERVER_LIB} -I${INTERNAL_LIB} -g"
Expand Down Expand Up @@ -365,9 +371,9 @@ jobs:
sudo env ACCEPT_EULA=Y apt-get update
sudo env ACCEPT_EULA=Y apt-get upgrade

- name: Install PostgreSQL14 Dev
- name: Install PostgreSQL18 Dev
run: |-
sudo apt-get -y install postgresql-server-dev-14
sudo apt-get -y install postgresql-server-dev-18

- name: Find stuff and set env
run: |-
Expand All @@ -378,7 +384,7 @@ jobs:
export PATH=$(pg_config --bindir):$PATH
export PGXS=$(pg_config --pgxs)

export SERVER_LIB=$(pg_config --includedir)/14/server
export SERVER_LIB=$(pg_config --includedir)/18/server
export INTERNAL_LIB=$(pg_config --includedir)/internal

export CFLAGS="$(pg_config --cflags) -I${SERVER_LIB} -I${INTERNAL_LIB} -g"
Expand Down
5 changes: 5 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,3 +1,8 @@
## v2.3.0 [2026-06-10]
_Whats new_
- Add support for building against PostgreSQL 18. Localized, version-guarded source changes: include `commands/explain_format.h` (PG18 EXPLAIN header split) and use `PathKey.pk_cmptype`/`COMPARE_GT` instead of `pk_strategy`/`BTGreaterStrategyNumber` (both `#if PG_VERSION_NUM >= 180000`); and pass the extra `create_foreignscan_path` arguments — `fdw_restrictinfo` (added in PostgreSQL 17, `#if PG_VERSION_NUM >= 170000`) and `disabled_nodes` (added in PostgreSQL 18, `#if PG_VERSION_NUM >= 180000`). Behaviour on PostgreSQL 16 and earlier is unchanged.
- Handle nested `RestrictInfo` nodes in `pull_var_clause` on PostgreSQL 18 — multi-table JOINs on foreign tables failed with `unrecognized node type: 318` without this. (`#if PG_VERSION_NUM >= 180000`; no change on earlier versions.)

## v2.2.4 [2026-05-25]
_Bug fixes_
- Fix `statement_timeout`, `pg_cancel_backend`, and `pg_terminate_backend` having no effect when a plugin's gRPC stream stalls — a hung scan held `AccessShareLock` indefinitely, blocking partition swaps and other DDL until restart. ([#671](https://github.com/turbot/steampipe-postgres-fdw/issues/671), [#672](https://github.com/turbot/steampipe-postgres-fdw/pull/672))
Expand Down
6 changes: 3 additions & 3 deletions fdw/Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -58,11 +58,11 @@ inst:
mkdir -p ../build-${PLATFORM}
rm -f ../build-${PLATFORM}/*

cp steampipe_postgres_fdw.so ../build-${PLATFORM}
@if [ -f steampipe_postgres_fdw.dylib ]; then cp steampipe_postgres_fdw.dylib ../build-${PLATFORM}/steampipe_postgres_fdw.so; else cp steampipe_postgres_fdw.so ../build-${PLATFORM}/steampipe_postgres_fdw.so; fi
cp steampipe_postgres_fdw.control ../build-${PLATFORM}
cp steampipe_postgres_fdw--1.0.sql ../build-${PLATFORM}
rm steampipe_postgres_fdw.so

rm -f steampipe_postgres_fdw.so steampipe_postgres_fdw.dylib
rm steampipe_postgres_fdw.a
rm steampipe_postgres_fdw.h

Expand Down
4 changes: 4 additions & 0 deletions fdw/common.h
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,10 @@
#include "catalog/pg_type.h"
#include "commands/defrem.h"
#include "commands/explain.h"
#if PG_VERSION_NUM >= 180000
/* PG18 moved the EXPLAIN property-output API into a separate header */
#include "commands/explain_format.h"
#endif
#include "foreign/fdwapi.h"
#include "foreign/foreign.h"
#include "funcapi.h"
Expand Down
12 changes: 12 additions & 0 deletions fdw/fdw.c
Original file line number Diff line number Diff line change
Expand Up @@ -436,11 +436,17 @@ static void fdwGetForeignPaths(PlannerInfo *root, RelOptInfo *baserel, Oid forei
baserel,
NULL, /* default pathtarget */
baserel->rows,
#if PG_VERSION_NUM >= 180000
0, /* disabled_nodes (PG18) */
#endif
planstate->startupCost,
baserel->rows * baserel->reltarget->width * 100000, // table scan is very expensive
NIL, /* no pathkeys */
NULL,
NULL,
#if PG_VERSION_NUM >= 170000
NIL, /* fdw_restrictinfo (added in PG17) */
#endif
(void *)fdw_private));

/* Add each ForeignPath previously found */
Expand All @@ -458,9 +464,15 @@ static void fdwGetForeignPaths(PlannerInfo *root, RelOptInfo *baserel, Oid forei
baserel,
NULL, /* default pathtarget */
path->path.rows,
#if PG_VERSION_NUM >= 180000
0, /* disabled_nodes (PG18) */
#endif
path->path.startup_cost, path->path.total_cost,
apply_pathkeys, NULL,
NULL,
#if PG_VERSION_NUM >= 170000
NIL, /* fdw_restrictinfo (added in PG17) */
#endif
(void *)fdw_private);
newpath->path.param_info = path->path.param_info;
add_path(baserel, (Path *)newpath);
Expand Down
45 changes: 42 additions & 3 deletions fdw/query.c
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@
#include "catalog/pg_operator.h"
#include "mb/pg_wchar.h"
#include "nodes/makefuncs.h"
#include "nodes/nodeFuncs.h"
#include "utils/lsyscache.h"
#include "miscadmin.h"
#include "parser/parsetree.h"
Expand All @@ -24,6 +25,34 @@
#define get_attname(x, y) get_attname(x, y, true)
#endif

#if PG_VERSION_NUM >= 180000
/*
* PG18 dropped the T_RestrictInfo case from expression_tree_walker
* (src/backend/nodes/nodeFuncs.c). When the FDW walks a clause subtree
* that contains a nested RestrictInfo (the orclause cache, certain
* join-equivalence-class derived predicates), the walker hits the
* unrecognized node tag (318) and elogs
* "unrecognized node type: 318". Restore the PG<=17 behaviour with a
* pre-pass mutator that replaces each RestrictInfo with its wrapped
* clause before pull_var_clause's walker sees it.
*/
static Node *
strip_restrictinfo_mutator(Node *node, void *context)
{
if (node == NULL)
return NULL;
if (IsA(node, RestrictInfo))
return strip_restrictinfo_mutator(
(Node *) ((RestrictInfo *) node)->clause, context);
return expression_tree_mutator(node, strip_restrictinfo_mutator, context);
}
#define PULL_VAR_CLAUSE_PG18_SAFE(node, flags) \
pull_var_clause(strip_restrictinfo_mutator((node), NULL), (flags))
#else
#define PULL_VAR_CLAUSE_PG18_SAFE(node, flags) \
pull_var_clause((node), (flags))
#endif

char *getOperatorString(Oid opoid);

Node *unnestClause(Node *node);
Expand Down Expand Up @@ -59,7 +88,7 @@ extractColumns(List *reltargetlist, List *restrictinfolist)
List *targetcolumns;
Node *node = (Node *)lfirst(lc);

targetcolumns = pull_var_clause(node,
targetcolumns = PULL_VAR_CLAUSE_PG18_SAFE(node,
#if PG_VERSION_NUM >= 90600
PVC_RECURSE_AGGREGATES |
PVC_RECURSE_PLACEHOLDERS);
Expand All @@ -74,7 +103,7 @@ extractColumns(List *reltargetlist, List *restrictinfolist)
{
List *targetcolumns;
RestrictInfo *node = (RestrictInfo *)lfirst(lc);
targetcolumns = pull_var_clause((Node *)node->clause,
targetcolumns = PULL_VAR_CLAUSE_PG18_SAFE((Node *)node->clause,
#if PG_VERSION_NUM >= 90600
PVC_RECURSE_AGGREGATES |
PVC_RECURSE_PLACEHOLDERS);
Expand Down Expand Up @@ -341,7 +370,7 @@ colnameFromVar(Var *var, PlannerInfo *root, FdwPlanState *planstate)
*/
bool isAttrInRestrictInfo(Index relid, AttrNumber attno, RestrictInfo *restrictinfo)
{
List *vars = pull_var_clause((Node *)restrictinfo->clause,
List *vars = PULL_VAR_CLAUSE_PG18_SAFE((Node *)restrictinfo->clause,
#if PG_VERSION_NUM >= 90600
PVC_RECURSE_AGGREGATES |
PVC_RECURSE_PLACEHOLDERS);
Expand Down Expand Up @@ -528,6 +557,9 @@ findPaths(PlannerInfo *root, RelOptInfo *baserel, List *possiblePaths,
NULL, /* default pathtarget */
#endif
nbrows,
#if PG_VERSION_NUM >= 180000
0, /* disabled_nodes (PG18) */
#endif
startupCost,
#if PG_VERSION_NUM >= 90600
nbrows * baserel->reltarget->width,
Expand All @@ -538,6 +570,9 @@ findPaths(PlannerInfo *root, RelOptInfo *baserel, List *possiblePaths,
NULL,
#if PG_VERSION_NUM >= 90500
NULL,
#endif
#if PG_VERSION_NUM >= 170000
NIL, /* fdw_restrictinfo (added in PG17) */
#endif
NULL);

Expand Down Expand Up @@ -574,7 +609,11 @@ deparse_sortgroup(PlannerInfo *root, Oid foreigntableid, RelOptInfo *rel)

if ((expr = fdw_get_em_expr(ec, rel)))
{
#if PG_VERSION_NUM >= 180000
md->reversed = (key->pk_cmptype == COMPARE_GT);
#else
md->reversed = (key->pk_strategy == BTGreaterStrategyNumber);
#endif
md->nulls_first = key->pk_nulls_first;
md->key = key;

Expand Down
2 changes: 1 addition & 1 deletion version/version.go
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ import (
)

// The main version number that is being run at the moment.
var fdwVersion = "2.2.4"
var fdwVersion = "2.3.0"

// A pre-release marker for the version. If this is "" (empty string)
// then it means that it is a final release. Otherwise, this is a pre-release
Expand Down
Loading