Skip to content

Commit 77d4200

Browse files
authored
ci: [WRA-15] add Wrappers extension upgrade test (supabase#582)
* fix(s3vectors): update SQL functions and operators for idempotent upgrades * fix: update version to 0.6.1 and adjust extension upgrade test conditions * fix sudo permission * fix sudo permission * fix sudo permission * fix sudo permission * fix sudo permission * fix sudo permission * fix sudo permission * fix sudo permission * fix sudo permission * fix sudo permission * fix sudo permission * restore changes for testing * revert to version 0.6.0
1 parent 7633d56 commit 77d4200

4 files changed

Lines changed: 141 additions & 14 deletions

File tree

.github/workflows/test_wrappers.yml

Lines changed: 92 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -144,3 +144,95 @@ jobs:
144144
145145
- name: Perform test
146146
run: cd wrappers && cargo pgrx test --features "wasm_fdw pg15"
147+
148+
# =============================================================
149+
# Extension upgrade test
150+
# =============================================================
151+
test_upgrade:
152+
name: Run extension upgrade test
153+
needs: [changes]
154+
if: needs.changes.outputs.native == 'true'
155+
runs-on: blacksmith-4vcpu-ubuntu-2404
156+
157+
steps:
158+
- name: Checkout code
159+
uses: actions/checkout@v6
160+
with:
161+
fetch-depth: 0
162+
163+
- uses: actions-rust-lang/setup-rust-toolchain@v1
164+
with:
165+
toolchain: 1.88.0
166+
167+
- name: Install PostgreSQL 15
168+
run: |
169+
sudo apt remove -y postgres*
170+
sudo apt -y install curl ca-certificates build-essential pkg-config libssl-dev
171+
sudo install -d /usr/share/postgresql-common/pgdg
172+
sudo curl -o /usr/share/postgresql-common/pgdg/apt.postgresql.org.asc --fail https://www.postgresql.org/media/keys/ACCC4CF8.asc
173+
. /etc/os-release
174+
sudo sh -c "echo 'deb [signed-by=/usr/share/postgresql-common/pgdg/apt.postgresql.org.asc] https://apt.postgresql.org/pub/repos/apt $VERSION_CODENAME-pgdg main' > /etc/apt/sources.list.d/pgdg.list"
175+
sudo apt update -y -qq --fix-missing
176+
sudo apt -y install postgresql-client-15 postgresql-15 postgresql-server-dev-15
177+
sudo apt -y autoremove && sudo apt -y clean
178+
sudo chmod a+rwx `/usr/lib/postgresql/15/bin/pg_config --pkglibdir` `/usr/lib/postgresql/15/bin/pg_config --sharedir`/extension /var/run/postgresql/
179+
180+
- run: cargo install --locked cargo-pgrx --version 0.16.1
181+
- run: cargo pgrx init --pg15 /usr/lib/postgresql/15/bin/pg_config
182+
- name: Make Rust toolchain available to sudo
183+
run: sudo ln -sf "$HOME/.cargo/bin"/* /usr/local/bin/
184+
185+
- name: Download and install latest released extension
186+
env:
187+
GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
188+
run: |
189+
LATEST_TAG=$(gh release list --repo "$GITHUB_REPOSITORY" --limit 50 --json tagName --jq '[.[] | select(.tagName | test("^v[0-9]+\\.[0-9]+\\.[0-9]+$"))] | .[0].tagName')
190+
echo "LATEST_TAG=${LATEST_TAG}" >> "$GITHUB_ENV"
191+
echo "OLD_VERSION=${LATEST_TAG#v}" >> "$GITHUB_ENV"
192+
gh release download "$LATEST_TAG" \
193+
--repo "$GITHUB_REPOSITORY" \
194+
--pattern "wrappers-${LATEST_TAG}-pg15-amd64-linux-gnu.deb" \
195+
--dir /tmp/wrappers-released
196+
sudo dpkg -i /tmp/wrappers-released/*.deb
197+
198+
- name: Build and install current branch extension
199+
run: |
200+
NEW_VERSION=$(cargo metadata --format-version 1 --no-deps --manifest-path wrappers/Cargo.toml | jq -r '.packages[] | select(.name == "wrappers") | .version')
201+
echo "NEW_VERSION=${NEW_VERSION}" >> "$GITHUB_ENV"
202+
cd wrappers && sudo env PATH="$PATH" RUSTUP_HOME="$HOME/.rustup" CARGO_HOME="$HOME/.cargo" PGRX_HOME="$HOME/.pgrx" cargo pgrx install \
203+
--no-default-features \
204+
--features "pg15,native_fdws" \
205+
--pg-config /usr/lib/postgresql/15/bin/pg_config
206+
207+
- name: Create upgrade SQL script
208+
run: |
209+
if [[ "$OLD_VERSION" != "$NEW_VERSION" ]]; then
210+
sudo cp /usr/share/postgresql/15/extension/wrappers--${NEW_VERSION}.sql \
211+
/usr/share/postgresql/15/extension/wrappers--${OLD_VERSION}--${NEW_VERSION}.sql
212+
fi
213+
214+
- name: Run upgrade test
215+
run: |
216+
if ! sudo pg_lsclusters | awk '$1 == "15" && $2 == "main" {found=1} END {exit !found}'; then
217+
sudo pg_createcluster 15 main
218+
fi
219+
220+
sudo pg_ctlcluster 15 main start
221+
PG_PORT=$(sudo pg_lsclusters | awk '$1 == "15" && $2 == "main" {print $3}')
222+
until sudo -u postgres psql -p "$PG_PORT" -c '\q' 2>/dev/null; do sleep 1; done
223+
224+
sudo -u postgres psql -p "$PG_PORT" -c "CREATE EXTENSION wrappers VERSION '${OLD_VERSION}';"
225+
226+
if [[ "$OLD_VERSION" != "$NEW_VERSION" ]]; then
227+
sudo -u postgres psql -p "$PG_PORT" -c "ALTER EXTENSION wrappers UPDATE TO '${NEW_VERSION}';"
228+
EXPECTED="$NEW_VERSION"
229+
else
230+
EXPECTED="$OLD_VERSION"
231+
fi
232+
233+
INSTALLED=$(sudo -u postgres psql -p "$PG_PORT" -t -A -c "SELECT extversion FROM pg_extension WHERE extname = 'wrappers';")
234+
if [[ "$INSTALLED" != "$EXPECTED" ]]; then
235+
echo "Upgrade test FAILED: expected ${EXPECTED}, got ${INSTALLED}"
236+
exit 1
237+
fi
238+
echo "Upgrade test passed: ${OLD_VERSION} -> ${NEW_VERSION}"

wrappers/build.rs

Lines changed: 47 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -37,22 +37,22 @@ BEGIN
3737
3838
-- 2. Input function
3939
BEGIN
40-
CREATE FUNCTION "s3vec_in"("input" cstring)
40+
CREATE OR REPLACE FUNCTION "s3vec_in"("input" cstring)
4141
RETURNS S3Vec
4242
IMMUTABLE PARALLEL SAFE
4343
LANGUAGE c
4444
AS '{lib_name}', 's3vec_in_wrapper';
45-
EXCEPTION WHEN duplicate_object THEN NULL;
45+
EXCEPTION WHEN duplicate_function THEN NULL;
4646
END;
4747
4848
-- 3. Output function
4949
BEGIN
50-
CREATE FUNCTION "s3vec_out"("input" S3Vec)
50+
CREATE OR REPLACE FUNCTION "s3vec_out"("input" S3Vec)
5151
RETURNS cstring
5252
IMMUTABLE STRICT PARALLEL SAFE
5353
LANGUAGE c
5454
AS '{lib_name}', 's3vec_out_wrapper';
55-
EXCEPTION WHEN duplicate_object THEN NULL;
55+
EXCEPTION WHEN duplicate_function THEN NULL;
5656
END;
5757
5858
-- 4. Complete type definition (must come after in/out functions)
@@ -65,11 +65,53 @@ BEGIN
6565
);
6666
EXCEPTION WHEN duplicate_object THEN NULL;
6767
END;
68+
69+
-- 5. s3vec_knn function
70+
-- PostgreSQL has no CREATE OR REPLACE OPERATOR, so we manage the function
71+
-- and operator together here with EXCEPTION WHEN to make upgrades idempotent.
72+
BEGIN
73+
CREATE OR REPLACE FUNCTION "s3vec_knn"("_left" S3Vec, "_right" S3Vec)
74+
RETURNS bool
75+
IMMUTABLE STRICT PARALLEL SAFE
76+
LANGUAGE c
77+
AS '{lib_name}', 's3vec_knn_wrapper';
78+
EXCEPTION WHEN duplicate_function THEN NULL;
79+
END;
80+
81+
-- 6. s3vec_knn operator (<==> for S3Vec)
82+
BEGIN
83+
CREATE OPERATOR <==> (
84+
PROCEDURE = "s3vec_knn",
85+
LEFTARG = S3Vec,
86+
RIGHTARG = S3Vec
87+
);
88+
EXCEPTION WHEN duplicate_function THEN NULL;
89+
END;
90+
91+
-- 7. metadata_filter function
92+
BEGIN
93+
CREATE OR REPLACE FUNCTION "metadata_filter"("_left" jsonb, "_right" jsonb)
94+
RETURNS bool
95+
IMMUTABLE STRICT PARALLEL SAFE
96+
LANGUAGE c
97+
AS '{lib_name}', 'metadata_filter_wrapper';
98+
EXCEPTION WHEN duplicate_function THEN NULL;
99+
END;
100+
101+
-- 8. metadata_filter operator (<==> for jsonb)
102+
BEGIN
103+
CREATE OPERATOR <==> (
104+
PROCEDURE = "metadata_filter",
105+
LEFTARG = jsonb,
106+
RIGHTARG = jsonb
107+
);
108+
EXCEPTION WHEN duplicate_function THEN NULL;
109+
END;
68110
END
69111
$s3vec_upgrade$;
70112
"#,
71113
name = "s3vec_type",
72-
creates = [Type(S3Vec)],
114+
creates = [Type(S3Vec), Function(s3vec_knn), Function(metadata_filter)],
73115
);
74116
"##
75117
);

wrappers/sql/bootstrap.sql

Lines changed: 0 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -21,8 +21,3 @@ COMMENT ON COLUMN wrappers_fdw_stats.rows_out IS 'Total rows output to Postgres'
2121
COMMENT ON COLUMN wrappers_fdw_stats.bytes_in IS 'Total bytes input from origin';
2222
COMMENT ON COLUMN wrappers_fdw_stats.bytes_out IS 'Total bytes output to Postgres';
2323
COMMENT ON COLUMN wrappers_fdw_stats.metadata IS 'Metadata specific for the FDW';
24-
25-
-- The operator '<==>' is defined in s3vectors_fdw since v0.5.6, drop it here
26-
-- to avoid conflict when upgrading wrappers extension.
27-
DROP OPERATOR IF EXISTS <==> (jsonb, jsonb);
28-

wrappers/src/fdw/s3vectors_fdw/s3vec.rs

Lines changed: 2 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -121,15 +121,13 @@ impl TryFrom<*mut bytea> for S3Vec {
121121
}
122122
}
123123

124-
#[pg_operator(create_or_replace, immutable, parallel_safe)]
125-
#[opname(<==>)]
124+
#[pg_extern(sql = false)] // SQL is written manually in build.rs to support idempotent upgrades
126125
fn s3vec_knn(_left: S3Vec, _right: S3Vec) -> bool {
127126
// always return true here, actual calculation will be done in the wrapper
128127
true
129128
}
130129

131-
#[pg_operator(create_or_replace, immutable, parallel_safe)]
132-
#[opname(<==>)]
130+
#[pg_extern(sql = false)] // SQL is written manually in build.rs to support idempotent upgrades
133131
fn metadata_filter(_left: JsonB, _right: JsonB) -> bool {
134132
// always return true here, actual calculation will be done in the wrapper
135133
true

0 commit comments

Comments
 (0)