Skip to content

Commit 5618379

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 5618379

3 files changed

Lines changed: 235 additions & 16 deletions

File tree

contrib/babelfishpg_tsql/src/pl_insert_exec.c

Lines changed: 28 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -268,19 +268,20 @@ pltsql_insert_exec_open_target_table(const char *target_table,
268268
char *schema_name = NULL;
269269
char *table_name = NULL;
270270
char *physical_schema = NULL;
271+
char *db = NULL;
271272

272273
if (target_table == NULL)
273274
return;
274275

275276
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);
277+
db = (db_name_in != NULL) ? pstrdup(db_name_in) : get_cur_db_name();
278+
if (db != NULL && db[0] != '\0')
279+
{
280+
schema_name = resolve_insert_exec_schema_name(schema_name_in, db);
281+
physical_schema = get_physical_schema_name(db, schema_name);
282+
}
283+
if (db != NULL)
284+
pfree(db);
284285

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

464476
/*
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
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

0 commit comments

Comments
 (0)