Skip to content

Commit 8fef935

Browse files
committed
Added pg endpoint tests, also did a fix as the PG endpoint runs without logical-DB, create_insert_exec_temp_table and pltsql_insert_exec_open_target_table
now resolve the physical schema only when a DB context exists; with none and no explicit schema, the target is referenced by its bare name and resolved via search_path, matching the flush path and a plain INSERT. The TDS path is unchanged.
1 parent cbaf680 commit 8fef935

9 files changed

Lines changed: 242 additions & 28 deletions

contrib/babelfishpg_tsql/src/pl_exec.c

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -442,9 +442,9 @@ static pltsql_CastHashEntry *get_cast_hashentry(PLtsql_execstate *estate,
442442
Oid srctype, int32 srctypmod,
443443
Oid dsttype, int32 dsttypmod);
444444
static void exec_init_tuple_store(PLtsql_execstate *estate);
445-
void exec_set_found(PLtsql_execstate *estate, bool state);
445+
static void exec_set_found(PLtsql_execstate *estate, bool state);
446446
static void exec_set_fetch_status(PLtsql_execstate *estate, int status);
447-
void exec_set_rowcount(uint64 rowno);
447+
static void exec_set_rowcount(uint64 rowno);
448448
static void exec_set_error(PLtsql_execstate *estate, int error, int pg_error, bool error_mapping_failed);
449449
static void pltsql_create_econtext(PLtsql_execstate *estate);
450450
static void pltsql_commit_not_required_impl_txn(PLtsql_execstate *estate);

contrib/babelfishpg_tsql/src/pl_insert_exec.c

Lines changed: 28 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -74,9 +74,6 @@ static void insertexec_destroy(DestReceiver *self);
7474
*/
7575
InsertExecContext *insert_exec_ctx = NULL;
7676
PLtsql_execstate *insert_exec_flush_estate = NULL;
77-
78-
extern void exec_set_rowcount(uint64 rowno);
79-
extern void exec_set_found(PLtsql_execstate *estate, bool state);
8077
/*
8178
* The flush INSERT is routed through execute_batch (the top-level batch entry
8279
* point). It runs through the same econtext setup as a normal T-SQL batch.
@@ -268,19 +265,20 @@ pltsql_insert_exec_open_target_table(const char *target_table,
268265
char *schema_name = NULL;
269266
char *table_name = NULL;
270267
char *physical_schema = NULL;
268+
char *db = NULL;
271269

272270
if (target_table == NULL)
273271
return;
274272

275273
table_name = pstrdup(target_table);
276-
schema_name = resolve_insert_exec_schema_name(schema_name_in, db_name_in);
277-
/*
278-
* Resolve against the target's database when a 3-part name
279-
* (db..table) was used; otherwise the current database.
280-
*/
281-
physical_schema = get_physical_schema_name(
282-
(db_name_in != NULL) ? (char *) db_name_in : get_cur_db_name(),
283-
schema_name);
274+
db = (db_name_in != NULL) ? pstrdup(db_name_in) : get_cur_db_name();
275+
if (db != NULL && db[0] != '\0')
276+
{
277+
schema_name = resolve_insert_exec_schema_name(schema_name_in, db);
278+
physical_schema = get_physical_schema_name(db, schema_name);
279+
}
280+
if (db != NULL)
281+
pfree(db);
284282

285283
/* Create RangeVar and get the relation OID */
286284
rv = makeRangeVar(physical_schema, table_name, -1);
@@ -451,14 +449,25 @@ create_insert_exec_temp_table(const char *target_table, const char *column_list,
451449
*/
452450
if (!(target_table[0] == '#' || target_table[0] == '@'))
453451
{
454-
char *sname = resolve_insert_exec_schema_name(schema_name_in, db_name_in);
455-
456-
physical_schema = get_physical_schema_name(
457-
(db_name_in != NULL) ? (char *) db_name_in : get_cur_db_name(), sname);
458-
pfree(sname);
459-
if (physical_schema == NULL)
460-
elog(ERROR, "INSERT EXEC failed due to unresolvable schema for target table \"%s\"",
461-
target_table);
452+
char *db = (db_name_in != NULL) ? pstrdup(db_name_in) : get_cur_db_name();
453+
/*
454+
* On the PostgreSQL endpoint a T-SQL procedure runs without logical
455+
* database context (fn_dbid is InvalidDbid for non-TDS connections),
456+
* so the current database name can be empty. With no DB context, leave
457+
* physical_schema NULL and reference the target by its bare name, so
458+
* search_path resolves it - exactly as a plain INSERT does.
459+
*/
460+
if (db != NULL && db[0] != '\0')
461+
{
462+
char *sname = resolve_insert_exec_schema_name(schema_name_in, db);
463+
physical_schema = get_physical_schema_name(db, sname);
464+
pfree(sname);
465+
if (physical_schema == NULL)
466+
elog(ERROR, "INSERT EXEC failed due to unresolvable schema for target table \"%s\"",
467+
target_table);
468+
}
469+
if (db != NULL)
470+
pfree(db);
462471
}
463472

464473
/*
@@ -621,8 +630,6 @@ flush_insert_exec_temp_table(PLtsql_execstate *estate, const char *target_schema
621630
* Report rows-affected from the DestReceiver's captured-row count
622631
*/
623632
estate->eval_processed = insert_exec_ctx->rows_processed;
624-
exec_set_rowcount(insert_exec_ctx->rows_processed);
625-
exec_set_found(estate, insert_exec_ctx->rows_processed != 0);
626633
}
627634

628635
/*
Lines changed: 121 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,121 @@
1+
2+
-- tsql
3+
-- This test verifies INSERT EXEC works when the enclosing T-SQL procedure is
4+
-- created on the Babelfish (TDS) endpoint but invoked from the PostgreSQL
5+
-- endpoint. The flush goes through execute_batch regardless of the entry point,
6+
-- so the buffered result set must still land in the target table.
7+
CREATE TABLE babel_ie_pg_src (id INT, val VARCHAR(20));
8+
GO
9+
INSERT INTO babel_ie_pg_src VALUES (1, 'alpha'), (2, 'beta'), (3, 'gamma');
10+
GO
11+
~~ROW COUNT: 3~~
12+
13+
14+
CREATE TABLE babel_ie_pg_dst (id INT, val VARCHAR(20));
15+
GO
16+
17+
-- Source procedure produces a result set
18+
CREATE PROCEDURE babel_ie_pg_source AS
19+
BEGIN
20+
SELECT id, val FROM babel_ie_pg_src ORDER BY id;
21+
END
22+
GO
23+
24+
-- Wrapper procedure buffers the result set into the target via INSERT EXEC
25+
CREATE PROCEDURE babel_ie_pg_wrapper AS
26+
BEGIN
27+
INSERT INTO babel_ie_pg_dst EXEC babel_ie_pg_source;
28+
END
29+
GO
30+
31+
-- Call the wrapper once from the TDS endpoint as a baseline
32+
EXEC babel_ie_pg_wrapper;
33+
GO
34+
~~ROW COUNT: 3~~
35+
36+
SELECT id, val FROM babel_ie_pg_dst ORDER BY id;
37+
GO
38+
~~START~~
39+
int#!#varchar
40+
1#!#alpha
41+
2#!#beta
42+
3#!#gamma
43+
~~END~~
44+
45+
46+
-- Empty the target so the PG-endpoint call starts clean
47+
DELETE FROM babel_ie_pg_dst;
48+
GO
49+
~~ROW COUNT: 3~~
50+
51+
52+
-- psql currentSchema=master_dbo,public
53+
-- Invoke the T-SQL procedure from the PostgreSQL endpoint
54+
CALL master_dbo.babel_ie_pg_wrapper();
55+
GO
56+
57+
-- Rows buffered by INSERT EXEC must be present in the target table
58+
SELECT id, val FROM master_dbo.babel_ie_pg_dst ORDER BY id;
59+
GO
60+
~~START~~
61+
int4#!#"sys"."varchar"
62+
1#!#alpha
63+
2#!#beta
64+
3#!#gamma
65+
~~END~~
66+
67+
68+
-- Clear the target again before the transaction cases
69+
DELETE FROM master_dbo.babel_ie_pg_dst;
70+
GO
71+
~~ROW COUNT: 3~~
72+
73+
74+
-- INSERT EXEC inside an explicit committed transaction on the PG endpoint:
75+
-- the buffered rows must persist after COMMIT.
76+
BEGIN;
77+
GO
78+
CALL master_dbo.babel_ie_pg_wrapper();
79+
GO
80+
COMMIT;
81+
GO
82+
SELECT id, val FROM master_dbo.babel_ie_pg_dst ORDER BY id;
83+
GO
84+
~~START~~
85+
int4#!#"sys"."varchar"
86+
1#!#alpha
87+
2#!#beta
88+
3#!#gamma
89+
~~END~~
90+
91+
92+
-- Clear the target before the rollback case
93+
DELETE FROM master_dbo.babel_ie_pg_dst;
94+
GO
95+
~~ROW COUNT: 3~~
96+
97+
98+
-- INSERT EXEC inside an explicit transaction that is rolled back on the PG
99+
-- endpoint: the buffered rows must be discarded, leaving the target empty.
100+
BEGIN;
101+
GO
102+
CALL master_dbo.babel_ie_pg_wrapper();
103+
GO
104+
ROLLBACK;
105+
GO
106+
SELECT id, val FROM master_dbo.babel_ie_pg_dst ORDER BY id;
107+
GO
108+
~~START~~
109+
int4#!#"sys"."varchar"
110+
~~END~~
111+
112+
113+
-- tsql
114+
DROP PROCEDURE babel_ie_pg_wrapper;
115+
GO
116+
DROP PROCEDURE babel_ie_pg_source;
117+
GO
118+
DROP TABLE babel_ie_pg_dst;
119+
GO
120+
DROP TABLE babel_ie_pg_src;
121+
GO

test/JDBC/expected/temp_table_rollback-vu-prepare.out

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -202,7 +202,7 @@ BEGIN
202202
CREATE TABLE #proc_create(id int, name varchar(30))
203203
INSERT INTO #proc_create VALUES (1, 'first')
204204
INSERT INTO #proc_create VALUES (2, 'second')
205-
SELECT * FROM #proc_create
205+
SELECT * FROM #proc_create ORDER BY id
206206
DROP TABLE #proc_create
207207
END
208208
GO

test/JDBC/expected/temp_table_rollback_isolation_read_uncommitted.out

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -204,7 +204,7 @@ BEGIN
204204
CREATE TABLE #proc_create(id int, name varchar(30))
205205
INSERT INTO #proc_create VALUES (1, 'first')
206206
INSERT INTO #proc_create VALUES (2, 'second')
207-
SELECT * FROM #proc_create
207+
SELECT * FROM #proc_create ORDER BY id
208208
DROP TABLE #proc_create
209209
END
210210
GO

test/JDBC/expected/temp_table_rollback_isolation_snapshot.out

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -204,7 +204,7 @@ BEGIN
204204
CREATE TABLE #proc_create(id int, name varchar(30))
205205
INSERT INTO #proc_create VALUES (1, 'first')
206206
INSERT INTO #proc_create VALUES (2, 'second')
207-
SELECT * FROM #proc_create
207+
SELECT * FROM #proc_create ORDER BY id
208208
DROP TABLE #proc_create
209209
END
210210
GO

test/JDBC/expected/temp_table_rollback_xact_abort_on.out

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -204,7 +204,7 @@ BEGIN
204204
CREATE TABLE #proc_create(id int, name varchar(30))
205205
INSERT INTO #proc_create VALUES (1, 'first')
206206
INSERT INTO #proc_create VALUES (2, 'second')
207-
SELECT * FROM #proc_create
207+
SELECT * FROM #proc_create ORDER BY id
208208
DROP TABLE #proc_create
209209
END
210210
GO
Lines changed: 86 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,86 @@
1+
-- This test verifies INSERT EXEC works when the enclosing T-SQL procedure is
2+
-- created on the Babelfish (TDS) endpoint but invoked from the PostgreSQL
3+
-- endpoint. The flush goes through execute_batch regardless of the entry point,
4+
-- so the buffered result set must still land in the target table.
5+
6+
-- tsql
7+
CREATE TABLE babel_ie_pg_src (id INT, val VARCHAR(20));
8+
GO
9+
INSERT INTO babel_ie_pg_src VALUES (1, 'alpha'), (2, 'beta'), (3, 'gamma');
10+
GO
11+
12+
CREATE TABLE babel_ie_pg_dst (id INT, val VARCHAR(20));
13+
GO
14+
15+
-- Source procedure produces a result set
16+
CREATE PROCEDURE babel_ie_pg_source AS
17+
BEGIN
18+
SELECT id, val FROM babel_ie_pg_src ORDER BY id;
19+
END
20+
GO
21+
22+
-- Wrapper procedure buffers the result set into the target via INSERT EXEC
23+
CREATE PROCEDURE babel_ie_pg_wrapper AS
24+
BEGIN
25+
INSERT INTO babel_ie_pg_dst EXEC babel_ie_pg_source;
26+
END
27+
GO
28+
29+
-- Call the wrapper once from the TDS endpoint as a baseline
30+
EXEC babel_ie_pg_wrapper;
31+
GO
32+
SELECT id, val FROM babel_ie_pg_dst ORDER BY id;
33+
GO
34+
35+
-- Empty the target so the PG-endpoint call starts clean
36+
DELETE FROM babel_ie_pg_dst;
37+
GO
38+
39+
-- psql currentSchema=master_dbo,public
40+
-- Invoke the T-SQL procedure from the PostgreSQL endpoint
41+
CALL master_dbo.babel_ie_pg_wrapper();
42+
GO
43+
44+
-- Rows buffered by INSERT EXEC must be present in the target table
45+
SELECT id, val FROM master_dbo.babel_ie_pg_dst ORDER BY id;
46+
GO
47+
48+
-- Clear the target again before the transaction cases
49+
DELETE FROM master_dbo.babel_ie_pg_dst;
50+
GO
51+
52+
-- INSERT EXEC inside an explicit committed transaction on the PG endpoint:
53+
-- the buffered rows must persist after COMMIT.
54+
BEGIN;
55+
GO
56+
CALL master_dbo.babel_ie_pg_wrapper();
57+
GO
58+
COMMIT;
59+
GO
60+
SELECT id, val FROM master_dbo.babel_ie_pg_dst ORDER BY id;
61+
GO
62+
63+
-- Clear the target before the rollback case
64+
DELETE FROM master_dbo.babel_ie_pg_dst;
65+
GO
66+
67+
-- INSERT EXEC inside an explicit transaction that is rolled back on the PG
68+
-- endpoint: the buffered rows must be discarded, leaving the target empty.
69+
BEGIN;
70+
GO
71+
CALL master_dbo.babel_ie_pg_wrapper();
72+
GO
73+
ROLLBACK;
74+
GO
75+
SELECT id, val FROM master_dbo.babel_ie_pg_dst ORDER BY id;
76+
GO
77+
78+
-- tsql
79+
DROP PROCEDURE babel_ie_pg_wrapper;
80+
GO
81+
DROP PROCEDURE babel_ie_pg_source;
82+
GO
83+
DROP TABLE babel_ie_pg_dst;
84+
GO
85+
DROP TABLE babel_ie_pg_src;
86+
GO

test/JDBC/input/temp_tables/temp_table_rollback-vu-prepare.sql

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -202,7 +202,7 @@ BEGIN
202202
CREATE TABLE #proc_create(id int, name varchar(30))
203203
INSERT INTO #proc_create VALUES (1, 'first')
204204
INSERT INTO #proc_create VALUES (2, 'second')
205-
SELECT * FROM #proc_create
205+
SELECT * FROM #proc_create ORDER BY id
206206
DROP TABLE #proc_create
207207
END
208208
GO

0 commit comments

Comments
 (0)