Skip to content

Commit 42711e4

Browse files
committed
Add PostgreSQL 18 support (dev branch)
- Add versions/18 directory with package.json pointing to 18-latest-dev branch - Update fetch-protos.js to include version 18 and handle dev branches - Add protos/18/pg_query.proto fetched from 18-latest-dev branch - Copy templates and configuration files for version 18 - WASM build and tests passing (41/41 tests) Note: This is a development branch tracking pganalyze/libpg_query 18-latest-dev which is still WIP (3/12 tasks complete). Core SQL parsing works but PL/pgSQL type support is incomplete.
1 parent 8ad9a92 commit 42711e4

13 files changed

Lines changed: 5276 additions & 3 deletions

File tree

protos/18/pg_query.proto

Lines changed: 4234 additions & 0 deletions
Large diffs are not rendered by default.

scripts/fetch-protos.js

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@ function getVersionMappings() {
99
const versionsDir = path.join(__dirname, '..', 'versions');
1010
const mappings = [];
1111

12-
for (const version of ['13', '14', '15', '16', '17']) {
12+
for (const version of ['13', '14', '15', '16', '17', '18']) {
1313
const packagePath = path.join(versionsDir, version, 'package.json');
1414
if (fs.existsSync(packagePath)) {
1515
const pkg = JSON.parse(fs.readFileSync(packagePath, 'utf8'));
@@ -70,7 +70,9 @@ async function fetchProtos() {
7070
}
7171

7272
// Use the libpgQueryTag from the Makefile
73-
const url = `https://raw.githubusercontent.com/pganalyze/libpg_query/refs/tags/${libpgQueryTag}/protobuf/pg_query.proto`;
73+
// For dev branches (containing 'dev'), use refs/heads/, otherwise use refs/tags/
74+
const refType = libpgQueryTag.includes('dev') ? 'heads' : 'tags';
75+
const url = `https://raw.githubusercontent.com/pganalyze/libpg_query/refs/${refType}/${libpgQueryTag}/protobuf/pg_query.proto`;
7476
const destPath = path.join(versionDir, 'pg_query.proto');
7577

7678
console.log(`Fetching protobuf for PostgreSQL ${pgVersion} with tag ${libpgQueryTag}...`);
@@ -93,4 +95,4 @@ if (require.main === module) {
9395
fetchProtos().catch(console.error);
9496
}
9597

96-
module.exports = { fetchProtos, getVersionMappings };
98+
module.exports = { fetchProtos, getVersionMappings };

versions/18/LICENSE

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
The MIT License (MIT)
2+
3+
Copyright (c) 2021 Dan Lynch <pyramation@gmail.com>
4+
Copyright (c) 2025 Constructive <developers@constructive.io>
5+
6+
Permission is hereby granted, free of charge, to any person obtaining a copy
7+
of this software and associated documentation files (the "Software"), to deal
8+
in the Software without restriction, including without limitation the rights
9+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
10+
copies of the Software, and to permit persons to whom the Software is
11+
furnished to do so, subject to the following conditions:
12+
13+
The above copyright notice and this permission notice shall be included in all
14+
copies or substantial portions of the Software.
15+
16+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
17+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
18+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
19+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
20+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
21+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
22+
SOFTWARE.

versions/18/Makefile

Lines changed: 99 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,99 @@
1+
# DO NOT MODIFY MANUALLY — this is generated from the templates dir
2+
#
3+
# To make changes, edit the files in the templates/ directory and run:
4+
# npm run copy:templates
5+
6+
WASM_OUT_DIR := wasm
7+
WASM_OUT_NAME := libpg-query
8+
WASM_MODULE_NAME := PgQueryModule
9+
LIBPG_QUERY_REPO := https://github.com/pganalyze/libpg_query.git
10+
LIBPG_QUERY_TAG := 18-latest-dev
11+
12+
CACHE_DIR := .cache
13+
14+
OS ?= $(shell uname -s)
15+
ARCH ?= $(shell uname -m)
16+
17+
ifdef EMSCRIPTEN
18+
PLATFORM := emscripten
19+
else ifeq ($(OS),Darwin)
20+
PLATFORM := darwin
21+
else ifeq ($(OS),Linux)
22+
PLATFORM := linux
23+
else
24+
$(error Unsupported platform: $(OS))
25+
endif
26+
27+
ifdef EMSCRIPTEN
28+
ARCH := wasm
29+
endif
30+
31+
PLATFORM_ARCH := $(PLATFORM)-$(ARCH)
32+
SRC_FILES := src/wasm_wrapper.c
33+
LIBPG_QUERY_DIR := $(CACHE_DIR)/$(PLATFORM_ARCH)/libpg_query/$(LIBPG_QUERY_TAG)
34+
LIBPG_QUERY_ARCHIVE := $(LIBPG_QUERY_DIR)/libpg_query.a
35+
LIBPG_QUERY_HEADER := $(LIBPG_QUERY_DIR)/pg_query.h
36+
CXXFLAGS := -O3 -flto
37+
38+
ifdef EMSCRIPTEN
39+
OUT_FILES := $(foreach EXT,.js .wasm,$(WASM_OUT_DIR)/$(WASM_OUT_NAME)$(EXT))
40+
else
41+
$(error Native builds are no longer supported. Use EMSCRIPTEN=1 for WASM builds only.)
42+
endif
43+
44+
# Clone libpg_query source (lives in CACHE_DIR)
45+
$(LIBPG_QUERY_DIR):
46+
mkdir -p $(CACHE_DIR)
47+
git clone -b $(LIBPG_QUERY_TAG) --single-branch $(LIBPG_QUERY_REPO) $(LIBPG_QUERY_DIR)
48+
49+
$(LIBPG_QUERY_HEADER): $(LIBPG_QUERY_DIR)
50+
51+
# Build libpg_query
52+
$(LIBPG_QUERY_ARCHIVE): $(LIBPG_QUERY_DIR)
53+
cd $(LIBPG_QUERY_DIR); $(MAKE) build
54+
55+
# Build libpg-query-node WASM module
56+
$(OUT_FILES): $(LIBPG_QUERY_ARCHIVE) $(LIBPG_QUERY_HEADER) $(SRC_FILES)
57+
ifdef EMSCRIPTEN
58+
mkdir -p $(WASM_OUT_DIR)
59+
$(CC) \
60+
-v \
61+
$(CXXFLAGS) \
62+
-I$(LIBPG_QUERY_DIR) \
63+
-I$(LIBPG_QUERY_DIR)/vendor \
64+
-L$(LIBPG_QUERY_DIR) \
65+
-sEXPORTED_FUNCTIONS="['_malloc','_free','_wasm_parse_query_raw','_wasm_free_parse_result']" \
66+
-sEXPORTED_RUNTIME_METHODS="['lengthBytesUTF8','stringToUTF8','getValue','UTF8ToString','HEAPU8','HEAPU32']" \
67+
-sEXPORT_NAME="$(WASM_MODULE_NAME)" \
68+
-sENVIRONMENT="web,node,worker" \
69+
-sASSERTIONS=0 \
70+
-sSINGLE_FILE=0 \
71+
-sMODULARIZE=1 \
72+
-sEXPORT_ES6=0 \
73+
-sALLOW_MEMORY_GROWTH=1 \
74+
-sINITIAL_MEMORY=134217728 \
75+
-sMAXIMUM_MEMORY=1073741824 \
76+
-sSTACK_SIZE=33554432 \
77+
-lpg_query \
78+
-o $@ \
79+
$(SRC_FILES)
80+
else
81+
$(error Native builds are no longer supported. Use EMSCRIPTEN=1 for WASM builds only.)
82+
endif
83+
84+
# Commands
85+
build: $(OUT_FILES)
86+
87+
build-cache: $(LIBPG_QUERY_ARCHIVE) $(LIBPG_QUERY_HEADER)
88+
89+
rebuild: clean build
90+
91+
rebuild-cache: clean-cache build-cache
92+
93+
clean:
94+
-@ rm -r $(OUT_FILES) > /dev/null 2>&1
95+
96+
clean-cache:
97+
-@ rm -rf $(LIBPG_QUERY_DIR)
98+
99+
.PHONY: build build-cache rebuild rebuild-cache clean clean-cache

versions/18/package.json

Lines changed: 52 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,52 @@
1+
{
2+
"name": "@libpg-query/v18",
3+
"version": "18.0.0-dev.0",
4+
"description": "The real PostgreSQL query parser (PG 18 dev)",
5+
"homepage": "https://github.com/constructive-io/libpg-query-node",
6+
"main": "./wasm/index.cjs",
7+
"module": "./wasm/index.js",
8+
"typings": "./wasm/index.d.ts",
9+
"publishConfig": {
10+
"access": "public"
11+
},
12+
"x-publish": {
13+
"publishName": "libpg-query",
14+
"pgVersion": "18",
15+
"distTag": "pg18-dev",
16+
"libpgQueryTag": "18-latest-dev"
17+
},
18+
"files": [
19+
"wasm/*"
20+
],
21+
"scripts": {
22+
"clean": "pnpm wasm:clean && rimraf wasm/*.js wasm/*.cjs wasm/*.d.ts",
23+
"build:js": "node scripts/build.js",
24+
"build": "pnpm clean && pnpm wasm:build && pnpm build:js",
25+
"publish:pkg": "node ../../scripts/publish-single-version.js",
26+
"wasm:make": "docker run --rm -v $(pwd):/src -u $(id -u):$(id -g) emscripten/emsdk emmake make",
27+
"wasm:build": "pnpm wasm:make build",
28+
"wasm:rebuild": "pnpm wasm:make rebuild",
29+
"wasm:clean": "pnpm wasm:make clean",
30+
"wasm:clean-cache": "pnpm wasm:make clean-cache",
31+
"test": "node --test test/parsing.test.js test/errors.test.js"
32+
},
33+
"author": "Constructive <developers@constructive.io>",
34+
"license": "MIT",
35+
"repository": {
36+
"type": "git",
37+
"url": "git://github.com/constructive-io/libpg-query-node.git"
38+
},
39+
"devDependencies": {},
40+
"dependencies": {
41+
"@pgsql/types": "^17.6.2"
42+
},
43+
"keywords": [
44+
"sql",
45+
"postgres",
46+
"postgresql",
47+
"pg",
48+
"query",
49+
"plpgsql",
50+
"database"
51+
]
52+
}

versions/18/scripts/build.js

Lines changed: 39 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,39 @@
1+
const fs = require('fs');
2+
const path = require('path');
3+
const { execSync } = require('child_process');
4+
5+
// Run TypeScript compilation
6+
console.log('Compiling TypeScript...');
7+
const tscPath = path.join(__dirname, '../../../node_modules/.bin/tsc');
8+
execSync(`${tscPath}`, { stdio: 'inherit', cwd: path.join(__dirname, '..') });
9+
execSync(`${tscPath} -p tsconfig.esm.json`, { stdio: 'inherit', cwd: path.join(__dirname, '..') });
10+
11+
// Rename files to have correct extensions
12+
const wasmDir = path.join(__dirname, '../wasm');
13+
const cjsDir = path.join(__dirname, '../cjs');
14+
const esmDir = path.join(__dirname, '../esm');
15+
16+
// Ensure wasm directory exists
17+
if (!fs.existsSync(wasmDir)) {
18+
fs.mkdirSync(wasmDir, { recursive: true });
19+
}
20+
21+
// Rename CommonJS files
22+
fs.renameSync(
23+
path.join(cjsDir, 'index.js'),
24+
path.join(wasmDir, 'index.cjs')
25+
);
26+
27+
// Rename ESM files
28+
fs.renameSync(
29+
path.join(esmDir, 'index.js'),
30+
path.join(wasmDir, 'index.js')
31+
);
32+
33+
// Rename declaration files
34+
fs.renameSync(
35+
path.join(cjsDir, 'index.d.ts'),
36+
path.join(wasmDir, 'index.d.ts')
37+
);
38+
39+
console.log('Build completed successfully!');

0 commit comments

Comments
 (0)