From 3a5334a56879ff620e0962515b57567a5e868b15 Mon Sep 17 00:00:00 2001 From: Shameem Ahmed <54461265+ahmed-shameem@users.noreply.github.com> Date: Thu, 18 Jan 2024 11:16:18 +0530 Subject: [PATCH] Fix database does not exists error when is_member(), schema_id() function gets called in parallel query mode. (#2242) This commit solves the issue of parallel worker not being able to obtain correct logical database name. Whenever get_cur_db_name() is called, it returns static char current_db_name[] which is initialised as empty. Now, parallel workers are not aware of the database name. For them, it is empty whenever get_cur_db_name() gets called. Hence, we were getting the following error: database "" does not exist So, to communicate the logical database name and more data related to babelfish we have introduced a struct BabelfishFixedParallelState. Currently BabelfishFixedParallelState has only 1 field, i.e., logical_db_name, we can add more fields to it whenever necessary. Then we will write the logical_db_name in DSM during initialisation (in InitializeParallelDSM) using a hook. Another hook is used while trying to fetch the logical database name in ParallelWorkerMain(). In this way we are introduction a mechanism through which we can communicate any babelfish related information to parallel workers. Engine PR: https://github.com/babelfish-for-postgresql/postgresql_modified_for_babelfish/pull/289 Issues Resolved BABEL-4538, BABEL-4481, BABEL-4421 Signed-off-by: Shameem Ahmed --- contrib/babelfishpg_tsql/src/hooks.c | 6 ++ contrib/babelfishpg_tsql/src/session.c | 81 ++++++++++++++++++++++++++ contrib/babelfishpg_tsql/src/session.h | 12 ++++ test/JDBC/parallel_query_jdbc_schedule | 27 +-------- 4 files changed, 100 insertions(+), 26 deletions(-) diff --git a/contrib/babelfishpg_tsql/src/hooks.c b/contrib/babelfishpg_tsql/src/hooks.c index 1e9b53dab7..ba02e37d13 100644 --- a/contrib/babelfishpg_tsql/src/hooks.c +++ b/contrib/babelfishpg_tsql/src/hooks.c @@ -327,6 +327,9 @@ InstallExtendedHooks(void) drop_relation_refcnt_hook = pltsql_drop_relation_refcnt_hook; select_common_type_hook = select_common_type_for_isnull; + + bbf_InitializeParallelDSM_hook = babelfixedparallelstate_insert; + bbf_ParallelWorkerMain_hook = babelfixedparallelstate_restore; } void @@ -378,6 +381,9 @@ UninstallExtendedHooks(void) IsToastClassHook = PrevIsToastClassHook; sortby_nulls_hook = prev_sortby_nulls_hook; drop_relation_refcnt_hook = prev_drop_relation_refcnt_hook; + + bbf_InitializeParallelDSM_hook = NULL; + bbf_ParallelWorkerMain_hook = NULL; } /***************************************** diff --git a/contrib/babelfishpg_tsql/src/session.c b/contrib/babelfishpg_tsql/src/session.c index 3810e521ed..d522e82cdd 100644 --- a/contrib/babelfishpg_tsql/src/session.c +++ b/contrib/babelfishpg_tsql/src/session.c @@ -16,6 +16,7 @@ #include "session.h" #include "pltsql.h" #include "guc.h" +#include "storage/shm_toc.h" /* Core Session Properties */ @@ -51,6 +52,30 @@ get_cur_db_name(void) return pstrdup(current_db_name); } +void +set_cur_db_name_for_parallel_worker(const char* logical_db_name) +{ + int len; + + if (logical_db_name == NULL) + ereport(ERROR, + (errcode(ERRCODE_UNDEFINED_DATABASE), + errmsg("database \"\" does not exist"))); + + len = strlen(logical_db_name); + + Assert(len <= MAX_BBF_NAMEDATALEND); + + if(!DbidIsValid(get_db_id(logical_db_name))) + ereport(ERROR, + (errcode(ERRCODE_UNDEFINED_DATABASE), + errmsg("database \"%s\" does not exist", logical_db_name))); + + strncpy(current_db_name, logical_db_name, MAX_BBF_NAMEDATALEND); + current_db_name[len] = '\0'; +} + + void set_cur_db(int16 id, const char *name) { @@ -369,3 +394,59 @@ initialize_context_table() session_context_table = hash_create("Session Context", 128, &hash_options, HASH_ELEM | HASH_STRINGS); } + +/* +* This function is responsible for estimating the size of the entry and the number of keys +* and insert into the DSM for parallel workers +* The first argument is ParallelContext which contains the info related to TOC +* The second argument indicates whether we want to estimate the space or +* we want to insert the data into DSM +*/ +void +babelfixedparallelstate_insert(ParallelContext *pcxt, bool estimate) +{ + BabelfishFixedParallelState *bfps; + int len; + char* current_db_name; + if (estimate) + { + /* Allow space to store the babelfish fixed-size parallel state. */ + shm_toc_estimate_chunk(&pcxt->estimator, sizeof(BabelfishFixedParallelState)); + shm_toc_estimate_keys(&pcxt->estimator, 1); + } + else + { + /* Initialize babelfish fixed-size state in shared memory. */ + bfps = (BabelfishFixedParallelState *) shm_toc_allocate(pcxt->toc, sizeof(BabelfishFixedParallelState)); + current_db_name = get_cur_db_name(); + + if (current_db_name == NULL) + ereport(ERROR, + (errcode(ERRCODE_UNDEFINED_DATABASE), + errmsg("database \"\" does not exist"))); + + if(!DbidIsValid(get_db_id(current_db_name))) + ereport(ERROR, + (errcode(ERRCODE_UNDEFINED_DATABASE), + errmsg("database \"%s\" does not exist", current_db_name))); + + len = strlen(current_db_name); + strncpy(bfps->logical_db_name, current_db_name, MAX_BBF_NAMEDATALEND); + bfps->logical_db_name[len] = '\0'; + shm_toc_insert(pcxt->toc, BABELFISH_PARALLEL_KEY_FIXED, bfps); + pfree(current_db_name); + } +} + +/* This function is responsible for restoring the babelfixedparallelstate*/ +void +babelfixedparallelstate_restore(shm_toc *toc) +{ + BabelfishFixedParallelState *bfps; + + /* Get the babelfish fixed parallel state from DSM */ + bfps = shm_toc_lookup(toc, BABELFISH_PARALLEL_KEY_FIXED, false); + + /* Set the logcial db name for parallel workers */ + set_cur_db_name_for_parallel_worker(bfps->logical_db_name); +} \ No newline at end of file diff --git a/contrib/babelfishpg_tsql/src/session.h b/contrib/babelfishpg_tsql/src/session.h index 32de3f8427..c5d17cb161 100644 --- a/contrib/babelfishpg_tsql/src/session.h +++ b/contrib/babelfishpg_tsql/src/session.h @@ -1,6 +1,8 @@ #ifndef SESSION_H #define SESSION_H #include "postgres.h" +#include "multidb.h" +#include "access/parallel.h" extern int16 get_cur_db_id(void); extern void set_cur_db(int16 id, const char *name); @@ -11,5 +13,15 @@ extern void check_session_db_access(const char *dn_name); extern void set_cur_user_db_and_path(const char *db_name); extern void restore_session_properties(void); extern void reset_session_properties(void); +extern void set_cur_db_name_for_parallel_worker(const char* logical_db_name); + +/* Hooks for parallel workers for babelfish fixed state */ +extern void babelfixedparallelstate_insert(ParallelContext *pcxt, bool estimate); +extern void babelfixedparallelstate_restore(shm_toc *toc); + +/* Babelfish Fixed-size parallel state */ +typedef struct BabelfishFixedParallelState { + char logical_db_name[MAX_BBF_NAMEDATALEND + 1]; +} BabelfishFixedParallelState; #endif diff --git a/test/JDBC/parallel_query_jdbc_schedule b/test/JDBC/parallel_query_jdbc_schedule index 2916bbfdf5..4a8315a1fb 100644 --- a/test/JDBC/parallel_query_jdbc_schedule +++ b/test/JDBC/parallel_query_jdbc_schedule @@ -6,28 +6,8 @@ # 5. To add a test, add test name (without extension, , and . For example if test file name is TestBigInt.txt write TestBigInt) on a new line # These tests are crashing/failing with parallel query mode is on. -# Group 1: BABEL-4481 -ignore#!#Test-sp_addrolemember-vu-prepare -ignore#!#Test-sp_addrolemember-vu-verify -ignore#!#Test-sp_addrolemember-vu-cleanup -ignore#!#Test-sp_droprolemember-vu-prepare -ignore#!#Test-sp_droprolemember-vu-verify -ignore#!#Test-sp_droprolemember-vu-cleanup -ignore#!#babel_datatype_sqlvariant-vu-verify - ignore#!#table-variable-vu-verify -# Other or mixed issues - JIRA-BABEL-4538 -# database "" does not exists. (calls is_member() functions) -ignore#!#BABEL-1621 -# database "" does not exists. (calls schema_id()) -ignore#!#BABEL-741-vu-verify -ignore#!#BABEL-2416 -ignore#!#BABEL-2833 -# database "" does not exists. (calls IS_ROLEMEMBER()) -ignore#!#BABEL-ROLE-MEMBER-vu-verify -ignore#!#BABEL-ROLE-MEMBER - # JIRA - BABEL-4419 ignore#!#BABEL-1056 ignore#!#BABEL-GUC-PLAN @@ -36,12 +16,7 @@ ignore#!#BABEL-COLUMN-CONSTRAINT ignore#!#BABEL-1251-vu-verify ignore#!#BABEL-1251 -# JIRA - BABEL-4421 -ignore#!#Test-sp_addrolemember-dep-vu-verify -ignore#!#Test-sp_droprolemember-dep-vu-verify -ignore#!#babel_table_type - -# These test should not ger run in parallel query +# These test should not get run in parallel query ignore#!#BABEL-1363 # Taking too much time to complete. (TIME-OUT FAILURES)