diff --git a/.release-please-manifest.json b/.release-please-manifest.json index 2dbb886e4..a00fc7297 100644 --- a/.release-please-manifest.json +++ b/.release-please-manifest.json @@ -10,8 +10,10 @@ "src/native/sdks/ts": "0.3.1", "src/extensions/external/pg_hashids": "0.3.2", "src/extensions/external/pg_ivm": "0.3.2", + "src/extensions/external/pg_partman": "0.0.0", "src/extensions/external/pg_textsearch": "0.3.2", "src/extensions/external/pg_uuidv7": "0.3.2", + "src/extensions/external/pgmq": "0.0.0", "src/extensions/external/pgtap": "0.3.2", "src/extensions/external/postgis": "0.3.2", "src/extensions/external/vector": "0.3.2", diff --git a/release-please-config.json b/release-please-config.json index 7d7334c6e..fd384c59b 100644 --- a/release-please-config.json +++ b/release-please-config.json @@ -245,6 +245,13 @@ "version-file": "VERSION", "changelog-path": "CHANGELOG.md" }, + "src/extensions/external/pg_partman": { + "release-type": "simple", + "component": "oliphaunt-extension-pg-partman", + "package-name": "oliphaunt-extension-pg-partman", + "version-file": "VERSION", + "changelog-path": "CHANGELOG.md" + }, "src/extensions/external/pg_textsearch": { "release-type": "simple", "component": "oliphaunt-extension-pg-textsearch", @@ -259,6 +266,13 @@ "version-file": "VERSION", "changelog-path": "CHANGELOG.md" }, + "src/extensions/external/pgmq": { + "release-type": "simple", + "component": "oliphaunt-extension-pgmq", + "package-name": "oliphaunt-extension-pgmq", + "version-file": "VERSION", + "changelog-path": "CHANGELOG.md" + }, "src/extensions/external/pgtap": { "release-type": "simple", "component": "oliphaunt-extension-pgtap", diff --git a/src/examples/native/react-native-expo/src/SmokeDashboard.tsx b/src/examples/native/react-native-expo/src/SmokeDashboard.tsx index 234588110..55025402c 100644 --- a/src/examples/native/react-native-expo/src/SmokeDashboard.tsx +++ b/src/examples/native/react-native-expo/src/SmokeDashboard.tsx @@ -12,6 +12,7 @@ import { GENERATED_MOBILE_EXTENSION_SMOKE, } from './generated/extension-smoke'; import { + activationSqlForExtension, runMobileBindingProof, runMobileReleaseExtensionProof, runPostgresLifecycleResumeCheck, @@ -113,7 +114,7 @@ const packagedCatalogProfile = process.env.EXPO_PUBLIC_OLIPHAUNT_CATALOG_PROFILE const packagedCatalogProfileProbeSql = process.env.EXPO_PUBLIC_OLIPHAUNT_CATALOG_PROFILE_PROBE_SQL; const packagedCatalogProfileProbeExpected = process.env.EXPO_PUBLIC_OLIPHAUNT_CATALOG_PROFILE_PROBE_EXPECTED; -const packagedExtensions = process.env.EXPO_PUBLIC_OLIPHAUNT_EXTENSIONS; +const packagedExtensions: string | undefined = process.env.EXPO_PUBLIC_OLIPHAUNT_EXTENSIONS; let initialLaunchUrlPromise: Promise | undefined; function smokeGlobalState(): SmokeGlobalState { @@ -544,7 +545,9 @@ function mobileReleaseExtensionProofPlan() { selected.has(extension.sqlName), ); if (plan.length !== selected.size) { - const known = new Set(GENERATED_MOBILE_EXTENSION_PLAN.map((extension) => extension.sqlName)); + const known = new Set( + GENERATED_MOBILE_EXTENSION_PLAN.map((extension) => extension.sqlName), + ); const unknown = requested.filter((extension) => !known.has(extension)); throw new Error(`unknown packaged mobile extensions: ${unknown.join(',')}`); } @@ -565,26 +568,6 @@ function mobileReleaseExtensionProofPlan() { }); } -function activationSqlForExtension(extension: { - readonly sqlName: string; - readonly createsExtension: boolean; -}): readonly string[] { - if (extension.createsExtension) { - return [`CREATE EXTENSION "${extension.sqlName}"`]; - } - if (extension.sqlName === 'auto_explain') { - return [ - "LOAD 'auto_explain'", - "SET auto_explain.log_min_duration = '0'", - "SET auto_explain.log_analyze = 'true'", - "SET auto_explain.log_level = 'NOTICE'", - ]; - } - throw new Error( - `generated mobile extension ${extension.sqlName} does not create an extension and has no runtime proof`, - ); -} - function waitForBackgroundAndForeground( stage: (name: string, extra?: Record) => void, ): Promise<{ states: AppStateStatus[] }> { diff --git a/src/examples/native/react-native-expo/src/generated/extension-smoke.ts b/src/examples/native/react-native-expo/src/generated/extension-smoke.ts index 08d274371..cfca0c3b2 100644 --- a/src/examples/native/react-native-expo/src/generated/extension-smoke.ts +++ b/src/examples/native/react-native-expo/src/generated/extension-smoke.ts @@ -7,7 +7,7 @@ export type GeneratedMobileExtensionProof = { readonly selectedExtensionDependencies: readonly string[]; }; -export const GENERATED_MOBILE_EXTENSION_METADATA_SHA256 = "c1d2e09905d7ecc0172173b34b9e4104dad58987503dd3dab7af4ae78890d9f3" as const; +export const GENERATED_MOBILE_EXTENSION_METADATA_SHA256 = "2f9c13406ab3ce4f8f4f9fb419aeb8ad899e5bde59228215024933dad44c46fe" as const; export const GENERATED_MOBILE_EXTENSION_PLAN = [ { @@ -20,6 +20,11 @@ export const GENERATED_MOBILE_EXTENSION_PLAN = [ "createsExtension": false, "selectedExtensionDependencies": [] }, + { + "sqlName": "autoinc", + "createsExtension": true, + "selectedExtensionDependencies": [] + }, { "sqlName": "bloom", "createsExtension": true, @@ -77,6 +82,11 @@ export const GENERATED_MOBILE_EXTENSION_PLAN = [ "createsExtension": true, "selectedExtensionDependencies": [] }, + { + "sqlName": "insert_username", + "createsExtension": true, + "selectedExtensionDependencies": [] + }, { "sqlName": "intarray", "createsExtension": true, @@ -97,11 +107,21 @@ export const GENERATED_MOBILE_EXTENSION_PLAN = [ "createsExtension": true, "selectedExtensionDependencies": [] }, + { + "sqlName": "moddatetime", + "createsExtension": true, + "selectedExtensionDependencies": [] + }, { "sqlName": "pageinspect", "createsExtension": true, "selectedExtensionDependencies": [] }, + { + "sqlName": "passwordcheck", + "createsExtension": false, + "selectedExtensionDependencies": [] + }, { "sqlName": "pg_buffercache", "createsExtension": true, @@ -122,6 +142,26 @@ export const GENERATED_MOBILE_EXTENSION_PLAN = [ "createsExtension": true, "selectedExtensionDependencies": [] }, + { + "sqlName": "pg_logicalinspect", + "createsExtension": true, + "selectedExtensionDependencies": [] + }, + { + "sqlName": "pg_overexplain", + "createsExtension": false, + "selectedExtensionDependencies": [] + }, + { + "sqlName": "pg_partman", + "createsExtension": true, + "selectedExtensionDependencies": [] + }, + { + "sqlName": "pg_stat_statements", + "createsExtension": true, + "selectedExtensionDependencies": [] + }, { "sqlName": "pg_surgery", "createsExtension": true, @@ -157,6 +197,11 @@ export const GENERATED_MOBILE_EXTENSION_PLAN = [ "createsExtension": true, "selectedExtensionDependencies": [] }, + { + "sqlName": "pgmq", + "createsExtension": true, + "selectedExtensionDependencies": [] + }, { "sqlName": "pgtap", "createsExtension": true, @@ -167,6 +212,11 @@ export const GENERATED_MOBILE_EXTENSION_PLAN = [ "createsExtension": true, "selectedExtensionDependencies": [] }, + { + "sqlName": "refint", + "createsExtension": true, + "selectedExtensionDependencies": [] + }, { "sqlName": "seg", "createsExtension": true, @@ -218,6 +268,15 @@ export const GENERATED_MOBILE_EXTENSION_SMOKE = { "auto_explain": [ "EXPLAIN SELECT count(*) FROM pg_class;" ], + "autoinc": [ + "DROP TABLE IF EXISTS oliphaunt_autoinc;", + "DROP SEQUENCE IF EXISTS oliphaunt_autoinc_sequence;", + "CREATE SEQUENCE oliphaunt_autoinc_sequence START 11;", + "CREATE TABLE oliphaunt_autoinc (id integer, value text);", + "CREATE TRIGGER oliphaunt_autoinc_trigger BEFORE INSERT ON oliphaunt_autoinc\nFOR EACH ROW EXECUTE FUNCTION autoinc('id', 'oliphaunt_autoinc_sequence');", + "INSERT INTO oliphaunt_autoinc VALUES (NULL, 'generated'), (50, 'preserved');", + "-- oliphaunt-verify\nDO $oliphaunt$\nBEGIN\n IF (SELECT array_agg(id ORDER BY id) FROM oliphaunt_autoinc) IS DISTINCT FROM ARRAY[11, 50] THEN\n RAISE EXCEPTION 'autoinc did not generate a missing id and preserve an explicit id';\n END IF;\nEND\n$oliphaunt$;" + ], "bloom": [ "CREATE TEMP TABLE oliphaunt_bloom (id int, value int);", "CREATE INDEX oliphaunt_bloom_idx ON oliphaunt_bloom USING bloom (id, value);", @@ -267,6 +326,14 @@ export const GENERATED_MOBILE_EXTENSION_SMOKE = { "INSERT INTO oliphaunt_hstore VALUES ('a=>1,b=>2'::hstore);", "DO $$ DECLARE v text; BEGIN SELECT attrs -> 'b' INTO v FROM oliphaunt_hstore; IF v <> '2' THEN RAISE EXCEPTION 'hstore lookup failed: %', v; END IF; END $$;" ], + "insert_username": [ + "DROP TABLE IF EXISTS oliphaunt_insert_username;", + "CREATE TABLE oliphaunt_insert_username (id integer, username text, expected_username text);", + "CREATE TRIGGER oliphaunt_insert_username_trigger BEFORE INSERT OR UPDATE ON oliphaunt_insert_username\nFOR EACH ROW EXECUTE FUNCTION insert_username('username');", + "INSERT INTO oliphaunt_insert_username VALUES (1, 'untrusted', current_user);", + "UPDATE oliphaunt_insert_username SET username = 'still untrusted';", + "-- oliphaunt-verify\nDO $oliphaunt$\nBEGIN\n IF NOT EXISTS (SELECT FROM oliphaunt_insert_username WHERE username = expected_username) THEN\n RAISE EXCEPTION 'insert_username did not replace the caller-supplied username';\n END IF;\nEND\n$oliphaunt$;" + ], "intarray": [ "CREATE TEMP TABLE oliphaunt_intarray (tags int[]);", "INSERT INTO oliphaunt_intarray VALUES (ARRAY[1, 2, 5]), (ARRAY[3, 4]);", @@ -285,11 +352,23 @@ export const GENERATED_MOBILE_EXTENSION_SMOKE = { "INSERT INTO oliphaunt_ltree VALUES ('Top.Science.Astronomy'), ('Top.Collections.Pictures');", "DO $$ DECLARE n int; BEGIN SELECT count(*) INTO n FROM oliphaunt_ltree WHERE path <@ 'Top.Science'; IF n <> 1 THEN RAISE EXCEPTION 'ltree ancestor query failed: %', n; END IF; END $$;" ], + "moddatetime": [ + "DROP TABLE IF EXISTS oliphaunt_moddatetime;", + "CREATE TABLE oliphaunt_moddatetime (id integer, modified_at timestamptz);", + "CREATE TRIGGER oliphaunt_moddatetime_trigger BEFORE UPDATE ON oliphaunt_moddatetime\nFOR EACH ROW EXECUTE FUNCTION moddatetime('modified_at');", + "INSERT INTO oliphaunt_moddatetime VALUES (1, '2000-01-01 00:00:00+00');", + "UPDATE oliphaunt_moddatetime SET id = 2;", + "-- oliphaunt-verify\nDO $oliphaunt$\nBEGIN\n IF NOT EXISTS (SELECT FROM oliphaunt_moddatetime WHERE id = 2 AND modified_at > '2000-01-01 00:00:00+00') THEN\n RAISE EXCEPTION 'moddatetime did not update the modification timestamp';\n END IF;\nEND\n$oliphaunt$;" + ], "pageinspect": [ "CREATE TEMP TABLE oliphaunt_pageinspect (id int);", "INSERT INTO oliphaunt_pageinspect SELECT generate_series(1, 5);", "SELECT * FROM page_header(get_raw_page('oliphaunt_pageinspect', 0));" ], + "passwordcheck": [ + "-- oliphaunt-verify\nLOAD 'passwordcheck';", + "-- oliphaunt-verify\nDO $oliphaunt$\nBEGIN\n CREATE ROLE oliphaunt_passwordcheck_probe;\n BEGIN\n ALTER ROLE oliphaunt_passwordcheck_probe PASSWORD 'short';\n RAISE EXCEPTION 'passwordcheck accepted a short password';\n EXCEPTION WHEN invalid_parameter_value THEN\n IF SQLERRM <> 'password is too short' THEN\n RAISE;\n END IF;\n END;\n ALTER ROLE oliphaunt_passwordcheck_probe PASSWORD 'a_nice_long_password';\n DROP ROLE oliphaunt_passwordcheck_probe;\nEND\n$oliphaunt$;" + ], "pg_buffercache": [ "SELECT * FROM pg_buffercache_summary();", "SELECT * FROM pg_buffercache_usage_counts();" @@ -304,12 +383,39 @@ export const GENERATED_MOBILE_EXTENSION_SMOKE = { "DO $$ BEGIN IF id_encode(1001) <> 'jNl' THEN RAISE EXCEPTION 'pg_hashids encode failed'; END IF; IF id_decode_once('jNl') <> 1001 THEN RAISE EXCEPTION 'pg_hashids decode failed'; END IF; END $$;" ], "pg_ivm": [ + "DROP TABLE IF EXISTS oliphaunt_ivm_restored;", "DROP TABLE IF EXISTS oliphaunt_ivm_summary;", "DROP TABLE IF EXISTS oliphaunt_ivm_orders;", "CREATE TABLE oliphaunt_ivm_orders (id int, amount int);", "INSERT INTO oliphaunt_ivm_orders VALUES (1, 10), (2, 20);", "SELECT pgivm.create_immv('oliphaunt_ivm_summary', $$ SELECT id, amount FROM oliphaunt_ivm_orders $$);", - "-- oliphaunt-verify\nDO $$\nDECLARE n int;\nBEGIN\n SELECT count(*) INTO n FROM oliphaunt_ivm_summary;\n IF n <> 2 THEN RAISE EXCEPTION 'pg_ivm count failed: %', n; END IF;\n UPDATE oliphaunt_ivm_orders SET amount = 11 WHERE id = 1;\n SELECT amount INTO n FROM oliphaunt_ivm_summary WHERE id = 1;\n IF n IS DISTINCT FROM 11 THEN RAISE EXCEPTION 'pg_ivm maintenance failed: %', n; END IF;\n UPDATE oliphaunt_ivm_orders SET amount = 10 WHERE id = 1;\nEND $$;" + "-- Recreate metadata for an existing populated relation, as after pg_dump.\nCREATE TABLE oliphaunt_ivm_restored AS SELECT id, amount FROM oliphaunt_ivm_orders;", + "SELECT pgivm.restore_immv('oliphaunt_ivm_restored', $$ SELECT id, amount FROM oliphaunt_ivm_orders $$);", + "-- oliphaunt-verify\nDO $$\nDECLARE n int; populated boolean;\nBEGIN\n SELECT count(*) INTO n FROM oliphaunt_ivm_summary;\n IF n <> 2 THEN RAISE EXCEPTION 'pg_ivm count failed: %', n; END IF;\n UPDATE oliphaunt_ivm_orders SET amount = 11 WHERE id = 1;\n SELECT amount INTO n FROM oliphaunt_ivm_summary WHERE id = 1;\n IF n IS DISTINCT FROM 11 THEN RAISE EXCEPTION 'pg_ivm maintenance failed: %', n; END IF;\n UPDATE oliphaunt_ivm_orders SET amount = 10 WHERE id = 1;\n SELECT ispopulated INTO populated FROM pgivm.pg_ivm_immv\n WHERE immvrelid = 'oliphaunt_ivm_restored'::regclass;\n IF populated IS DISTINCT FROM true THEN\n RAISE EXCEPTION 'pg_ivm restored relation lost populated state';\n END IF;\n -- Before 1.17 this refresh added duplicate maintenance triggers after restore.\n PERFORM pgivm.refresh_immv('oliphaunt_ivm_restored');\n INSERT INTO oliphaunt_ivm_orders VALUES (99, 30);\n SELECT count(*) INTO n FROM oliphaunt_ivm_restored WHERE id = 99;\n IF n <> 1 THEN RAISE EXCEPTION 'pg_ivm restored maintenance duplicated rows: %', n; END IF;\n DELETE FROM oliphaunt_ivm_orders WHERE id = 99;\nEND $$;" + ], + "pg_logicalinspect": [ + "-- Exercise both entry points without requiring a logical replication slot.\n-- Invalid snapshot names must be rejected before any filesystem access.\n-- oliphaunt-verify\nDO $oliphaunt$\nBEGIN\n BEGIN\n PERFORM pg_get_logical_snapshot_meta('../invalid');\n RAISE EXCEPTION 'pg_logicalinspect accepted an invalid snapshot name';\n EXCEPTION WHEN internal_error THEN\n IF SQLERRM <> 'invalid snapshot file name \"../invalid\"' THEN\n RAISE;\n END IF;\n END;\n BEGIN\n PERFORM pg_get_logical_snapshot_info('../invalid');\n RAISE EXCEPTION 'pg_logicalinspect accepted an invalid snapshot name';\n EXCEPTION WHEN internal_error THEN\n IF SQLERRM <> 'invalid snapshot file name \"../invalid\"' THEN\n RAISE;\n END IF;\n END;\nEND\n$oliphaunt$;" + ], + "pg_overexplain": [ + "-- oliphaunt-verify\nLOAD 'pg_overexplain';", + "-- oliphaunt-verify\nDO $oliphaunt$\nDECLARE\n document jsonb;\nBEGIN\n EXECUTE 'EXPLAIN (DEBUG, RANGE_TABLE, FORMAT JSON, COSTS OFF) SELECT oid FROM pg_class WHERE relname = ''pg_class'''\n INTO document;\n IF (document->0->'Plan' ? 'Plan Node ID') IS DISTINCT FROM true\n OR COALESCE(jsonb_array_length(document->0->'Range Table'), 0) < 1 THEN\n RAISE EXCEPTION 'pg_overexplain did not include plan IDs and the range table: %', document;\n END IF;\nEND\n$oliphaunt$;" + ], + "pg_partman": [ + "SELECT set_config('search_path', quote_ident(n.nspname) || ', public', false)\nFROM pg_extension e JOIN pg_namespace n ON n.oid = e.extnamespace\nWHERE e.extname = 'pg_partman';", + "CREATE TABLE public.oliphaunt_partman_events (id bigint NOT NULL, payload text)\nPARTITION BY RANGE (id);", + "SELECT create_parent('public.oliphaunt_partman_events', 'id', '10',\n p_premake := 2, p_start_partition := '0', p_jobmon := false);", + "INSERT INTO public.oliphaunt_partman_events VALUES (1, 'old'), (25, 'retained');", + "SELECT run_maintenance('public.oliphaunt_partman_events', p_jobmon := false);", + "DO $$\nBEGIN\n IF to_regclass('public.oliphaunt_partman_events_p40') IS NULL THEN\n RAISE EXCEPTION 'pg_partman did not premake partitions beyond the highest ID';\n END IF;\nEND $$;", + "UPDATE part_config SET retention = '10', retention_keep_table = false\nWHERE parent_table = 'public.oliphaunt_partman_events';", + "SELECT run_maintenance('public.oliphaunt_partman_events', p_jobmon := false);", + "-- oliphaunt-verify\nSELECT set_config('search_path', quote_ident(n.nspname) || ', public', false)\nFROM pg_extension e JOIN pg_namespace n ON n.oid = e.extnamespace\nWHERE e.extname = 'pg_partman';", + "DO $$\nBEGIN\n IF to_regclass('public.oliphaunt_partman_events_p0') IS NOT NULL THEN\n RAISE EXCEPTION 'pg_partman did not remove the expired ID partition';\n END IF;\n IF (SELECT count(*) FROM public.oliphaunt_partman_events) <> 1\n OR NOT EXISTS (SELECT FROM public.oliphaunt_partman_events WHERE id = 25 AND payload = 'retained') THEN\n RAISE EXCEPTION 'pg_partman retention removed or changed the retained row';\n END IF;\n IF NOT EXISTS (SELECT FROM part_config WHERE parent_table = 'public.oliphaunt_partman_events') THEN\n RAISE EXCEPTION 'pg_partman configuration did not survive';\n END IF;\nEND $$;" + ], + "pg_stat_statements": [ + "-- Reset and collect fresh counters on creation, restart, and backup restore.\n-- This fails if the library was loaded after shared-memory startup.\n-- oliphaunt-verify\nSELECT pg_stat_statements_reset();", + "-- oliphaunt-verify\nSELECT sum(value) FROM generate_series(1, 3) AS oliphaunt_pgss_probe(value);", + "-- oliphaunt-verify\nDO $oliphaunt$\nBEGIN\n IF NOT EXISTS (\n SELECT FROM pg_stat_statements\n WHERE query LIKE 'SELECT sum(value) FROM generate_series%oliphaunt_pgss_probe%'\n AND dbid = (SELECT oid FROM pg_database WHERE datname = current_database())\n AND queryid <> 0 AND calls >= 1 AND rows = calls\n ) THEN\n RAISE EXCEPTION 'pg_stat_statements did not record a completed query';\n END IF;\nEND\n$oliphaunt$;" ], "pg_surgery": [ "DO $$ BEGIN IF NOT EXISTS (SELECT 1 FROM pg_proc WHERE proname = 'heap_force_kill') THEN RAISE EXCEPTION 'pg_surgery function missing'; END IF; END $$;" @@ -350,6 +456,18 @@ export const GENERATED_MOBILE_EXTENSION_SMOKE = { "DO $$ DECLARE armored text; header_count int; BEGIN SELECT armor(digest('test', 'sha1'), ARRAY['Version'], ARRAY['oliphaunt']) INTO armored; IF position('Version: oliphaunt' in armored) = 0 THEN RAISE EXCEPTION 'armor header failed'; END IF; SELECT count(*) INTO header_count FROM pgp_armor_headers(armored); IF header_count <> 1 THEN RAISE EXCEPTION 'armor header count failed: %', header_count; END IF; END $$;", "DO $$ DECLARE encrypted bytea; crypto_key bytea := decode('000102030405060708090a0b0c0d0e0f', 'hex'); crypto_iv bytea := decode('101112131415161718191a1b1c1d1e1f', 'hex'); BEGIN SELECT pgp_sym_encrypt('oliphaunt secret', 'passphrase') INTO encrypted; IF pgp_key_id(encrypted) <> 'SYMKEY' THEN RAISE EXCEPTION 'PGP symmetric key id failed'; END IF; SELECT encrypt(convert_to('oliphaunt raw cipher', 'UTF8'), crypto_key, 'aes') INTO encrypted; IF convert_from(decrypt(encrypted, crypto_key, 'aes'), 'UTF8') <> 'oliphaunt raw cipher' THEN RAISE EXCEPTION 'raw decrypt failed'; END IF; SELECT encrypt_iv(convert_to('oliphaunt iv cipher', 'UTF8'), crypto_key, crypto_iv, 'aes-cbc') INTO encrypted; IF convert_from(decrypt_iv(encrypted, crypto_key, crypto_iv, 'aes-cbc'), 'UTF8') <> 'oliphaunt iv cipher' THEN RAISE EXCEPTION 'raw iv decrypt failed'; END IF; END $$;" ], + "pgmq": [ + "DO $proof$\nBEGIN\n IF EXISTS (SELECT FROM pgmq.meta WHERE queue_name = 'oliphaunt_queue') THEN\n PERFORM pgmq.drop_queue('oliphaunt_queue');\n END IF;\nEND\n$proof$;", + "SELECT pgmq.create('oliphaunt_queue');", + "SELECT pgmq.send('oliphaunt_queue', '{\"payload\":\"persistent\"}'::jsonb);", + "DO $proof$\nDECLARE\n message record;\nBEGIN\n SELECT * INTO STRICT message FROM pgmq.read('oliphaunt_queue', 30, 1);\n IF message.message <> '{\"payload\":\"persistent\"}'::jsonb OR message.read_ct <> 1 THEN\n RAISE EXCEPTION 'PGMQ read lost payload or delivery count';\n END IF;\n IF EXISTS (SELECT FROM pgmq.read('oliphaunt_queue', 30, 1)) THEN\n RAISE EXCEPTION 'PGMQ visibility timeout did not hide the leased message';\n END IF;\n IF NOT pgmq.archive('oliphaunt_queue', message.msg_id) THEN\n RAISE EXCEPTION 'PGMQ archive failed';\n END IF;\n IF (SELECT count(*) FROM pgmq.a_oliphaunt_queue) <> 1 THEN\n RAISE EXCEPTION 'PGMQ archive lost the message';\n END IF;\nEND\n$proof$;", + "SELECT pgmq.send('oliphaunt_queue', '{\"payload\":\"delete\"}'::jsonb);", + "DO $proof$\nDECLARE\n message record;\nBEGIN\n SELECT * INTO STRICT message FROM pgmq.pop('oliphaunt_queue');\n IF message.message <> '{\"payload\":\"delete\"}'::jsonb THEN\n RAISE EXCEPTION 'PGMQ pop returned the wrong message';\n END IF;\n IF EXISTS (SELECT FROM pgmq.read('oliphaunt_queue', 30, 1)) THEN\n RAISE EXCEPTION 'PGMQ pop did not remove the message';\n END IF;\nEND\n$proof$;", + "SELECT pgmq.create('oliphaunt_drop_queue');", + "SELECT pgmq.drop_queue('oliphaunt_drop_queue');", + "SELECT pgmq.send('oliphaunt_queue', '{\"payload\":\"restart-and-restore\"}'::jsonb);", + "-- oliphaunt-verify\nDO $proof$\nBEGIN\n IF (SELECT count(*) FROM pgmq.q_oliphaunt_queue) <> 1 OR\n NOT EXISTS (SELECT FROM pgmq.q_oliphaunt_queue\n WHERE message = '{\"payload\":\"restart-and-restore\"}'::jsonb) THEN\n RAISE EXCEPTION 'PGMQ persistent queue message did not survive';\n END IF;\n IF (SELECT count(*) FROM pgmq.a_oliphaunt_queue) <> 1 OR\n NOT EXISTS (SELECT FROM pgmq.a_oliphaunt_queue\n WHERE message = '{\"payload\":\"persistent\"}'::jsonb) THEN\n RAISE EXCEPTION 'PGMQ archived message did not survive';\n END IF;\nEND\n$proof$;" + ], "pgtap": [ "SELECT plan(2);", "SELECT ok(true, 'pgTAP ok() executes');", @@ -363,6 +481,19 @@ export const GENERATED_MOBILE_EXTENSION_SMOKE = { "CREATE INDEX oliphaunt_postgis_points_gix ON oliphaunt_postgis_points USING GIST (geom);", "-- oliphaunt-verify\nDO $$\nDECLARE\n distance float8;\n srid int;\n area float8;\n polygons int;\n nearby int;\nBEGIN\n SELECT ST_Distance(ST_GeomFromText('POINT(0 0)'), ST_GeomFromText('POINT(3 4)')) INTO distance;\n IF distance <> 5 THEN\n RAISE EXCEPTION 'postgis geometry distance failed: %', distance;\n END IF;\n IF ST_AsText(ST_Buffer(ST_GeomFromText('POINT(0 0)'), 1, 'quad_segs=1')) IS NULL THEN\n RAISE EXCEPTION 'postgis buffer failed';\n END IF;\n IF NOT ST_Within(\n ST_GeomFromText('POINT(0.5 0.5)'),\n ST_GeomFromText('POLYGON((0 0,0 1,1 1,1 0,0 0))')\n ) THEN\n RAISE EXCEPTION 'postgis within failed';\n END IF;\n SELECT ST_SRID(ST_Transform(ST_SetSRID(ST_MakePoint(-71.060316, 48.432044), 4326), 3857)) INTO srid;\n IF srid <> 3857 THEN\n RAISE EXCEPTION 'postgis transform failed: %', srid;\n END IF;\n SELECT ST_Area(ST_Transform(ST_SetSRID(ST_MakePolygon(ST_GeomFromText('LINESTRING(-71.1776848522251 42.3902896512902,-71.1776843766797 42.3903701743239,-71.1775844305465 42.3903829478009,-71.1775825927231 42.3902893647987,-71.1776848522251 42.3902896512902)')), 4326), 26986)) INTO area;\n IF area <= 0 THEN\n RAISE EXCEPTION 'postgis projected area failed: %', area;\n END IF;\n SELECT ST_NumGeometries(ST_Polygonize(ARRAY[\n ST_GeomFromText('LINESTRING(0 0, 1 0)'),\n ST_GeomFromText('LINESTRING(1 0, 1 1)'),\n ST_GeomFromText('LINESTRING(1 1, 0 1)'),\n ST_GeomFromText('LINESTRING(0 1, 0 0)')\n ])) INTO polygons;\n IF polygons <> 1 THEN\n RAISE EXCEPTION 'postgis polygonize failed: %', polygons;\n END IF;\n SELECT count(*) INTO nearby\n FROM oliphaunt_postgis_points\n WHERE ST_DWithin(\n geom::geography,\n ST_SetSRID(ST_MakePoint(-71.060316, 48.432044), 4326)::geography,\n 200\n );\n IF nearby <> 2 THEN\n RAISE EXCEPTION 'postgis dwithin failed: %', nearby;\n END IF;\nEND $$;" ], + "refint": [ + "DROP TABLE IF EXISTS oliphaunt_refint_child;", + "DROP TABLE IF EXISTS oliphaunt_refint_parent;", + "CREATE TABLE oliphaunt_refint_parent (id integer PRIMARY KEY);", + "CREATE TABLE oliphaunt_refint_child (parent_id integer);", + "CREATE TRIGGER oliphaunt_refint_parent_trigger AFTER DELETE OR UPDATE ON oliphaunt_refint_parent\nFOR EACH ROW EXECUTE FUNCTION check_foreign_key(1, 'cascade', 'id', 'oliphaunt_refint_child', 'parent_id');", + "CREATE TRIGGER oliphaunt_refint_child_trigger AFTER INSERT OR UPDATE ON oliphaunt_refint_child\nFOR EACH ROW EXECUTE FUNCTION check_primary_key('parent_id', 'oliphaunt_refint_parent', 'id');", + "INSERT INTO oliphaunt_refint_parent VALUES (1), (2);", + "INSERT INTO oliphaunt_refint_child VALUES (1), (2);", + "DO $oliphaunt$\nBEGIN\n BEGIN\n INSERT INTO oliphaunt_refint_child VALUES (3);\n RAISE EXCEPTION 'refint accepted a missing parent';\n EXCEPTION WHEN triggered_action_exception THEN\n NULL;\n END;\nEND\n$oliphaunt$;", + "DELETE FROM oliphaunt_refint_parent WHERE id = 1;", + "-- oliphaunt-verify\nDO $oliphaunt$\nBEGIN\n IF (SELECT array_agg(parent_id) FROM oliphaunt_refint_child) IS DISTINCT FROM ARRAY[2] THEN\n RAISE EXCEPTION 'refint did not cascade deletion to the referencing row';\n END IF;\nEND\n$oliphaunt$;" + ], "seg": [ "DO $$ BEGIN IF '7(+-)1'::seg::text <> '6 .. 8' THEN RAISE EXCEPTION 'seg cast failed'; END IF; END $$;" ], @@ -395,6 +526,14 @@ export const GENERATED_MOBILE_EXTENSION_SMOKE = { "DROP TABLE IF EXISTS oliphaunt_vector;", "CREATE TABLE oliphaunt_vector (id int PRIMARY KEY, embedding vector(3));", "INSERT INTO oliphaunt_vector VALUES (1, '[1,2,3]');", - "-- oliphaunt-verify\nDO $$ DECLARE d float8; BEGIN SELECT embedding <-> '[1,2,4]'::vector INTO d FROM oliphaunt_vector WHERE id = 1; IF d IS DISTINCT FROM 1 THEN RAISE EXCEPTION 'vector distance failed: %', d; END IF; END $$;" + "DROP TABLE IF EXISTS oliphaunt_vector_indexed;", + "CREATE TABLE oliphaunt_vector_indexed (id int PRIMARY KEY, embedding vector(3));", + "INSERT INTO oliphaunt_vector_indexed SELECT i, ARRAY[i, i, i]::vector FROM generate_series(1, 64) i;", + "CREATE INDEX ON oliphaunt_vector_indexed USING hnsw (embedding vector_l2_ops);", + "DELETE FROM oliphaunt_vector_indexed WHERE id = 32;", + "VACUUM oliphaunt_vector_indexed;", + "INSERT INTO oliphaunt_vector_indexed VALUES (32, '[32,32,32]');", + "-- oliphaunt-verify\nDO $$ DECLARE d float8; BEGIN SELECT embedding <-> '[1,2,4]'::vector INTO d FROM oliphaunt_vector WHERE id = 1; IF d IS DISTINCT FROM 1 THEN RAISE EXCEPTION 'vector distance failed: %', d; END IF; END $$;", + "DO $$\nDECLARE nearest int;\nBEGIN\n PERFORM set_config('enable_seqscan', 'off', true);\n SELECT id INTO nearest FROM oliphaunt_vector_indexed ORDER BY embedding <-> '[32,32,32]'::vector LIMIT 1;\n IF nearest IS DISTINCT FROM 32 THEN\n RAISE EXCEPTION 'vector HNSW search after vacuum/insert failed: %', nearest;\n END IF;\nEND $$;" ] } as const satisfies Readonly>; diff --git a/src/examples/native/react-native-expo/src/mobile-smoke.ts b/src/examples/native/react-native-expo/src/mobile-smoke.ts index e8b9e0b4e..56d015d22 100644 --- a/src/examples/native/react-native-expo/src/mobile-smoke.ts +++ b/src/examples/native/react-native-expo/src/mobile-smoke.ts @@ -236,6 +236,25 @@ async function provePgTextsearchEnglishSnowball(db: OliphauntDatabase): Promise< } } +export function activationSqlForExtension(extension: { + readonly sqlName: string; + readonly createsExtension: boolean; +}): readonly string[] { + if (extension.createsExtension) { + return [`CREATE EXTENSION "${extension.sqlName}"`]; + } + if (extension.sqlName === 'auto_explain') { + return [ + "LOAD 'auto_explain'", + "SET auto_explain.log_min_duration = '0'", + "SET auto_explain.log_analyze = 'true'", + "SET auto_explain.log_level = 'NOTICE'", + ]; + } + // Other LOAD-only modules are activated by their canonical smoke recipes. + return []; +} + export async function runMobileReleaseExtensionProof( db: OliphauntDatabase, plan: readonly MobileReleaseExtensionProof[], @@ -277,12 +296,15 @@ export async function runMobileReleaseExtensionProof( return `${extension.sqlName} ${version}; dependency closure ${extension.selectedExtensionDependencies.join(',') || 'none'}`; } - const configured = await scalar( - db, - "SELECT current_setting('auto_explain.log_min_duration')::text AS value", - ); - assertEqual(configured, '0', 'auto_explain load/configuration proof'); - return 'auto_explain loaded and configured in the installed app session'; + if (extension.sqlName === 'auto_explain') { + const configured = await scalar( + db, + "SELECT current_setting('auto_explain.log_min_duration')::text AS value", + ); + assertEqual(configured, '0', 'auto_explain load/configuration proof'); + return 'auto_explain loaded and configured in the installed app session'; + } + return `${extension.sqlName} canonical LOAD-only smoke proof completed in the installed app session`; }, onCheckStage, ); diff --git a/src/examples/native/react-native-expo/tools/mobile-extension-proof.test.mts b/src/examples/native/react-native-expo/tools/mobile-extension-proof.test.mts index 5a457d9e7..84c3112bb 100644 --- a/src/examples/native/react-native-expo/tools/mobile-extension-proof.test.mts +++ b/src/examples/native/react-native-expo/tools/mobile-extension-proof.test.mts @@ -1,5 +1,9 @@ import assert from 'node:assert/strict'; import { mock, test } from 'bun:test'; +import { + GENERATED_MOBILE_EXTENSION_PLAN, + GENERATED_MOBILE_EXTENSION_SMOKE, +} from '../src/generated/extension-smoke'; class FixturePostgresError extends Error {} @@ -10,7 +14,9 @@ mock.module('@oliphaunt/react-native', () => ({ }, })); -const { runMobileReleaseExtensionProof } = await import('../src/mobile-smoke.ts'); +const { activationSqlForExtension, runMobileReleaseExtensionProof } = await import( + '../src/mobile-smoke.ts' +); const { serializeExpoSmokePassReceipt } = await import('../src/smoke-pass-receipt.ts'); function queryResult(values) { @@ -53,7 +59,10 @@ test('the successful pg_textsearch producer supplies every semantic PASS fact', createsExtension: true, nativeModuleStem: 'pg_textsearch', selectedExtensionDependencies: [], - activationSql: ['CREATE EXTENSION pg_textsearch'], + activationSql: activationSqlForExtension({ + sqlName: 'pg_textsearch', + createsExtension: true, + }), smokeStatements: ['SELECT 1'], }, ]); @@ -62,7 +71,7 @@ test('the successful pg_textsearch producer supplies every semantic PASS fact', assert.equal(proof.extensionCatalogComplete, true); assert.equal(proof.pgTextsearchEnglishBm25, true); assert.deepEqual(executed, [ - 'CREATE EXTENSION pg_textsearch', + 'CREATE EXTENSION "pg_textsearch"', 'DROP TABLE IF EXISTS oliphaunt_mobile_pg_textsearch_english', 'CREATE TABLE oliphaunt_mobile_pg_textsearch_english (id bigint PRIMARY KEY, body text NOT NULL)', `INSERT INTO oliphaunt_mobile_pg_textsearch_english (id, body) VALUES @@ -102,3 +111,79 @@ test('the successful pg_textsearch producer supplies every semantic PASS fact', assert.equal(receipt.extensionCatalogComplete, true); assert.equal(receipt.pgTextsearchEnglishBm25, true); }); + +for (const sqlName of ['passwordcheck', 'pg_overexplain']) { + test(`${sqlName} proves its generated LOAD-only recipe without auto_explain`, async () => { + const extension = GENERATED_MOBILE_EXTENSION_PLAN.find((row) => row.sqlName === sqlName); + assert.ok(extension); + assert.equal(extension.createsExtension, false); + const smokeStatements = GENERATED_MOBILE_EXTENSION_SMOKE[sqlName]; + const queried = []; + const db = { + async execute(sql) { + throw new Error(`unexpected LOAD-only activation: ${sql}`); + }, + async query(sql) { + queried.push(sql); + if (smokeStatements.includes(sql)) return queryResult({}); + if (sql.includes('string_agg')) return queryResult({ value: '' }); + throw new Error(`unexpected LOAD-only query: ${sql}`); + }, + }; + const proof = await runMobileReleaseExtensionProof(db, [ + { + ...extension, + activationSql: activationSqlForExtension(extension), + smokeStatements, + }, + ]); + assert.deepEqual(queried.slice(0, -1), smokeStatements); + assert.deepEqual(proof.activatedExtensions, [sqlName]); + assert.equal(proof.extensionCatalogComplete, true); + assert.equal(proof.pgTextsearchEnglishBm25, false); + assert.equal(proof.checks[0].name, `extension activation: ${sqlName}`); + assert.equal( + proof.checks[0].detail, + `${sqlName} canonical LOAD-only smoke proof completed in the installed app session`, + ); + }); +} + +test('auto_explain still requires its configured logging duration', async () => { + const extension = GENERATED_MOBILE_EXTENSION_PLAN.find((row) => row.sqlName === 'auto_explain'); + assert.ok(extension); + const executed = []; + let logMinDuration = '0'; + const db = { + async execute(sql) { + executed.push(sql); + }, + async query(sql) { + if (GENERATED_MOBILE_EXTENSION_SMOKE.auto_explain.includes(sql)) return queryResult({}); + if (sql === "SELECT current_setting('auto_explain.log_min_duration')::text AS value") + return queryResult({ value: logMinDuration }); + if (sql.includes('string_agg')) return queryResult({ value: '' }); + throw new Error(`unexpected auto_explain query: ${sql}`); + }, + }; + const plan = [ + { + ...extension, + activationSql: activationSqlForExtension(extension), + smokeStatements: GENERATED_MOBILE_EXTENSION_SMOKE.auto_explain, + }, + ]; + const proof = await runMobileReleaseExtensionProof(db, plan); + assert.deepEqual(executed, [ + "LOAD 'auto_explain'", + "SET auto_explain.log_min_duration = '0'", + "SET auto_explain.log_analyze = 'true'", + "SET auto_explain.log_level = 'NOTICE'", + ]); + assert.equal(proof.extensionCatalogComplete, true); + logMinDuration = '-1'; + await assert.rejects( + () => runMobileReleaseExtensionProof(db, plan), + /auto_explain load\/configuration proof/, + ); +}); diff --git a/src/extensions/artifacts/native/tools/build-windows-extensions.sh b/src/extensions/artifacts/native/tools/build-windows-extensions.sh index eb17ffd30..9f3d8c7bf 100644 --- a/src/extensions/artifacts/native/tools/build-windows-extensions.sh +++ b/src/extensions/artifacts/native/tools/build-windows-extensions.sh @@ -141,7 +141,7 @@ windows_extension_postgis_flatgeobuf() { logged flatgeobuf-library.log native lib.exe /nologo "/OUT:$(native_path "$prefix/lib/flatgeobuf.lib")" "${objects[@]}" } -windows_extension_install() { +windows_extension_install_pgtap() { selected pgtap || return 0 local directory="$work_root/pgtap-windows" destination="$install_dir/share/postgresql/extension" windows_extension_generate pgtap @@ -152,3 +152,9 @@ windows_extension_install() { mkdir -p "$destination" cp "$directory/pgtap.control" "$directory/sql/"pgtap*.sql "$directory/sql/uninstall_pgtap.sql" "$destination/" } + +windows_extension_install() { + windows_extension_install_pgtap + if selected pgmq; then windows_extension_generate pgmq-install; fi + if selected pg_partman; then windows_extension_generate pg_partman-install; fi +} diff --git a/src/extensions/artifacts/native/tools/package-release-assets.sh b/src/extensions/artifacts/native/tools/package-release-assets.sh index ccbcb86aa..97537e68c 100755 --- a/src/extensions/artifacts/native/tools/package-release-assets.sh +++ b/src/extensions/artifacts/native/tools/package-release-assets.sh @@ -616,11 +616,13 @@ package_ios_target() { ios_device_root="$mobile_extension_work_root/$target_id/ios-device" macos_archive_root="$mobile_extension_work_root/$target_id/macos-extension-archives" ios_xcframework_root="$mobile_extension_work_root/$target_id/ios-extension-xcframeworks" - require_dir "$ios_xcframework_root/out" "iOS extension XCFramework output" - tools/dev/bun.sh tools/packaging/platform-binary-contract.mts \ - --target "$target_id" \ - --root "$ios_xcframework_root/out" \ - --required-apple-platforms macos,ios,ios-simulator + if [ -n "$mobile_extensions" ]; then + require_dir "$ios_xcframework_root/out" "iOS extension XCFramework output" + tools/dev/bun.sh tools/packaging/platform-binary-contract.mts \ + --target "$target_id" \ + --root "$ios_xcframework_root/out" \ + --required-apple-platforms macos,ios,ios-simulator + fi local sql_name pg_major creates_extension stem dependencies shared_preload desktop_prebuilt mobile_prebuilt mobile_static_required mobile_static_targets data_files artifact_policy runtime_artifact ios_artifact static_prefix registration_artifact dependency dependency_xcframework dependency_artifact while IFS=$'\t' read -r sql_name pg_major creates_extension stem dependencies shared_preload desktop_prebuilt mobile_prebuilt mobile_static_required mobile_static_targets data_files artifact_policy; do [ -n "$sql_name" ] || continue @@ -764,6 +766,9 @@ package_android_target() { done < <(catalog_rows) } +# Tests can call the real packaging functions with independently produced inputs. +if [ "${BASH_SOURCE[0]}" != "$0" ]; then return 0; fi + phase="${OLIPHAUNT_EXTENSION_PHASE:-all}" case "$phase:$target_id" in all:*) fetch_extension_source_assets ;; diff --git a/src/extensions/artifacts/native/tools/package-release-assets.test.sh b/src/extensions/artifacts/native/tools/package-release-assets.test.sh index b68aa39df..50c80fcee 100644 --- a/src/extensions/artifacts/native/tools/package-release-assets.test.sh +++ b/src/extensions/artifacts/native/tools/package-release-assets.test.sh @@ -40,4 +40,30 @@ if OLIPHAUNT_EXTENSION_PHASE=android-package OLIPHAUNT_EXTENSION_TARGET=ios-xcfr echo 'accepted Android phase for iOS' >&2; exit 1 fi grep -q 'invalid extension phase' "$scratch/wrong-phase.log" -echo 'Android split extension producer checks passed' + +# SQL-only iOS products do not produce an XCFramework. Exercise the real +# packager with a host fixture, replacing only the platform compiler producer. +( + export OLIPHAUNT_EXTENSION_TARGET=ios-xcframework + export OLIPHAUNT_EXTENSION_PRODUCTS=oliphaunt-extension-pgmq + export OLIPHAUNT_EXTENSION_HOST_RUNTIME_ROOT="$scratch/ios-host" + export OLIPHAUNT_EXTENSION_RELEASE_ASSET_DIR="$scratch/ios-assets" + export OLIPHAUNT_EXTENSION_RELEASE_STAGE_ROOT="$scratch/ios-stage" + ios_sql="$scratch/ios-host/share/postgresql/extension" + mkdir -p "$ios_sql" + bun - "$scratch/ios-host/postgres" <<'JS' +import {writeFileSync} from 'node:fs'; +import {machoFixture} from './tools/packaging/testdata/release-fixture-utils.mts'; +writeFileSync(process.argv[2], machoFixture()); +JS + printf "default_version = '1.13.0'\n" > "$ios_sql/pgmq.control" + printf 'select 1;\n' > "$ios_sql/pgmq--1.13.0.sql" + source "$producer" + build_mobile_static_artifacts() { [ -z "$1" ]; } + bun "$packager" list-catalog > "$catalog_file" + write_indexes + package_ios_target + [ ! -e "$mobile_extension_work_root/ios-xcframework/ios-extension-xcframeworks/out" ] + [ "$(find "$out_dir" -name '*-pgmq-*-runtime.tar.gz' | wc -l)" = 1 ] +) +echo 'Android split and SQL-only iOS extension producer checks passed' diff --git a/src/extensions/artifacts/native/tools/windows-extension-sources.mts b/src/extensions/artifacts/native/tools/windows-extension-sources.mts index 3a2ef1259..11fbdaff0 100644 --- a/src/extensions/artifacts/native/tools/windows-extension-sources.mts +++ b/src/extensions/artifacts/native/tools/windows-extension-sources.mts @@ -583,6 +583,49 @@ export function pgtap(config: Config, install = false) { } } +// PGMQ's PGXS build only copies the canonical SQL and all versioned upgrades. +// Keep this equivalent Windows path independent of GNU Make or a C compiler. +export function installPgmq(config: Config) { + const directory = path.join( + config.repo, + 'target/oliphaunt-sources/checkouts/pgmq/pgmq-extension', + ); + const destination = path.join(config.install, 'share/postgresql/extension'); + const release = version(directory, 'pgmq'); + assert(/^[a-zA-Z0-9._-]+$/.test(release) && !release.includes('--'), 'invalid PGMQ version'); + mkdirSync(destination, { recursive: true }); + copyFileSync(path.join(directory, 'pgmq.control'), path.join(destination, 'pgmq.control')); + for (const file of glob(path.join(directory, 'sql'), 'pgmq--*.sql')) + copyFileSync(path.join(directory, 'sql', file), path.join(destination, file)); + copyFileSync( + path.join(directory, 'sql/pgmq.sql'), + path.join(destination, `pgmq--${release}.sql`), + ); +} + +export function installPartman(config: Config) { + const source = path.join(config.repo, 'target/oliphaunt-sources/checkouts/pg_partman'); + const destination = path.join(config.install, 'share/postgresql/extension'); + // Match the pinned Makefile's wildcard groups: types and tables precede functions. + const inputs = ['types', 'tables', 'functions', 'procedures'].flatMap((group) => { + const directory = path.join(source, 'sql', group); + const names = glob(directory, '*.sql'); + assert(names.length > 0, `pg_partman SQL group is empty: ${group}`); + return names.map((name) => read(path.join(directory, name))); + }); + write( + path.join(destination, `pg_partman--${version(source, 'pg_partman')}.sql`), + inputs.join(''), + ); + copyFileSync( + path.join(source, 'pg_partman.control'), + path.join(destination, 'pg_partman.control'), + ); + for (const name of glob(path.join(source, 'updates'), 'pg_partman--*--*.sql')) { + copyFileSync(path.join(source, 'updates', name), path.join(destination, name)); + } +} + if (import.meta.main) { const phase = process.argv[2]; const { values } = parseArgs({ @@ -627,12 +670,18 @@ if (import.meta.main) { case 'postgis-sql-unpackaged': postgisSql(config, phase); break; + case 'pg_partman-install': + installPartman(config); + break; case 'pgtap': pgtap(config); break; case 'pgtap-install': pgtap(config, true); break; + case 'pgmq-install': + installPgmq(config); + break; default: throw new Error(`unknown Windows extension phase ${phase}`); } diff --git a/src/extensions/artifacts/native/tools/windows-extension-sources.test.mts b/src/extensions/artifacts/native/tools/windows-extension-sources.test.mts index 8b409d260..53f5ed255 100644 --- a/src/extensions/artifacts/native/tools/windows-extension-sources.test.mts +++ b/src/extensions/artifacts/native/tools/windows-extension-sources.test.mts @@ -1,9 +1,72 @@ import { test } from 'bun:test'; import assert from 'node:assert/strict'; -import { mkdirSync, mkdtempSync, readFileSync, rmSync, writeFileSync } from 'node:fs'; +import { mkdirSync, mkdtempSync, readdirSync, readFileSync, rmSync, writeFileSync } from 'node:fs'; import { tmpdir } from 'node:os'; import path from 'node:path'; -import { pgxsSources, prepareSimple } from './windows-extension-sources.mts'; +import { + installPartman, + installPgmq, + pgxsSources, + prepareSimple, +} from './windows-extension-sources.mts'; + +test('PGMQ SQL packaging includes the current installation and upgrades, without unrelated files', () => { + const root = mkdtempSync(path.join(tmpdir(), 'pgmq-windows-')); + const source = path.join(root, 'target/oliphaunt-sources/checkouts/pgmq/pgmq-extension'); + const install = path.join(root, 'install'); + try { + mkdirSync(path.join(source, 'sql'), { recursive: true }); + writeFileSync(path.join(source, 'pgmq.control'), "default_version = '1.13.0'\n"); + writeFileSync(path.join(source, 'sql/pgmq.sql'), '-- current SQL\n'); + writeFileSync(path.join(source, 'sql/pgmq--1.12.0--1.13.0.sql'), '-- upgrade SQL\n'); + writeFileSync(path.join(source, 'sql/unrelated.sql'), '-- foreign SQL\n'); + installPgmq({ repo: root, work: root, postgres: root, install }); + const destination = path.join(install, 'share/postgresql/extension'); + assert.deepEqual(readdirSync(destination).sort(), [ + 'pgmq--1.12.0--1.13.0.sql', + 'pgmq--1.13.0.sql', + 'pgmq.control', + ]); + assert.equal( + readFileSync(path.join(destination, 'pgmq--1.13.0.sql'), 'utf8'), + '-- current SQL\n', + ); + } finally { + rmSync(root, { recursive: true, force: true }); + } +}); + +test('SQL-only pg_partman stages ordered install SQL and upgrades without workers or tools', () => { + const root = mkdtempSync(path.join(tmpdir(), 'partman-windows-')); + try { + const source = path.join(root, 'target/oliphaunt-sources/checkouts/pg_partman'); + for (const group of ['types', 'tables', 'functions', 'procedures']) { + mkdirSync(path.join(source, 'sql', group), { recursive: true }); + writeFileSync(path.join(source, 'sql', group, 'b.sql'), `${group}-b\n`); + writeFileSync(path.join(source, 'sql', group, 'a.sql'), `${group}-a\n`); + } + mkdirSync(path.join(source, 'updates')); + writeFileSync(path.join(source, 'updates', 'pg_partman--5.4.0--5.5.0.sql'), 'upgrade\n'); + writeFileSync(path.join(source, 'updates', 'foreign.sql'), 'excluded\n'); + writeFileSync(path.join(source, 'pg_partman.control'), "default_version = '5.5.0'\n"); + const install = path.join(root, 'install'); + installPartman({ repo: root, work: root, postgres: root, install }); + const destination = path.join(install, 'share/postgresql/extension'); + assert.equal( + readFileSync(path.join(destination, 'pg_partman--5.5.0.sql'), 'utf8'), + ['types', 'tables', 'functions', 'procedures'] + .map((group) => `${group}-a\n${group}-b\n`) + .join(''), + ); + assert.deepEqual([...new Bun.Glob('**/*').scanSync({ cwd: install, onlyFiles: true })].sort(), [ + 'share/postgresql/extension/pg_partman--5.4.0--5.5.0.sql', + 'share/postgresql/extension/pg_partman--5.5.0.sql', + 'share/postgresql/extension/pg_partman.control', + ]); + } finally { + rmSync(root, { recursive: true, force: true }); + } +}); test('Windows textsearch compiles upstream layout checks and installs the upgrade chain', () => { const root = mkdtempSync(path.join(tmpdir(), 'textsearch-windows-')); diff --git a/src/extensions/catalog/extensions.source.json b/src/extensions/catalog/extensions.source.json index 6afb49f57..9506717d5 100644 --- a/src/extensions/catalog/extensions.source.json +++ b/src/extensions/catalog/extensions.source.json @@ -65,6 +65,37 @@ "native-module-file": "auto_explain.so", "notes": [] }, + { + "id": "autoinc", + "sql-name": "autoinc", + "rust-constant": "AUTOINC", + "display-name": "autoinc", + "source-kind": "postgres-contrib", + "upstream-import-name": "autoinc", + "package-export": "./contrib/autoinc", + "tags": ["postgres extension", "postgres/contrib"], + "control-file": "src/third-party/postgres/contrib/spi/autoinc.control", + "control": { + "module-pathname": "$libdir/autoinc", + "requires": [], + "relocatable": "true" + }, + "dependencies": [], + "load-order": [], + "lifecycle": { + "create-extension": true, + "create-schema": "pg_catalog", + "load-sql": [], + "post-create-sql": [], + "startup-config": [], + "preload-required": false, + "restart-required": false, + "shared-memory-required": false + }, + "tests": ["src/test-fixtures/extensions/autoinc.sql"], + "native-module-file": "autoinc.so", + "notes": [] + }, { "id": "bloom", "sql-name": "bloom", @@ -427,6 +458,37 @@ "native-module-file": "hstore.so", "notes": [] }, + { + "id": "insert_username", + "sql-name": "insert_username", + "rust-constant": "INSERT_USERNAME", + "display-name": "insert_username", + "source-kind": "postgres-contrib", + "upstream-import-name": "insert_username", + "package-export": "./contrib/insert_username", + "tags": ["postgres extension", "postgres/contrib"], + "control-file": "src/third-party/postgres/contrib/spi/insert_username.control", + "control": { + "module-pathname": "$libdir/insert_username", + "requires": [], + "relocatable": "true" + }, + "dependencies": [], + "load-order": [], + "lifecycle": { + "create-extension": true, + "create-schema": "pg_catalog", + "load-sql": [], + "post-create-sql": [], + "startup-config": [], + "preload-required": false, + "restart-required": false, + "shared-memory-required": false + }, + "tests": ["src/test-fixtures/extensions/insert_username.sql"], + "native-module-file": "insert_username.so", + "notes": [] + }, { "id": "intarray", "sql-name": "intarray", @@ -555,6 +617,37 @@ "native-module-file": "ltree.so", "notes": [] }, + { + "id": "moddatetime", + "sql-name": "moddatetime", + "rust-constant": "MODDATETIME", + "display-name": "moddatetime", + "source-kind": "postgres-contrib", + "upstream-import-name": "moddatetime", + "package-export": "./contrib/moddatetime", + "tags": ["postgres extension", "postgres/contrib"], + "control-file": "src/third-party/postgres/contrib/spi/moddatetime.control", + "control": { + "module-pathname": "$libdir/moddatetime", + "requires": [], + "relocatable": "true" + }, + "dependencies": [], + "load-order": [], + "lifecycle": { + "create-extension": true, + "create-schema": "pg_catalog", + "load-sql": [], + "post-create-sql": [], + "startup-config": [], + "preload-required": false, + "restart-required": false, + "shared-memory-required": false + }, + "tests": ["src/test-fixtures/extensions/moddatetime.sql"], + "native-module-file": "moddatetime.so", + "notes": [] + }, { "id": "pageinspect", "sql-name": "pageinspect", @@ -589,6 +682,32 @@ "native-module-file": "pageinspect.so", "notes": [] }, + { + "id": "passwordcheck", + "sql-name": "passwordcheck", + "rust-constant": "PASSWORDCHECK", + "display-name": "passwordcheck", + "source-kind": "postgres-contrib", + "upstream-import-name": "passwordcheck", + "package-export": "./contrib/passwordcheck", + "tags": ["postgres extension", "postgres/contrib"], + "dependencies": [], + "load-order": [], + "lifecycle": { + "create-extension": false, + "load-sql": ["LOAD 'passwordcheck';"], + "post-create-sql": [], + "startup-config": [], + "preload-required": false, + "restart-required": false, + "shared-memory-required": false + }, + "tests": ["src/test-fixtures/extensions/passwordcheck.sql"], + "native-module-file": "passwordcheck.so", + "notes": [ + "LOAD enables password checks for the current session. Use shared_preload_libraries to enforce checks across postmaster sessions." + ] + }, { "id": "pg_buffercache", "sql-name": "pg_buffercache", @@ -722,6 +841,123 @@ "native-module-file": "pg_ivm.so", "notes": [] }, + { + "id": "pg_logicalinspect", + "sql-name": "pg_logicalinspect", + "rust-constant": "PG_LOGICALINSPECT", + "display-name": "pg_logicalinspect", + "source-kind": "postgres-contrib", + "upstream-import-name": "pg_logicalinspect", + "package-export": "./contrib/pg_logicalinspect", + "tags": ["postgres extension", "postgres/contrib"], + "control-file": "src/third-party/postgres/contrib/pg_logicalinspect/pg_logicalinspect.control", + "control": { + "module-pathname": "$libdir/pg_logicalinspect", + "requires": [], + "relocatable": "true" + }, + "dependencies": [], + "load-order": [], + "lifecycle": { + "create-extension": true, + "create-schema": "pg_catalog", + "load-sql": [], + "post-create-sql": [], + "startup-config": [], + "preload-required": false, + "restart-required": false, + "shared-memory-required": false + }, + "tests": ["src/test-fixtures/extensions/pg_logicalinspect.sql"], + "native-module-file": "pg_logicalinspect.so", + "notes": [] + }, + { + "id": "pg_overexplain", + "sql-name": "pg_overexplain", + "rust-constant": "PG_OVEREXPLAIN", + "display-name": "pg_overexplain", + "source-kind": "postgres-contrib", + "upstream-import-name": "pg_overexplain", + "package-export": "./contrib/pg_overexplain", + "tags": ["postgres extension", "postgres/contrib"], + "dependencies": [], + "load-order": [], + "lifecycle": { + "create-extension": false, + "load-sql": ["LOAD 'pg_overexplain';"], + "post-create-sql": [], + "startup-config": [], + "preload-required": false, + "restart-required": false, + "shared-memory-required": false + }, + "tests": ["src/test-fixtures/extensions/pg_overexplain.sql"], + "native-module-file": "pg_overexplain.so", + "notes": [] + }, + { + "id": "pg_stat_statements", + "sql-name": "pg_stat_statements", + "rust-constant": "PG_STAT_STATEMENTS", + "display-name": "pg_stat_statements", + "source-kind": "postgres-contrib", + "upstream-import-name": "pg_stat_statements", + "package-export": "./contrib/pg_stat_statements", + "tags": ["postgres extension", "postgres/contrib"], + "control-file": "src/third-party/postgres/contrib/pg_stat_statements/pg_stat_statements.control", + "control": { + "module-pathname": "$libdir/pg_stat_statements", + "requires": [], + "relocatable": "true" + }, + "dependencies": [], + "load-order": [], + "lifecycle": { + "create-extension": true, + "load-sql": [], + "post-create-sql": [], + "startup-config": ["shared_preload_libraries=pg_stat_statements"], + "preload-required": true, + "restart-required": true, + "shared-memory-required": true + }, + "tests": ["src/test-fixtures/extensions/pg_stat_statements.sql"], + "native-module-file": "pg_stat_statements.so", + "notes": [] + }, + { + "id": "pg_partman", + "sql-name": "pg_partman", + "rust-constant": "PG_PARTMAN", + "display-name": "pg_partman", + "source-kind": "oliphaunt-other-extension", + "upstream-import-name": "pg_partman", + "package-export": "./pg_partman", + "tags": ["postgres extension"], + "control-file": "target/oliphaunt-sources/checkouts/pg_partman/pg_partman.control", + "control": { + "requires": ["plpgsql"], + "relocatable": "false", + "superuser": "false" + }, + "dependencies": ["plpgsql"], + "load-order": [], + "lifecycle": { + "create-extension": true, + "create-schema": "partman", + "load-sql": [], + "post-create-sql": [], + "startup-config": [], + "preload-required": false, + "restart-required": false, + "shared-memory-required": false + }, + "tests": ["src/test-fixtures/extensions/pg_partman.sql"], + "notes": [ + "SQL-only build without pg_partman_bgw or Python utilities. Applications invoke maintenance explicitly." + ] + }, { "id": "pg_surgery", "sql-name": "pg_surgery", @@ -951,6 +1187,38 @@ "native-module-file": "pgcrypto.so", "notes": [] }, + { + "id": "pgmq", + "sql-name": "pgmq", + "rust-constant": "PGMQ", + "display-name": "PGMQ", + "source-kind": "oliphaunt-other-extension", + "upstream-import-name": "pgmq", + "package-export": "./pgmq", + "tags": ["postgres extension"], + "control-file": "target/oliphaunt-sources/checkouts/pgmq/pgmq-extension/pgmq.control", + "control": { + "module-pathname": "$libdir/pgmq", + "requires": [], + "relocatable": "false", + "schema": "pgmq", + "superuser": "false" + }, + "dependencies": ["plpgsql"], + "load-order": [], + "lifecycle": { + "create-extension": true, + "create-schema": "pgmq", + "load-sql": [], + "post-create-sql": [], + "startup-config": [], + "preload-required": false, + "restart-required": false, + "shared-memory-required": false + }, + "tests": ["src/test-fixtures/extensions/pgmq.sql"], + "notes": ["Partitioned queues additionally require pg_partman; basic queues do not."] + }, { "id": "pgtap", "sql-name": "pgtap", @@ -1011,6 +1279,37 @@ "native-module-file": "postgis-3.so", "notes": [] }, + { + "id": "refint", + "sql-name": "refint", + "rust-constant": "REFINT", + "display-name": "refint", + "source-kind": "postgres-contrib", + "upstream-import-name": "refint", + "package-export": "./contrib/refint", + "tags": ["postgres extension", "postgres/contrib"], + "control-file": "src/third-party/postgres/contrib/spi/refint.control", + "control": { + "module-pathname": "$libdir/refint", + "requires": [], + "relocatable": "true" + }, + "dependencies": [], + "load-order": [], + "lifecycle": { + "create-extension": true, + "create-schema": "pg_catalog", + "load-sql": [], + "post-create-sql": [], + "startup-config": [], + "preload-required": false, + "restart-required": false, + "shared-memory-required": false + }, + "tests": ["src/test-fixtures/extensions/refint.sql"], + "native-module-file": "refint.so", + "notes": [] + }, { "id": "seg", "sql-name": "seg", diff --git a/src/extensions/contrib/postgres18.toml b/src/extensions/contrib/postgres18.toml index b1a95d479..c0493bb2d 100644 --- a/src/extensions/contrib/postgres18.toml +++ b/src/extensions/contrib/postgres18.toml @@ -16,6 +16,14 @@ sql-name = "auto_explain" contrib-dir = "auto_explain" module-file = "auto_explain.so" +[[extensions]] +id = "autoinc" +sql-name = "autoinc" +contrib-dir = "spi" +module-file = "autoinc.so" +default-version = "1.0" +mobile-static-source-files = ["autoinc.c"] + [[extensions]] id = "bloom" sql-name = "bloom" @@ -94,6 +102,14 @@ contrib-dir = "hstore" module-file = "hstore.so" default-version = "1.8" +[[extensions]] +id = "insert_username" +sql-name = "insert_username" +contrib-dir = "spi" +module-file = "insert_username.so" +default-version = "1.0" +mobile-static-source-files = ["insert_username.c"] + [[extensions]] id = "intarray" sql-name = "intarray" @@ -122,6 +138,14 @@ contrib-dir = "ltree" module-file = "ltree.so" default-version = "1.3" +[[extensions]] +id = "moddatetime" +sql-name = "moddatetime" +contrib-dir = "spi" +module-file = "moddatetime.so" +default-version = "1.0" +mobile-static-source-files = ["moddatetime.c"] + [[extensions]] id = "pageinspect" sql-name = "pageinspect" @@ -129,6 +153,12 @@ contrib-dir = "pageinspect" module-file = "pageinspect.so" default-version = "1.13" +[[extensions]] +id = "passwordcheck" +sql-name = "passwordcheck" +contrib-dir = "passwordcheck" +module-file = "passwordcheck.so" + [[extensions]] id = "pg_buffercache" sql-name = "pg_buffercache" @@ -143,6 +173,26 @@ contrib-dir = "pg_freespacemap" module-file = "pg_freespacemap.so" default-version = "1.3" +[[extensions]] +id = "pg_logicalinspect" +sql-name = "pg_logicalinspect" +contrib-dir = "pg_logicalinspect" +module-file = "pg_logicalinspect.so" +default-version = "1.0" + +[[extensions]] +id = "pg_overexplain" +sql-name = "pg_overexplain" +contrib-dir = "pg_overexplain" +module-file = "pg_overexplain.so" + +[[extensions]] +id = "pg_stat_statements" +sql-name = "pg_stat_statements" +contrib-dir = "pg_stat_statements" +module-file = "pg_stat_statements.so" +default-version = "1.12" + [[extensions]] id = "pg_surgery" sql-name = "pg_surgery" @@ -178,6 +228,14 @@ contrib-dir = "pgcrypto" module-file = "pgcrypto.so" default-version = "1.4" +[[extensions]] +id = "refint" +sql-name = "refint" +contrib-dir = "spi" +module-file = "refint.so" +default-version = "1.0" +mobile-static-source-files = ["refint.c"] + [[extensions]] id = "seg" sql-name = "seg" diff --git a/src/extensions/evidence/matrix.toml b/src/extensions/evidence/matrix.toml index f2f3de647..f663fc7a9 100644 --- a/src/extensions/evidence/matrix.toml +++ b/src/extensions/evidence/matrix.toml @@ -10,9 +10,11 @@ source-digest-inputs = [ "src/database-resources/icu/source.toml", "src/extensions/external/pg_hashids/source.toml", "src/extensions/external/pg_ivm/source.toml", + "src/extensions/external/pg_partman/source.toml", "src/extensions/external/pg_textsearch/source.toml", "src/extensions/external/pg_textsearch/tests/upgrade/source.toml", "src/extensions/external/pg_uuidv7/source.toml", + "src/extensions/external/pgmq/source.toml", "src/extensions/external/pgtap/source.toml", "src/extensions/external/postgis/dependencies/geos/source.toml", "src/extensions/external/postgis/dependencies/json-c/source.toml", @@ -29,11 +31,21 @@ source-digest-inputs = [ "src/extensions/external/pg_hashids/upstream-license-data.json", "src/extensions/external/pg_ivm/targets/native-static-registry.toml", "src/extensions/external/pg_ivm/upstream-license-data.json", + "src/extensions/external/pg_partman/recipe.toml", + "src/extensions/external/pg_partman/targets/native-static-registry.toml", + "src/extensions/external/pg_partman/targets/native.toml", + "src/extensions/external/pg_partman/targets/wasix.toml", + "src/extensions/external/pg_partman/upstream-license-data.json", "src/extensions/external/pg_textsearch/recipe.toml", "src/extensions/external/pg_textsearch/targets/native-static-registry.toml", "src/extensions/external/pg_textsearch/tests/qualify.sh", "src/extensions/external/pg_textsearch/upstream-license-data.json", "src/extensions/external/pg_uuidv7/upstream-license-data.json", + "src/extensions/external/pgmq/recipe.toml", + "src/extensions/external/pgmq/targets/native-static-registry.toml", + "src/extensions/external/pgmq/targets/native.toml", + "src/extensions/external/pgmq/targets/wasix.toml", + "src/extensions/external/pgmq/upstream-license-data.json", "src/extensions/external/pgtap/recipe.toml", "src/extensions/external/pgtap/targets/native-static-registry.toml", "src/extensions/external/pgtap/targets/native.toml", @@ -58,6 +70,7 @@ source-digest-inputs = [ "src/test-fixtures/extensions/manifest.json", "src/test-fixtures/extensions/amcheck.sql", "src/test-fixtures/extensions/auto_explain.sql", + "src/test-fixtures/extensions/autoinc.sql", "src/test-fixtures/extensions/bloom.sql", "src/test-fixtures/extensions/btree_gin.sql", "src/test-fixtures/extensions/btree_gist.sql", @@ -69,15 +82,22 @@ source-digest-inputs = [ "src/test-fixtures/extensions/file_fdw.sql", "src/test-fixtures/extensions/fuzzystrmatch.sql", "src/test-fixtures/extensions/hstore.sql", + "src/test-fixtures/extensions/insert_username.sql", "src/test-fixtures/extensions/intarray.sql", "src/test-fixtures/extensions/isn.sql", "src/test-fixtures/extensions/lo.sql", "src/test-fixtures/extensions/ltree.sql", + "src/test-fixtures/extensions/moddatetime.sql", "src/test-fixtures/extensions/pageinspect.sql", + "src/test-fixtures/extensions/passwordcheck.sql", "src/test-fixtures/extensions/pg_buffercache.sql", "src/test-fixtures/extensions/pg_freespacemap.sql", "src/test-fixtures/extensions/pg_hashids.sql", "src/test-fixtures/extensions/pg_ivm.sql", + "src/test-fixtures/extensions/pg_logicalinspect.sql", + "src/test-fixtures/extensions/pg_overexplain.sql", + "src/test-fixtures/extensions/pg_partman.sql", + "src/test-fixtures/extensions/pg_stat_statements.sql", "src/test-fixtures/extensions/pg_surgery.sql", "src/test-fixtures/extensions/pg_textsearch.sql", "src/test-fixtures/extensions/pg_trgm.sql", @@ -85,8 +105,10 @@ source-digest-inputs = [ "src/test-fixtures/extensions/pg_visibility.sql", "src/test-fixtures/extensions/pg_walinspect.sql", "src/test-fixtures/extensions/pgcrypto.sql", + "src/test-fixtures/extensions/pgmq.sql", "src/test-fixtures/extensions/pgtap.sql", "src/test-fixtures/extensions/postgis.sql", + "src/test-fixtures/extensions/refint.sql", "src/test-fixtures/extensions/seg.sql", "src/test-fixtures/extensions/tablefunc.sql", "src/test-fixtures/extensions/tcn.sql", @@ -113,6 +135,14 @@ platform-targets = ["portable"] runtime-modes = ["direct","server","restart","backup-restore","materialization"] evidence-required = ["wasix-full-lifecycle-v1"] +[[claims]] +extension = "autoinc" +postgres-major = 18 +artifact-family = "wasix-runtime" +platform-targets = ["portable"] +runtime-modes = ["direct","server","restart","backup-restore","materialization"] +evidence-required = ["wasix-full-lifecycle-v1"] + [[claims]] extension = "bloom" postgres-major = 18 @@ -201,6 +231,14 @@ platform-targets = ["portable"] runtime-modes = ["direct","server","restart","backup-restore","materialization"] evidence-required = ["wasix-full-lifecycle-v1"] +[[claims]] +extension = "insert_username" +postgres-major = 18 +artifact-family = "wasix-runtime" +platform-targets = ["portable"] +runtime-modes = ["direct","server","restart","backup-restore","materialization"] +evidence-required = ["wasix-full-lifecycle-v1"] + [[claims]] extension = "intarray" postgres-major = 18 @@ -233,6 +271,14 @@ platform-targets = ["portable"] runtime-modes = ["direct","server","restart","backup-restore","materialization"] evidence-required = ["wasix-full-lifecycle-v1"] +[[claims]] +extension = "moddatetime" +postgres-major = 18 +artifact-family = "wasix-runtime" +platform-targets = ["portable"] +runtime-modes = ["direct","server","restart","backup-restore","materialization"] +evidence-required = ["wasix-full-lifecycle-v1"] + [[claims]] extension = "pageinspect" postgres-major = 18 @@ -241,6 +287,14 @@ platform-targets = ["portable"] runtime-modes = ["direct","server","restart","backup-restore","materialization"] evidence-required = ["wasix-full-lifecycle-v1"] +[[claims]] +extension = "passwordcheck" +postgres-major = 18 +artifact-family = "wasix-runtime" +platform-targets = ["portable"] +runtime-modes = ["direct","server","restart","backup-restore","materialization"] +evidence-required = ["wasix-full-lifecycle-v1"] + [[claims]] extension = "pg_buffercache" postgres-major = 18 @@ -273,6 +327,38 @@ platform-targets = ["portable"] runtime-modes = ["direct","server","restart","backup-restore","materialization"] evidence-required = ["wasix-full-lifecycle-v1"] +[[claims]] +extension = "pg_logicalinspect" +postgres-major = 18 +artifact-family = "wasix-runtime" +platform-targets = ["portable"] +runtime-modes = ["direct","server","restart","backup-restore","materialization"] +evidence-required = ["wasix-full-lifecycle-v1"] + +[[claims]] +extension = "pg_overexplain" +postgres-major = 18 +artifact-family = "wasix-runtime" +platform-targets = ["portable"] +runtime-modes = ["direct","server","restart","backup-restore","materialization"] +evidence-required = ["wasix-full-lifecycle-v1"] + +[[claims]] +extension = "pg_partman" +postgres-major = 18 +artifact-family = "wasix-runtime" +platform-targets = ["portable"] +runtime-modes = ["direct","server","restart","backup-restore","materialization"] +evidence-required = ["wasix-full-lifecycle-v1"] + +[[claims]] +extension = "pg_stat_statements" +postgres-major = 18 +artifact-family = "wasix-runtime" +platform-targets = ["portable"] +runtime-modes = ["direct","server","restart","backup-restore","materialization"] +evidence-required = ["wasix-full-lifecycle-v1"] + [[claims]] extension = "pg_surgery" postgres-major = 18 @@ -329,6 +415,14 @@ platform-targets = ["portable"] runtime-modes = ["direct","server","restart","backup-restore","materialization"] evidence-required = ["wasix-full-lifecycle-v1"] +[[claims]] +extension = "pgmq" +postgres-major = 18 +artifact-family = "wasix-runtime" +platform-targets = ["portable"] +runtime-modes = ["direct","server","restart","backup-restore","materialization"] +evidence-required = ["wasix-full-lifecycle-v1"] + [[claims]] extension = "pgtap" postgres-major = 18 @@ -345,6 +439,14 @@ platform-targets = ["portable"] runtime-modes = ["direct","server","restart","backup-restore","materialization"] evidence-required = ["wasix-full-lifecycle-v1"] +[[claims]] +extension = "refint" +postgres-major = 18 +artifact-family = "wasix-runtime" +platform-targets = ["portable"] +runtime-modes = ["direct","server","restart","backup-restore","materialization"] +evidence-required = ["wasix-full-lifecycle-v1"] + [[claims]] extension = "seg" postgres-major = 18 diff --git a/src/extensions/external/pg_ivm/source.toml b/src/extensions/external/pg_ivm/source.toml index 30babd02e..94684a1f0 100644 --- a/src/extensions/external/pg_ivm/source.toml +++ b/src/extensions/external/pg_ivm/source.toml @@ -1,9 +1,9 @@ name = "pg_ivm" url = "https://github.com/sraoss/pg_ivm.git" branch = "pinned" -commit = "b66487f7a6f8deee3998e858d773e19923e4bd4b" +commit = "678c37861080aa221b859cefaca98725646dbf7c" [extension-control] sql-name = "pg_ivm" source-path = "pg_ivm.control" -default-version = "1.13" +default-version = "1.17" diff --git a/src/extensions/external/pg_ivm/upstream-license-data.json b/src/extensions/external/pg_ivm/upstream-license-data.json index b07587576..e38b593fc 100644 --- a/src/extensions/external/pg_ivm/upstream-license-data.json +++ b/src/extensions/external/pg_ivm/upstream-license-data.json @@ -7,7 +7,7 @@ "kind": "git", "url": "https://github.com/sraoss/pg_ivm.git", "branch": "pinned", - "commit": "b66487f7a6f8deee3998e858d773e19923e4bd4b" + "commit": "678c37861080aa221b859cefaca98725646dbf7c" } ], "extension": { @@ -19,12 +19,12 @@ "destination": "share/licenses/pg_ivm/LICENSE", "role": "license", "spdx": "PostgreSQL", - "license_url": "https://github.com/sraoss/pg_ivm/blob/b66487f7a6f8deee3998e858d773e19923e4bd4b/LICENSE", - "sha256": "22e995337ca75d05f5057e741e063acb802ff10cb8a13dc822bae749d9df59f4" + "license_url": "https://github.com/sraoss/pg_ivm/blob/678c37861080aa221b859cefaca98725646dbf7c/LICENSE", + "sha256": "f395253af7c50689bdfcd7df4ea247dc2fc39fa0627100699f006639df406d2b" } ] }, "blobs": { - "22e995337ca75d05f5057e741e063acb802ff10cb8a13dc822bae749d9df59f4": "UG9ydGlvbnMgQ29weXJpZ2h0IChjKSAxOTk2LTIwMjIsIFBvc3RncmVTUUwgR2xvYmFsIERldmVsb3BtZW50IEdyb3VwCgpQb3J0aW9ucyBDb3B5cmlnaHQgKGMpIDIwMjIsIElWTSBEZXZlbG9wbWVudCBHcm91cAoKUGVybWlzc2lvbiB0byB1c2UsIGNvcHksIG1vZGlmeSwgYW5kIGRpc3RyaWJ1dGUgdGhpcyBzb2Z0d2FyZSBhbmQgaXRzCmRvY3VtZW50YXRpb24gZm9yIGFueSBwdXJwb3NlLCB3aXRob3V0IGZlZSwgYW5kIHdpdGhvdXQgYSB3cml0dGVuIGFncmVlbWVudAppcyBoZXJlYnkgZ3JhbnRlZCwgcHJvdmlkZWQgdGhhdCB0aGUgYWJvdmUgY29weXJpZ2h0IG5vdGljZSBhbmQgdGhpcwpwYXJhZ3JhcGggYW5kIHRoZSBmb2xsb3dpbmcgdHdvIHBhcmFncmFwaHMgYXBwZWFyIGluIGFsbCBjb3BpZXMuCgpJTiBOTyBFVkVOVCBTSEFMTCBUSEUgQVVUSE9SUyBCRSBMSUFCTEUgVE8gQU5ZIFBBUlRZIEZPUiBESVJFQ1QsCklORElSRUNULCBTUEVDSUFMLCBJTkNJREVOVEFMLCBPUiBDT05TRVFVRU5USUFMIERBTUFHRVMsIElOQ0xVRElORwpMT1NUIFBST0ZJVFMsIEFSSVNJTkcgT1VUIE9GIFRIRSBVU0UgT0YgVEhJUyBTT0ZUV0FSRSBBTkQgSVRTCkRPQ1VNRU5UQVRJT04sIEVWRU4gSUYgVEhFIEFVVEhPUlMgSEFWRSBCRUVOIEFEVklTRUQgT0YgVEhFClBPU1NJQklMSVRZIE9GIFNVQ0ggREFNQUdFLgoKVEhFIEFVVEhPUlMgU1BFQ0lGSUNBTExZIERJU0NMQUlNIEFOWSBXQVJSQU5USUVTLCBJTkNMVURJTkcsIEJVVCBOT1QKTElNSVRFRCBUTywgVEhFIElNUExJRUQgV0FSUkFOVElFUyBPRiBNRVJDSEFOVEFCSUxJVFkgQU5EIEZJVE5FU1MgRk9SCkEgUEFSVElDVUxBUiBQVVJQT1NFLiAgVEhFIFNPRlRXQVJFIFBST1ZJREVEIEhFUkVVTkRFUiBJUyBPTiBBTiAiQVMKSVMiIEJBU0lTLCBBTkQgVEhFIEFVVEhPUlMgSEFWRSBOTyBPQkxJR0FUSU9OUyBUTyBQUk9WSURFIE1BSU5URU5BTkNFLApTVVBQT1JULCBVUERBVEVTLCBFTkhBTkNFTUVOVFMsIE9SIE1PRElGSUNBVElPTlMuCg==" + "f395253af7c50689bdfcd7df4ea247dc2fc39fa0627100699f006639df406d2b": "UG9ydGlvbnMgQ29weXJpZ2h0IChjKSAxOTk2LTIwMjIsIFBvc3RncmVTUUwgR2xvYmFsIERldmVsb3BtZW50IEdyb3VwCgpQb3J0aW9ucyBDb3B5cmlnaHQgKGMpIDIwMjYsIElWTSBEZXZlbG9wbWVudCBHcm91cAoKUGVybWlzc2lvbiB0byB1c2UsIGNvcHksIG1vZGlmeSwgYW5kIGRpc3RyaWJ1dGUgdGhpcyBzb2Z0d2FyZSBhbmQgaXRzCmRvY3VtZW50YXRpb24gZm9yIGFueSBwdXJwb3NlLCB3aXRob3V0IGZlZSwgYW5kIHdpdGhvdXQgYSB3cml0dGVuIGFncmVlbWVudAppcyBoZXJlYnkgZ3JhbnRlZCwgcHJvdmlkZWQgdGhhdCB0aGUgYWJvdmUgY29weXJpZ2h0IG5vdGljZSBhbmQgdGhpcwpwYXJhZ3JhcGggYW5kIHRoZSBmb2xsb3dpbmcgdHdvIHBhcmFncmFwaHMgYXBwZWFyIGluIGFsbCBjb3BpZXMuCgpJTiBOTyBFVkVOVCBTSEFMTCBUSEUgQVVUSE9SUyBCRSBMSUFCTEUgVE8gQU5ZIFBBUlRZIEZPUiBESVJFQ1QsCklORElSRUNULCBTUEVDSUFMLCBJTkNJREVOVEFMLCBPUiBDT05TRVFVRU5USUFMIERBTUFHRVMsIElOQ0xVRElORwpMT1NUIFBST0ZJVFMsIEFSSVNJTkcgT1VUIE9GIFRIRSBVU0UgT0YgVEhJUyBTT0ZUV0FSRSBBTkQgSVRTCkRPQ1VNRU5UQVRJT04sIEVWRU4gSUYgVEhFIEFVVEhPUlMgSEFWRSBCRUVOIEFEVklTRUQgT0YgVEhFClBPU1NJQklMSVRZIE9GIFNVQ0ggREFNQUdFLgoKVEhFIEFVVEhPUlMgU1BFQ0lGSUNBTExZIERJU0NMQUlNIEFOWSBXQVJSQU5USUVTLCBJTkNMVURJTkcsIEJVVCBOT1QKTElNSVRFRCBUTywgVEhFIElNUExJRUQgV0FSUkFOVElFUyBPRiBNRVJDSEFOVEFCSUxJVFkgQU5EIEZJVE5FU1MgRk9SCkEgUEFSVElDVUxBUiBQVVJQT1NFLiAgVEhFIFNPRlRXQVJFIFBST1ZJREVEIEhFUkVVTkRFUiBJUyBPTiBBTiAiQVMKSVMiIEJBU0lTLCBBTkQgVEhFIEFVVEhPUlMgSEFWRSBOTyBPQkxJR0FUSU9OUyBUTyBQUk9WSURFIE1BSU5URU5BTkNFLApTVVBQT1JULCBVUERBVEVTLCBFTkhBTkNFTUVOVFMsIE9SIE1PRElGSUNBVElPTlMuCg==" } } diff --git a/src/extensions/external/pg_partman/CHANGELOG.md b/src/extensions/external/pg_partman/CHANGELOG.md new file mode 100644 index 000000000..e69de29bb diff --git a/src/extensions/external/pg_partman/VERSION b/src/extensions/external/pg_partman/VERSION new file mode 100644 index 000000000..77d6f4ca2 --- /dev/null +++ b/src/extensions/external/pg_partman/VERSION @@ -0,0 +1 @@ +0.0.0 diff --git a/src/extensions/external/pg_partman/moon.yml b/src/extensions/external/pg_partman/moon.yml new file mode 100644 index 000000000..d141faa96 --- /dev/null +++ b/src/extensions/external/pg_partman/moon.yml @@ -0,0 +1,19 @@ +$schema: "https://moonrepo.dev/schemas/project.json" + +id: "oliphaunt-extension-pg-partman" +language: "unknown" +layer: "library" +stack: "systems" +tags: ["extensions", "external", "release-product"] +dependsOn: + - id: "extension-runtime-contract" + scope: "build" + - id: "liboliphaunt-native" + scope: "build" + - id: "liboliphaunt-wasix" + scope: "build" + +project: + release: + component: "oliphaunt-extension-pg-partman" + packagePath: "src/extensions/external/pg_partman" diff --git a/src/extensions/external/pg_partman/recipe.toml b/src/extensions/external/pg_partman/recipe.toml new file mode 100644 index 000000000..3b4d6ce8b --- /dev/null +++ b/src/extensions/external/pg_partman/recipe.toml @@ -0,0 +1,30 @@ +schema = "oliphaunt-extension-recipe-v1" +sql_name = "pg_partman" +display_name = "pg_partman" +kind = "external-simple-pgxs" +license = "PostgreSQL" +source = "pg_partman" +postgres_majors = [18] + +[lifecycle] +creates_extension = true +requires = ["plpgsql"] +implicit_sql_dependencies = [] +load_sql = [] +post_create_sql = [] +shared_preload_libraries = [] +restart_required = false +background_workers = false +shared_memory = false +session_load_required = false +needs_superuser = false +trusted = false + +[artifacts] +control_files = ["share/postgresql/extension/pg_partman.control"] +sql_globs = ["share/postgresql/extension/pg_partman--*.sql"] +native_modules = [] +native_dependency_modules = [] +data_files = [] +headers = [] +licenses = [] diff --git a/src/extensions/external/pg_partman/release.toml b/src/extensions/external/pg_partman/release.toml new file mode 100644 index 000000000..466c156ec --- /dev/null +++ b/src/extensions/external/pg_partman/release.toml @@ -0,0 +1,55 @@ +id = "oliphaunt-extension-pg-partman" +owner = "@oliphaunt/extensions" +kind = "exact-extension-artifact" +shared_source_paths = ["src/extensions/artifacts/packages/tools/package-extension-cargo-facades.mts", "src/extensions/artifacts/packages/tools/package-extension-release-carriers.mts", "src/native/sdks/swift/tools/ios-carrier-manifest.mts", "src/wasix/runtime/tools/package_liboliphaunt_wasix_cargo_artifacts.mts", "tools/packaging/build-maven-artifact-manifest.mts", "tools/packaging/maven-artifact-staging.mts"] +publish_targets = [ + "github-release-assets", + "npm", + "maven-central", + "crates-io", +] +registry_packages = [ + "crates:oliphaunt-extension-pg-partman", + "crates:oliphaunt-extension-pg-partman-linux-arm64-gnu", + "crates:oliphaunt-extension-pg-partman-linux-x64-gnu", + "crates:oliphaunt-extension-pg-partman-macos-arm64", + "crates:oliphaunt-extension-pg-partman-wasix", + "crates:oliphaunt-extension-pg-partman-windows-x64-msvc", + "npm:@oliphaunt/extension-pg-partman", + "npm:@oliphaunt/extension-pg-partman-linux-arm64-gnu", + "npm:@oliphaunt/extension-pg-partman-linux-x64-gnu", + "npm:@oliphaunt/extension-pg-partman-macos-arm64", + "npm:@oliphaunt/extension-pg-partman-wasix", + "npm:@oliphaunt/extension-pg-partman-windows-x64-msvc", + "maven:dev.oliphaunt.extensions:oliphaunt-extension-pg-partman-android-arm64-v8a", + "maven:dev.oliphaunt.extensions:oliphaunt-extension-pg-partman-android-x86_64", +] +release_artifacts = ["exact-extension-artifacts"] +extension_sql_name = "pg_partman" + +[extension] +sql_name = "pg_partman" +class = "external" +versioning = "upstream-bound" + +[extension.source] +path = "src/extensions/external/pg_partman/source.toml" + +[extension.compatibility] +postgres_major = "18" +extension_runtime_contract = "src/extensions/contracts/contract.toml" +native_runtime_product = "liboliphaunt-native" +native_runtime_version = "0.3.3" +wasix_runtime_product = "liboliphaunt-wasix" +wasix_runtime_version = "0.3.2" +[compatibility_versions.oliphaunt-extension-pg-partman-liboliphaunt-native] +public_support = true +source_product = "liboliphaunt-native" +path = "src/extensions/external/pg_partman/release.toml" +parser = "toml:extension.compatibility.native_runtime_version" + +[compatibility_versions.oliphaunt-extension-pg-partman-liboliphaunt-wasix] +public_support = true +source_product = "liboliphaunt-wasix" +path = "src/extensions/external/pg_partman/release.toml" +parser = "toml:extension.compatibility.wasix_runtime_version" diff --git a/src/extensions/external/pg_partman/source.toml b/src/extensions/external/pg_partman/source.toml new file mode 100644 index 000000000..0b691c7c0 --- /dev/null +++ b/src/extensions/external/pg_partman/source.toml @@ -0,0 +1,9 @@ +name = "pg_partman" +url = "https://github.com/pgpartman/pg_partman.git" +branch = "pinned" +commit = "f7e83b9c441c7e97066d815bbe14e02a9dc5ff94" + +[extension-control] +sql-name = "pg_partman" +source-path = "pg_partman.control" +default-version = "5.5.0" diff --git a/src/extensions/external/pg_partman/targets/native-static-registry.toml b/src/extensions/external/pg_partman/targets/native-static-registry.toml new file mode 100644 index 000000000..095968283 --- /dev/null +++ b/src/extensions/external/pg_partman/targets/native-static-registry.toml @@ -0,0 +1,12 @@ +schema = "oliphaunt-extension-target-v1" +artifact_family = "sql-only" +build_kind = "pgxs-sql-only" +platform_targets = [ + "macos-arm64", + "ios-arm64", + "ios-simulator-arm64", + "android-arm64-v8a", + "android-x86_64", +] +module_files = [] +data_files = [] diff --git a/src/extensions/external/pg_partman/targets/native.toml b/src/extensions/external/pg_partman/targets/native.toml new file mode 100644 index 000000000..e693c7978 --- /dev/null +++ b/src/extensions/external/pg_partman/targets/native.toml @@ -0,0 +1,5 @@ +schema = "oliphaunt-extension-target-v1" +artifact_family = "sql-only" +build_kind = "pgxs-sql-only" +module_files = [] +data_files = [] diff --git a/src/extensions/external/pg_partman/targets/wasix.toml b/src/extensions/external/pg_partman/targets/wasix.toml new file mode 100644 index 000000000..e693c7978 --- /dev/null +++ b/src/extensions/external/pg_partman/targets/wasix.toml @@ -0,0 +1,5 @@ +schema = "oliphaunt-extension-target-v1" +artifact_family = "sql-only" +build_kind = "pgxs-sql-only" +module_files = [] +data_files = [] diff --git a/src/extensions/external/pg_partman/upstream-license-data.json b/src/extensions/external/pg_partman/upstream-license-data.json new file mode 100644 index 000000000..a06f79f4b --- /dev/null +++ b/src/extensions/external/pg_partman/upstream-license-data.json @@ -0,0 +1,30 @@ +{ + "schema": "oliphaunt-extension-upstream-license-data-v1", + "sources": [ + { + "id": "pg_partman", + "manifest": "src/extensions/external/pg_partman/source.toml", + "kind": "git", + "url": "https://github.com/pgpartman/pg_partman.git", + "branch": "pinned", + "commit": "f7e83b9c441c7e97066d815bbe14e02a9dc5ff94" + } + ], + "extension": { + "sql_name": "pg_partman", + "files": [ + { + "source": "pg_partman", + "path": "LICENSE.txt", + "destination": "share/licenses/pg_partman/LICENSE.txt", + "role": "license", + "spdx": "PostgreSQL", + "license_url": "https://github.com/pgpartman/pg_partman/blob/f7e83b9c441c7e97066d815bbe14e02a9dc5ff94/LICENSE.txt", + "sha256": "657cd7bde17fc758e47824280a7ccb9bc7d44067e3f3790c2ef4b07e8a04223a" + } + ] + }, + "blobs": { + "657cd7bde17fc758e47824280a7ccb9bc7d44067e3f3790c2ef4b07e8a04223a": "TElDRU5TRSBBTkQgQ09QWVJJR0hUCi0tLS0tLS0tLS0tLS0tLS0tLS0tLQoKUEcgUGFydGl0aW9uIE1hbmFnZXIgKHBnX3BhcnRtYW4pIGlzIHJlbGVhc2VkIHVuZGVyIHRoZSBQb3N0Z3JlU1FMIExpY2Vuc2UsIGEgbGliZXJhbCBPcGVuIFNvdXJjZSBsaWNlbnNlLCBzaW1pbGFyIHRvIHRoZSBCU0Qgb3IgTUlUIGxpY2Vuc2VzLgoKQ29weXJpZ2h0IChjKSAyMDI1LTIwMjYgU25vd2ZsYWtlLCBJbmMuCkNvcHlyaWdodCAoYykgMjAxOC0yMDI1IENydW5jaHkgRGF0YSBTb2x1dGlvbnMsIEluYy4KQ29weXJpZ2h0IChjKSAyMDE3IE9tbmlUSSwgSW5jLgoKUGVybWlzc2lvbiB0byB1c2UsIGNvcHksIG1vZGlmeSwgYW5kIGRpc3RyaWJ1dGUgdGhpcyBzb2Z0d2FyZSBhbmQgaXRzIGRvY3VtZW50YXRpb24gZm9yIGFueSBwdXJwb3NlLCB3aXRob3V0IGZlZSwgYW5kIHdpdGhvdXQgYSB3cml0dGVuIGFncmVlbWVudCBpcyBoZXJlYnkgZ3JhbnRlZCwgcHJvdmlkZWQgdGhhdCB0aGUgYWJvdmUgY29weXJpZ2h0IG5vdGljZSBhbmQgdGhpcyBwYXJhZ3JhcGggYW5kIHRoZSBmb2xsb3dpbmcgdHdvIHBhcmFncmFwaHMgYXBwZWFyIGluIGFsbCBjb3BpZXMuCgpJTiBOTyBFVkVOVCBTSEFMTCBUSEUgQVVUSE9SIEJFIExJQUJMRSBUTyBBTlkgUEFSVFkgRk9SIERJUkVDVCwgSU5ESVJFQ1QsIFNQRUNJQUwsIElOQ0lERU5UQUwsIE9SIENPTlNFUVVFTlRJQUwgREFNQUdFUywgSU5DTFVESU5HIExPU1QgUFJPRklUUywgQVJJU0lORyBPVVQgT0YgVEhFIFVTRSBPRiBUSElTIFNPRlRXQVJFIEFORCBJVFMgRE9DVU1FTlRBVElPTiwgRVZFTiBJRiBUSEUgQVVUSE9SIEhBUyBCRUVOIEFEVklTRUQgT0YgVEhFIFBPU1NJQklMSVRZIE9GIFNVQ0ggREFNQUdFLgoKVEhFIEFVVEhPUiBTUEVDSUZJQ0FMTFkgRElTQ0xBSU1TIEFOWSBXQVJSQU5USUVTLCBJTkNMVURJTkcsIEJVVCBOT1QgTElNSVRFRCBUTywgVEhFIElNUExJRUQgV0FSUkFOVElFUyBPRiBNRVJDSEFOVEFCSUxJVFkgQU5EIEZJVE5FU1MgRk9SIEEgUEFSVElDVUxBUiBQVVJQT1NFLiBUSEUgU09GVFdBUkUgUFJPVklERUQgSEVSRVVOREVSIElTIE9OIEFOICJBUyBJUyIgQkFTSVMsIEFORCBUSEUgQVVUSE9SIEhBUyBOTyBPQkxJR0FUSU9OUyBUTyBQUk9WSURFIE1BSU5URU5BTkNFLCBTVVBQT1JULCBVUERBVEVTLCBFTkhBTkNFTUVOVFMsIE9SIE1PRElGSUNBVElPTlMuCg==" + } +} diff --git a/src/extensions/external/pgmq/CHANGELOG.md b/src/extensions/external/pgmq/CHANGELOG.md new file mode 100644 index 000000000..e69de29bb diff --git a/src/extensions/external/pgmq/VERSION b/src/extensions/external/pgmq/VERSION new file mode 100644 index 000000000..77d6f4ca2 --- /dev/null +++ b/src/extensions/external/pgmq/VERSION @@ -0,0 +1 @@ +0.0.0 diff --git a/src/extensions/external/pgmq/moon.yml b/src/extensions/external/pgmq/moon.yml new file mode 100644 index 000000000..a5a2ce6d5 --- /dev/null +++ b/src/extensions/external/pgmq/moon.yml @@ -0,0 +1,19 @@ +$schema: "https://moonrepo.dev/schemas/project.json" + +id: "oliphaunt-extension-pgmq" +language: "unknown" +layer: "library" +stack: "systems" +tags: ["extensions", "external", "release-product"] +dependsOn: + - id: "extension-runtime-contract" + scope: "build" + - id: "liboliphaunt-native" + scope: "build" + - id: "liboliphaunt-wasix" + scope: "build" + +project: + release: + component: "oliphaunt-extension-pgmq" + packagePath: "src/extensions/external/pgmq" diff --git a/src/extensions/external/pgmq/recipe.toml b/src/extensions/external/pgmq/recipe.toml new file mode 100644 index 000000000..4f150afa5 --- /dev/null +++ b/src/extensions/external/pgmq/recipe.toml @@ -0,0 +1,33 @@ +schema = "oliphaunt-extension-recipe-v1" +sql_name = "pgmq" +display_name = "PGMQ" +kind = "external-simple-pgxs" +license = "PostgreSQL" +source = "pgmq" +postgres_majors = [18] + +[lifecycle] +creates_extension = true +requires = [] +implicit_sql_dependencies = ["plpgsql"] +load_sql = [] +post_create_sql = [] +shared_preload_libraries = [] +restart_required = false +background_workers = false +shared_memory = false +session_load_required = false +needs_superuser = false +trusted = false + +[artifacts] +control_files = ["share/postgresql/extension/pgmq.control"] +sql_globs = ["share/postgresql/extension/pgmq--*.sql"] +native_modules = [] +native_dependency_modules = [] +data_files = [] +headers = [] +licenses = ["share/licenses/pgmq/LICENSE"] + +[build] +source_subdirectory = "pgmq-extension" diff --git a/src/extensions/external/pgmq/release.toml b/src/extensions/external/pgmq/release.toml new file mode 100644 index 000000000..a3a1d003f --- /dev/null +++ b/src/extensions/external/pgmq/release.toml @@ -0,0 +1,55 @@ +id = "oliphaunt-extension-pgmq" +owner = "@oliphaunt/extensions" +kind = "exact-extension-artifact" +shared_source_paths = ["src/extensions/artifacts/packages/tools/package-extension-cargo-facades.mts", "src/extensions/artifacts/packages/tools/package-extension-release-carriers.mts", "src/native/sdks/swift/tools/ios-carrier-manifest.mts", "src/wasix/runtime/tools/package_liboliphaunt_wasix_cargo_artifacts.mts", "tools/packaging/build-maven-artifact-manifest.mts", "tools/packaging/maven-artifact-staging.mts"] +publish_targets = [ + "github-release-assets", + "npm", + "maven-central", + "crates-io", +] +registry_packages = [ + "crates:oliphaunt-extension-pgmq", + "crates:oliphaunt-extension-pgmq-linux-arm64-gnu", + "crates:oliphaunt-extension-pgmq-linux-x64-gnu", + "crates:oliphaunt-extension-pgmq-macos-arm64", + "crates:oliphaunt-extension-pgmq-wasix", + "crates:oliphaunt-extension-pgmq-windows-x64-msvc", + "npm:@oliphaunt/extension-pgmq", + "npm:@oliphaunt/extension-pgmq-linux-arm64-gnu", + "npm:@oliphaunt/extension-pgmq-linux-x64-gnu", + "npm:@oliphaunt/extension-pgmq-macos-arm64", + "npm:@oliphaunt/extension-pgmq-wasix", + "npm:@oliphaunt/extension-pgmq-windows-x64-msvc", + "maven:dev.oliphaunt.extensions:oliphaunt-extension-pgmq-android-arm64-v8a", + "maven:dev.oliphaunt.extensions:oliphaunt-extension-pgmq-android-x86_64", +] +release_artifacts = ["exact-extension-artifacts"] +extension_sql_name = "pgmq" + +[extension] +sql_name = "pgmq" +class = "external" +versioning = "upstream-bound" + +[extension.source] +path = "src/extensions/external/pgmq/source.toml" + +[extension.compatibility] +postgres_major = "18" +extension_runtime_contract = "src/extensions/contracts/contract.toml" +native_runtime_product = "liboliphaunt-native" +native_runtime_version = "0.3.3" +wasix_runtime_product = "liboliphaunt-wasix" +wasix_runtime_version = "0.3.2" +[compatibility_versions.oliphaunt-extension-pgmq-liboliphaunt-native] +public_support = true +source_product = "liboliphaunt-native" +path = "src/extensions/external/pgmq/release.toml" +parser = "toml:extension.compatibility.native_runtime_version" + +[compatibility_versions.oliphaunt-extension-pgmq-liboliphaunt-wasix] +public_support = true +source_product = "liboliphaunt-wasix" +path = "src/extensions/external/pgmq/release.toml" +parser = "toml:extension.compatibility.wasix_runtime_version" diff --git a/src/extensions/external/pgmq/source.toml b/src/extensions/external/pgmq/source.toml new file mode 100644 index 000000000..fcc3a41eb --- /dev/null +++ b/src/extensions/external/pgmq/source.toml @@ -0,0 +1,9 @@ +name = "pgmq" +url = "https://github.com/pgmq/pgmq.git" +branch = "pinned" +commit = "32c075bb6dbed66a303d1a792393c93e36c09a97" + +[extension-control] +sql-name = "pgmq" +source-path = "pgmq-extension/pgmq.control" +default-version = "1.13.0" diff --git a/src/extensions/external/pgmq/targets/native-static-registry.toml b/src/extensions/external/pgmq/targets/native-static-registry.toml new file mode 100644 index 000000000..095968283 --- /dev/null +++ b/src/extensions/external/pgmq/targets/native-static-registry.toml @@ -0,0 +1,12 @@ +schema = "oliphaunt-extension-target-v1" +artifact_family = "sql-only" +build_kind = "pgxs-sql-only" +platform_targets = [ + "macos-arm64", + "ios-arm64", + "ios-simulator-arm64", + "android-arm64-v8a", + "android-x86_64", +] +module_files = [] +data_files = [] diff --git a/src/extensions/external/pgmq/targets/native.toml b/src/extensions/external/pgmq/targets/native.toml new file mode 100644 index 000000000..e693c7978 --- /dev/null +++ b/src/extensions/external/pgmq/targets/native.toml @@ -0,0 +1,5 @@ +schema = "oliphaunt-extension-target-v1" +artifact_family = "sql-only" +build_kind = "pgxs-sql-only" +module_files = [] +data_files = [] diff --git a/src/extensions/external/pgmq/targets/wasix.toml b/src/extensions/external/pgmq/targets/wasix.toml new file mode 100644 index 000000000..e693c7978 --- /dev/null +++ b/src/extensions/external/pgmq/targets/wasix.toml @@ -0,0 +1,5 @@ +schema = "oliphaunt-extension-target-v1" +artifact_family = "sql-only" +build_kind = "pgxs-sql-only" +module_files = [] +data_files = [] diff --git a/src/extensions/external/pgmq/upstream-license-data.json b/src/extensions/external/pgmq/upstream-license-data.json new file mode 100644 index 000000000..1415ec8c2 --- /dev/null +++ b/src/extensions/external/pgmq/upstream-license-data.json @@ -0,0 +1,30 @@ +{ + "schema": "oliphaunt-extension-upstream-license-data-v1", + "sources": [ + { + "id": "pgmq", + "manifest": "src/extensions/external/pgmq/source.toml", + "kind": "git", + "url": "https://github.com/pgmq/pgmq.git", + "branch": "pinned", + "commit": "32c075bb6dbed66a303d1a792393c93e36c09a97" + } + ], + "extension": { + "sql_name": "pgmq", + "files": [ + { + "source": "pgmq", + "path": "LICENSE", + "destination": "share/licenses/pgmq/LICENSE", + "role": "license", + "spdx": "PostgreSQL", + "license_url": "https://github.com/pgmq/pgmq/blob/32c075bb6dbed66a303d1a792393c93e36c09a97/LICENSE", + "sha256": "a3ce61e0031bdcad1024b1bf50ded2359602160f00e0cac8e509752273df6179" + } + ] + }, + "blobs": { + "a3ce61e0031bdcad1024b1bf50ded2359602160f00e0cac8e509752273df6179": "VGhlIFBvc3RncmVTUUwgTGljZW5zZQoKQ29weXJpZ2h0IChjKSAyMDIzLCBUZW1ibwoKUGVybWlzc2lvbiB0byB1c2UsIGNvcHksIG1vZGlmeSwgYW5kIGRpc3RyaWJ1dGUgdGhpcyBzb2Z0d2FyZSBhbmQgaXRzIGRvY3VtZW50YXRpb24gZm9yIGFueSBwdXJwb3NlLCB3aXRob3V0IGZlZSwgYW5kIHdpdGhvdXQgYSB3cml0dGVuIGFncmVlbWVudCBpcyBoZXJlYnkgZ3JhbnRlZCwgcHJvdmlkZWQgdGhhdCB0aGUgYWJvdmUgY29weXJpZ2h0IG5vdGljZSBhbmQgdGhpcyBwYXJhZ3JhcGggYW5kIHRoZSBmb2xsb3dpbmcgdHdvIHBhcmFncmFwaHMgYXBwZWFyIGluIGFsbCBjb3BpZXMuCgpJTiBOTyBFVkVOVCBTSEFMTCBURU1CTyBCRSBMSUFCTEUgVE8gQU5ZIFBBUlRZIEZPUiBESVJFQ1QsIElORElSRUNULCBTUEVDSUFMLCBJTkNJREVOVEFMLCBPUiBDT05TRVFVRU5USUFMIERBTUFHRVMsIElOQ0xVRElORyBMT1NUIFBST0ZJVFMsIEFSSVNJTkcgT1VUIE9GIFRIRSBVU0UgT0YgVEhJUyBTT0ZUV0FSRSBBTkQgSVRTIERPQ1VNRU5UQVRJT04sIEVWRU4gSUYgVEVNQk8gSEFTIEJFRU4gQURWSVNFRCBPRiBUSEUgUE9TU0lCSUxJVFkgT0YgU1VDSCBEQU1BR0UuCgpURU1CTyBTUEVDSUZJQ0FMTFkgRElTQ0xBSU1TIEFOWSBXQVJSQU5USUVTLCBJTkNMVURJTkcsIEJVVCBOT1QgTElNSVRFRCBUTywgVEhFIElNUExJRUQgV0FSUkFOVElFUyBPRiBNRVJDSEFOVEFCSUxJVFkgQU5EIEZJVE5FU1MgRk9SIEEgUEFSVElDVUxBUiBQVVJQT1NFLiBUSEUgU09GVFdBUkUgUFJPVklERUQgSEVSRVVOREVSIElTIE9OIEFOICJBUyBJUyIgQkFTSVMsIEFORCBURU1CTyBIQVMgTk8gT0JMSUdBVElPTlMgVE8gUFJPVklERSBNQUlOVEVOQU5DRSwgU1VQUE9SVCwgVVBEQVRFUywgRU5IQU5DRU1FTlRTLCBPUiBNT0RJRklDQVRJT05TLgo=" + } +} diff --git a/src/extensions/external/vector/source.toml b/src/extensions/external/vector/source.toml index 9793cfe07..6f58b3348 100644 --- a/src/extensions/external/vector/source.toml +++ b/src/extensions/external/vector/source.toml @@ -1,9 +1,9 @@ name = "pgvector" url = "https://github.com/pgvector/pgvector.git" branch = "master" -commit = "d238409becebb8172fe696ffa776badfad4b631c" +commit = "f37c13f68b57d2c3472b2214fbcff699d6d34876" [extension-control] sql-name = "vector" source-path = "vector.control" -default-version = "0.8.2" +default-version = "0.8.7" diff --git a/src/extensions/external/vector/upstream-license-data.json b/src/extensions/external/vector/upstream-license-data.json index ae8bd584a..f59751ed1 100644 --- a/src/extensions/external/vector/upstream-license-data.json +++ b/src/extensions/external/vector/upstream-license-data.json @@ -7,7 +7,7 @@ "kind": "git", "url": "https://github.com/pgvector/pgvector.git", "branch": "master", - "commit": "d238409becebb8172fe696ffa776badfad4b631c" + "commit": "f37c13f68b57d2c3472b2214fbcff699d6d34876" } ], "extension": { @@ -19,7 +19,7 @@ "destination": "share/licenses/vector/LICENSE", "role": "license", "spdx": "PostgreSQL", - "license_url": "https://github.com/pgvector/pgvector/blob/d238409becebb8172fe696ffa776badfad4b631c/LICENSE", + "license_url": "https://github.com/pgvector/pgvector/blob/f37c13f68b57d2c3472b2214fbcff699d6d34876/LICENSE", "sha256": "6bba9ebeb73e27477463b05e5ef1bf303bccbddb3db9bbc95905d351604d6a87" } ] diff --git a/src/extensions/generated/contrib-build.tsv b/src/extensions/generated/contrib-build.tsv index 1aef0fed0..a8c3aa55e 100644 --- a/src/extensions/generated/contrib-build.tsv +++ b/src/extensions/generated/contrib-build.tsv @@ -1,6 +1,7 @@ # id sql_name contrib_dir module_file archive amcheck amcheck amcheck amcheck.so extensions/amcheck.tar.zst auto_explain auto_explain auto_explain auto_explain.so extensions/auto_explain.tar.zst +autoinc autoinc spi autoinc.so extensions/autoinc.tar.zst bloom bloom bloom bloom.so extensions/bloom.tar.zst btree_gin btree_gin btree_gin btree_gin.so extensions/btree_gin.tar.zst btree_gist btree_gist btree_gist btree_gist.so extensions/btree_gist.tar.zst @@ -12,18 +13,25 @@ earthdistance earthdistance earthdistance earthdistance.so extensions/earthdista file_fdw file_fdw file_fdw file_fdw.so extensions/file_fdw.tar.zst fuzzystrmatch fuzzystrmatch fuzzystrmatch fuzzystrmatch.so extensions/fuzzystrmatch.tar.zst hstore hstore hstore hstore.so extensions/hstore.tar.zst +insert_username insert_username spi insert_username.so extensions/insert_username.tar.zst intarray intarray intarray _int.so extensions/intarray.tar.zst isn isn isn isn.so extensions/isn.tar.zst lo lo lo lo.so extensions/lo.tar.zst ltree ltree ltree ltree.so extensions/ltree.tar.zst +moddatetime moddatetime spi moddatetime.so extensions/moddatetime.tar.zst pageinspect pageinspect pageinspect pageinspect.so extensions/pageinspect.tar.zst +passwordcheck passwordcheck passwordcheck passwordcheck.so extensions/passwordcheck.tar.zst pg_buffercache pg_buffercache pg_buffercache pg_buffercache.so extensions/pg_buffercache.tar.zst pg_freespacemap pg_freespacemap pg_freespacemap pg_freespacemap.so extensions/pg_freespacemap.tar.zst +pg_logicalinspect pg_logicalinspect pg_logicalinspect pg_logicalinspect.so extensions/pg_logicalinspect.tar.zst +pg_overexplain pg_overexplain pg_overexplain pg_overexplain.so extensions/pg_overexplain.tar.zst +pg_stat_statements pg_stat_statements pg_stat_statements pg_stat_statements.so extensions/pg_stat_statements.tar.zst pg_surgery pg_surgery pg_surgery pg_surgery.so extensions/pg_surgery.tar.zst pg_trgm pg_trgm pg_trgm pg_trgm.so extensions/pg_trgm.tar.zst pg_visibility pg_visibility pg_visibility pg_visibility.so extensions/pg_visibility.tar.zst pg_walinspect pg_walinspect pg_walinspect pg_walinspect.so extensions/pg_walinspect.tar.zst pgcrypto pgcrypto pgcrypto pgcrypto.so extensions/pgcrypto.tar.zst +refint refint spi refint.so extensions/refint.tar.zst seg seg seg seg.so extensions/seg.tar.zst tablefunc tablefunc tablefunc tablefunc.so extensions/tablefunc.tar.zst tcn tcn tcn tcn.so extensions/tcn.tar.zst diff --git a/src/extensions/generated/docs/extension-evidence.json b/src/extensions/generated/docs/extension-evidence.json index 7eec97f1b..5dd4582a9 100644 --- a/src/extensions/generated/docs/extension-evidence.json +++ b/src/extensions/generated/docs/extension-evidence.json @@ -68,6 +68,40 @@ ], "sql-name": "auto_explain" }, + { + "artifact-family": "wasix-runtime", + "evidence-required": [ + "wasix-full-lifecycle-v1" + ], + "extension": "autoinc", + "latest-accepted-evidence": [], + "missing-current-evidence": [ + { + "artifact-family": "wasix-runtime", + "evidence-tier": "wasix-full-lifecycle-v1", + "platform-target": "portable", + "runtime-modes": [ + "direct", + "server", + "restart", + "backup-restore", + "materialization" + ] + } + ], + "platform-targets": [ + "portable" + ], + "postgres-major": 18, + "runtime-modes": [ + "direct", + "server", + "restart", + "backup-restore", + "materialization" + ], + "sql-name": "autoinc" + }, { "artifact-family": "wasix-runtime", "evidence-required": [ @@ -442,6 +476,40 @@ ], "sql-name": "hstore" }, + { + "artifact-family": "wasix-runtime", + "evidence-required": [ + "wasix-full-lifecycle-v1" + ], + "extension": "insert_username", + "latest-accepted-evidence": [], + "missing-current-evidence": [ + { + "artifact-family": "wasix-runtime", + "evidence-tier": "wasix-full-lifecycle-v1", + "platform-target": "portable", + "runtime-modes": [ + "direct", + "server", + "restart", + "backup-restore", + "materialization" + ] + } + ], + "platform-targets": [ + "portable" + ], + "postgres-major": 18, + "runtime-modes": [ + "direct", + "server", + "restart", + "backup-restore", + "materialization" + ], + "sql-name": "insert_username" + }, { "artifact-family": "wasix-runtime", "evidence-required": [ @@ -578,6 +646,40 @@ ], "sql-name": "ltree" }, + { + "artifact-family": "wasix-runtime", + "evidence-required": [ + "wasix-full-lifecycle-v1" + ], + "extension": "moddatetime", + "latest-accepted-evidence": [], + "missing-current-evidence": [ + { + "artifact-family": "wasix-runtime", + "evidence-tier": "wasix-full-lifecycle-v1", + "platform-target": "portable", + "runtime-modes": [ + "direct", + "server", + "restart", + "backup-restore", + "materialization" + ] + } + ], + "platform-targets": [ + "portable" + ], + "postgres-major": 18, + "runtime-modes": [ + "direct", + "server", + "restart", + "backup-restore", + "materialization" + ], + "sql-name": "moddatetime" + }, { "artifact-family": "wasix-runtime", "evidence-required": [ @@ -612,6 +714,40 @@ ], "sql-name": "pageinspect" }, + { + "artifact-family": "wasix-runtime", + "evidence-required": [ + "wasix-full-lifecycle-v1" + ], + "extension": "passwordcheck", + "latest-accepted-evidence": [], + "missing-current-evidence": [ + { + "artifact-family": "wasix-runtime", + "evidence-tier": "wasix-full-lifecycle-v1", + "platform-target": "portable", + "runtime-modes": [ + "direct", + "server", + "restart", + "backup-restore", + "materialization" + ] + } + ], + "platform-targets": [ + "portable" + ], + "postgres-major": 18, + "runtime-modes": [ + "direct", + "server", + "restart", + "backup-restore", + "materialization" + ], + "sql-name": "passwordcheck" + }, { "artifact-family": "wasix-runtime", "evidence-required": [ @@ -748,6 +884,142 @@ ], "sql-name": "pg_ivm" }, + { + "artifact-family": "wasix-runtime", + "evidence-required": [ + "wasix-full-lifecycle-v1" + ], + "extension": "pg_logicalinspect", + "latest-accepted-evidence": [], + "missing-current-evidence": [ + { + "artifact-family": "wasix-runtime", + "evidence-tier": "wasix-full-lifecycle-v1", + "platform-target": "portable", + "runtime-modes": [ + "direct", + "server", + "restart", + "backup-restore", + "materialization" + ] + } + ], + "platform-targets": [ + "portable" + ], + "postgres-major": 18, + "runtime-modes": [ + "direct", + "server", + "restart", + "backup-restore", + "materialization" + ], + "sql-name": "pg_logicalinspect" + }, + { + "artifact-family": "wasix-runtime", + "evidence-required": [ + "wasix-full-lifecycle-v1" + ], + "extension": "pg_overexplain", + "latest-accepted-evidence": [], + "missing-current-evidence": [ + { + "artifact-family": "wasix-runtime", + "evidence-tier": "wasix-full-lifecycle-v1", + "platform-target": "portable", + "runtime-modes": [ + "direct", + "server", + "restart", + "backup-restore", + "materialization" + ] + } + ], + "platform-targets": [ + "portable" + ], + "postgres-major": 18, + "runtime-modes": [ + "direct", + "server", + "restart", + "backup-restore", + "materialization" + ], + "sql-name": "pg_overexplain" + }, + { + "artifact-family": "wasix-runtime", + "evidence-required": [ + "wasix-full-lifecycle-v1" + ], + "extension": "pg_partman", + "latest-accepted-evidence": [], + "missing-current-evidence": [ + { + "artifact-family": "wasix-runtime", + "evidence-tier": "wasix-full-lifecycle-v1", + "platform-target": "portable", + "runtime-modes": [ + "direct", + "server", + "restart", + "backup-restore", + "materialization" + ] + } + ], + "platform-targets": [ + "portable" + ], + "postgres-major": 18, + "runtime-modes": [ + "direct", + "server", + "restart", + "backup-restore", + "materialization" + ], + "sql-name": "pg_partman" + }, + { + "artifact-family": "wasix-runtime", + "evidence-required": [ + "wasix-full-lifecycle-v1" + ], + "extension": "pg_stat_statements", + "latest-accepted-evidence": [], + "missing-current-evidence": [ + { + "artifact-family": "wasix-runtime", + "evidence-tier": "wasix-full-lifecycle-v1", + "platform-target": "portable", + "runtime-modes": [ + "direct", + "server", + "restart", + "backup-restore", + "materialization" + ] + } + ], + "platform-targets": [ + "portable" + ], + "postgres-major": 18, + "runtime-modes": [ + "direct", + "server", + "restart", + "backup-restore", + "materialization" + ], + "sql-name": "pg_stat_statements" + }, { "artifact-family": "wasix-runtime", "evidence-required": [ @@ -986,6 +1258,40 @@ ], "sql-name": "pgcrypto" }, + { + "artifact-family": "wasix-runtime", + "evidence-required": [ + "wasix-full-lifecycle-v1" + ], + "extension": "pgmq", + "latest-accepted-evidence": [], + "missing-current-evidence": [ + { + "artifact-family": "wasix-runtime", + "evidence-tier": "wasix-full-lifecycle-v1", + "platform-target": "portable", + "runtime-modes": [ + "direct", + "server", + "restart", + "backup-restore", + "materialization" + ] + } + ], + "platform-targets": [ + "portable" + ], + "postgres-major": 18, + "runtime-modes": [ + "direct", + "server", + "restart", + "backup-restore", + "materialization" + ], + "sql-name": "pgmq" + }, { "artifact-family": "wasix-runtime", "evidence-required": [ @@ -1054,6 +1360,40 @@ ], "sql-name": "postgis" }, + { + "artifact-family": "wasix-runtime", + "evidence-required": [ + "wasix-full-lifecycle-v1" + ], + "extension": "refint", + "latest-accepted-evidence": [], + "missing-current-evidence": [ + { + "artifact-family": "wasix-runtime", + "evidence-tier": "wasix-full-lifecycle-v1", + "platform-target": "portable", + "runtime-modes": [ + "direct", + "server", + "restart", + "backup-restore", + "materialization" + ] + } + ], + "platform-targets": [ + "portable" + ], + "postgres-major": 18, + "runtime-modes": [ + "direct", + "server", + "restart", + "backup-restore", + "materialization" + ], + "sql-name": "refint" + }, { "artifact-family": "wasix-runtime", "evidence-required": [ @@ -1346,7 +1686,7 @@ "collector": "src/extensions/tools/collect-wasix-evidence.sh", "kind": "exact-sha-ci" }, - "source-digest": "sha256:9bd5bb09681d1ca3f0057fc0e91cddd2b1516d87940544ae17eb9ea4f1ddffa3", + "source-digest": "sha256:04e5ff53f5a967c2ab54efc0cafdfbd6d8b14db12e51e53bd4010fd79b177132", "source-digest-inputs": [ "src/third-party/postgres/source.toml", "src/extensions/catalog/extensions.source.json", @@ -1358,9 +1698,11 @@ "src/database-resources/icu/source.toml", "src/extensions/external/pg_hashids/source.toml", "src/extensions/external/pg_ivm/source.toml", + "src/extensions/external/pg_partman/source.toml", "src/extensions/external/pg_textsearch/source.toml", "src/extensions/external/pg_textsearch/tests/upgrade/source.toml", "src/extensions/external/pg_uuidv7/source.toml", + "src/extensions/external/pgmq/source.toml", "src/extensions/external/pgtap/source.toml", "src/extensions/external/postgis/dependencies/geos/source.toml", "src/extensions/external/postgis/dependencies/json-c/source.toml", @@ -1377,11 +1719,21 @@ "src/extensions/external/pg_hashids/upstream-license-data.json", "src/extensions/external/pg_ivm/targets/native-static-registry.toml", "src/extensions/external/pg_ivm/upstream-license-data.json", + "src/extensions/external/pg_partman/recipe.toml", + "src/extensions/external/pg_partman/targets/native-static-registry.toml", + "src/extensions/external/pg_partman/targets/native.toml", + "src/extensions/external/pg_partman/targets/wasix.toml", + "src/extensions/external/pg_partman/upstream-license-data.json", "src/extensions/external/pg_textsearch/recipe.toml", "src/extensions/external/pg_textsearch/targets/native-static-registry.toml", "src/extensions/external/pg_textsearch/tests/qualify.sh", "src/extensions/external/pg_textsearch/upstream-license-data.json", "src/extensions/external/pg_uuidv7/upstream-license-data.json", + "src/extensions/external/pgmq/recipe.toml", + "src/extensions/external/pgmq/targets/native-static-registry.toml", + "src/extensions/external/pgmq/targets/native.toml", + "src/extensions/external/pgmq/targets/wasix.toml", + "src/extensions/external/pgmq/upstream-license-data.json", "src/extensions/external/pgtap/recipe.toml", "src/extensions/external/pgtap/targets/native-static-registry.toml", "src/extensions/external/pgtap/targets/native.toml", @@ -1406,6 +1758,7 @@ "src/test-fixtures/extensions/manifest.json", "src/test-fixtures/extensions/amcheck.sql", "src/test-fixtures/extensions/auto_explain.sql", + "src/test-fixtures/extensions/autoinc.sql", "src/test-fixtures/extensions/bloom.sql", "src/test-fixtures/extensions/btree_gin.sql", "src/test-fixtures/extensions/btree_gist.sql", @@ -1417,15 +1770,22 @@ "src/test-fixtures/extensions/file_fdw.sql", "src/test-fixtures/extensions/fuzzystrmatch.sql", "src/test-fixtures/extensions/hstore.sql", + "src/test-fixtures/extensions/insert_username.sql", "src/test-fixtures/extensions/intarray.sql", "src/test-fixtures/extensions/isn.sql", "src/test-fixtures/extensions/lo.sql", "src/test-fixtures/extensions/ltree.sql", + "src/test-fixtures/extensions/moddatetime.sql", "src/test-fixtures/extensions/pageinspect.sql", + "src/test-fixtures/extensions/passwordcheck.sql", "src/test-fixtures/extensions/pg_buffercache.sql", "src/test-fixtures/extensions/pg_freespacemap.sql", "src/test-fixtures/extensions/pg_hashids.sql", "src/test-fixtures/extensions/pg_ivm.sql", + "src/test-fixtures/extensions/pg_logicalinspect.sql", + "src/test-fixtures/extensions/pg_overexplain.sql", + "src/test-fixtures/extensions/pg_partman.sql", + "src/test-fixtures/extensions/pg_stat_statements.sql", "src/test-fixtures/extensions/pg_surgery.sql", "src/test-fixtures/extensions/pg_textsearch.sql", "src/test-fixtures/extensions/pg_trgm.sql", @@ -1433,8 +1793,10 @@ "src/test-fixtures/extensions/pg_visibility.sql", "src/test-fixtures/extensions/pg_walinspect.sql", "src/test-fixtures/extensions/pgcrypto.sql", + "src/test-fixtures/extensions/pgmq.sql", "src/test-fixtures/extensions/pgtap.sql", "src/test-fixtures/extensions/postgis.sql", + "src/test-fixtures/extensions/refint.sql", "src/test-fixtures/extensions/seg.sql", "src/test-fixtures/extensions/tablefunc.sql", "src/test-fixtures/extensions/tcn.sql", diff --git a/src/extensions/generated/extensions.catalog.json b/src/extensions/generated/extensions.catalog.json index 24b8230d0..9d78e7b8e 100644 --- a/src/extensions/generated/extensions.catalog.json +++ b/src/extensions/generated/extensions.catalog.json @@ -92,6 +92,43 @@ "native-module-file": "auto_explain.so", "notes": [] }, + { + "id": "autoinc", + "sql-name": "autoinc", + "rust-constant": "AUTOINC", + "display-name": "autoinc", + "source-kind": "postgres-contrib", + "upstream-import-name": "autoinc", + "package-export": "./contrib/autoinc", + "tags": [ + "postgres extension", + "postgres/contrib" + ], + "control-file": "src/third-party/postgres/contrib/spi/autoinc.control", + "control": { + "default-version": "1.0", + "module-pathname": "$libdir/autoinc", + "requires": [], + "relocatable": "true" + }, + "dependencies": [], + "load-order": [], + "lifecycle": { + "create-extension": true, + "create-schema": "pg_catalog", + "load-sql": [], + "post-create-sql": [], + "startup-config": [], + "preload-required": false, + "restart-required": false, + "shared-memory-required": false + }, + "tests": [ + "src/test-fixtures/extensions/autoinc.sql" + ], + "native-module-file": "autoinc.so", + "notes": [] + }, { "id": "bloom", "sql-name": "bloom", @@ -514,6 +551,43 @@ "native-module-file": "hstore.so", "notes": [] }, + { + "id": "insert_username", + "sql-name": "insert_username", + "rust-constant": "INSERT_USERNAME", + "display-name": "insert_username", + "source-kind": "postgres-contrib", + "upstream-import-name": "insert_username", + "package-export": "./contrib/insert_username", + "tags": [ + "postgres extension", + "postgres/contrib" + ], + "control-file": "src/third-party/postgres/contrib/spi/insert_username.control", + "control": { + "default-version": "1.0", + "module-pathname": "$libdir/insert_username", + "requires": [], + "relocatable": "true" + }, + "dependencies": [], + "load-order": [], + "lifecycle": { + "create-extension": true, + "create-schema": "pg_catalog", + "load-sql": [], + "post-create-sql": [], + "startup-config": [], + "preload-required": false, + "restart-required": false, + "shared-memory-required": false + }, + "tests": [ + "src/test-fixtures/extensions/insert_username.sql" + ], + "native-module-file": "insert_username.so", + "notes": [] + }, { "id": "intarray", "sql-name": "intarray", @@ -666,6 +740,43 @@ "native-module-file": "ltree.so", "notes": [] }, + { + "id": "moddatetime", + "sql-name": "moddatetime", + "rust-constant": "MODDATETIME", + "display-name": "moddatetime", + "source-kind": "postgres-contrib", + "upstream-import-name": "moddatetime", + "package-export": "./contrib/moddatetime", + "tags": [ + "postgres extension", + "postgres/contrib" + ], + "control-file": "src/third-party/postgres/contrib/spi/moddatetime.control", + "control": { + "default-version": "1.0", + "module-pathname": "$libdir/moddatetime", + "requires": [], + "relocatable": "true" + }, + "dependencies": [], + "load-order": [], + "lifecycle": { + "create-extension": true, + "create-schema": "pg_catalog", + "load-sql": [], + "post-create-sql": [], + "startup-config": [], + "preload-required": false, + "restart-required": false, + "shared-memory-required": false + }, + "tests": [ + "src/test-fixtures/extensions/moddatetime.sql" + ], + "native-module-file": "moddatetime.so", + "notes": [] + }, { "id": "pageinspect", "sql-name": "pageinspect", @@ -704,6 +815,39 @@ "native-module-file": "pageinspect.so", "notes": [] }, + { + "id": "passwordcheck", + "sql-name": "passwordcheck", + "rust-constant": "PASSWORDCHECK", + "display-name": "passwordcheck", + "source-kind": "postgres-contrib", + "upstream-import-name": "passwordcheck", + "package-export": "./contrib/passwordcheck", + "tags": [ + "postgres extension", + "postgres/contrib" + ], + "dependencies": [], + "load-order": [], + "lifecycle": { + "create-extension": false, + "load-sql": [ + "LOAD 'passwordcheck';" + ], + "post-create-sql": [], + "startup-config": [], + "preload-required": false, + "restart-required": false, + "shared-memory-required": false + }, + "tests": [ + "src/test-fixtures/extensions/passwordcheck.sql" + ], + "native-module-file": "passwordcheck.so", + "notes": [ + "LOAD enables password checks for the current session. Use shared_preload_libraries to enforce checks across postmaster sessions." + ] + }, { "id": "pg_buffercache", "sql-name": "pg_buffercache", @@ -831,7 +975,7 @@ "bundle-size": 24865, "control-file": "target/oliphaunt-sources/checkouts/pg_ivm/pg_ivm.control", "control": { - "default-version": "1.13", + "default-version": "1.17", "module-pathname": "$libdir/pg_ivm", "requires": [], "relocatable": "false", @@ -855,6 +999,153 @@ "native-module-file": "pg_ivm.so", "notes": [] }, + { + "id": "pg_logicalinspect", + "sql-name": "pg_logicalinspect", + "rust-constant": "PG_LOGICALINSPECT", + "display-name": "pg_logicalinspect", + "source-kind": "postgres-contrib", + "upstream-import-name": "pg_logicalinspect", + "package-export": "./contrib/pg_logicalinspect", + "tags": [ + "postgres extension", + "postgres/contrib" + ], + "control-file": "src/third-party/postgres/contrib/pg_logicalinspect/pg_logicalinspect.control", + "control": { + "default-version": "1.0", + "module-pathname": "$libdir/pg_logicalinspect", + "requires": [], + "relocatable": "true" + }, + "dependencies": [], + "load-order": [], + "lifecycle": { + "create-extension": true, + "create-schema": "pg_catalog", + "load-sql": [], + "post-create-sql": [], + "startup-config": [], + "preload-required": false, + "restart-required": false, + "shared-memory-required": false + }, + "tests": [ + "src/test-fixtures/extensions/pg_logicalinspect.sql" + ], + "native-module-file": "pg_logicalinspect.so", + "notes": [] + }, + { + "id": "pg_overexplain", + "sql-name": "pg_overexplain", + "rust-constant": "PG_OVEREXPLAIN", + "display-name": "pg_overexplain", + "source-kind": "postgres-contrib", + "upstream-import-name": "pg_overexplain", + "package-export": "./contrib/pg_overexplain", + "tags": [ + "postgres extension", + "postgres/contrib" + ], + "dependencies": [], + "load-order": [], + "lifecycle": { + "create-extension": false, + "load-sql": [ + "LOAD 'pg_overexplain';" + ], + "post-create-sql": [], + "startup-config": [], + "preload-required": false, + "restart-required": false, + "shared-memory-required": false + }, + "tests": [ + "src/test-fixtures/extensions/pg_overexplain.sql" + ], + "native-module-file": "pg_overexplain.so", + "notes": [] + }, + { + "id": "pg_partman", + "sql-name": "pg_partman", + "rust-constant": "PG_PARTMAN", + "display-name": "pg_partman", + "source-kind": "oliphaunt-other-extension", + "upstream-import-name": "pg_partman", + "package-export": "./pg_partman", + "tags": [ + "postgres extension" + ], + "control-file": "target/oliphaunt-sources/checkouts/pg_partman/pg_partman.control", + "control": { + "default-version": "5.5.0", + "requires": [ + "plpgsql" + ], + "relocatable": "false", + "superuser": "false" + }, + "dependencies": [ + "plpgsql" + ], + "load-order": [], + "lifecycle": { + "create-extension": true, + "create-schema": "partman", + "load-sql": [], + "post-create-sql": [], + "startup-config": [], + "preload-required": false, + "restart-required": false, + "shared-memory-required": false + }, + "tests": [ + "src/test-fixtures/extensions/pg_partman.sql" + ], + "notes": [ + "SQL-only build without pg_partman_bgw or Python utilities. Applications invoke maintenance explicitly." + ] + }, + { + "id": "pg_stat_statements", + "sql-name": "pg_stat_statements", + "rust-constant": "PG_STAT_STATEMENTS", + "display-name": "pg_stat_statements", + "source-kind": "postgres-contrib", + "upstream-import-name": "pg_stat_statements", + "package-export": "./contrib/pg_stat_statements", + "tags": [ + "postgres extension", + "postgres/contrib" + ], + "control-file": "src/third-party/postgres/contrib/pg_stat_statements/pg_stat_statements.control", + "control": { + "default-version": "1.12", + "module-pathname": "$libdir/pg_stat_statements", + "requires": [], + "relocatable": "true" + }, + "dependencies": [], + "load-order": [], + "lifecycle": { + "create-extension": true, + "load-sql": [], + "post-create-sql": [], + "startup-config": [ + "shared_preload_libraries=pg_stat_statements" + ], + "preload-required": true, + "restart-required": true, + "shared-memory-required": true + }, + "tests": [ + "src/test-fixtures/extensions/pg_stat_statements.sql" + ], + "native-module-file": "pg_stat_statements.so", + "notes": [] + }, { "id": "pg_surgery", "sql-name": "pg_surgery", @@ -1120,6 +1411,47 @@ "native-module-file": "pgcrypto.so", "notes": [] }, + { + "id": "pgmq", + "sql-name": "pgmq", + "rust-constant": "PGMQ", + "display-name": "PGMQ", + "source-kind": "oliphaunt-other-extension", + "upstream-import-name": "pgmq", + "package-export": "./pgmq", + "tags": [ + "postgres extension" + ], + "control-file": "target/oliphaunt-sources/checkouts/pgmq/pgmq-extension/pgmq.control", + "control": { + "default-version": "1.13.0", + "module-pathname": "$libdir/pgmq", + "requires": [], + "relocatable": "false", + "schema": "pgmq", + "superuser": "false" + }, + "dependencies": [ + "plpgsql" + ], + "load-order": [], + "lifecycle": { + "create-extension": true, + "create-schema": "pgmq", + "load-sql": [], + "post-create-sql": [], + "startup-config": [], + "preload-required": false, + "restart-required": false, + "shared-memory-required": false + }, + "tests": [ + "src/test-fixtures/extensions/pgmq.sql" + ], + "notes": [ + "Partitioned queues additionally require pg_partman; basic queues do not." + ] + }, { "id": "pgtap", "sql-name": "pgtap", @@ -1196,6 +1528,43 @@ "native-module-file": "postgis-3.so", "notes": [] }, + { + "id": "refint", + "sql-name": "refint", + "rust-constant": "REFINT", + "display-name": "refint", + "source-kind": "postgres-contrib", + "upstream-import-name": "refint", + "package-export": "./contrib/refint", + "tags": [ + "postgres extension", + "postgres/contrib" + ], + "control-file": "src/third-party/postgres/contrib/spi/refint.control", + "control": { + "default-version": "1.0", + "module-pathname": "$libdir/refint", + "requires": [], + "relocatable": "true" + }, + "dependencies": [], + "load-order": [], + "lifecycle": { + "create-extension": true, + "create-schema": "pg_catalog", + "load-sql": [], + "post-create-sql": [], + "startup-config": [], + "preload-required": false, + "restart-required": false, + "shared-memory-required": false + }, + "tests": [ + "src/test-fixtures/extensions/refint.sql" + ], + "native-module-file": "refint.so", + "notes": [] + }, { "id": "seg", "sql-name": "seg", @@ -1476,7 +1845,7 @@ "bundle-size": 43953, "control-file": "target/oliphaunt-sources/checkouts/pgvector/vector.control", "control": { - "default-version": "0.8.2", + "default-version": "0.8.7", "module-pathname": "$libdir/vector", "requires": [], "relocatable": "true" diff --git a/src/extensions/generated/mobile/static-extensions.tsv b/src/extensions/generated/mobile/static-extensions.tsv index 18310e567..c4b7151a6 100644 --- a/src/extensions/generated/mobile/static-extensions.tsv +++ b/src/extensions/generated/mobile/static-extensions.tsv @@ -2,6 +2,7 @@ sql-name native-module-stem source-kind source-rel mobile-static-dependencies ios-static-dependencies android-static-dependencies include-dependencies include-dirs cflags hash-source-dependencies ios-hash-source-dependencies android-hash-source-dependencies hash-dirs source-files source-recursive-dirs amcheck amcheck contrib contrib/amcheck auto_explain auto_explain contrib contrib/auto_explain +autoinc autoinc contrib contrib/spi autoinc.c bloom bloom contrib contrib/bloom btree_gin btree_gin contrib contrib/btree_gin btree_gist btree_gist contrib contrib/btree_gist @@ -13,15 +14,21 @@ earthdistance earthdistance contrib contrib/earthdistance file_fdw file_fdw contrib contrib/file_fdw fuzzystrmatch fuzzystrmatch contrib contrib/fuzzystrmatch hstore hstore contrib contrib/hstore +insert_username insert_username contrib contrib/spi insert_username.c intarray _int contrib contrib/intarray isn isn contrib contrib/isn lo lo contrib contrib/lo ltree ltree contrib contrib/ltree +moddatetime moddatetime contrib contrib/spi moddatetime.c pageinspect pageinspect contrib contrib/pageinspect +passwordcheck passwordcheck contrib contrib/passwordcheck pg_buffercache pg_buffercache contrib contrib/pg_buffercache pg_freespacemap pg_freespacemap contrib contrib/pg_freespacemap pg_hashids pg_hashids external target/oliphaunt-sources/checkouts/pg_hashids pg_ivm pg_ivm external target/oliphaunt-sources/checkouts/pg_ivm createas.c,matview.c,pg_ivm.c,ruleutils.c,subselect.c +pg_logicalinspect pg_logicalinspect contrib contrib/pg_logicalinspect +pg_overexplain pg_overexplain contrib contrib/pg_overexplain +pg_stat_statements pg_stat_statements contrib contrib/pg_stat_statements pg_surgery pg_surgery contrib contrib/pg_surgery pg_textsearch pg_textsearch external target/oliphaunt-sources/checkouts/pg_textsearch source:src -DPG_TEXTSEARCH_VERSION="1.5.1" src pg_trgm pg_trgm contrib contrib/pg_trgm @@ -30,6 +37,7 @@ pg_visibility pg_visibility contrib contrib/pg_visibility pg_walinspect pg_walinspect contrib contrib/pg_walinspect pgcrypto pgcrypto contrib contrib/pgcrypto openssl openssl openssl openssl openssl openssl openssl postgis postgis-3 external target/oliphaunt-sources/checkouts/postgis geos,geos-c,json-c,libcharset,libiconv,libxml2,proj,sqlite geos,geos-c,json-c,libxml2,proj,sqlite geos,geos-c,json-c,libcharset,libiconv,libxml2,proj,sqlite geos,json-c,libiconv,libxml2,proj,sqlite geos,json-c,libiconv,libxml2,proj,sqlite geos,json-c,libxml2,proj,sqlite geos,json-c,libiconv,libxml2,proj,sqlite +refint refint contrib contrib/spi refint.c seg seg contrib contrib/seg tablefunc tablefunc contrib contrib/tablefunc tcn tcn contrib contrib/tcn diff --git a/src/extensions/generated/mobile/static-registry.json b/src/extensions/generated/mobile/static-registry.json index 2a4cdcf26..6741a89bf 100644 --- a/src/extensions/generated/mobile/static-registry.json +++ b/src/extensions/generated/mobile/static-registry.json @@ -25,6 +25,13 @@ "sql-name": "auto_explain", "static-registry-required": true }, + { + "data-files": [], + "id": "autoinc", + "native-module-stem": "autoinc", + "sql-name": "autoinc", + "static-registry-required": true + }, { "data-files": [], "id": "bloom", @@ -104,6 +111,13 @@ "sql-name": "hstore", "static-registry-required": true }, + { + "data-files": [], + "id": "insert_username", + "native-module-stem": "insert_username", + "sql-name": "insert_username", + "static-registry-required": true + }, { "data-files": [], "id": "intarray", @@ -132,6 +146,13 @@ "sql-name": "ltree", "static-registry-required": true }, + { + "data-files": [], + "id": "moddatetime", + "native-module-stem": "moddatetime", + "sql-name": "moddatetime", + "static-registry-required": true + }, { "data-files": [], "id": "pageinspect", @@ -139,6 +160,13 @@ "sql-name": "pageinspect", "static-registry-required": true }, + { + "data-files": [], + "id": "passwordcheck", + "native-module-stem": "passwordcheck", + "sql-name": "passwordcheck", + "static-registry-required": true + }, { "data-files": [], "id": "pg_buffercache", @@ -167,6 +195,27 @@ "sql-name": "pg_ivm", "static-registry-required": true }, + { + "data-files": [], + "id": "pg_logicalinspect", + "native-module-stem": "pg_logicalinspect", + "sql-name": "pg_logicalinspect", + "static-registry-required": true + }, + { + "data-files": [], + "id": "pg_overexplain", + "native-module-stem": "pg_overexplain", + "sql-name": "pg_overexplain", + "static-registry-required": true + }, + { + "data-files": [], + "id": "pg_stat_statements", + "native-module-stem": "pg_stat_statements", + "sql-name": "pg_stat_statements", + "static-registry-required": true + }, { "data-files": [], "id": "pg_surgery", @@ -233,6 +282,13 @@ "sql-name": "postgis", "static-registry-required": true }, + { + "data-files": [], + "id": "refint", + "native-module-stem": "refint", + "sql-name": "refint", + "static-registry-required": true + }, { "data-files": [], "id": "seg", diff --git a/src/extensions/generated/pgxs-build.tsv b/src/extensions/generated/pgxs-build.tsv index 173f0cf1a..a9537f6af 100644 --- a/src/extensions/generated/pgxs-build.tsv +++ b/src/extensions/generated/pgxs-build.tsv @@ -1,7 +1,9 @@ # id sql_name source_dir module_file archive make_args pg_hashids pg_hashids target/oliphaunt-sources/checkouts/pg_hashids pg_hashids.so extensions/pg_hashids.tar.zst - pg_ivm pg_ivm target/oliphaunt-sources/checkouts/pg_ivm pg_ivm.so extensions/pg_ivm.tar.zst - +pg_partman pg_partman target/oliphaunt-sources/checkouts/pg_partman - extensions/pg_partman.tar.zst NO_BGW=1 SCRIPTS= DOCS= pg_textsearch pg_textsearch target/oliphaunt-sources/checkouts/pg_textsearch pg_textsearch.so extensions/pg_textsearch.tar.zst - pg_uuidv7 pg_uuidv7 target/oliphaunt-sources/checkouts/pg_uuidv7 pg_uuidv7.so extensions/pg_uuidv7.tar.zst - +pgmq pgmq target/oliphaunt-sources/checkouts/pgmq/pgmq-extension - extensions/pgmq.tar.zst - pgtap pgtap target/oliphaunt-sources/checkouts/pgtap - extensions/pgtap.tar.zst - -vector vector target/oliphaunt-sources/checkouts/pgvector vector.so extensions/vector.tar.zst - +vector vector target/oliphaunt-sources/checkouts/pgvector vector.so extensions/vector.tar.zst OPTFLAGS=-mno-relaxed-simd diff --git a/src/extensions/generated/sdk/extensions.json b/src/extensions/generated/sdk/extensions.json index c8a047409..01b3e6f72 100644 --- a/src/extensions/generated/sdk/extensions.json +++ b/src/extensions/generated/sdk/extensions.json @@ -1,5 +1,5 @@ { - "extension-catalog-sha256": "c1d2e09905d7ecc0172173b34b9e4104dad58987503dd3dab7af4ae78890d9f3", + "extension-catalog-sha256": "2f9c13406ab3ce4f8f4f9fb419aeb8ad899e5bde59228215024933dad44c46fe", "extensions": [ { "artifact-product": "oliphaunt-extension-contrib-pg18", @@ -53,6 +53,32 @@ "source-kind": "postgres-contrib", "sql-name": "auto_explain" }, + { + "artifact-product": "oliphaunt-extension-contrib-pg18", + "cargo-package": "oliphaunt-extension-contrib-pg18", + "creates-extension": true, + "data-files": [], + "dependencies": [], + "display-name": "autoinc", + "extension-sql-file-names": [], + "extension-sql-file-prefixes": [], + "id": "autoinc", + "maven-artifact": "oliphaunt-extension-contrib-pg18", + "maven-group": "dev.oliphaunt.extensions", + "native-component-requirements": [], + "native-components": [], + "native-module-stem": "autoinc", + "npm-package": "@oliphaunt/extension-contrib-pg18", + "postgres-major": 18, + "release-product": "liboliphaunt-native", + "runtime-bound": true, + "runtime-environment": [], + "runtime-share-data-files": [], + "selected-extension-dependencies": [], + "shared-preload-libraries": [], + "source-kind": "postgres-contrib", + "sql-name": "autoinc" + }, { "artifact-product": "oliphaunt-extension-contrib-pg18", "cargo-package": "oliphaunt-extension-contrib-pg18", @@ -347,6 +373,32 @@ "source-kind": "postgres-contrib", "sql-name": "hstore" }, + { + "artifact-product": "oliphaunt-extension-contrib-pg18", + "cargo-package": "oliphaunt-extension-contrib-pg18", + "creates-extension": true, + "data-files": [], + "dependencies": [], + "display-name": "insert_username", + "extension-sql-file-names": [], + "extension-sql-file-prefixes": [], + "id": "insert_username", + "maven-artifact": "oliphaunt-extension-contrib-pg18", + "maven-group": "dev.oliphaunt.extensions", + "native-component-requirements": [], + "native-components": [], + "native-module-stem": "insert_username", + "npm-package": "@oliphaunt/extension-contrib-pg18", + "postgres-major": 18, + "release-product": "liboliphaunt-native", + "runtime-bound": true, + "runtime-environment": [], + "runtime-share-data-files": [], + "selected-extension-dependencies": [], + "shared-preload-libraries": [], + "source-kind": "postgres-contrib", + "sql-name": "insert_username" + }, { "artifact-product": "oliphaunt-extension-contrib-pg18", "cargo-package": "oliphaunt-extension-contrib-pg18", @@ -451,6 +503,32 @@ "source-kind": "postgres-contrib", "sql-name": "ltree" }, + { + "artifact-product": "oliphaunt-extension-contrib-pg18", + "cargo-package": "oliphaunt-extension-contrib-pg18", + "creates-extension": true, + "data-files": [], + "dependencies": [], + "display-name": "moddatetime", + "extension-sql-file-names": [], + "extension-sql-file-prefixes": [], + "id": "moddatetime", + "maven-artifact": "oliphaunt-extension-contrib-pg18", + "maven-group": "dev.oliphaunt.extensions", + "native-component-requirements": [], + "native-components": [], + "native-module-stem": "moddatetime", + "npm-package": "@oliphaunt/extension-contrib-pg18", + "postgres-major": 18, + "release-product": "liboliphaunt-native", + "runtime-bound": true, + "runtime-environment": [], + "runtime-share-data-files": [], + "selected-extension-dependencies": [], + "shared-preload-libraries": [], + "source-kind": "postgres-contrib", + "sql-name": "moddatetime" + }, { "artifact-product": "oliphaunt-extension-contrib-pg18", "cargo-package": "oliphaunt-extension-contrib-pg18", @@ -477,6 +555,32 @@ "source-kind": "postgres-contrib", "sql-name": "pageinspect" }, + { + "artifact-product": "oliphaunt-extension-contrib-pg18", + "cargo-package": "oliphaunt-extension-contrib-pg18", + "creates-extension": false, + "data-files": [], + "dependencies": [], + "display-name": "passwordcheck", + "extension-sql-file-names": [], + "extension-sql-file-prefixes": [], + "id": "passwordcheck", + "maven-artifact": "oliphaunt-extension-contrib-pg18", + "maven-group": "dev.oliphaunt.extensions", + "native-component-requirements": [], + "native-components": [], + "native-module-stem": "passwordcheck", + "npm-package": "@oliphaunt/extension-contrib-pg18", + "postgres-major": 18, + "release-product": "liboliphaunt-native", + "runtime-bound": true, + "runtime-environment": [], + "runtime-share-data-files": [], + "selected-extension-dependencies": [], + "shared-preload-libraries": [], + "source-kind": "postgres-contrib", + "sql-name": "passwordcheck" + }, { "artifact-product": "oliphaunt-extension-contrib-pg18", "cargo-package": "oliphaunt-extension-contrib-pg18", @@ -581,6 +685,114 @@ "source-kind": "oliphaunt-other-extension", "sql-name": "pg_ivm" }, + { + "artifact-product": "oliphaunt-extension-contrib-pg18", + "cargo-package": "oliphaunt-extension-contrib-pg18", + "creates-extension": true, + "data-files": [], + "dependencies": [], + "display-name": "pg_logicalinspect", + "extension-sql-file-names": [], + "extension-sql-file-prefixes": [], + "id": "pg_logicalinspect", + "maven-artifact": "oliphaunt-extension-contrib-pg18", + "maven-group": "dev.oliphaunt.extensions", + "native-component-requirements": [], + "native-components": [], + "native-module-stem": "pg_logicalinspect", + "npm-package": "@oliphaunt/extension-contrib-pg18", + "postgres-major": 18, + "release-product": "liboliphaunt-native", + "runtime-bound": true, + "runtime-environment": [], + "runtime-share-data-files": [], + "selected-extension-dependencies": [], + "shared-preload-libraries": [], + "source-kind": "postgres-contrib", + "sql-name": "pg_logicalinspect" + }, + { + "artifact-product": "oliphaunt-extension-contrib-pg18", + "cargo-package": "oliphaunt-extension-contrib-pg18", + "creates-extension": false, + "data-files": [], + "dependencies": [], + "display-name": "pg_overexplain", + "extension-sql-file-names": [], + "extension-sql-file-prefixes": [], + "id": "pg_overexplain", + "maven-artifact": "oliphaunt-extension-contrib-pg18", + "maven-group": "dev.oliphaunt.extensions", + "native-component-requirements": [], + "native-components": [], + "native-module-stem": "pg_overexplain", + "npm-package": "@oliphaunt/extension-contrib-pg18", + "postgres-major": 18, + "release-product": "liboliphaunt-native", + "runtime-bound": true, + "runtime-environment": [], + "runtime-share-data-files": [], + "selected-extension-dependencies": [], + "shared-preload-libraries": [], + "source-kind": "postgres-contrib", + "sql-name": "pg_overexplain" + }, + { + "artifact-product": "oliphaunt-extension-pg-partman", + "cargo-package": "oliphaunt-extension-pg-partman", + "creates-extension": true, + "data-files": [], + "dependencies": [ + "plpgsql" + ], + "display-name": "pg_partman", + "extension-sql-file-names": [], + "extension-sql-file-prefixes": [], + "id": "pg_partman", + "maven-artifact": "oliphaunt-extension-pg-partman", + "maven-group": "dev.oliphaunt.extensions", + "native-component-requirements": [], + "native-components": [], + "native-module-stem": null, + "npm-package": "@oliphaunt/extension-pg-partman", + "postgres-major": 18, + "release-product": "oliphaunt-extension-pg-partman", + "runtime-bound": false, + "runtime-environment": [], + "runtime-share-data-files": [], + "selected-extension-dependencies": [], + "shared-preload-libraries": [], + "source-kind": "oliphaunt-other-extension", + "sql-name": "pg_partman" + }, + { + "artifact-product": "oliphaunt-extension-contrib-pg18", + "cargo-package": "oliphaunt-extension-contrib-pg18", + "creates-extension": true, + "data-files": [], + "dependencies": [], + "display-name": "pg_stat_statements", + "extension-sql-file-names": [], + "extension-sql-file-prefixes": [], + "id": "pg_stat_statements", + "maven-artifact": "oliphaunt-extension-contrib-pg18", + "maven-group": "dev.oliphaunt.extensions", + "native-component-requirements": [], + "native-components": [], + "native-module-stem": "pg_stat_statements", + "npm-package": "@oliphaunt/extension-contrib-pg18", + "postgres-major": 18, + "release-product": "liboliphaunt-native", + "runtime-bound": true, + "runtime-environment": [], + "runtime-share-data-files": [], + "selected-extension-dependencies": [], + "shared-preload-libraries": [ + "pg_stat_statements" + ], + "source-kind": "postgres-contrib", + "sql-name": "pg_stat_statements" + }, { "artifact-product": "oliphaunt-extension-contrib-pg18", "cargo-package": "oliphaunt-extension-contrib-pg18", @@ -864,6 +1076,34 @@ "source-kind": "postgres-contrib", "sql-name": "pgcrypto" }, + { + "artifact-product": "oliphaunt-extension-pgmq", + "cargo-package": "oliphaunt-extension-pgmq", + "creates-extension": true, + "data-files": [], + "dependencies": [ + "plpgsql" + ], + "display-name": "PGMQ", + "extension-sql-file-names": [], + "extension-sql-file-prefixes": [], + "id": "pgmq", + "maven-artifact": "oliphaunt-extension-pgmq", + "maven-group": "dev.oliphaunt.extensions", + "native-component-requirements": [], + "native-components": [], + "native-module-stem": null, + "npm-package": "@oliphaunt/extension-pgmq", + "postgres-major": 18, + "release-product": "oliphaunt-extension-pgmq", + "runtime-bound": false, + "runtime-environment": [], + "runtime-share-data-files": [], + "selected-extension-dependencies": [], + "shared-preload-libraries": [], + "source-kind": "oliphaunt-other-extension", + "sql-name": "pgmq" + }, { "artifact-product": "oliphaunt-extension-pgtap", "cargo-package": "oliphaunt-extension-pgtap", @@ -1156,6 +1396,32 @@ "source-kind": "postgis", "sql-name": "postgis" }, + { + "artifact-product": "oliphaunt-extension-contrib-pg18", + "cargo-package": "oliphaunt-extension-contrib-pg18", + "creates-extension": true, + "data-files": [], + "dependencies": [], + "display-name": "refint", + "extension-sql-file-names": [], + "extension-sql-file-prefixes": [], + "id": "refint", + "maven-artifact": "oliphaunt-extension-contrib-pg18", + "maven-group": "dev.oliphaunt.extensions", + "native-component-requirements": [], + "native-components": [], + "native-module-stem": "refint", + "npm-package": "@oliphaunt/extension-contrib-pg18", + "postgres-major": 18, + "release-product": "liboliphaunt-native", + "runtime-bound": true, + "runtime-environment": [], + "runtime-share-data-files": [], + "selected-extension-dependencies": [], + "shared-preload-libraries": [], + "source-kind": "postgres-contrib", + "sql-name": "refint" + }, { "artifact-product": "oliphaunt-extension-contrib-pg18", "cargo-package": "oliphaunt-extension-contrib-pg18", diff --git a/src/extensions/generated/wasix/extensions.json b/src/extensions/generated/wasix/extensions.json index 8103c602e..952b99967 100644 --- a/src/extensions/generated/wasix/extensions.json +++ b/src/extensions/generated/wasix/extensions.json @@ -48,6 +48,28 @@ "native-support-modules": [], "sql-name": "auto_explain" }, + { + "archive": "extensions/autoinc.tar.zst", + "dependencies": [], + "id": "autoinc", + "lifecycle": { + "create-extension": true, + "create-schema": "pg_catalog", + "load-sql": [], + "post-create-sql": [], + "preload-required": false, + "restart-required": false, + "shared-memory-required": false, + "startup-config": [] + }, + "load-order": [], + "native-components": [], + "native-link-units": [], + "native-module-file": "autoinc.so", + "native-runtime-files": [], + "native-support-modules": [], + "sql-name": "autoinc" + }, { "archive": "extensions/bloom.tar.zst", "dependencies": [], @@ -292,6 +314,28 @@ "native-support-modules": [], "sql-name": "hstore" }, + { + "archive": "extensions/insert_username.tar.zst", + "dependencies": [], + "id": "insert_username", + "lifecycle": { + "create-extension": true, + "create-schema": "pg_catalog", + "load-sql": [], + "post-create-sql": [], + "preload-required": false, + "restart-required": false, + "shared-memory-required": false, + "startup-config": [] + }, + "load-order": [], + "native-components": [], + "native-link-units": [], + "native-module-file": "insert_username.so", + "native-runtime-files": [], + "native-support-modules": [], + "sql-name": "insert_username" + }, { "archive": "extensions/intarray.tar.zst", "dependencies": [], @@ -380,6 +424,28 @@ "native-support-modules": [], "sql-name": "ltree" }, + { + "archive": "extensions/moddatetime.tar.zst", + "dependencies": [], + "id": "moddatetime", + "lifecycle": { + "create-extension": true, + "create-schema": "pg_catalog", + "load-sql": [], + "post-create-sql": [], + "preload-required": false, + "restart-required": false, + "shared-memory-required": false, + "startup-config": [] + }, + "load-order": [], + "native-components": [], + "native-link-units": [], + "native-module-file": "moddatetime.so", + "native-runtime-files": [], + "native-support-modules": [], + "sql-name": "moddatetime" + }, { "archive": "extensions/pageinspect.tar.zst", "dependencies": [], @@ -402,6 +468,29 @@ "native-support-modules": [], "sql-name": "pageinspect" }, + { + "archive": "extensions/passwordcheck.tar.zst", + "dependencies": [], + "id": "passwordcheck", + "lifecycle": { + "create-extension": false, + "load-sql": [ + "LOAD 'passwordcheck';" + ], + "post-create-sql": [], + "preload-required": false, + "restart-required": false, + "shared-memory-required": false, + "startup-config": [] + }, + "load-order": [], + "native-components": [], + "native-link-units": [], + "native-module-file": "passwordcheck.so", + "native-runtime-files": [], + "native-support-modules": [], + "sql-name": "passwordcheck" + }, { "archive": "extensions/pg_buffercache.tar.zst", "dependencies": [], @@ -490,6 +579,98 @@ "native-support-modules": [], "sql-name": "pg_ivm" }, + { + "archive": "extensions/pg_logicalinspect.tar.zst", + "dependencies": [], + "id": "pg_logicalinspect", + "lifecycle": { + "create-extension": true, + "create-schema": "pg_catalog", + "load-sql": [], + "post-create-sql": [], + "preload-required": false, + "restart-required": false, + "shared-memory-required": false, + "startup-config": [] + }, + "load-order": [], + "native-components": [], + "native-link-units": [], + "native-module-file": "pg_logicalinspect.so", + "native-runtime-files": [], + "native-support-modules": [], + "sql-name": "pg_logicalinspect" + }, + { + "archive": "extensions/pg_overexplain.tar.zst", + "dependencies": [], + "id": "pg_overexplain", + "lifecycle": { + "create-extension": false, + "load-sql": [ + "LOAD 'pg_overexplain';" + ], + "post-create-sql": [], + "preload-required": false, + "restart-required": false, + "shared-memory-required": false, + "startup-config": [] + }, + "load-order": [], + "native-components": [], + "native-link-units": [], + "native-module-file": "pg_overexplain.so", + "native-runtime-files": [], + "native-support-modules": [], + "sql-name": "pg_overexplain" + }, + { + "archive": "extensions/pg_partman.tar.zst", + "dependencies": [ + "plpgsql" + ], + "id": "pg_partman", + "lifecycle": { + "create-extension": true, + "create-schema": "partman", + "load-sql": [], + "post-create-sql": [], + "preload-required": false, + "restart-required": false, + "shared-memory-required": false, + "startup-config": [] + }, + "load-order": [], + "native-components": [], + "native-link-units": [], + "native-module-file": null, + "native-runtime-files": [], + "native-support-modules": [], + "sql-name": "pg_partman" + }, + { + "archive": "extensions/pg_stat_statements.tar.zst", + "dependencies": [], + "id": "pg_stat_statements", + "lifecycle": { + "create-extension": true, + "load-sql": [], + "post-create-sql": [], + "preload-required": true, + "restart-required": true, + "shared-memory-required": true, + "startup-config": [ + "shared_preload_libraries=pg_stat_statements" + ] + }, + "load-order": [], + "native-components": [], + "native-link-units": [], + "native-module-file": "pg_stat_statements.so", + "native-runtime-files": [], + "native-support-modules": [], + "sql-name": "pg_stat_statements" + }, { "archive": "extensions/pg_surgery.tar.zst", "dependencies": [], @@ -649,6 +830,30 @@ "native-support-modules": [], "sql-name": "pgcrypto" }, + { + "archive": "extensions/pgmq.tar.zst", + "dependencies": [ + "plpgsql" + ], + "id": "pgmq", + "lifecycle": { + "create-extension": true, + "create-schema": "pgmq", + "load-sql": [], + "post-create-sql": [], + "preload-required": false, + "restart-required": false, + "shared-memory-required": false, + "startup-config": [] + }, + "load-order": [], + "native-components": [], + "native-link-units": [], + "native-module-file": null, + "native-runtime-files": [], + "native-support-modules": [], + "sql-name": "pgmq" + }, { "archive": "extensions/pgtap.tar.zst", "dependencies": [ @@ -721,6 +926,28 @@ ], "sql-name": "postgis" }, + { + "archive": "extensions/refint.tar.zst", + "dependencies": [], + "id": "refint", + "lifecycle": { + "create-extension": true, + "create-schema": "pg_catalog", + "load-sql": [], + "post-create-sql": [], + "preload-required": false, + "restart-required": false, + "shared-memory-required": false, + "startup-config": [] + }, + "load-order": [], + "native-components": [], + "native-link-units": [], + "native-module-file": "refint.so", + "native-runtime-files": [], + "native-support-modules": [], + "sql-name": "refint" + }, { "archive": "extensions/seg.tar.zst", "dependencies": [], diff --git a/src/extensions/tools/extension-model.test.mts b/src/extensions/tools/extension-model.test.mts index 64b618a52..20d97601e 100644 --- a/src/extensions/tools/extension-model.test.mts +++ b/src/extensions/tools/extension-model.test.mts @@ -10,9 +10,24 @@ import { sourceDigest, sourceDigestInputs, } from './extension-evidence.mts'; -import { discoverCatalog, extensionProjections, readJson } from './extension-projections.mts'; +import { + discoverCatalog, + extensionProjections, + pgxsSourceDirectory, + readJson, +} from './extension-projections.mts'; const identity = { commit: '1'.repeat(40), tree: '2'.repeat(40) }; + +test('nested PGXS roots remain inside the immutable source checkout', () => { + assert.equal( + pgxsSourceDirectory('pgmq', 'pgmq-extension'), + 'target/oliphaunt-sources/checkouts/pgmq/pgmq-extension', + ); + assert.equal(pgxsSourceDirectory('pgtap'), 'target/oliphaunt-sources/checkouts/pgtap'); + for (const value of ['', '.', '..', '../outside', '/absolute', 'a/../b', 'a//b', 'a\\b', 12]) + assert.throws(() => pgxsSourceDirectory('pgmq', value), /within the pinned checkout/); +}); const catalog = { extensions: [{ id: 'vector', 'sql-name': 'vector' }] }; const matrix = () => Bun.TOML.parse(evidenceMatrix(catalog)); function run() { @@ -149,3 +164,18 @@ test('extension projections retain dependency and runtime data while deriving mo assert(updated.includes('-DPG_TEXTSEARCH_VERSION="9.8.7"')); assert(!updated.includes('@EXTVERSION@')); }); + +test('SPI modules compile only their own C source in mobile static registries', () => { + const rows = readFileSync('src/extensions/generated/mobile/static-extensions.tsv', 'utf8') + .trimEnd() + .split('\n') + .slice(2) + .map((line) => line.split('\t')); + for (const name of ['autoinc', 'insert_username', 'moddatetime', 'refint']) { + const row = rows.find((fields) => fields[0] === name); + assert(row, `missing SPI module ${name}`); + assert.equal(row[3], 'contrib/spi'); + assert.equal(row[14], `${name}.c`); + assert(!row[15], 'SPI members must not also compile recursive source directories'); + } +}); diff --git a/src/extensions/tools/extension-projections.mts b/src/extensions/tools/extension-projections.mts index da44b182a..9818e5d36 100644 --- a/src/extensions/tools/extension-projections.mts +++ b/src/extensions/tools/extension-projections.mts @@ -393,7 +393,7 @@ ${metadataRows.map((row) => ` public static let ${row.id.replace(/[-_]([a-z]) dependencies('sources', ['ios-xcframework']), dependencies('sources', ['android-arm64-v8a', 'android-x86_64']), list('hash_dirs', 'mobile-static-hash-dirs'), - list('source_files'), + list('source_files', 'mobile-static-source-files'), list('source_recursive_dirs'), ] .map((value) => (Array.isArray(value) ? value.join(',') : value)) @@ -638,14 +638,24 @@ export function catalogProjections(catalog: Row): Map { ); } else if (row['source-kind'] === 'oliphaunt-other-extension') { const source = readToml(`${externalRoot}/${row['sql-name']}/source.toml`); + const recipePath = `${externalRoot}/${row['sql-name']}/recipe.toml`; + const recipe = existsSync(recipePath) ? readToml(recipePath) : {}; pgxs.push( [ row.id, row['sql-name'], - `target/oliphaunt-sources/checkouts/${source.name}`, + pgxsSourceDirectory(source.name, recipe.build?.source_subdirectory), row['native-module-file'] ?? '-', archive, - row.id === 'age' ? 'SIZEOF_DATUM=4' : '-', + row.id === 'age' + ? 'SIZEOF_DATUM=4' + : row.id === 'pg_partman' + ? 'NO_BGW=1 SCRIPTS= DOCS=' + : row.id === 'vector' + ? // Upstream contracts floating-point operations; keep its SIMD within + // the pinned Wasmer runtime's supported, non-relaxed instruction set. + 'OPTFLAGS=-mno-relaxed-simd' + : '-', ].join('\t'), ); } else assert.equal(row['source-kind'], 'postgis', 'unsupported extension build kind'); @@ -659,6 +669,18 @@ export function catalogProjections(catalog: Row): Map { return outputs; } +export function pgxsSourceDirectory(sourceName: string, subdirectory?: unknown): string { + assert(/^[a-zA-Z0-9_-]+$/.test(sourceName), 'invalid PGXS source name'); + const root = `target/oliphaunt-sources/checkouts/${sourceName}`; + if (subdirectory === undefined) return root; + assert( + typeof subdirectory === 'string' && + subdirectory.split('/').every((part) => /^[a-zA-Z0-9_-][a-zA-Z0-9_.-]*$/.test(part)), + 'PGXS source subdirectory must stay within the pinned checkout', + ); + return `${root}/${subdirectory}`; +} + function wasixRustModule(rows: Row[]): string { const cfg = (_row: Row) => ''; // Metadata is available independently of embedded payload features. const array = (values: string[]) => `&[${values.map(literal).join(', ')}]`; diff --git a/src/native/runtime/bin/build-postgres18-linux.sh b/src/native/runtime/bin/build-postgres18-linux.sh index daf31cd91..efd354a88 100755 --- a/src/native/runtime/bin/build-postgres18-linux.sh +++ b/src/native/runtime/bin/build-postgres18-linux.sh @@ -104,27 +104,34 @@ contrib_extensions=( lo ltree pageinspect + passwordcheck pg_buffercache pg_freespacemap - pgcrypto - uuid-ossp + pg_logicalinspect + pg_overexplain + pg_stat_statements pg_surgery pg_trgm pg_visibility pg_walinspect + pgcrypto seg + spi tablefunc tcn tsm_system_rows tsm_system_time unaccent + uuid-ossp ) external_extensions=( pg_ivm pg_hashids pg_uuidv7 + pg_partman pgtap + pgmq pgvector pg_textsearch postgis @@ -132,6 +139,7 @@ external_extensions=( required_extension_controls=( amcheck + autoinc bloom btree_gin btree_gist @@ -143,24 +151,31 @@ required_extension_controls=( file_fdw fuzzystrmatch hstore + insert_username intarray isn lo ltree + moddatetime pageinspect pg_buffercache pg_freespacemap pg_hashids pg_ivm - pgcrypto - postgis + pg_logicalinspect + pg_stat_statements pg_surgery pg_textsearch pg_trgm pg_uuidv7 pg_visibility pg_walinspect + pgcrypto + pg_partman pgtap + pgmq + postgis + refint seg tablefunc tcn @@ -175,6 +190,7 @@ required_extension_modules=( _int amcheck auto_explain + autoinc bloom btree_gin btree_gist @@ -186,22 +202,29 @@ required_extension_modules=( file_fdw fuzzystrmatch hstore + insert_username isn lo ltree + moddatetime pageinspect + passwordcheck pg_buffercache pg_freespacemap pg_hashids pg_ivm - pgcrypto - postgis-3 + pg_logicalinspect + pg_overexplain + pg_stat_statements pg_surgery pg_textsearch pg_trgm pg_uuidv7 pg_visibility pg_walinspect + pgcrypto + postgis-3 + refint seg tablefunc tcn @@ -227,7 +250,7 @@ native_extensions_include_postgis() { native_extension_has_control_artifacts() { case "$1" in - auto_explain) return 1 ;; + auto_explain|passwordcheck|pg_overexplain) return 1 ;; *) return 0 ;; esac } @@ -1109,6 +1132,9 @@ pgxs_extension_link_args() { local be_dllibs="$2" [ -z "$be_dllibs" ] || printf '%s\n' "PG_LDFLAGS=$be_dllibs" case "$extension" in + pg_partman) + printf '%s\n' "NO_BGW=1" "SCRIPTS=" "DOCS=" + ;; pg_textsearch|pgvector|vector) printf '%s\n' "SHLIB_LINK=-lm" ;; @@ -1146,12 +1172,17 @@ build_pgxs_extension() { cp -a "$checkout/." "$build_checkout/" rm -rf "$build_checkout/.git" make -C "$build_checkout" PG_CONFIG="$install_dir/bin/pg_config" clean >> "$make_log" 2>&1 || true - make -C "$build_checkout" \ - PG_CONFIG="$install_dir/bin/pg_config" \ - CC="$cc_string" \ - OPTFLAGS="" \ - "${normal_link_args[@]}" \ - install >> "$make_log" 2>&1 + # PGXS freezes DATA before building; generated SQL must exist before the + # separate install invocation (PGMQ derives its default-version script). + local target + for target in all install; do + make -C "$build_checkout" \ + PG_CONFIG="$install_dir/bin/pg_config" \ + CC="$cc_string" \ + OPTFLAGS="" \ + "${normal_link_args[@]}" \ + "$target" >> "$make_log" 2>&1 + done make -C "$build_checkout" PG_CONFIG="$install_dir/bin/pg_config" clean >> "$make_log" 2>&1 || true make -C "$build_checkout" \ PG_CONFIG="$install_dir/bin/pg_config" \ diff --git a/src/native/runtime/bin/build-postgres18-macos.sh b/src/native/runtime/bin/build-postgres18-macos.sh index f067404ba..bd051ed16 100755 --- a/src/native/runtime/bin/build-postgres18-macos.sh +++ b/src/native/runtime/bin/build-postgres18-macos.sh @@ -88,27 +88,34 @@ contrib_extensions=( lo ltree pageinspect + passwordcheck pg_buffercache pg_freespacemap - pgcrypto - uuid-ossp + pg_logicalinspect + pg_overexplain + pg_stat_statements pg_surgery pg_trgm pg_visibility pg_walinspect + pgcrypto seg + spi tablefunc tcn tsm_system_rows tsm_system_time unaccent + uuid-ossp ) external_extensions=( pg_ivm pg_hashids pg_uuidv7 + pg_partman pgtap + pgmq pgvector pg_textsearch postgis @@ -116,6 +123,7 @@ external_extensions=( required_extension_controls=( amcheck + autoinc bloom btree_gin btree_gist @@ -127,24 +135,31 @@ required_extension_controls=( file_fdw fuzzystrmatch hstore + insert_username intarray isn lo ltree + moddatetime pageinspect pg_buffercache pg_freespacemap pg_hashids pg_ivm - pgcrypto - postgis + pg_logicalinspect + pg_stat_statements pg_surgery pg_textsearch pg_trgm pg_uuidv7 pg_visibility pg_walinspect + pgcrypto + pg_partman pgtap + pgmq + postgis + refint seg tablefunc tcn @@ -159,6 +174,7 @@ required_extension_modules=( _int amcheck auto_explain + autoinc bloom btree_gin btree_gist @@ -170,22 +186,29 @@ required_extension_modules=( file_fdw fuzzystrmatch hstore + insert_username isn lo ltree + moddatetime pageinspect + passwordcheck pg_buffercache pg_freespacemap pg_hashids pg_ivm - pgcrypto - postgis-3 + pg_logicalinspect + pg_overexplain + pg_stat_statements pg_surgery pg_textsearch pg_trgm pg_uuidv7 pg_visibility pg_walinspect + pgcrypto + postgis-3 + refint seg tablefunc tcn @@ -211,7 +234,7 @@ native_extensions_include_postgis() { native_extension_has_control_artifacts() { case "$1" in - auto_explain) return 1 ;; + auto_explain|passwordcheck|pg_overexplain) return 1 ;; *) return 0 ;; esac } @@ -1921,6 +1944,9 @@ pgxs_extension_link_args() { local link_flags="$3" local be_dllibs="$link_flags" case "$extension" in + pg_partman) + printf '%s\n' "NO_BGW=1" "SCRIPTS=" "DOCS=" + ;; pg_textsearch|pgvector|vector) if [ -n "$be_dllibs" ]; then be_dllibs="$be_dllibs -lm" @@ -1981,12 +2007,17 @@ build_pgxs_extension() { make -C "$build_checkout" \ PG_CONFIG="$install_dir/bin/pg_config" \ clean - make -C "$build_checkout" \ - PG_CONFIG="$install_dir/bin/pg_config" \ - CC="$CC" \ - OPTFLAGS="" \ - "${normal_link_args[@]}" \ - install + # PGXS freezes DATA before building; generated SQL must exist before the + # separate install invocation (PGMQ derives its default-version script). + local target + for target in all install; do + make -C "$build_checkout" \ + PG_CONFIG="$install_dir/bin/pg_config" \ + CC="$CC" \ + OPTFLAGS="" \ + "${normal_link_args[@]}" \ + "$target" + done make -C "$build_checkout" \ PG_CONFIG="$install_dir/bin/pg_config" \ clean diff --git a/src/native/rust-bindings/src/generated/extensions.rs b/src/native/rust-bindings/src/generated/extensions.rs index 711cff99a..16ec08fd9 100644 --- a/src/native/rust-bindings/src/generated/extensions.rs +++ b/src/native/rust-bindings/src/generated/extensions.rs @@ -16,6 +16,8 @@ enum ExtensionId { Amcheck, /// PostgreSQL `auto_explain`. AutoExplain, + /// PostgreSQL `autoinc`. + Autoinc, /// PostgreSQL `bloom`. Bloom, /// PostgreSQL `btree_gin`. @@ -38,6 +40,8 @@ enum ExtensionId { Fuzzystrmatch, /// PostgreSQL `hstore`. Hstore, + /// PostgreSQL `insert_username`. + InsertUsername, /// PostgreSQL `intarray`. Intarray, /// PostgreSQL `isn`. @@ -46,8 +50,12 @@ enum ExtensionId { Lo, /// PostgreSQL `ltree`. Ltree, + /// PostgreSQL `moddatetime`. + Moddatetime, /// PostgreSQL `pageinspect`. Pageinspect, + /// PostgreSQL `passwordcheck`. + Passwordcheck, /// PostgreSQL `pg_buffercache`. PgBuffercache, /// PostgreSQL `pg_freespacemap`. @@ -56,6 +64,14 @@ enum ExtensionId { PgHashids, /// PostgreSQL `pg_ivm`. PgIvm, + /// PostgreSQL `pg_logicalinspect`. + PgLogicalinspect, + /// PostgreSQL `pg_overexplain`. + PgOverexplain, + /// PostgreSQL `pg_partman`. + PgPartman, + /// PostgreSQL `pg_stat_statements`. + PgStatStatements, /// PostgreSQL `pg_surgery`. PgSurgery, /// PostgreSQL `pg_textsearch`. @@ -70,10 +86,14 @@ enum ExtensionId { PgWalinspect, /// PostgreSQL `pgcrypto`. Pgcrypto, + /// PostgreSQL `pgmq`. + Pgmq, /// PostgreSQL `pgtap`. Pgtap, /// PostgreSQL `postgis`. Postgis, + /// PostgreSQL `refint`. + Refint, /// PostgreSQL `seg`. Seg, /// PostgreSQL `tablefunc`. @@ -103,6 +123,11 @@ impl Extension { id: ExtensionId::AutoExplain, package: None, }; + /// Select the `autoinc` artifact. + pub const AUTOINC: Self = Self { + id: ExtensionId::Autoinc, + package: None, + }; /// Select the `bloom` artifact. pub const BLOOM: Self = Self { id: ExtensionId::Bloom, @@ -158,6 +183,11 @@ impl Extension { id: ExtensionId::Hstore, package: None, }; + /// Select the `insert_username` artifact. + pub const INSERT_USERNAME: Self = Self { + id: ExtensionId::InsertUsername, + package: None, + }; /// Select the `intarray` artifact. pub const INTARRAY: Self = Self { id: ExtensionId::Intarray, @@ -178,11 +208,21 @@ impl Extension { id: ExtensionId::Ltree, package: None, }; + /// Select the `moddatetime` artifact. + pub const MODDATETIME: Self = Self { + id: ExtensionId::Moddatetime, + package: None, + }; /// Select the `pageinspect` artifact. pub const PAGEINSPECT: Self = Self { id: ExtensionId::Pageinspect, package: None, }; + /// Select the `passwordcheck` artifact. + pub const PASSWORDCHECK: Self = Self { + id: ExtensionId::Passwordcheck, + package: None, + }; /// Select the `pg_buffercache` artifact. pub const PG_BUFFERCACHE: Self = Self { id: ExtensionId::PgBuffercache, @@ -203,6 +243,26 @@ impl Extension { id: ExtensionId::PgIvm, package: None, }; + /// Select the `pg_logicalinspect` artifact. + pub const PG_LOGICALINSPECT: Self = Self { + id: ExtensionId::PgLogicalinspect, + package: None, + }; + /// Select the `pg_overexplain` artifact. + pub const PG_OVEREXPLAIN: Self = Self { + id: ExtensionId::PgOverexplain, + package: None, + }; + /// Select the `pg_partman` artifact. + pub const PG_PARTMAN: Self = Self { + id: ExtensionId::PgPartman, + package: None, + }; + /// Select the `pg_stat_statements` artifact. + pub const PG_STAT_STATEMENTS: Self = Self { + id: ExtensionId::PgStatStatements, + package: None, + }; /// Select the `pg_surgery` artifact. pub const PG_SURGERY: Self = Self { id: ExtensionId::PgSurgery, @@ -238,6 +298,11 @@ impl Extension { id: ExtensionId::Pgcrypto, package: None, }; + /// Select the `pgmq` artifact. + pub const PGMQ: Self = Self { + id: ExtensionId::Pgmq, + package: None, + }; /// Select the `pgtap` artifact. pub const PGTAP: Self = Self { id: ExtensionId::Pgtap, @@ -248,6 +313,11 @@ impl Extension { id: ExtensionId::Postgis, package: None, }; + /// Select the `refint` artifact. + pub const REFINT: Self = Self { + id: ExtensionId::Refint, + package: None, + }; /// Select the `seg` artifact. pub const SEG: Self = Self { id: ExtensionId::Seg, @@ -293,6 +363,7 @@ impl Extension { pub const ALL: &'static [Self] = &[ Extension::AMCHECK, Extension::AUTO_EXPLAIN, + Extension::AUTOINC, Extension::BLOOM, Extension::BTREE_GIN, Extension::BTREE_GIST, @@ -304,15 +375,22 @@ impl Extension { Extension::FILE_FDW, Extension::FUZZYSTRMATCH, Extension::HSTORE, + Extension::INSERT_USERNAME, Extension::INTARRAY, Extension::ISN, Extension::LO, Extension::LTREE, + Extension::MODDATETIME, Extension::PAGEINSPECT, + Extension::PASSWORDCHECK, Extension::PG_BUFFERCACHE, Extension::PG_FREESPACEMAP, Extension::PG_HASHIDS, Extension::PG_IVM, + Extension::PG_LOGICALINSPECT, + Extension::PG_OVEREXPLAIN, + Extension::PG_PARTMAN, + Extension::PG_STAT_STATEMENTS, Extension::PG_SURGERY, Extension::PG_TEXTSEARCH, Extension::PG_TRGM, @@ -320,8 +398,10 @@ impl Extension { Extension::PG_VISIBILITY, Extension::PG_WALINSPECT, Extension::PGCRYPTO, + Extension::PGMQ, Extension::PGTAP, Extension::POSTGIS, + Extension::REFINT, Extension::SEG, Extension::TABLEFUNC, Extension::TCN, @@ -338,6 +418,7 @@ pub(super) const fn sql_name(extension: Extension) -> &'static str { match extension.id { ExtensionId::Amcheck => "amcheck", ExtensionId::AutoExplain => "auto_explain", + ExtensionId::Autoinc => "autoinc", ExtensionId::Bloom => "bloom", ExtensionId::BtreeGin => "btree_gin", ExtensionId::BtreeGist => "btree_gist", @@ -349,15 +430,22 @@ pub(super) const fn sql_name(extension: Extension) -> &'static str { ExtensionId::FileFdw => "file_fdw", ExtensionId::Fuzzystrmatch => "fuzzystrmatch", ExtensionId::Hstore => "hstore", + ExtensionId::InsertUsername => "insert_username", ExtensionId::Intarray => "intarray", ExtensionId::Isn => "isn", ExtensionId::Lo => "lo", ExtensionId::Ltree => "ltree", + ExtensionId::Moddatetime => "moddatetime", ExtensionId::Pageinspect => "pageinspect", + ExtensionId::Passwordcheck => "passwordcheck", ExtensionId::PgBuffercache => "pg_buffercache", ExtensionId::PgFreespacemap => "pg_freespacemap", ExtensionId::PgHashids => "pg_hashids", ExtensionId::PgIvm => "pg_ivm", + ExtensionId::PgLogicalinspect => "pg_logicalinspect", + ExtensionId::PgOverexplain => "pg_overexplain", + ExtensionId::PgPartman => "pg_partman", + ExtensionId::PgStatStatements => "pg_stat_statements", ExtensionId::PgSurgery => "pg_surgery", ExtensionId::PgTextsearch => "pg_textsearch", ExtensionId::PgTrgm => "pg_trgm", @@ -365,8 +453,10 @@ pub(super) const fn sql_name(extension: Extension) -> &'static str { ExtensionId::PgVisibility => "pg_visibility", ExtensionId::PgWalinspect => "pg_walinspect", ExtensionId::Pgcrypto => "pgcrypto", + ExtensionId::Pgmq => "pgmq", ExtensionId::Pgtap => "pgtap", ExtensionId::Postgis => "postgis", + ExtensionId::Refint => "refint", ExtensionId::Seg => "seg", ExtensionId::Tablefunc => "tablefunc", ExtensionId::Tcn => "tcn", @@ -383,6 +473,7 @@ pub(super) const fn artifact_product(extension: Extension) -> &'static str { match extension.id { ExtensionId::Amcheck => "oliphaunt-extension-contrib-pg18", ExtensionId::AutoExplain => "oliphaunt-extension-contrib-pg18", + ExtensionId::Autoinc => "oliphaunt-extension-contrib-pg18", ExtensionId::Bloom => "oliphaunt-extension-contrib-pg18", ExtensionId::BtreeGin => "oliphaunt-extension-contrib-pg18", ExtensionId::BtreeGist => "oliphaunt-extension-contrib-pg18", @@ -394,15 +485,22 @@ pub(super) const fn artifact_product(extension: Extension) -> &'static str { ExtensionId::FileFdw => "oliphaunt-extension-contrib-pg18", ExtensionId::Fuzzystrmatch => "oliphaunt-extension-contrib-pg18", ExtensionId::Hstore => "oliphaunt-extension-contrib-pg18", + ExtensionId::InsertUsername => "oliphaunt-extension-contrib-pg18", ExtensionId::Intarray => "oliphaunt-extension-contrib-pg18", ExtensionId::Isn => "oliphaunt-extension-contrib-pg18", ExtensionId::Lo => "oliphaunt-extension-contrib-pg18", ExtensionId::Ltree => "oliphaunt-extension-contrib-pg18", + ExtensionId::Moddatetime => "oliphaunt-extension-contrib-pg18", ExtensionId::Pageinspect => "oliphaunt-extension-contrib-pg18", + ExtensionId::Passwordcheck => "oliphaunt-extension-contrib-pg18", ExtensionId::PgBuffercache => "oliphaunt-extension-contrib-pg18", ExtensionId::PgFreespacemap => "oliphaunt-extension-contrib-pg18", ExtensionId::PgHashids => "oliphaunt-extension-pg-hashids", ExtensionId::PgIvm => "oliphaunt-extension-pg-ivm", + ExtensionId::PgLogicalinspect => "oliphaunt-extension-contrib-pg18", + ExtensionId::PgOverexplain => "oliphaunt-extension-contrib-pg18", + ExtensionId::PgPartman => "oliphaunt-extension-pg-partman", + ExtensionId::PgStatStatements => "oliphaunt-extension-contrib-pg18", ExtensionId::PgSurgery => "oliphaunt-extension-contrib-pg18", ExtensionId::PgTextsearch => "oliphaunt-extension-pg-textsearch", ExtensionId::PgTrgm => "oliphaunt-extension-contrib-pg18", @@ -410,8 +508,10 @@ pub(super) const fn artifact_product(extension: Extension) -> &'static str { ExtensionId::PgVisibility => "oliphaunt-extension-contrib-pg18", ExtensionId::PgWalinspect => "oliphaunt-extension-contrib-pg18", ExtensionId::Pgcrypto => "oliphaunt-extension-contrib-pg18", + ExtensionId::Pgmq => "oliphaunt-extension-pgmq", ExtensionId::Pgtap => "oliphaunt-extension-pgtap", ExtensionId::Postgis => "oliphaunt-extension-postgis", + ExtensionId::Refint => "oliphaunt-extension-contrib-pg18", ExtensionId::Seg => "oliphaunt-extension-contrib-pg18", ExtensionId::Tablefunc => "oliphaunt-extension-contrib-pg18", ExtensionId::Tcn => "oliphaunt-extension-contrib-pg18", @@ -428,6 +528,7 @@ pub(super) const fn native_module_stem(extension: Extension) -> Option<&'static match extension.id { ExtensionId::Amcheck => Some("amcheck"), ExtensionId::AutoExplain => Some("auto_explain"), + ExtensionId::Autoinc => Some("autoinc"), ExtensionId::Bloom => Some("bloom"), ExtensionId::BtreeGin => Some("btree_gin"), ExtensionId::BtreeGist => Some("btree_gist"), @@ -439,15 +540,22 @@ pub(super) const fn native_module_stem(extension: Extension) -> Option<&'static ExtensionId::FileFdw => Some("file_fdw"), ExtensionId::Fuzzystrmatch => Some("fuzzystrmatch"), ExtensionId::Hstore => Some("hstore"), + ExtensionId::InsertUsername => Some("insert_username"), ExtensionId::Intarray => Some("_int"), ExtensionId::Isn => Some("isn"), ExtensionId::Lo => Some("lo"), ExtensionId::Ltree => Some("ltree"), + ExtensionId::Moddatetime => Some("moddatetime"), ExtensionId::Pageinspect => Some("pageinspect"), + ExtensionId::Passwordcheck => Some("passwordcheck"), ExtensionId::PgBuffercache => Some("pg_buffercache"), ExtensionId::PgFreespacemap => Some("pg_freespacemap"), ExtensionId::PgHashids => Some("pg_hashids"), ExtensionId::PgIvm => Some("pg_ivm"), + ExtensionId::PgLogicalinspect => Some("pg_logicalinspect"), + ExtensionId::PgOverexplain => Some("pg_overexplain"), + ExtensionId::PgPartman => None, + ExtensionId::PgStatStatements => Some("pg_stat_statements"), ExtensionId::PgSurgery => Some("pg_surgery"), ExtensionId::PgTextsearch => Some("pg_textsearch"), ExtensionId::PgTrgm => Some("pg_trgm"), @@ -455,8 +563,10 @@ pub(super) const fn native_module_stem(extension: Extension) -> Option<&'static ExtensionId::PgVisibility => Some("pg_visibility"), ExtensionId::PgWalinspect => Some("pg_walinspect"), ExtensionId::Pgcrypto => Some("pgcrypto"), + ExtensionId::Pgmq => None, ExtensionId::Pgtap => None, ExtensionId::Postgis => Some("postgis-3"), + ExtensionId::Refint => Some("refint"), ExtensionId::Seg => Some("seg"), ExtensionId::Tablefunc => Some("tablefunc"), ExtensionId::Tcn => Some("tcn"), @@ -473,6 +583,7 @@ pub(super) const fn creates_extension(extension: Extension) -> bool { match extension.id { ExtensionId::Amcheck => true, ExtensionId::AutoExplain => false, + ExtensionId::Autoinc => true, ExtensionId::Bloom => true, ExtensionId::BtreeGin => true, ExtensionId::BtreeGist => true, @@ -484,15 +595,22 @@ pub(super) const fn creates_extension(extension: Extension) -> bool { ExtensionId::FileFdw => true, ExtensionId::Fuzzystrmatch => true, ExtensionId::Hstore => true, + ExtensionId::InsertUsername => true, ExtensionId::Intarray => true, ExtensionId::Isn => true, ExtensionId::Lo => true, ExtensionId::Ltree => true, + ExtensionId::Moddatetime => true, ExtensionId::Pageinspect => true, + ExtensionId::Passwordcheck => false, ExtensionId::PgBuffercache => true, ExtensionId::PgFreespacemap => true, ExtensionId::PgHashids => true, ExtensionId::PgIvm => true, + ExtensionId::PgLogicalinspect => true, + ExtensionId::PgOverexplain => false, + ExtensionId::PgPartman => true, + ExtensionId::PgStatStatements => true, ExtensionId::PgSurgery => true, ExtensionId::PgTextsearch => true, ExtensionId::PgTrgm => true, @@ -500,8 +618,10 @@ pub(super) const fn creates_extension(extension: Extension) -> bool { ExtensionId::PgVisibility => true, ExtensionId::PgWalinspect => true, ExtensionId::Pgcrypto => true, + ExtensionId::Pgmq => true, ExtensionId::Pgtap => true, ExtensionId::Postgis => true, + ExtensionId::Refint => true, ExtensionId::Seg => true, ExtensionId::Tablefunc => true, ExtensionId::Tcn => true, @@ -518,6 +638,7 @@ pub(super) const fn dependencies(extension: Extension) -> &'static [Extension] { match extension.id { ExtensionId::Amcheck => &[], ExtensionId::AutoExplain => &[], + ExtensionId::Autoinc => &[], ExtensionId::Bloom => &[], ExtensionId::BtreeGin => &[], ExtensionId::BtreeGist => &[], @@ -529,15 +650,22 @@ pub(super) const fn dependencies(extension: Extension) -> &'static [Extension] { ExtensionId::FileFdw => &[], ExtensionId::Fuzzystrmatch => &[], ExtensionId::Hstore => &[], + ExtensionId::InsertUsername => &[], ExtensionId::Intarray => &[], ExtensionId::Isn => &[], ExtensionId::Lo => &[], ExtensionId::Ltree => &[], + ExtensionId::Moddatetime => &[], ExtensionId::Pageinspect => &[], + ExtensionId::Passwordcheck => &[], ExtensionId::PgBuffercache => &[], ExtensionId::PgFreespacemap => &[], ExtensionId::PgHashids => &[], ExtensionId::PgIvm => &[], + ExtensionId::PgLogicalinspect => &[], + ExtensionId::PgOverexplain => &[], + ExtensionId::PgPartman => &[], + ExtensionId::PgStatStatements => &[], ExtensionId::PgSurgery => &[], ExtensionId::PgTextsearch => &[], ExtensionId::PgTrgm => &[], @@ -545,8 +673,10 @@ pub(super) const fn dependencies(extension: Extension) -> &'static [Extension] { ExtensionId::PgVisibility => &[], ExtensionId::PgWalinspect => &[], ExtensionId::Pgcrypto => &[], + ExtensionId::Pgmq => &[], ExtensionId::Pgtap => &[], ExtensionId::Postgis => &[], + ExtensionId::Refint => &[], ExtensionId::Seg => &[], ExtensionId::Tablefunc => &[], ExtensionId::Tcn => &[], @@ -563,6 +693,7 @@ pub(super) const fn required_shared_preload_library(extension: Extension) -> Opt match extension.id { ExtensionId::Amcheck => None, ExtensionId::AutoExplain => None, + ExtensionId::Autoinc => None, ExtensionId::Bloom => None, ExtensionId::BtreeGin => None, ExtensionId::BtreeGist => None, @@ -574,15 +705,22 @@ pub(super) const fn required_shared_preload_library(extension: Extension) -> Opt ExtensionId::FileFdw => None, ExtensionId::Fuzzystrmatch => None, ExtensionId::Hstore => None, + ExtensionId::InsertUsername => None, ExtensionId::Intarray => None, ExtensionId::Isn => None, ExtensionId::Lo => None, ExtensionId::Ltree => None, + ExtensionId::Moddatetime => None, ExtensionId::Pageinspect => None, + ExtensionId::Passwordcheck => None, ExtensionId::PgBuffercache => None, ExtensionId::PgFreespacemap => None, ExtensionId::PgHashids => None, ExtensionId::PgIvm => None, + ExtensionId::PgLogicalinspect => None, + ExtensionId::PgOverexplain => None, + ExtensionId::PgPartman => None, + ExtensionId::PgStatStatements => Some("pg_stat_statements"), ExtensionId::PgSurgery => None, ExtensionId::PgTextsearch => Some("pg_textsearch"), ExtensionId::PgTrgm => None, @@ -590,8 +728,10 @@ pub(super) const fn required_shared_preload_library(extension: Extension) -> Opt ExtensionId::PgVisibility => None, ExtensionId::PgWalinspect => None, ExtensionId::Pgcrypto => None, + ExtensionId::Pgmq => None, ExtensionId::Pgtap => None, ExtensionId::Postgis => None, + ExtensionId::Refint => None, ExtensionId::Seg => None, ExtensionId::Tablefunc => None, ExtensionId::Tcn => None, @@ -608,6 +748,7 @@ pub(super) const fn extension_data_files(extension: Extension) -> &'static [&'st match extension.id { ExtensionId::Amcheck => &[], ExtensionId::AutoExplain => &[], + ExtensionId::Autoinc => &[], ExtensionId::Bloom => &[], ExtensionId::BtreeGin => &[], ExtensionId::BtreeGist => &[], @@ -619,15 +760,22 @@ pub(super) const fn extension_data_files(extension: Extension) -> &'static [&'st ExtensionId::FileFdw => &[], ExtensionId::Fuzzystrmatch => &[], ExtensionId::Hstore => &[], + ExtensionId::InsertUsername => &[], ExtensionId::Intarray => &[], ExtensionId::Isn => &[], ExtensionId::Lo => &[], ExtensionId::Ltree => &[], + ExtensionId::Moddatetime => &[], ExtensionId::Pageinspect => &[], + ExtensionId::Passwordcheck => &[], ExtensionId::PgBuffercache => &[], ExtensionId::PgFreespacemap => &[], ExtensionId::PgHashids => &[], ExtensionId::PgIvm => &[], + ExtensionId::PgLogicalinspect => &[], + ExtensionId::PgOverexplain => &[], + ExtensionId::PgPartman => &[], + ExtensionId::PgStatStatements => &[], ExtensionId::PgSurgery => &[], ExtensionId::PgTextsearch => &[], ExtensionId::PgTrgm => &[], @@ -635,6 +783,7 @@ pub(super) const fn extension_data_files(extension: Extension) -> &'static [&'st ExtensionId::PgVisibility => &[], ExtensionId::PgWalinspect => &[], ExtensionId::Pgcrypto => &[], + ExtensionId::Pgmq => &[], ExtensionId::Pgtap => &[], ExtensionId::Postgis => &[ "contrib/postgis-3.6/legacy.sql", @@ -647,6 +796,7 @@ pub(super) const fn extension_data_files(extension: Extension) -> &'static [&'st "contrib/postgis-3.6/uninstall_postgis.sql", "proj/proj.db", ], + ExtensionId::Refint => &[], ExtensionId::Seg => &[], ExtensionId::Tablefunc => &[], ExtensionId::Tcn => &[], @@ -663,6 +813,7 @@ pub(super) const fn extension_sql_file_prefixes(extension: Extension) -> &'stati match extension.id { ExtensionId::Amcheck => &[], ExtensionId::AutoExplain => &[], + ExtensionId::Autoinc => &[], ExtensionId::Bloom => &[], ExtensionId::BtreeGin => &[], ExtensionId::BtreeGist => &[], @@ -674,15 +825,22 @@ pub(super) const fn extension_sql_file_prefixes(extension: Extension) -> &'stati ExtensionId::FileFdw => &[], ExtensionId::Fuzzystrmatch => &[], ExtensionId::Hstore => &[], + ExtensionId::InsertUsername => &[], ExtensionId::Intarray => &[], ExtensionId::Isn => &[], ExtensionId::Lo => &[], ExtensionId::Ltree => &[], + ExtensionId::Moddatetime => &[], ExtensionId::Pageinspect => &[], + ExtensionId::Passwordcheck => &[], ExtensionId::PgBuffercache => &[], ExtensionId::PgFreespacemap => &[], ExtensionId::PgHashids => &[], ExtensionId::PgIvm => &[], + ExtensionId::PgLogicalinspect => &[], + ExtensionId::PgOverexplain => &[], + ExtensionId::PgPartman => &[], + ExtensionId::PgStatStatements => &[], ExtensionId::PgSurgery => &[], ExtensionId::PgTextsearch => &[], ExtensionId::PgTrgm => &[], @@ -690,12 +848,14 @@ pub(super) const fn extension_sql_file_prefixes(extension: Extension) -> &'stati ExtensionId::PgVisibility => &[], ExtensionId::PgWalinspect => &[], ExtensionId::Pgcrypto => &[], + ExtensionId::Pgmq => &[], ExtensionId::Pgtap => &["pgtap-core", "pgtap-schema"], ExtensionId::Postgis => &[ "postgis_comments", "postgis_proc_set_search_path", "rtpostgis", ], + ExtensionId::Refint => &[], ExtensionId::Seg => &[], ExtensionId::Tablefunc => &[], ExtensionId::Tcn => &[], @@ -712,6 +872,7 @@ pub(super) const fn extension_sql_file_names(extension: Extension) -> &'static [ match extension.id { ExtensionId::Amcheck => &[], ExtensionId::AutoExplain => &[], + ExtensionId::Autoinc => &[], ExtensionId::Bloom => &[], ExtensionId::BtreeGin => &[], ExtensionId::BtreeGist => &[], @@ -723,15 +884,22 @@ pub(super) const fn extension_sql_file_names(extension: Extension) -> &'static [ ExtensionId::FileFdw => &[], ExtensionId::Fuzzystrmatch => &[], ExtensionId::Hstore => &[], + ExtensionId::InsertUsername => &[], ExtensionId::Intarray => &[], ExtensionId::Isn => &[], ExtensionId::Lo => &[], ExtensionId::Ltree => &[], + ExtensionId::Moddatetime => &[], ExtensionId::Pageinspect => &[], + ExtensionId::Passwordcheck => &[], ExtensionId::PgBuffercache => &[], ExtensionId::PgFreespacemap => &[], ExtensionId::PgHashids => &[], ExtensionId::PgIvm => &[], + ExtensionId::PgLogicalinspect => &[], + ExtensionId::PgOverexplain => &[], + ExtensionId::PgPartman => &[], + ExtensionId::PgStatStatements => &[], ExtensionId::PgSurgery => &[], ExtensionId::PgTextsearch => &[], ExtensionId::PgTrgm => &[], @@ -739,8 +907,10 @@ pub(super) const fn extension_sql_file_names(extension: Extension) -> &'static [ ExtensionId::PgVisibility => &[], ExtensionId::PgWalinspect => &[], ExtensionId::Pgcrypto => &[], + ExtensionId::Pgmq => &[], ExtensionId::Pgtap => &["uninstall_pgtap.sql"], ExtensionId::Postgis => &["uninstall_postgis.sql"], + ExtensionId::Refint => &[], ExtensionId::Seg => &[], ExtensionId::Tablefunc => &[], ExtensionId::Tcn => &[], @@ -759,6 +929,7 @@ pub(super) const fn runtime_environment( match extension.id { ExtensionId::Amcheck => &[], ExtensionId::AutoExplain => &[], + ExtensionId::Autoinc => &[], ExtensionId::Bloom => &[], ExtensionId::BtreeGin => &[], ExtensionId::BtreeGist => &[], @@ -770,15 +941,22 @@ pub(super) const fn runtime_environment( ExtensionId::FileFdw => &[], ExtensionId::Fuzzystrmatch => &[], ExtensionId::Hstore => &[], + ExtensionId::InsertUsername => &[], ExtensionId::Intarray => &[], ExtensionId::Isn => &[], ExtensionId::Lo => &[], ExtensionId::Ltree => &[], + ExtensionId::Moddatetime => &[], ExtensionId::Pageinspect => &[], + ExtensionId::Passwordcheck => &[], ExtensionId::PgBuffercache => &[], ExtensionId::PgFreespacemap => &[], ExtensionId::PgHashids => &[], ExtensionId::PgIvm => &[], + ExtensionId::PgLogicalinspect => &[], + ExtensionId::PgOverexplain => &[], + ExtensionId::PgPartman => &[], + ExtensionId::PgStatStatements => &[], ExtensionId::PgSurgery => &[], ExtensionId::PgTextsearch => &[], ExtensionId::PgTrgm => &[], @@ -786,12 +964,14 @@ pub(super) const fn runtime_environment( ExtensionId::PgVisibility => &[], ExtensionId::PgWalinspect => &[], ExtensionId::Pgcrypto => &[], + ExtensionId::Pgmq => &[], ExtensionId::Pgtap => &[], ExtensionId::Postgis => &[ExtensionRuntimeEnvironment { name: "PROJ_DATA", relative_path: "share/postgresql/proj", required_file: "proj.db", }], + ExtensionId::Refint => &[], ExtensionId::Seg => &[], ExtensionId::Tablefunc => &[], ExtensionId::Tcn => &[], diff --git a/src/native/sdks/kotlin/oliphaunt-android-gradle-plugin/src/main/resources/dev/oliphaunt/android/extension-legal-catalog.json b/src/native/sdks/kotlin/oliphaunt-android-gradle-plugin/src/main/resources/dev/oliphaunt/android/extension-legal-catalog.json index 9bd0307d2..27fb8778c 100644 --- a/src/native/sdks/kotlin/oliphaunt-android-gradle-plugin/src/main/resources/dev/oliphaunt/android/extension-legal-catalog.json +++ b/src/native/sdks/kotlin/oliphaunt-android-gradle-plugin/src/main/resources/dev/oliphaunt/android/extension-legal-catalog.json @@ -1,6 +1,6 @@ { "schema": "oliphaunt-android-extension-legal-catalog-v1", - "sourceCatalogSha256": "c1d2e09905d7ecc0172173b34b9e4104dad58987503dd3dab7af4ae78890d9f3", + "sourceCatalogSha256": "2f9c13406ab3ce4f8f4f9fb419aeb8ad899e5bde59228215024933dad44c46fe", "contracts": [ { "scope": "aggregate", @@ -155,7 +155,7 @@ { "path": "share/licenses/pg_ivm/LICENSE", "bytes": 1015, - "sha256": "22e995337ca75d05f5057e741e063acb802ff10cb8a13dc822bae749d9df59f4", + "sha256": "f395253af7c50689bdfcd7df4ea247dc2fc39fa0627100699f006639df406d2b", "mode": "0644" } ] @@ -185,7 +185,67 @@ { "path": "share/licenses/pg_ivm/LICENSE", "bytes": 1015, - "sha256": "22e995337ca75d05f5057e741e063acb802ff10cb8a13dc822bae749d9df59f4", + "sha256": "f395253af7c50689bdfcd7df4ea247dc2fc39fa0627100699f006639df406d2b", + "mode": "0644" + } + ] + }, + { + "scope": "aggregate", + "identity": "oliphaunt-extension-pg-partman", + "product": "oliphaunt-extension-pg-partman", + "target": "android-arm64-v8a", + "profile": "external-native", + "licenseFiles": [ + "share/licenses/pg_partman/LICENSE.txt" + ], + "members": [ + { + "path": "LICENSE", + "bytes": 1085, + "sha256": "6f8300e2f43c5a012d6f914fe5affa9090b97b0be39ddf3846f01b905edd8c10", + "mode": "0644" + }, + { + "path": "THIRD_PARTY_NOTICES.md", + "bytes": 821, + "sha256": "20fd67487d1a631ba959cf7ec3fdbaf4977997ed624c0188dcb3c8870eded830", + "mode": "0644" + }, + { + "path": "share/licenses/pg_partman/LICENSE.txt", + "bytes": 1201, + "sha256": "657cd7bde17fc758e47824280a7ccb9bc7d44067e3f3790c2ef4b07e8a04223a", + "mode": "0644" + } + ] + }, + { + "scope": "aggregate", + "identity": "oliphaunt-extension-pg-partman", + "product": "oliphaunt-extension-pg-partman", + "target": "android-x86_64", + "profile": "external-native", + "licenseFiles": [ + "share/licenses/pg_partman/LICENSE.txt" + ], + "members": [ + { + "path": "LICENSE", + "bytes": 1085, + "sha256": "6f8300e2f43c5a012d6f914fe5affa9090b97b0be39ddf3846f01b905edd8c10", + "mode": "0644" + }, + { + "path": "THIRD_PARTY_NOTICES.md", + "bytes": 821, + "sha256": "20fd67487d1a631ba959cf7ec3fdbaf4977997ed624c0188dcb3c8870eded830", + "mode": "0644" + }, + { + "path": "share/licenses/pg_partman/LICENSE.txt", + "bytes": 1201, + "sha256": "657cd7bde17fc758e47824280a7ccb9bc7d44067e3f3790c2ef4b07e8a04223a", "mode": "0644" } ] @@ -324,6 +384,66 @@ } ] }, + { + "scope": "aggregate", + "identity": "oliphaunt-extension-pgmq", + "product": "oliphaunt-extension-pgmq", + "target": "android-arm64-v8a", + "profile": "external-native", + "licenseFiles": [ + "share/licenses/pgmq/LICENSE" + ], + "members": [ + { + "path": "LICENSE", + "bytes": 1085, + "sha256": "6f8300e2f43c5a012d6f914fe5affa9090b97b0be39ddf3846f01b905edd8c10", + "mode": "0644" + }, + { + "path": "THIRD_PARTY_NOTICES.md", + "bytes": 821, + "sha256": "20fd67487d1a631ba959cf7ec3fdbaf4977997ed624c0188dcb3c8870eded830", + "mode": "0644" + }, + { + "path": "share/licenses/pgmq/LICENSE", + "bytes": 917, + "sha256": "a3ce61e0031bdcad1024b1bf50ded2359602160f00e0cac8e509752273df6179", + "mode": "0644" + } + ] + }, + { + "scope": "aggregate", + "identity": "oliphaunt-extension-pgmq", + "product": "oliphaunt-extension-pgmq", + "target": "android-x86_64", + "profile": "external-native", + "licenseFiles": [ + "share/licenses/pgmq/LICENSE" + ], + "members": [ + { + "path": "LICENSE", + "bytes": 1085, + "sha256": "6f8300e2f43c5a012d6f914fe5affa9090b97b0be39ddf3846f01b905edd8c10", + "mode": "0644" + }, + { + "path": "THIRD_PARTY_NOTICES.md", + "bytes": 821, + "sha256": "20fd67487d1a631ba959cf7ec3fdbaf4977997ed624c0188dcb3c8870eded830", + "mode": "0644" + }, + { + "path": "share/licenses/pgmq/LICENSE", + "bytes": 917, + "sha256": "a3ce61e0031bdcad1024b1bf50ded2359602160f00e0cac8e509752273df6179", + "mode": "0644" + } + ] + }, { "scope": "aggregate", "identity": "oliphaunt-extension-pgtap", @@ -828,7 +948,7 @@ }, { "scope": "leaf", - "identity": "bloom", + "identity": "autoinc", "product": "oliphaunt-extension-contrib-pg18", "target": "android-arm64-v8a", "profile": "contrib-native", @@ -856,7 +976,7 @@ }, { "scope": "leaf", - "identity": "bloom", + "identity": "autoinc", "product": "oliphaunt-extension-contrib-pg18", "target": "android-x86_64", "profile": "contrib-native", @@ -884,7 +1004,7 @@ }, { "scope": "leaf", - "identity": "btree_gin", + "identity": "bloom", "product": "oliphaunt-extension-contrib-pg18", "target": "android-arm64-v8a", "profile": "contrib-native", @@ -912,7 +1032,7 @@ }, { "scope": "leaf", - "identity": "btree_gin", + "identity": "bloom", "product": "oliphaunt-extension-contrib-pg18", "target": "android-x86_64", "profile": "contrib-native", @@ -940,7 +1060,7 @@ }, { "scope": "leaf", - "identity": "btree_gist", + "identity": "btree_gin", "product": "oliphaunt-extension-contrib-pg18", "target": "android-arm64-v8a", "profile": "contrib-native", @@ -968,7 +1088,7 @@ }, { "scope": "leaf", - "identity": "btree_gist", + "identity": "btree_gin", "product": "oliphaunt-extension-contrib-pg18", "target": "android-x86_64", "profile": "contrib-native", @@ -996,7 +1116,7 @@ }, { "scope": "leaf", - "identity": "citext", + "identity": "btree_gist", "product": "oliphaunt-extension-contrib-pg18", "target": "android-arm64-v8a", "profile": "contrib-native", @@ -1024,7 +1144,7 @@ }, { "scope": "leaf", - "identity": "citext", + "identity": "btree_gist", "product": "oliphaunt-extension-contrib-pg18", "target": "android-x86_64", "profile": "contrib-native", @@ -1052,7 +1172,7 @@ }, { "scope": "leaf", - "identity": "cube", + "identity": "citext", "product": "oliphaunt-extension-contrib-pg18", "target": "android-arm64-v8a", "profile": "contrib-native", @@ -1080,7 +1200,7 @@ }, { "scope": "leaf", - "identity": "cube", + "identity": "citext", "product": "oliphaunt-extension-contrib-pg18", "target": "android-x86_64", "profile": "contrib-native", @@ -1108,7 +1228,7 @@ }, { "scope": "leaf", - "identity": "dict_int", + "identity": "cube", "product": "oliphaunt-extension-contrib-pg18", "target": "android-arm64-v8a", "profile": "contrib-native", @@ -1136,7 +1256,7 @@ }, { "scope": "leaf", - "identity": "dict_int", + "identity": "cube", "product": "oliphaunt-extension-contrib-pg18", "target": "android-x86_64", "profile": "contrib-native", @@ -1164,7 +1284,7 @@ }, { "scope": "leaf", - "identity": "dict_xsyn", + "identity": "dict_int", "product": "oliphaunt-extension-contrib-pg18", "target": "android-arm64-v8a", "profile": "contrib-native", @@ -1192,7 +1312,7 @@ }, { "scope": "leaf", - "identity": "dict_xsyn", + "identity": "dict_int", "product": "oliphaunt-extension-contrib-pg18", "target": "android-x86_64", "profile": "contrib-native", @@ -1220,7 +1340,7 @@ }, { "scope": "leaf", - "identity": "earthdistance", + "identity": "dict_xsyn", "product": "oliphaunt-extension-contrib-pg18", "target": "android-arm64-v8a", "profile": "contrib-native", @@ -1248,7 +1368,7 @@ }, { "scope": "leaf", - "identity": "earthdistance", + "identity": "dict_xsyn", "product": "oliphaunt-extension-contrib-pg18", "target": "android-x86_64", "profile": "contrib-native", @@ -1276,7 +1396,7 @@ }, { "scope": "leaf", - "identity": "file_fdw", + "identity": "earthdistance", "product": "oliphaunt-extension-contrib-pg18", "target": "android-arm64-v8a", "profile": "contrib-native", @@ -1304,7 +1424,7 @@ }, { "scope": "leaf", - "identity": "file_fdw", + "identity": "earthdistance", "product": "oliphaunt-extension-contrib-pg18", "target": "android-x86_64", "profile": "contrib-native", @@ -1332,7 +1452,7 @@ }, { "scope": "leaf", - "identity": "fuzzystrmatch", + "identity": "file_fdw", "product": "oliphaunt-extension-contrib-pg18", "target": "android-arm64-v8a", "profile": "contrib-native", @@ -1360,7 +1480,7 @@ }, { "scope": "leaf", - "identity": "fuzzystrmatch", + "identity": "file_fdw", "product": "oliphaunt-extension-contrib-pg18", "target": "android-x86_64", "profile": "contrib-native", @@ -1388,7 +1508,7 @@ }, { "scope": "leaf", - "identity": "hstore", + "identity": "fuzzystrmatch", "product": "oliphaunt-extension-contrib-pg18", "target": "android-arm64-v8a", "profile": "contrib-native", @@ -1416,7 +1536,7 @@ }, { "scope": "leaf", - "identity": "hstore", + "identity": "fuzzystrmatch", "product": "oliphaunt-extension-contrib-pg18", "target": "android-x86_64", "profile": "contrib-native", @@ -1444,7 +1564,7 @@ }, { "scope": "leaf", - "identity": "intarray", + "identity": "hstore", "product": "oliphaunt-extension-contrib-pg18", "target": "android-arm64-v8a", "profile": "contrib-native", @@ -1472,7 +1592,7 @@ }, { "scope": "leaf", - "identity": "intarray", + "identity": "hstore", "product": "oliphaunt-extension-contrib-pg18", "target": "android-x86_64", "profile": "contrib-native", @@ -1500,7 +1620,7 @@ }, { "scope": "leaf", - "identity": "isn", + "identity": "insert_username", "product": "oliphaunt-extension-contrib-pg18", "target": "android-arm64-v8a", "profile": "contrib-native", @@ -1528,7 +1648,7 @@ }, { "scope": "leaf", - "identity": "isn", + "identity": "insert_username", "product": "oliphaunt-extension-contrib-pg18", "target": "android-x86_64", "profile": "contrib-native", @@ -1556,7 +1676,7 @@ }, { "scope": "leaf", - "identity": "lo", + "identity": "intarray", "product": "oliphaunt-extension-contrib-pg18", "target": "android-arm64-v8a", "profile": "contrib-native", @@ -1584,7 +1704,7 @@ }, { "scope": "leaf", - "identity": "lo", + "identity": "intarray", "product": "oliphaunt-extension-contrib-pg18", "target": "android-x86_64", "profile": "contrib-native", @@ -1612,7 +1732,7 @@ }, { "scope": "leaf", - "identity": "ltree", + "identity": "isn", "product": "oliphaunt-extension-contrib-pg18", "target": "android-arm64-v8a", "profile": "contrib-native", @@ -1640,7 +1760,7 @@ }, { "scope": "leaf", - "identity": "ltree", + "identity": "isn", "product": "oliphaunt-extension-contrib-pg18", "target": "android-x86_64", "profile": "contrib-native", @@ -1668,7 +1788,7 @@ }, { "scope": "leaf", - "identity": "pageinspect", + "identity": "lo", "product": "oliphaunt-extension-contrib-pg18", "target": "android-arm64-v8a", "profile": "contrib-native", @@ -1696,7 +1816,7 @@ }, { "scope": "leaf", - "identity": "pageinspect", + "identity": "lo", "product": "oliphaunt-extension-contrib-pg18", "target": "android-x86_64", "profile": "contrib-native", @@ -1724,7 +1844,7 @@ }, { "scope": "leaf", - "identity": "pg_buffercache", + "identity": "ltree", "product": "oliphaunt-extension-contrib-pg18", "target": "android-arm64-v8a", "profile": "contrib-native", @@ -1752,7 +1872,7 @@ }, { "scope": "leaf", - "identity": "pg_buffercache", + "identity": "ltree", "product": "oliphaunt-extension-contrib-pg18", "target": "android-x86_64", "profile": "contrib-native", @@ -1780,7 +1900,7 @@ }, { "scope": "leaf", - "identity": "pg_freespacemap", + "identity": "moddatetime", "product": "oliphaunt-extension-contrib-pg18", "target": "android-arm64-v8a", "profile": "contrib-native", @@ -1808,7 +1928,7 @@ }, { "scope": "leaf", - "identity": "pg_freespacemap", + "identity": "moddatetime", "product": "oliphaunt-extension-contrib-pg18", "target": "android-x86_64", "profile": "contrib-native", @@ -1836,13 +1956,11 @@ }, { "scope": "leaf", - "identity": "pg_hashids", - "product": "oliphaunt-extension-pg-hashids", + "identity": "pageinspect", + "product": "oliphaunt-extension-contrib-pg18", "target": "android-arm64-v8a", - "profile": "external-native", - "licenseFiles": [ - "share/licenses/pg_hashids/LICENSE" - ], + "profile": "contrib-native", + "licenseFiles": [], "members": [ { "path": "LICENSE", @@ -1851,28 +1969,26 @@ "mode": "0644" }, { - "path": "THIRD_PARTY_NOTICES.md", - "bytes": 821, - "sha256": "20fd67487d1a631ba959cf7ec3fdbaf4977997ed624c0188dcb3c8870eded830", + "path": "THIRD_PARTY_LICENSES/PostgreSQL-COPYRIGHT", + "bytes": 1198, + "sha256": "3d6af92ff8a4c2cdf69afb1cf44edea727922f5cd0cf8b5f72b11cdecac8fdfd", "mode": "0644" }, { - "path": "files/share/licenses/pg_hashids/LICENSE", - "bytes": 1081, - "sha256": "be1317083fe59a08568b79a5fcf765ac0627f3bd4cff6853bbc949edfd430938", + "path": "THIRD_PARTY_NOTICES.md", + "bytes": 821, + "sha256": "20fd67487d1a631ba959cf7ec3fdbaf4977997ed624c0188dcb3c8870eded830", "mode": "0644" } ] }, { "scope": "leaf", - "identity": "pg_hashids", - "product": "oliphaunt-extension-pg-hashids", + "identity": "pageinspect", + "product": "oliphaunt-extension-contrib-pg18", "target": "android-x86_64", - "profile": "external-native", - "licenseFiles": [ - "share/licenses/pg_hashids/LICENSE" - ], + "profile": "contrib-native", + "licenseFiles": [], "members": [ { "path": "LICENSE", @@ -1881,28 +1997,26 @@ "mode": "0644" }, { - "path": "THIRD_PARTY_NOTICES.md", - "bytes": 821, - "sha256": "20fd67487d1a631ba959cf7ec3fdbaf4977997ed624c0188dcb3c8870eded830", + "path": "THIRD_PARTY_LICENSES/PostgreSQL-COPYRIGHT", + "bytes": 1198, + "sha256": "3d6af92ff8a4c2cdf69afb1cf44edea727922f5cd0cf8b5f72b11cdecac8fdfd", "mode": "0644" }, { - "path": "files/share/licenses/pg_hashids/LICENSE", - "bytes": 1081, - "sha256": "be1317083fe59a08568b79a5fcf765ac0627f3bd4cff6853bbc949edfd430938", + "path": "THIRD_PARTY_NOTICES.md", + "bytes": 821, + "sha256": "20fd67487d1a631ba959cf7ec3fdbaf4977997ed624c0188dcb3c8870eded830", "mode": "0644" } ] }, { "scope": "leaf", - "identity": "pg_ivm", - "product": "oliphaunt-extension-pg-ivm", + "identity": "passwordcheck", + "product": "oliphaunt-extension-contrib-pg18", "target": "android-arm64-v8a", - "profile": "external-native", - "licenseFiles": [ - "share/licenses/pg_ivm/LICENSE" - ], + "profile": "contrib-native", + "licenseFiles": [], "members": [ { "path": "LICENSE", @@ -1911,28 +2025,26 @@ "mode": "0644" }, { - "path": "THIRD_PARTY_NOTICES.md", - "bytes": 821, - "sha256": "20fd67487d1a631ba959cf7ec3fdbaf4977997ed624c0188dcb3c8870eded830", + "path": "THIRD_PARTY_LICENSES/PostgreSQL-COPYRIGHT", + "bytes": 1198, + "sha256": "3d6af92ff8a4c2cdf69afb1cf44edea727922f5cd0cf8b5f72b11cdecac8fdfd", "mode": "0644" }, { - "path": "files/share/licenses/pg_ivm/LICENSE", - "bytes": 1015, - "sha256": "22e995337ca75d05f5057e741e063acb802ff10cb8a13dc822bae749d9df59f4", + "path": "THIRD_PARTY_NOTICES.md", + "bytes": 821, + "sha256": "20fd67487d1a631ba959cf7ec3fdbaf4977997ed624c0188dcb3c8870eded830", "mode": "0644" } ] }, { "scope": "leaf", - "identity": "pg_ivm", - "product": "oliphaunt-extension-pg-ivm", + "identity": "passwordcheck", + "product": "oliphaunt-extension-contrib-pg18", "target": "android-x86_64", - "profile": "external-native", - "licenseFiles": [ - "share/licenses/pg_ivm/LICENSE" - ], + "profile": "contrib-native", + "licenseFiles": [], "members": [ { "path": "LICENSE", @@ -1941,22 +2053,22 @@ "mode": "0644" }, { - "path": "THIRD_PARTY_NOTICES.md", - "bytes": 821, - "sha256": "20fd67487d1a631ba959cf7ec3fdbaf4977997ed624c0188dcb3c8870eded830", + "path": "THIRD_PARTY_LICENSES/PostgreSQL-COPYRIGHT", + "bytes": 1198, + "sha256": "3d6af92ff8a4c2cdf69afb1cf44edea727922f5cd0cf8b5f72b11cdecac8fdfd", "mode": "0644" }, { - "path": "files/share/licenses/pg_ivm/LICENSE", - "bytes": 1015, - "sha256": "22e995337ca75d05f5057e741e063acb802ff10cb8a13dc822bae749d9df59f4", + "path": "THIRD_PARTY_NOTICES.md", + "bytes": 821, + "sha256": "20fd67487d1a631ba959cf7ec3fdbaf4977997ed624c0188dcb3c8870eded830", "mode": "0644" } ] }, { "scope": "leaf", - "identity": "pg_surgery", + "identity": "pg_buffercache", "product": "oliphaunt-extension-contrib-pg18", "target": "android-arm64-v8a", "profile": "contrib-native", @@ -1984,7 +2096,7 @@ }, { "scope": "leaf", - "identity": "pg_surgery", + "identity": "pg_buffercache", "product": "oliphaunt-extension-contrib-pg18", "target": "android-x86_64", "profile": "contrib-native", @@ -2012,11 +2124,471 @@ }, { "scope": "leaf", - "identity": "pg_textsearch", - "product": "oliphaunt-extension-pg-textsearch", + "identity": "pg_freespacemap", + "product": "oliphaunt-extension-contrib-pg18", "target": "android-arm64-v8a", - "profile": "external-native", - "licenseFiles": [ + "profile": "contrib-native", + "licenseFiles": [], + "members": [ + { + "path": "LICENSE", + "bytes": 1085, + "sha256": "6f8300e2f43c5a012d6f914fe5affa9090b97b0be39ddf3846f01b905edd8c10", + "mode": "0644" + }, + { + "path": "THIRD_PARTY_LICENSES/PostgreSQL-COPYRIGHT", + "bytes": 1198, + "sha256": "3d6af92ff8a4c2cdf69afb1cf44edea727922f5cd0cf8b5f72b11cdecac8fdfd", + "mode": "0644" + }, + { + "path": "THIRD_PARTY_NOTICES.md", + "bytes": 821, + "sha256": "20fd67487d1a631ba959cf7ec3fdbaf4977997ed624c0188dcb3c8870eded830", + "mode": "0644" + } + ] + }, + { + "scope": "leaf", + "identity": "pg_freespacemap", + "product": "oliphaunt-extension-contrib-pg18", + "target": "android-x86_64", + "profile": "contrib-native", + "licenseFiles": [], + "members": [ + { + "path": "LICENSE", + "bytes": 1085, + "sha256": "6f8300e2f43c5a012d6f914fe5affa9090b97b0be39ddf3846f01b905edd8c10", + "mode": "0644" + }, + { + "path": "THIRD_PARTY_LICENSES/PostgreSQL-COPYRIGHT", + "bytes": 1198, + "sha256": "3d6af92ff8a4c2cdf69afb1cf44edea727922f5cd0cf8b5f72b11cdecac8fdfd", + "mode": "0644" + }, + { + "path": "THIRD_PARTY_NOTICES.md", + "bytes": 821, + "sha256": "20fd67487d1a631ba959cf7ec3fdbaf4977997ed624c0188dcb3c8870eded830", + "mode": "0644" + } + ] + }, + { + "scope": "leaf", + "identity": "pg_hashids", + "product": "oliphaunt-extension-pg-hashids", + "target": "android-arm64-v8a", + "profile": "external-native", + "licenseFiles": [ + "share/licenses/pg_hashids/LICENSE" + ], + "members": [ + { + "path": "LICENSE", + "bytes": 1085, + "sha256": "6f8300e2f43c5a012d6f914fe5affa9090b97b0be39ddf3846f01b905edd8c10", + "mode": "0644" + }, + { + "path": "THIRD_PARTY_NOTICES.md", + "bytes": 821, + "sha256": "20fd67487d1a631ba959cf7ec3fdbaf4977997ed624c0188dcb3c8870eded830", + "mode": "0644" + }, + { + "path": "files/share/licenses/pg_hashids/LICENSE", + "bytes": 1081, + "sha256": "be1317083fe59a08568b79a5fcf765ac0627f3bd4cff6853bbc949edfd430938", + "mode": "0644" + } + ] + }, + { + "scope": "leaf", + "identity": "pg_hashids", + "product": "oliphaunt-extension-pg-hashids", + "target": "android-x86_64", + "profile": "external-native", + "licenseFiles": [ + "share/licenses/pg_hashids/LICENSE" + ], + "members": [ + { + "path": "LICENSE", + "bytes": 1085, + "sha256": "6f8300e2f43c5a012d6f914fe5affa9090b97b0be39ddf3846f01b905edd8c10", + "mode": "0644" + }, + { + "path": "THIRD_PARTY_NOTICES.md", + "bytes": 821, + "sha256": "20fd67487d1a631ba959cf7ec3fdbaf4977997ed624c0188dcb3c8870eded830", + "mode": "0644" + }, + { + "path": "files/share/licenses/pg_hashids/LICENSE", + "bytes": 1081, + "sha256": "be1317083fe59a08568b79a5fcf765ac0627f3bd4cff6853bbc949edfd430938", + "mode": "0644" + } + ] + }, + { + "scope": "leaf", + "identity": "pg_ivm", + "product": "oliphaunt-extension-pg-ivm", + "target": "android-arm64-v8a", + "profile": "external-native", + "licenseFiles": [ + "share/licenses/pg_ivm/LICENSE" + ], + "members": [ + { + "path": "LICENSE", + "bytes": 1085, + "sha256": "6f8300e2f43c5a012d6f914fe5affa9090b97b0be39ddf3846f01b905edd8c10", + "mode": "0644" + }, + { + "path": "THIRD_PARTY_NOTICES.md", + "bytes": 821, + "sha256": "20fd67487d1a631ba959cf7ec3fdbaf4977997ed624c0188dcb3c8870eded830", + "mode": "0644" + }, + { + "path": "files/share/licenses/pg_ivm/LICENSE", + "bytes": 1015, + "sha256": "f395253af7c50689bdfcd7df4ea247dc2fc39fa0627100699f006639df406d2b", + "mode": "0644" + } + ] + }, + { + "scope": "leaf", + "identity": "pg_ivm", + "product": "oliphaunt-extension-pg-ivm", + "target": "android-x86_64", + "profile": "external-native", + "licenseFiles": [ + "share/licenses/pg_ivm/LICENSE" + ], + "members": [ + { + "path": "LICENSE", + "bytes": 1085, + "sha256": "6f8300e2f43c5a012d6f914fe5affa9090b97b0be39ddf3846f01b905edd8c10", + "mode": "0644" + }, + { + "path": "THIRD_PARTY_NOTICES.md", + "bytes": 821, + "sha256": "20fd67487d1a631ba959cf7ec3fdbaf4977997ed624c0188dcb3c8870eded830", + "mode": "0644" + }, + { + "path": "files/share/licenses/pg_ivm/LICENSE", + "bytes": 1015, + "sha256": "f395253af7c50689bdfcd7df4ea247dc2fc39fa0627100699f006639df406d2b", + "mode": "0644" + } + ] + }, + { + "scope": "leaf", + "identity": "pg_logicalinspect", + "product": "oliphaunt-extension-contrib-pg18", + "target": "android-arm64-v8a", + "profile": "contrib-native", + "licenseFiles": [], + "members": [ + { + "path": "LICENSE", + "bytes": 1085, + "sha256": "6f8300e2f43c5a012d6f914fe5affa9090b97b0be39ddf3846f01b905edd8c10", + "mode": "0644" + }, + { + "path": "THIRD_PARTY_LICENSES/PostgreSQL-COPYRIGHT", + "bytes": 1198, + "sha256": "3d6af92ff8a4c2cdf69afb1cf44edea727922f5cd0cf8b5f72b11cdecac8fdfd", + "mode": "0644" + }, + { + "path": "THIRD_PARTY_NOTICES.md", + "bytes": 821, + "sha256": "20fd67487d1a631ba959cf7ec3fdbaf4977997ed624c0188dcb3c8870eded830", + "mode": "0644" + } + ] + }, + { + "scope": "leaf", + "identity": "pg_logicalinspect", + "product": "oliphaunt-extension-contrib-pg18", + "target": "android-x86_64", + "profile": "contrib-native", + "licenseFiles": [], + "members": [ + { + "path": "LICENSE", + "bytes": 1085, + "sha256": "6f8300e2f43c5a012d6f914fe5affa9090b97b0be39ddf3846f01b905edd8c10", + "mode": "0644" + }, + { + "path": "THIRD_PARTY_LICENSES/PostgreSQL-COPYRIGHT", + "bytes": 1198, + "sha256": "3d6af92ff8a4c2cdf69afb1cf44edea727922f5cd0cf8b5f72b11cdecac8fdfd", + "mode": "0644" + }, + { + "path": "THIRD_PARTY_NOTICES.md", + "bytes": 821, + "sha256": "20fd67487d1a631ba959cf7ec3fdbaf4977997ed624c0188dcb3c8870eded830", + "mode": "0644" + } + ] + }, + { + "scope": "leaf", + "identity": "pg_overexplain", + "product": "oliphaunt-extension-contrib-pg18", + "target": "android-arm64-v8a", + "profile": "contrib-native", + "licenseFiles": [], + "members": [ + { + "path": "LICENSE", + "bytes": 1085, + "sha256": "6f8300e2f43c5a012d6f914fe5affa9090b97b0be39ddf3846f01b905edd8c10", + "mode": "0644" + }, + { + "path": "THIRD_PARTY_LICENSES/PostgreSQL-COPYRIGHT", + "bytes": 1198, + "sha256": "3d6af92ff8a4c2cdf69afb1cf44edea727922f5cd0cf8b5f72b11cdecac8fdfd", + "mode": "0644" + }, + { + "path": "THIRD_PARTY_NOTICES.md", + "bytes": 821, + "sha256": "20fd67487d1a631ba959cf7ec3fdbaf4977997ed624c0188dcb3c8870eded830", + "mode": "0644" + } + ] + }, + { + "scope": "leaf", + "identity": "pg_overexplain", + "product": "oliphaunt-extension-contrib-pg18", + "target": "android-x86_64", + "profile": "contrib-native", + "licenseFiles": [], + "members": [ + { + "path": "LICENSE", + "bytes": 1085, + "sha256": "6f8300e2f43c5a012d6f914fe5affa9090b97b0be39ddf3846f01b905edd8c10", + "mode": "0644" + }, + { + "path": "THIRD_PARTY_LICENSES/PostgreSQL-COPYRIGHT", + "bytes": 1198, + "sha256": "3d6af92ff8a4c2cdf69afb1cf44edea727922f5cd0cf8b5f72b11cdecac8fdfd", + "mode": "0644" + }, + { + "path": "THIRD_PARTY_NOTICES.md", + "bytes": 821, + "sha256": "20fd67487d1a631ba959cf7ec3fdbaf4977997ed624c0188dcb3c8870eded830", + "mode": "0644" + } + ] + }, + { + "scope": "leaf", + "identity": "pg_partman", + "product": "oliphaunt-extension-pg-partman", + "target": "android-arm64-v8a", + "profile": "external-native", + "licenseFiles": [ + "share/licenses/pg_partman/LICENSE.txt" + ], + "members": [ + { + "path": "LICENSE", + "bytes": 1085, + "sha256": "6f8300e2f43c5a012d6f914fe5affa9090b97b0be39ddf3846f01b905edd8c10", + "mode": "0644" + }, + { + "path": "THIRD_PARTY_NOTICES.md", + "bytes": 821, + "sha256": "20fd67487d1a631ba959cf7ec3fdbaf4977997ed624c0188dcb3c8870eded830", + "mode": "0644" + }, + { + "path": "files/share/licenses/pg_partman/LICENSE.txt", + "bytes": 1201, + "sha256": "657cd7bde17fc758e47824280a7ccb9bc7d44067e3f3790c2ef4b07e8a04223a", + "mode": "0644" + } + ] + }, + { + "scope": "leaf", + "identity": "pg_partman", + "product": "oliphaunt-extension-pg-partman", + "target": "android-x86_64", + "profile": "external-native", + "licenseFiles": [ + "share/licenses/pg_partman/LICENSE.txt" + ], + "members": [ + { + "path": "LICENSE", + "bytes": 1085, + "sha256": "6f8300e2f43c5a012d6f914fe5affa9090b97b0be39ddf3846f01b905edd8c10", + "mode": "0644" + }, + { + "path": "THIRD_PARTY_NOTICES.md", + "bytes": 821, + "sha256": "20fd67487d1a631ba959cf7ec3fdbaf4977997ed624c0188dcb3c8870eded830", + "mode": "0644" + }, + { + "path": "files/share/licenses/pg_partman/LICENSE.txt", + "bytes": 1201, + "sha256": "657cd7bde17fc758e47824280a7ccb9bc7d44067e3f3790c2ef4b07e8a04223a", + "mode": "0644" + } + ] + }, + { + "scope": "leaf", + "identity": "pg_stat_statements", + "product": "oliphaunt-extension-contrib-pg18", + "target": "android-arm64-v8a", + "profile": "contrib-native", + "licenseFiles": [], + "members": [ + { + "path": "LICENSE", + "bytes": 1085, + "sha256": "6f8300e2f43c5a012d6f914fe5affa9090b97b0be39ddf3846f01b905edd8c10", + "mode": "0644" + }, + { + "path": "THIRD_PARTY_LICENSES/PostgreSQL-COPYRIGHT", + "bytes": 1198, + "sha256": "3d6af92ff8a4c2cdf69afb1cf44edea727922f5cd0cf8b5f72b11cdecac8fdfd", + "mode": "0644" + }, + { + "path": "THIRD_PARTY_NOTICES.md", + "bytes": 821, + "sha256": "20fd67487d1a631ba959cf7ec3fdbaf4977997ed624c0188dcb3c8870eded830", + "mode": "0644" + } + ] + }, + { + "scope": "leaf", + "identity": "pg_stat_statements", + "product": "oliphaunt-extension-contrib-pg18", + "target": "android-x86_64", + "profile": "contrib-native", + "licenseFiles": [], + "members": [ + { + "path": "LICENSE", + "bytes": 1085, + "sha256": "6f8300e2f43c5a012d6f914fe5affa9090b97b0be39ddf3846f01b905edd8c10", + "mode": "0644" + }, + { + "path": "THIRD_PARTY_LICENSES/PostgreSQL-COPYRIGHT", + "bytes": 1198, + "sha256": "3d6af92ff8a4c2cdf69afb1cf44edea727922f5cd0cf8b5f72b11cdecac8fdfd", + "mode": "0644" + }, + { + "path": "THIRD_PARTY_NOTICES.md", + "bytes": 821, + "sha256": "20fd67487d1a631ba959cf7ec3fdbaf4977997ed624c0188dcb3c8870eded830", + "mode": "0644" + } + ] + }, + { + "scope": "leaf", + "identity": "pg_surgery", + "product": "oliphaunt-extension-contrib-pg18", + "target": "android-arm64-v8a", + "profile": "contrib-native", + "licenseFiles": [], + "members": [ + { + "path": "LICENSE", + "bytes": 1085, + "sha256": "6f8300e2f43c5a012d6f914fe5affa9090b97b0be39ddf3846f01b905edd8c10", + "mode": "0644" + }, + { + "path": "THIRD_PARTY_LICENSES/PostgreSQL-COPYRIGHT", + "bytes": 1198, + "sha256": "3d6af92ff8a4c2cdf69afb1cf44edea727922f5cd0cf8b5f72b11cdecac8fdfd", + "mode": "0644" + }, + { + "path": "THIRD_PARTY_NOTICES.md", + "bytes": 821, + "sha256": "20fd67487d1a631ba959cf7ec3fdbaf4977997ed624c0188dcb3c8870eded830", + "mode": "0644" + } + ] + }, + { + "scope": "leaf", + "identity": "pg_surgery", + "product": "oliphaunt-extension-contrib-pg18", + "target": "android-x86_64", + "profile": "contrib-native", + "licenseFiles": [], + "members": [ + { + "path": "LICENSE", + "bytes": 1085, + "sha256": "6f8300e2f43c5a012d6f914fe5affa9090b97b0be39ddf3846f01b905edd8c10", + "mode": "0644" + }, + { + "path": "THIRD_PARTY_LICENSES/PostgreSQL-COPYRIGHT", + "bytes": 1198, + "sha256": "3d6af92ff8a4c2cdf69afb1cf44edea727922f5cd0cf8b5f72b11cdecac8fdfd", + "mode": "0644" + }, + { + "path": "THIRD_PARTY_NOTICES.md", + "bytes": 821, + "sha256": "20fd67487d1a631ba959cf7ec3fdbaf4977997ed624c0188dcb3c8870eded830", + "mode": "0644" + } + ] + }, + { + "scope": "leaf", + "identity": "pg_textsearch", + "product": "oliphaunt-extension-pg-textsearch", + "target": "android-arm64-v8a", + "profile": "external-native", + "licenseFiles": [ "share/licenses/pg_textsearch/LICENSE", "share/licenses/pg_textsearch/NOTICE" ], @@ -2380,6 +2952,66 @@ } ] }, + { + "scope": "leaf", + "identity": "pgmq", + "product": "oliphaunt-extension-pgmq", + "target": "android-arm64-v8a", + "profile": "external-native", + "licenseFiles": [ + "share/licenses/pgmq/LICENSE" + ], + "members": [ + { + "path": "LICENSE", + "bytes": 1085, + "sha256": "6f8300e2f43c5a012d6f914fe5affa9090b97b0be39ddf3846f01b905edd8c10", + "mode": "0644" + }, + { + "path": "THIRD_PARTY_NOTICES.md", + "bytes": 821, + "sha256": "20fd67487d1a631ba959cf7ec3fdbaf4977997ed624c0188dcb3c8870eded830", + "mode": "0644" + }, + { + "path": "files/share/licenses/pgmq/LICENSE", + "bytes": 917, + "sha256": "a3ce61e0031bdcad1024b1bf50ded2359602160f00e0cac8e509752273df6179", + "mode": "0644" + } + ] + }, + { + "scope": "leaf", + "identity": "pgmq", + "product": "oliphaunt-extension-pgmq", + "target": "android-x86_64", + "profile": "external-native", + "licenseFiles": [ + "share/licenses/pgmq/LICENSE" + ], + "members": [ + { + "path": "LICENSE", + "bytes": 1085, + "sha256": "6f8300e2f43c5a012d6f914fe5affa9090b97b0be39ddf3846f01b905edd8c10", + "mode": "0644" + }, + { + "path": "THIRD_PARTY_NOTICES.md", + "bytes": 821, + "sha256": "20fd67487d1a631ba959cf7ec3fdbaf4977997ed624c0188dcb3c8870eded830", + "mode": "0644" + }, + { + "path": "files/share/licenses/pgmq/LICENSE", + "bytes": 917, + "sha256": "a3ce61e0031bdcad1024b1bf50ded2359602160f00e0cac8e509752273df6179", + "mode": "0644" + } + ] + }, { "scope": "leaf", "identity": "pgtap", @@ -2710,6 +3342,62 @@ } ] }, + { + "scope": "leaf", + "identity": "refint", + "product": "oliphaunt-extension-contrib-pg18", + "target": "android-arm64-v8a", + "profile": "contrib-native", + "licenseFiles": [], + "members": [ + { + "path": "LICENSE", + "bytes": 1085, + "sha256": "6f8300e2f43c5a012d6f914fe5affa9090b97b0be39ddf3846f01b905edd8c10", + "mode": "0644" + }, + { + "path": "THIRD_PARTY_LICENSES/PostgreSQL-COPYRIGHT", + "bytes": 1198, + "sha256": "3d6af92ff8a4c2cdf69afb1cf44edea727922f5cd0cf8b5f72b11cdecac8fdfd", + "mode": "0644" + }, + { + "path": "THIRD_PARTY_NOTICES.md", + "bytes": 821, + "sha256": "20fd67487d1a631ba959cf7ec3fdbaf4977997ed624c0188dcb3c8870eded830", + "mode": "0644" + } + ] + }, + { + "scope": "leaf", + "identity": "refint", + "product": "oliphaunt-extension-contrib-pg18", + "target": "android-x86_64", + "profile": "contrib-native", + "licenseFiles": [], + "members": [ + { + "path": "LICENSE", + "bytes": 1085, + "sha256": "6f8300e2f43c5a012d6f914fe5affa9090b97b0be39ddf3846f01b905edd8c10", + "mode": "0644" + }, + { + "path": "THIRD_PARTY_LICENSES/PostgreSQL-COPYRIGHT", + "bytes": 1198, + "sha256": "3d6af92ff8a4c2cdf69afb1cf44edea727922f5cd0cf8b5f72b11cdecac8fdfd", + "mode": "0644" + }, + { + "path": "THIRD_PARTY_NOTICES.md", + "bytes": 821, + "sha256": "20fd67487d1a631ba959cf7ec3fdbaf4977997ed624c0188dcb3c8870eded830", + "mode": "0644" + } + ] + }, { "scope": "leaf", "identity": "seg", diff --git a/src/native/sdks/kotlin/oliphaunt-android-gradle-plugin/src/main/resources/dev/oliphaunt/android/extensions.properties b/src/native/sdks/kotlin/oliphaunt-android-gradle-plugin/src/main/resources/dev/oliphaunt/android/extensions.properties index e7fcddbbd..cbcb220d0 100644 --- a/src/native/sdks/kotlin/oliphaunt-android-gradle-plugin/src/main/resources/dev/oliphaunt/android/extensions.properties +++ b/src/native/sdks/kotlin/oliphaunt-android-gradle-plugin/src/main/resources/dev/oliphaunt/android/extensions.properties @@ -1,7 +1,7 @@ # This file is generated by src/extensions/tools/check-extension-model.sh. # Do not edit by hand. schema=oliphaunt-android-extension-catalog-v2 -catalogSha256=c1d2e09905d7ecc0172173b34b9e4104dad58987503dd3dab7af4ae78890d9f3 +catalogSha256=2f9c13406ab3ce4f8f4f9fb419aeb8ad899e5bde59228215024933dad44c46fe extension.amcheck.artifactProduct=oliphaunt-extension-contrib-pg18 extension.amcheck.releaseProduct=liboliphaunt-native extension.amcheck.mavenGroup=dev.oliphaunt.extensions @@ -14,6 +14,12 @@ extension.auto_explain.mavenGroup=dev.oliphaunt.extensions extension.auto_explain.mavenArtifact=oliphaunt-extension-contrib-pg18 extension.auto_explain.runtimeBound=true extension.auto_explain.dependencies= +extension.autoinc.artifactProduct=oliphaunt-extension-contrib-pg18 +extension.autoinc.releaseProduct=liboliphaunt-native +extension.autoinc.mavenGroup=dev.oliphaunt.extensions +extension.autoinc.mavenArtifact=oliphaunt-extension-contrib-pg18 +extension.autoinc.runtimeBound=true +extension.autoinc.dependencies= extension.bloom.artifactProduct=oliphaunt-extension-contrib-pg18 extension.bloom.releaseProduct=liboliphaunt-native extension.bloom.mavenGroup=dev.oliphaunt.extensions @@ -80,6 +86,12 @@ extension.hstore.mavenGroup=dev.oliphaunt.extensions extension.hstore.mavenArtifact=oliphaunt-extension-contrib-pg18 extension.hstore.runtimeBound=true extension.hstore.dependencies= +extension.insert_username.artifactProduct=oliphaunt-extension-contrib-pg18 +extension.insert_username.releaseProduct=liboliphaunt-native +extension.insert_username.mavenGroup=dev.oliphaunt.extensions +extension.insert_username.mavenArtifact=oliphaunt-extension-contrib-pg18 +extension.insert_username.runtimeBound=true +extension.insert_username.dependencies= extension.intarray.artifactProduct=oliphaunt-extension-contrib-pg18 extension.intarray.releaseProduct=liboliphaunt-native extension.intarray.mavenGroup=dev.oliphaunt.extensions @@ -104,12 +116,24 @@ extension.ltree.mavenGroup=dev.oliphaunt.extensions extension.ltree.mavenArtifact=oliphaunt-extension-contrib-pg18 extension.ltree.runtimeBound=true extension.ltree.dependencies= +extension.moddatetime.artifactProduct=oliphaunt-extension-contrib-pg18 +extension.moddatetime.releaseProduct=liboliphaunt-native +extension.moddatetime.mavenGroup=dev.oliphaunt.extensions +extension.moddatetime.mavenArtifact=oliphaunt-extension-contrib-pg18 +extension.moddatetime.runtimeBound=true +extension.moddatetime.dependencies= extension.pageinspect.artifactProduct=oliphaunt-extension-contrib-pg18 extension.pageinspect.releaseProduct=liboliphaunt-native extension.pageinspect.mavenGroup=dev.oliphaunt.extensions extension.pageinspect.mavenArtifact=oliphaunt-extension-contrib-pg18 extension.pageinspect.runtimeBound=true extension.pageinspect.dependencies= +extension.passwordcheck.artifactProduct=oliphaunt-extension-contrib-pg18 +extension.passwordcheck.releaseProduct=liboliphaunt-native +extension.passwordcheck.mavenGroup=dev.oliphaunt.extensions +extension.passwordcheck.mavenArtifact=oliphaunt-extension-contrib-pg18 +extension.passwordcheck.runtimeBound=true +extension.passwordcheck.dependencies= extension.pg_buffercache.artifactProduct=oliphaunt-extension-contrib-pg18 extension.pg_buffercache.releaseProduct=liboliphaunt-native extension.pg_buffercache.mavenGroup=dev.oliphaunt.extensions @@ -134,6 +158,30 @@ extension.pg_ivm.mavenGroup=dev.oliphaunt.extensions extension.pg_ivm.mavenArtifact=oliphaunt-extension-pg-ivm extension.pg_ivm.runtimeBound=false extension.pg_ivm.dependencies= +extension.pg_logicalinspect.artifactProduct=oliphaunt-extension-contrib-pg18 +extension.pg_logicalinspect.releaseProduct=liboliphaunt-native +extension.pg_logicalinspect.mavenGroup=dev.oliphaunt.extensions +extension.pg_logicalinspect.mavenArtifact=oliphaunt-extension-contrib-pg18 +extension.pg_logicalinspect.runtimeBound=true +extension.pg_logicalinspect.dependencies= +extension.pg_overexplain.artifactProduct=oliphaunt-extension-contrib-pg18 +extension.pg_overexplain.releaseProduct=liboliphaunt-native +extension.pg_overexplain.mavenGroup=dev.oliphaunt.extensions +extension.pg_overexplain.mavenArtifact=oliphaunt-extension-contrib-pg18 +extension.pg_overexplain.runtimeBound=true +extension.pg_overexplain.dependencies= +extension.pg_partman.artifactProduct=oliphaunt-extension-pg-partman +extension.pg_partman.releaseProduct=oliphaunt-extension-pg-partman +extension.pg_partman.mavenGroup=dev.oliphaunt.extensions +extension.pg_partman.mavenArtifact=oliphaunt-extension-pg-partman +extension.pg_partman.runtimeBound=false +extension.pg_partman.dependencies= +extension.pg_stat_statements.artifactProduct=oliphaunt-extension-contrib-pg18 +extension.pg_stat_statements.releaseProduct=liboliphaunt-native +extension.pg_stat_statements.mavenGroup=dev.oliphaunt.extensions +extension.pg_stat_statements.mavenArtifact=oliphaunt-extension-contrib-pg18 +extension.pg_stat_statements.runtimeBound=true +extension.pg_stat_statements.dependencies= extension.pg_surgery.artifactProduct=oliphaunt-extension-contrib-pg18 extension.pg_surgery.releaseProduct=liboliphaunt-native extension.pg_surgery.mavenGroup=dev.oliphaunt.extensions @@ -176,6 +224,12 @@ extension.pgcrypto.mavenGroup=dev.oliphaunt.extensions extension.pgcrypto.mavenArtifact=oliphaunt-extension-contrib-pg18 extension.pgcrypto.runtimeBound=true extension.pgcrypto.dependencies= +extension.pgmq.artifactProduct=oliphaunt-extension-pgmq +extension.pgmq.releaseProduct=oliphaunt-extension-pgmq +extension.pgmq.mavenGroup=dev.oliphaunt.extensions +extension.pgmq.mavenArtifact=oliphaunt-extension-pgmq +extension.pgmq.runtimeBound=false +extension.pgmq.dependencies= extension.pgtap.artifactProduct=oliphaunt-extension-pgtap extension.pgtap.releaseProduct=oliphaunt-extension-pgtap extension.pgtap.mavenGroup=dev.oliphaunt.extensions @@ -188,6 +242,12 @@ extension.postgis.mavenGroup=dev.oliphaunt.extensions extension.postgis.mavenArtifact=oliphaunt-extension-postgis extension.postgis.runtimeBound=false extension.postgis.dependencies= +extension.refint.artifactProduct=oliphaunt-extension-contrib-pg18 +extension.refint.releaseProduct=liboliphaunt-native +extension.refint.mavenGroup=dev.oliphaunt.extensions +extension.refint.mavenArtifact=oliphaunt-extension-contrib-pg18 +extension.refint.runtimeBound=true +extension.refint.dependencies= extension.seg.artifactProduct=oliphaunt-extension-contrib-pg18 extension.seg.releaseProduct=liboliphaunt-native extension.seg.mavenGroup=dev.oliphaunt.extensions diff --git a/src/native/sdks/kotlin/oliphaunt/src/commonMain/kotlin/dev/oliphaunt/GeneratedExtensions.kt b/src/native/sdks/kotlin/oliphaunt/src/commonMain/kotlin/dev/oliphaunt/GeneratedExtensions.kt index 929af8cae..022d153fd 100644 --- a/src/native/sdks/kotlin/oliphaunt/src/commonMain/kotlin/dev/oliphaunt/GeneratedExtensions.kt +++ b/src/native/sdks/kotlin/oliphaunt/src/commonMain/kotlin/dev/oliphaunt/GeneratedExtensions.kt @@ -11,6 +11,7 @@ internal data class GeneratedExtensionRuntimeContract( internal val generatedExtensionRuntimeContracts: Map = mapOf( "amcheck" to GeneratedExtensionRuntimeContract(createsExtension = true, nativeModuleStem = "amcheck"), "auto_explain" to GeneratedExtensionRuntimeContract(createsExtension = false, nativeModuleStem = "auto_explain"), + "autoinc" to GeneratedExtensionRuntimeContract(createsExtension = true, nativeModuleStem = "autoinc"), "bloom" to GeneratedExtensionRuntimeContract(createsExtension = true, nativeModuleStem = "bloom"), "btree_gin" to GeneratedExtensionRuntimeContract(createsExtension = true, nativeModuleStem = "btree_gin"), "btree_gist" to GeneratedExtensionRuntimeContract(createsExtension = true, nativeModuleStem = "btree_gist"), @@ -22,15 +23,22 @@ internal val generatedExtensionRuntimeContracts: Map [row['sql-name'], row['native-module-stem']]), ); assert.equal(bySqlName.get('intarray'), '_int'); + assert.equal(bySqlName.get('pg_partman'), null); + assert.equal(bySqlName.get('pgmq'), null); assert.equal(bySqlName.get('pgtap'), null); assert.equal(bySqlName.get('postgis'), 'postgis-3'); assert.equal(bySqlName.get('uuid-ossp'), 'uuid-ossp'); const expectedStems = [...bySqlName.values()].filter((stem) => stem !== null).sort(); - assert.equal(expectedStems.length, 38); + assert.equal(expectedStems.length, 46); + assert.deepEqual( + expectedStems, + MOBILE_STATIC_REGISTRY.modules.map((row) => row['native-module-stem']).sort(), + ); const evidence = iosCocoaPodsExtensionLinkEvidence({ expectedStems, inputText: expectedStems diff --git a/src/native/sdks/rust/tests/native_extensions.rs b/src/native/sdks/rust/tests/native_extensions.rs index fba094efc..ba7b622d1 100644 --- a/src/native/sdks/rust/tests/native_extensions.rs +++ b/src/native/sdks/rust/tests/native_extensions.rs @@ -561,7 +561,7 @@ fn assert_repeated_create_extension_error_recovers( mode: TestMode, extension: Extension, ) -> Result<()> { - if extension == Extension::AUTO_EXPLAIN { + if !extension.creates_extension() { return Ok(()); } @@ -596,7 +596,7 @@ fn assert_repeated_create_extension_error_recovers( } fn assert_extension_visible(db: &TestDatabase, mode: TestMode, extension: Extension) -> Result<()> { - if extension != Extension::AUTO_EXPLAIN { + if extension.creates_extension() { let response = block_on(db.exec_protocol_raw(raw_query_message(&format!( "SELECT extname FROM pg_extension WHERE extname = '{}'", extension.sql_name() @@ -616,7 +616,7 @@ fn assert_extension_visible(db: &TestDatabase, mode: TestMode, extension: Extens } fn install_sql(extension: Extension) -> String { - if extension != Extension::AUTO_EXPLAIN { + if extension.creates_extension() { let sql_name = extension.sql_name().replace('"', "\"\""); format!("CREATE EXTENSION \"{sql_name}\" CASCADE") } else { @@ -625,6 +625,21 @@ fn install_sql(extension: Extension) -> String { } } +#[test] +fn native_extension_installation_respects_module_only_contracts() { + for (extension, expected) in [ + (Extension::AUTO_EXPLAIN, "LOAD 'auto_explain'"), + (Extension::PASSWORDCHECK, "LOAD 'passwordcheck'"), + (Extension::PG_OVEREXPLAIN, "LOAD 'pg_overexplain'"), + ( + Extension::PG_STAT_STATEMENTS, + "CREATE EXTENSION \"pg_stat_statements\" CASCADE", + ), + ] { + assert_eq!(install_sql(extension), expected); + } +} + fn run_extension_functional_smoke( db: &TestDatabase, mode: TestMode, diff --git a/src/native/sdks/rust/tests/public_api.rs b/src/native/sdks/rust/tests/public_api.rs index 8a4a5c6a0..edd547674 100644 --- a/src/native/sdks/rust/tests/public_api.rs +++ b/src/native/sdks/rust/tests/public_api.rs @@ -408,7 +408,60 @@ fn extension_catalog_is_exact_and_sorted() { .map(|extension| extension.sql_name()) .collect::>(); assert!(names.windows(2).all(|pair| pair[0] < pair[1])); - assert_eq!(names.len(), 39); + assert_eq!( + names, + [ + "amcheck", + "auto_explain", + "autoinc", + "bloom", + "btree_gin", + "btree_gist", + "citext", + "cube", + "dict_int", + "dict_xsyn", + "earthdistance", + "file_fdw", + "fuzzystrmatch", + "hstore", + "insert_username", + "intarray", + "isn", + "lo", + "ltree", + "moddatetime", + "pageinspect", + "passwordcheck", + "pg_buffercache", + "pg_freespacemap", + "pg_hashids", + "pg_ivm", + "pg_logicalinspect", + "pg_overexplain", + "pg_partman", + "pg_stat_statements", + "pg_surgery", + "pg_textsearch", + "pg_trgm", + "pg_uuidv7", + "pg_visibility", + "pg_walinspect", + "pgcrypto", + "pgmq", + "pgtap", + "postgis", + "refint", + "seg", + "tablefunc", + "tcn", + "tsm_system_rows", + "tsm_system_time", + "unaccent", + "uuid-ossp", + "vector", + ] + ); for extension in Extension::ALL { assert_eq!( Extension::by_sql_name(extension.sql_name()), diff --git a/src/native/sdks/swift/Sources/OliphauntCore/OliphauntExtension.swift b/src/native/sdks/swift/Sources/OliphauntCore/OliphauntExtension.swift index 6179324b9..83fac6f02 100644 --- a/src/native/sdks/swift/Sources/OliphauntCore/OliphauntExtension.swift +++ b/src/native/sdks/swift/Sources/OliphauntCore/OliphauntExtension.swift @@ -35,6 +35,7 @@ public struct OliphauntExtension: Sendable, Equatable { public static let amcheck = OliphauntExtension(sqlName: "amcheck", registration: {}) public static let autoExplain = OliphauntExtension(sqlName: "auto_explain", registration: {}) + public static let autoinc = OliphauntExtension(sqlName: "autoinc", registration: {}) public static let bloom = OliphauntExtension(sqlName: "bloom", registration: {}) public static let btreeGin = OliphauntExtension(sqlName: "btree_gin", registration: {}) public static let btreeGist = OliphauntExtension(sqlName: "btree_gist", registration: {}) @@ -46,15 +47,22 @@ public struct OliphauntExtension: Sendable, Equatable { public static let fileFdw = OliphauntExtension(sqlName: "file_fdw", registration: {}) public static let fuzzystrmatch = OliphauntExtension(sqlName: "fuzzystrmatch", registration: {}) public static let hstore = OliphauntExtension(sqlName: "hstore", registration: {}) + public static let insertUsername = OliphauntExtension(sqlName: "insert_username", registration: {}) public static let intarray = OliphauntExtension(sqlName: "intarray", registration: {}) public static let isn = OliphauntExtension(sqlName: "isn", registration: {}) public static let lo = OliphauntExtension(sqlName: "lo", registration: {}) public static let ltree = OliphauntExtension(sqlName: "ltree", registration: {}) + public static let moddatetime = OliphauntExtension(sqlName: "moddatetime", registration: {}) public static let pageinspect = OliphauntExtension(sqlName: "pageinspect", registration: {}) + public static let passwordcheck = OliphauntExtension(sqlName: "passwordcheck", registration: {}) public static let pgBuffercache = OliphauntExtension(sqlName: "pg_buffercache", registration: {}) public static let pgFreespacemap = OliphauntExtension(sqlName: "pg_freespacemap", registration: {}) public static let pgHashids = OliphauntExtension(sqlName: "pg_hashids", registration: {}) public static let pgIvm = OliphauntExtension(sqlName: "pg_ivm", registration: {}) + public static let pgLogicalinspect = OliphauntExtension(sqlName: "pg_logicalinspect", registration: {}) + public static let pgOverexplain = OliphauntExtension(sqlName: "pg_overexplain", registration: {}) + public static let pgPartman = OliphauntExtension(sqlName: "pg_partman", registration: {}) + public static let pgStatStatements = OliphauntExtension(sqlName: "pg_stat_statements", registration: {}) public static let pgSurgery = OliphauntExtension(sqlName: "pg_surgery", registration: {}) public static let pgTextsearch = OliphauntExtension(sqlName: "pg_textsearch", registration: {}) public static let pgTrgm = OliphauntExtension(sqlName: "pg_trgm", registration: {}) @@ -62,8 +70,10 @@ public struct OliphauntExtension: Sendable, Equatable { public static let pgVisibility = OliphauntExtension(sqlName: "pg_visibility", registration: {}) public static let pgWalinspect = OliphauntExtension(sqlName: "pg_walinspect", registration: {}) public static let pgcrypto = OliphauntExtension(sqlName: "pgcrypto", registration: {}) + public static let pgmq = OliphauntExtension(sqlName: "pgmq", registration: {}) public static let pgtap = OliphauntExtension(sqlName: "pgtap", registration: {}) public static let postgis = OliphauntExtension(sqlName: "postgis", registration: {}) + public static let refint = OliphauntExtension(sqlName: "refint", registration: {}) public static let seg = OliphauntExtension(sqlName: "seg", registration: {}) public static let tablefunc = OliphauntExtension(sqlName: "tablefunc", registration: {}) public static let tcn = OliphauntExtension(sqlName: "tcn", registration: {}) diff --git a/src/native/sdks/ts/src/generated/extensions.ts b/src/native/sdks/ts/src/generated/extensions.ts index c729ea666..eead69ab3 100644 --- a/src/native/sdks/ts/src/generated/extensions.ts +++ b/src/native/sdks/ts/src/generated/extensions.ts @@ -25,7 +25,7 @@ export type GeneratedExtensionMetadata = { readonly sourceKind: string; }; -export const GENERATED_EXTENSION_METADATA_SHA256 = "c1d2e09905d7ecc0172173b34b9e4104dad58987503dd3dab7af4ae78890d9f3" as const; +export const GENERATED_EXTENSION_METADATA_SHA256 = "2f9c13406ab3ce4f8f4f9fb419aeb8ad899e5bde59228215024933dad44c46fe" as const; export const GENERATED_EXTENSION_METADATA = [ { @@ -74,6 +74,29 @@ export const GENERATED_EXTENSION_METADATA = [ "sourceKind": "postgres-contrib", "sqlName": "auto_explain" }, + { + "artifactProduct": "oliphaunt-extension-contrib-pg18", + "cargoPackage": "oliphaunt-extension-contrib-pg18", + "createsExtension": true, + "dataFiles": [], + "dependencies": [], + "displayName": "autoinc", + "extensionSqlFileNames": [], + "extensionSqlFilePrefixes": [], + "id": "autoinc", + "mavenArtifact": "oliphaunt-extension-contrib-pg18", + "mavenGroup": "dev.oliphaunt.extensions", + "nativeModuleStem": "autoinc", + "npmPackage": "@oliphaunt/extension-contrib-pg18", + "postgresMajor": 18, + "releaseProduct": "liboliphaunt-native", + "runtimeBound": true, + "runtimeShareDataFiles": [], + "selectedExtensionDependencies": [], + "sharedPreloadLibraries": [], + "sourceKind": "postgres-contrib", + "sqlName": "autoinc" + }, { "artifactProduct": "oliphaunt-extension-contrib-pg18", "cargoPackage": "oliphaunt-extension-contrib-pg18", @@ -335,6 +358,29 @@ export const GENERATED_EXTENSION_METADATA = [ "sourceKind": "postgres-contrib", "sqlName": "hstore" }, + { + "artifactProduct": "oliphaunt-extension-contrib-pg18", + "cargoPackage": "oliphaunt-extension-contrib-pg18", + "createsExtension": true, + "dataFiles": [], + "dependencies": [], + "displayName": "insert_username", + "extensionSqlFileNames": [], + "extensionSqlFilePrefixes": [], + "id": "insert_username", + "mavenArtifact": "oliphaunt-extension-contrib-pg18", + "mavenGroup": "dev.oliphaunt.extensions", + "nativeModuleStem": "insert_username", + "npmPackage": "@oliphaunt/extension-contrib-pg18", + "postgresMajor": 18, + "releaseProduct": "liboliphaunt-native", + "runtimeBound": true, + "runtimeShareDataFiles": [], + "selectedExtensionDependencies": [], + "sharedPreloadLibraries": [], + "sourceKind": "postgres-contrib", + "sqlName": "insert_username" + }, { "artifactProduct": "oliphaunt-extension-contrib-pg18", "cargoPackage": "oliphaunt-extension-contrib-pg18", @@ -427,6 +473,29 @@ export const GENERATED_EXTENSION_METADATA = [ "sourceKind": "postgres-contrib", "sqlName": "ltree" }, + { + "artifactProduct": "oliphaunt-extension-contrib-pg18", + "cargoPackage": "oliphaunt-extension-contrib-pg18", + "createsExtension": true, + "dataFiles": [], + "dependencies": [], + "displayName": "moddatetime", + "extensionSqlFileNames": [], + "extensionSqlFilePrefixes": [], + "id": "moddatetime", + "mavenArtifact": "oliphaunt-extension-contrib-pg18", + "mavenGroup": "dev.oliphaunt.extensions", + "nativeModuleStem": "moddatetime", + "npmPackage": "@oliphaunt/extension-contrib-pg18", + "postgresMajor": 18, + "releaseProduct": "liboliphaunt-native", + "runtimeBound": true, + "runtimeShareDataFiles": [], + "selectedExtensionDependencies": [], + "sharedPreloadLibraries": [], + "sourceKind": "postgres-contrib", + "sqlName": "moddatetime" + }, { "artifactProduct": "oliphaunt-extension-contrib-pg18", "cargoPackage": "oliphaunt-extension-contrib-pg18", @@ -450,6 +519,29 @@ export const GENERATED_EXTENSION_METADATA = [ "sourceKind": "postgres-contrib", "sqlName": "pageinspect" }, + { + "artifactProduct": "oliphaunt-extension-contrib-pg18", + "cargoPackage": "oliphaunt-extension-contrib-pg18", + "createsExtension": false, + "dataFiles": [], + "dependencies": [], + "displayName": "passwordcheck", + "extensionSqlFileNames": [], + "extensionSqlFilePrefixes": [], + "id": "passwordcheck", + "mavenArtifact": "oliphaunt-extension-contrib-pg18", + "mavenGroup": "dev.oliphaunt.extensions", + "nativeModuleStem": "passwordcheck", + "npmPackage": "@oliphaunt/extension-contrib-pg18", + "postgresMajor": 18, + "releaseProduct": "liboliphaunt-native", + "runtimeBound": true, + "runtimeShareDataFiles": [], + "selectedExtensionDependencies": [], + "sharedPreloadLibraries": [], + "sourceKind": "postgres-contrib", + "sqlName": "passwordcheck" + }, { "artifactProduct": "oliphaunt-extension-contrib-pg18", "cargoPackage": "oliphaunt-extension-contrib-pg18", @@ -542,6 +634,102 @@ export const GENERATED_EXTENSION_METADATA = [ "sourceKind": "oliphaunt-other-extension", "sqlName": "pg_ivm" }, + { + "artifactProduct": "oliphaunt-extension-contrib-pg18", + "cargoPackage": "oliphaunt-extension-contrib-pg18", + "createsExtension": true, + "dataFiles": [], + "dependencies": [], + "displayName": "pg_logicalinspect", + "extensionSqlFileNames": [], + "extensionSqlFilePrefixes": [], + "id": "pg_logicalinspect", + "mavenArtifact": "oliphaunt-extension-contrib-pg18", + "mavenGroup": "dev.oliphaunt.extensions", + "nativeModuleStem": "pg_logicalinspect", + "npmPackage": "@oliphaunt/extension-contrib-pg18", + "postgresMajor": 18, + "releaseProduct": "liboliphaunt-native", + "runtimeBound": true, + "runtimeShareDataFiles": [], + "selectedExtensionDependencies": [], + "sharedPreloadLibraries": [], + "sourceKind": "postgres-contrib", + "sqlName": "pg_logicalinspect" + }, + { + "artifactProduct": "oliphaunt-extension-contrib-pg18", + "cargoPackage": "oliphaunt-extension-contrib-pg18", + "createsExtension": false, + "dataFiles": [], + "dependencies": [], + "displayName": "pg_overexplain", + "extensionSqlFileNames": [], + "extensionSqlFilePrefixes": [], + "id": "pg_overexplain", + "mavenArtifact": "oliphaunt-extension-contrib-pg18", + "mavenGroup": "dev.oliphaunt.extensions", + "nativeModuleStem": "pg_overexplain", + "npmPackage": "@oliphaunt/extension-contrib-pg18", + "postgresMajor": 18, + "releaseProduct": "liboliphaunt-native", + "runtimeBound": true, + "runtimeShareDataFiles": [], + "selectedExtensionDependencies": [], + "sharedPreloadLibraries": [], + "sourceKind": "postgres-contrib", + "sqlName": "pg_overexplain" + }, + { + "artifactProduct": "oliphaunt-extension-pg-partman", + "cargoPackage": "oliphaunt-extension-pg-partman", + "createsExtension": true, + "dataFiles": [], + "dependencies": [ + "plpgsql" + ], + "displayName": "pg_partman", + "extensionSqlFileNames": [], + "extensionSqlFilePrefixes": [], + "id": "pg_partman", + "mavenArtifact": "oliphaunt-extension-pg-partman", + "mavenGroup": "dev.oliphaunt.extensions", + "nativeModuleStem": null, + "npmPackage": "@oliphaunt/extension-pg-partman", + "postgresMajor": 18, + "releaseProduct": "oliphaunt-extension-pg-partman", + "runtimeBound": false, + "runtimeShareDataFiles": [], + "selectedExtensionDependencies": [], + "sharedPreloadLibraries": [], + "sourceKind": "oliphaunt-other-extension", + "sqlName": "pg_partman" + }, + { + "artifactProduct": "oliphaunt-extension-contrib-pg18", + "cargoPackage": "oliphaunt-extension-contrib-pg18", + "createsExtension": true, + "dataFiles": [], + "dependencies": [], + "displayName": "pg_stat_statements", + "extensionSqlFileNames": [], + "extensionSqlFilePrefixes": [], + "id": "pg_stat_statements", + "mavenArtifact": "oliphaunt-extension-contrib-pg18", + "mavenGroup": "dev.oliphaunt.extensions", + "nativeModuleStem": "pg_stat_statements", + "npmPackage": "@oliphaunt/extension-contrib-pg18", + "postgresMajor": 18, + "releaseProduct": "liboliphaunt-native", + "runtimeBound": true, + "runtimeShareDataFiles": [], + "selectedExtensionDependencies": [], + "sharedPreloadLibraries": [ + "pg_stat_statements" + ], + "sourceKind": "postgres-contrib", + "sqlName": "pg_stat_statements" + }, { "artifactProduct": "oliphaunt-extension-contrib-pg18", "cargoPackage": "oliphaunt-extension-contrib-pg18", @@ -705,6 +893,31 @@ export const GENERATED_EXTENSION_METADATA = [ "sourceKind": "postgres-contrib", "sqlName": "pgcrypto" }, + { + "artifactProduct": "oliphaunt-extension-pgmq", + "cargoPackage": "oliphaunt-extension-pgmq", + "createsExtension": true, + "dataFiles": [], + "dependencies": [ + "plpgsql" + ], + "displayName": "PGMQ", + "extensionSqlFileNames": [], + "extensionSqlFilePrefixes": [], + "id": "pgmq", + "mavenArtifact": "oliphaunt-extension-pgmq", + "mavenGroup": "dev.oliphaunt.extensions", + "nativeModuleStem": null, + "npmPackage": "@oliphaunt/extension-pgmq", + "postgresMajor": 18, + "releaseProduct": "oliphaunt-extension-pgmq", + "runtimeBound": false, + "runtimeShareDataFiles": [], + "selectedExtensionDependencies": [], + "sharedPreloadLibraries": [], + "sourceKind": "oliphaunt-other-extension", + "sqlName": "pgmq" + }, { "artifactProduct": "oliphaunt-extension-pgtap", "cargoPackage": "oliphaunt-extension-pgtap", @@ -784,6 +997,29 @@ export const GENERATED_EXTENSION_METADATA = [ "sourceKind": "postgis", "sqlName": "postgis" }, + { + "artifactProduct": "oliphaunt-extension-contrib-pg18", + "cargoPackage": "oliphaunt-extension-contrib-pg18", + "createsExtension": true, + "dataFiles": [], + "dependencies": [], + "displayName": "refint", + "extensionSqlFileNames": [], + "extensionSqlFilePrefixes": [], + "id": "refint", + "mavenArtifact": "oliphaunt-extension-contrib-pg18", + "mavenGroup": "dev.oliphaunt.extensions", + "nativeModuleStem": "refint", + "npmPackage": "@oliphaunt/extension-contrib-pg18", + "postgresMajor": 18, + "releaseProduct": "liboliphaunt-native", + "runtimeBound": true, + "runtimeShareDataFiles": [], + "selectedExtensionDependencies": [], + "sharedPreloadLibraries": [], + "sourceKind": "postgres-contrib", + "sqlName": "refint" + }, { "artifactProduct": "oliphaunt-extension-contrib-pg18", "cargoPackage": "oliphaunt-extension-contrib-pg18", diff --git a/src/test-fixtures/extensions/autoinc.sql b/src/test-fixtures/extensions/autoinc.sql new file mode 100644 index 000000000..0aa522408 --- /dev/null +++ b/src/test-fixtures/extensions/autoinc.sql @@ -0,0 +1,21 @@ +DROP TABLE IF EXISTS oliphaunt_autoinc; +-- oliphaunt-statement +DROP SEQUENCE IF EXISTS oliphaunt_autoinc_sequence; +-- oliphaunt-statement +CREATE SEQUENCE oliphaunt_autoinc_sequence START 11; +-- oliphaunt-statement +CREATE TABLE oliphaunt_autoinc (id integer, value text); +-- oliphaunt-statement +CREATE TRIGGER oliphaunt_autoinc_trigger BEFORE INSERT ON oliphaunt_autoinc +FOR EACH ROW EXECUTE FUNCTION autoinc('id', 'oliphaunt_autoinc_sequence'); +-- oliphaunt-statement +INSERT INTO oliphaunt_autoinc VALUES (NULL, 'generated'), (50, 'preserved'); +-- oliphaunt-statement +-- oliphaunt-verify +DO $oliphaunt$ +BEGIN + IF (SELECT array_agg(id ORDER BY id) FROM oliphaunt_autoinc) IS DISTINCT FROM ARRAY[11, 50] THEN + RAISE EXCEPTION 'autoinc did not generate a missing id and preserve an explicit id'; + END IF; +END +$oliphaunt$; diff --git a/src/test-fixtures/extensions/insert_username.sql b/src/test-fixtures/extensions/insert_username.sql new file mode 100644 index 000000000..d3e57c833 --- /dev/null +++ b/src/test-fixtures/extensions/insert_username.sql @@ -0,0 +1,19 @@ +DROP TABLE IF EXISTS oliphaunt_insert_username; +-- oliphaunt-statement +CREATE TABLE oliphaunt_insert_username (id integer, username text, expected_username text); +-- oliphaunt-statement +CREATE TRIGGER oliphaunt_insert_username_trigger BEFORE INSERT OR UPDATE ON oliphaunt_insert_username +FOR EACH ROW EXECUTE FUNCTION insert_username('username'); +-- oliphaunt-statement +INSERT INTO oliphaunt_insert_username VALUES (1, 'untrusted', current_user); +-- oliphaunt-statement +UPDATE oliphaunt_insert_username SET username = 'still untrusted'; +-- oliphaunt-statement +-- oliphaunt-verify +DO $oliphaunt$ +BEGIN + IF NOT EXISTS (SELECT FROM oliphaunt_insert_username WHERE username = expected_username) THEN + RAISE EXCEPTION 'insert_username did not replace the caller-supplied username'; + END IF; +END +$oliphaunt$; diff --git a/src/test-fixtures/extensions/manifest.json b/src/test-fixtures/extensions/manifest.json index 138c4d127..d0bae547f 100644 --- a/src/test-fixtures/extensions/manifest.json +++ b/src/test-fixtures/extensions/manifest.json @@ -3,6 +3,7 @@ "recipes": { "amcheck": "amcheck.sql", "auto_explain": "auto_explain.sql", + "autoinc": "autoinc.sql", "bloom": "bloom.sql", "btree_gin": "btree_gin.sql", "btree_gist": "btree_gist.sql", @@ -14,15 +15,22 @@ "file_fdw": "file_fdw.sql", "fuzzystrmatch": "fuzzystrmatch.sql", "hstore": "hstore.sql", + "insert_username": "insert_username.sql", "intarray": "intarray.sql", "isn": "isn.sql", "lo": "lo.sql", "ltree": "ltree.sql", + "moddatetime": "moddatetime.sql", "pageinspect": "pageinspect.sql", + "passwordcheck": "passwordcheck.sql", "pg_buffercache": "pg_buffercache.sql", "pg_freespacemap": "pg_freespacemap.sql", "pg_hashids": "pg_hashids.sql", "pg_ivm": "pg_ivm.sql", + "pg_logicalinspect": "pg_logicalinspect.sql", + "pg_overexplain": "pg_overexplain.sql", + "pg_stat_statements": "pg_stat_statements.sql", + "pg_partman": "pg_partman.sql", "pg_surgery": "pg_surgery.sql", "pg_textsearch": "pg_textsearch.sql", "pg_trgm": "pg_trgm.sql", @@ -30,8 +38,10 @@ "pg_visibility": "pg_visibility.sql", "pg_walinspect": "pg_walinspect.sql", "pgcrypto": "pgcrypto.sql", + "pgmq": "pgmq.sql", "pgtap": "pgtap.sql", "postgis": "postgis.sql", + "refint": "refint.sql", "seg": "seg.sql", "tablefunc": "tablefunc.sql", "tcn": "tcn.sql", diff --git a/src/test-fixtures/extensions/moddatetime.sql b/src/test-fixtures/extensions/moddatetime.sql new file mode 100644 index 000000000..04f51873a --- /dev/null +++ b/src/test-fixtures/extensions/moddatetime.sql @@ -0,0 +1,19 @@ +DROP TABLE IF EXISTS oliphaunt_moddatetime; +-- oliphaunt-statement +CREATE TABLE oliphaunt_moddatetime (id integer, modified_at timestamptz); +-- oliphaunt-statement +CREATE TRIGGER oliphaunt_moddatetime_trigger BEFORE UPDATE ON oliphaunt_moddatetime +FOR EACH ROW EXECUTE FUNCTION moddatetime('modified_at'); +-- oliphaunt-statement +INSERT INTO oliphaunt_moddatetime VALUES (1, '2000-01-01 00:00:00+00'); +-- oliphaunt-statement +UPDATE oliphaunt_moddatetime SET id = 2; +-- oliphaunt-statement +-- oliphaunt-verify +DO $oliphaunt$ +BEGIN + IF NOT EXISTS (SELECT FROM oliphaunt_moddatetime WHERE id = 2 AND modified_at > '2000-01-01 00:00:00+00') THEN + RAISE EXCEPTION 'moddatetime did not update the modification timestamp'; + END IF; +END +$oliphaunt$; diff --git a/src/test-fixtures/extensions/passwordcheck.sql b/src/test-fixtures/extensions/passwordcheck.sql new file mode 100644 index 000000000..ab67772c1 --- /dev/null +++ b/src/test-fixtures/extensions/passwordcheck.sql @@ -0,0 +1,20 @@ +-- oliphaunt-verify +LOAD 'passwordcheck'; + +-- oliphaunt-statement +-- oliphaunt-verify +DO $oliphaunt$ +BEGIN + CREATE ROLE oliphaunt_passwordcheck_probe; + BEGIN + ALTER ROLE oliphaunt_passwordcheck_probe PASSWORD 'short'; + RAISE EXCEPTION 'passwordcheck accepted a short password'; + EXCEPTION WHEN invalid_parameter_value THEN + IF SQLERRM <> 'password is too short' THEN + RAISE; + END IF; + END; + ALTER ROLE oliphaunt_passwordcheck_probe PASSWORD 'a_nice_long_password'; + DROP ROLE oliphaunt_passwordcheck_probe; +END +$oliphaunt$; diff --git a/src/test-fixtures/extensions/pg_ivm.sql b/src/test-fixtures/extensions/pg_ivm.sql index 6fa633545..5a7c57879 100644 --- a/src/test-fixtures/extensions/pg_ivm.sql +++ b/src/test-fixtures/extensions/pg_ivm.sql @@ -1,3 +1,5 @@ +DROP TABLE IF EXISTS oliphaunt_ivm_restored; +-- oliphaunt-statement DROP TABLE IF EXISTS oliphaunt_ivm_summary; -- oliphaunt-statement DROP TABLE IF EXISTS oliphaunt_ivm_orders; @@ -8,9 +10,14 @@ INSERT INTO oliphaunt_ivm_orders VALUES (1, 10), (2, 20); -- oliphaunt-statement SELECT pgivm.create_immv('oliphaunt_ivm_summary', $$ SELECT id, amount FROM oliphaunt_ivm_orders $$); -- oliphaunt-statement +-- Recreate metadata for an existing populated relation, as after pg_dump. +CREATE TABLE oliphaunt_ivm_restored AS SELECT id, amount FROM oliphaunt_ivm_orders; +-- oliphaunt-statement +SELECT pgivm.restore_immv('oliphaunt_ivm_restored', $$ SELECT id, amount FROM oliphaunt_ivm_orders $$); +-- oliphaunt-statement -- oliphaunt-verify DO $$ -DECLARE n int; +DECLARE n int; populated boolean; BEGIN SELECT count(*) INTO n FROM oliphaunt_ivm_summary; IF n <> 2 THEN RAISE EXCEPTION 'pg_ivm count failed: %', n; END IF; @@ -18,4 +25,15 @@ BEGIN SELECT amount INTO n FROM oliphaunt_ivm_summary WHERE id = 1; IF n IS DISTINCT FROM 11 THEN RAISE EXCEPTION 'pg_ivm maintenance failed: %', n; END IF; UPDATE oliphaunt_ivm_orders SET amount = 10 WHERE id = 1; + SELECT ispopulated INTO populated FROM pgivm.pg_ivm_immv + WHERE immvrelid = 'oliphaunt_ivm_restored'::regclass; + IF populated IS DISTINCT FROM true THEN + RAISE EXCEPTION 'pg_ivm restored relation lost populated state'; + END IF; + -- Before 1.17 this refresh added duplicate maintenance triggers after restore. + PERFORM pgivm.refresh_immv('oliphaunt_ivm_restored'); + INSERT INTO oliphaunt_ivm_orders VALUES (99, 30); + SELECT count(*) INTO n FROM oliphaunt_ivm_restored WHERE id = 99; + IF n <> 1 THEN RAISE EXCEPTION 'pg_ivm restored maintenance duplicated rows: %', n; END IF; + DELETE FROM oliphaunt_ivm_orders WHERE id = 99; END $$; diff --git a/src/test-fixtures/extensions/pg_logicalinspect.sql b/src/test-fixtures/extensions/pg_logicalinspect.sql new file mode 100644 index 000000000..612e793bd --- /dev/null +++ b/src/test-fixtures/extensions/pg_logicalinspect.sql @@ -0,0 +1,23 @@ +-- Exercise both entry points without requiring a logical replication slot. +-- Invalid snapshot names must be rejected before any filesystem access. +-- oliphaunt-verify +DO $oliphaunt$ +BEGIN + BEGIN + PERFORM pg_get_logical_snapshot_meta('../invalid'); + RAISE EXCEPTION 'pg_logicalinspect accepted an invalid snapshot name'; + EXCEPTION WHEN internal_error THEN + IF SQLERRM <> 'invalid snapshot file name "../invalid"' THEN + RAISE; + END IF; + END; + BEGIN + PERFORM pg_get_logical_snapshot_info('../invalid'); + RAISE EXCEPTION 'pg_logicalinspect accepted an invalid snapshot name'; + EXCEPTION WHEN internal_error THEN + IF SQLERRM <> 'invalid snapshot file name "../invalid"' THEN + RAISE; + END IF; + END; +END +$oliphaunt$; diff --git a/src/test-fixtures/extensions/pg_overexplain.sql b/src/test-fixtures/extensions/pg_overexplain.sql new file mode 100644 index 000000000..a3b17b19b --- /dev/null +++ b/src/test-fixtures/extensions/pg_overexplain.sql @@ -0,0 +1,17 @@ +-- oliphaunt-verify +LOAD 'pg_overexplain'; + +-- oliphaunt-statement +-- oliphaunt-verify +DO $oliphaunt$ +DECLARE + document jsonb; +BEGIN + EXECUTE 'EXPLAIN (DEBUG, RANGE_TABLE, FORMAT JSON, COSTS OFF) SELECT oid FROM pg_class WHERE relname = ''pg_class''' + INTO document; + IF (document->0->'Plan' ? 'Plan Node ID') IS DISTINCT FROM true + OR COALESCE(jsonb_array_length(document->0->'Range Table'), 0) < 1 THEN + RAISE EXCEPTION 'pg_overexplain did not include plan IDs and the range table: %', document; + END IF; +END +$oliphaunt$; diff --git a/src/test-fixtures/extensions/pg_partman.sql b/src/test-fixtures/extensions/pg_partman.sql new file mode 100644 index 000000000..c293ac88a --- /dev/null +++ b/src/test-fixtures/extensions/pg_partman.sql @@ -0,0 +1,44 @@ +SELECT set_config('search_path', quote_ident(n.nspname) || ', public', false) +FROM pg_extension e JOIN pg_namespace n ON n.oid = e.extnamespace +WHERE e.extname = 'pg_partman'; +-- oliphaunt-statement +CREATE TABLE public.oliphaunt_partman_events (id bigint NOT NULL, payload text) +PARTITION BY RANGE (id); +-- oliphaunt-statement +SELECT create_parent('public.oliphaunt_partman_events', 'id', '10', + p_premake := 2, p_start_partition := '0', p_jobmon := false); +-- oliphaunt-statement +INSERT INTO public.oliphaunt_partman_events VALUES (1, 'old'), (25, 'retained'); +-- oliphaunt-statement +SELECT run_maintenance('public.oliphaunt_partman_events', p_jobmon := false); +-- oliphaunt-statement +DO $$ +BEGIN + IF to_regclass('public.oliphaunt_partman_events_p40') IS NULL THEN + RAISE EXCEPTION 'pg_partman did not premake partitions beyond the highest ID'; + END IF; +END $$; +-- oliphaunt-statement +UPDATE part_config SET retention = '10', retention_keep_table = false +WHERE parent_table = 'public.oliphaunt_partman_events'; +-- oliphaunt-statement +SELECT run_maintenance('public.oliphaunt_partman_events', p_jobmon := false); +-- oliphaunt-statement +-- oliphaunt-verify +SELECT set_config('search_path', quote_ident(n.nspname) || ', public', false) +FROM pg_extension e JOIN pg_namespace n ON n.oid = e.extnamespace +WHERE e.extname = 'pg_partman'; +-- oliphaunt-statement +DO $$ +BEGIN + IF to_regclass('public.oliphaunt_partman_events_p0') IS NOT NULL THEN + RAISE EXCEPTION 'pg_partman did not remove the expired ID partition'; + END IF; + IF (SELECT count(*) FROM public.oliphaunt_partman_events) <> 1 + OR NOT EXISTS (SELECT FROM public.oliphaunt_partman_events WHERE id = 25 AND payload = 'retained') THEN + RAISE EXCEPTION 'pg_partman retention removed or changed the retained row'; + END IF; + IF NOT EXISTS (SELECT FROM part_config WHERE parent_table = 'public.oliphaunt_partman_events') THEN + RAISE EXCEPTION 'pg_partman configuration did not survive'; + END IF; +END $$; diff --git a/src/test-fixtures/extensions/pg_stat_statements.sql b/src/test-fixtures/extensions/pg_stat_statements.sql new file mode 100644 index 000000000..b85346d43 --- /dev/null +++ b/src/test-fixtures/extensions/pg_stat_statements.sql @@ -0,0 +1,21 @@ +-- Reset and collect fresh counters on creation, restart, and backup restore. +-- This fails if the library was loaded after shared-memory startup. +-- oliphaunt-verify +SELECT pg_stat_statements_reset(); +-- oliphaunt-statement +-- oliphaunt-verify +SELECT sum(value) FROM generate_series(1, 3) AS oliphaunt_pgss_probe(value); +-- oliphaunt-statement +-- oliphaunt-verify +DO $oliphaunt$ +BEGIN + IF NOT EXISTS ( + SELECT FROM pg_stat_statements + WHERE query LIKE 'SELECT sum(value) FROM generate_series%oliphaunt_pgss_probe%' + AND dbid = (SELECT oid FROM pg_database WHERE datname = current_database()) + AND queryid <> 0 AND calls >= 1 AND rows = calls + ) THEN + RAISE EXCEPTION 'pg_stat_statements did not record a completed query'; + END IF; +END +$oliphaunt$; diff --git a/src/test-fixtures/extensions/pgmq.sql b/src/test-fixtures/extensions/pgmq.sql new file mode 100644 index 000000000..798791a48 --- /dev/null +++ b/src/test-fixtures/extensions/pgmq.sql @@ -0,0 +1,69 @@ +DO $proof$ +BEGIN + IF EXISTS (SELECT FROM pgmq.meta WHERE queue_name = 'oliphaunt_queue') THEN + PERFORM pgmq.drop_queue('oliphaunt_queue'); + END IF; +END +$proof$; +-- oliphaunt-statement +SELECT pgmq.create('oliphaunt_queue'); +-- oliphaunt-statement +SELECT pgmq.send('oliphaunt_queue', '{"payload":"persistent"}'::jsonb); +-- oliphaunt-statement +DO $proof$ +DECLARE + message record; +BEGIN + SELECT * INTO STRICT message FROM pgmq.read('oliphaunt_queue', 30, 1); + IF message.message <> '{"payload":"persistent"}'::jsonb OR message.read_ct <> 1 THEN + RAISE EXCEPTION 'PGMQ read lost payload or delivery count'; + END IF; + IF EXISTS (SELECT FROM pgmq.read('oliphaunt_queue', 30, 1)) THEN + RAISE EXCEPTION 'PGMQ visibility timeout did not hide the leased message'; + END IF; + IF NOT pgmq.archive('oliphaunt_queue', message.msg_id) THEN + RAISE EXCEPTION 'PGMQ archive failed'; + END IF; + IF (SELECT count(*) FROM pgmq.a_oliphaunt_queue) <> 1 THEN + RAISE EXCEPTION 'PGMQ archive lost the message'; + END IF; +END +$proof$; +-- oliphaunt-statement +SELECT pgmq.send('oliphaunt_queue', '{"payload":"delete"}'::jsonb); +-- oliphaunt-statement +DO $proof$ +DECLARE + message record; +BEGIN + SELECT * INTO STRICT message FROM pgmq.pop('oliphaunt_queue'); + IF message.message <> '{"payload":"delete"}'::jsonb THEN + RAISE EXCEPTION 'PGMQ pop returned the wrong message'; + END IF; + IF EXISTS (SELECT FROM pgmq.read('oliphaunt_queue', 30, 1)) THEN + RAISE EXCEPTION 'PGMQ pop did not remove the message'; + END IF; +END +$proof$; +-- oliphaunt-statement +SELECT pgmq.create('oliphaunt_drop_queue'); +-- oliphaunt-statement +SELECT pgmq.drop_queue('oliphaunt_drop_queue'); +-- oliphaunt-statement +SELECT pgmq.send('oliphaunt_queue', '{"payload":"restart-and-restore"}'::jsonb); +-- oliphaunt-statement +-- oliphaunt-verify +DO $proof$ +BEGIN + IF (SELECT count(*) FROM pgmq.q_oliphaunt_queue) <> 1 OR + NOT EXISTS (SELECT FROM pgmq.q_oliphaunt_queue + WHERE message = '{"payload":"restart-and-restore"}'::jsonb) THEN + RAISE EXCEPTION 'PGMQ persistent queue message did not survive'; + END IF; + IF (SELECT count(*) FROM pgmq.a_oliphaunt_queue) <> 1 OR + NOT EXISTS (SELECT FROM pgmq.a_oliphaunt_queue + WHERE message = '{"payload":"persistent"}'::jsonb) THEN + RAISE EXCEPTION 'PGMQ archived message did not survive'; + END IF; +END +$proof$; diff --git a/src/test-fixtures/extensions/refint.sql b/src/test-fixtures/extensions/refint.sql new file mode 100644 index 000000000..b21dc3717 --- /dev/null +++ b/src/test-fixtures/extensions/refint.sql @@ -0,0 +1,39 @@ +DROP TABLE IF EXISTS oliphaunt_refint_child; +-- oliphaunt-statement +DROP TABLE IF EXISTS oliphaunt_refint_parent; +-- oliphaunt-statement +CREATE TABLE oliphaunt_refint_parent (id integer PRIMARY KEY); +-- oliphaunt-statement +CREATE TABLE oliphaunt_refint_child (parent_id integer); +-- oliphaunt-statement +CREATE TRIGGER oliphaunt_refint_parent_trigger AFTER DELETE OR UPDATE ON oliphaunt_refint_parent +FOR EACH ROW EXECUTE FUNCTION check_foreign_key(1, 'cascade', 'id', 'oliphaunt_refint_child', 'parent_id'); +-- oliphaunt-statement +CREATE TRIGGER oliphaunt_refint_child_trigger AFTER INSERT OR UPDATE ON oliphaunt_refint_child +FOR EACH ROW EXECUTE FUNCTION check_primary_key('parent_id', 'oliphaunt_refint_parent', 'id'); +-- oliphaunt-statement +INSERT INTO oliphaunt_refint_parent VALUES (1), (2); +-- oliphaunt-statement +INSERT INTO oliphaunt_refint_child VALUES (1), (2); +-- oliphaunt-statement +DO $oliphaunt$ +BEGIN + BEGIN + INSERT INTO oliphaunt_refint_child VALUES (3); + RAISE EXCEPTION 'refint accepted a missing parent'; + EXCEPTION WHEN triggered_action_exception THEN + NULL; + END; +END +$oliphaunt$; +-- oliphaunt-statement +DELETE FROM oliphaunt_refint_parent WHERE id = 1; +-- oliphaunt-statement +-- oliphaunt-verify +DO $oliphaunt$ +BEGIN + IF (SELECT array_agg(parent_id) FROM oliphaunt_refint_child) IS DISTINCT FROM ARRAY[2] THEN + RAISE EXCEPTION 'refint did not cascade deletion to the referencing row'; + END IF; +END +$oliphaunt$; diff --git a/src/test-fixtures/extensions/vector.sql b/src/test-fixtures/extensions/vector.sql index 8e6f86da0..9fc26f2b7 100644 --- a/src/test-fixtures/extensions/vector.sql +++ b/src/test-fixtures/extensions/vector.sql @@ -4,5 +4,30 @@ CREATE TABLE oliphaunt_vector (id int PRIMARY KEY, embedding vector(3)); -- oliphaunt-statement INSERT INTO oliphaunt_vector VALUES (1, '[1,2,3]'); -- oliphaunt-statement +DROP TABLE IF EXISTS oliphaunt_vector_indexed; +-- oliphaunt-statement +CREATE TABLE oliphaunt_vector_indexed (id int PRIMARY KEY, embedding vector(3)); +-- oliphaunt-statement +INSERT INTO oliphaunt_vector_indexed SELECT i, ARRAY[i, i, i]::vector FROM generate_series(1, 64) i; +-- oliphaunt-statement +CREATE INDEX ON oliphaunt_vector_indexed USING hnsw (embedding vector_l2_ops); +-- oliphaunt-statement +DELETE FROM oliphaunt_vector_indexed WHERE id = 32; +-- oliphaunt-statement +VACUUM oliphaunt_vector_indexed; +-- oliphaunt-statement +INSERT INTO oliphaunt_vector_indexed VALUES (32, '[32,32,32]'); +-- oliphaunt-statement -- oliphaunt-verify DO $$ DECLARE d float8; BEGIN SELECT embedding <-> '[1,2,4]'::vector INTO d FROM oliphaunt_vector WHERE id = 1; IF d IS DISTINCT FROM 1 THEN RAISE EXCEPTION 'vector distance failed: %', d; END IF; END $$; + +-- oliphaunt-statement +DO $$ +DECLARE nearest int; +BEGIN + PERFORM set_config('enable_seqscan', 'off', true); + SELECT id INTO nearest FROM oliphaunt_vector_indexed ORDER BY embedding <-> '[32,32,32]'::vector LIMIT 1; + IF nearest IS DISTINCT FROM 32 THEN + RAISE EXCEPTION 'vector HNSW search after vacuum/insert failed: %', nearest; + END IF; +END $$; diff --git a/src/wasix/node-addon/Cargo.toml b/src/wasix/node-addon/Cargo.toml index f04684fb2..2b1cc6517 100644 --- a/src/wasix/node-addon/Cargo.toml +++ b/src/wasix/node-addon/Cargo.toml @@ -22,6 +22,7 @@ release = [ "tools", "extension-amcheck", "extension-auto-explain", + "extension-autoinc", "extension-bloom", "extension-btree-gin", "extension-btree-gist", @@ -33,18 +34,25 @@ release = [ "extension-file-fdw", "extension-fuzzystrmatch", "extension-hstore", + "extension-insert-username", "extension-intarray", "extension-isn", "extension-lo", "extension-ltree", + "extension-moddatetime", "extension-pageinspect", + "extension-passwordcheck", "extension-pg-buffercache", "extension-pg-freespacemap", + "extension-pg-logicalinspect", + "extension-pg-overexplain", + "extension-pg-stat-statements", "extension-pg-surgery", "extension-pg-trgm", "extension-pg-visibility", "extension-pg-walinspect", "extension-pgcrypto", + "extension-refint", "extension-seg", "extension-tablefunc", "extension-tcn", @@ -55,6 +63,7 @@ release = [ ] extension-amcheck = ["extensions", "oliphaunt-wasix/extension-amcheck"] extension-auto-explain = ["extensions", "oliphaunt-wasix/extension-auto-explain"] +extension-autoinc = ["extensions", "oliphaunt-wasix/extension-autoinc"] extension-bloom = ["extensions", "oliphaunt-wasix/extension-bloom"] extension-btree-gin = ["extensions", "oliphaunt-wasix/extension-btree-gin"] extension-btree-gist = ["extensions", "oliphaunt-wasix/extension-btree-gist"] @@ -66,15 +75,22 @@ extension-earthdistance = ["extensions", "oliphaunt-wasix/extension-earthdistanc extension-file-fdw = ["extensions", "oliphaunt-wasix/extension-file-fdw"] extension-fuzzystrmatch = ["extensions", "oliphaunt-wasix/extension-fuzzystrmatch"] extension-hstore = ["extensions", "oliphaunt-wasix/extension-hstore"] +extension-insert-username = ["extensions", "oliphaunt-wasix/extension-insert-username"] extension-intarray = ["extensions", "oliphaunt-wasix/extension-intarray"] extension-isn = ["extensions", "oliphaunt-wasix/extension-isn"] extension-lo = ["extensions", "oliphaunt-wasix/extension-lo"] extension-ltree = ["extensions", "oliphaunt-wasix/extension-ltree"] +extension-moddatetime = ["extensions", "oliphaunt-wasix/extension-moddatetime"] extension-pageinspect = ["extensions", "oliphaunt-wasix/extension-pageinspect"] +extension-passwordcheck = ["extensions", "oliphaunt-wasix/extension-passwordcheck"] extension-pg-buffercache = ["extensions", "oliphaunt-wasix/extension-pg-buffercache"] extension-pg-freespacemap = ["extensions", "oliphaunt-wasix/extension-pg-freespacemap"] extension-pg-hashids = ["extensions", "oliphaunt-wasix/extension-pg-hashids"] extension-pg-ivm = ["extensions", "oliphaunt-wasix/extension-pg-ivm"] +extension-pg-logicalinspect = ["extensions", "oliphaunt-wasix/extension-pg-logicalinspect"] +extension-pg-overexplain = ["extensions", "oliphaunt-wasix/extension-pg-overexplain"] +extension-pg-partman = ["extensions", "oliphaunt-wasix/extension-pg-partman"] +extension-pg-stat-statements = ["extensions", "oliphaunt-wasix/extension-pg-stat-statements"] extension-pg-surgery = ["extensions", "oliphaunt-wasix/extension-pg-surgery"] extension-pg-textsearch = ["extensions", "oliphaunt-wasix/extension-pg-textsearch"] extension-pg-trgm = ["extensions", "oliphaunt-wasix/extension-pg-trgm"] @@ -82,8 +98,10 @@ extension-pg-uuidv7 = ["extensions", "oliphaunt-wasix/extension-pg-uuidv7"] extension-pg-visibility = ["extensions", "oliphaunt-wasix/extension-pg-visibility"] extension-pg-walinspect = ["extensions", "oliphaunt-wasix/extension-pg-walinspect"] extension-pgcrypto = ["extensions", "oliphaunt-wasix/extension-pgcrypto"] +extension-pgmq = ["extensions", "oliphaunt-wasix/extension-pgmq"] extension-pgtap = ["extensions", "oliphaunt-wasix/extension-pgtap"] extension-postgis = ["extensions", "oliphaunt-wasix/extension-postgis"] +extension-refint = ["extensions", "oliphaunt-wasix/extension-refint"] extension-seg = ["extensions", "oliphaunt-wasix/extension-seg"] extension-tablefunc = ["extensions", "oliphaunt-wasix/extension-tablefunc"] extension-tcn = ["extensions", "oliphaunt-wasix/extension-tcn"] diff --git a/src/wasix/pgwire-server/Cargo.toml b/src/wasix/pgwire-server/Cargo.toml index b2ea8b4b6..40e181ef1 100644 --- a/src/wasix/pgwire-server/Cargo.toml +++ b/src/wasix/pgwire-server/Cargo.toml @@ -18,6 +18,7 @@ icu = ["wasix", "oliphaunt-wasix/icu"] extension-amcheck = ["extensions", "oliphaunt-wasix/extension-amcheck"] extension-auto-explain = ["extensions", "oliphaunt-wasix/extension-auto-explain"] +extension-autoinc = ["extensions", "oliphaunt-wasix/extension-autoinc"] extension-bloom = ["extensions", "oliphaunt-wasix/extension-bloom"] extension-btree-gin = ["extensions", "oliphaunt-wasix/extension-btree-gin"] extension-btree-gist = ["extensions", "oliphaunt-wasix/extension-btree-gist"] @@ -29,15 +30,22 @@ extension-earthdistance = ["extensions", "oliphaunt-wasix/extension-earthdistanc extension-file-fdw = ["extensions", "oliphaunt-wasix/extension-file-fdw"] extension-fuzzystrmatch = ["extensions", "oliphaunt-wasix/extension-fuzzystrmatch"] extension-hstore = ["extensions", "oliphaunt-wasix/extension-hstore"] +extension-insert-username = ["extensions", "oliphaunt-wasix/extension-insert-username"] extension-intarray = ["extensions", "oliphaunt-wasix/extension-intarray"] extension-isn = ["extensions", "oliphaunt-wasix/extension-isn"] extension-lo = ["extensions", "oliphaunt-wasix/extension-lo"] extension-ltree = ["extensions", "oliphaunt-wasix/extension-ltree"] +extension-moddatetime = ["extensions", "oliphaunt-wasix/extension-moddatetime"] extension-pageinspect = ["extensions", "oliphaunt-wasix/extension-pageinspect"] +extension-passwordcheck = ["extensions", "oliphaunt-wasix/extension-passwordcheck"] extension-pg-buffercache = ["extensions", "oliphaunt-wasix/extension-pg-buffercache"] extension-pg-freespacemap = ["extensions", "oliphaunt-wasix/extension-pg-freespacemap"] extension-pg-hashids = ["extensions", "oliphaunt-wasix/extension-pg-hashids"] extension-pg-ivm = ["extensions", "oliphaunt-wasix/extension-pg-ivm"] +extension-pg-logicalinspect = ["extensions", "oliphaunt-wasix/extension-pg-logicalinspect"] +extension-pg-overexplain = ["extensions", "oliphaunt-wasix/extension-pg-overexplain"] +extension-pg-partman = ["extensions", "oliphaunt-wasix/extension-pg-partman"] +extension-pg-stat-statements = ["extensions", "oliphaunt-wasix/extension-pg-stat-statements"] extension-pg-surgery = ["extensions", "oliphaunt-wasix/extension-pg-surgery"] extension-pg-textsearch = ["extensions", "oliphaunt-wasix/extension-pg-textsearch"] extension-pg-trgm = ["extensions", "oliphaunt-wasix/extension-pg-trgm"] @@ -45,8 +53,10 @@ extension-pg-uuidv7 = ["extensions", "oliphaunt-wasix/extension-pg-uuidv7"] extension-pg-visibility = ["extensions", "oliphaunt-wasix/extension-pg-visibility"] extension-pg-walinspect = ["extensions", "oliphaunt-wasix/extension-pg-walinspect"] extension-pgcrypto = ["extensions", "oliphaunt-wasix/extension-pgcrypto"] +extension-pgmq = ["extensions", "oliphaunt-wasix/extension-pgmq"] extension-pgtap = ["extensions", "oliphaunt-wasix/extension-pgtap"] extension-postgis = ["extensions", "oliphaunt-wasix/extension-postgis"] +extension-refint = ["extensions", "oliphaunt-wasix/extension-refint"] extension-seg = ["extensions", "oliphaunt-wasix/extension-seg"] extension-tablefunc = ["extensions", "oliphaunt-wasix/extension-tablefunc"] extension-tcn = ["extensions", "oliphaunt-wasix/extension-tcn"] diff --git a/src/wasix/runtime/assets/build/docker_pgxs_extensions.sh b/src/wasix/runtime/assets/build/docker_pgxs_extensions.sh index 110799144..d68383391 100755 --- a/src/wasix/runtime/assets/build/docker_pgxs_extensions.sh +++ b/src/wasix/runtime/assets/build/docker_pgxs_extensions.sh @@ -92,7 +92,7 @@ fi ln -sf "$PGSRC/src/makefiles/pgxs.mk" "$BUILD_DIR/src/makefiles/pgxs.mk" ln -sf "$PGSRC/src/Makefile.shlib" "$BUILD_DIR/src/Makefile.shlib" - while IFS=$'\''\t'\'' read -r id sql_name source_dir module_file archive stable make_args; do + while IFS=$'\''\t'\'' read -r id sql_name source_dir module_file archive make_args; do case "$id" in ""|"#"*) continue ;; esac test -n "$sql_name" test -n "$source_dir" diff --git a/src/wasix/runtime/assets/build/docker_pgxs_extensions.test.sh b/src/wasix/runtime/assets/build/docker_pgxs_extensions.test.sh new file mode 100644 index 000000000..290114552 --- /dev/null +++ b/src/wasix/runtime/assets/build/docker_pgxs_extensions.test.sh @@ -0,0 +1,87 @@ +#!/usr/bin/env bash +set -euo pipefail + +script_dir="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)" +repo_root="$(git -C "$script_dir" rev-parse --show-toplevel)" +fixture="$(mktemp -d)" +trap 'rm -rf "$fixture"' EXIT +export OLIPHAUNT_PGXS_TEST_ROOT="$fixture" +build_scripts="$fixture/src/wasix/runtime/assets/build" +mkdir -p "$build_scripts" "$fixture/bin" "$fixture/build/src/backend" "$fixture/postgres/src/makefiles" +touch "$fixture/build/config.status" "$fixture/build/src/backend/oliphaunt" +printf 'test\n' > "$fixture/build/.oliphaunt-wasix-build-profile" +sha256sum "$fixture/build/config.status" > "$fixture/build/.oliphaunt-wasix-bridge-sha256" +cat > "$build_scripts/profile_flags.sh" <<'SH' +oliphaunt_wasix_apply_wasix_profile() { :; } +oliphaunt_wasix_wasix_profile_signature() { echo test; } +SH +cat > "$build_scripts/source_lane.sh" <<'SH' +oliphaunt_wasix_check_source_markers() { :; } +oliphaunt_wasix_verify_side_module_sjlj() { :; } +SH +touch "$build_scripts/docker_wasix_env.sh" +printf '#!/usr/bin/env bash\necho\n' > "$build_scripts/pg_config_wasix.sh" +chmod +x "$build_scripts/pg_config_wasix.sh" + +# Run the actual Docker payload locally with harmless source/build fixtures. +# Only the container mount path and prerequisite toolchain are substituted. +cat > "$fixture/bin/docker" <<'SH' +#!/usr/bin/env bash +set -euo pipefail +if [[ "$1" == image ]]; then exit 0; fi +while [[ "$1" != bash ]]; do + if [[ "$1" == -e ]]; then export "$2"; shift; fi + shift +done +payload="${3//\/work\//$OLIPHAUNT_PGXS_TEST_ROOT/}" +cd "$OLIPHAUNT_PGXS_TEST_ROOT" +exec bash -c "$payload" +SH +chmod +x "$fixture/bin/docker" + +# Use generated SQL-only and SIMD policy rows, plus a compiled extension with one make arg. +awk -F '\t' '$1 == "pg_partman" || $1 == "vector"' "$repo_root/src/extensions/generated/pgxs-build.tsv" > "$fixture/plan.tsv" +test -s "$fixture/plan.tsv" +printf 'age\tage\tfixture-age\tage.so\textensions/age.tar.zst\tSIZEOF_DATUM=4\n' >> "$fixture/plan.tsv" +partman_source="$(awk -F '\t' '$1 == "pg_partman" {print $3}' "$fixture/plan.tsv")" +vector_source="$(awk -F '\t' '$1 == "vector" {print $3}' "$fixture/plan.tsv")" +mkdir -p "$fixture/$partman_source" "$fixture/$vector_source" "$fixture/fixture-age" +cat > "$fixture/$partman_source/Makefile" <<'MAKE' +SCRIPTS = unwanted-tools +DOCS = unwanted-docs +all: + @test "$(NO_BGW)" = 1 + @test -z "$(SCRIPTS)" + @test -z "$(DOCS)" + @touch flags-verified +clean: + @true +MAKE +cat > "$fixture/$vector_source/Makefile" <<'MAKE' +OPTFLAGS = -march=native +PG_CFLAGS += $(OPTFLAGS) -ffp-contract=fast +all: + @test "$(PG_CFLAGS)" = '-mno-relaxed-simd -ffp-contract=fast' + @touch vector.so flags-verified +clean: + @true +MAKE +cat > "$fixture/fixture-age/Makefile" <<'MAKE' +all: + @test "$(SIZEOF_DATUM)" = 4 + @touch age.so flags-verified +clean: + @true +MAKE + +DOCKER="$fixture/bin/docker" \ + JOBS=2 OLIPHAUNT_WASM_SKIP_IMAGE_BUILD=1 \ + CONTAINER_PGSRC="$fixture/postgres" \ + CONTAINER_BUILD_DIR="$fixture/build" \ + CONTAINER_ROOT="$build_scripts" \ + CONTAINER_PLAN="$fixture/plan.tsv" \ + bash "$script_dir/docker_pgxs_extensions.sh" +test -f "$fixture/build/pgxs/pg_partman/flags-verified" +test -f "$fixture/build/pgxs/age/flags-verified" +test -f "$fixture/build/pgxs/vector/flags-verified" +echo 'WASIX PGXS generated plan passes each make argument to the actual build' diff --git a/src/wasix/runtime/assets/generated/wasix-dl.exports b/src/wasix/runtime/assets/generated/wasix-dl.exports index 388c2ee05..ba6b4249e 100644 --- a/src/wasix/runtime/assets/generated/wasix-dl.exports +++ b/src/wasix/runtime/assets/generated/wasix-dl.exports @@ -3,6 +3,7 @@ AcquireRewriteLocks ActiveSnapshotSet AggCheckCallContext AllocSetContextCreateInternal +AllocateFile AlterTableGetLockLevel AlterTableInternal AlterTableLookupRelation @@ -29,6 +30,7 @@ BufFileWrite BufferBlocks BufferDescriptors BufferGetBlockNumber +BufferUsageAccumDiff BuildIndexInfo BuildTupleFromCStrings CacheMemoryContext @@ -45,6 +47,8 @@ CheckFunctionValidatorAccess CheckIndexCompatible CheckTableNotInUse CheckXidAlive +CleanQuerytext +CloseTransientFile CommandCounterIncrement CommitTransactionCommand ConditionVariableBroadcast @@ -93,6 +97,7 @@ DirectFunctionCall4Coll DirectFunctionCall5Coll EOH_flatten_into EOH_get_flat_size +EnableQueryId EncodeDateOnly EncodeDateTime EncodeSpecialDate @@ -120,12 +125,18 @@ ExecutorStart ExecutorStart_hook ExitParallelMode ExplainBeginOutput +ExplainCloseGroup ExplainEndOutput +ExplainIndentText +ExplainOpenGroup ExplainPrintJITSummary ExplainPrintPlan ExplainPrintTriggers +ExplainPropertyBool +ExplainPropertyFloat ExplainPropertyInteger ExplainPropertyText +ExplainPropertyUInteger ExplainQueryParameters ExplainQueryText ExprEvalPushStep @@ -139,6 +150,7 @@ FreeCachedExpression FreeErrorData FreeExecutorState FreeExprContext +FreeFile FreeQueryDesc FuncnameGetCandidates FunctionCall0Coll @@ -165,6 +177,8 @@ GetDatabaseEncodingName GetDefaultCharSignedness GetDefaultOpClass GetErrorContextStack +GetExplainExtensionId +GetExplainExtensionState GetFlushRecPtr GetForeignColumnOptions GetForeignDataWrapper @@ -172,7 +186,9 @@ GetForeignServer GetForeignTable GetFreeIndexPage GetLatestSnapshot +GetLockmodeName GetMemoryChunkContext +GetNamedLWLockTranche GetOldestNonRemovableTransactionId GetRecordedFreeSpace GetRunningTransactionData @@ -205,6 +221,7 @@ IsCatalogNamespace IsInParallelMode IsToastNamespace IsTransactionState +IsUnderPostmaster IsValidJsonNumber ItemPointerCompare ItemPointerEquals @@ -264,6 +281,7 @@ NewRelationCreateToastTable NextCopyFrom OidFunctionCall1Coll OidOutputFunctionCall +OpenTransientFile OpernameGetOprid OutputFunctionCall PG_exception_stack @@ -304,6 +322,7 @@ ReadNextMultiXactId RecentXmin RecordFreeIndexPage RecoveryInProgress +RegisterExtensionExplainOption RegisterSnapshot RegisterSubXactCallback RegisterXactCallback @@ -322,6 +341,7 @@ ReleaseCurrentSubTransaction ReleaseSysCache RelnameGetRelid RequestAddinShmemSpace +RequestNamedLWLockTranche ResourceOwnerCreate ResourceOwnerDelete ResourceOwnerEnlarge @@ -345,6 +365,7 @@ SPI_cursor_open_with_paramlist SPI_cursor_parse_open SPI_datumTransfer SPI_exec +SPI_execp SPI_execute SPI_execute_extended SPI_execute_plan @@ -356,7 +377,9 @@ SPI_fnumber SPI_freeplan SPI_freetuptable SPI_getbinval +SPI_getrelname SPI_gettype +SPI_gettypeid SPI_getvalue SPI_keepplan SPI_modifytuple @@ -379,6 +402,8 @@ SPI_scroll_cursor_move SPI_tuptable ScanKeyInit ScanKeywordLookup +ScanKeywordTokens +ScanKeywords SearchPathMatchesCurrentEnvironment SearchSysCache1 SearchSysCache2 @@ -388,11 +413,14 @@ SearchSysCacheExists SearchSysCacheList SearchSysCacheLocked1 SetConfigOption +SetExplainExtensionState SetTuplestoreDestReceiverParams SetUserIdAndSecContext SharedFileSetAttach SharedFileSetInit +ShmemInitHash ShmemInitStruct +SnapBuildRestoreSnapshot SnapshotAnyData SnapshotSelfData SplitIdentifierString @@ -428,6 +456,7 @@ UnregisterSnapshot UpdateActiveSnapshotCommandId WaitForParallelWorkersToAttach WaitForParallelWorkersToFinish +WalUsageAccumDiff WinGetCurrentPosition WinGetFuncArgCurrent WinGetFuncArgInPartition @@ -510,6 +539,7 @@ biteq bitge bitgt bitle +bitlength bitlt block_range_read_stream_cb bloom_add_element @@ -523,7 +553,6 @@ bms_del_member bms_del_members bms_equal bms_free -bms_int_members bms_is_member bms_is_subset bms_make_singleton @@ -570,6 +599,7 @@ check_amoptsproc_signature check_amproc_signature check_can_set_role check_function_bodies +check_password_hook check_stack_depth clamp_row_est clauselist_selectivity @@ -642,6 +672,7 @@ dshash_release_lock dshash_seq_init dshash_seq_next dshash_seq_term +durable_rename end_MultiFuncCall enlargeStringInfo enum_cmp @@ -683,6 +714,8 @@ expanded_record_lookup_field expanded_record_set_field_internal expanded_record_set_fields expanded_record_set_tuple +explain_per_node_hook +explain_per_plan_hook exprCollation exprLocation exprType @@ -736,6 +769,7 @@ free_object_addresses fseek fstat ftell +ftruncate function_parse_error_transpose fwrite gen_random_uuid @@ -774,6 +808,7 @@ get_function_sibling_type get_index_am_oid get_mergejoin_opfamilies get_namespace_name +get_namespace_name_or_temp get_namespace_oid get_opcode get_opfamily_member @@ -828,16 +863,19 @@ hash_bytes hash_bytes_extended hash_create hash_destroy +hash_estimate_size hash_get_num_entries hash_search hash_seq_init hash_seq_search +hash_seq_term heap_deform_tuple heap_fetch heap_form_tuple heap_freetuple heap_getsysattr heap_modify_tuple +heap_modify_tuple_by_cols heap_reloptions heap_truncate_find_FKs heap_tuple_needs_eventual_freeze @@ -880,8 +918,8 @@ list_concat list_concat_copy list_concat_unique_oid list_copy -list_delete_cell list_delete_first +list_delete_int list_delete_last list_delete_nth_cell list_free @@ -951,6 +989,7 @@ nanosleep network_cmp new_object_addresses nextafterf +nextval nocache_index_getattr nocachegetattr nodeToString @@ -987,6 +1026,7 @@ oliphaunt_wasix_set_active oliphaunt_wasix_set_force_host_error_recovery oliphaunt_wasix_set_protocol_transport oliphaunt_wasix_start +on_shmem_exit op_hashjoinable op_mergejoinable open @@ -1005,6 +1045,8 @@ parser_errposition per_MultiFuncCall performMultipleDeletions pfree +pgBufferUsage +pgWalUsage pg_any_to_server pg_ascii_tolower pg_attribute_aclcheck @@ -1044,7 +1086,6 @@ pg_numa_query_pages pg_number_of_ones pg_parse_query pg_plan_query -pg_popcount64 pg_popcount_optimized pg_printf pg_prng_double @@ -1081,6 +1122,7 @@ pgstat_count_heap_insert pgstat_count_truncate pgstat_progress_update_param pgstat_report_activity +plain_crypt_verify plan_create_index_workers planner_hook pnstrdup @@ -1108,6 +1150,7 @@ pull_varattnos pull_varnos pull_vars_of_level pushJsonbValue +pwrite qsort qsort_arg query_tree_walker_impl @@ -1245,9 +1288,11 @@ timestamp_cmp timestamp_eq timestamp_ge timestamp_gt +timestamp_in timestamp_le timestamp_lt timestamp_mi +timestamptz_in timetz_cmp tm2timestamp to_hex32 @@ -1293,6 +1338,7 @@ type_is_collatable type_is_rowtype typeidType typenameTypeIdAndMod +unlink unpack_sql_state untransformRelOptions updateClosestMatch diff --git a/src/wasix/runtime/crates/assets/Cargo.toml b/src/wasix/runtime/crates/assets/Cargo.toml index c91d03aa8..d26cb2bfe 100644 --- a/src/wasix/runtime/crates/assets/Cargo.toml +++ b/src/wasix/runtime/crates/assets/Cargo.toml @@ -26,6 +26,7 @@ include = [ [features] extension-amcheck = [] extension-auto-explain = [] +extension-autoinc = [] extension-bloom = [] extension-btree-gin = [] extension-btree-gist = [] @@ -37,15 +38,22 @@ extension-earthdistance = ["extension-cube"] extension-file-fdw = [] extension-fuzzystrmatch = [] extension-hstore = [] +extension-insert-username = [] extension-intarray = [] extension-isn = [] extension-lo = [] extension-ltree = [] +extension-moddatetime = [] extension-pageinspect = [] +extension-passwordcheck = [] extension-pg-buffercache = [] extension-pg-freespacemap = [] extension-pg-hashids = [] extension-pg-ivm = [] +extension-pg-logicalinspect = [] +extension-pg-overexplain = [] +extension-pg-stat-statements = [] +extension-pg-partman = [] extension-pg-surgery = [] extension-pg-textsearch = [] extension-pg-trgm = [] @@ -53,8 +61,10 @@ extension-pg-uuidv7 = [] extension-pg-visibility = [] extension-pg-walinspect = [] extension-pgcrypto = [] +extension-pgmq = [] extension-pgtap = [] extension-postgis = [] +extension-refint = [] extension-seg = [] extension-tablefunc = [] extension-tcn = [] diff --git a/src/wasix/runtime/crates/assets/build-support.rs b/src/wasix/runtime/crates/assets/build-support.rs index e26af1d7b..aa732cde3 100644 --- a/src/wasix/runtime/crates/assets/build-support.rs +++ b/src/wasix/runtime/crates/assets/build-support.rs @@ -107,6 +107,13 @@ const EXTENSION_PACKAGES: &[ExtensionPackage] = &[ sql_name: "auto_explain", crate_ident: "oliphaunt_extension_contrib_pg18", }, + ExtensionPackage { + feature: "extension-autoinc", + env: "CARGO_FEATURE_EXTENSION_AUTOINC", + product: "oliphaunt-extension-contrib-pg18", + sql_name: "autoinc", + crate_ident: "oliphaunt_extension_contrib_pg18", + }, ExtensionPackage { feature: "extension-bloom", env: "CARGO_FEATURE_EXTENSION_BLOOM", @@ -184,6 +191,13 @@ const EXTENSION_PACKAGES: &[ExtensionPackage] = &[ sql_name: "hstore", crate_ident: "oliphaunt_extension_contrib_pg18", }, + ExtensionPackage { + feature: "extension-insert-username", + env: "CARGO_FEATURE_EXTENSION_INSERT_USERNAME", + product: "oliphaunt-extension-contrib-pg18", + sql_name: "insert_username", + crate_ident: "oliphaunt_extension_contrib_pg18", + }, ExtensionPackage { feature: "extension-intarray", env: "CARGO_FEATURE_EXTENSION_INTARRAY", @@ -212,6 +226,13 @@ const EXTENSION_PACKAGES: &[ExtensionPackage] = &[ sql_name: "ltree", crate_ident: "oliphaunt_extension_contrib_pg18", }, + ExtensionPackage { + feature: "extension-moddatetime", + env: "CARGO_FEATURE_EXTENSION_MODDATETIME", + product: "oliphaunt-extension-contrib-pg18", + sql_name: "moddatetime", + crate_ident: "oliphaunt_extension_contrib_pg18", + }, ExtensionPackage { feature: "extension-pageinspect", env: "CARGO_FEATURE_EXTENSION_PAGEINSPECT", @@ -219,6 +240,13 @@ const EXTENSION_PACKAGES: &[ExtensionPackage] = &[ sql_name: "pageinspect", crate_ident: "oliphaunt_extension_contrib_pg18", }, + ExtensionPackage { + feature: "extension-passwordcheck", + env: "CARGO_FEATURE_EXTENSION_PASSWORDCHECK", + product: "oliphaunt-extension-contrib-pg18", + sql_name: "passwordcheck", + crate_ident: "oliphaunt_extension_contrib_pg18", + }, ExtensionPackage { feature: "extension-pg-buffercache", env: "CARGO_FEATURE_EXTENSION_PG_BUFFERCACHE", @@ -233,6 +261,27 @@ const EXTENSION_PACKAGES: &[ExtensionPackage] = &[ sql_name: "pg_freespacemap", crate_ident: "oliphaunt_extension_contrib_pg18", }, + ExtensionPackage { + feature: "extension-pg-logicalinspect", + env: "CARGO_FEATURE_EXTENSION_PG_LOGICALINSPECT", + product: "oliphaunt-extension-contrib-pg18", + sql_name: "pg_logicalinspect", + crate_ident: "oliphaunt_extension_contrib_pg18", + }, + ExtensionPackage { + feature: "extension-pg-overexplain", + env: "CARGO_FEATURE_EXTENSION_PG_OVEREXPLAIN", + product: "oliphaunt-extension-contrib-pg18", + sql_name: "pg_overexplain", + crate_ident: "oliphaunt_extension_contrib_pg18", + }, + ExtensionPackage { + feature: "extension-pg-stat-statements", + env: "CARGO_FEATURE_EXTENSION_PG_STAT_STATEMENTS", + product: "oliphaunt-extension-contrib-pg18", + sql_name: "pg_stat_statements", + crate_ident: "oliphaunt_extension_contrib_pg18", + }, ExtensionPackage { feature: "extension-pg-surgery", env: "CARGO_FEATURE_EXTENSION_PG_SURGERY", @@ -268,6 +317,13 @@ const EXTENSION_PACKAGES: &[ExtensionPackage] = &[ sql_name: "pgcrypto", crate_ident: "oliphaunt_extension_contrib_pg18", }, + ExtensionPackage { + feature: "extension-refint", + env: "CARGO_FEATURE_EXTENSION_REFINT", + product: "oliphaunt-extension-contrib-pg18", + sql_name: "refint", + crate_ident: "oliphaunt_extension_contrib_pg18", + }, ExtensionPackage { feature: "extension-seg", env: "CARGO_FEATURE_EXTENSION_SEG", @@ -331,6 +387,20 @@ const EXTENSION_PACKAGES: &[ExtensionPackage] = &[ sql_name: "pg_ivm", crate_ident: "oliphaunt_extension_pg_ivm", }, + ExtensionPackage { + feature: "extension-pgmq", + env: "CARGO_FEATURE_EXTENSION_PGMQ", + product: "oliphaunt-extension-pgmq", + sql_name: "pgmq", + crate_ident: "oliphaunt_extension_pgmq", + }, + ExtensionPackage { + feature: "extension-pg-partman", + env: "CARGO_FEATURE_EXTENSION_PG_PARTMAN", + product: "oliphaunt-extension-pg-partman", + sql_name: "pg_partman", + crate_ident: "oliphaunt_extension_pg_partman", + }, ExtensionPackage { feature: "extension-pg-textsearch", env: "CARGO_FEATURE_EXTENSION_PG_TEXTSEARCH", diff --git a/src/wasix/runtime/moon.yml b/src/wasix/runtime/moon.yml index 79e79beab..a5fa1b311 100644 --- a/src/wasix/runtime/moon.yml +++ b/src/wasix/runtime/moon.yml @@ -107,10 +107,15 @@ tasks: tags: - quality - unit - script: "set -e\nbash src/wasix/runtime/tools/check-shim-abi.sh\nbash src/wasix/runtime/assets/build/docker/install-pinned-apt-packages.test.sh\nbash src/wasix/runtime/assets/build/docker/install-pinned-wasixcc.test.sh\n" + script: "set -e\nbash src/wasix/runtime/tools/check-shim-abi.sh\nbash src/wasix/runtime/assets/build/docker/install-pinned-apt-packages.test.sh\nbash src/wasix/runtime/assets/build/docker/install-pinned-wasixcc.test.sh\nbash src/wasix/runtime/assets/build/docker_pgxs_extensions.test.sh\n" inputs: - /tools/dev/acquisition.sh - assets/build/docker/**/* + - assets/build/docker_pgxs_extensions.sh + - assets/build/docker_pgxs_extensions.test.sh + - assets/build/wasix_third_party.sh + - assets/build/source_lane.sh + - /src/extensions/generated/pgxs-build.tsv - assets/build/wasix_shim/**/* - tools/check-shim-abi.sh options: diff --git a/src/wasix/runtime/tools/package-liboliphaunt-wasix-cargo-artifacts.test.mts b/src/wasix/runtime/tools/package-liboliphaunt-wasix-cargo-artifacts.test.mts index 1f5b6e0b3..ef19ee11c 100644 --- a/src/wasix/runtime/tools/package-liboliphaunt-wasix-cargo-artifacts.test.mts +++ b/src/wasix/runtime/tools/package-liboliphaunt-wasix-cargo-artifacts.test.mts @@ -17,10 +17,10 @@ import { createDeterministicTar } from '../../../../tools/packaging/cargo-source import { canonicalGzipSync } from '../../../../tools/packaging/portable-archive.mts'; import { stageReleaseNotices } from '../../../../tools/packaging/release-notices.mts'; import { + exactExtensionProducts, extensionReleaseProduct, extensionReleaseVersion, extensionSqlNames, - exactExtensionProducts, } from '../../../../tools/release/release-artifact-targets.mts'; import { extractArchiveMemberToFile, @@ -218,6 +218,36 @@ function aggregateFixture(root, { nestedOwner = false } = {}) { } describe('aggregate WASIX Cargo artifact packaging', () => { + test('source consumers select every catalog member through the asset build script', () => { + const manifest = JSON.parse( + readFileSync(path.join(ROOT, 'src/extensions/generated/wasix/extensions.json'), 'utf8'), + ); + const sqlNames = manifest.extensions.map((extension) => extension['sql-name']).sort(); + const features = sqlNames.map((sqlName) => `extension-${sqlName.replaceAll('_', '-')}`); + const app = path.join(scratch, 'all-members', 'app'); + mkdirSync(path.join(app, 'src'), { recursive: true }); + writeFileSync( + path.join(app, 'Cargo.toml'), + `[package] +name = "wasix-all-members-proof" +version = "0.0.0" +edition = "2024" +[dependencies] +liboliphaunt-wasix-portable = { path = ${JSON.stringify(path.join(ROOT, 'src/wasix/runtime/crates/assets'))}, features = ${JSON.stringify(features)} } +[workspace] +`, + ); + writeFileSync( + path.join(app, 'src/main.rs'), + `fn main() { + let mut selected = liboliphaunt_wasix_portable::SELECTED_EXTENSION_SQL_NAMES.to_vec(); + selected.sort_unstable(); + assert_eq!(selected, ${JSON.stringify(sqlNames)}); +} +`, + ); + }); + test('runtime source builds use every external extension product version independently of the runtime', () => { const root = path.join(scratch, 'independent-extension'); const host = supportedRustcHostTriple(); diff --git a/src/wasix/runtime/tools/test-packaging.sh b/src/wasix/runtime/tools/test-packaging.sh index 719d33b2e..907d723ca 100644 --- a/src/wasix/runtime/tools/test-packaging.sh +++ b/src/wasix/runtime/tools/test-packaging.sh @@ -18,15 +18,19 @@ if bun "$contract" unsupported > /dev/null 2>&1; then fi bash tools/dev/bun.sh test ./src/wasix/runtime/tools node src/wasix/runtime/tools/wasix-runtime-npm.test-consumer.mts -for scenario in nested-owner aggregate independent-extension; do +for scenario in all-members nested-owner aggregate independent-extension; do root="$OLIPHAUNT_WASIX_PACKAGING_TEST_ROOT/$scenario" # Keep registry dependencies at the qualified workspace versions; this # disposable consumer only changes local carrier paths and feature selection. cp Cargo.lock "$root/app/Cargo.lock" cargo fetch --manifest-path "$root/app/Cargo.toml" + if [[ "$scenario" == all-members ]]; then + artifact_env=(-u OLIPHAUNT_WASIX_EXTENSION_ARTIFACT_ROOT) + else + artifact_env=("OLIPHAUNT_WASIX_EXTENSION_ARTIFACT_ROOT=$root") + fi CARGO_TARGET_DIR="$OLIPHAUNT_WASIX_PACKAGING_TEST_ROOT/cargo-target" \ - OLIPHAUNT_WASIX_EXTENSION_ARTIFACT_ROOT="$root" \ - cargo run --locked --offline --manifest-path "$root/app/Cargo.toml" + env "${artifact_env[@]}" cargo run --locked --offline --manifest-path "$root/app/Cargo.toml" done root="$OLIPHAUNT_WASIX_PACKAGING_TEST_ROOT/independent-extension" manifest="$root/oliphaunt-extension-pg-hashids/extension-artifacts.json" diff --git a/src/wasix/runtime/tools/wasix-extension-features.test.mts b/src/wasix/runtime/tools/wasix-extension-features.test.mts index bbc87c1a2..188a3e067 100644 --- a/src/wasix/runtime/tools/wasix-extension-features.test.mts +++ b/src/wasix/runtime/tools/wasix-extension-features.test.mts @@ -9,24 +9,62 @@ import { extensionFeatures, fullEvidenceFeatures } from './wasix-extension-featu const ROOT = path.resolve(import.meta.dirname, '../../../..'); -test('the live WASIX public surface includes the PostGIS product', () => { +test('every catalog extension has matching Rust asset, SDK, server, and Node-API features', () => { const manifest = JSON.parse( readFileSync(path.join(ROOT, 'src/extensions/generated/wasix/extensions.json'), 'utf8'), ); - assert.equal( - manifest.extensions.some((row) => row['sql-name'] === 'postgis'), - true, - ); + const expected = extensionFeatures(manifest); for (const relative of [ 'src/wasix/runtime/crates/assets/Cargo.toml', 'src/wasix/sdks/rust/Cargo.toml', + 'src/wasix/pgwire-server/Cargo.toml', + 'src/wasix/node-addon/Cargo.toml', ]) { const cargo = Bun.TOML.parse(readFileSync(path.join(ROOT, relative), 'utf8')); - assert.equal(Object.hasOwn(cargo.features ?? {}, 'extension-postgis'), true, relative); + assert.deepEqual( + Object.keys(cargo.features ?? {}) + .filter((feature) => feature.startsWith('extension-')) + .sort(), + expected, + relative, + ); + for (const extension of manifest.extensions) { + const feature = `extension-${extension['sql-name'].replaceAll('_', '-')}`; + // plpgsql ships in the core runtime rather than an extension carrier. + const forwardsSdk = relative.includes('/pgwire-server/') || relative.includes('/node-addon/'); + const dependencies = (forwardsSdk ? [] : extension.dependencies) + .filter((sqlName) => sqlName !== 'plpgsql') + .map((sqlName) => `extension-${sqlName.replaceAll('_', '-')}`); + const forwarding = forwardsSdk + ? ['extensions', `oliphaunt-wasix/${feature}`] + : relative.includes('/sdks/') + ? ['extensions', `liboliphaunt-wasix-portable/${feature}`] + : []; + assert.deepEqual( + cargo.features[feature].toSorted(), + [...dependencies, ...forwarding].sort(), + `${relative}: ${feature}`, + ); + } } }); +test('the Node-API release embeds the complete contrib catalog', () => { + const catalog = JSON.parse( + readFileSync(path.join(ROOT, 'src/extensions/generated/extensions.catalog.json'), 'utf8'), + ); + const cargo = Bun.TOML.parse( + readFileSync(path.join(ROOT, 'src/wasix/node-addon/Cargo.toml'), 'utf8'), + ); + const contrib = extensionFeatures({ + extensions: catalog.extensions.filter( + (extension) => extension['source-kind'] === 'postgres-contrib', + ), + }); + assert.deepEqual(cargo.features.release.toSorted(), ['tools', ...contrib].sort()); +}); + test('full WASIX evidence enables every extension feature', () => { const manifest = { extensions: [{ 'sql-name': 'vector' }, { 'sql-name': 'pg_trgm' }], diff --git a/src/wasix/runtime/tools/xtask/src/asset_pipeline.rs b/src/wasix/runtime/tools/xtask/src/asset_pipeline.rs index 3b1b105f8..62c188848 100644 --- a/src/wasix/runtime/tools/xtask/src/asset_pipeline.rs +++ b/src/wasix/runtime/tools/xtask/src/asset_pipeline.rs @@ -1691,6 +1691,31 @@ fn stage_pgxs_style_extension( .join(control_file.file_name().unwrap_or_default()), )?; } + if sql_name == "pgmq" { + let sql_dir = build_dir.join("sql"); + let mut copied = false; + for entry in sorted_children(&sql_dir)? { + let Some(name) = entry.file_name().and_then(|name| name.to_str()) else { + continue; + }; + if entry.is_file() && name.starts_with("pgmq--") && name.ends_with(".sql") { + copy_file(&entry, &extension_sql_dir.join(name))?; + copied = true; + } + } + ensure!(copied, "PGMQ build has no versioned SQL files"); + return Ok(()); + } + if sql_name == "pg_partman" { + // sql/ also contains source fragments: only ship the assembled install + // script and versioned updates, never the unexpanded @extschema@ pieces. + ensure!( + copy_extension_sql_files(&build_dir.join("sql"), sql_name, &extension_sql_dir)?, + "pg_partman generated install SQL is missing" + ); + copy_extension_sql_files(&source.join("updates"), sql_name, &extension_sql_dir)?; + return Ok(()); + } let mut copied_root_sql = copy_extension_sql_files(&build_dir, sql_name, &extension_sql_dir)?; if !copied_root_sql { copied_root_sql = copy_extension_sql_files(source, sql_name, &extension_sql_dir)?; @@ -2558,6 +2583,139 @@ fn extension_control_files_for_asset_manifest( mod tests { use super::*; + #[test] + fn pgmq_stages_generated_install_and_upgrade_sql_only() { + let root = temp_aot_manifest_path("pgmq-stage"); + let source = root.join("source"); + let build = root.join("build"); + let stage = root.join("stage"); + let sql = build.join("pgxs/pgmq/sql"); + fs::create_dir_all(&source).unwrap(); + fs::create_dir_all(&sql).unwrap(); + fs::write(source.join("pgmq.control"), "default_version = '1.13.0'\n").unwrap(); + for name in [ + "pgmq.sql", + "pgmq--1.13.0.sql", + "pgmq--1.12.0--1.13.0.sql", + "foreign.sql", + ] { + fs::write(sql.join(name), "-- SQL\n").unwrap(); + } + let extension = extension_catalog::ExtensionBuildSpec { + id: "pgmq".into(), + display_name: "PGMQ".into(), + sql_name: "pgmq".into(), + build_kind: "pgxs-sql-only".into(), + source_dir: source.to_string_lossy().into(), + contrib_dir: None, + module_file: None, + archive: "extensions/pgmq.tar.zst".into(), + control_file: None, + native_support_modules: vec![], + excluded_sql_extensions: vec![], + staging: None, + lifecycle: extension_catalog::ExtensionLifecycle { + create_extension: true, + create_schema: Some("pgmq".into()), + load_sql: vec![], + post_create_sql: vec![], + startup_config: vec![], + preload_required: false, + restart_required: false, + shared_memory_required: false, + }, + }; + stage_pgxs_style_extension(&build, &extension, &stage).unwrap(); + let files: Vec<_> = sorted_children(&stage.join("share/postgresql/extension")) + .unwrap() + .into_iter() + .map(|path| path.file_name().unwrap().to_string_lossy().into_owned()) + .collect(); + assert_eq!( + files, + [ + "pgmq--1.12.0--1.13.0.sql", + "pgmq--1.13.0.sql", + "pgmq.control" + ] + ); + fs::remove_dir_all(root).unwrap(); + } + + #[test] + fn partman_staging_keeps_install_and_upgrade_sql_without_source_fragments() { + let root = temp_aot_manifest_path("partman-stage"); + let source = root.join("source"); + let build = root.join("build"); + let stage = root.join("stage"); + let built_sql = build.join("pgxs/pg_partman/sql"); + fs::create_dir_all(built_sql.join("functions")).unwrap(); + fs::create_dir_all(source.join("updates")).unwrap(); + fs::write( + source.join("pg_partman.control"), + "default_version = '5.5.0'\n", + ) + .unwrap(); + fs::write(built_sql.join("pg_partman--5.5.0.sql"), "install\n").unwrap(); + fs::write( + built_sql.join("functions/raw.sql"), + "@extschema@ fragment\n", + ) + .unwrap(); + fs::write( + source.join("updates/pg_partman--5.4.0--5.5.0.sql"), + "upgrade\n", + ) + .unwrap(); + fs::write(source.join("updates/unrelated.sql"), "excluded\n").unwrap(); + let extension = extension_catalog::ExtensionBuildSpec { + id: "pg_partman".to_owned(), + display_name: "pg_partman".to_owned(), + sql_name: "pg_partman".to_owned(), + build_kind: "pgxs-sql-only".to_owned(), + source_dir: source.to_string_lossy().into_owned(), + contrib_dir: None, + module_file: None, + archive: "extensions/pg_partman.tar.zst".to_owned(), + control_file: None, + native_support_modules: Vec::new(), + excluded_sql_extensions: Vec::new(), + staging: None, + lifecycle: extension_catalog::ExtensionLifecycle { + create_extension: true, + create_schema: Some("partman".to_owned()), + load_sql: Vec::new(), + post_create_sql: Vec::new(), + startup_config: Vec::new(), + preload_required: false, + restart_required: false, + shared_memory_required: false, + }, + }; + stage_pgxs_style_extension(&build, &extension, &stage).unwrap(); + let names = sorted_files(&stage) + .unwrap() + .into_iter() + .map(|file| { + file.strip_prefix(&stage) + .unwrap() + .to_string_lossy() + .replace('\\', "/") + }) + .collect::>(); + assert_eq!( + names, + vec![ + "share/postgresql/extension/pg_partman--5.4.0--5.5.0.sql", + "share/postgresql/extension/pg_partman--5.5.0.sql", + "share/postgresql/extension/pg_partman.control", + ] + ); + fs::remove_file(built_sql.join("pg_partman--5.5.0.sql")).unwrap(); + assert!(stage_pgxs_style_extension(&build, &extension, &root.join("missing")).is_err()); + fs::remove_dir_all(root).unwrap(); + } + fn manifest_extension_metadata( create_extension: bool, control_files: Vec<&str>, diff --git a/src/wasix/runtime/tools/xtask/src/extension_catalog.rs b/src/wasix/runtime/tools/xtask/src/extension_catalog.rs index d79407c61..f5f17677b 100644 --- a/src/wasix/runtime/tools/xtask/src/extension_catalog.rs +++ b/src/wasix/runtime/tools/xtask/src/extension_catalog.rs @@ -54,7 +54,7 @@ fn build_specs_at( display_name: extension.display_name.clone(), sql_name: extension.sql_name.clone(), build_kind, - source_dir: extension_source_dir(extension), + source_dir: extension_source_dir_at(extension, repository_root)?, contrib_dir: (extension.source_kind == "postgres-contrib") .then(|| extension_contrib_dir_name(&extension.id)), module_file: extension.native_module_file.clone(), @@ -205,8 +205,41 @@ fn build_kind( } } -fn extension_source_dir(extension: &ExtensionCatalogEntry) -> String { - extension_source_dir_for(&extension.id, &extension.source_kind) +fn extension_source_dir_at( + extension: &ExtensionCatalogEntry, + repository_root: &Path, +) -> Result { + let root = extension_source_dir_for(&extension.id, &extension.source_kind); + let recipe = repository_root + .join(EXTERNAL_EXTENSION_RECIPE_ROOT) + .join(&extension.sql_name) + .join("recipe.toml"); + if !recipe.is_file() { + return Ok(root); + } + let text = fs::read_to_string(&recipe).with_context(|| format!("read {}", recipe.display()))?; + let recipe: toml::Value = toml::from_str(&text).context("parse extension recipe")?; + let Some(subdirectory) = recipe + .get("build") + .and_then(|value| value.get("source_subdirectory")) + else { + return Ok(root); + }; + let subdirectory = subdirectory + .as_str() + .context("PGXS source subdirectory must be a string")?; + ensure!( + subdirectory.split('/').all(|part| { + let mut bytes = part.bytes(); + bytes + .next() + .is_some_and(|byte| byte.is_ascii_alphanumeric() || matches!(byte, b'_' | b'-')) + && bytes + .all(|byte| byte.is_ascii_alphanumeric() || matches!(byte, b'_' | b'-' | b'.')) + }), + "PGXS source subdirectory must stay within the pinned checkout" + ); + Ok(format!("{root}/{subdirectory}")) } fn extension_source_dir_for(id: &str, source_kind: &str) -> String { @@ -227,6 +260,7 @@ fn extension_source_dir_for(id: &str, source_kind: &str) -> String { fn extension_contrib_dir_name(id: &str) -> String { match id { "uuid_ossp" => "uuid-ossp".to_owned(), + "autoinc" | "insert_username" | "moddatetime" | "refint" => "spi".to_owned(), other => other.to_owned(), } } @@ -376,5 +410,40 @@ mod tests { .iter() .any(|module| module.name == "postgis_deps") ); + let pgmq = specs.iter().find(|spec| spec.id == "pgmq").unwrap(); + assert_eq!(pgmq.build_kind, "pgxs-sql-only"); + assert_eq!( + pgmq.source_dir, + "target/oliphaunt-sources/checkouts/pgmq/pgmq-extension" + ); + } + + #[test] + fn contrib_build_paths_match_the_shared_postgres_inventory() { + let root = Path::new(env!("CARGO_MANIFEST_DIR")).join("../../../../.."); + let catalog: ExtensionCatalog = + serde_json::from_str(&fs::read_to_string(root.join(CATALOG_PATH)).unwrap()).unwrap(); + let inventory: toml::Value = toml::from_str( + &fs::read_to_string(root.join("src/extensions/contrib/postgres18.toml")).unwrap(), + ) + .unwrap(); + for spec in build_specs_at(&catalog, &root).unwrap() { + let Some(directory) = spec.contrib_dir else { + continue; + }; + let recipe = inventory["extensions"] + .as_array() + .unwrap() + .iter() + .find(|recipe| recipe["id"].as_str() == Some(spec.id.as_str())) + .unwrap(); + assert_eq!(Some(directory.as_str()), recipe["contrib-dir"].as_str()); + assert_eq!( + spec.source_dir, + format!("{POSTGRES_CONTRIB}/{directory}"), + "{} must stage its own SQL files from the canonical contrib directory", + spec.id + ); + } } } diff --git a/src/wasix/sdks/rust/Cargo.toml b/src/wasix/sdks/rust/Cargo.toml index a47f56288..e39b9223e 100644 --- a/src/wasix/sdks/rust/Cargo.toml +++ b/src/wasix/sdks/rust/Cargo.toml @@ -38,6 +38,7 @@ tools = [ ] extension-amcheck = ["extensions", "liboliphaunt-wasix-portable/extension-amcheck"] extension-auto-explain = ["extensions", "liboliphaunt-wasix-portable/extension-auto-explain"] +extension-autoinc = ["extensions", "liboliphaunt-wasix-portable/extension-autoinc"] extension-bloom = ["extensions", "liboliphaunt-wasix-portable/extension-bloom"] extension-btree-gin = ["extensions", "liboliphaunt-wasix-portable/extension-btree-gin"] extension-btree-gist = ["extensions", "liboliphaunt-wasix-portable/extension-btree-gist"] @@ -53,15 +54,22 @@ extension-earthdistance = [ extension-file-fdw = ["extensions", "liboliphaunt-wasix-portable/extension-file-fdw"] extension-fuzzystrmatch = ["extensions", "liboliphaunt-wasix-portable/extension-fuzzystrmatch"] extension-hstore = ["extensions", "liboliphaunt-wasix-portable/extension-hstore"] +extension-insert-username = ["extensions", "liboliphaunt-wasix-portable/extension-insert-username"] extension-intarray = ["extensions", "liboliphaunt-wasix-portable/extension-intarray"] extension-isn = ["extensions", "liboliphaunt-wasix-portable/extension-isn"] extension-lo = ["extensions", "liboliphaunt-wasix-portable/extension-lo"] extension-ltree = ["extensions", "liboliphaunt-wasix-portable/extension-ltree"] +extension-moddatetime = ["extensions", "liboliphaunt-wasix-portable/extension-moddatetime"] extension-pageinspect = ["extensions", "liboliphaunt-wasix-portable/extension-pageinspect"] +extension-passwordcheck = ["extensions", "liboliphaunt-wasix-portable/extension-passwordcheck"] extension-pg-buffercache = ["extensions", "liboliphaunt-wasix-portable/extension-pg-buffercache"] extension-pg-freespacemap = ["extensions", "liboliphaunt-wasix-portable/extension-pg-freespacemap"] extension-pg-hashids = ["extensions", "liboliphaunt-wasix-portable/extension-pg-hashids"] extension-pg-ivm = ["extensions", "liboliphaunt-wasix-portable/extension-pg-ivm"] +extension-pg-logicalinspect = ["extensions", "liboliphaunt-wasix-portable/extension-pg-logicalinspect"] +extension-pg-overexplain = ["extensions", "liboliphaunt-wasix-portable/extension-pg-overexplain"] +extension-pg-stat-statements = ["extensions", "liboliphaunt-wasix-portable/extension-pg-stat-statements"] +extension-pg-partman = ["extensions", "liboliphaunt-wasix-portable/extension-pg-partman"] extension-pg-surgery = ["extensions", "liboliphaunt-wasix-portable/extension-pg-surgery"] extension-pg-textsearch = ["extensions", "liboliphaunt-wasix-portable/extension-pg-textsearch"] extension-pg-trgm = ["extensions", "liboliphaunt-wasix-portable/extension-pg-trgm"] @@ -69,8 +77,10 @@ extension-pg-uuidv7 = ["extensions", "liboliphaunt-wasix-portable/extension-pg-u extension-pg-visibility = ["extensions", "liboliphaunt-wasix-portable/extension-pg-visibility"] extension-pg-walinspect = ["extensions", "liboliphaunt-wasix-portable/extension-pg-walinspect"] extension-pgcrypto = ["extensions", "liboliphaunt-wasix-portable/extension-pgcrypto"] +extension-pgmq = ["extensions", "liboliphaunt-wasix-portable/extension-pgmq"] extension-pgtap = ["extensions", "liboliphaunt-wasix-portable/extension-pgtap"] extension-postgis = ["extensions", "liboliphaunt-wasix-portable/extension-postgis"] +extension-refint = ["extensions", "liboliphaunt-wasix-portable/extension-refint"] extension-seg = ["extensions", "liboliphaunt-wasix-portable/extension-seg"] extension-tablefunc = ["extensions", "liboliphaunt-wasix-portable/extension-tablefunc"] extension-tcn = ["extensions", "liboliphaunt-wasix-portable/extension-tcn"] diff --git a/src/wasix/sdks/rust/src/oliphaunt/generated_extensions.rs b/src/wasix/sdks/rust/src/oliphaunt/generated_extensions.rs index 04f2b30d4..b87e2d2fc 100644 --- a/src/wasix/sdks/rust/src/oliphaunt/generated_extensions.rs +++ b/src/wasix/sdks/rust/src/oliphaunt/generated_extensions.rs @@ -22,6 +22,16 @@ const DEFINITION_AUTO_EXPLAIN: Extension = Extension { package: None, }; +const DEFINITION_AUTOINC: Extension = Extension { + sql_name: "autoinc", + native_support_modules: &[], + native_module_file: Some("autoinc.so"), + aot_name: Some("extension:autoinc"), + dependencies: &[], + startup_config: &[], + package: None, +}; + const DEFINITION_BLOOM: Extension = Extension { sql_name: "bloom", native_support_modules: &[], @@ -132,6 +142,16 @@ const DEFINITION_HSTORE: Extension = Extension { package: None, }; +const DEFINITION_INSERT_USERNAME: Extension = Extension { + sql_name: "insert_username", + native_support_modules: &[], + native_module_file: Some("insert_username.so"), + aot_name: Some("extension:insert_username"), + dependencies: &[], + startup_config: &[], + package: None, +}; + const DEFINITION_INTARRAY: Extension = Extension { sql_name: "intarray", native_support_modules: &[], @@ -172,6 +192,16 @@ const DEFINITION_LTREE: Extension = Extension { package: None, }; +const DEFINITION_MODDATETIME: Extension = Extension { + sql_name: "moddatetime", + native_support_modules: &[], + native_module_file: Some("moddatetime.so"), + aot_name: Some("extension:moddatetime"), + dependencies: &[], + startup_config: &[], + package: None, +}; + const DEFINITION_PAGEINSPECT: Extension = Extension { sql_name: "pageinspect", native_support_modules: &[], @@ -182,6 +212,16 @@ const DEFINITION_PAGEINSPECT: Extension = Extension { package: None, }; +const DEFINITION_PASSWORDCHECK: Extension = Extension { + sql_name: "passwordcheck", + native_support_modules: &[], + native_module_file: Some("passwordcheck.so"), + aot_name: Some("extension:passwordcheck"), + dependencies: &[], + startup_config: &[], + package: None, +}; + const DEFINITION_PG_BUFFERCACHE: Extension = Extension { sql_name: "pg_buffercache", native_support_modules: &[], @@ -222,6 +262,46 @@ const DEFINITION_PG_IVM: Extension = Extension { package: None, }; +const DEFINITION_PG_LOGICALINSPECT: Extension = Extension { + sql_name: "pg_logicalinspect", + native_support_modules: &[], + native_module_file: Some("pg_logicalinspect.so"), + aot_name: Some("extension:pg_logicalinspect"), + dependencies: &[], + startup_config: &[], + package: None, +}; + +const DEFINITION_PG_OVEREXPLAIN: Extension = Extension { + sql_name: "pg_overexplain", + native_support_modules: &[], + native_module_file: Some("pg_overexplain.so"), + aot_name: Some("extension:pg_overexplain"), + dependencies: &[], + startup_config: &[], + package: None, +}; + +const DEFINITION_PG_PARTMAN: Extension = Extension { + sql_name: "pg_partman", + native_support_modules: &[], + native_module_file: None, + aot_name: None, + dependencies: &[], + startup_config: &[], + package: None, +}; + +const DEFINITION_PG_STAT_STATEMENTS: Extension = Extension { + sql_name: "pg_stat_statements", + native_support_modules: &[], + native_module_file: Some("pg_stat_statements.so"), + aot_name: Some("extension:pg_stat_statements"), + dependencies: &[], + startup_config: &["shared_preload_libraries=pg_stat_statements"], + package: None, +}; + const DEFINITION_PG_SURGERY: Extension = Extension { sql_name: "pg_surgery", native_support_modules: &[], @@ -292,6 +372,16 @@ const DEFINITION_PGCRYPTO: Extension = Extension { package: None, }; +const DEFINITION_PGMQ: Extension = Extension { + sql_name: "pgmq", + native_support_modules: &[], + native_module_file: None, + aot_name: None, + dependencies: &[], + startup_config: &[], + package: None, +}; + const DEFINITION_PGTAP: Extension = Extension { sql_name: "pgtap", native_support_modules: &[], @@ -315,6 +405,16 @@ const DEFINITION_POSTGIS: Extension = Extension { package: None, }; +const DEFINITION_REFINT: Extension = Extension { + sql_name: "refint", + native_support_modules: &[], + native_module_file: Some("refint.so"), + aot_name: Some("extension:refint"), + dependencies: &[], + startup_config: &[], + package: None, +}; + const DEFINITION_SEG: Extension = Extension { sql_name: "seg", native_support_modules: &[], @@ -402,6 +502,9 @@ impl Extension { /// Select the `auto_explain` artifact. pub const AUTO_EXPLAIN: Self = DEFINITION_AUTO_EXPLAIN; + /// Select the `autoinc` artifact. + + pub const AUTOINC: Self = DEFINITION_AUTOINC; /// Select the `bloom` artifact. pub const BLOOM: Self = DEFINITION_BLOOM; @@ -435,6 +538,9 @@ impl Extension { /// Select the `hstore` artifact. pub const HSTORE: Self = DEFINITION_HSTORE; + /// Select the `insert_username` artifact. + + pub const INSERT_USERNAME: Self = DEFINITION_INSERT_USERNAME; /// Select the `intarray` artifact. pub const INTARRAY: Self = DEFINITION_INTARRAY; @@ -447,9 +553,15 @@ impl Extension { /// Select the `ltree` artifact. pub const LTREE: Self = DEFINITION_LTREE; + /// Select the `moddatetime` artifact. + + pub const MODDATETIME: Self = DEFINITION_MODDATETIME; /// Select the `pageinspect` artifact. pub const PAGEINSPECT: Self = DEFINITION_PAGEINSPECT; + /// Select the `passwordcheck` artifact. + + pub const PASSWORDCHECK: Self = DEFINITION_PASSWORDCHECK; /// Select the `pg_buffercache` artifact. pub const PG_BUFFERCACHE: Self = DEFINITION_PG_BUFFERCACHE; @@ -462,6 +574,18 @@ impl Extension { /// Select the `pg_ivm` artifact. pub const PG_IVM: Self = DEFINITION_PG_IVM; + /// Select the `pg_logicalinspect` artifact. + + pub const PG_LOGICALINSPECT: Self = DEFINITION_PG_LOGICALINSPECT; + /// Select the `pg_overexplain` artifact. + + pub const PG_OVEREXPLAIN: Self = DEFINITION_PG_OVEREXPLAIN; + /// Select the `pg_partman` artifact. + + pub const PG_PARTMAN: Self = DEFINITION_PG_PARTMAN; + /// Select the `pg_stat_statements` artifact. + + pub const PG_STAT_STATEMENTS: Self = DEFINITION_PG_STAT_STATEMENTS; /// Select the `pg_surgery` artifact. pub const PG_SURGERY: Self = DEFINITION_PG_SURGERY; @@ -483,12 +607,18 @@ impl Extension { /// Select the `pgcrypto` artifact. pub const PGCRYPTO: Self = DEFINITION_PGCRYPTO; + /// Select the `pgmq` artifact. + + pub const PGMQ: Self = DEFINITION_PGMQ; /// Select the `pgtap` artifact. pub const PGTAP: Self = DEFINITION_PGTAP; /// Select the `postgis` artifact. pub const POSTGIS: Self = DEFINITION_POSTGIS; + /// Select the `refint` artifact. + + pub const REFINT: Self = DEFINITION_REFINT; /// Select the `seg` artifact. pub const SEG: Self = DEFINITION_SEG; @@ -518,6 +648,7 @@ impl Extension { pub const ALL: &'static [Self] = &[ Self::AMCHECK, Self::AUTO_EXPLAIN, + Self::AUTOINC, Self::BLOOM, Self::BTREE_GIN, Self::BTREE_GIST, @@ -529,15 +660,22 @@ impl Extension { Self::FILE_FDW, Self::FUZZYSTRMATCH, Self::HSTORE, + Self::INSERT_USERNAME, Self::INTARRAY, Self::ISN, Self::LO, Self::LTREE, + Self::MODDATETIME, Self::PAGEINSPECT, + Self::PASSWORDCHECK, Self::PG_BUFFERCACHE, Self::PG_FREESPACEMAP, Self::PG_HASHIDS, Self::PG_IVM, + Self::PG_LOGICALINSPECT, + Self::PG_OVEREXPLAIN, + Self::PG_PARTMAN, + Self::PG_STAT_STATEMENTS, Self::PG_SURGERY, Self::PG_TEXTSEARCH, Self::PG_TRGM, @@ -545,8 +683,10 @@ impl Extension { Self::PG_VISIBILITY, Self::PG_WALINSPECT, Self::PGCRYPTO, + Self::PGMQ, Self::PGTAP, Self::POSTGIS, + Self::REFINT, Self::SEG, Self::TABLEFUNC, Self::TCN, @@ -565,6 +705,8 @@ pub(super) fn creates_database_object_for_test(extension: Extension) -> bool { "auto_explain" => false, + "autoinc" => true, + "bloom" => true, "btree_gin" => true, @@ -587,6 +729,8 @@ pub(super) fn creates_database_object_for_test(extension: Extension) -> bool { "hstore" => true, + "insert_username" => true, + "intarray" => true, "isn" => true, @@ -595,8 +739,12 @@ pub(super) fn creates_database_object_for_test(extension: Extension) -> bool { "ltree" => true, + "moddatetime" => true, + "pageinspect" => true, + "passwordcheck" => false, + "pg_buffercache" => true, "pg_freespacemap" => true, @@ -605,6 +753,14 @@ pub(super) fn creates_database_object_for_test(extension: Extension) -> bool { "pg_ivm" => true, + "pg_logicalinspect" => true, + + "pg_overexplain" => false, + + "pg_partman" => true, + + "pg_stat_statements" => true, + "pg_surgery" => true, "pg_textsearch" => true, @@ -619,10 +775,14 @@ pub(super) fn creates_database_object_for_test(extension: Extension) -> bool { "pgcrypto" => true, + "pgmq" => true, + "pgtap" => true, "postgis" => true, + "refint" => true, + "seg" => true, "tablefunc" => true, @@ -654,6 +814,8 @@ pub(super) fn activation_sql_for_test(extension: Extension) -> &'static [&'stati "SET auto_explain.log_level = 'NOTICE';", ], + "autoinc" => &["CREATE EXTENSION IF NOT EXISTS \"autoinc\" WITH SCHEMA \"pg_catalog\";"], + "bloom" => &["CREATE EXTENSION IF NOT EXISTS \"bloom\" WITH SCHEMA \"pg_catalog\";"], "btree_gin" => { @@ -686,6 +848,10 @@ pub(super) fn activation_sql_for_test(extension: Extension) -> &'static [&'stati "hstore" => &["CREATE EXTENSION IF NOT EXISTS \"hstore\" WITH SCHEMA \"pg_catalog\";"], + "insert_username" => { + &["CREATE EXTENSION IF NOT EXISTS \"insert_username\" WITH SCHEMA \"pg_catalog\";"] + } + "intarray" => &["CREATE EXTENSION IF NOT EXISTS \"intarray\" WITH SCHEMA \"pg_catalog\";"], "isn" => &["CREATE EXTENSION IF NOT EXISTS \"isn\" WITH SCHEMA \"pg_catalog\";"], @@ -694,10 +860,16 @@ pub(super) fn activation_sql_for_test(extension: Extension) -> &'static [&'stati "ltree" => &["CREATE EXTENSION IF NOT EXISTS \"ltree\" WITH SCHEMA \"pg_catalog\";"], + "moddatetime" => { + &["CREATE EXTENSION IF NOT EXISTS \"moddatetime\" WITH SCHEMA \"pg_catalog\";"] + } + "pageinspect" => { &["CREATE EXTENSION IF NOT EXISTS \"pageinspect\" WITH SCHEMA \"pg_catalog\";"] } + "passwordcheck" => &["LOAD 'passwordcheck';"], + "pg_buffercache" => { &["CREATE EXTENSION IF NOT EXISTS \"pg_buffercache\" WITH SCHEMA \"pg_catalog\";"] } @@ -712,6 +884,19 @@ pub(super) fn activation_sql_for_test(extension: Extension) -> &'static [&'stati "pg_ivm" => &["CREATE EXTENSION IF NOT EXISTS \"pg_ivm\" WITH SCHEMA \"pg_catalog\";"], + "pg_logicalinspect" => { + &["CREATE EXTENSION IF NOT EXISTS \"pg_logicalinspect\" WITH SCHEMA \"pg_catalog\";"] + } + + "pg_overexplain" => &["LOAD 'pg_overexplain';"], + + "pg_partman" => &[ + "CREATE SCHEMA IF NOT EXISTS \"partman\";", + "CREATE EXTENSION IF NOT EXISTS \"pg_partman\" WITH SCHEMA \"partman\";", + ], + + "pg_stat_statements" => &["CREATE EXTENSION IF NOT EXISTS \"pg_stat_statements\";"], + "pg_surgery" => { &["CREATE EXTENSION IF NOT EXISTS \"pg_surgery\" WITH SCHEMA \"pg_catalog\";"] } @@ -736,10 +921,17 @@ pub(super) fn activation_sql_for_test(extension: Extension) -> &'static [&'stati "pgcrypto" => &["CREATE EXTENSION IF NOT EXISTS \"pgcrypto\";"], + "pgmq" => &[ + "CREATE SCHEMA IF NOT EXISTS \"pgmq\";", + "CREATE EXTENSION IF NOT EXISTS \"pgmq\" WITH SCHEMA \"pgmq\";", + ], + "pgtap" => &["CREATE EXTENSION IF NOT EXISTS \"pgtap\" WITH SCHEMA \"pg_catalog\";"], "postgis" => &["CREATE EXTENSION IF NOT EXISTS \"postgis\";"], + "refint" => &["CREATE EXTENSION IF NOT EXISTS \"refint\" WITH SCHEMA \"pg_catalog\";"], + "seg" => &["CREATE EXTENSION IF NOT EXISTS \"seg\" WITH SCHEMA \"pg_catalog\";"], "tablefunc" => { diff --git a/tools/release/check-release-metadata.mts b/tools/release/check-release-metadata.mts index b7c3d4939..36b7b3f46 100755 --- a/tools/release/check-release-metadata.mts +++ b/tools/release/check-release-metadata.mts @@ -300,11 +300,7 @@ function validateCompatibility(graph, { publication = false } = {}) { new Set(entries.map((entry) => entry.id)).size === entries.length, 'compatibility field ids must be globally unique', ); - const dependencyPlan = new Map( - (publication ? releaseDependencyPlan(graph.products, Object.keys(graph.products)) : []).map( - (entry) => [entry.id, entry.version], - ), - ); + let dependencyPlan = new Map(); let pendingRelease; let checkedPendingRelease = false; let pendingVersions = new Map(); @@ -349,6 +345,12 @@ function validateCompatibility(graph, { publication = false } = {}) { if (status.currentTagCommit === null) { pendingRelease = latestVerifiedReleaseCommit({ repo: ROOT }); pendingVersions = new Map(Object.entries(pendingRelease?.versions ?? {})); + dependencyPlan = new Map( + releaseDependencyPlan(graph.products, pendingVersions.keys()).map((entry) => [ + entry.id, + entry.version, + ]), + ); checkedPendingRelease = true; } } @@ -369,11 +371,17 @@ function validateCompatibility(graph, { publication = false } = {}) { // release. Once published, its immutable tag supplies this value. missingValue: value, }) - : dependencyPlan.get(entry.id); + : // A 0.0.0 product has no immutable release yet. An unrelated runtime + // release must preserve its declaration, just as candidate sync does. + pendingVersions.has(entry.product) + ? dependencyPlan.get(entry.id) + : value; const provenance = source.kind === 'tagged-sink' ? `immutable ${entry.product} tag ${source.tag}` - : `planned ${entry.sourceProduct} binding ${expected}`; + : pendingVersions.has(entry.product) + ? `planned ${entry.sourceProduct} binding ${expected}` + : `unreleased ${entry.product} declared requirement ${expected}`; requireCompatibilityVersionBinding( { id: entry.id, diff --git a/tools/release/prepare-release-candidate.test.mts b/tools/release/prepare-release-candidate.test.mts index e906ecfa3..5bfbbfbe3 100644 --- a/tools/release/prepare-release-candidate.test.mts +++ b/tools/release/prepare-release-candidate.test.mts @@ -406,13 +406,9 @@ for (const scenario of [ files: [`${native}/src/liboliphaunt.c`, 'src/extensions/external/vector/source.toml'], products: [ 'liboliphaunt-native', - 'oliphaunt-extension-vector', - 'oliphaunt-extension-pg-hashids', - 'oliphaunt-extension-pg-ivm', - 'oliphaunt-extension-pg-textsearch', - 'oliphaunt-extension-pg-uuidv7', - 'oliphaunt-extension-pgtap', - 'oliphaunt-extension-postgis', + ...Object.keys(graph.products).filter( + (id) => graph.products[id].extension?.class === 'external', + ), 'oliphaunt-js', 'oliphaunt-kotlin', 'oliphaunt-swift', @@ -466,13 +462,9 @@ for (const scenario of [ files: ['src/extensions/artifacts/packages/tools/package-extension-cargo-facades.mts'], products: [ 'liboliphaunt-native', - 'oliphaunt-extension-pg-hashids', - 'oliphaunt-extension-pg-ivm', - 'oliphaunt-extension-pg-textsearch', - 'oliphaunt-extension-pg-uuidv7', - 'oliphaunt-extension-pgtap', - 'oliphaunt-extension-postgis', - 'oliphaunt-extension-vector', + ...Object.keys(graph.products).filter( + (id) => graph.products[id].extension?.class === 'external', + ), 'oliphaunt-js', 'oliphaunt-kotlin', 'oliphaunt-swift', diff --git a/tools/release/release-dependency-plan.test.mts b/tools/release/release-dependency-plan.test.mts index c12b168f2..4613f7d63 100644 --- a/tools/release/release-dependency-plan.test.mts +++ b/tools/release/release-dependency-plan.test.mts @@ -1,4 +1,5 @@ import { expect, test } from 'bun:test'; +import { requireCompatibilityVersionBinding } from './compatibility-version-policy.mts'; import { releaseDependencyPlan, requirePublicSupportTransition, @@ -34,6 +35,43 @@ test('selected source consumers retain declarations while compiled payloads name ).toBe(true); }); +test('new SQL-only extensions retain declared hosts until their own release is selected', () => { + const runtime = 'liboliphaunt-wasix'; + for (const extension of ['pgmq', 'pg_partman']) { + const product = `oliphaunt-extension-${extension.replaceAll('_', '-')}`; + const products = { + [runtime]: { path: 'src/wasix/runtime', version: '0.3.3' }, + [product]: { + path: `src/extensions/external/${extension}`, + version: '0.0.0', + kind: 'exact-extension-artifact', + extension: { class: 'external' }, + }, + }; + const entry = { id: `${product}-host`, product, sourceProduct: runtime, publicSupport: true }; + const options = { entries: [entry], readValue: () => '0.3.2' }; + const [unchanged] = releaseDependencyPlan(products, [runtime], options); + expect(unchanged.version).toBe('0.3.2'); + expect(unchanged.binding).toBe('declared-requirement'); + + products[product].version = '0.1.0'; + const [selected] = releaseDependencyPlan(products, [runtime, product], options); + expect(selected.version).toBe('0.3.3'); + expect(selected.binding).toBe('compiled-input'); + const validate = (value) => + requireCompatibilityVersionBinding({ + id: entry.id, + value, + expected: selected.version, + sourceProduct: runtime, + sourceVersion: products[runtime].version, + provenance: `planned ${runtime} binding ${selected.version}`, + }); + expect(() => validate('0.3.2')).toThrow('must match planned'); + expect(() => validate('0.3.3')).not.toThrow(); + } +}); + test('support removal requires the configured pre-1.0 or stable breaking boundary', () => { const base = { product: 'extension',