Skip to content

Commit e23f7fc

Browse files
authored
Replace direct USE DB execution with API invokation (#4546) (#4558) (#4559)
With this commit we replace direct USE DB execution with API invocation during login. Bolstering the login process. Task: BABEL-6346 Signed-off-by: Kushaal Shroff kushaal@amazon.com Co-authored-by: Mohit Raj <mrxmohit@amazon.com> (cherry picked from commit 54fa74e)
1 parent 74e8de3 commit e23f7fc

File tree

5 files changed

+42
-17
lines changed

5 files changed

+42
-17
lines changed

contrib/babelfishpg_tds/src/backend/tds/tdslogin.c

Lines changed: 5 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -2033,10 +2033,9 @@ TdsProcessLogin(Port *port, bool loadedSsl)
20332033
void
20342034
TdsSetDbContext()
20352035
{
2036-
char *dbname = NULL;
2037-
char *useDbCommand = NULL;
2038-
char *user = NULL;
2039-
MemoryContext oldContext = CurrentMemoryContext;
2036+
char *dbname = NULL;
2037+
char *user = NULL;
2038+
MemoryContext oldContext = CurrentMemoryContext;
20402039

20412040
PG_TRY();
20422041
{
@@ -2059,11 +2058,6 @@ TdsSetDbContext()
20592058
(errcode(ERRCODE_UNDEFINED_DATABASE),
20602059
errmsg("database \"%s\" does not exist", loginInfo->database)));
20612060

2062-
/*
2063-
* Any delimitated/quoted db name identifier requested in login
2064-
* must be already handled before this point.
2065-
*/
2066-
useDbCommand = psprintf("USE [%s]", loginInfo->database);
20672061
dbname = pstrdup(loginInfo->database);
20682062
}
20692063
else
@@ -2078,8 +2072,6 @@ TdsSetDbContext()
20782072
ereport(ERROR,
20792073
(errcode(ERRCODE_UNDEFINED_DATABASE),
20802074
errmsg("could not find default database for user \"%s\"", loginInfo->username)));
2081-
2082-
useDbCommand = psprintf("USE [%s]", temp);
20832075
dbname = pstrdup(temp);
20842076
CommitTransactionCommand();
20852077
MemoryContextSwitchTo(oldContext);
@@ -2096,10 +2088,9 @@ TdsSetDbContext()
20962088
errmsg("Cannot open database \"%s\" requested by the login. The login failed", dbname)));
20972089

20982090
/*
2099-
* loginInfo has a database name provided, so we execute a "USE
2100-
* [<db_name>]" through pltsql inline handler.
2091+
* Direct API invokation for switching database context.
21012092
*/
2102-
ExecuteSQLBatch(useDbCommand);
2093+
pltsql_plugin_handler_ptr->switch_database_context(dbname);
21032094
CommitTransactionCommand();
21042095
}
21052096
PG_CATCH();
@@ -2136,8 +2127,6 @@ TdsSetDbContext()
21362127
PG_RE_THROW();
21372128
}
21382129
PG_END_TRY();
2139-
if (useDbCommand)
2140-
pfree(useDbCommand);
21412130
if (dbname)
21422131
pfree(dbname);
21432132
}

contrib/babelfishpg_tsql/src/pl_handler.c

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3695,6 +3695,7 @@ _PG_init(void)
36953695
(*pltsql_protocol_plugin_ptr)->pltsql_get_logical_schema_name = &get_logical_schema_name;
36963696
(*pltsql_protocol_plugin_ptr)->pltsql_is_fmtonly_stmt = &pltsql_fmtonly;
36973697
(*pltsql_protocol_plugin_ptr)->pltsql_get_user_for_database = &get_user_for_database;
3698+
(*pltsql_protocol_plugin_ptr)->switch_database_context = &switch_database_context;
36983699
(*pltsql_protocol_plugin_ptr)->get_insert_bulk_rows_per_batch = &get_insert_bulk_rows_per_batch;
36993700
(*pltsql_protocol_plugin_ptr)->get_insert_bulk_kilobytes_per_batch = &get_insert_bulk_kilobytes_per_batch;
37003701
(*pltsql_protocol_plugin_ptr)->tsql_varchar_input = common_utility_plugin_ptr->tsql_varchar_input;

contrib/babelfishpg_tsql/src/pltsql.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1649,6 +1649,8 @@ typedef struct PLtsql_protocol_plugin
16491649

16501650
char *(*pltsql_get_user_for_database) (const char *db_name);
16511651

1652+
void (*switch_database_context) (const char *dbname);
1653+
16521654
char *(*TsqlEncodingConversion) (const char *s, int len, int encoding, int *encodedByteLen);
16531655

16541656
int (*TdsGetEncodingFromLcid) (int32_t lcid);

contrib/babelfishpg_tsql/src/session.c

Lines changed: 33 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -162,6 +162,38 @@ set_cur_user_db_and_path(const char *db_name)
162162
set_search_path_for_user_schema(db_name, user);
163163
}
164164

165+
/*
166+
* switch_database_context - Switching database context during login
167+
*
168+
* This function performs all necessary steps to securely switch database context:
169+
* 1. Validates user has access to the database
170+
* 2. Acquires session-level lock on the target database
171+
* 3. Sets the database, user, and search path
172+
*
173+
*/
174+
void
175+
switch_database_context(const char *dbname)
176+
{
177+
int16 new_db_id;
178+
179+
/* Validate user has access to the database */
180+
check_session_db_access(dbname);
181+
182+
/* Get database ID for lock acquisition */
183+
new_db_id = get_db_id(dbname);
184+
185+
/* Acquire session-level lock on the new database */
186+
if (!TryLockLogicalDatabaseForSession(new_db_id, ShareLock))
187+
ereport(ERROR,
188+
(errcode(ERRCODE_INTERNAL_ERROR),
189+
errmsg("Cannot use database \"%s\", failed to obtain lock. "
190+
"\"%s\" is probably undergoing DDL statements in another session.",
191+
dbname, dbname)));
192+
193+
/* Set database context, user, and search path */
194+
set_cur_user_db_and_path(dbname);
195+
}
196+
165197
static void
166198
set_search_path_for_user_schema(const char *db_name, const char *user)
167199
{
@@ -456,4 +488,4 @@ babelfixedparallelstate_restore(shm_toc *toc)
456488

457489
/* Set the logcial db name for parallel workers */
458490
set_cur_db_name_for_parallel_worker(bfps->logical_db_name);
459-
}
491+
}

contrib/babelfishpg_tsql/src/session.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@ extern void set_cur_user_db_and_path(const char *db_name);
1414
extern void restore_session_properties(void);
1515
extern void reset_session_properties(void);
1616
extern void set_cur_db_name_for_parallel_worker(const char* logical_db_name);
17+
extern void switch_database_context(const char *dbname);
1718

1819
/* Hooks for parallel workers for babelfish fixed state */
1920
extern void babelfixedparallelstate_insert(ParallelContext *pcxt, bool estimate);

0 commit comments

Comments
 (0)