Skip to content

Commit 112b039

Browse files
committed
Fix INSERT EXEC error 556: Detect schema changes during execution
Problem: SQL Server raises error 556 ('INSERT EXEC failed because the stored procedure altered the schema of the target table') when a procedure executed via INSERT EXEC modifies the target table's schema (e.g., ALTER TABLE ADD COLUMN). Babelfish was not detecting this scenario. Previous Approaches (Failed): 1. Holding target table open with table_open() - Fixed 556_1 test but caused 'relcache reference not owned by resource owner' errors in upgrade tests because Relation pointers cannot be held across subtransaction boundaries. 2. Using locks only with LockRelationOid() - Fixed upgrade tests but broke 556_1 because CheckTableNotInUse() only checks reference count, not locks. Solution (Schema Signature Approach): Instead of holding the Relation pointer open, we now: 1. Capture the target table's 'schema signature' at INSERT EXEC start: - Column count (natts) - Column type OIDs (atttypids) - Column type modifiers (atttypmods) 2. Acquire RowExclusiveLock on the target table (released at transaction end) 3. Before flushing buffered data to the target, verify the schema signature hasn't changed 4. If schema changed, raise error 556 with the appropriate SQL Server message Major Version Upgrade Handling: In major version upgrade scenarios, table OIDs may change (tables are recreated with different OIDs). The schema verification and lock release functions now wrap table_open/UnlockRelationOid calls in PG_TRY blocks to gracefully handle stale OIDs - if the relation cannot be opened, we skip the schema check and let the actual INSERT validate the data. This approach: - Detects ALTER TABLE operations that change column count or types - Avoids holding Relation pointers across subtransaction boundaries - Works correctly with upgrade tests (no relcache reference issues) - Handles stale OIDs gracefully in major version upgrade scenarios - Properly handles temp tables and table variables (skips schema capture) Implementation Details: - Added InsertExecSchemaSignature struct to store column metadata - Added pltsql_insert_exec_verify_schema() to check schema before flush - Modified pltsql_insert_exec_open_target_table() to capture schema signature - Modified pltsql_insert_exec_close_target_table() to free schema signature - Modified flush_insert_exec_temp_table() to call verify and raise error 556 - Added error mapping for the new error message to map to SQL Server error 556 - Added PG_TRY/PG_CATCH blocks to handle stale OIDs in upgrade scenarios Files Changed: - contrib/babelfishpg_tsql/src/pl_exec-2.c: Schema signature implementation - contrib/babelfishpg_tsql/src/pltsql.h: Added pltsql_insert_exec_verify_schema() - contrib/babelfishpg_tds/error_mapping.txt: Added error 556 mapping - test/JDBC/expected/TestErrorHelperFunctions.out: Updated expected output - test/JDBC/expected/TestErrorHelperFunctionsUpgrade-vu-verify.out: Updated Tests Verified: - 556_1: Passed (schema change detection) - BABEL-1944: Passed (upgrade test - no relcache issues) - BABEL-INSERT-EXEC: Passed (general INSERT EXEC functionality) - BABEL-INSERT-EXECUTE: Passed (INSERT EXECUTE functionality) - TestErrorHelperFunctions: Passed (error mapping validation)
1 parent 2d9d515 commit 112b039

File tree

5 files changed

+287
-40
lines changed

5 files changed

+287
-40
lines changed

contrib/babelfishpg_tds/error_mapping.txt

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -188,4 +188,5 @@ XX000 ERRCODE_INTERNAL_ERROR "The table-valued parameter \"%s\" must be declared
188188
42P01 ERRCODE_UNDEFINED_TABLE "FOR JSON AUTO requires at least one table for generating JSON objects. Use FOR JSON PATH or add a FROM clause with a table name." SQL_ERROR_13600 16
189189
42P01 ERRCODE_FEATURE_NOT_SUPPORTED "sub-select and values for json auto are not currently supported." SQL_ERROR_13600 16
190190
54000 ERRCODE_PROGRAM_LIMIT_EXCEEDED "nested INSERT ... EXECUTE statements are not allowed" SQL_ERROR_8164 16
191+
0A000 ERRCODE_FEATURE_NOT_SUPPORTED "INSERT EXEC failed because the stored procedure altered the schema of the target table." SQL_ERROR_556 16
191192

0 commit comments

Comments
 (0)