diff --git a/postgresql-15.0-llvm_pointer.patch b/postgresql-15.0-llvm_pointer.patch new file mode 100644 index 0000000..d9a06cd --- /dev/null +++ b/postgresql-15.0-llvm_pointer.patch @@ -0,0 +1,191 @@ +# From 0fed706031df781bb5889a859c47379e3c37f4f4 Mon Sep 17 00:00:00 2001 +# From: Thomas Munro +# Date: Thu, 22 Sep 2022 23:38:56 +1200 +# Subject: [PATCH v2] WIP: jit: LLVM 15: Minimal changes. + +# Per https://llvm.org/docs/OpaquePointers.html, support for non-opaque +# pointers still exists and we can request that on our context. We have +# until LLVM 16 to move to opaque pointers. +# --- +# src/backend/jit/llvm/llvmjit.c | 18 +++++++ +# src/backend/jit/llvm/meson.build | 3 ++ +# configure | 89 ++++++++++++++++++++++++++++++++ +# configure.ac | 3 ++ +# 4 files changed, 113 insertions(+) + +diff --git a/src/backend/jit/llvm/llvmjit.c b/src/backend/jit/llvm/llvmjit.c +index fd3eecf27d3..bccfcfa9698 100644 +--- a/src/backend/jit/llvm/llvmjit.c ++++ b/src/backend/jit/llvm/llvmjit.c +@@ -798,6 +798,16 @@ llvm_session_initialize(void) + LLVMInitializeNativeAsmPrinter(); + LLVMInitializeNativeAsmParser(); + ++ /* ++ * When targetting an llvm version with opaque pointers enabled by ++ * default, turn them off for the context we build our code in. Don't need ++ * to do so for other contexts (e.g. llvm_ts_context) - once the IR is ++ * generated, it carries the necessary information. ++ */ ++#if LLVM_VERSION_MAJOR > 14 ++ LLVMContextSetOpaquePointers(LLVMGetGlobalContext(), false); ++#endif ++ + /* + * Synchronize types early, as that also includes inferring the target + * triple. +@@ -1112,7 +1122,11 @@ llvm_resolve_symbols(LLVMOrcDefinitionGeneratorRef GeneratorObj, void *Ctx, + LLVMOrcJITDylibRef JD, LLVMOrcJITDylibLookupFlags JDLookupFlags, + LLVMOrcCLookupSet LookupSet, size_t LookupSetSize) + { ++#if LLVM_VERSION_MAJOR > 14 ++ LLVMOrcCSymbolMapPairs symbols = palloc0(sizeof(LLVMOrcCSymbolMapPair) * LookupSetSize); ++#else + LLVMOrcCSymbolMapPairs symbols = palloc0(sizeof(LLVMJITCSymbolMapPair) * LookupSetSize); ++#endif + LLVMErrorRef error; + LLVMOrcMaterializationUnitRef mu; + +@@ -1230,7 +1244,11 @@ llvm_create_jit_instance(LLVMTargetMachineRef tm) + * Symbol resolution support for "special" functions, e.g. a call into an + * SQL callable function. + */ ++#if LLVM_VERSION_MAJOR > 14 ++ ref_gen = LLVMOrcCreateCustomCAPIDefinitionGenerator(llvm_resolve_symbols, NULL, NULL); ++#else + ref_gen = LLVMOrcCreateCustomCAPIDefinitionGenerator(llvm_resolve_symbols, NULL); ++#endif + LLVMOrcJITDylibAddGenerator(LLVMOrcLLJITGetMainJITDylib(lljit), ref_gen); + + return lljit; +# diff --git a/src/backend/jit/llvm/meson.build b/src/backend/jit/llvm/meson.build +# index de2e624ab58..e5a702163b7 100644 +# --- a/src/backend/jit/llvm/meson.build +# +++ b/src/backend/jit/llvm/meson.build +# @@ -51,6 +51,9 @@ endif + +# # XXX: Need to determine proper version of the function cflags for clang +# bitcode_cflags = ['-fno-strict-aliasing', '-fwrapv'] +# +if llvm.version().version_compare('>=15.0') +# + bitcode_cflags += ['-Xclang', '-no-opaque-pointers'] +# +endif +# bitcode_cflags += cppflags + + # XXX: Worth improving on the logic to find directories here +diff --git a/configure b/configure +index 1caca21b625..cf457a0ed4a 100755 +--- a/configure ++++ b/configure +@@ -7391,6 +7391,95 @@ if test x"$pgac_cv_prog_CLANGXX_cxxflags__fexcess_precision_standard" = x"yes"; + fi + + ++ { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether ${CLANG} supports -Xclang -no-opaque-pointers, for BITCODE_CFLAGS" >&5 ++$as_echo_n "checking whether ${CLANG} supports -Xclang -no-opaque-pointers, for BITCODE_CFLAGS... " >&6; } ++if ${pgac_cv_prog_CLANG_cflags__Xclang__no_opaque_pointers+:} false; then : ++ $as_echo_n "(cached) " >&6 ++else ++ pgac_save_CFLAGS=$CFLAGS ++pgac_save_CC=$CC ++CC=${CLANG} ++CFLAGS="${BITCODE_CFLAGS} -Xclang -no-opaque-pointers" ++ac_save_c_werror_flag=$ac_c_werror_flag ++ac_c_werror_flag=yes ++cat confdefs.h - <<_ACEOF >conftest.$ac_ext ++/* end confdefs.h. */ ++ ++int ++main () ++{ ++ ++ ; ++ return 0; ++} ++_ACEOF ++if ac_fn_c_try_compile "$LINENO"; then : ++ pgac_cv_prog_CLANG_cflags__Xclang__no_opaque_pointers=yes ++else ++ pgac_cv_prog_CLANG_cflags__Xclang__no_opaque_pointers=no ++fi ++rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext ++ac_c_werror_flag=$ac_save_c_werror_flag ++CFLAGS="$pgac_save_CFLAGS" ++CC="$pgac_save_CC" ++fi ++{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $pgac_cv_prog_CLANG_cflags__Xclang__no_opaque_pointers" >&5 ++$as_echo "$pgac_cv_prog_CLANG_cflags__Xclang__no_opaque_pointers" >&6; } ++if test x"$pgac_cv_prog_CLANG_cflags__Xclang__no_opaque_pointers" = x"yes"; then ++ BITCODE_CFLAGS="${BITCODE_CFLAGS} -Xclang -no-opaque-pointers" ++fi ++ ++ { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether ${CLANGXX} supports -Xclang -no-opaque-pointers, for BITCODE_CXXFLAGS" >&5 ++$as_echo_n "checking whether ${CLANGXX} supports -Xclang -no-opaque-pointers, for BITCODE_CXXFLAGS... " >&6; } ++if ${pgac_cv_prog_CLANGXX_cxxflags__Xclang__no_opaque_pointers+:} false; then : ++ $as_echo_n "(cached) " >&6 ++else ++ pgac_save_CXXFLAGS=$CXXFLAGS ++pgac_save_CXX=$CXX ++CXX=${CLANGXX} ++CXXFLAGS="${BITCODE_CXXFLAGS} -Xclang -no-opaque-pointers" ++ac_save_cxx_werror_flag=$ac_cxx_werror_flag ++ac_cxx_werror_flag=yes ++ac_ext=cpp ++ac_cpp='$CXXCPP $CPPFLAGS' ++ac_compile='$CXX -c $CXXFLAGS $CPPFLAGS conftest.$ac_ext >&5' ++ac_link='$CXX -o conftest$ac_exeext $CXXFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' ++ac_compiler_gnu=$ac_cv_cxx_compiler_gnu ++ ++cat confdefs.h - <<_ACEOF >conftest.$ac_ext ++/* end confdefs.h. */ ++ ++int ++main () ++{ ++ ++ ; ++ return 0; ++} ++_ACEOF ++if ac_fn_cxx_try_compile "$LINENO"; then : ++ pgac_cv_prog_CLANGXX_cxxflags__Xclang__no_opaque_pointers=yes ++else ++ pgac_cv_prog_CLANGXX_cxxflags__Xclang__no_opaque_pointers=no ++fi ++rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext ++ac_ext=c ++ac_cpp='$CPP $CPPFLAGS' ++ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' ++ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' ++ac_compiler_gnu=$ac_cv_c_compiler_gnu ++ ++ac_cxx_werror_flag=$ac_save_cxx_werror_flag ++CXXFLAGS="$pgac_save_CXXFLAGS" ++CXX="$pgac_save_CXX" ++fi ++{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $pgac_cv_prog_CLANGXX_cxxflags__Xclang__no_opaque_pointers" >&5 ++$as_echo "$pgac_cv_prog_CLANGXX_cxxflags__Xclang__no_opaque_pointers" >&6; } ++if test x"$pgac_cv_prog_CLANGXX_cxxflags__Xclang__no_opaque_pointers" = x"yes"; then ++ BITCODE_CXXFLAGS="${BITCODE_CXXFLAGS} -Xclang -no-opaque-pointers" ++fi ++ ++ + NOT_THE_CFLAGS="" + { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether ${CLANG} supports -Wunused-command-line-argument, for NOT_THE_CFLAGS" >&5 + $as_echo_n "checking whether ${CLANG} supports -Wunused-command-line-argument, for NOT_THE_CFLAGS... " >&6; } +diff --git a/configure.ac b/configure.ac +index 10fa55dd154..ecc6c495db9 100644 +--- a/configure.ac ++++ b/configure.ac +@@ -625,6 +625,9 @@ if test "$with_llvm" = yes ; then + PGAC_PROG_VARCC_VARFLAGS_OPT(CLANG, BITCODE_CFLAGS, [-fexcess-precision=standard]) + PGAC_PROG_VARCXX_VARFLAGS_OPT(CLANGXX, BITCODE_CXXFLAGS, [-fexcess-precision=standard]) + ++ PGAC_PROG_VARCC_VARFLAGS_OPT(CLANG, BITCODE_CFLAGS, [-Xclang -no-opaque-pointers]) ++ PGAC_PROG_VARCXX_VARFLAGS_OPT(CLANGXX, BITCODE_CXXFLAGS, [-Xclang -no-opaque-pointers]) ++ + NOT_THE_CFLAGS="" + PGAC_PROG_VARCC_VARFLAGS_OPT(CLANG, NOT_THE_CFLAGS, [-Wunused-command-line-argument]) + if test -n "$NOT_THE_CFLAGS"; then +-- +2.37.3.542.gdd3f6c4cae + diff --git a/postgresql-SPI-s-handling-of-errors-during-transaction-comm.patch b/postgresql-SPI-s-handling-of-errors-during-transaction-comm.patch deleted file mode 100644 index 6b7ecdd..0000000 --- a/postgresql-SPI-s-handling-of-errors-during-transaction-comm.patch +++ /dev/null @@ -1,1096 +0,0 @@ -From 2e517818f4af4abe93bf56442469944544f10d4b Mon Sep 17 00:00:00 2001 -From: Tom Lane -Date: Mon, 28 Feb 2022 12:45:36 -0500 -Subject: [PATCH] Fix SPI's handling of errors during transaction commit. - -SPI_commit previously left it up to the caller to recover from any error -occurring during commit. Since that's complicated and requires use of -low-level xact.c facilities, it's not too surprising that no caller got -it right. Let's move the responsibility for cleanup into spi.c. Doing -that requires redefining SPI_commit as starting a new transaction, so -that it becomes equivalent to SPI_commit_and_chain except that you get -default transaction characteristics instead of preserving the prior -transaction's characteristics. We can make this pretty transparent -API-wise by redefining SPI_start_transaction() as a no-op. Callers -that expect to do something in between might be surprised, but -available evidence is that no callers do so. - -Having made that API redefinition, we can fix this mess by having -SPI_commit[_and_chain] trap errors and start a new, clean transaction -before re-throwing the error. Likewise for SPI_rollback[_and_chain]. -Some cleanup is also needed in AtEOXact_SPI, which was nowhere near -smart enough to deal with SPI contexts nested inside a committing -context. - -While plperl and pltcl need no changes beyond removing their now-useless -SPI_start_transaction() calls, plpython needs some more work because it -hadn't gotten the memo about catching commit/rollback errors in the -first place. Such an error resulted in longjmp'ing out of the Python -interpreter, which leaks Python stack entries at present and is reported -to crash Python 3.11 altogether. Add the missing logic to catch such -errors and convert them into Python exceptions. - -We are probably going to have to back-patch this once Python 3.11 ships, -but it's a sufficiently basic change that I'm a bit nervous about doing -so immediately. Let's let it bake awhile in HEAD first. - -Peter Eisentraut and Tom Lane - -Discussion: https://postgr.es/m/3375ffd8-d71c-2565-e348-a597d6e739e3@enterprisedb.com -Discussion: https://postgr.es/m/17416-ed8fe5d7213d6c25@postgresql.org ---- - doc/src/sgml/spi.sgml | 51 ++-- - src/backend/executor/spi.c | 221 +++++++++++++----- - src/backend/tcop/postgres.c | 2 - - src/backend/utils/mmgr/portalmem.c | 2 +- - src/include/executor/spi.h | 1 - - src/pl/plperl/expected/plperl_transaction.out | 48 ++++ - src/pl/plperl/plperl.c | 2 - - src/pl/plperl/sql/plperl_transaction.sql | 32 +++ - src/pl/plpgsql/src/pl_exec.c | 6 - - .../expected/plpython_transaction.out | 67 +++++- - src/pl/plpython/plpy_plpymodule.c | 30 --- - src/pl/plpython/plpy_spi.c | 94 ++++++++ - src/pl/plpython/plpy_spi.h | 3 + - src/pl/plpython/sql/plpython_transaction.sql | 30 +++ - src/pl/tcl/expected/pltcl_transaction.out | 49 ++++ - src/pl/tcl/pltcl.c | 2 - - src/pl/tcl/sql/pltcl_transaction.sql | 37 +++ - 17 files changed, 535 insertions(+), 142 deletions(-) - -diff --git a/doc/src/sgml/spi.sgml b/doc/src/sgml/spi.sgml -index d710e2d0df..7581661fc4 100644 ---- a/doc/src/sgml/spi.sgml -+++ b/doc/src/sgml/spi.sgml -@@ -99,10 +99,9 @@ int SPI_connect_ext(int options) - - - Sets the SPI connection to be nonatomic, which -- means that transaction control calls SPI_commit, -- SPI_rollback, and -- SPI_start_transaction are allowed. Otherwise, -- calling these functions will result in an immediate error. -+ means that transaction control calls (SPI_commit, -+ SPI_rollback) are allowed. Otherwise, -+ calling those functions will result in an immediate error. - - - -@@ -5040,15 +5039,17 @@ void SPI_commit_and_chain(void) - - SPI_commit commits the current transaction. It is - approximately equivalent to running the SQL -- command COMMIT. After a transaction is committed, a new -- transaction has to be started -- using SPI_start_transaction before further database -- actions can be executed. -+ command COMMIT. After the transaction is committed, a -+ new transaction is automatically started using default transaction -+ characteristics, so that the caller can continue using SPI facilities. -+ If there is a failure during commit, the current transaction is instead -+ rolled back and a new transaction is started, after which the error is -+ thrown in the usual way. - - - -- SPI_commit_and_chain is the same, but a new -- transaction is immediately started with the same transaction -+ SPI_commit_and_chain is the same, but the new -+ transaction is started with the same transaction - characteristics as the just finished one, like with the SQL command - COMMIT AND CHAIN. - -@@ -5093,14 +5094,13 @@ void SPI_rollback_and_chain(void) - - SPI_rollback rolls back the current transaction. It - is approximately equivalent to running the SQL -- command ROLLBACK. After a transaction is rolled back, a -- new transaction has to be started -- using SPI_start_transaction before further database -- actions can be executed. -+ command ROLLBACK. After the transaction is rolled back, -+ a new transaction is automatically started using default transaction -+ characteristics, so that the caller can continue using SPI facilities. - - -- SPI_rollback_and_chain is the same, but a new -- transaction is immediately started with the same transaction -+ SPI_rollback_and_chain is the same, but the new -+ transaction is started with the same transaction - characteristics as the just finished one, like with the SQL command - ROLLBACK AND CHAIN. - -@@ -5124,7 +5124,7 @@ void SPI_rollback_and_chain(void) - - - SPI_start_transaction -- start a new transaction -+ obsolete function - - - -@@ -5137,17 +5137,12 @@ void SPI_start_transaction(void) - Description - - -- SPI_start_transaction starts a new transaction. It -- can only be called after SPI_commit -- or SPI_rollback, as there is no transaction active at -- that point. Normally, when an SPI-using procedure is called, there is already a -- transaction active, so attempting to start another one before closing out -- the current one will result in an error. -- -- -- -- This function can only be executed if the SPI connection has been set as -- nonatomic in the call to SPI_connect_ext. -+ SPI_start_transaction does nothing, and exists -+ only for code compatibility with -+ earlier PostgreSQL releases. It used to -+ be required after calling SPI_commit -+ or SPI_rollback, but now those functions start -+ a new transaction automatically. - - - -diff --git a/src/backend/executor/spi.c b/src/backend/executor/spi.c -index c93f90de9b..7971050746 100644 ---- a/src/backend/executor/spi.c -+++ b/src/backend/executor/spi.c -@@ -156,7 +156,8 @@ SPI_connect_ext(int options) - * XXX It could be better to use PortalContext as the parent context in - * all cases, but we may not be inside a portal (consider deferred-trigger - * execution). Perhaps CurTransactionContext could be an option? For now -- * it doesn't matter because we clean up explicitly in AtEOSubXact_SPI(). -+ * it doesn't matter because we clean up explicitly in AtEOSubXact_SPI(); -+ * but see also AtEOXact_SPI(). - */ - _SPI_current->procCxt = AllocSetContextCreate(_SPI_current->atomic ? TopTransactionContext : PortalContext, - "SPI Proc", -@@ -214,13 +215,13 @@ SPI_finish(void) - return SPI_OK_FINISH; - } - -+/* -+ * SPI_start_transaction is a no-op, kept for backwards compatibility. -+ * SPI callers are *always* inside a transaction. -+ */ - void - SPI_start_transaction(void) - { -- MemoryContext oldcontext = CurrentMemoryContext; -- -- StartTransactionCommand(); -- MemoryContextSwitchTo(oldcontext); - } - - static void -@@ -228,6 +229,12 @@ _SPI_commit(bool chain) - { - MemoryContext oldcontext = CurrentMemoryContext; - -+ /* -+ * Complain if we are in a context that doesn't permit transaction -+ * termination. (Note: here and _SPI_rollback should be the only places -+ * that throw ERRCODE_INVALID_TRANSACTION_TERMINATION, so that callers can -+ * test for that with security that they know what happened.) -+ */ - if (_SPI_current->atomic) - ereport(ERROR, - (errcode(ERRCODE_INVALID_TRANSACTION_TERMINATION), -@@ -240,40 +247,74 @@ _SPI_commit(bool chain) - * top-level transaction in such a block violates that idea. A future PL - * implementation might have different ideas about this, in which case - * this restriction would have to be refined or the check possibly be -- * moved out of SPI into the PLs. -+ * moved out of SPI into the PLs. Note however that the code below relies -+ * on not being within a subtransaction. - */ - if (IsSubTransaction()) - ereport(ERROR, - (errcode(ERRCODE_INVALID_TRANSACTION_TERMINATION), - errmsg("cannot commit while a subtransaction is active"))); - -- /* -- * Hold any pinned portals that any PLs might be using. We have to do -- * this before changing transaction state, since this will run -- * user-defined code that might throw an error. -- */ -- HoldPinnedPortals(); -+ /* XXX this ain't re-entrant enough for my taste */ -+ if (chain) -+ SaveTransactionCharacteristics(); - -- /* Start the actual commit */ -- _SPI_current->internal_xact = true; -+ /* Catch any error occurring during the COMMIT */ -+ PG_TRY(); -+ { -+ /* Protect current SPI stack entry against deletion */ -+ _SPI_current->internal_xact = true; - -- /* Release snapshots associated with portals */ -- ForgetPortalSnapshots(); -+ /* -+ * Hold any pinned portals that any PLs might be using. We have to do -+ * this before changing transaction state, since this will run -+ * user-defined code that might throw an error. -+ */ -+ HoldPinnedPortals(); - -- if (chain) -- SaveTransactionCharacteristics(); -+ /* Release snapshots associated with portals */ -+ ForgetPortalSnapshots(); - -- CommitTransactionCommand(); -+ /* Do the deed */ -+ CommitTransactionCommand(); - -- if (chain) -- { -+ /* Immediately start a new transaction */ - StartTransactionCommand(); -- RestoreTransactionCharacteristics(); -+ if (chain) -+ RestoreTransactionCharacteristics(); -+ -+ MemoryContextSwitchTo(oldcontext); -+ -+ _SPI_current->internal_xact = false; - } -+ PG_CATCH(); -+ { -+ ErrorData *edata; - -- MemoryContextSwitchTo(oldcontext); -+ /* Save error info in caller's context */ -+ MemoryContextSwitchTo(oldcontext); -+ edata = CopyErrorData(); -+ FlushErrorState(); - -- _SPI_current->internal_xact = false; -+ /* -+ * Abort the failed transaction. If this fails too, we'll just -+ * propagate the error out ... there's not that much we can do. -+ */ -+ AbortCurrentTransaction(); -+ -+ /* ... and start a new one */ -+ StartTransactionCommand(); -+ if (chain) -+ RestoreTransactionCharacteristics(); -+ -+ MemoryContextSwitchTo(oldcontext); -+ -+ _SPI_current->internal_xact = false; -+ -+ /* Now that we've cleaned up the transaction, re-throw the error */ -+ ReThrowError(edata); -+ } -+ PG_END_TRY(); - } - - void -@@ -293,6 +334,7 @@ _SPI_rollback(bool chain) - { - MemoryContext oldcontext = CurrentMemoryContext; - -+ /* see under SPI_commit() */ - if (_SPI_current->atomic) - ereport(ERROR, - (errcode(ERRCODE_INVALID_TRANSACTION_TERMINATION), -@@ -304,34 +346,68 @@ _SPI_rollback(bool chain) - (errcode(ERRCODE_INVALID_TRANSACTION_TERMINATION), - errmsg("cannot roll back while a subtransaction is active"))); - -- /* -- * Hold any pinned portals that any PLs might be using. We have to do -- * this before changing transaction state, since this will run -- * user-defined code that might throw an error, and in any case couldn't -- * be run in an already-aborted transaction. -- */ -- HoldPinnedPortals(); -+ /* XXX this ain't re-entrant enough for my taste */ -+ if (chain) -+ SaveTransactionCharacteristics(); - -- /* Start the actual rollback */ -- _SPI_current->internal_xact = true; -+ /* Catch any error occurring during the ROLLBACK */ -+ PG_TRY(); -+ { -+ /* Protect current SPI stack entry against deletion */ -+ _SPI_current->internal_xact = true; - -- /* Release snapshots associated with portals */ -- ForgetPortalSnapshots(); -+ /* -+ * Hold any pinned portals that any PLs might be using. We have to do -+ * this before changing transaction state, since this will run -+ * user-defined code that might throw an error, and in any case -+ * couldn't be run in an already-aborted transaction. -+ */ -+ HoldPinnedPortals(); - -- if (chain) -- SaveTransactionCharacteristics(); -+ /* Release snapshots associated with portals */ -+ ForgetPortalSnapshots(); - -- AbortCurrentTransaction(); -+ /* Do the deed */ -+ AbortCurrentTransaction(); - -- if (chain) -- { -+ /* Immediately start a new transaction */ - StartTransactionCommand(); -- RestoreTransactionCharacteristics(); -+ if (chain) -+ RestoreTransactionCharacteristics(); -+ -+ MemoryContextSwitchTo(oldcontext); -+ -+ _SPI_current->internal_xact = false; - } -+ PG_CATCH(); -+ { -+ ErrorData *edata; - -- MemoryContextSwitchTo(oldcontext); -+ /* Save error info in caller's context */ -+ MemoryContextSwitchTo(oldcontext); -+ edata = CopyErrorData(); -+ FlushErrorState(); - -- _SPI_current->internal_xact = false; -+ /* -+ * Try again to abort the failed transaction. If this fails too, -+ * we'll just propagate the error out ... there's not that much we can -+ * do. -+ */ -+ AbortCurrentTransaction(); -+ -+ /* ... and start a new one */ -+ StartTransactionCommand(); -+ if (chain) -+ RestoreTransactionCharacteristics(); -+ -+ MemoryContextSwitchTo(oldcontext); -+ -+ _SPI_current->internal_xact = false; -+ -+ /* Now that we've cleaned up the transaction, re-throw the error */ -+ ReThrowError(edata); -+ } -+ PG_END_TRY(); - } - - void -@@ -346,38 +422,55 @@ SPI_rollback_and_chain(void) - _SPI_rollback(true); - } - --/* -- * Clean up SPI state. Called on transaction end (of non-SPI-internal -- * transactions) and when returning to the main loop on error. -- */ --void --SPICleanup(void) --{ -- _SPI_current = NULL; -- _SPI_connected = -1; -- /* Reset API global variables, too */ -- SPI_processed = 0; -- SPI_tuptable = NULL; -- SPI_result = 0; --} -- - /* - * Clean up SPI state at transaction commit or abort. - */ - void - AtEOXact_SPI(bool isCommit) - { -- /* Do nothing if the transaction end was initiated by SPI. */ -- if (_SPI_current && _SPI_current->internal_xact) -- return; -+ bool found = false; - -- if (isCommit && _SPI_connected != -1) -+ /* -+ * Pop stack entries, stopping if we find one marked internal_xact (that -+ * one belongs to the caller of SPI_commit or SPI_abort). -+ */ -+ while (_SPI_connected >= 0) -+ { -+ _SPI_connection *connection = &(_SPI_stack[_SPI_connected]); -+ -+ if (connection->internal_xact) -+ break; -+ -+ found = true; -+ -+ /* -+ * We need not release the procedure's memory contexts explicitly, as -+ * they'll go away automatically when their parent context does; see -+ * notes in SPI_connect_ext. -+ */ -+ -+ /* -+ * Restore outer global variables and pop the stack entry. Unlike -+ * SPI_finish(), we don't risk switching to memory contexts that might -+ * be already gone. -+ */ -+ SPI_processed = connection->outer_processed; -+ SPI_tuptable = connection->outer_tuptable; -+ SPI_result = connection->outer_result; -+ -+ _SPI_connected--; -+ if (_SPI_connected < 0) -+ _SPI_current = NULL; -+ else -+ _SPI_current = &(_SPI_stack[_SPI_connected]); -+ } -+ -+ /* We should only find entries to pop during an ABORT. */ -+ if (found && isCommit) - ereport(WARNING, - (errcode(ERRCODE_WARNING), - errmsg("transaction left non-empty SPI stack"), - errhint("Check for missing \"SPI_finish\" calls."))); -- -- SPICleanup(); - } - - /* -diff --git a/src/backend/tcop/postgres.c b/src/backend/tcop/postgres.c -index 3c7d08209f..34c13a1113 100644 ---- a/src/backend/tcop/postgres.c -+++ b/src/backend/tcop/postgres.c -@@ -42,7 +42,6 @@ - #include "catalog/pg_type.h" - #include "commands/async.h" - #include "commands/prepare.h" --#include "executor/spi.h" - #include "jit/jit.h" - #include "libpq/libpq.h" - #include "libpq/pqformat.h" -@@ -4253,7 +4252,6 @@ PostgresMain(int argc, char *argv[], - WalSndErrorCleanup(); - - PortalErrorCleanup(); -- SPICleanup(); - - /* - * We can't release replication slots inside AbortTransaction() as we -diff --git a/src/backend/utils/mmgr/portalmem.c b/src/backend/utils/mmgr/portalmem.c -index 21ad87c024..afc03682d9 100644 ---- a/src/backend/utils/mmgr/portalmem.c -+++ b/src/backend/utils/mmgr/portalmem.c -@@ -1261,7 +1261,7 @@ HoldPinnedPortals(void) - */ - if (portal->strategy != PORTAL_ONE_SELECT) - ereport(ERROR, -- (errcode(ERRCODE_INVALID_TRANSACTION_TERMINATION), -+ (errcode(ERRCODE_OBJECT_NOT_IN_PREREQUISITE_STATE), - errmsg("cannot perform transaction commands inside a cursor loop that is not read-only"))); - - /* Verify it's in a suitable state to be held */ -diff --git a/src/include/executor/spi.h b/src/include/executor/spi.h -index e20e7df780..6ec3851444 100644 ---- a/src/include/executor/spi.h -+++ b/src/include/executor/spi.h -@@ -205,7 +205,6 @@ extern void SPI_commit_and_chain(void); - extern void SPI_rollback(void); - extern void SPI_rollback_and_chain(void); - --extern void SPICleanup(void); - extern void AtEOXact_SPI(bool isCommit); - extern void AtEOSubXact_SPI(bool isCommit, SubTransactionId mySubid); - extern bool SPI_inside_nonatomic_context(void); -diff --git a/src/pl/plperl/expected/plperl_transaction.out b/src/pl/plperl/expected/plperl_transaction.out -index 7ca0ef35fb..da4283cbce 100644 ---- a/src/pl/plperl/expected/plperl_transaction.out -+++ b/src/pl/plperl/expected/plperl_transaction.out -@@ -192,5 +192,53 @@ SELECT * FROM pg_cursors; - ------+-----------+-------------+-----------+---------------+--------------- - (0 rows) - -+-- check handling of an error during COMMIT -+CREATE TABLE testpk (id int PRIMARY KEY); -+CREATE TABLE testfk(f1 int REFERENCES testpk DEFERRABLE INITIALLY DEFERRED); -+DO LANGUAGE plperl $$ -+# this insert will fail during commit: -+spi_exec_query("INSERT INTO testfk VALUES (0)"); -+spi_commit(); -+elog(WARNING, 'should not get here'); -+$$; -+ERROR: insert or update on table "testfk" violates foreign key constraint "testfk_f1_fkey" at line 4. -+CONTEXT: PL/Perl anonymous code block -+SELECT * FROM testpk; -+ id -+---- -+(0 rows) -+ -+SELECT * FROM testfk; -+ f1 -+---- -+(0 rows) -+ -+DO LANGUAGE plperl $$ -+# this insert will fail during commit: -+spi_exec_query("INSERT INTO testfk VALUES (0)"); -+eval { -+ spi_commit(); -+}; -+if ($@) { -+ elog(INFO, $@); -+} -+# these inserts should work: -+spi_exec_query("INSERT INTO testpk VALUES (1)"); -+spi_exec_query("INSERT INTO testfk VALUES (1)"); -+$$; -+INFO: insert or update on table "testfk" violates foreign key constraint "testfk_f1_fkey" at line 5. -+ -+SELECT * FROM testpk; -+ id -+---- -+ 1 -+(1 row) -+ -+SELECT * FROM testfk; -+ f1 -+---- -+ 1 -+(1 row) -+ - DROP TABLE test1; - DROP TABLE test2; -diff --git a/src/pl/plperl/plperl.c b/src/pl/plperl/plperl.c -index 81bb480bc2..edb93ec1c4 100644 ---- a/src/pl/plperl/plperl.c -+++ b/src/pl/plperl/plperl.c -@@ -3986,7 +3986,6 @@ plperl_spi_commit(void) - PG_TRY(); - { - SPI_commit(); -- SPI_start_transaction(); - } - PG_CATCH(); - { -@@ -4013,7 +4012,6 @@ plperl_spi_rollback(void) - PG_TRY(); - { - SPI_rollback(); -- SPI_start_transaction(); - } - PG_CATCH(); - { -diff --git a/src/pl/plperl/sql/plperl_transaction.sql b/src/pl/plperl/sql/plperl_transaction.sql -index 0a60799805..d10c8bee89 100644 ---- a/src/pl/plperl/sql/plperl_transaction.sql -+++ b/src/pl/plperl/sql/plperl_transaction.sql -@@ -159,5 +159,37 @@ SELECT * FROM test1; - SELECT * FROM pg_cursors; - - -+-- check handling of an error during COMMIT -+CREATE TABLE testpk (id int PRIMARY KEY); -+CREATE TABLE testfk(f1 int REFERENCES testpk DEFERRABLE INITIALLY DEFERRED); -+ -+DO LANGUAGE plperl $$ -+# this insert will fail during commit: -+spi_exec_query("INSERT INTO testfk VALUES (0)"); -+spi_commit(); -+elog(WARNING, 'should not get here'); -+$$; -+ -+SELECT * FROM testpk; -+SELECT * FROM testfk; -+ -+DO LANGUAGE plperl $$ -+# this insert will fail during commit: -+spi_exec_query("INSERT INTO testfk VALUES (0)"); -+eval { -+ spi_commit(); -+}; -+if ($@) { -+ elog(INFO, $@); -+} -+# these inserts should work: -+spi_exec_query("INSERT INTO testpk VALUES (1)"); -+spi_exec_query("INSERT INTO testfk VALUES (1)"); -+$$; -+ -+SELECT * FROM testpk; -+SELECT * FROM testfk; -+ -+ - DROP TABLE test1; - DROP TABLE test2; -diff --git a/src/pl/plpgsql/src/pl_exec.c b/src/pl/plpgsql/src/pl_exec.c -index 9674c29250..915139378e 100644 ---- a/src/pl/plpgsql/src/pl_exec.c -+++ b/src/pl/plpgsql/src/pl_exec.c -@@ -4916,10 +4916,7 @@ exec_stmt_commit(PLpgSQL_execstate *estate, PLpgSQL_stmt_commit *stmt) - if (stmt->chain) - SPI_commit_and_chain(); - else -- { - SPI_commit(); -- SPI_start_transaction(); -- } - - /* - * We need to build new simple-expression infrastructure, since the old -@@ -4943,10 +4940,7 @@ exec_stmt_rollback(PLpgSQL_execstate *estate, PLpgSQL_stmt_rollback *stmt) - if (stmt->chain) - SPI_rollback_and_chain(); - else -- { - SPI_rollback(); -- SPI_start_transaction(); -- } - - /* - * We need to build new simple-expression infrastructure, since the old -diff --git a/src/pl/plpython/expected/plpython_transaction.out b/src/pl/plpython/expected/plpython_transaction.out -index 14152993c7..72d1e45a76 100644 ---- a/src/pl/plpython/expected/plpython_transaction.out -+++ b/src/pl/plpython/expected/plpython_transaction.out -@@ -55,8 +55,11 @@ for i in range(0, 10): - return 1 - $$; - SELECT transaction_test2(); --ERROR: invalid transaction termination --CONTEXT: PL/Python function "transaction_test2" -+ERROR: spiexceptions.InvalidTransactionTermination: invalid transaction termination -+CONTEXT: Traceback (most recent call last): -+ PL/Python function "transaction_test2", line 5, in -+ plpy.commit() -+PL/Python function "transaction_test2" - SELECT * FROM test1; - a | b - ---+--- -@@ -70,7 +73,7 @@ plpy.execute("CALL transaction_test1()") - return 1 - $$; - SELECT transaction_test3(); --ERROR: spiexceptions.InvalidTransactionTermination: invalid transaction termination -+ERROR: spiexceptions.InvalidTransactionTermination: spiexceptions.InvalidTransactionTermination: invalid transaction termination - CONTEXT: Traceback (most recent call last): - PL/Python function "transaction_test3", line 2, in - plpy.execute("CALL transaction_test1()") -@@ -88,7 +91,7 @@ plpy.execute("DO LANGUAGE plpythonu $x$ plpy.commit() $x$") - return 1 - $$; - SELECT transaction_test4(); --ERROR: spiexceptions.InvalidTransactionTermination: invalid transaction termination -+ERROR: spiexceptions.InvalidTransactionTermination: spiexceptions.InvalidTransactionTermination: invalid transaction termination - CONTEXT: Traceback (most recent call last): - PL/Python function "transaction_test4", line 2, in - plpy.execute("DO LANGUAGE plpythonu $x$ plpy.commit() $x$") -@@ -100,8 +103,11 @@ s.enter() - plpy.commit() - $$; - WARNING: forcibly aborting a subtransaction that has not been exited --ERROR: cannot commit while a subtransaction is active --CONTEXT: PL/Python anonymous code block -+ERROR: spiexceptions.InvalidTransactionTermination: cannot commit while a subtransaction is active -+CONTEXT: Traceback (most recent call last): -+ PL/Python anonymous code block, line 4, in -+ plpy.commit() -+PL/Python anonymous code block - -- commit inside cursor loop - CREATE TABLE test2 (x int); - INSERT INTO test2 VALUES (0), (1), (2), (3), (4); -@@ -191,5 +197,54 @@ SELECT * FROM pg_cursors; - ------+-----------+-------------+-----------+---------------+--------------- - (0 rows) - -+-- check handling of an error during COMMIT -+CREATE TABLE testpk (id int PRIMARY KEY); -+CREATE TABLE testfk(f1 int REFERENCES testpk DEFERRABLE INITIALLY DEFERRED); -+DO LANGUAGE plpythonu $$ -+# this insert will fail during commit: -+plpy.execute("INSERT INTO testfk VALUES (0)") -+plpy.commit() -+plpy.warning('should not get here') -+$$; -+ERROR: spiexceptions.ForeignKeyViolation: insert or update on table "testfk" violates foreign key constraint "testfk_f1_fkey" -+DETAIL: Key (f1)=(0) is not present in table "testpk". -+CONTEXT: Traceback (most recent call last): -+ PL/Python anonymous code block, line 4, in -+ plpy.commit() -+PL/Python anonymous code block -+SELECT * FROM testpk; -+ id -+---- -+(0 rows) -+ -+SELECT * FROM testfk; -+ f1 -+---- -+(0 rows) -+ -+DO LANGUAGE plpythonu $$ -+# this insert will fail during commit: -+plpy.execute("INSERT INTO testfk VALUES (0)") -+try: -+ plpy.commit() -+except Exception as e: -+ plpy.info('sqlstate: %s' % (e.sqlstate)) -+# these inserts should work: -+plpy.execute("INSERT INTO testpk VALUES (1)") -+plpy.execute("INSERT INTO testfk VALUES (1)") -+$$; -+INFO: sqlstate: 23503 -+SELECT * FROM testpk; -+ id -+---- -+ 1 -+(1 row) -+ -+SELECT * FROM testfk; -+ f1 -+---- -+ 1 -+(1 row) -+ - DROP TABLE test1; - DROP TABLE test2; -diff --git a/src/pl/plpython/plpy_plpymodule.c b/src/pl/plpython/plpy_plpymodule.c -index 0365acc95b..907f89d153 100644 ---- a/src/pl/plpython/plpy_plpymodule.c -+++ b/src/pl/plpython/plpy_plpymodule.c -@@ -40,8 +40,6 @@ static PyObject *PLy_fatal(PyObject *self, PyObject *args, PyObject *kw); - static PyObject *PLy_quote_literal(PyObject *self, PyObject *args); - static PyObject *PLy_quote_nullable(PyObject *self, PyObject *args); - static PyObject *PLy_quote_ident(PyObject *self, PyObject *args); --static PyObject *PLy_commit(PyObject *self, PyObject *args); --static PyObject *PLy_rollback(PyObject *self, PyObject *args); - - - /* A list of all known exceptions, generated from backend/utils/errcodes.txt */ -@@ -577,31 +575,3 @@ PLy_output(volatile int level, PyObject *self, PyObject *args, PyObject *kw) - */ - Py_RETURN_NONE; - } -- --static PyObject * --PLy_commit(PyObject *self, PyObject *args) --{ -- PLyExecutionContext *exec_ctx = PLy_current_execution_context(); -- -- SPI_commit(); -- SPI_start_transaction(); -- -- /* was cleared at transaction end, reset pointer */ -- exec_ctx->scratch_ctx = NULL; -- -- Py_RETURN_NONE; --} -- --static PyObject * --PLy_rollback(PyObject *self, PyObject *args) --{ -- PLyExecutionContext *exec_ctx = PLy_current_execution_context(); -- -- SPI_rollback(); -- SPI_start_transaction(); -- -- /* was cleared at transaction end, reset pointer */ -- exec_ctx->scratch_ctx = NULL; -- -- Py_RETURN_NONE; --} -diff --git a/src/pl/plpython/plpy_spi.c b/src/pl/plpython/plpy_spi.c -index 99c1b4f28f..86d70470a7 100644 ---- a/src/pl/plpython/plpy_spi.c -+++ b/src/pl/plpython/plpy_spi.c -@@ -456,6 +456,100 @@ PLy_spi_execute_fetch_result(SPITupleTable *tuptable, uint64 rows, int status) - return (PyObject *) result; - } - -+PyObject * -+PLy_commit(PyObject *self, PyObject *args) -+{ -+ MemoryContext oldcontext = CurrentMemoryContext; -+ PLyExecutionContext *exec_ctx = PLy_current_execution_context(); -+ -+ PG_TRY(); -+ { -+ SPI_commit(); -+ -+ /* was cleared at transaction end, reset pointer */ -+ exec_ctx->scratch_ctx = NULL; -+ } -+ PG_CATCH(); -+ { -+ ErrorData *edata; -+ PLyExceptionEntry *entry; -+ PyObject *exc; -+ -+ /* Save error info */ -+ MemoryContextSwitchTo(oldcontext); -+ edata = CopyErrorData(); -+ FlushErrorState(); -+ -+ /* was cleared at transaction end, reset pointer */ -+ exec_ctx->scratch_ctx = NULL; -+ -+ /* Look up the correct exception */ -+ entry = hash_search(PLy_spi_exceptions, &(edata->sqlerrcode), -+ HASH_FIND, NULL); -+ -+ /* -+ * This could be a custom error code, if that's the case fallback to -+ * SPIError -+ */ -+ exc = entry ? entry->exc : PLy_exc_spi_error; -+ /* Make Python raise the exception */ -+ PLy_spi_exception_set(exc, edata); -+ FreeErrorData(edata); -+ -+ return NULL; -+ } -+ PG_END_TRY(); -+ -+ Py_RETURN_NONE; -+} -+ -+PyObject * -+PLy_rollback(PyObject *self, PyObject *args) -+{ -+ MemoryContext oldcontext = CurrentMemoryContext; -+ PLyExecutionContext *exec_ctx = PLy_current_execution_context(); -+ -+ PG_TRY(); -+ { -+ SPI_rollback(); -+ -+ /* was cleared at transaction end, reset pointer */ -+ exec_ctx->scratch_ctx = NULL; -+ } -+ PG_CATCH(); -+ { -+ ErrorData *edata; -+ PLyExceptionEntry *entry; -+ PyObject *exc; -+ -+ /* Save error info */ -+ MemoryContextSwitchTo(oldcontext); -+ edata = CopyErrorData(); -+ FlushErrorState(); -+ -+ /* was cleared at transaction end, reset pointer */ -+ exec_ctx->scratch_ctx = NULL; -+ -+ /* Look up the correct exception */ -+ entry = hash_search(PLy_spi_exceptions, &(edata->sqlerrcode), -+ HASH_FIND, NULL); -+ -+ /* -+ * This could be a custom error code, if that's the case fallback to -+ * SPIError -+ */ -+ exc = entry ? entry->exc : PLy_exc_spi_error; -+ /* Make Python raise the exception */ -+ PLy_spi_exception_set(exc, edata); -+ FreeErrorData(edata); -+ -+ return NULL; -+ } -+ PG_END_TRY(); -+ -+ Py_RETURN_NONE; -+} -+ - /* - * Utilities for running SPI functions in subtransactions. - * -diff --git a/src/pl/plpython/plpy_spi.h b/src/pl/plpython/plpy_spi.h -index a5e2e60da7..98ccd21093 100644 ---- a/src/pl/plpython/plpy_spi.h -+++ b/src/pl/plpython/plpy_spi.h -@@ -12,6 +12,9 @@ extern PyObject *PLy_spi_prepare(PyObject *self, PyObject *args); - extern PyObject *PLy_spi_execute(PyObject *self, PyObject *args); - extern PyObject *PLy_spi_execute_plan(PyObject *ob, PyObject *list, long limit); - -+extern PyObject *PLy_commit(PyObject *self, PyObject *args); -+extern PyObject *PLy_rollback(PyObject *self, PyObject *args); -+ - typedef struct PLyExceptionEntry - { - int sqlstate; /* hash key, must be first */ -diff --git a/src/pl/plpython/sql/plpython_transaction.sql b/src/pl/plpython/sql/plpython_transaction.sql -index 33b37e5b7f..68588d9fb0 100644 ---- a/src/pl/plpython/sql/plpython_transaction.sql -+++ b/src/pl/plpython/sql/plpython_transaction.sql -@@ -148,5 +148,35 @@ SELECT * FROM test1; - SELECT * FROM pg_cursors; - - -+-- check handling of an error during COMMIT -+CREATE TABLE testpk (id int PRIMARY KEY); -+CREATE TABLE testfk(f1 int REFERENCES testpk DEFERRABLE INITIALLY DEFERRED); -+ -+DO LANGUAGE plpythonu $$ -+# this insert will fail during commit: -+plpy.execute("INSERT INTO testfk VALUES (0)") -+plpy.commit() -+plpy.warning('should not get here') -+$$; -+ -+SELECT * FROM testpk; -+SELECT * FROM testfk; -+ -+DO LANGUAGE plpythonu $$ -+# this insert will fail during commit: -+plpy.execute("INSERT INTO testfk VALUES (0)") -+try: -+ plpy.commit() -+except Exception as e: -+ plpy.info('sqlstate: %s' % (e.sqlstate)) -+# these inserts should work: -+plpy.execute("INSERT INTO testpk VALUES (1)") -+plpy.execute("INSERT INTO testfk VALUES (1)") -+$$; -+ -+SELECT * FROM testpk; -+SELECT * FROM testfk; -+ -+ - DROP TABLE test1; - DROP TABLE test2; -diff --git a/src/pl/tcl/expected/pltcl_transaction.out b/src/pl/tcl/expected/pltcl_transaction.out -index 007204b99a..f557b79138 100644 ---- a/src/pl/tcl/expected/pltcl_transaction.out -+++ b/src/pl/tcl/expected/pltcl_transaction.out -@@ -96,5 +96,54 @@ SELECT * FROM test1; - ---+--- - (0 rows) - -+-- check handling of an error during COMMIT -+CREATE TABLE testpk (id int PRIMARY KEY); -+CREATE TABLE testfk(f1 int REFERENCES testpk DEFERRABLE INITIALLY DEFERRED); -+CREATE PROCEDURE transaction_testfk() -+LANGUAGE pltcl -+AS $$ -+# this insert will fail during commit: -+spi_exec "INSERT INTO testfk VALUES (0)" -+commit -+elog WARNING "should not get here" -+$$; -+CALL transaction_testfk(); -+ERROR: insert or update on table "testfk" violates foreign key constraint "testfk_f1_fkey" -+SELECT * FROM testpk; -+ id -+---- -+(0 rows) -+ -+SELECT * FROM testfk; -+ f1 -+---- -+(0 rows) -+ -+CREATE OR REPLACE PROCEDURE transaction_testfk() -+LANGUAGE pltcl -+AS $$ -+# this insert will fail during commit: -+spi_exec "INSERT INTO testfk VALUES (0)" -+if [catch {commit} msg] { -+ elog INFO $msg -+} -+# these inserts should work: -+spi_exec "INSERT INTO testpk VALUES (1)" -+spi_exec "INSERT INTO testfk VALUES (1)" -+$$; -+CALL transaction_testfk(); -+INFO: insert or update on table "testfk" violates foreign key constraint "testfk_f1_fkey" -+SELECT * FROM testpk; -+ id -+---- -+ 1 -+(1 row) -+ -+SELECT * FROM testfk; -+ f1 -+---- -+ 1 -+(1 row) -+ - DROP TABLE test1; - DROP TABLE test2; -diff --git a/src/pl/tcl/pltcl.c b/src/pl/tcl/pltcl.c -index c5fad05e12..68c9bd1970 100644 ---- a/src/pl/tcl/pltcl.c -+++ b/src/pl/tcl/pltcl.c -@@ -2935,7 +2935,6 @@ pltcl_commit(ClientData cdata, Tcl_Interp *interp, - PG_TRY(); - { - SPI_commit(); -- SPI_start_transaction(); - } - PG_CATCH(); - { -@@ -2975,7 +2974,6 @@ pltcl_rollback(ClientData cdata, Tcl_Interp *interp, - PG_TRY(); - { - SPI_rollback(); -- SPI_start_transaction(); - } - PG_CATCH(); - { -diff --git a/src/pl/tcl/sql/pltcl_transaction.sql b/src/pl/tcl/sql/pltcl_transaction.sql -index c752faf665..bd759850a7 100644 ---- a/src/pl/tcl/sql/pltcl_transaction.sql -+++ b/src/pl/tcl/sql/pltcl_transaction.sql -@@ -94,5 +94,42 @@ CALL transaction_test4b(); - SELECT * FROM test1; - - -+-- check handling of an error during COMMIT -+CREATE TABLE testpk (id int PRIMARY KEY); -+CREATE TABLE testfk(f1 int REFERENCES testpk DEFERRABLE INITIALLY DEFERRED); -+ -+CREATE PROCEDURE transaction_testfk() -+LANGUAGE pltcl -+AS $$ -+# this insert will fail during commit: -+spi_exec "INSERT INTO testfk VALUES (0)" -+commit -+elog WARNING "should not get here" -+$$; -+ -+CALL transaction_testfk(); -+ -+SELECT * FROM testpk; -+SELECT * FROM testfk; -+ -+CREATE OR REPLACE PROCEDURE transaction_testfk() -+LANGUAGE pltcl -+AS $$ -+# this insert will fail during commit: -+spi_exec "INSERT INTO testfk VALUES (0)" -+if [catch {commit} msg] { -+ elog INFO $msg -+} -+# these inserts should work: -+spi_exec "INSERT INTO testpk VALUES (1)" -+spi_exec "INSERT INTO testfk VALUES (1)" -+$$; -+ -+CALL transaction_testfk(); -+ -+SELECT * FROM testpk; -+SELECT * FROM testfk; -+ -+ - DROP TABLE test1; - DROP TABLE test2; --- -2.35.1 - diff --git a/postgresql-logging.patch b/postgresql-logging.patch index 50ebdaa..c4fac84 100644 --- a/postgresql-logging.patch +++ b/postgresql-logging.patch @@ -1,16 +1,16 @@ -diff -up postgresql-14beta2/src/backend/utils/misc/postgresql.conf.sample.patch2 postgresql-14beta2/src/backend/utils/misc/postgresql.conf.sample ---- postgresql-14beta2/src/backend/utils/misc/postgresql.conf.sample.patch2 2021-06-21 23:07:55.000000000 +0200 -+++ postgresql-14beta2/src/backend/utils/misc/postgresql.conf.sample 2021-06-25 19:37:21.868632721 +0200 -@@ -435,7 +435,7 @@ - # requires logging_collector to be on. +diff -up postgresql-15.0_original/src/backend/utils/misc/postgresql.conf.sample postgresql-15.0/src/backend/utils/misc/postgresql.conf.sample +--- postgresql-15.0_original/src/backend/utils/misc/postgresql.conf.sample 2022-09-27 16:57:00.652909198 +0200 ++++ postgresql-15.0/src/backend/utils/misc/postgresql.conf.sample 2022-09-27 17:01:56.073606108 +0200 +@@ -449,7 +449,7 @@ + # logging_collector to be on. # This is used when logging to stderr: --#logging_collector = off # Enable capturing of stderr and csvlog -+logging_collector = on # Enable capturing of stderr and csvlog - # into log files. Required to be on for - # csvlogs. +-#logging_collector = off # Enable capturing of stderr, jsonlog, ++logging_collector = on # Enable capturing of stderr, jsonlog, + # and csvlog into log files. Required + # to be on for csvlogs and jsonlogs. # (change requires restart) -@@ -443,16 +443,16 @@ +@@ -457,16 +457,16 @@ # These are only used if logging_collector is on: #log_directory = 'log' # directory where log files are written, # can be absolute or relative to PGDATA @@ -22,8 +22,7 @@ diff -up postgresql-14beta2/src/backend/utils/misc/postgresql.conf.sample.patch2 -#log_rotation_age = 1d # Automatic rotation of logfiles will +log_rotation_age = 1d # Automatic rotation of logfiles will # happen after that time. 0 disables. --#log_rotation_size = 10MB # Automatic rotation of logfiles will -+log_rotation_size = 0 # Automatic rotation of logfiles will + #log_rotation_size = 10MB # Automatic rotation of logfiles will # happen after that much log output. # 0 disables. -#log_truncate_on_rotation = off # If on, an existing log file with the diff --git a/postgresql-pgcrypto-openssl3-tests.patch b/postgresql-pgcrypto-openssl3-tests.patch index 16399a4..6ca2a9b 100644 --- a/postgresql-pgcrypto-openssl3-tests.patch +++ b/postgresql-pgcrypto-openssl3-tests.patch @@ -39,34 +39,22 @@ diff -ur postgresql-13.4/contrib/pgcrypto/expected/pgp-pubkey-decrypt.out postgr from keytbl, encdata where keytbl.id=3 and encdata.id=3; pgp_pub_decrypt ----------------- -diff -ur postgresql-13.4/contrib/pgcrypto/Makefile postgresql-13.4.patched/contrib/pgcrypto/Makefile ---- postgresql-13.4/contrib/pgcrypto/Makefile 2021-08-09 16:49:05.000000000 -0400 -+++ postgresql-13.4.patched/contrib/pgcrypto/Makefile 2021-09-01 08:26:47.207164873 -0400 -@@ -5,7 +5,7 @@ - INT_TESTS = sha2 - - OSSL_SRCS = openssl.c pgp-mpi-openssl.c --OSSL_TESTS = sha2 des 3des cast5 -+OSSL_TESTS = sha2 - - ZLIB_TST = pgp-compression - ZLIB_OFF_TST = pgp-zlib-DISABLED -@@ -49,12 +49,13 @@ +diff -ur postgresql-15.0_original/contrib/pgcrypto/Makefile postgresql-15.0/contrib/pgcrypto/Makefile +--- postgresql-15.0_original/contrib/pgcrypto/Makefile 2022-09-05 23:12:45.000000000 +0200 ++++ postgresql-15.0/contrib/pgcrypto/Makefile 2022-09-27 17:12:54.463159362 +0200 +@@ -39,9 +39,9 @@ pgcrypto--1.0--1.1.sql PGFILEDESC = "pgcrypto - cryptographic functions" -REGRESS = init md5 sha1 hmac-md5 hmac-sha1 blowfish rijndael \ -+REGRESS = init md5 sha1 hmac-md5 hmac-sha1 rijndael \ - $(CF_TESTS) \ +- sha2 des 3des cast5 \ - crypt-des crypt-md5 crypt-blowfish crypt-xdes \ ++REGRESS = init md5 sha1 hmac-md5 hmac-sha1 rijndael \ ++ sha2 \ + crypt-md5 \ pgp-armor pgp-decrypt pgp-encrypt $(CF_PGP_TESTS) \ pgp-pubkey-decrypt pgp-pubkey-encrypt pgp-info - -+#REGRESS = init pgp-pubkey-decrypt pgp-decrypt \ - EXTRA_CLEAN = gen-rtab - - ifdef USE_PGXS + diff -ur postgresql-13.4/contrib/pgcrypto/sql/pgp-decrypt.sql postgresql-13.4.patched/contrib/pgcrypto/sql/pgp-decrypt.sql --- postgresql-13.4/contrib/pgcrypto/sql/pgp-decrypt.sql 2021-08-09 16:49:05.000000000 -0400 +++ postgresql-13.4.patched/contrib/pgcrypto/sql/pgp-decrypt.sql 2021-09-01 08:16:12.525212175 -0400 diff --git a/postgresql-pl-perl-test-case.patch b/postgresql-pl-perl-test-case.patch deleted file mode 100644 index 3b9cdc6..0000000 --- a/postgresql-pl-perl-test-case.patch +++ /dev/null @@ -1,61 +0,0 @@ -From eb39610f82679e015dd990a3fbba1c62e399c32a Mon Sep 17 00:00:00 2001 -From: Tom Lane -Date: Wed, 1 Jun 2022 16:15:47 -0400 -Subject: [PATCH] Fix pl/perl test case so it will still work under Perl 5.36. -MIME-Version: 1.0 -Content-Type: text/plain; charset=UTF-8 -Content-Transfer-Encoding: 8bit - -Perl 5.36 has reclassified the warning condition that this test -case used, so that the expected error fails to appear. Tweak -the test so it instead exercises a case that's handled the same -way in all Perl versions of interest. - -This appears to meet our standards for back-patching into -out-of-support branches: it changes no user-visible behavior -but enables testing of old branches with newer tools. -Hence, back-patch as far as 9.2. - -Dagfinn Ilmari Mannsåker, per report from Jitka Plesníková. - -Discussion: https://postgr.es/m/564579.1654093326@sss.pgh.pa.us ---- - src/pl/plperl/expected/plperl.out | 6 +++--- - src/pl/plperl/sql/plperl.sql | 4 ++-- - 2 files changed, 5 insertions(+), 5 deletions(-) - -diff --git a/src/pl/plperl/expected/plperl.out b/src/pl/plperl/expected/plperl.out -index d8a1ff5dd8..e3d7c8896a 100644 ---- a/src/pl/plperl/expected/plperl.out -+++ b/src/pl/plperl/expected/plperl.out -@@ -724,9 +724,9 @@ DO $do$ use strict; my $name = "foo"; my $ref = $$name; $do$ LANGUAGE plperl; - ERROR: Can't use string ("foo") as a SCALAR ref while "strict refs" in use at line 1. - CONTEXT: PL/Perl anonymous code block - -- check that we can "use warnings" (in this case to turn a warn into an error) ---- yields "ERROR: Useless use of sort in scalar context." --DO $do$ use warnings FATAL => qw(void) ; my @y; my $x = sort @y; 1; $do$ LANGUAGE plperl; --ERROR: Useless use of sort in scalar context at line 1. -+-- yields "ERROR: Useless use of sort in void context." -+DO $do$ use warnings FATAL => qw(void) ; my @y; sort @y; 1; $do$ LANGUAGE plperl; -+ERROR: Useless use of sort in void context at line 1. - CONTEXT: PL/Perl anonymous code block - -- make sure functions marked as VOID without an explicit return work - CREATE OR REPLACE FUNCTION myfuncs() RETURNS void AS $$ -diff --git a/src/pl/plperl/sql/plperl.sql b/src/pl/plperl/sql/plperl.sql -index b0d950b230..bb0b8ce4cb 100644 ---- a/src/pl/plperl/sql/plperl.sql -+++ b/src/pl/plperl/sql/plperl.sql -@@ -469,8 +469,8 @@ DO $$ use blib; $$ LANGUAGE plperl; - DO $do$ use strict; my $name = "foo"; my $ref = $$name; $do$ LANGUAGE plperl; - - -- check that we can "use warnings" (in this case to turn a warn into an error) ---- yields "ERROR: Useless use of sort in scalar context." --DO $do$ use warnings FATAL => qw(void) ; my @y; my $x = sort @y; 1; $do$ LANGUAGE plperl; -+-- yields "ERROR: Useless use of sort in void context." -+DO $do$ use warnings FATAL => qw(void) ; my @y; sort @y; 1; $do$ LANGUAGE plperl; - - -- make sure functions marked as VOID without an explicit return work - CREATE OR REPLACE FUNCTION myfuncs() RETURNS void AS $$ --- -2.35.1 - diff --git a/postgresql-server-pg_config.patch b/postgresql-server-pg_config.patch index 9ce0b4b..83793e1 100644 --- a/postgresql-server-pg_config.patch +++ b/postgresql-server-pg_config.patch @@ -47,12 +47,12 @@ diff -ur postgresql-14rc1/src/bin/pg_config/Makefile pgsql14/src/bin/pg_config/M rm -rf tmp_check check: -diff -ur postgresql-14rc1/src/bin/pg_config/nls.mk pgsql14/src/bin/pg_config/nls.mk ---- postgresql-14rc1/src/bin/pg_config/nls.mk 2021-09-20 23:33:01.000000000 +0200 -+++ pgsql14/src/bin/pg_config/nls.mk 2021-09-22 10:48:51.492460567 +0200 +diff -ur postgresql-15.0_original/src/bin/pg_config/nls.mk postgresql-15.0/src/bin/pg_config/nls.mk +--- postgresql-15.0_original/src/bin/pg_config/nls.mk 2022-09-05 23:12:45.000000000 +0200 ++++ postgresql-15.0/src/bin/pg_config/nls.mk 2022-09-27 17:04:14.618932977 +0200 @@ -1,4 +1,4 @@ # src/bin/pg_config/nls.mk -CATALOG_NAME = pg_config +CATALOG_NAME = pg_server_config - AVAIL_LANGUAGES = cs de el es fr he it ja ko pl pt_BR ru sv tr uk vi zh_CN + AVAIL_LANGUAGES = cs de el es fr he it ja ka ko pl pt_BR ru sv tr uk vi zh_CN GETTEXT_FILES = pg_config.c ../../common/config_info.c ../../common/exec.c diff --git a/postgresql.spec b/postgresql.spec index 59e357c..fd5eb7d 100644 --- a/postgresql.spec +++ b/postgresql.spec @@ -63,9 +63,9 @@ Summary: PostgreSQL client programs Name: postgresql -%global majorversion 14 -Version: %{majorversion}.3 -Release: 10%{?dist} +%global majorversion 15 +Version: %{majorversion}.0 +Release: 1%{?dist} # The PostgreSQL license is very similar to other MIT licenses, but the OSI # recognizes it as an independent license, so we do as well. @@ -76,8 +76,8 @@ Url: http://www.postgresql.org/ # in-place upgrade of an old database. In most cases it will not be critical # that this be kept up with the latest minor release of the previous series; # but update when bugs affecting pg_dump output are fixed. -%global prevmajorversion 13 -%global prevversion %{prevmajorversion}.7 +%global prevmajorversion 14 +%global prevversion %{prevmajorversion}.3 %global prev_prefix %{_libdir}/pgsql/postgresql-%{prevmajorversion} %global precise_version %{?epoch:%epoch:}%version-%release @@ -118,10 +118,8 @@ Patch10: postgresql-datalayout-mismatch-on-s390.patch Patch12: postgresql-no-libecpg.patch # This patch disables deprecated ciphers in the test suite Patch14: postgresql-pgcrypto-openssl3-tests.patch -# Fix compatibility with Python 3.11 -Patch15: postgresql-SPI-s-handling-of-errors-during-transaction-comm.patch -# Fix compatibility with Perl 5.36 -Patch16: postgresql-pl-perl-test-case.patch +# This patch enables to build PostgreSQL 15 with llvm 15 +Patch15: postgresql-15.0-llvm_pointer.patch BuildRequires: make BuildRequires: lz4-devel @@ -129,6 +127,7 @@ BuildRequires: gcc BuildRequires: perl(ExtUtils::MakeMaker) glibc-devel bison flex gawk BuildRequires: perl(ExtUtils::Embed), perl-devel BuildRequires: perl(Opcode) +BuildRequires: perl-FindBin %if 0%{?fedora} || 0%{?rhel} > 7 BuildRequires: perl-generators %endif @@ -444,7 +443,6 @@ goal of accelerating analytics queries. %patch10 -p1 %patch14 -p1 %patch15 -p1 -%patch16 -p1 # We used to run autoconf here, but there's no longer any real need to, # since Postgres ships with a reasonably modern configure script. @@ -1001,6 +999,7 @@ make -C postgresql-setup-%{setup_version} check %{_datadir}/pgsql/extension/pg_surgery* %{_datadir}/pgsql/extension/pg_trgm* %{_datadir}/pgsql/extension/pg_visibility* +%{_datadir}/pgsql/extension/pg_walinspect* %{_datadir}/pgsql/extension/pgcrypto* %{_datadir}/pgsql/extension/pgrowlocks* %{_datadir}/pgsql/extension/pgstattuple* @@ -1059,6 +1058,9 @@ make -C postgresql-setup-%{setup_version} check %{_libdir}/pgsql/pg_surgery.so %{_libdir}/pgsql/pg_trgm.so %{_libdir}/pgsql/pg_visibility.so +%{_libdir}/pgsql/basebackup_to_shell.so +%{_libdir}/pgsql/basic_archive.so +%{_libdir}/pgsql/pg_walinspect.so %{_libdir}/pgsql/pgcrypto.so %{_libdir}/pgsql/pgrowlocks.so %{_libdir}/pgsql/pgstattuple.so @@ -1265,6 +1267,12 @@ make -C postgresql-setup-%{setup_version} check %changelog +* Tue Sep 27 2022 Ondrej Sloup - 15.1-1 +- Update to v15 +- Add llvm pointer patch +- Add new build require for perl-FindBin +- Resolves: https://fedoraproject.org/wiki/Changes/PostgreSQL_15 + * Thu Sep 01 2022 Ondrej Sloup - 14.3-10 - Add dependency on util-linux to make runuser available (rhbz#2071437) diff --git a/sources b/sources index 52cbd03..5e552fb 100644 --- a/sources +++ b/sources @@ -1,6 +1,3 @@ -SHA512 (postgresql-13.7.tar.bz2) = 9254f21519c8d4e926f70082503bb5593c91064a3d2a4ea18ac503dfd9aa94751d6f01ce00fca9fec9b2b7af40caf8d0951b661dd8be4d6aa87c1e35b6fa7a41 -SHA512 (postgresql-13.7.tar.bz2.sha256) = a6e3601c6f8370318631820cb0f9858e49ea7d672652fe68ca0c0603e4fd28851fe1966a0825c8dafab11e15a0856486d82406f5b2d033917da0328089ca3f37 -SHA512 (postgresql-14.3.tar.bz2) = 70e6f67b5729a23f80b92b04e3fad2e09596b939660e3ddebf499d06af946459a45a019279e05413673e7b65d09a28a0440ed3c2ae565068466ed37e2d4f6f17 -SHA512 (postgresql-14.3.tar.bz2.sha256) = 29a4b501bdd17ad36e6b7c8c8e7c2f418b72c70811317409ad067d2d059e6adaf511efa367393d6837dcab458537fb3f297e9046bfc38072dc5d1af6338404f5 -SHA512 (postgresql-setup-8.7.tar.gz) = 741f036be517e7d9725e4f146ca7dac8b8a16b6a93d045a64ef268487f48faad6b08317b58e07ad16a31002d2a10de0ac32513a4935c3f22f48ec768a742d1fc -SHA512 (postgresql-14.3-US.pdf) = 5069ff8030f8bf780dfa026ee968aeb56f93e2f3625af63f145db83d879dd2a332a0994e184391ed502be9ec8a015ba895f098b4aa64cd56c9466d5cfde6b7fd +SHA512 (postgresql-15.0.tar.bz2) = 537d223be619d8b192756791cb614638f7188532f981e233bbfa8c0245adf5afe94ba5160d771af77f7d4ead41bcf346cbb2197e1358a6411ead06b19e29f120 +SHA512 (postgresql-15.0.tar.bz2.sha256) = 9da21058369ceac6870f5394853ba58c90f0b5dbcd1524f170033598d6cd5e38b4329373e97f242c4f56a93ae0b1a212e762740149937f519db22ed7435c6fe8 +SHA512 (postgresql-15.0-US.pdf) = 97f685740ed384b7e1c439f326a2cd1771aac47accba64ec70f8d7d370944c163ad9c4bc61328358a6f442d44d01a7c426cfb2a57c99dfa4580a298a8db145a0