From 3978271baffdbdc332701cdad4c7ece22cf761c0 Mon Sep 17 00:00:00 2001 From: Chapman Flack Date: Tue, 11 Aug 2026 22:27:06 -0400 Subject: [PATCH 1/2] Disconnect SPI at end of Function_create Issue #544 presented a mystery where the regression test for trigger transition tables would succeed with check_function_bodies on, but fail with check_function_bodies off. In the 'on' case, the function would be ready to use ahead of its first invocation (the validator having done all the necessary work). The first invocation would find the function cached and invoke it, with SPI not yet connected. On the function's first use of SPI, Invocation_assertConnect sees there is a TriggerData associated with the invocation, and registers the transition tables to make them visible by the expected names. In the 'off' case, the function's first invocation requires Function_create to do its work, which may involve an SPI connection from PL/Java's class loader. Taking place before the invocation has been recognized as handling a trigger, this connection is made without registering the transition tables. By the time the function itself first uses SPI, the TriggerData has been associated with the invocation, but no registration occurs because SPI is already connected. Ending any SPI connection that Function_create may have made ensures that the first use of SPI by the function itself makes a new SPI connection that is appropriately set up. It is a bug for check_function_bodies to have an effect on a function's runtime behavior and not just on its validation. To catch such behavior in the future, the regression test script now repeats the example jar installation and test execution with check_function_bodies set to off. --- CI/common | 28 ++++++++++++++++++++++++++++ CI/integration | 29 +++++++++++++++++++---------- pljava-so/src/main/c/Function.c | 3 ++- 3 files changed, 49 insertions(+), 11 deletions(-) diff --git a/CI/common b/CI/common index 08df17edc..f26509b0e 100644 --- a/CI/common +++ b/CI/common @@ -279,4 +279,32 @@ boolean loadExamplesAndTest(Connection c) throws Exception ); } +/* + * Unloads the PL/Java example and Saxon jars, returning true if that produced + * the expected sequence of results (not necessarily meaning success, unless + * results.get("ng") is also zero afterward. + */ +boolean unloadExamples(Connection c) throws Exception +{ + return stateMachine( + "remove example and saxon jars", + null, + + Stream.concat( + Node.removeJar(c, "examples", true), + Node.removeJar(c, "saxon", false) + ) + .flatMap(Node::semiFlattenDiagnostics) + .peek(Node::peek), + + (o,p,q) -> isDiagnostic(o, Set.of("error")) ? 1 : -2, + (o,p,q) -> isVoidResultSet(o, 1, 1) ? 3 : false, + + (o,p,q) -> isDiagnostic(o, Set.of("error")) ? 3 : -4, + (o,p,q) -> isVoidResultSet(o, 1, 1) ? 5 : false, + + (o,p,q) -> null == o + ); +} + int pgMajorVersion; diff --git a/CI/integration b/CI/integration index 7690cd8e2..920eba303 100644 --- a/CI/integration +++ b/CI/integration @@ -205,18 +205,27 @@ try ( /* * Also confirm that the generated undeploy actions work. */ - succeeding &= stateMachine( - "remove jar void result", - null, + unloadExamples(c); - q(c, "SELECT sqlj.remove_jar('examples', true)") - .flatMap(Node::semiFlattenDiagnostics) - .peek(Node::peek), + /* + * Repeat the regression tests with check_function_bodies off (issue 544). + */ + try ( Connection c2 = n1.connect() ) + { + succeeding &= stateMachine( + "check_function_bodies off", + null, - (o,p,q) -> isDiagnostic(o, Set.of("error")) ? 1 : -2, - (o,p,q) -> isVoidResultSet(o, 1, 1) ? 3 : false, - (o,p,q) -> null == o - ); + q(c2, "SET check_function_bodies TO off") + .flatMap(Node::semiFlattenDiagnostics) + .peek(Node::peek), + + (o,p,q) -> isDiagnostic(o, Set.of("error")) ? 1 : -2, + NOTHING_OR_PGJDBC_ZERO_COUNT, + (o,p,q) -> null == o + ); + succeeding &= loadExamplesAndTest(c2) && unloadExamples(c2); + } /* * Get another new connection and make sure the extension can be diff --git a/pljava-so/src/main/c/Function.c b/pljava-so/src/main/c/Function.c index 891591a6e..1913ece84 100644 --- a/pljava-so/src/main/c/Function.c +++ b/pljava-so/src/main/c/Function.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2004-2025 Tada AB and other contributors, as listed below. + * Copyright (c) 2004-2026 Tada AB and other contributors, as listed below. * * All rights reserved. This program and the accompanying materials * are made available under the terms of the The BSD 3-Clause License @@ -789,6 +789,7 @@ static Function Function_create( funcOid); } + Invocation_assertDisconnect(); /* func may make its own connection */ return self; } From 23401dfb931ea9cb696dc5b29d5d9ebf0beda6e4 Mon Sep 17 00:00:00 2001 From: Chapman Flack Date: Wed, 12 Aug 2026 17:57:04 -0400 Subject: [PATCH 2/2] ci: try to re-run only expected workflows The failing run on initial creation of this PR was from a CI system that should not even have been activated for this PR.