diff --git a/.github/workflows/odbc-tests.yml b/.github/workflows/odbc-tests.yml index 99f5659c56..bd8572c6fd 100644 --- a/.github/workflows/odbc-tests.yml +++ b/.github/workflows/odbc-tests.yml @@ -58,14 +58,14 @@ jobs: if: steps.install-extensions.outcome == 'success' && steps.install-unix-odbc-driver.outcome=='success' run: | cd ~ - wget https://ftp.postgresql.org/pub/odbc/versions/src/psqlodbc-12.01.0000.tar.gz - tar -zxvf psqlodbc-12.01.0000.tar.gz - cd psqlodbc-12.01.0000 + wget https://ftp.postgresql.org/pub/odbc/versions/src/psqlodbc-16.00.0000.tar.gz + tar -zxvf psqlodbc-16.00.0000.tar.gz + cd psqlodbc-16.00.0000 ./configure sudo make sudo make install - echo '[ODBC_Driver_12_for_PostgreSQL]' | sudo tee -a /etc/odbcinst.ini > /dev/null - echo 'Description=ODBC Driver 12 for PostgreSQL Server' | sudo tee -a /etc/odbcinst.ini > /dev/null + echo '[ODBC_Driver_16_for_PostgreSQL]' | sudo tee -a /etc/odbcinst.ini > /dev/null + echo 'Description=ODBC Driver 16 for PostgreSQL Server' | sudo tee -a /etc/odbcinst.ini > /dev/null echo 'Driver=/usr/local/lib/psqlodbcw.so' | sudo tee -a /etc/odbcinst.ini > /dev/null echo 'UsageCount=1' | sudo tee -a /etc/odbcinst.ini > /dev/null @@ -81,7 +81,7 @@ jobs: MSSQL_BABEL_DB_USER=jdbc_user \ MSSQL_BABEL_DB_PASSWORD=12345678 \ MSSQL_BABEL_DB_NAME=master \ - PSQL_ODBC_DRIVER_NAME=ODBC_Driver_12_for_PostgreSQL \ + PSQL_ODBC_DRIVER_NAME=ODBC_Driver_16_for_PostgreSQL \ PSQL_BABEL_DB_SERVER=localhost \ PSQL_BABEL_DB_PORT=5432 \ PSQL_BABEL_DB_USER=jdbc_user \ diff --git a/contrib/babelfishpg_tsql/src/pl_exec.c b/contrib/babelfishpg_tsql/src/pl_exec.c index 006d1d7aa4..0719abae18 100644 --- a/contrib/babelfishpg_tsql/src/pl_exec.c +++ b/contrib/babelfishpg_tsql/src/pl_exec.c @@ -6939,7 +6939,7 @@ exec_eval_datum(PLtsql_execstate *estate, *typeid = tbl->tbltypeid; *typetypmod = -1; *value = CStringGetDatum(tbl->tblname); - *isnull = false; + *isnull = !tbl->tblname ? true : false; break; } @@ -10097,9 +10097,17 @@ pltsql_clean_table_variables(PLtsql_execstate *estate, PLtsql_function *func) bool old_pltsql_explain_only = pltsql_explain_only; const char *query_fmt = "DROP TABLE %s"; const char *query; + bool old_abort_curr_txn = AbortCurTransaction; PG_TRY(); { + /* + * Temporarily set this to false to allow DROP to continue. + * Othewise, DROP would not be allowed to acquire xlock on the + * relation. + */ + AbortCurTransaction = false; + foreach(lc, func->table_varnos) { n = lfirst_int(lc); @@ -10126,9 +10134,15 @@ pltsql_clean_table_variables(PLtsql_execstate *estate, PLtsql_function *func) append_explain_info(NULL, query); } } + + Assert(!AbortCurTransaction); /* engine should not change this value */ + AbortCurTransaction = old_abort_curr_txn; } PG_CATCH(); { + Assert(!AbortCurTransaction); /* engine should not change this value */ + AbortCurTransaction = old_abort_curr_txn; + pltsql_explain_only = old_pltsql_explain_only; /* Recover EXPLAIN ONLY * mode */ PG_RE_THROW(); diff --git a/test/JDBC/expected/table-variable-vu-cleanup.out b/test/JDBC/expected/table-variable-vu-cleanup.out index 0f51fcf5bf..0ca455f18b 100644 --- a/test/JDBC/expected/table-variable-vu-cleanup.out +++ b/test/JDBC/expected/table-variable-vu-cleanup.out @@ -59,3 +59,13 @@ drop schema table_variable_vu_schema go drop function table_variable_vu_func2 go + +-- BABEL-4337 - nested tv +DROP FUNCTION tv_nested_func2 +GO + +DROP FUNCTION tv_nested_func1 +GO + +DROP TYPE tv_nested_type +GO diff --git a/test/JDBC/expected/table-variable-vu-prepare.out b/test/JDBC/expected/table-variable-vu-prepare.out index a8fa6e5c22..b2851259f0 100644 --- a/test/JDBC/expected/table-variable-vu-prepare.out +++ b/test/JDBC/expected/table-variable-vu-prepare.out @@ -239,3 +239,11 @@ BEGIN RETURN END go + +-- BABEL-4337 - nested TV, null check in tblname +CREATE TYPE tv_nested_type AS TABLE (a INT) +GO +CREATE FUNCTION tv_nested_func1 (@t tv_nested_type readonly) RETURNS @a TABLE (y INT) AS BEGIN; INSERT INTO @a SELECT x FROM @t; RETURN; END; +GO +CREATE FUNCTION tv_nested_func2 (@t tv_nested_type readonly) RETURNS @a TABLE (x INT) AS BEGIN; INSERT INTO @a SELECT y FROM tv_nested_func1(@t); RETURN; END; +GO diff --git a/test/JDBC/expected/table-variable-vu-verify.out b/test/JDBC/expected/table-variable-vu-verify.out index 8d0b1652a0..c338b6f4ee 100644 --- a/test/JDBC/expected/table-variable-vu-verify.out +++ b/test/JDBC/expected/table-variable-vu-verify.out @@ -263,3 +263,13 @@ bit 1 ~~END~~ + +-- BABEL-4337 - check nested TV for null; should not crash but throw an error +SELECT * FROM tv_nested_func2(NULL) +go +~~START~~ +int +~~ERROR (Code: 33557097)~~ + +~~ERROR (Message: table variable underlying typename is NULL. refname: @t)~~ + diff --git a/test/JDBC/expected/table_variable_xact_errors.out b/test/JDBC/expected/table_variable_xact_errors.out index c28a4a2364..e1bbdbe15e 100644 --- a/test/JDBC/expected/table_variable_xact_errors.out +++ b/test/JDBC/expected/table_variable_xact_errors.out @@ -459,13 +459,13 @@ GO ------------------------------------------------------------------------------- --- Cursor not explicitly closed +-- Cursor not explicitly closed ------------------------------------------------------------------------------- -DECLARE @STATION_INTS_TABLE TABLE (STATION_INT INT) -DECLARE @v INT -DECLARE CUR_NETWORK CURSOR LOCAL FOR SELECT STATION_INT FROM @STATION_INTS_TABLE -OPEN CUR_NETWORK -FETCH NEXT FROM CUR_NETWORK INTO @v +DECLARE @STATION_INTS_TABLE TABLE (STATION_INT INT) +DECLARE @v INT +DECLARE CUR_NETWORK CURSOR LOCAL FOR SELECT STATION_INT FROM @STATION_INTS_TABLE +OPEN CUR_NETWORK +FETCH NEXT FROM CUR_NETWORK INTO @v GO select 123 @@ -476,16 +476,16 @@ int ~~END~~ -CREATE FUNCTION [dbo].[WOSQL_BuildRevenueDetailOLUQuery] () -RETURNS NVARCHAR(MAX) AS + +CREATE FUNCTION [dbo].[WOSQL_BuildRevenueDetailOLUQuery] () +RETURNS NVARCHAR(MAX) AS BEGIN - DECLARE @TSQL NVARCHAR(MAX) - DECLARE @STATION_INTS_TABLE TABLE (STATION_INT INT) + DECLARE @TSQL NVARCHAR(MAX) + DECLARE @STATION_INTS_TABLE TABLE (STATION_INT INT) DECLARE @STATION_INT INT SET @TSQL = '' - DECLARE CUR_NETWORK CURSOR LOCAL FOR - SELECT STATION_INT FROM @STATION_INTS_TABLE OPEN CUR_NETWORK + DECLARE CUR_NETWORK CURSOR LOCAL FOR + SELECT STATION_INT FROM @STATION_INTS_TABLE OPEN CUR_NETWORK FETCH NEXT FROM CUR_NETWORK INTO @STATION_INT - RETURN @TSQL END GO @@ -534,7 +534,7 @@ nvarchar ~~ERROR (Message: Throw error)~~ -DROP FUNCTION [dbo].[WOSQL_BuildRevenueDetailOLUQuery] +DROP FUNCTION [dbo].[WOSQL_BuildRevenueDetailOLUQuery] GO @@ -569,3 +569,44 @@ nvarchar DROP FUNCTION [dbo].[WOSQL_BuildRevenueDetailOLUQuery] GO + +------------------------------------------------------------------------------- +-- BABEL-4267: Error should not cause crash +------------------------------------------------------------------------------- +CREATE PROCEDURE usp_PopulateDiscount +AS + DECLARE @Lookup TABLE (StartDate DATETIME NOT NULL) + INSERT INTO @Lookup SELECT GETDATE() + BEGIN TRANSACTION + DELETE trgt FROM Discount trgt -- Discount does not exist + COMMIT +go + +EXECUTE usp_PopulateDiscount +go +~~ROW COUNT: 1~~ + +~~ERROR (Code: 33557097)~~ + +~~ERROR (Message: relation "discount" does not exist)~~ + + +CREATE PROCEDURE test +AS +BEGIN TRY + DECLARE @tv1 TABLE(c1 INT PRIMARY KEY, b INT IDENTITY, c CHAR(15) DEFAULT 'Whoops!') + SELECT 1/0 +END TRY +BEGIN CATCH + BEGIN TRANSACTION + INSERT INTO @tv1 VALUES(1, 3, 'Three') -- invalid syntax, should do a clean shutdown + COMMIT +END CATCH; +GO + +exec test +go +~~ERROR (Code: 33557097)~~ + +~~ERROR (Message: INSERT has more expressions than target columns)~~ + diff --git a/test/JDBC/expected/table_variable_xact_errors_isolation_snapshot.out b/test/JDBC/expected/table_variable_xact_errors_isolation_snapshot.out index e17c27c0b0..ba79b81593 100644 --- a/test/JDBC/expected/table_variable_xact_errors_isolation_snapshot.out +++ b/test/JDBC/expected/table_variable_xact_errors_isolation_snapshot.out @@ -461,13 +461,13 @@ GO ------------------------------------------------------------------------------- --- Cursor not explicitly closed +-- Cursor not explicitly closed ------------------------------------------------------------------------------- -DECLARE @STATION_INTS_TABLE TABLE (STATION_INT INT) -DECLARE @v INT -DECLARE CUR_NETWORK CURSOR LOCAL FOR SELECT STATION_INT FROM @STATION_INTS_TABLE -OPEN CUR_NETWORK -FETCH NEXT FROM CUR_NETWORK INTO @v +DECLARE @STATION_INTS_TABLE TABLE (STATION_INT INT) +DECLARE @v INT +DECLARE CUR_NETWORK CURSOR LOCAL FOR SELECT STATION_INT FROM @STATION_INTS_TABLE +OPEN CUR_NETWORK +FETCH NEXT FROM CUR_NETWORK INTO @v GO select 123 @@ -478,16 +478,16 @@ int ~~END~~ -CREATE FUNCTION [dbo].[WOSQL_BuildRevenueDetailOLUQuery] () -RETURNS NVARCHAR(MAX) AS + +CREATE FUNCTION [dbo].[WOSQL_BuildRevenueDetailOLUQuery] () +RETURNS NVARCHAR(MAX) AS BEGIN - DECLARE @TSQL NVARCHAR(MAX) - DECLARE @STATION_INTS_TABLE TABLE (STATION_INT INT) + DECLARE @TSQL NVARCHAR(MAX) + DECLARE @STATION_INTS_TABLE TABLE (STATION_INT INT) DECLARE @STATION_INT INT SET @TSQL = '' - DECLARE CUR_NETWORK CURSOR LOCAL FOR - SELECT STATION_INT FROM @STATION_INTS_TABLE OPEN CUR_NETWORK + DECLARE CUR_NETWORK CURSOR LOCAL FOR + SELECT STATION_INT FROM @STATION_INTS_TABLE OPEN CUR_NETWORK FETCH NEXT FROM CUR_NETWORK INTO @STATION_INT - RETURN @TSQL END GO @@ -536,7 +536,7 @@ nvarchar ~~ERROR (Message: Throw error)~~ -DROP FUNCTION [dbo].[WOSQL_BuildRevenueDetailOLUQuery] +DROP FUNCTION [dbo].[WOSQL_BuildRevenueDetailOLUQuery] GO @@ -571,3 +571,52 @@ nvarchar DROP FUNCTION [dbo].[WOSQL_BuildRevenueDetailOLUQuery] GO + +------------------------------------------------------------------------------- +-- BABEL-4267: Error should not cause crash +------------------------------------------------------------------------------- +CREATE PROCEDURE usp_PopulateDiscount +AS + DECLARE @Lookup TABLE (StartDate DATETIME NOT NULL) + INSERT INTO @Lookup SELECT GETDATE() + BEGIN TRANSACTION + DELETE trgt FROM Discount trgt -- Discount does not exist + COMMIT +go +~~ERROR (Code: 2714)~~ + +~~ERROR (Message: function "usp_populatediscount" already exists with same argument types)~~ + + +EXECUTE usp_PopulateDiscount +go +~~ROW COUNT: 1~~ + +~~ERROR (Code: 33557097)~~ + +~~ERROR (Message: relation "discount" does not exist)~~ + + +CREATE PROCEDURE test +AS +BEGIN TRY + DECLARE @tv1 TABLE(c1 INT PRIMARY KEY, b INT IDENTITY, c CHAR(15) DEFAULT 'Whoops!') + SELECT 1/0 +END TRY +BEGIN CATCH + BEGIN TRANSACTION + INSERT INTO @tv1 VALUES(1, 3, 'Three') -- invalid syntax, should do a clean shutdown + COMMIT +END CATCH; +GO +~~ERROR (Code: 2714)~~ + +~~ERROR (Message: function "test" already exists with same argument types)~~ + + +exec test +go +~~ERROR (Code: 33557097)~~ + +~~ERROR (Message: INSERT has more expressions than target columns)~~ + diff --git a/test/JDBC/expected/table_variable_xact_errors_xact_abort_on.out b/test/JDBC/expected/table_variable_xact_errors_xact_abort_on.out index 2d2a815de4..3cc08659ff 100644 --- a/test/JDBC/expected/table_variable_xact_errors_xact_abort_on.out +++ b/test/JDBC/expected/table_variable_xact_errors_xact_abort_on.out @@ -443,13 +443,13 @@ GO ------------------------------------------------------------------------------- --- Cursor not explicitly closed +-- Cursor not explicitly closed ------------------------------------------------------------------------------- -DECLARE @STATION_INTS_TABLE TABLE (STATION_INT INT) -DECLARE @v INT -DECLARE CUR_NETWORK CURSOR LOCAL FOR SELECT STATION_INT FROM @STATION_INTS_TABLE -OPEN CUR_NETWORK -FETCH NEXT FROM CUR_NETWORK INTO @v +DECLARE @STATION_INTS_TABLE TABLE (STATION_INT INT) +DECLARE @v INT +DECLARE CUR_NETWORK CURSOR LOCAL FOR SELECT STATION_INT FROM @STATION_INTS_TABLE +OPEN CUR_NETWORK +FETCH NEXT FROM CUR_NETWORK INTO @v GO select 123 @@ -460,16 +460,16 @@ int ~~END~~ -CREATE FUNCTION [dbo].[WOSQL_BuildRevenueDetailOLUQuery] () -RETURNS NVARCHAR(MAX) AS + +CREATE FUNCTION [dbo].[WOSQL_BuildRevenueDetailOLUQuery] () +RETURNS NVARCHAR(MAX) AS BEGIN - DECLARE @TSQL NVARCHAR(MAX) - DECLARE @STATION_INTS_TABLE TABLE (STATION_INT INT) + DECLARE @TSQL NVARCHAR(MAX) + DECLARE @STATION_INTS_TABLE TABLE (STATION_INT INT) DECLARE @STATION_INT INT SET @TSQL = '' - DECLARE CUR_NETWORK CURSOR LOCAL FOR - SELECT STATION_INT FROM @STATION_INTS_TABLE OPEN CUR_NETWORK + DECLARE CUR_NETWORK CURSOR LOCAL FOR + SELECT STATION_INT FROM @STATION_INTS_TABLE OPEN CUR_NETWORK FETCH NEXT FROM CUR_NETWORK INTO @STATION_INT - RETURN @TSQL END GO @@ -518,7 +518,7 @@ nvarchar ~~ERROR (Message: Throw error)~~ -DROP FUNCTION [dbo].[WOSQL_BuildRevenueDetailOLUQuery] +DROP FUNCTION [dbo].[WOSQL_BuildRevenueDetailOLUQuery] GO @@ -553,3 +553,52 @@ nvarchar DROP FUNCTION [dbo].[WOSQL_BuildRevenueDetailOLUQuery] GO + +------------------------------------------------------------------------------- +-- BABEL-4267: Error should not cause crash +------------------------------------------------------------------------------- +CREATE PROCEDURE usp_PopulateDiscount +AS + DECLARE @Lookup TABLE (StartDate DATETIME NOT NULL) + INSERT INTO @Lookup SELECT GETDATE() + BEGIN TRANSACTION + DELETE trgt FROM Discount trgt -- Discount does not exist + COMMIT +go +~~ERROR (Code: 2714)~~ + +~~ERROR (Message: function "usp_populatediscount" already exists with same argument types)~~ + + +EXECUTE usp_PopulateDiscount +go +~~ROW COUNT: 1~~ + +~~ERROR (Code: 33557097)~~ + +~~ERROR (Message: relation "discount" does not exist)~~ + + +CREATE PROCEDURE test +AS +BEGIN TRY + DECLARE @tv1 TABLE(c1 INT PRIMARY KEY, b INT IDENTITY, c CHAR(15) DEFAULT 'Whoops!') + SELECT 1/0 +END TRY +BEGIN CATCH + BEGIN TRANSACTION + INSERT INTO @tv1 VALUES(1, 3, 'Three') -- invalid syntax, should do a clean shutdown + COMMIT +END CATCH; +GO +~~ERROR (Code: 2714)~~ + +~~ERROR (Message: function "test" already exists with same argument types)~~ + + +exec test +go +~~ERROR (Code: 33557097)~~ + +~~ERROR (Message: INSERT has more expressions than target columns)~~ + diff --git a/test/JDBC/input/table_variables/table-variable-vu-cleanup.sql b/test/JDBC/input/table_variables/table-variable-vu-cleanup.sql index cf26e12984..0ca455f18b 100644 --- a/test/JDBC/input/table_variables/table-variable-vu-cleanup.sql +++ b/test/JDBC/input/table_variables/table-variable-vu-cleanup.sql @@ -58,4 +58,14 @@ go drop schema table_variable_vu_schema go drop function table_variable_vu_func2 -go \ No newline at end of file +go + +-- BABEL-4337 - nested tv +DROP FUNCTION tv_nested_func2 +GO + +DROP FUNCTION tv_nested_func1 +GO + +DROP TYPE tv_nested_type +GO diff --git a/test/JDBC/input/table_variables/table-variable-vu-prepare.sql b/test/JDBC/input/table_variables/table-variable-vu-prepare.sql index 50020889e6..5751d93362 100644 --- a/test/JDBC/input/table_variables/table-variable-vu-prepare.sql +++ b/test/JDBC/input/table_variables/table-variable-vu-prepare.sql @@ -224,4 +224,12 @@ BEGIN INSERT @SomeTable SELECT 1234, 'abcd' RETURN END -go \ No newline at end of file +go + +-- BABEL-4337 - nested TV, null check in tblname +CREATE TYPE tv_nested_type AS TABLE (a INT) +GO +CREATE FUNCTION tv_nested_func1 (@t tv_nested_type readonly) RETURNS @a TABLE (y INT) AS BEGIN; INSERT INTO @a SELECT x FROM @t; RETURN; END; +GO +CREATE FUNCTION tv_nested_func2 (@t tv_nested_type readonly) RETURNS @a TABLE (x INT) AS BEGIN; INSERT INTO @a SELECT y FROM tv_nested_func1(@t); RETURN; END; +GO diff --git a/test/JDBC/input/table_variables/table-variable-vu-verify.sql b/test/JDBC/input/table_variables/table-variable-vu-verify.sql index a443dc1f4f..6fbdbdfe3d 100644 --- a/test/JDBC/input/table_variables/table-variable-vu-verify.sql +++ b/test/JDBC/input/table_variables/table-variable-vu-verify.sql @@ -97,4 +97,8 @@ go select * from table_variable_vu_func2() select typbyval from pg_catalog.pg_type where typname like '@sometable_table_variable_vu_func2%'; -go \ No newline at end of file +go + +-- BABEL-4337 - check nested TV for null; should not crash but throw an error +SELECT * FROM tv_nested_func2(NULL) +go diff --git a/test/JDBC/input/table_variables/table_variable_xact_errors.sql b/test/JDBC/input/table_variables/table_variable_xact_errors.sql index baf6aedd14..37c29a9e98 100644 --- a/test/JDBC/input/table_variables/table_variable_xact_errors.sql +++ b/test/JDBC/input/table_variables/table_variable_xact_errors.sql @@ -312,30 +312,30 @@ DROP TYPE typb GO ------------------------------------------------------------------------------- --- Cursor not explicitly closed +-- Cursor not explicitly closed ------------------------------------------------------------------------------- -DECLARE @STATION_INTS_TABLE TABLE (STATION_INT INT) -DECLARE @v INT +DECLARE @STATION_INTS_TABLE TABLE (STATION_INT INT) +DECLARE @v INT -DECLARE CUR_NETWORK CURSOR LOCAL FOR SELECT STATION_INT FROM @STATION_INTS_TABLE -OPEN CUR_NETWORK -FETCH NEXT FROM CUR_NETWORK INTO @v +DECLARE CUR_NETWORK CURSOR LOCAL FOR SELECT STATION_INT FROM @STATION_INTS_TABLE +OPEN CUR_NETWORK +FETCH NEXT FROM CUR_NETWORK INTO @v GO select 123 GO -CREATE FUNCTION [dbo].[WOSQL_BuildRevenueDetailOLUQuery] () -RETURNS NVARCHAR(MAX) AS +CREATE FUNCTION [dbo].[WOSQL_BuildRevenueDetailOLUQuery] () +RETURNS NVARCHAR(MAX) AS BEGIN - DECLARE @TSQL NVARCHAR(MAX) - DECLARE @STATION_INTS_TABLE TABLE (STATION_INT INT) + DECLARE @TSQL NVARCHAR(MAX) + DECLARE @STATION_INTS_TABLE TABLE (STATION_INT INT) DECLARE @STATION_INT INT SET @TSQL = '' - DECLARE CUR_NETWORK CURSOR LOCAL FOR - SELECT STATION_INT FROM @STATION_INTS_TABLE OPEN CUR_NETWORK + DECLARE CUR_NETWORK CURSOR LOCAL FOR + SELECT STATION_INT FROM @STATION_INTS_TABLE OPEN CUR_NETWORK FETCH NEXT FROM CUR_NETWORK INTO @STATION_INT - + RETURN @TSQL END GO @@ -368,7 +368,7 @@ GO SELECT dbo.WOSQL_BuildRevenueDetailOLUQuery() GO -DROP FUNCTION [dbo].[WOSQL_BuildRevenueDetailOLUQuery] +DROP FUNCTION [dbo].[WOSQL_BuildRevenueDetailOLUQuery] GO CREATE FUNCTION [dbo].[WOSQL_BuildRevenueDetailOLUQuery] () @@ -397,3 +397,34 @@ GO DROP FUNCTION [dbo].[WOSQL_BuildRevenueDetailOLUQuery] GO +------------------------------------------------------------------------------- +-- BABEL-4267: Error should not cause crash +------------------------------------------------------------------------------- + +CREATE PROCEDURE usp_PopulateDiscount +AS + DECLARE @Lookup TABLE (StartDate DATETIME NOT NULL) + INSERT INTO @Lookup SELECT GETDATE() + BEGIN TRANSACTION + DELETE trgt FROM Discount trgt -- Discount does not exist + COMMIT +go + +EXECUTE usp_PopulateDiscount +go + +CREATE PROCEDURE test +AS +BEGIN TRY + DECLARE @tv1 TABLE(c1 INT PRIMARY KEY, b INT IDENTITY, c CHAR(15) DEFAULT 'Whoops!') + SELECT 1/0 +END TRY +BEGIN CATCH + BEGIN TRANSACTION + INSERT INTO @tv1 VALUES(1, 3, 'Three') -- invalid syntax, should do a clean shutdown + COMMIT +END CATCH; +GO + +exec test +go \ No newline at end of file