From 70304e4521fec43af6989f5ec1ce63d7890e6f66 Mon Sep 17 00:00:00 2001 From: kritika-0601 <122882328+kritika-0601@users.noreply.github.com> Date: Fri, 31 Mar 2023 17:00:34 +0530 Subject: [PATCH 01/43] Update major-version-upgrade.yml --- .github/workflows/major-version-upgrade.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/major-version-upgrade.yml b/.github/workflows/major-version-upgrade.yml index 3aa6514a4f..a6783b9710 100644 --- a/.github/workflows/major-version-upgrade.yml +++ b/.github/workflows/major-version-upgrade.yml @@ -71,7 +71,7 @@ jobs: ~/${{env.OLD_INSTALL_DIR}}/bin/pg_ctl -D ~/${{env.OLD_INSTALL_DIR}}/data -l logfile13 start cd ${{env.OLD_INSTALL_DIR}}/data sudo sed -i "s/#listen_addresses = 'localhost'/listen_addresses = '*'/g" postgresql.conf - sudo sed -i "s/#shared_preload_libraries = ''/shared_preload_libraries = 'babelfishpg_tds'/g" postgresql.conf + sudo sed -i "s/#shared_preload_libraries = ''/shared_preload_libraries = 'babelfishpg_tds, pg_stat_statements'/g" postgresql.conf ipaddress=$(ifconfig eth0 | grep 'inet ' | cut -d: -f2 | awk '{ print $2}') sudo echo "host all all $ipaddress/32 trust" >> pg_hba.conf ~/${{env.OLD_INSTALL_DIR}}/bin/pg_ctl -D ~/${{env.OLD_INSTALL_DIR}}/data -l logfile13 restart From 1c4572c7a1c7d1d4eeae346533cc2bd4300275a9 Mon Sep 17 00:00:00 2001 From: Kritika Date: Fri, 31 Mar 2023 06:14:08 +0000 Subject: [PATCH 02/43] Transaction statements not visible in pg_stat_statements view Subsequent processutility hooks after bbf_processutilty are not being called. Created a hook for that and called it inside relevant ProcessUtility function. Signed-off-by: Kritika --- contrib/babelfishpg_tsql/src/hooks.c | 16 ++++++++++++++++ contrib/babelfishpg_tsql/src/hooks.h | 5 +++++ contrib/babelfishpg_tsql/src/pl_handler.c | 20 ++++++++++---------- 3 files changed, 31 insertions(+), 10 deletions(-) diff --git a/contrib/babelfishpg_tsql/src/hooks.c b/contrib/babelfishpg_tsql/src/hooks.c index bdcd1098d2..5292e000a2 100644 --- a/contrib/babelfishpg_tsql/src/hooks.c +++ b/contrib/babelfishpg_tsql/src/hooks.c @@ -127,6 +127,7 @@ static void insert_pltsql_function_defaults(HeapTuple func_tuple, List *defaults static int print_pltsql_function_arguments(StringInfo buf, HeapTuple proctup, bool print_table_args, bool print_defaults); static void pltsql_GetNewObjectId(VariableCache variableCache); static void pltsql_validate_var_datatype_scale(const TypeName *typeName, Type typ); +static void pltsql_transactionStmt(PlannedStmt *pstmt, ParamListInfo params, QueryCompletion *qc); /***************************************** * Executor Hooks @@ -188,6 +189,7 @@ static validate_var_datatype_scale_hook_type prev_validate_var_datatype_scale_ho static modify_RangeTblFunction_tupdesc_hook_type prev_modify_RangeTblFunction_tupdesc_hook = NULL; static fill_missing_values_in_copyfrom_hook_type prev_fill_missing_values_in_copyfrom_hook = NULL; static check_rowcount_hook_type prev_check_rowcount_hook = NULL; +static transactionStmt_hook_type prev_transactionStmt_hook = NULL; /***************************************** * Install / Uninstall @@ -298,6 +300,9 @@ InstallExtendedHooks(void) fill_missing_values_in_copyfrom_hook = fill_missing_values_in_copyfrom; prev_check_rowcount_hook = check_rowcount_hook; check_rowcount_hook = bbf_check_rowcount_hook; + + prev_transactionStmt_hook = transactionStmt_hook; + transactionStmt_hook = pltsql_transactionStmt; } void @@ -342,11 +347,22 @@ UninstallExtendedHooks(void) modify_RangeTblFunction_tupdesc_hook = prev_modify_RangeTblFunction_tupdesc_hook; fill_missing_values_in_copyfrom_hook = prev_fill_missing_values_in_copyfrom_hook; check_rowcount_hook = prev_check_rowcount_hook; + transactionStmt_hook = prev_transactionStmt_hook; } /***************************************** * Hook Functions *****************************************/ +static void +pltsql_transactionStmt(PlannedStmt *pstmt, ParamListInfo params, QueryCompletion *qc) +{ + Node *parsetree = pstmt->utilityStmt; + if (NestedTranCount > 0 || (sql_dialect == SQL_DIALECT_TSQL && !IsTransactionBlockActive())) + { + PLTsqlProcessTransaction(parsetree, params, qc); + return; + } +} static void pltsql_GetNewObjectId(VariableCache variableCache) diff --git a/contrib/babelfishpg_tsql/src/hooks.h b/contrib/babelfishpg_tsql/src/hooks.h index 3efc536d44..647732e100 100644 --- a/contrib/babelfishpg_tsql/src/hooks.h +++ b/contrib/babelfishpg_tsql/src/hooks.h @@ -3,6 +3,7 @@ #include "postgres.h" #include "catalog/catalog.h" #include "parser/analyze.h" +#include "tcop/cmdtag.h" extern IsExtendedCatalogHookType PrevIsExtendedCatalogHook; @@ -22,4 +23,8 @@ extern Oid get_tsql_trigger_oid(List *object, extern char *update_delete_target_alias; extern bool sp_describe_first_result_set_inprogress; + +extern void PLTsqlProcessTransaction(Node *parsetree, + ParamListInfo params, + QueryCompletion *qc); #endif diff --git a/contrib/babelfishpg_tsql/src/pl_handler.c b/contrib/babelfishpg_tsql/src/pl_handler.c index 7fd9ec26a4..0666bacee3 100644 --- a/contrib/babelfishpg_tsql/src/pl_handler.c +++ b/contrib/babelfishpg_tsql/src/pl_handler.c @@ -1925,7 +1925,7 @@ bbf_table_var_lookup(const char *relname, Oid relnamespace) /* * Transaction processing using tsql semantics */ -static void +extern void PLTsqlProcessTransaction(Node *parsetree, ParamListInfo params, QueryCompletion *qc) @@ -2358,15 +2358,15 @@ bbf_ProcessUtility(PlannedStmt *pstmt, EventTriggerEndCompleteQuery(); return; } - case T_TransactionStmt: - { - if (NestedTranCount > 0 || (sql_dialect == SQL_DIALECT_TSQL && !IsTransactionBlockActive())) - { - PLTsqlProcessTransaction(parsetree, params, qc); - return; - } - break; - } + // case T_TransactionStmt: + // { + // if (NestedTranCount > 0 || (sql_dialect == SQL_DIALECT_TSQL && !IsTransactionBlockActive())) + // { + // PLTsqlProcessTransaction(parsetree, params, qc); + // return; + // } + // break; + // } case T_TruncateStmt: { if (sql_dialect == SQL_DIALECT_TSQL) From d99f4b2e07480fd904e072721592a559cd16f9ed Mon Sep 17 00:00:00 2001 From: Kritika Date: Fri, 31 Mar 2023 10:12:29 +0000 Subject: [PATCH 03/43] retrigger tests From 3c1b8bd4bf6314d997fd2124a47363d40c88d02c Mon Sep 17 00:00:00 2001 From: Kritika Date: Sat, 1 Apr 2023 14:35:57 +0000 Subject: [PATCH 04/43] Transaction statements not visible in pg_stat_statements view Subsequent processutility hooks after bbf_processutilty are not being called. Created a hook for that and called it inside relevant ProcessUtility function. Signed-off-by: Kritika --- contrib/babelfishpg_tsql/src/hooks.c | 11 +++++++++++ contrib/babelfishpg_tsql/src/hooks.h | 7 ++++--- contrib/babelfishpg_tsql/src/pl_handler.c | 9 --------- 3 files changed, 15 insertions(+), 12 deletions(-) diff --git a/contrib/babelfishpg_tsql/src/hooks.c b/contrib/babelfishpg_tsql/src/hooks.c index 5292e000a2..e74c6ba9b3 100644 --- a/contrib/babelfishpg_tsql/src/hooks.c +++ b/contrib/babelfishpg_tsql/src/hooks.c @@ -364,6 +364,17 @@ pltsql_transactionStmt(PlannedStmt *pstmt, ParamListInfo params, QueryCompletion } } +static void +pltsql_transactionStmt(PlannedStmt *pstmt, ParamListInfo params, QueryCompletion *qc) +{ + Node *parsetree = pstmt->utilityStmt; + if (NestedTranCount > 0 || (sql_dialect == SQL_DIALECT_TSQL && !IsTransactionBlockActive())) + { + PLTsqlProcessTransaction(parsetree, params, qc); + return; + } +} + static void pltsql_GetNewObjectId(VariableCache variableCache) { diff --git a/contrib/babelfishpg_tsql/src/hooks.h b/contrib/babelfishpg_tsql/src/hooks.h index 647732e100..2872c27540 100644 --- a/contrib/babelfishpg_tsql/src/hooks.h +++ b/contrib/babelfishpg_tsql/src/hooks.h @@ -24,7 +24,8 @@ extern Oid get_tsql_trigger_oid(List *object, extern char *update_delete_target_alias; extern bool sp_describe_first_result_set_inprogress; -extern void PLTsqlProcessTransaction(Node *parsetree, - ParamListInfo params, - QueryCompletion *qc); +extern void +PLTsqlProcessTransaction(Node *parsetree, + ParamListInfo params, + QueryCompletion *qc) #endif diff --git a/contrib/babelfishpg_tsql/src/pl_handler.c b/contrib/babelfishpg_tsql/src/pl_handler.c index 0666bacee3..2a8ad05799 100644 --- a/contrib/babelfishpg_tsql/src/pl_handler.c +++ b/contrib/babelfishpg_tsql/src/pl_handler.c @@ -2358,15 +2358,6 @@ bbf_ProcessUtility(PlannedStmt *pstmt, EventTriggerEndCompleteQuery(); return; } - // case T_TransactionStmt: - // { - // if (NestedTranCount > 0 || (sql_dialect == SQL_DIALECT_TSQL && !IsTransactionBlockActive())) - // { - // PLTsqlProcessTransaction(parsetree, params, qc); - // return; - // } - // break; - // } case T_TruncateStmt: { if (sql_dialect == SQL_DIALECT_TSQL) From c94fc41a6a68a9d4a981dd301a69604e14c72e8b Mon Sep 17 00:00:00 2001 From: kritika-0601 <122882328+kritika-0601@users.noreply.github.com> Date: Sat, 1 Apr 2023 20:08:13 +0530 Subject: [PATCH 05/43] Update major-version-upgrade.yml --- .github/workflows/major-version-upgrade.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/major-version-upgrade.yml b/.github/workflows/major-version-upgrade.yml index a6783b9710..3aa6514a4f 100644 --- a/.github/workflows/major-version-upgrade.yml +++ b/.github/workflows/major-version-upgrade.yml @@ -71,7 +71,7 @@ jobs: ~/${{env.OLD_INSTALL_DIR}}/bin/pg_ctl -D ~/${{env.OLD_INSTALL_DIR}}/data -l logfile13 start cd ${{env.OLD_INSTALL_DIR}}/data sudo sed -i "s/#listen_addresses = 'localhost'/listen_addresses = '*'/g" postgresql.conf - sudo sed -i "s/#shared_preload_libraries = ''/shared_preload_libraries = 'babelfishpg_tds, pg_stat_statements'/g" postgresql.conf + sudo sed -i "s/#shared_preload_libraries = ''/shared_preload_libraries = 'babelfishpg_tds'/g" postgresql.conf ipaddress=$(ifconfig eth0 | grep 'inet ' | cut -d: -f2 | awk '{ print $2}') sudo echo "host all all $ipaddress/32 trust" >> pg_hba.conf ~/${{env.OLD_INSTALL_DIR}}/bin/pg_ctl -D ~/${{env.OLD_INSTALL_DIR}}/data -l logfile13 restart From 3ae046431a76e6c456038289e806ffd468a83ad1 Mon Sep 17 00:00:00 2001 From: Kritika Date: Sat, 1 Apr 2023 14:39:59 +0000 Subject: [PATCH 06/43] Transaction statements not visible in pg_stat_statements view Subsequent processutility hooks after bbf_processutilty are not being called. Created a hook for that and called it inside relevant ProcessUtility function. Signed-off-by: Kritika --- contrib/babelfishpg_tsql/src/hooks.c | 11 ----------- 1 file changed, 11 deletions(-) diff --git a/contrib/babelfishpg_tsql/src/hooks.c b/contrib/babelfishpg_tsql/src/hooks.c index e74c6ba9b3..5292e000a2 100644 --- a/contrib/babelfishpg_tsql/src/hooks.c +++ b/contrib/babelfishpg_tsql/src/hooks.c @@ -364,17 +364,6 @@ pltsql_transactionStmt(PlannedStmt *pstmt, ParamListInfo params, QueryCompletion } } -static void -pltsql_transactionStmt(PlannedStmt *pstmt, ParamListInfo params, QueryCompletion *qc) -{ - Node *parsetree = pstmt->utilityStmt; - if (NestedTranCount > 0 || (sql_dialect == SQL_DIALECT_TSQL && !IsTransactionBlockActive())) - { - PLTsqlProcessTransaction(parsetree, params, qc); - return; - } -} - static void pltsql_GetNewObjectId(VariableCache variableCache) { From f4cf79d8dc2e22f5142fd77d02a823c950418604 Mon Sep 17 00:00:00 2001 From: Kritika Date: Fri, 31 Mar 2023 10:12:29 +0000 Subject: [PATCH 07/43] retrigger tests From 1ed996d2b3356326e1f200fd895325b5cb9acc22 Mon Sep 17 00:00:00 2001 From: Kritika Date: Sat, 1 Apr 2023 15:09:43 +0000 Subject: [PATCH 08/43] Transaction statements not visible in pg_stat_statements view Subsequent processutility hooks after bbf_processutilty are not being called. Created a hook for that and called it inside relevant ProcessUtility function. Signed-off-by: Kritika --- contrib/babelfishpg_tsql/src/hooks.h | 7 +++---- contrib/babelfishpg_tsql/src/pl_handler.c | 9 +++++++++ 2 files changed, 12 insertions(+), 4 deletions(-) diff --git a/contrib/babelfishpg_tsql/src/hooks.h b/contrib/babelfishpg_tsql/src/hooks.h index 2872c27540..1f8f1b1584 100644 --- a/contrib/babelfishpg_tsql/src/hooks.h +++ b/contrib/babelfishpg_tsql/src/hooks.h @@ -24,8 +24,7 @@ extern Oid get_tsql_trigger_oid(List *object, extern char *update_delete_target_alias; extern bool sp_describe_first_result_set_inprogress; -extern void -PLTsqlProcessTransaction(Node *parsetree, - ParamListInfo params, - QueryCompletion *qc) +extern void PLTsqlProcessTransaction(Node *parsetree, + ParamListInfo params, + QueryCompletion *qc); #endif diff --git a/contrib/babelfishpg_tsql/src/pl_handler.c b/contrib/babelfishpg_tsql/src/pl_handler.c index 2a8ad05799..cf58eb222c 100644 --- a/contrib/babelfishpg_tsql/src/pl_handler.c +++ b/contrib/babelfishpg_tsql/src/pl_handler.c @@ -2358,6 +2358,15 @@ bbf_ProcessUtility(PlannedStmt *pstmt, EventTriggerEndCompleteQuery(); return; } + // case T_TransactionStmt: + // { + // if (NestedTranCount > 0 || (sql_dialect == SQL_DIALECT_TSQL && !IsTransactionBlockActive())) + // { + // PLTsqlProcessTransaction(parsetree, params, qc); + // return; + // } + // break; + // } case T_TruncateStmt: { if (sql_dialect == SQL_DIALECT_TSQL) From 628a124eaeca235aac437068fef8bd110e473870 Mon Sep 17 00:00:00 2001 From: Kritika Date: Fri, 31 Mar 2023 10:12:29 +0000 Subject: [PATCH 09/43] retrigger tests From 37603a66f0ce29a4b49fb169788d7808a5ec7810 Mon Sep 17 00:00:00 2001 From: Kritika Date: Fri, 31 Mar 2023 10:12:29 +0000 Subject: [PATCH 10/43] retrigger tests From f2ca9e2656481a8469bfded7ddaf6c069fa8253c Mon Sep 17 00:00:00 2001 From: Kritika Date: Thu, 13 Apr 2023 10:03:35 +0000 Subject: [PATCH 11/43] Create proc/func/database etc not visible in pg_stat_statements view Subsequent processutility hooks after bbf_processutilty are not being called. Created a hook for that and called it inside relevant ProcessUtility function. Signed-off-by: Kritika --- contrib/babelfishpg_tsql/src/hooks.c | 245 +++++++++++++++++++++- contrib/babelfishpg_tsql/src/pl_handler.c | 190 ----------------- 2 files changed, 235 insertions(+), 200 deletions(-) diff --git a/contrib/babelfishpg_tsql/src/hooks.c b/contrib/babelfishpg_tsql/src/hooks.c index 5292e000a2..3f964d543e 100644 --- a/contrib/babelfishpg_tsql/src/hooks.c +++ b/contrib/babelfishpg_tsql/src/hooks.c @@ -70,6 +70,7 @@ extern bool babelfish_dump_restore; extern char *babelfish_dump_restore_min_oid; extern bool pltsql_quoted_identifier; extern bool pltsql_ansi_nulls; +extern bool restore_tsql_tabletype; /***************************************** * Catalog Hooks @@ -127,7 +128,11 @@ static void insert_pltsql_function_defaults(HeapTuple func_tuple, List *defaults static int print_pltsql_function_arguments(StringInfo buf, HeapTuple proctup, bool print_table_args, bool print_defaults); static void pltsql_GetNewObjectId(VariableCache variableCache); static void pltsql_validate_var_datatype_scale(const TypeName *typeName, Type typ); -static void pltsql_transactionStmt(PlannedStmt *pstmt, ParamListInfo params, QueryCompletion *qc); +static void pltsql_miscProcessUtility(ParseState *pstate, + PlannedStmt *pstmt, + const char *queryString, + ProcessUtilityContext context, + ParamListInfo params, QueryCompletion *qc, int *flag); /***************************************** * Executor Hooks @@ -189,7 +194,7 @@ static validate_var_datatype_scale_hook_type prev_validate_var_datatype_scale_ho static modify_RangeTblFunction_tupdesc_hook_type prev_modify_RangeTblFunction_tupdesc_hook = NULL; static fill_missing_values_in_copyfrom_hook_type prev_fill_missing_values_in_copyfrom_hook = NULL; static check_rowcount_hook_type prev_check_rowcount_hook = NULL; -static transactionStmt_hook_type prev_transactionStmt_hook = NULL; +static miscProcessUtility_hook_type prev_miscProcessUtility_hook = NULL; /***************************************** * Install / Uninstall @@ -301,8 +306,8 @@ InstallExtendedHooks(void) prev_check_rowcount_hook = check_rowcount_hook; check_rowcount_hook = bbf_check_rowcount_hook; - prev_transactionStmt_hook = transactionStmt_hook; - transactionStmt_hook = pltsql_transactionStmt; + prev_miscProcessUtility_hook = miscProcessUtility_hook; + miscProcessUtility_hook = pltsql_miscProcessUtility; } void @@ -347,22 +352,242 @@ UninstallExtendedHooks(void) modify_RangeTblFunction_tupdesc_hook = prev_modify_RangeTblFunction_tupdesc_hook; fill_missing_values_in_copyfrom_hook = prev_fill_missing_values_in_copyfrom_hook; check_rowcount_hook = prev_check_rowcount_hook; - transactionStmt_hook = prev_transactionStmt_hook; + miscProcessUtility_hook = prev_miscProcessUtility_hook; } /***************************************** * Hook Functions *****************************************/ static void -pltsql_transactionStmt(PlannedStmt *pstmt, ParamListInfo params, QueryCompletion *qc) +pltsql_miscProcessUtility(ParseState *pstate, PlannedStmt *pstmt, const char *queryString, ProcessUtilityContext context, + ParamListInfo params, QueryCompletion *qc, int *flag) { Node *parsetree = pstmt->utilityStmt; - if (NestedTranCount > 0 || (sql_dialect == SQL_DIALECT_TSQL && !IsTransactionBlockActive())) + + + pstate->p_sourcetext = queryString; + + switch (nodeTag(parsetree)) { - PLTsqlProcessTransaction(parsetree, params, qc); - return; + case T_CreateFunctionStmt: + { + CreateFunctionStmt *stmt = (CreateFunctionStmt *)parsetree; + ListCell *option, *location_cell = NULL; + DefElem *language_item = NULL; + char *language = NULL; + ObjectAddress address; + bool isCompleteQuery = (context != PROCESS_UTILITY_SUBCOMMAND); + bool needCleanup; + Node *tbltypStmt = NULL; + Node *trigStmt = NULL; + ObjectAddress tbltyp; + int origname_location = -1; + *flag = true; + + foreach(option, stmt->options) + { + DefElem *defel = (DefElem *)lfirst(option); + + if (strcmp(defel->defname, "language") == 0) + { + if (language_item) + ereport(ERROR, + (errcode(ERRCODE_SYNTAX_ERROR), + errmsg("conflicting or redundant options"), + parser_errposition(pstate, defel->location))); + language_item = defel; + } + } + + if (language_item) + language = strVal(language_item->arg); + + if((language && !strcmp(language,"pltsql")) || sql_dialect == SQL_DIALECT_TSQL) + { + + /* All event trigger calls are done only when isCompleteQuery is true */ + needCleanup = isCompleteQuery && EventTriggerBeginCompleteQuery(); + + /* PG_TRY block is to ensure we call EventTriggerEndCompleteQuery */ + PG_TRY(); + { + + if (isCompleteQuery) + EventTriggerDDLCommandStart(parsetree); + + foreach (option, stmt->options) + { + DefElem *defel = (DefElem *)lfirst(option); + if (strcmp(defel->defname, "tbltypStmt") == 0) + { + /* + * tbltypStmt is an implicit option in tsql dialect, + * we use this mechanism to create tsql style + * multi-statement table-valued function and its + * return (table) type in one statement. + */ + tbltypStmt = defel->arg; + } + else if (strcmp(defel->defname, "trigStmt") == 0) + { + /* + * trigStmt is an implicit option in tsql dialect, + * we use this mechanism to create tsql style function + * and trigger in one statement. + */ + trigStmt = defel->arg; + } + else if (strcmp(defel->defname, "location") == 0) + { + /* + * location is an implicit option in tsql dialect, + * we use this mechanism to store location of function + * name so that we can extract original input function + * name from queryString. + */ + origname_location = intVal((Node *)defel->arg); + location_cell = option; + pfree(defel); + } + } + + /* delete location cell if it exists as it is for internal use only */ + if (location_cell) + stmt->options = list_delete_cell(stmt->options, location_cell); + + /* + * For tbltypStmt, we need to first process the CreateStmt + * to create the type that will be used as the function's + * return type. Then, after the function is created, add a + * dependency between the type and the function. + */ + if (tbltypStmt) + { + /* Handle tbltypStmt, which is a CreateStmt */ + PlannedStmt *wrapper; + + wrapper = makeNode(PlannedStmt); + wrapper->commandType = CMD_UTILITY; + wrapper->canSetTag = false; + wrapper->utilityStmt = tbltypStmt; + wrapper->stmt_location = pstmt->stmt_location; + wrapper->stmt_len = pstmt->stmt_len; + + ProcessUtility(wrapper, + queryString, + false, + PROCESS_UTILITY_SUBCOMMAND, + params, + NULL, + None_Receiver, + NULL); + + /* Need CCI between commands */ + CommandCounterIncrement(); + } + + address = CreateFunction(pstate, stmt); + + /* Store function/procedure related metadata in babelfish catalog */ + pltsql_store_func_default_positions(address, stmt->parameters, queryString, origname_location); + + if (tbltypStmt || restore_tsql_tabletype) + { + /* + * Add internal dependency between the table type and + * the function. + */ + tbltyp.classId = TypeRelationId; + tbltyp.objectId = typenameTypeId(pstate, + stmt->returnType); + tbltyp.objectSubId = 0; + recordDependencyOn(&tbltyp, &address, DEPENDENCY_INTERNAL); + } + + /* + * For trigStmt, we need to process the CreateTrigStmt after + * the function is created, and record bidirectional + * dependency so that Drop Trigger CASCADE will drop the + * implicit trigger function. + * Create trigger takes care of dependency addition. + */ + if (trigStmt) + { + (void)CreateTrigger((CreateTrigStmt *)trigStmt, + pstate->p_sourcetext, InvalidOid, InvalidOid, + InvalidOid, InvalidOid, address.objectId, + InvalidOid, NULL, false, false); + } + + /* + * Remember the object so that ddl_command_end event triggers have + * access to it. + */ + EventTriggerCollectSimpleCommand(address, InvalidObjectAddress, + parsetree); + + if (isCompleteQuery) + { + EventTriggerSQLDrop(parsetree); + EventTriggerDDLCommandEnd(parsetree); + } + } + + PG_CATCH(); + { + if (needCleanup) + EventTriggerEndCompleteQuery(); + PG_RE_THROW(); + } + PG_END_TRY(); + + if (needCleanup) + EventTriggerEndCompleteQuery(); + return; + + } + else + { + address = CreateFunction(pstate, (CreateFunctionStmt *) parsetree); + break; + } + break; + } + case T_CreatedbStmt: + { + *flag = true; + if (sql_dialect == SQL_DIALECT_TSQL) + { + create_bbf_db(pstate, (CreatedbStmt *) parsetree); + return; + } + break; + } + case T_DropdbStmt: + { + *flag = true; + if (sql_dialect == SQL_DIALECT_TSQL) + { + DropdbStmt *stmt = (DropdbStmt *) parsetree; + drop_bbf_db(stmt->dbname, stmt->missing_ok, false); + return; + } + break; + } + case T_TransactionStmt: + { + *flag = true; + if (NestedTranCount > 0 || (sql_dialect == SQL_DIALECT_TSQL && !IsTransactionBlockActive())) + { + PLTsqlProcessTransaction(parsetree, params, qc); + } + break; + } + default: + break; } -} +} + static void pltsql_GetNewObjectId(VariableCache variableCache) diff --git a/contrib/babelfishpg_tsql/src/pl_handler.c b/contrib/babelfishpg_tsql/src/pl_handler.c index cf58eb222c..4c14abaf48 100644 --- a/contrib/babelfishpg_tsql/src/pl_handler.c +++ b/contrib/babelfishpg_tsql/src/pl_handler.c @@ -2193,180 +2193,6 @@ bbf_ProcessUtility(PlannedStmt *pstmt, switch (nodeTag(parsetree)) { - case T_CreateFunctionStmt: - { - CreateFunctionStmt *stmt = (CreateFunctionStmt *) parsetree; - bool isCompleteQuery = (context != PROCESS_UTILITY_SUBCOMMAND); - bool needCleanup; - ListCell *option, - *location_cell = NULL; - Node *tbltypStmt = NULL; - Node *trigStmt = NULL; - ObjectAddress tbltyp; - ObjectAddress address; - int origname_location = -1; - - /* - * All event trigger calls are done only when isCompleteQuery - * is true - */ - needCleanup = isCompleteQuery && EventTriggerBeginCompleteQuery(); - - /* - * PG_TRY block is to ensure we call - * EventTriggerEndCompleteQuery - */ - PG_TRY(); - { - if (isCompleteQuery) - EventTriggerDDLCommandStart(parsetree); - - foreach(option, stmt->options) - { - DefElem *defel = (DefElem *) lfirst(option); - - if (strcmp(defel->defname, "tbltypStmt") == 0) - { - /* - * tbltypStmt is an implicit option in tsql - * dialect, we use this mechanism to create tsql - * style multi-statement table-valued function and - * its return (table) type in one statement. - */ - tbltypStmt = defel->arg; - } - else if (strcmp(defel->defname, "trigStmt") == 0) - { - /* - * trigStmt is an implicit option in tsql dialect, - * we use this mechanism to create tsql style - * function and trigger in one statement. - */ - trigStmt = defel->arg; - } - else if (strcmp(defel->defname, "location") == 0) - { - /* - * location is an implicit option in tsql dialect, - * we use this mechanism to store location of - * function name so that we can extract original - * input function name from queryString. - */ - origname_location = intVal((Node *) defel->arg); - location_cell = option; - pfree(defel); - } - } - - /* - * delete location cell if it exists as it is for internal - * use only - */ - if (location_cell) - stmt->options = list_delete_cell(stmt->options, location_cell); - - /* - * For tbltypStmt, we need to first process the CreateStmt - * to create the type that will be used as the function's - * return type. Then, after the function is created, add a - * dependency between the type and the function. - */ - if (tbltypStmt) - { - /* Handle tbltypStmt, which is a CreateStmt */ - PlannedStmt *wrapper; - - wrapper = makeNode(PlannedStmt); - wrapper->commandType = CMD_UTILITY; - wrapper->canSetTag = false; - wrapper->utilityStmt = tbltypStmt; - wrapper->stmt_location = pstmt->stmt_location; - wrapper->stmt_len = pstmt->stmt_len; - - ProcessUtility(wrapper, - queryString, - readOnlyTree, - PROCESS_UTILITY_SUBCOMMAND, - params, - NULL, - None_Receiver, - NULL); - - /* Need CCI between commands */ - CommandCounterIncrement(); - } - - address = CreateFunction(pstate, stmt); - - /* - * Store function/procedure related metadata in babelfish - * catalog - */ - pltsql_store_func_default_positions(address, stmt->parameters, queryString, origname_location); - - if (tbltypStmt || restore_tsql_tabletype) - { - /* - * Add internal dependency between the table type and - * the function. - */ - tbltyp.classId = TypeRelationId; - tbltyp.objectId = typenameTypeId(pstate, - stmt->returnType); - tbltyp.objectSubId = 0; - recordDependencyOn(&tbltyp, &address, DEPENDENCY_INTERNAL); - } - - /* - * For trigStmt, we need to process the CreateTrigStmt - * after the function is created, and record bidirectional - * dependency so that Drop Trigger CASCADE will drop the - * implicit trigger function. Create trigger takes care of - * dependency addition. - */ - if (trigStmt) - { - (void) CreateTrigger((CreateTrigStmt *) trigStmt, - pstate->p_sourcetext, InvalidOid, InvalidOid, - InvalidOid, InvalidOid, address.objectId, - InvalidOid, NULL, false, false); - } - - /* - * Remember the object so that ddl_command_end event - * triggers have access to it. - */ - EventTriggerCollectSimpleCommand(address, InvalidObjectAddress, - parsetree); - - if (isCompleteQuery) - { - EventTriggerSQLDrop(parsetree); - EventTriggerDDLCommandEnd(parsetree); - } - - } - PG_CATCH(); - { - if (needCleanup) - EventTriggerEndCompleteQuery(); - PG_RE_THROW(); - } - PG_END_TRY(); - - if (needCleanup) - EventTriggerEndCompleteQuery(); - return; - } - // case T_TransactionStmt: - // { - // if (NestedTranCount > 0 || (sql_dialect == SQL_DIALECT_TSQL && !IsTransactionBlockActive())) - // { - // PLTsqlProcessTransaction(parsetree, params, qc); - // return; - // } - // break; - // } case T_TruncateStmt: { if (sql_dialect == SQL_DIALECT_TSQL) @@ -3330,22 +3156,6 @@ bbf_ProcessUtility(PlannedStmt *pstmt, return; } } - case T_CreatedbStmt: - if (sql_dialect == SQL_DIALECT_TSQL) - { - create_bbf_db(pstate, (CreatedbStmt *) parsetree); - return; - } - break; - case T_DropdbStmt: - if (sql_dialect == SQL_DIALECT_TSQL) - { - DropdbStmt *stmt = (DropdbStmt *) parsetree; - - drop_bbf_db(stmt->dbname, stmt->missing_ok, false); - return; - } - break; case T_GrantRoleStmt: if (sql_dialect == SQL_DIALECT_TSQL) { From 839ce194618e92e075032f97cbfced7b9765d84c Mon Sep 17 00:00:00 2001 From: Kritika Date: Thu, 13 Apr 2023 17:49:09 +0000 Subject: [PATCH 12/43] retrigger tests From 3938a87669a2d96dee9f6656770769f657c2bf65 Mon Sep 17 00:00:00 2001 From: Kritika Date: Fri, 14 Apr 2023 05:27:44 +0000 Subject: [PATCH 13/43] retrigger tests From 4ab495f23cfdb31ffc7b65714fb1fac0bd808ded Mon Sep 17 00:00:00 2001 From: Kritika Date: Fri, 14 Apr 2023 05:44:53 +0000 Subject: [PATCH 14/43] retrigger tests From c22c4618f80acd230f1a260caffc654b1a879c57 Mon Sep 17 00:00:00 2001 From: Kritika Date: Fri, 14 Apr 2023 06:17:49 +0000 Subject: [PATCH 15/43] retrigger tests From 0eab309d7191878c54dc4f3df4d6013191d690a3 Mon Sep 17 00:00:00 2001 From: Kritika Date: Fri, 14 Apr 2023 09:46:52 +0000 Subject: [PATCH 16/43] Create proc/func/database etc not visible in pg_stat_statements view Subsequent processutility hooks after bbf_processutilty are not being called. Created a hook for that and called it inside relevant ProcessUtility function. Signed-off-by: Kritika --- contrib/babelfishpg_tsql/src/hooks.c | 16 ++++++---------- 1 file changed, 6 insertions(+), 10 deletions(-) diff --git a/contrib/babelfishpg_tsql/src/hooks.c b/contrib/babelfishpg_tsql/src/hooks.c index 739e562c5d..eaa1e32b85 100644 --- a/contrib/babelfishpg_tsql/src/hooks.c +++ b/contrib/babelfishpg_tsql/src/hooks.c @@ -405,7 +405,6 @@ pltsql_miscProcessUtility(ParseState *pstate, PlannedStmt *pstmt, const char *qu Node *trigStmt = NULL; ObjectAddress tbltyp; int origname_location = -1; - *flag = true; foreach(option, stmt->options) { @@ -427,7 +426,7 @@ pltsql_miscProcessUtility(ParseState *pstate, PlannedStmt *pstmt, const char *qu if((language && !strcmp(language,"pltsql")) || sql_dialect == SQL_DIALECT_TSQL) { - + *flag = true; /* All event trigger calls are done only when isCompleteQuery is true */ needCleanup = isCompleteQuery && EventTriggerBeginCompleteQuery(); @@ -569,18 +568,13 @@ pltsql_miscProcessUtility(ParseState *pstate, PlannedStmt *pstmt, const char *qu return; } - else - { - address = CreateFunction(pstate, (CreateFunctionStmt *) parsetree); - break; - } break; } case T_CreatedbStmt: { - *flag = true; if (sql_dialect == SQL_DIALECT_TSQL) { + *flag = true; create_bbf_db(pstate, (CreatedbStmt *) parsetree); return; } @@ -588,10 +582,10 @@ pltsql_miscProcessUtility(ParseState *pstate, PlannedStmt *pstmt, const char *qu } case T_DropdbStmt: { - *flag = true; if (sql_dialect == SQL_DIALECT_TSQL) { DropdbStmt *stmt = (DropdbStmt *) parsetree; + *flag = true; drop_bbf_db(stmt->dbname, stmt->missing_ok, false); return; } @@ -599,14 +593,16 @@ pltsql_miscProcessUtility(ParseState *pstate, PlannedStmt *pstmt, const char *qu } case T_TransactionStmt: { - *flag = true; if (NestedTranCount > 0 || (sql_dialect == SQL_DIALECT_TSQL && !IsTransactionBlockActive())) { + + *flag = true; PLTsqlProcessTransaction(parsetree, params, qc); } break; } default: + *flag = false; break; } } From 51cc85cf9f1d0ad9618d3c4bb69aa67f816e7e05 Mon Sep 17 00:00:00 2001 From: Kritika Date: Mon, 17 Apr 2023 04:23:23 +0000 Subject: [PATCH 17/43] retrigger tests From 9335b0ae803a6864d40b78fceef1303d2c207c2e Mon Sep 17 00:00:00 2001 From: Kritika Date: Tue, 18 Apr 2023 09:24:47 +0000 Subject: [PATCH 18/43] retrigger tests From 7bef777777803fa50343afe0ae6707e480911e69 Mon Sep 17 00:00:00 2001 From: Kritika Date: Tue, 18 Apr 2023 09:32:30 +0000 Subject: [PATCH 19/43] retrigger tests From 14cf51b1788ffa59a999b9476f76080bbc437955 Mon Sep 17 00:00:00 2001 From: Kritika Date: Wed, 19 Apr 2023 04:51:03 +0000 Subject: [PATCH 20/43] Create proc/func/database etc not visible in pg_stat_statements view Subsequent processutility hooks after bbf_processutilty are not being called. Created a hook for that and called it inside relevant ProcessUtility function. Signed-off-by: Kritika --- contrib/babelfishpg_tsql/src/hooks.h | 4 ---- 1 file changed, 4 deletions(-) diff --git a/contrib/babelfishpg_tsql/src/hooks.h b/contrib/babelfishpg_tsql/src/hooks.h index 1f8f1b1584..592af08d58 100644 --- a/contrib/babelfishpg_tsql/src/hooks.h +++ b/contrib/babelfishpg_tsql/src/hooks.h @@ -3,7 +3,6 @@ #include "postgres.h" #include "catalog/catalog.h" #include "parser/analyze.h" -#include "tcop/cmdtag.h" extern IsExtendedCatalogHookType PrevIsExtendedCatalogHook; @@ -24,7 +23,4 @@ extern Oid get_tsql_trigger_oid(List *object, extern char *update_delete_target_alias; extern bool sp_describe_first_result_set_inprogress; -extern void PLTsqlProcessTransaction(Node *parsetree, - ParamListInfo params, - QueryCompletion *qc); #endif From cc75b1837f6f7ca4740bfeaa6e5c0a142995b4b0 Mon Sep 17 00:00:00 2001 From: Kritika Date: Wed, 19 Apr 2023 14:07:41 +0000 Subject: [PATCH 21/43] Create proc/func/database etc not visible in pg_stat_statements view Subsequent processutility hooks after bbf_processutilty are not being called. Created a hook for that and called it inside relevant ProcessUtility function. Signed-off-by: Kritika --- contrib/babelfishpg_tsql/src/hooks.c | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/contrib/babelfishpg_tsql/src/hooks.c b/contrib/babelfishpg_tsql/src/hooks.c index eaa1e32b85..b1110483ca 100644 --- a/contrib/babelfishpg_tsql/src/hooks.c +++ b/contrib/babelfishpg_tsql/src/hooks.c @@ -129,7 +129,7 @@ static void insert_pltsql_function_defaults(HeapTuple func_tuple, List *defaults static int print_pltsql_function_arguments(StringInfo buf, HeapTuple proctup, bool print_table_args, bool print_defaults); static void pltsql_GetNewObjectId(VariableCache variableCache); static void pltsql_validate_var_datatype_scale(const TypeName *typeName, Type typ); -static void pltsql_miscProcessUtility(ParseState *pstate, +static void pltsql_bbfCustomProcessUtility(ParseState *pstate, PlannedStmt *pstmt, const char *queryString, ProcessUtilityContext context, @@ -199,7 +199,7 @@ static validate_var_datatype_scale_hook_type prev_validate_var_datatype_scale_ho static modify_RangeTblFunction_tupdesc_hook_type prev_modify_RangeTblFunction_tupdesc_hook = NULL; static fill_missing_values_in_copyfrom_hook_type prev_fill_missing_values_in_copyfrom_hook = NULL; static check_rowcount_hook_type prev_check_rowcount_hook = NULL; -static miscProcessUtility_hook_type prev_miscProcessUtility_hook = NULL; +static bbfCustomProcessUtility_hook_type prev_bbfCustomProcessUtility_hook = NULL; static sortby_nulls_hook_type prev_sortby_nulls_hook = NULL; /***************************************** @@ -321,8 +321,8 @@ InstallExtendedHooks(void) prev_check_rowcount_hook = check_rowcount_hook; check_rowcount_hook = bbf_check_rowcount_hook; - prev_miscProcessUtility_hook = miscProcessUtility_hook; - miscProcessUtility_hook = pltsql_miscProcessUtility; + prev_bbfCustomProcessUtility_hook = bbfCustomProcessUtility_hook; + bbfCustomProcessUtility_hook = pltsql_bbfCustomProcessUtility; prev_sortby_nulls_hook = sortby_nulls_hook; sortby_nulls_hook = sort_nulls_first; @@ -374,7 +374,7 @@ UninstallExtendedHooks(void) modify_RangeTblFunction_tupdesc_hook = prev_modify_RangeTblFunction_tupdesc_hook; fill_missing_values_in_copyfrom_hook = prev_fill_missing_values_in_copyfrom_hook; check_rowcount_hook = prev_check_rowcount_hook; - miscProcessUtility_hook = prev_miscProcessUtility_hook; + bbfCustomProcessUtility_hook = prev_bbfCustomProcessUtility_hook; sortby_nulls_hook = prev_sortby_nulls_hook; } @@ -382,7 +382,7 @@ UninstallExtendedHooks(void) * Hook Functions *****************************************/ static void -pltsql_miscProcessUtility(ParseState *pstate, PlannedStmt *pstmt, const char *queryString, ProcessUtilityContext context, +pltsql_bbfCustomProcessUtility(ParseState *pstate, PlannedStmt *pstmt, const char *queryString, ProcessUtilityContext context, ParamListInfo params, QueryCompletion *qc, int *flag) { Node *parsetree = pstmt->utilityStmt; From 216088f0ead4cc7c94a29ab25917e156a91eaaa0 Mon Sep 17 00:00:00 2001 From: Kritika Date: Wed, 19 Apr 2023 14:44:57 +0000 Subject: [PATCH 22/43] Create proc/func/database etc not visible in pg_stat_statements view Subsequent processutility hooks after bbf_processutilty are not being called. Created a hook for that and called it inside relevant ProcessUtility function. Signed-off-by: Kritika --- contrib/babelfishpg_tsql/src/hooks.c | 23 ++++++++++------------- 1 file changed, 10 insertions(+), 13 deletions(-) diff --git a/contrib/babelfishpg_tsql/src/hooks.c b/contrib/babelfishpg_tsql/src/hooks.c index b1110483ca..218f064061 100644 --- a/contrib/babelfishpg_tsql/src/hooks.c +++ b/contrib/babelfishpg_tsql/src/hooks.c @@ -129,11 +129,11 @@ static void insert_pltsql_function_defaults(HeapTuple func_tuple, List *defaults static int print_pltsql_function_arguments(StringInfo buf, HeapTuple proctup, bool print_table_args, bool print_defaults); static void pltsql_GetNewObjectId(VariableCache variableCache); static void pltsql_validate_var_datatype_scale(const TypeName *typeName, Type typ); -static void pltsql_bbfCustomProcessUtility(ParseState *pstate, +static bool pltsql_bbfCustomProcessUtility(ParseState *pstate, PlannedStmt *pstmt, const char *queryString, ProcessUtilityContext context, - ParamListInfo params, QueryCompletion *qc, int *flag); + ParamListInfo params, QueryCompletion *qc); /***************************************** * Executor Hooks @@ -381,9 +381,9 @@ UninstallExtendedHooks(void) /***************************************** * Hook Functions *****************************************/ -static void +static bool pltsql_bbfCustomProcessUtility(ParseState *pstate, PlannedStmt *pstmt, const char *queryString, ProcessUtilityContext context, - ParamListInfo params, QueryCompletion *qc, int *flag) + ParamListInfo params, QueryCompletion *qc) { Node *parsetree = pstmt->utilityStmt; @@ -426,7 +426,6 @@ pltsql_bbfCustomProcessUtility(ParseState *pstate, PlannedStmt *pstmt, const cha if((language && !strcmp(language,"pltsql")) || sql_dialect == SQL_DIALECT_TSQL) { - *flag = true; /* All event trigger calls are done only when isCompleteQuery is true */ needCleanup = isCompleteQuery && EventTriggerBeginCompleteQuery(); @@ -565,7 +564,7 @@ pltsql_bbfCustomProcessUtility(ParseState *pstate, PlannedStmt *pstmt, const cha if (needCleanup) EventTriggerEndCompleteQuery(); - return; + return true; } break; @@ -574,9 +573,8 @@ pltsql_bbfCustomProcessUtility(ParseState *pstate, PlannedStmt *pstmt, const cha { if (sql_dialect == SQL_DIALECT_TSQL) { - *flag = true; create_bbf_db(pstate, (CreatedbStmt *) parsetree); - return; + return true; } break; } @@ -585,9 +583,8 @@ pltsql_bbfCustomProcessUtility(ParseState *pstate, PlannedStmt *pstmt, const cha if (sql_dialect == SQL_DIALECT_TSQL) { DropdbStmt *stmt = (DropdbStmt *) parsetree; - *flag = true; drop_bbf_db(stmt->dbname, stmt->missing_ok, false); - return; + return true; } break; } @@ -595,16 +592,16 @@ pltsql_bbfCustomProcessUtility(ParseState *pstate, PlannedStmt *pstmt, const cha { if (NestedTranCount > 0 || (sql_dialect == SQL_DIALECT_TSQL && !IsTransactionBlockActive())) { - - *flag = true; PLTsqlProcessTransaction(parsetree, params, qc); + return false; } break; } default: - *flag = false; + return false; break; } + return false; } From bfa69790622c6bdfafd8c6527549da9c9f4877cb Mon Sep 17 00:00:00 2001 From: Kritika Date: Thu, 20 Apr 2023 04:39:39 +0000 Subject: [PATCH 23/43] Create proc/func/database etc not visible in pg_stat_statements view Subsequent processutility hooks after bbf_processutilty are not being called. Created a hook for that and called it inside relevant ProcessUtility function. Signed-off-by: Kritika --- contrib/babelfishpg_tsql/src/hooks.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/contrib/babelfishpg_tsql/src/hooks.c b/contrib/babelfishpg_tsql/src/hooks.c index 2457b93f8d..81baa9d4c7 100644 --- a/contrib/babelfishpg_tsql/src/hooks.c +++ b/contrib/babelfishpg_tsql/src/hooks.c @@ -593,7 +593,7 @@ pltsql_bbfCustomProcessUtility(ParseState *pstate, PlannedStmt *pstmt, const cha if (NestedTranCount > 0 || (sql_dialect == SQL_DIALECT_TSQL && !IsTransactionBlockActive())) { PLTsqlProcessTransaction(parsetree, params, qc); - return false; + return true; } break; } From c809b721bc461ed08b9dd0ce90ccce8fa2277a0c Mon Sep 17 00:00:00 2001 From: Kritika Date: Thu, 20 Apr 2023 06:40:03 +0000 Subject: [PATCH 24/43] Create proc/func/database etc not visible in pg_stat_statements view Subsequent processutility hooks after bbf_processutilty are not being called. Created a hook for that and called it inside relevant ProcessUtility function. Signed-off-by: Kritika --- contrib/babelfishpg_tsql/src/hooks.c | 182 +------------------ contrib/babelfishpg_tsql/src/pltsql.h | 3 + contrib/babelfishpg_tsql/src/pltsql_utils.c | 188 ++++++++++++++++++++ 3 files changed, 196 insertions(+), 177 deletions(-) diff --git a/contrib/babelfishpg_tsql/src/hooks.c b/contrib/babelfishpg_tsql/src/hooks.c index 81baa9d4c7..0218087bb9 100644 --- a/contrib/babelfishpg_tsql/src/hooks.c +++ b/contrib/babelfishpg_tsql/src/hooks.c @@ -70,7 +70,6 @@ extern bool babelfish_dump_restore; extern char *babelfish_dump_restore_min_oid; extern bool pltsql_quoted_identifier; extern bool pltsql_ansi_nulls; -extern bool restore_tsql_tabletype; /***************************************** * Catalog Hooks @@ -384,189 +383,18 @@ UninstallExtendedHooks(void) static bool pltsql_bbfCustomProcessUtility(ParseState *pstate, PlannedStmt *pstmt, const char *queryString, ProcessUtilityContext context, ParamListInfo params, QueryCompletion *qc) -{ +{ Node *parsetree = pstmt->utilityStmt; - - pstate->p_sourcetext = queryString; - switch (nodeTag(parsetree)) { case T_CreateFunctionStmt: - { - CreateFunctionStmt *stmt = (CreateFunctionStmt *)parsetree; - ListCell *option, *location_cell = NULL; - DefElem *language_item = NULL; - char *language = NULL; - ObjectAddress address; - bool isCompleteQuery = (context != PROCESS_UTILITY_SUBCOMMAND); - bool needCleanup; - Node *tbltypStmt = NULL; - Node *trigStmt = NULL; - ObjectAddress tbltyp; - int origname_location = -1; - - foreach(option, stmt->options) - { - DefElem *defel = (DefElem *)lfirst(option); - - if (strcmp(defel->defname, "language") == 0) - { - if (language_item) - ereport(ERROR, - (errcode(ERRCODE_SYNTAX_ERROR), - errmsg("conflicting or redundant options"), - parser_errposition(pstate, defel->location))); - language_item = defel; - } - } - - if (language_item) - language = strVal(language_item->arg); - - if((language && !strcmp(language,"pltsql")) || sql_dialect == SQL_DIALECT_TSQL) + { + if (sql_dialect == SQL_DIALECT_TSQL) { - /* All event trigger calls are done only when isCompleteQuery is true */ - needCleanup = isCompleteQuery && EventTriggerBeginCompleteQuery(); - - /* PG_TRY block is to ensure we call EventTriggerEndCompleteQuery */ - PG_TRY(); - { - - if (isCompleteQuery) - EventTriggerDDLCommandStart(parsetree); - - foreach (option, stmt->options) - { - DefElem *defel = (DefElem *)lfirst(option); - if (strcmp(defel->defname, "tbltypStmt") == 0) - { - /* - * tbltypStmt is an implicit option in tsql dialect, - * we use this mechanism to create tsql style - * multi-statement table-valued function and its - * return (table) type in one statement. - */ - tbltypStmt = defel->arg; - } - else if (strcmp(defel->defname, "trigStmt") == 0) - { - /* - * trigStmt is an implicit option in tsql dialect, - * we use this mechanism to create tsql style function - * and trigger in one statement. - */ - trigStmt = defel->arg; - } - else if (strcmp(defel->defname, "location") == 0) - { - /* - * location is an implicit option in tsql dialect, - * we use this mechanism to store location of function - * name so that we can extract original input function - * name from queryString. - */ - origname_location = intVal((Node *)defel->arg); - location_cell = option; - pfree(defel); - } - } - - /* delete location cell if it exists as it is for internal use only */ - if (location_cell) - stmt->options = list_delete_cell(stmt->options, location_cell); - - /* - * For tbltypStmt, we need to first process the CreateStmt - * to create the type that will be used as the function's - * return type. Then, after the function is created, add a - * dependency between the type and the function. - */ - if (tbltypStmt) - { - /* Handle tbltypStmt, which is a CreateStmt */ - PlannedStmt *wrapper; - - wrapper = makeNode(PlannedStmt); - wrapper->commandType = CMD_UTILITY; - wrapper->canSetTag = false; - wrapper->utilityStmt = tbltypStmt; - wrapper->stmt_location = pstmt->stmt_location; - wrapper->stmt_len = pstmt->stmt_len; - - ProcessUtility(wrapper, - queryString, - false, - PROCESS_UTILITY_SUBCOMMAND, - params, - NULL, - None_Receiver, - NULL); - - /* Need CCI between commands */ - CommandCounterIncrement(); - } - - address = CreateFunction(pstate, stmt); - - /* Store function/procedure related metadata in babelfish catalog */ - pltsql_store_func_default_positions(address, stmt->parameters, queryString, origname_location); - - if (tbltypStmt || restore_tsql_tabletype) - { - /* - * Add internal dependency between the table type and - * the function. - */ - tbltyp.classId = TypeRelationId; - tbltyp.objectId = typenameTypeId(pstate, - stmt->returnType); - tbltyp.objectSubId = 0; - recordDependencyOn(&tbltyp, &address, DEPENDENCY_INTERNAL); - } - - /* - * For trigStmt, we need to process the CreateTrigStmt after - * the function is created, and record bidirectional - * dependency so that Drop Trigger CASCADE will drop the - * implicit trigger function. - * Create trigger takes care of dependency addition. - */ - if (trigStmt) - { - (void)CreateTrigger((CreateTrigStmt *)trigStmt, - pstate->p_sourcetext, InvalidOid, InvalidOid, - InvalidOid, InvalidOid, address.objectId, - InvalidOid, NULL, false, false); - } - - /* - * Remember the object so that ddl_command_end event triggers have - * access to it. - */ - EventTriggerCollectSimpleCommand(address, InvalidObjectAddress, - parsetree); - - if (isCompleteQuery) - { - EventTriggerSQLDrop(parsetree); - EventTriggerDDLCommandEnd(parsetree); - } - } - - PG_CATCH(); - { - if (needCleanup) - EventTriggerEndCompleteQuery(); - PG_RE_THROW(); - } - PG_END_TRY(); - - if (needCleanup) - EventTriggerEndCompleteQuery(); + pltsql_createFunction(pstate, pstmt, queryString, context, params); return true; - - } + } break; } case T_CreatedbStmt: diff --git a/contrib/babelfishpg_tsql/src/pltsql.h b/contrib/babelfishpg_tsql/src/pltsql.h index 9cb0c6d633..5e35926b83 100644 --- a/contrib/babelfishpg_tsql/src/pltsql.h +++ b/contrib/babelfishpg_tsql/src/pltsql.h @@ -31,6 +31,7 @@ #include "utils/plancache.h" #include "utils/portal.h" #include "utils/typcache.h" +#include "tcop/utility.h" #include "dynavec.h" #include "dynastack.h" @@ -2016,6 +2017,8 @@ extern void remove_trailing_spaces(char *name); extern Oid tsql_get_proc_nsp_oid(Oid object_id); extern Oid tsql_get_constraint_nsp_oid(Oid object_id, Oid user_id); extern Oid tsql_get_trigger_rel_oid(Oid object_id); +extern void pltsql_createFunction(ParseState *pstate, PlannedStmt *pstmt, const char *queryString, ProcessUtilityContext context, + ParamListInfo params); typedef struct { diff --git a/contrib/babelfishpg_tsql/src/pltsql_utils.c b/contrib/babelfishpg_tsql/src/pltsql_utils.c index 7b19ace186..e35082c732 100644 --- a/contrib/babelfishpg_tsql/src/pltsql_utils.c +++ b/contrib/babelfishpg_tsql/src/pltsql_utils.c @@ -22,6 +22,8 @@ #include "access/table.h" #include "access/genam.h" #include "catalog.h" +#include "parser/gramparse.h" +#include "hooks.h" #include "multidb.h" @@ -35,6 +37,12 @@ bool is_tsql_any_char_datatype(Oid oid); /* sys.char / sys.nchar / * sys.varchar / sys.nvarchar */ bool is_tsql_text_ntext_or_image_datatype(Oid oid); +void +pltsql_createFunction(ParseState *pstate, PlannedStmt *pstmt, const char *queryString, ProcessUtilityContext context, + ParamListInfo params); + +extern bool restore_tsql_tabletype; + /* * Following the rule for locktag fields of advisory locks: * field1: MyDatabaseId ... ensures locks are local to each database @@ -67,6 +75,186 @@ const uint64 PLTSQL_LOCKTAG_OFFSET = 0xABCDEF; * Also, length should be restricted to 8000 for sys.varchar and sys.char datatypes. * And length should be restricted to 4000 for sys.varchar and sys.char datatypes */ +void +pltsql_createFunction(ParseState *pstate, PlannedStmt *pstmt, const char *queryString, ProcessUtilityContext context, + ParamListInfo params) +{ + Node *parsetree = pstmt->utilityStmt; + CreateFunctionStmt *stmt = (CreateFunctionStmt *)parsetree; + ListCell *option, *location_cell = NULL; + DefElem *language_item = NULL; + char *language = NULL; + ObjectAddress address; + bool isCompleteQuery = (context != PROCESS_UTILITY_SUBCOMMAND); + bool needCleanup; + Node *tbltypStmt = NULL; + Node *trigStmt = NULL; + ObjectAddress tbltyp; + int origname_location = -1; + + pstate->p_sourcetext = queryString; + + foreach(option, stmt->options) + { + DefElem *defel = (DefElem *)lfirst(option); + + if (strcmp(defel->defname, "language") == 0) + { + if (language_item) + ereport(ERROR, + (errcode(ERRCODE_SYNTAX_ERROR), + errmsg("conflicting or redundant options"), + parser_errposition(pstate, defel->location))); + language_item = defel; + } + } + + if (language_item) + language = strVal(language_item->arg); + + if((language && !strcmp(language,"pltsql")) || sql_dialect == SQL_DIALECT_TSQL) + { + /* All event trigger calls are done only when isCompleteQuery is true */ + needCleanup = isCompleteQuery && EventTriggerBeginCompleteQuery(); + + /* PG_TRY block is to ensure we call EventTriggerEndCompleteQuery */ + PG_TRY(); + { + + if (isCompleteQuery) + EventTriggerDDLCommandStart(parsetree); + + foreach (option, stmt->options) + { + DefElem *defel = (DefElem *)lfirst(option); + if (strcmp(defel->defname, "tbltypStmt") == 0) + { + /* + * tbltypStmt is an implicit option in tsql dialect, + * we use this mechanism to create tsql style + * multi-statement table-valued function and its + * return (table) type in one statement. + */ + tbltypStmt = defel->arg; + } + else if (strcmp(defel->defname, "trigStmt") == 0) + { + /* + * trigStmt is an implicit option in tsql dialect, + * we use this mechanism to create tsql style function + * and trigger in one statement. + */ + trigStmt = defel->arg; + } + else if (strcmp(defel->defname, "location") == 0) + { + /* + * location is an implicit option in tsql dialect, + * we use this mechanism to store location of function + * name so that we can extract original input function + * name from queryString. + */ + origname_location = intVal((Node *)defel->arg); + location_cell = option; + pfree(defel); + } + } + + /* delete location cell if it exists as it is for internal use only */ + if (location_cell) + stmt->options = list_delete_cell(stmt->options, location_cell); + + /* + * For tbltypStmt, we need to first process the CreateStmt + * to create the type that will be used as the function's + * return type. Then, after the function is created, add a + * dependency between the type and the function. + */ + if (tbltypStmt) + { + /* Handle tbltypStmt, which is a CreateStmt */ + PlannedStmt *wrapper; + + wrapper = makeNode(PlannedStmt); + wrapper->commandType = CMD_UTILITY; + wrapper->canSetTag = false; + wrapper->utilityStmt = tbltypStmt; + wrapper->stmt_location = pstmt->stmt_location; + wrapper->stmt_len = pstmt->stmt_len; + + ProcessUtility(wrapper, + queryString, + false, + PROCESS_UTILITY_SUBCOMMAND, + params, + NULL, + None_Receiver, + NULL); + + /* Need CCI between commands */ + CommandCounterIncrement(); + } + + address = CreateFunction(pstate, stmt); + + /* Store function/procedure related metadata in babelfish catalog */ + pltsql_store_func_default_positions(address, stmt->parameters, queryString, origname_location); + + if (tbltypStmt || restore_tsql_tabletype) + { + /* + * Add internal dependency between the table type and + * the function. + */ + tbltyp.classId = TypeRelationId; + tbltyp.objectId = typenameTypeId(pstate, + stmt->returnType); + tbltyp.objectSubId = 0; + recordDependencyOn(&tbltyp, &address, DEPENDENCY_INTERNAL); + } + + /* + * For trigStmt, we need to process the CreateTrigStmt after + * the function is created, and record bidirectional + * dependency so that Drop Trigger CASCADE will drop the + * implicit trigger function. + * Create trigger takes care of dependency addition. + */ + if (trigStmt) + { + (void)CreateTrigger((CreateTrigStmt *)trigStmt, + pstate->p_sourcetext, InvalidOid, InvalidOid, + InvalidOid, InvalidOid, address.objectId, + InvalidOid, NULL, false, false); + } + + /* + * Remember the object so that ddl_command_end event triggers have + * access to it. + */ + EventTriggerCollectSimpleCommand(address, InvalidObjectAddress, + parsetree); + + if (isCompleteQuery) + { + EventTriggerSQLDrop(parsetree); + EventTriggerDDLCommandEnd(parsetree); + } + } + + PG_CATCH(); + { + if (needCleanup) + EventTriggerEndCompleteQuery(); + PG_RE_THROW(); + } + PG_END_TRY(); + + if (needCleanup) + EventTriggerEndCompleteQuery(); + } +} + void pltsql_check_or_set_default_typmod(TypeName *typeName, int32 *typmod, bool is_cast) { From 5951d53553009a3811e3c02e1301ce7b552cfca1 Mon Sep 17 00:00:00 2001 From: Kritika Date: Thu, 20 Apr 2023 10:21:35 +0000 Subject: [PATCH 25/43] Create proc/func/database etc not visible in pg_stat_statements view Subsequent processutility hooks after bbf_processutilty are not being called. Created a hook for that and called it inside relevant ProcessUtility function. Signed-off-by: Kritika --- contrib/babelfishpg_tsql/src/hooks.c | 6 +----- contrib/babelfishpg_tsql/src/pltsql.h | 2 +- contrib/babelfishpg_tsql/src/pltsql_utils.c | 14 +++++++++++--- 3 files changed, 13 insertions(+), 9 deletions(-) diff --git a/contrib/babelfishpg_tsql/src/hooks.c b/contrib/babelfishpg_tsql/src/hooks.c index 0218087bb9..d657487993 100644 --- a/contrib/babelfishpg_tsql/src/hooks.c +++ b/contrib/babelfishpg_tsql/src/hooks.c @@ -390,11 +390,7 @@ pltsql_bbfCustomProcessUtility(ParseState *pstate, PlannedStmt *pstmt, const cha { case T_CreateFunctionStmt: { - if (sql_dialect == SQL_DIALECT_TSQL) - { - pltsql_createFunction(pstate, pstmt, queryString, context, params); - return true; - } + return pltsql_createFunction(pstate, pstmt, queryString, context, params); break; } case T_CreatedbStmt: diff --git a/contrib/babelfishpg_tsql/src/pltsql.h b/contrib/babelfishpg_tsql/src/pltsql.h index 5e35926b83..c77e4ab24c 100644 --- a/contrib/babelfishpg_tsql/src/pltsql.h +++ b/contrib/babelfishpg_tsql/src/pltsql.h @@ -2017,7 +2017,7 @@ extern void remove_trailing_spaces(char *name); extern Oid tsql_get_proc_nsp_oid(Oid object_id); extern Oid tsql_get_constraint_nsp_oid(Oid object_id, Oid user_id); extern Oid tsql_get_trigger_rel_oid(Oid object_id); -extern void pltsql_createFunction(ParseState *pstate, PlannedStmt *pstmt, const char *queryString, ProcessUtilityContext context, +extern bool pltsql_createFunction(ParseState *pstate, PlannedStmt *pstmt, const char *queryString, ProcessUtilityContext context, ParamListInfo params); typedef struct diff --git a/contrib/babelfishpg_tsql/src/pltsql_utils.c b/contrib/babelfishpg_tsql/src/pltsql_utils.c index e35082c732..b41291d7c2 100644 --- a/contrib/babelfishpg_tsql/src/pltsql_utils.c +++ b/contrib/babelfishpg_tsql/src/pltsql_utils.c @@ -37,7 +37,7 @@ bool is_tsql_any_char_datatype(Oid oid); /* sys.char / sys.nchar / * sys.varchar / sys.nvarchar */ bool is_tsql_text_ntext_or_image_datatype(Oid oid); -void +bool pltsql_createFunction(ParseState *pstate, PlannedStmt *pstmt, const char *queryString, ProcessUtilityContext context, ParamListInfo params); @@ -75,7 +75,7 @@ const uint64 PLTSQL_LOCKTAG_OFFSET = 0xABCDEF; * Also, length should be restricted to 8000 for sys.varchar and sys.char datatypes. * And length should be restricted to 4000 for sys.varchar and sys.char datatypes */ -void +bool pltsql_createFunction(ParseState *pstate, PlannedStmt *pstmt, const char *queryString, ProcessUtilityContext context, ParamListInfo params) { @@ -112,8 +112,13 @@ pltsql_createFunction(ParseState *pstate, PlannedStmt *pstmt, const char *queryS if (language_item) language = strVal(language_item->arg); - if((language && !strcmp(language,"pltsql")) || sql_dialect == SQL_DIALECT_TSQL) + if(!((language && !strcmp(language,"pltsql")) || sql_dialect == SQL_DIALECT_TSQL)) { + return false; + } + + else + { /* All event trigger calls are done only when isCompleteQuery is true */ needCleanup = isCompleteQuery && EventTriggerBeginCompleteQuery(); @@ -252,6 +257,9 @@ pltsql_createFunction(ParseState *pstate, PlannedStmt *pstmt, const char *queryS if (needCleanup) EventTriggerEndCompleteQuery(); + + return true; + } } From 9bec2e2443bdba80714052f2589867049be8aaf1 Mon Sep 17 00:00:00 2001 From: Kritika Date: Thu, 27 Apr 2023 05:20:10 +0000 Subject: [PATCH 26/43] retrigger tests From aed53a9c804dcaa75a4a057c53e7830ae97e9b3f Mon Sep 17 00:00:00 2001 From: Kritika Date: Tue, 2 May 2023 03:54:55 +0000 Subject: [PATCH 27/43] Create proc/func/database etc not visible in pg_stat_statements view Subsequent processutility hooks after bbf_processutilty are not being called. Created a hook for that and called it inside relevant ProcessUtility function. Signed-off-by: Kritika --- contrib/babelfishpg_tsql/src/pl_handler.c | 101 ----- contrib/babelfishpg_tsql/src/pltsql_utils.c | 425 ++++++++++++-------- 2 files changed, 263 insertions(+), 263 deletions(-) diff --git a/contrib/babelfishpg_tsql/src/pl_handler.c b/contrib/babelfishpg_tsql/src/pl_handler.c index 74c5143ae9..6b478ca5a6 100644 --- a/contrib/babelfishpg_tsql/src/pl_handler.c +++ b/contrib/babelfishpg_tsql/src/pl_handler.c @@ -1881,107 +1881,6 @@ bbf_table_var_lookup(const char *relname, Oid relnamespace) return relid; } -/* - * Transaction processing using tsql semantics - */ -extern void -PLTsqlProcessTransaction(Node *parsetree, - ParamListInfo params, - QueryCompletion *qc) -{ - char *txnName = NULL; - TransactionStmt *stmt = (TransactionStmt *) parsetree; - - if (params != NULL && params->numParams > 0 && !params->params[0].isnull) - { - Oid typOutput; - bool typIsVarlena; - FmgrInfo finfo; - - Assert(params->numParams == 1); - getTypeOutputInfo(params->params[0].ptype, &typOutput, &typIsVarlena); - fmgr_info(typOutput, &finfo); - txnName = OutputFunctionCall(&finfo, params->params[0].value); - } - else - txnName = stmt->savepoint_name; - - if (txnName != NULL && strlen(txnName) > TSQL_TXN_NAME_LIMIT / 2) - ereport(ERROR, - (errcode(ERRCODE_NAME_TOO_LONG), - errmsg("Transaction name length %zu above limit %u", - strlen(txnName), TSQL_TXN_NAME_LIMIT / 2))); - - if (AbortCurTransaction) - { - if (stmt->kind == TRANS_STMT_BEGIN || - stmt->kind == TRANS_STMT_COMMIT || - stmt->kind == TRANS_STMT_SAVEPOINT) - ereport(ERROR, - (errcode(ERRCODE_TRANSACTION_ROLLBACK), - errmsg("The current transaction cannot be committed and cannot support operations that write to the log file. Roll back the transaction."))); - } - - switch (stmt->kind) - { - case TRANS_STMT_BEGIN: - { - PLTsqlStartTransaction(txnName); - } - break; - - case TRANS_STMT_COMMIT: - { - if (exec_state_call_stack && - exec_state_call_stack->estate && - exec_state_call_stack->estate->insert_exec && - NestedTranCount <= 1) - ereport(ERROR, - (errcode(ERRCODE_TRANSACTION_ROLLBACK), - errmsg("Cannot use the COMMIT statement within an INSERT-EXEC statement unless BEGIN TRANSACTION is used first."))); - - PLTsqlCommitTransaction(qc, stmt->chain); - } - break; - - case TRANS_STMT_ROLLBACK: - { - if (exec_state_call_stack && - exec_state_call_stack->estate && - exec_state_call_stack->estate->insert_exec) - ereport(ERROR, - (errcode(ERRCODE_TRANSACTION_ROLLBACK), - errmsg("Cannot use the ROLLBACK statement within an INSERT-EXEC statement."))); - - /* - * Table variables should be immune to ROLLBACK, but we - * haven't implemented this yet so we throw an error if - * ROLLBACK is used with table variables. - */ - if (exec_state_call_stack && - exec_state_call_stack->estate && - exec_state_call_stack->estate->func && - list_length(exec_state_call_stack->estate->func->table_varnos) > 0) - ereport(ERROR, - (errcode(ERRCODE_FEATURE_NOT_SUPPORTED), - errmsg("ROLLBACK statement with active table variables is not yet supported."))); - PLTsqlRollbackTransaction(txnName, qc, stmt->chain); - } - break; - - case TRANS_STMT_SAVEPOINT: - RequireTransactionBlock(true, "SAVEPOINT"); - DefineSavepoint(txnName); - break; - - default: - ereport(ERROR, - (errcode(ERRCODE_INVALID_TRANSACTION_INITIATION), - errmsg("Unsupported transaction command : %d", stmt->kind))); - break; - } -} - /* * It returns TRUE when we should not execute the utility statement, * e.g., CREATE FUNCTION, in EXPLAIN ONLY MODE. diff --git a/contrib/babelfishpg_tsql/src/pltsql_utils.c b/contrib/babelfishpg_tsql/src/pltsql_utils.c index b41291d7c2..f4066f641e 100644 --- a/contrib/babelfishpg_tsql/src/pltsql_utils.c +++ b/contrib/babelfishpg_tsql/src/pltsql_utils.c @@ -75,192 +75,293 @@ const uint64 PLTSQL_LOCKTAG_OFFSET = 0xABCDEF; * Also, length should be restricted to 8000 for sys.varchar and sys.char datatypes. * And length should be restricted to 4000 for sys.varchar and sys.char datatypes */ + +/* + * Transaction processing using tsql semantics + */ +extern void +PLTsqlProcessTransaction(Node *parsetree, + ParamListInfo params, + QueryCompletion *qc) +{ + char *txnName = NULL; + TransactionStmt *stmt = (TransactionStmt *) parsetree; + + if (params != NULL && params->numParams > 0 && !params->params[0].isnull) + { + Oid typOutput; + bool typIsVarlena; + FmgrInfo finfo; + + Assert(params->numParams == 1); + getTypeOutputInfo(params->params[0].ptype, &typOutput, &typIsVarlena); + fmgr_info(typOutput, &finfo); + txnName = OutputFunctionCall(&finfo, params->params[0].value); + } + else + txnName = stmt->savepoint_name; + + if (txnName != NULL && strlen(txnName) > TSQL_TXN_NAME_LIMIT / 2) + ereport(ERROR, + (errcode(ERRCODE_NAME_TOO_LONG), + errmsg("Transaction name length %zu above limit %u", + strlen(txnName), TSQL_TXN_NAME_LIMIT / 2))); + + if (AbortCurTransaction) + { + if (stmt->kind == TRANS_STMT_BEGIN || + stmt->kind == TRANS_STMT_COMMIT || + stmt->kind == TRANS_STMT_SAVEPOINT) + ereport(ERROR, + (errcode(ERRCODE_TRANSACTION_ROLLBACK), + errmsg("The current transaction cannot be committed and cannot support operations that write to the log file. Roll back the transaction."))); + } + + switch (stmt->kind) + { + case TRANS_STMT_BEGIN: + { + PLTsqlStartTransaction(txnName); + } + break; + + case TRANS_STMT_COMMIT: + { + if (exec_state_call_stack && + exec_state_call_stack->estate && + exec_state_call_stack->estate->insert_exec && + NestedTranCount <= 1) + ereport(ERROR, + (errcode(ERRCODE_TRANSACTION_ROLLBACK), + errmsg("Cannot use the COMMIT statement within an INSERT-EXEC statement unless BEGIN TRANSACTION is used first."))); + + PLTsqlCommitTransaction(qc, stmt->chain); + } + break; + + case TRANS_STMT_ROLLBACK: + { + if (exec_state_call_stack && + exec_state_call_stack->estate && + exec_state_call_stack->estate->insert_exec) + ereport(ERROR, + (errcode(ERRCODE_TRANSACTION_ROLLBACK), + errmsg("Cannot use the ROLLBACK statement within an INSERT-EXEC statement."))); + + /* + * Table variables should be immune to ROLLBACK, but we + * haven't implemented this yet so we throw an error if + * ROLLBACK is used with table variables. + */ + if (exec_state_call_stack && + exec_state_call_stack->estate && + exec_state_call_stack->estate->func && + list_length(exec_state_call_stack->estate->func->table_varnos) > 0) + ereport(ERROR, + (errcode(ERRCODE_FEATURE_NOT_SUPPORTED), + errmsg("ROLLBACK statement with active table variables is not yet supported."))); + PLTsqlRollbackTransaction(txnName, qc, stmt->chain); + } + break; + + case TRANS_STMT_SAVEPOINT: + RequireTransactionBlock(true, "SAVEPOINT"); + DefineSavepoint(txnName); + break; + + default: + ereport(ERROR, + (errcode(ERRCODE_INVALID_TRANSACTION_INITIATION), + errmsg("Unsupported transaction command : %d", stmt->kind))); + break; + } +} + bool pltsql_createFunction(ParseState *pstate, PlannedStmt *pstmt, const char *queryString, ProcessUtilityContext context, ParamListInfo params) { Node *parsetree = pstmt->utilityStmt; CreateFunctionStmt *stmt = (CreateFunctionStmt *)parsetree; - ListCell *option, *location_cell = NULL; - DefElem *language_item = NULL; - char *language = NULL; - ObjectAddress address; - bool isCompleteQuery = (context != PROCESS_UTILITY_SUBCOMMAND); - bool needCleanup; - Node *tbltypStmt = NULL; - Node *trigStmt = NULL; - ObjectAddress tbltyp; - int origname_location = -1; - - pstate->p_sourcetext = queryString; - - foreach(option, stmt->options) - { - DefElem *defel = (DefElem *)lfirst(option); - - if (strcmp(defel->defname, "language") == 0) - { - if (language_item) - ereport(ERROR, - (errcode(ERRCODE_SYNTAX_ERROR), - errmsg("conflicting or redundant options"), - parser_errposition(pstate, defel->location))); - language_item = defel; - } - } - - if (language_item) - language = strVal(language_item->arg); - - if(!((language && !strcmp(language,"pltsql")) || sql_dialect == SQL_DIALECT_TSQL)) + ListCell *option, *location_cell = NULL; + DefElem *language_item = NULL; + char *language = NULL; + ObjectAddress address; + bool isCompleteQuery = (context != PROCESS_UTILITY_SUBCOMMAND); + bool needCleanup; + Node *tbltypStmt = NULL; + Node *trigStmt = NULL; + ObjectAddress tbltyp; + int origname_location = -1; + + pstate->p_sourcetext = queryString; + + foreach(option, stmt->options) { - return false; + DefElem *defel = (DefElem *)lfirst(option); + + if (strcmp(defel->defname, "language") == 0) + { + if (language_item) + ereport(ERROR, + (errcode(ERRCODE_SYNTAX_ERROR), + errmsg("conflicting or redundant options"), + parser_errposition(pstate, defel->location))); + language_item = defel; + } } - else - { - /* All event trigger calls are done only when isCompleteQuery is true */ - needCleanup = isCompleteQuery && EventTriggerBeginCompleteQuery(); + if (language_item) + language = strVal(language_item->arg); - /* PG_TRY block is to ensure we call EventTriggerEndCompleteQuery */ - PG_TRY(); - { + if(!((language && !strcmp(language,"pltsql")) || sql_dialect == SQL_DIALECT_TSQL)) + { + return false; + } - if (isCompleteQuery) - EventTriggerDDLCommandStart(parsetree); - - foreach (option, stmt->options) - { - DefElem *defel = (DefElem *)lfirst(option); - if (strcmp(defel->defname, "tbltypStmt") == 0) - { - /* - * tbltypStmt is an implicit option in tsql dialect, - * we use this mechanism to create tsql style - * multi-statement table-valued function and its - * return (table) type in one statement. - */ - tbltypStmt = defel->arg; - } - else if (strcmp(defel->defname, "trigStmt") == 0) - { - /* - * trigStmt is an implicit option in tsql dialect, - * we use this mechanism to create tsql style function - * and trigger in one statement. - */ - trigStmt = defel->arg; - } - else if (strcmp(defel->defname, "location") == 0) - { - /* - * location is an implicit option in tsql dialect, - * we use this mechanism to store location of function - * name so that we can extract original input function - * name from queryString. - */ - origname_location = intVal((Node *)defel->arg); - location_cell = option; - pfree(defel); - } - } - - /* delete location cell if it exists as it is for internal use only */ - if (location_cell) - stmt->options = list_delete_cell(stmt->options, location_cell); + else + { + /* All event trigger calls are done only when isCompleteQuery is true */ + needCleanup = isCompleteQuery && EventTriggerBeginCompleteQuery(); - /* - * For tbltypStmt, we need to first process the CreateStmt - * to create the type that will be used as the function's - * return type. Then, after the function is created, add a - * dependency between the type and the function. - */ - if (tbltypStmt) - { - /* Handle tbltypStmt, which is a CreateStmt */ - PlannedStmt *wrapper; - - wrapper = makeNode(PlannedStmt); - wrapper->commandType = CMD_UTILITY; - wrapper->canSetTag = false; - wrapper->utilityStmt = tbltypStmt; - wrapper->stmt_location = pstmt->stmt_location; - wrapper->stmt_len = pstmt->stmt_len; - - ProcessUtility(wrapper, - queryString, - false, - PROCESS_UTILITY_SUBCOMMAND, - params, - NULL, - None_Receiver, - NULL); - - /* Need CCI between commands */ - CommandCounterIncrement(); - } - - address = CreateFunction(pstate, stmt); - - /* Store function/procedure related metadata in babelfish catalog */ - pltsql_store_func_default_positions(address, stmt->parameters, queryString, origname_location); - - if (tbltypStmt || restore_tsql_tabletype) - { - /* - * Add internal dependency between the table type and - * the function. - */ - tbltyp.classId = TypeRelationId; - tbltyp.objectId = typenameTypeId(pstate, - stmt->returnType); - tbltyp.objectSubId = 0; - recordDependencyOn(&tbltyp, &address, DEPENDENCY_INTERNAL); - } + /* PG_TRY block is to ensure we call EventTriggerEndCompleteQuery */ + PG_TRY(); + { + if (isCompleteQuery) + EventTriggerDDLCommandStart(parsetree); + + foreach (option, stmt->options) + { + DefElem *defel = (DefElem *)lfirst(option); + if (strcmp(defel->defname, "tbltypStmt") == 0) + { /* - * For trigStmt, we need to process the CreateTrigStmt after - * the function is created, and record bidirectional - * dependency so that Drop Trigger CASCADE will drop the - * implicit trigger function. - * Create trigger takes care of dependency addition. + * tbltypStmt is an implicit option in tsql dialect, + * we use this mechanism to create tsql style + * multi-statement table-valued function and its + * return (table) type in one statement. */ - if (trigStmt) - { - (void)CreateTrigger((CreateTrigStmt *)trigStmt, - pstate->p_sourcetext, InvalidOid, InvalidOid, - InvalidOid, InvalidOid, address.objectId, - InvalidOid, NULL, false, false); - } - + tbltypStmt = defel->arg; + } + else if (strcmp(defel->defname, "trigStmt") == 0) + { /* - * Remember the object so that ddl_command_end event triggers have - * access to it. + * trigStmt is an implicit option in tsql dialect, + * we use this mechanism to create tsql style function + * and trigger in one statement. */ - EventTriggerCollectSimpleCommand(address, InvalidObjectAddress, - parsetree); - - if (isCompleteQuery) - { - EventTriggerSQLDrop(parsetree); - EventTriggerDDLCommandEnd(parsetree); - } + trigStmt = defel->arg; } - - PG_CATCH(); + else if (strcmp(defel->defname, "location") == 0) { - if (needCleanup) - EventTriggerEndCompleteQuery(); - PG_RE_THROW(); + /* + * location is an implicit option in tsql dialect, + * we use this mechanism to store location of function + * name so that we can extract original input function + * name from queryString. + */ + origname_location = intVal((Node *)defel->arg); + location_cell = option; + pfree(defel); } - PG_END_TRY(); + } - if (needCleanup) - EventTriggerEndCompleteQuery(); + /* delete location cell if it exists as it is for internal use only */ + if (location_cell) + stmt->options = list_delete_cell(stmt->options, location_cell); - return true; + /* + * For tbltypStmt, we need to first process the CreateStmt + * to create the type that will be used as the function's + * return type. Then, after the function is created, add a + * dependency between the type and the function. + */ + if (tbltypStmt) + { + /* Handle tbltypStmt, which is a CreateStmt */ + PlannedStmt *wrapper; + + wrapper = makeNode(PlannedStmt); + wrapper->commandType = CMD_UTILITY; + wrapper->canSetTag = false; + wrapper->utilityStmt = tbltypStmt; + wrapper->stmt_location = pstmt->stmt_location; + wrapper->stmt_len = pstmt->stmt_len; + + ProcessUtility(wrapper, + queryString, + false, + PROCESS_UTILITY_SUBCOMMAND, + params, + NULL, + None_Receiver, + NULL); + + /* Need CCI between commands */ + CommandCounterIncrement(); + } + + address = CreateFunction(pstate, stmt); + + /* Store function/procedure related metadata in babelfish catalog */ + pltsql_store_func_default_positions(address, stmt->parameters, queryString, origname_location); + + if (tbltypStmt || restore_tsql_tabletype) + { + /* + * Add internal dependency between the table type and + * the function. + */ + tbltyp.classId = TypeRelationId; + tbltyp.objectId = typenameTypeId(pstate, + stmt->returnType); + tbltyp.objectSubId = 0; + recordDependencyOn(&tbltyp, &address, DEPENDENCY_INTERNAL); + } + + /* + * For trigStmt, we need to process the CreateTrigStmt after + * the function is created, and record bidirectional + * dependency so that Drop Trigger CASCADE will drop the + * implicit trigger function. + * Create trigger takes care of dependency addition. + */ + if (trigStmt) + { + (void)CreateTrigger((CreateTrigStmt *)trigStmt, + pstate->p_sourcetext, InvalidOid, InvalidOid, + InvalidOid, InvalidOid, address.objectId, + InvalidOid, NULL, false, false); + } + + /* + * Remember the object so that ddl_command_end event triggers have + * access to it. + */ + EventTriggerCollectSimpleCommand(address, InvalidObjectAddress, + parsetree); + if (isCompleteQuery) + { + EventTriggerSQLDrop(parsetree); + EventTriggerDDLCommandEnd(parsetree); } + } + + PG_CATCH(); + { + if (needCleanup) + EventTriggerEndCompleteQuery(); + PG_RE_THROW(); + } + PG_END_TRY(); + + if (needCleanup) + EventTriggerEndCompleteQuery(); + + return true; + } } void From c0018a3dc278cad61e32b88dae90b03bf8be5ef2 Mon Sep 17 00:00:00 2001 From: Kritika Date: Tue, 2 May 2023 04:26:27 +0000 Subject: [PATCH 28/43] retrigger tests From 9b4ddfef2a2ab6509dc872b0af3ede5e0eda6478 Mon Sep 17 00:00:00 2001 From: Kritika Date: Tue, 2 May 2023 05:06:57 +0000 Subject: [PATCH 29/43] retrigger tests From 54eacc433694de7f814e871e4ae13d3bede1f412 Mon Sep 17 00:00:00 2001 From: Kritika Date: Tue, 2 May 2023 06:39:50 +0000 Subject: [PATCH 30/43] Create proc/func/database etc not visible in pg_stat_statements view Subsequent processutility hooks after bbf_processutilty are not being called. Created a hook for that and called it inside relevant ProcessUtility function. Signed-off-by: Kritika --- contrib/babelfishpg_tsql/src/pl_handler.c | 101 ++++++++++++++++++++ contrib/babelfishpg_tsql/src/pltsql_utils.c | 101 -------------------- 2 files changed, 101 insertions(+), 101 deletions(-) diff --git a/contrib/babelfishpg_tsql/src/pl_handler.c b/contrib/babelfishpg_tsql/src/pl_handler.c index 25f588771c..4cc809ab9b 100644 --- a/contrib/babelfishpg_tsql/src/pl_handler.c +++ b/contrib/babelfishpg_tsql/src/pl_handler.c @@ -1881,6 +1881,107 @@ bbf_table_var_lookup(const char *relname, Oid relnamespace) return relid; } +/* + * Transaction processing using tsql semantics + */ +extern void +PLTsqlProcessTransaction(Node *parsetree, + ParamListInfo params, + QueryCompletion *qc) +{ + char *txnName = NULL; + TransactionStmt *stmt = (TransactionStmt *) parsetree; + + if (params != NULL && params->numParams > 0 && !params->params[0].isnull) + { + Oid typOutput; + bool typIsVarlena; + FmgrInfo finfo; + + Assert(params->numParams == 1); + getTypeOutputInfo(params->params[0].ptype, &typOutput, &typIsVarlena); + fmgr_info(typOutput, &finfo); + txnName = OutputFunctionCall(&finfo, params->params[0].value); + } + else + txnName = stmt->savepoint_name; + + if (txnName != NULL && strlen(txnName) > TSQL_TXN_NAME_LIMIT / 2) + ereport(ERROR, + (errcode(ERRCODE_NAME_TOO_LONG), + errmsg("Transaction name length %zu above limit %u", + strlen(txnName), TSQL_TXN_NAME_LIMIT / 2))); + + if (AbortCurTransaction) + { + if (stmt->kind == TRANS_STMT_BEGIN || + stmt->kind == TRANS_STMT_COMMIT || + stmt->kind == TRANS_STMT_SAVEPOINT) + ereport(ERROR, + (errcode(ERRCODE_TRANSACTION_ROLLBACK), + errmsg("The current transaction cannot be committed and cannot support operations that write to the log file. Roll back the transaction."))); + } + + switch (stmt->kind) + { + case TRANS_STMT_BEGIN: + { + PLTsqlStartTransaction(txnName); + } + break; + + case TRANS_STMT_COMMIT: + { + if (exec_state_call_stack && + exec_state_call_stack->estate && + exec_state_call_stack->estate->insert_exec && + NestedTranCount <= 1) + ereport(ERROR, + (errcode(ERRCODE_TRANSACTION_ROLLBACK), + errmsg("Cannot use the COMMIT statement within an INSERT-EXEC statement unless BEGIN TRANSACTION is used first."))); + + PLTsqlCommitTransaction(qc, stmt->chain); + } + break; + + case TRANS_STMT_ROLLBACK: + { + if (exec_state_call_stack && + exec_state_call_stack->estate && + exec_state_call_stack->estate->insert_exec) + ereport(ERROR, + (errcode(ERRCODE_TRANSACTION_ROLLBACK), + errmsg("Cannot use the ROLLBACK statement within an INSERT-EXEC statement."))); + + /* + * Table variables should be immune to ROLLBACK, but we + * haven't implemented this yet so we throw an error if + * ROLLBACK is used with table variables. + */ + if (exec_state_call_stack && + exec_state_call_stack->estate && + exec_state_call_stack->estate->func && + list_length(exec_state_call_stack->estate->func->table_varnos) > 0) + ereport(ERROR, + (errcode(ERRCODE_FEATURE_NOT_SUPPORTED), + errmsg("ROLLBACK statement with active table variables is not yet supported."))); + PLTsqlRollbackTransaction(txnName, qc, stmt->chain); + } + break; + + case TRANS_STMT_SAVEPOINT: + RequireTransactionBlock(true, "SAVEPOINT"); + DefineSavepoint(txnName); + break; + + default: + ereport(ERROR, + (errcode(ERRCODE_INVALID_TRANSACTION_INITIATION), + errmsg("Unsupported transaction command : %d", stmt->kind))); + break; + } +} + /* * It returns TRUE when we should not execute the utility statement, diff --git a/contrib/babelfishpg_tsql/src/pltsql_utils.c b/contrib/babelfishpg_tsql/src/pltsql_utils.c index f4066f641e..ebf344228e 100644 --- a/contrib/babelfishpg_tsql/src/pltsql_utils.c +++ b/contrib/babelfishpg_tsql/src/pltsql_utils.c @@ -76,107 +76,6 @@ const uint64 PLTSQL_LOCKTAG_OFFSET = 0xABCDEF; * And length should be restricted to 4000 for sys.varchar and sys.char datatypes */ -/* - * Transaction processing using tsql semantics - */ -extern void -PLTsqlProcessTransaction(Node *parsetree, - ParamListInfo params, - QueryCompletion *qc) -{ - char *txnName = NULL; - TransactionStmt *stmt = (TransactionStmt *) parsetree; - - if (params != NULL && params->numParams > 0 && !params->params[0].isnull) - { - Oid typOutput; - bool typIsVarlena; - FmgrInfo finfo; - - Assert(params->numParams == 1); - getTypeOutputInfo(params->params[0].ptype, &typOutput, &typIsVarlena); - fmgr_info(typOutput, &finfo); - txnName = OutputFunctionCall(&finfo, params->params[0].value); - } - else - txnName = stmt->savepoint_name; - - if (txnName != NULL && strlen(txnName) > TSQL_TXN_NAME_LIMIT / 2) - ereport(ERROR, - (errcode(ERRCODE_NAME_TOO_LONG), - errmsg("Transaction name length %zu above limit %u", - strlen(txnName), TSQL_TXN_NAME_LIMIT / 2))); - - if (AbortCurTransaction) - { - if (stmt->kind == TRANS_STMT_BEGIN || - stmt->kind == TRANS_STMT_COMMIT || - stmt->kind == TRANS_STMT_SAVEPOINT) - ereport(ERROR, - (errcode(ERRCODE_TRANSACTION_ROLLBACK), - errmsg("The current transaction cannot be committed and cannot support operations that write to the log file. Roll back the transaction."))); - } - - switch (stmt->kind) - { - case TRANS_STMT_BEGIN: - { - PLTsqlStartTransaction(txnName); - } - break; - - case TRANS_STMT_COMMIT: - { - if (exec_state_call_stack && - exec_state_call_stack->estate && - exec_state_call_stack->estate->insert_exec && - NestedTranCount <= 1) - ereport(ERROR, - (errcode(ERRCODE_TRANSACTION_ROLLBACK), - errmsg("Cannot use the COMMIT statement within an INSERT-EXEC statement unless BEGIN TRANSACTION is used first."))); - - PLTsqlCommitTransaction(qc, stmt->chain); - } - break; - - case TRANS_STMT_ROLLBACK: - { - if (exec_state_call_stack && - exec_state_call_stack->estate && - exec_state_call_stack->estate->insert_exec) - ereport(ERROR, - (errcode(ERRCODE_TRANSACTION_ROLLBACK), - errmsg("Cannot use the ROLLBACK statement within an INSERT-EXEC statement."))); - - /* - * Table variables should be immune to ROLLBACK, but we - * haven't implemented this yet so we throw an error if - * ROLLBACK is used with table variables. - */ - if (exec_state_call_stack && - exec_state_call_stack->estate && - exec_state_call_stack->estate->func && - list_length(exec_state_call_stack->estate->func->table_varnos) > 0) - ereport(ERROR, - (errcode(ERRCODE_FEATURE_NOT_SUPPORTED), - errmsg("ROLLBACK statement with active table variables is not yet supported."))); - PLTsqlRollbackTransaction(txnName, qc, stmt->chain); - } - break; - - case TRANS_STMT_SAVEPOINT: - RequireTransactionBlock(true, "SAVEPOINT"); - DefineSavepoint(txnName); - break; - - default: - ereport(ERROR, - (errcode(ERRCODE_INVALID_TRANSACTION_INITIATION), - errmsg("Unsupported transaction command : %d", stmt->kind))); - break; - } -} - bool pltsql_createFunction(ParseState *pstate, PlannedStmt *pstmt, const char *queryString, ProcessUtilityContext context, ParamListInfo params) From dc436231715cb13ef9793193e22e362645dd42b5 Mon Sep 17 00:00:00 2001 From: Kritika Date: Tue, 2 May 2023 06:48:07 +0000 Subject: [PATCH 31/43] Create proc/func/database etc not visible in pg_stat_statements view Subsequent processutility hooks after bbf_processutilty are not being called. Created a hook for that and called it inside relevant ProcessUtility function. Signed-off-by: Kritika --- contrib/babelfishpg_tsql/src/hooks.c | 4 +- contrib/babelfishpg_tsql/src/pl_handler.c | 101 -------------------- contrib/babelfishpg_tsql/src/pltsql_utils.c | 101 ++++++++++++++++++++ 3 files changed, 103 insertions(+), 103 deletions(-) diff --git a/contrib/babelfishpg_tsql/src/hooks.c b/contrib/babelfishpg_tsql/src/hooks.c index 5f95de9e66..649691e43c 100644 --- a/contrib/babelfishpg_tsql/src/hooks.c +++ b/contrib/babelfishpg_tsql/src/hooks.c @@ -452,8 +452,8 @@ pltsql_bbfCustomProcessUtility(ParseState *pstate, PlannedStmt *pstmt, const cha { if (NestedTranCount > 0 || (sql_dialect == SQL_DIALECT_TSQL && !IsTransactionBlockActive())) { - PLTsqlProcessTransaction(parsetree, params, qc); - return true; + return PLTsqlProcessTransaction(parsetree, params, qc); + //return true; } break; } diff --git a/contrib/babelfishpg_tsql/src/pl_handler.c b/contrib/babelfishpg_tsql/src/pl_handler.c index 4cc809ab9b..25f588771c 100644 --- a/contrib/babelfishpg_tsql/src/pl_handler.c +++ b/contrib/babelfishpg_tsql/src/pl_handler.c @@ -1881,107 +1881,6 @@ bbf_table_var_lookup(const char *relname, Oid relnamespace) return relid; } -/* - * Transaction processing using tsql semantics - */ -extern void -PLTsqlProcessTransaction(Node *parsetree, - ParamListInfo params, - QueryCompletion *qc) -{ - char *txnName = NULL; - TransactionStmt *stmt = (TransactionStmt *) parsetree; - - if (params != NULL && params->numParams > 0 && !params->params[0].isnull) - { - Oid typOutput; - bool typIsVarlena; - FmgrInfo finfo; - - Assert(params->numParams == 1); - getTypeOutputInfo(params->params[0].ptype, &typOutput, &typIsVarlena); - fmgr_info(typOutput, &finfo); - txnName = OutputFunctionCall(&finfo, params->params[0].value); - } - else - txnName = stmt->savepoint_name; - - if (txnName != NULL && strlen(txnName) > TSQL_TXN_NAME_LIMIT / 2) - ereport(ERROR, - (errcode(ERRCODE_NAME_TOO_LONG), - errmsg("Transaction name length %zu above limit %u", - strlen(txnName), TSQL_TXN_NAME_LIMIT / 2))); - - if (AbortCurTransaction) - { - if (stmt->kind == TRANS_STMT_BEGIN || - stmt->kind == TRANS_STMT_COMMIT || - stmt->kind == TRANS_STMT_SAVEPOINT) - ereport(ERROR, - (errcode(ERRCODE_TRANSACTION_ROLLBACK), - errmsg("The current transaction cannot be committed and cannot support operations that write to the log file. Roll back the transaction."))); - } - - switch (stmt->kind) - { - case TRANS_STMT_BEGIN: - { - PLTsqlStartTransaction(txnName); - } - break; - - case TRANS_STMT_COMMIT: - { - if (exec_state_call_stack && - exec_state_call_stack->estate && - exec_state_call_stack->estate->insert_exec && - NestedTranCount <= 1) - ereport(ERROR, - (errcode(ERRCODE_TRANSACTION_ROLLBACK), - errmsg("Cannot use the COMMIT statement within an INSERT-EXEC statement unless BEGIN TRANSACTION is used first."))); - - PLTsqlCommitTransaction(qc, stmt->chain); - } - break; - - case TRANS_STMT_ROLLBACK: - { - if (exec_state_call_stack && - exec_state_call_stack->estate && - exec_state_call_stack->estate->insert_exec) - ereport(ERROR, - (errcode(ERRCODE_TRANSACTION_ROLLBACK), - errmsg("Cannot use the ROLLBACK statement within an INSERT-EXEC statement."))); - - /* - * Table variables should be immune to ROLLBACK, but we - * haven't implemented this yet so we throw an error if - * ROLLBACK is used with table variables. - */ - if (exec_state_call_stack && - exec_state_call_stack->estate && - exec_state_call_stack->estate->func && - list_length(exec_state_call_stack->estate->func->table_varnos) > 0) - ereport(ERROR, - (errcode(ERRCODE_FEATURE_NOT_SUPPORTED), - errmsg("ROLLBACK statement with active table variables is not yet supported."))); - PLTsqlRollbackTransaction(txnName, qc, stmt->chain); - } - break; - - case TRANS_STMT_SAVEPOINT: - RequireTransactionBlock(true, "SAVEPOINT"); - DefineSavepoint(txnName); - break; - - default: - ereport(ERROR, - (errcode(ERRCODE_INVALID_TRANSACTION_INITIATION), - errmsg("Unsupported transaction command : %d", stmt->kind))); - break; - } -} - /* * It returns TRUE when we should not execute the utility statement, diff --git a/contrib/babelfishpg_tsql/src/pltsql_utils.c b/contrib/babelfishpg_tsql/src/pltsql_utils.c index ebf344228e..fd1f069e94 100644 --- a/contrib/babelfishpg_tsql/src/pltsql_utils.c +++ b/contrib/babelfishpg_tsql/src/pltsql_utils.c @@ -76,6 +76,107 @@ const uint64 PLTSQL_LOCKTAG_OFFSET = 0xABCDEF; * And length should be restricted to 4000 for sys.varchar and sys.char datatypes */ +/* + * Transaction processing using tsql semantics + */ +extern bool +PLTsqlProcessTransaction(Node *parsetree, + ParamListInfo params, + QueryCompletion *qc) +{ + char *txnName = NULL; + TransactionStmt *stmt = (TransactionStmt *) parsetree; + + if (params != NULL && params->numParams > 0 && !params->params[0].isnull) + { + Oid typOutput; + bool typIsVarlena; + FmgrInfo finfo; + + Assert(params->numParams == 1); + getTypeOutputInfo(params->params[0].ptype, &typOutput, &typIsVarlena); + fmgr_info(typOutput, &finfo); + txnName = OutputFunctionCall(&finfo, params->params[0].value); + } + else + txnName = stmt->savepoint_name; + + if (txnName != NULL && strlen(txnName) > TSQL_TXN_NAME_LIMIT / 2) + ereport(ERROR, + (errcode(ERRCODE_NAME_TOO_LONG), + errmsg("Transaction name length %zu above limit %u", + strlen(txnName), TSQL_TXN_NAME_LIMIT / 2))); + + if (AbortCurTransaction) + { + if (stmt->kind == TRANS_STMT_BEGIN || + stmt->kind == TRANS_STMT_COMMIT || + stmt->kind == TRANS_STMT_SAVEPOINT) + ereport(ERROR, + (errcode(ERRCODE_TRANSACTION_ROLLBACK), + errmsg("The current transaction cannot be committed and cannot support operations that write to the log file. Roll back the transaction."))); + } + + switch (stmt->kind) + { + case TRANS_STMT_BEGIN: + { + PLTsqlStartTransaction(txnName); + } + break; + + case TRANS_STMT_COMMIT: + { + if (exec_state_call_stack && + exec_state_call_stack->estate && + exec_state_call_stack->estate->insert_exec && + NestedTranCount <= 1) + ereport(ERROR, + (errcode(ERRCODE_TRANSACTION_ROLLBACK), + errmsg("Cannot use the COMMIT statement within an INSERT-EXEC statement unless BEGIN TRANSACTION is used first."))); + + PLTsqlCommitTransaction(qc, stmt->chain); + } + break; + + case TRANS_STMT_ROLLBACK: + { + if (exec_state_call_stack && + exec_state_call_stack->estate && + exec_state_call_stack->estate->insert_exec) + ereport(ERROR, + (errcode(ERRCODE_TRANSACTION_ROLLBACK), + errmsg("Cannot use the ROLLBACK statement within an INSERT-EXEC statement."))); + + /* + * Table variables should be immune to ROLLBACK, but we + * haven't implemented this yet so we throw an error if + * ROLLBACK is used with table variables. + */ + if (exec_state_call_stack && + exec_state_call_stack->estate && + exec_state_call_stack->estate->func && + list_length(exec_state_call_stack->estate->func->table_varnos) > 0) + ereport(ERROR, + (errcode(ERRCODE_FEATURE_NOT_SUPPORTED), + errmsg("ROLLBACK statement with active table variables is not yet supported."))); + PLTsqlRollbackTransaction(txnName, qc, stmt->chain); + } + break; + + case TRANS_STMT_SAVEPOINT: + RequireTransactionBlock(true, "SAVEPOINT"); + DefineSavepoint(txnName); + break; + + default: + ereport(ERROR, + (errcode(ERRCODE_INVALID_TRANSACTION_INITIATION), + errmsg("Unsupported transaction command : %d", stmt->kind))); + break; + } +} + bool pltsql_createFunction(ParseState *pstate, PlannedStmt *pstmt, const char *queryString, ProcessUtilityContext context, ParamListInfo params) From 342c57e30236101045fb7067144c13f3744ea0d9 Mon Sep 17 00:00:00 2001 From: Kritika Date: Tue, 2 May 2023 06:55:54 +0000 Subject: [PATCH 32/43] Create proc/func/database etc not visible in pg_stat_statements view Subsequent processutility hooks after bbf_processutilty are not being called. Created a hook for that and called it inside relevant ProcessUtility function. Signed-off-by: Kritika --- contrib/babelfishpg_tsql/src/pltsql_utils.c | 1 + 1 file changed, 1 insertion(+) diff --git a/contrib/babelfishpg_tsql/src/pltsql_utils.c b/contrib/babelfishpg_tsql/src/pltsql_utils.c index fd1f069e94..ee21148476 100644 --- a/contrib/babelfishpg_tsql/src/pltsql_utils.c +++ b/contrib/babelfishpg_tsql/src/pltsql_utils.c @@ -175,6 +175,7 @@ PLTsqlProcessTransaction(Node *parsetree, errmsg("Unsupported transaction command : %d", stmt->kind))); break; } + return true; } bool From d53c59168d6dc32bb65808ddc4e57c07c0c26c6f Mon Sep 17 00:00:00 2001 From: Kritika Date: Tue, 2 May 2023 06:59:16 +0000 Subject: [PATCH 33/43] retrigger tests From 86bb18f9097d4476581e3382b14290a8612693c1 Mon Sep 17 00:00:00 2001 From: Kritika Date: Tue, 2 May 2023 08:15:09 +0000 Subject: [PATCH 34/43] Create proc/func/database etc not visible in pg_stat_statements view Subsequent processutility hooks after bbf_processutilty are not being called. Created a hook for that and called it inside relevant ProcessUtility function. Signed-off-by: Kritika --- contrib/babelfishpg_tsql/src/hooks.c | 4 +- contrib/babelfishpg_tsql/src/pl_handler.c | 101 +++++++++++++++++++ contrib/babelfishpg_tsql/src/pltsql_utils.c | 102 -------------------- 3 files changed, 103 insertions(+), 104 deletions(-) diff --git a/contrib/babelfishpg_tsql/src/hooks.c b/contrib/babelfishpg_tsql/src/hooks.c index 649691e43c..5f95de9e66 100644 --- a/contrib/babelfishpg_tsql/src/hooks.c +++ b/contrib/babelfishpg_tsql/src/hooks.c @@ -452,8 +452,8 @@ pltsql_bbfCustomProcessUtility(ParseState *pstate, PlannedStmt *pstmt, const cha { if (NestedTranCount > 0 || (sql_dialect == SQL_DIALECT_TSQL && !IsTransactionBlockActive())) { - return PLTsqlProcessTransaction(parsetree, params, qc); - //return true; + PLTsqlProcessTransaction(parsetree, params, qc); + return true; } break; } diff --git a/contrib/babelfishpg_tsql/src/pl_handler.c b/contrib/babelfishpg_tsql/src/pl_handler.c index 25f588771c..41ffaaa55d 100644 --- a/contrib/babelfishpg_tsql/src/pl_handler.c +++ b/contrib/babelfishpg_tsql/src/pl_handler.c @@ -1882,6 +1882,107 @@ bbf_table_var_lookup(const char *relname, Oid relnamespace) return relid; } +/* + * Transaction processing using tsql semantics + */ +extern void +PLTsqlProcessTransaction(Node *parsetree, + ParamListInfo params, + QueryCompletion *qc) +{ + char *txnName = NULL; + TransactionStmt *stmt = (TransactionStmt *) parsetree; + + if (params != NULL && params->numParams > 0 && !params->params[0].isnull) + { + Oid typOutput; + bool typIsVarlena; + FmgrInfo finfo; + + Assert(params->numParams == 1); + getTypeOutputInfo(params->params[0].ptype, &typOutput, &typIsVarlena); + fmgr_info(typOutput, &finfo); + txnName = OutputFunctionCall(&finfo, params->params[0].value); + } + else + txnName = stmt->savepoint_name; + + if (txnName != NULL && strlen(txnName) > TSQL_TXN_NAME_LIMIT / 2) + ereport(ERROR, + (errcode(ERRCODE_NAME_TOO_LONG), + errmsg("Transaction name length %zu above limit %u", + strlen(txnName), TSQL_TXN_NAME_LIMIT / 2))); + + if (AbortCurTransaction) + { + if (stmt->kind == TRANS_STMT_BEGIN || + stmt->kind == TRANS_STMT_COMMIT || + stmt->kind == TRANS_STMT_SAVEPOINT) + ereport(ERROR, + (errcode(ERRCODE_TRANSACTION_ROLLBACK), + errmsg("The current transaction cannot be committed and cannot support operations that write to the log file. Roll back the transaction."))); + } + + switch (stmt->kind) + { + case TRANS_STMT_BEGIN: + { + PLTsqlStartTransaction(txnName); + } + break; + + case TRANS_STMT_COMMIT: + { + if (exec_state_call_stack && + exec_state_call_stack->estate && + exec_state_call_stack->estate->insert_exec && + NestedTranCount <= 1) + ereport(ERROR, + (errcode(ERRCODE_TRANSACTION_ROLLBACK), + errmsg("Cannot use the COMMIT statement within an INSERT-EXEC statement unless BEGIN TRANSACTION is used first."))); + + PLTsqlCommitTransaction(qc, stmt->chain); + } + break; + + case TRANS_STMT_ROLLBACK: + { + if (exec_state_call_stack && + exec_state_call_stack->estate && + exec_state_call_stack->estate->insert_exec) + ereport(ERROR, + (errcode(ERRCODE_TRANSACTION_ROLLBACK), + errmsg("Cannot use the ROLLBACK statement within an INSERT-EXEC statement."))); + + /* + * Table variables should be immune to ROLLBACK, but we + * haven't implemented this yet so we throw an error if + * ROLLBACK is used with table variables. + */ + if (exec_state_call_stack && + exec_state_call_stack->estate && + exec_state_call_stack->estate->func && + list_length(exec_state_call_stack->estate->func->table_varnos) > 0) + ereport(ERROR, + (errcode(ERRCODE_FEATURE_NOT_SUPPORTED), + errmsg("ROLLBACK statement with active table variables is not yet supported."))); + PLTsqlRollbackTransaction(txnName, qc, stmt->chain); + } + break; + + case TRANS_STMT_SAVEPOINT: + RequireTransactionBlock(true, "SAVEPOINT"); + DefineSavepoint(txnName); + break; + + default: + ereport(ERROR, + (errcode(ERRCODE_INVALID_TRANSACTION_INITIATION), + errmsg("Unsupported transaction command : %d", stmt->kind))); + break; + } +} + /* * It returns TRUE when we should not execute the utility statement, * e.g., CREATE FUNCTION, in EXPLAIN ONLY MODE. diff --git a/contrib/babelfishpg_tsql/src/pltsql_utils.c b/contrib/babelfishpg_tsql/src/pltsql_utils.c index ee21148476..ebf344228e 100644 --- a/contrib/babelfishpg_tsql/src/pltsql_utils.c +++ b/contrib/babelfishpg_tsql/src/pltsql_utils.c @@ -76,108 +76,6 @@ const uint64 PLTSQL_LOCKTAG_OFFSET = 0xABCDEF; * And length should be restricted to 4000 for sys.varchar and sys.char datatypes */ -/* - * Transaction processing using tsql semantics - */ -extern bool -PLTsqlProcessTransaction(Node *parsetree, - ParamListInfo params, - QueryCompletion *qc) -{ - char *txnName = NULL; - TransactionStmt *stmt = (TransactionStmt *) parsetree; - - if (params != NULL && params->numParams > 0 && !params->params[0].isnull) - { - Oid typOutput; - bool typIsVarlena; - FmgrInfo finfo; - - Assert(params->numParams == 1); - getTypeOutputInfo(params->params[0].ptype, &typOutput, &typIsVarlena); - fmgr_info(typOutput, &finfo); - txnName = OutputFunctionCall(&finfo, params->params[0].value); - } - else - txnName = stmt->savepoint_name; - - if (txnName != NULL && strlen(txnName) > TSQL_TXN_NAME_LIMIT / 2) - ereport(ERROR, - (errcode(ERRCODE_NAME_TOO_LONG), - errmsg("Transaction name length %zu above limit %u", - strlen(txnName), TSQL_TXN_NAME_LIMIT / 2))); - - if (AbortCurTransaction) - { - if (stmt->kind == TRANS_STMT_BEGIN || - stmt->kind == TRANS_STMT_COMMIT || - stmt->kind == TRANS_STMT_SAVEPOINT) - ereport(ERROR, - (errcode(ERRCODE_TRANSACTION_ROLLBACK), - errmsg("The current transaction cannot be committed and cannot support operations that write to the log file. Roll back the transaction."))); - } - - switch (stmt->kind) - { - case TRANS_STMT_BEGIN: - { - PLTsqlStartTransaction(txnName); - } - break; - - case TRANS_STMT_COMMIT: - { - if (exec_state_call_stack && - exec_state_call_stack->estate && - exec_state_call_stack->estate->insert_exec && - NestedTranCount <= 1) - ereport(ERROR, - (errcode(ERRCODE_TRANSACTION_ROLLBACK), - errmsg("Cannot use the COMMIT statement within an INSERT-EXEC statement unless BEGIN TRANSACTION is used first."))); - - PLTsqlCommitTransaction(qc, stmt->chain); - } - break; - - case TRANS_STMT_ROLLBACK: - { - if (exec_state_call_stack && - exec_state_call_stack->estate && - exec_state_call_stack->estate->insert_exec) - ereport(ERROR, - (errcode(ERRCODE_TRANSACTION_ROLLBACK), - errmsg("Cannot use the ROLLBACK statement within an INSERT-EXEC statement."))); - - /* - * Table variables should be immune to ROLLBACK, but we - * haven't implemented this yet so we throw an error if - * ROLLBACK is used with table variables. - */ - if (exec_state_call_stack && - exec_state_call_stack->estate && - exec_state_call_stack->estate->func && - list_length(exec_state_call_stack->estate->func->table_varnos) > 0) - ereport(ERROR, - (errcode(ERRCODE_FEATURE_NOT_SUPPORTED), - errmsg("ROLLBACK statement with active table variables is not yet supported."))); - PLTsqlRollbackTransaction(txnName, qc, stmt->chain); - } - break; - - case TRANS_STMT_SAVEPOINT: - RequireTransactionBlock(true, "SAVEPOINT"); - DefineSavepoint(txnName); - break; - - default: - ereport(ERROR, - (errcode(ERRCODE_INVALID_TRANSACTION_INITIATION), - errmsg("Unsupported transaction command : %d", stmt->kind))); - break; - } - return true; -} - bool pltsql_createFunction(ParseState *pstate, PlannedStmt *pstmt, const char *queryString, ProcessUtilityContext context, ParamListInfo params) From 16aee8bbf724c7149215b713147072bf180cfbf5 Mon Sep 17 00:00:00 2001 From: Kritika Date: Tue, 2 May 2023 10:00:46 +0000 Subject: [PATCH 35/43] Create proc/func/database etc not visible in pg_stat_statements view Subsequent processutility hooks after bbf_processutilty are not being called. Created a hook for that and called it inside relevant ProcessUtility function. Signed-off-by: Kritika --- contrib/babelfishpg_tsql/src/pl_handler.c | 13 ------------- 1 file changed, 13 deletions(-) diff --git a/contrib/babelfishpg_tsql/src/pl_handler.c b/contrib/babelfishpg_tsql/src/pl_handler.c index 41ffaaa55d..1095e1ecc5 100644 --- a/contrib/babelfishpg_tsql/src/pl_handler.c +++ b/contrib/babelfishpg_tsql/src/pl_handler.c @@ -1953,19 +1953,6 @@ PLTsqlProcessTransaction(Node *parsetree, ereport(ERROR, (errcode(ERRCODE_TRANSACTION_ROLLBACK), errmsg("Cannot use the ROLLBACK statement within an INSERT-EXEC statement."))); - - /* - * Table variables should be immune to ROLLBACK, but we - * haven't implemented this yet so we throw an error if - * ROLLBACK is used with table variables. - */ - if (exec_state_call_stack && - exec_state_call_stack->estate && - exec_state_call_stack->estate->func && - list_length(exec_state_call_stack->estate->func->table_varnos) > 0) - ereport(ERROR, - (errcode(ERRCODE_FEATURE_NOT_SUPPORTED), - errmsg("ROLLBACK statement with active table variables is not yet supported."))); PLTsqlRollbackTransaction(txnName, qc, stmt->chain); } break; From a8419eb03ea3025834fae7564d5a4bf466aeac5a Mon Sep 17 00:00:00 2001 From: Kritika Date: Wed, 3 May 2023 05:57:54 +0000 Subject: [PATCH 36/43] Create proc/func/database etc not visible in pg_stat_statements view Subsequent processutility hooks after bbf_processutilty are not being called. Created a hook for that and called it inside relevant ProcessUtility function. Signed-off-by: Kritika --- contrib/babelfishpg_tsql/src/pl_handler.c | 88 --------------------- contrib/babelfishpg_tsql/src/pltsql_utils.c | 88 +++++++++++++++++++++ 2 files changed, 88 insertions(+), 88 deletions(-) diff --git a/contrib/babelfishpg_tsql/src/pl_handler.c b/contrib/babelfishpg_tsql/src/pl_handler.c index 1095e1ecc5..25f588771c 100644 --- a/contrib/babelfishpg_tsql/src/pl_handler.c +++ b/contrib/babelfishpg_tsql/src/pl_handler.c @@ -1882,94 +1882,6 @@ bbf_table_var_lookup(const char *relname, Oid relnamespace) return relid; } -/* - * Transaction processing using tsql semantics - */ -extern void -PLTsqlProcessTransaction(Node *parsetree, - ParamListInfo params, - QueryCompletion *qc) -{ - char *txnName = NULL; - TransactionStmt *stmt = (TransactionStmt *) parsetree; - - if (params != NULL && params->numParams > 0 && !params->params[0].isnull) - { - Oid typOutput; - bool typIsVarlena; - FmgrInfo finfo; - - Assert(params->numParams == 1); - getTypeOutputInfo(params->params[0].ptype, &typOutput, &typIsVarlena); - fmgr_info(typOutput, &finfo); - txnName = OutputFunctionCall(&finfo, params->params[0].value); - } - else - txnName = stmt->savepoint_name; - - if (txnName != NULL && strlen(txnName) > TSQL_TXN_NAME_LIMIT / 2) - ereport(ERROR, - (errcode(ERRCODE_NAME_TOO_LONG), - errmsg("Transaction name length %zu above limit %u", - strlen(txnName), TSQL_TXN_NAME_LIMIT / 2))); - - if (AbortCurTransaction) - { - if (stmt->kind == TRANS_STMT_BEGIN || - stmt->kind == TRANS_STMT_COMMIT || - stmt->kind == TRANS_STMT_SAVEPOINT) - ereport(ERROR, - (errcode(ERRCODE_TRANSACTION_ROLLBACK), - errmsg("The current transaction cannot be committed and cannot support operations that write to the log file. Roll back the transaction."))); - } - - switch (stmt->kind) - { - case TRANS_STMT_BEGIN: - { - PLTsqlStartTransaction(txnName); - } - break; - - case TRANS_STMT_COMMIT: - { - if (exec_state_call_stack && - exec_state_call_stack->estate && - exec_state_call_stack->estate->insert_exec && - NestedTranCount <= 1) - ereport(ERROR, - (errcode(ERRCODE_TRANSACTION_ROLLBACK), - errmsg("Cannot use the COMMIT statement within an INSERT-EXEC statement unless BEGIN TRANSACTION is used first."))); - - PLTsqlCommitTransaction(qc, stmt->chain); - } - break; - - case TRANS_STMT_ROLLBACK: - { - if (exec_state_call_stack && - exec_state_call_stack->estate && - exec_state_call_stack->estate->insert_exec) - ereport(ERROR, - (errcode(ERRCODE_TRANSACTION_ROLLBACK), - errmsg("Cannot use the ROLLBACK statement within an INSERT-EXEC statement."))); - PLTsqlRollbackTransaction(txnName, qc, stmt->chain); - } - break; - - case TRANS_STMT_SAVEPOINT: - RequireTransactionBlock(true, "SAVEPOINT"); - DefineSavepoint(txnName); - break; - - default: - ereport(ERROR, - (errcode(ERRCODE_INVALID_TRANSACTION_INITIATION), - errmsg("Unsupported transaction command : %d", stmt->kind))); - break; - } -} - /* * It returns TRUE when we should not execute the utility statement, * e.g., CREATE FUNCTION, in EXPLAIN ONLY MODE. diff --git a/contrib/babelfishpg_tsql/src/pltsql_utils.c b/contrib/babelfishpg_tsql/src/pltsql_utils.c index 038c5d3a98..7a0f98fed6 100644 --- a/contrib/babelfishpg_tsql/src/pltsql_utils.c +++ b/contrib/babelfishpg_tsql/src/pltsql_utils.c @@ -75,6 +75,94 @@ const uint64 PLTSQL_LOCKTAG_OFFSET = 0xABCDEF; * Also, length should be restricted to 8000 for sys.varchar and sys.char datatypes. * And length should be restricted to 4000 for sys.varchar and sys.char datatypes */ +/* + * Transaction processing using tsql semantics + */ +extern void +PLTsqlProcessTransaction(Node *parsetree, + ParamListInfo params, + QueryCompletion *qc) +{ + char *txnName = NULL; + TransactionStmt *stmt = (TransactionStmt *) parsetree; + + if (params != NULL && params->numParams > 0 && !params->params[0].isnull) + { + Oid typOutput; + bool typIsVarlena; + FmgrInfo finfo; + + Assert(params->numParams == 1); + getTypeOutputInfo(params->params[0].ptype, &typOutput, &typIsVarlena); + fmgr_info(typOutput, &finfo); + txnName = OutputFunctionCall(&finfo, params->params[0].value); + } + else + txnName = stmt->savepoint_name; + + if (txnName != NULL && strlen(txnName) > TSQL_TXN_NAME_LIMIT / 2) + ereport(ERROR, + (errcode(ERRCODE_NAME_TOO_LONG), + errmsg("Transaction name length %zu above limit %u", + strlen(txnName), TSQL_TXN_NAME_LIMIT / 2))); + + if (AbortCurTransaction) + { + if (stmt->kind == TRANS_STMT_BEGIN || + stmt->kind == TRANS_STMT_COMMIT || + stmt->kind == TRANS_STMT_SAVEPOINT) + ereport(ERROR, + (errcode(ERRCODE_TRANSACTION_ROLLBACK), + errmsg("The current transaction cannot be committed and cannot support operations that write to the log file. Roll back the transaction."))); + } + + switch (stmt->kind) + { + case TRANS_STMT_BEGIN: + { + PLTsqlStartTransaction(txnName); + } + break; + + case TRANS_STMT_COMMIT: + { + if (exec_state_call_stack && + exec_state_call_stack->estate && + exec_state_call_stack->estate->insert_exec && + NestedTranCount <= 1) + ereport(ERROR, + (errcode(ERRCODE_TRANSACTION_ROLLBACK), + errmsg("Cannot use the COMMIT statement within an INSERT-EXEC statement unless BEGIN TRANSACTION is used first."))); + + PLTsqlCommitTransaction(qc, stmt->chain); + } + break; + + case TRANS_STMT_ROLLBACK: + { + if (exec_state_call_stack && + exec_state_call_stack->estate && + exec_state_call_stack->estate->insert_exec) + ereport(ERROR, + (errcode(ERRCODE_TRANSACTION_ROLLBACK), + errmsg("Cannot use the ROLLBACK statement within an INSERT-EXEC statement."))); + PLTsqlRollbackTransaction(txnName, qc, stmt->chain); + } + break; + + case TRANS_STMT_SAVEPOINT: + RequireTransactionBlock(true, "SAVEPOINT"); + DefineSavepoint(txnName); + break; + + default: + ereport(ERROR, + (errcode(ERRCODE_INVALID_TRANSACTION_INITIATION), + errmsg("Unsupported transaction command : %d", stmt->kind))); + break; + } +} + bool pltsql_createFunction(ParseState *pstate, PlannedStmt *pstmt, const char *queryString, ProcessUtilityContext context, From 48e8d0ecc3812b0a9bec67ae89847e398b639f6a Mon Sep 17 00:00:00 2001 From: Kritika Date: Wed, 3 May 2023 08:22:12 +0000 Subject: [PATCH 37/43] Create proc/func/database etc not visible in pg_stat_statements view Subsequent processutility hooks after bbf_processutilty are not being called. Created a hook for that and called it inside relevant ProcessUtility function. Signed-off-by: Kritika --- contrib/babelfishpg_tsql/src/pltsql_utils.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/contrib/babelfishpg_tsql/src/pltsql_utils.c b/contrib/babelfishpg_tsql/src/pltsql_utils.c index 7a0f98fed6..4f2a83685b 100644 --- a/contrib/babelfishpg_tsql/src/pltsql_utils.c +++ b/contrib/babelfishpg_tsql/src/pltsql_utils.c @@ -78,7 +78,7 @@ const uint64 PLTSQL_LOCKTAG_OFFSET = 0xABCDEF; /* * Transaction processing using tsql semantics */ -extern void +void PLTsqlProcessTransaction(Node *parsetree, ParamListInfo params, QueryCompletion *qc) From 58f21493d7543b5191fb1aa0f86cd1d68524a913 Mon Sep 17 00:00:00 2001 From: Kritika Date: Wed, 3 May 2023 08:26:47 +0000 Subject: [PATCH 38/43] Create proc/func/database etc not visible in pg_stat_statements view Subsequent processutility hooks after bbf_processutilty are not being called. Created a hook for that and called it inside relevant ProcessUtility function. Signed-off-by: Kritika --- contrib/babelfishpg_tsql/src/hooks.h | 1 - 1 file changed, 1 deletion(-) diff --git a/contrib/babelfishpg_tsql/src/hooks.h b/contrib/babelfishpg_tsql/src/hooks.h index b17629aacc..0cc74c9c1f 100644 --- a/contrib/babelfishpg_tsql/src/hooks.h +++ b/contrib/babelfishpg_tsql/src/hooks.h @@ -24,5 +24,4 @@ extern Oid get_tsql_trigger_oid(List *object, extern char *update_delete_target_alias; extern bool sp_describe_first_result_set_inprogress; - #endif From e10624504f098f3f9df7c5383281930871266492 Mon Sep 17 00:00:00 2001 From: Kritika Date: Thu, 4 May 2023 10:43:17 +0000 Subject: [PATCH 39/43] retrigger tests From e6b5eb0761dc8fd12d59c68cad61ee7b030736e4 Mon Sep 17 00:00:00 2001 From: Kritika Date: Mon, 8 May 2023 06:02:40 +0000 Subject: [PATCH 40/43] Create proc/func/database etc not visible in pg_stat_statements view Subsequent processutility hooks after bbf_processutilty are not being called. Created a hook for that and called it inside relevant ProcessUtility function. Signed-off-by: Kritika --- contrib/babelfishpg_tsql/src/pltsql.h | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/contrib/babelfishpg_tsql/src/pltsql.h b/contrib/babelfishpg_tsql/src/pltsql.h index c77e4ab24c..084b310182 100644 --- a/contrib/babelfishpg_tsql/src/pltsql.h +++ b/contrib/babelfishpg_tsql/src/pltsql.h @@ -1976,6 +1976,10 @@ extern void pltsql_read_procedure_info(StringInfo inout_str, Oid *atttypid, Oid *atttypmod, int *attcollation); +void PLTsqlProcessTransaction(Node *parsetree, + ParamListInfo params, + QueryCompletion *qc); + extern void PLTsqlStartTransaction(char *txnName); extern void PLTsqlCommitTransaction(QueryCompletion *qc, bool chain); From eb288a93b99bf30c398c622e7c54af751edf18e5 Mon Sep 17 00:00:00 2001 From: Kritika Date: Tue, 16 May 2023 08:18:30 +0000 Subject: [PATCH 41/43] retrigger tests From b519ad7d8d2990c6e0154516ee77e1f1c27423d5 Mon Sep 17 00:00:00 2001 From: Kritika Date: Mon, 29 May 2023 06:13:48 +0000 Subject: [PATCH 42/43] Create proc/func/database etc not visible in pg_stat_statements view Subsequent processutility hooks after bbf_processutilty are not being called. Created a hook for that and called it inside relevant ProcessUtility function. Signed-off-by: Kritika --- contrib/babelfishpg_tsql/src/pltsql_utils.c | 33 ++++++++++----------- 1 file changed, 16 insertions(+), 17 deletions(-) diff --git a/contrib/babelfishpg_tsql/src/pltsql_utils.c b/contrib/babelfishpg_tsql/src/pltsql_utils.c index 413c0a655b..ba4f6b2a35 100644 --- a/contrib/babelfishpg_tsql/src/pltsql_utils.c +++ b/contrib/babelfishpg_tsql/src/pltsql_utils.c @@ -59,23 +59,6 @@ const uint64 PLTSQL_LOCKTAG_OFFSET = 0xABCDEF; (uint32) ((((int64) key16) + PLTSQL_LOCKTAG_OFFSET) >> 32), \ (uint32) (((int64) key16) + PLTSQL_LOCKTAG_OFFSET), \ 3) - -/* - * Setup default typmod for sys types/domains when typmod isn't specified - * (that is, typmod = -1). - * We only care to do this in TSQL dialect, this means sys.varchar - * defaults to sys.varchar(1) only in TSQL dialect. - * - * is_cast indicates if it's a CAST/CONVERT statement, if it's true the default - * length of string and binary type will be set to 30. - * - * If typmod is TSQLMaxTypmod (-8000), it means MAX is used in the - * length field of VARCHAR, NVARCHAR or VARBINARY. Set typmod to -1, - * by default -1 the engine will treat it as unlimited length. - * - * Also, length should be restricted to 8000 for sys.varchar and sys.char datatypes. - * And length should be restricted to 4000 for sys.varchar and sys.char datatypes - */ /* * Transaction processing using tsql semantics */ @@ -352,6 +335,22 @@ pltsql_createFunction(ParseState *pstate, PlannedStmt *pstmt, const char *queryS } } +/* + * Setup default typmod for sys types/domains when typmod isn't specified + * (that is, typmod = -1). + * We only care to do this in TSQL dialect, this means sys.varchar + * defaults to sys.varchar(1) only in TSQL dialect. + * + * is_cast indicates if it's a CAST/CONVERT statement, if it's true the default + * length of string and binary type will be set to 30. + * + * If typmod is TSQLMaxTypmod (-8000), it means MAX is used in the + * length field of VARCHAR, NVARCHAR or VARBINARY. Set typmod to -1, + * by default -1 the engine will treat it as unlimited length. + * + * Also, length should be restricted to 8000 for sys.varchar and sys.char datatypes. + * And length should be restricted to 4000 for sys.varchar and sys.char datatypes + */ void pltsql_check_or_set_default_typmod(TypeName *typeName, int32 *typmod, bool is_cast) { From a9b5facc52d19d991e55d4d863989286cf938e78 Mon Sep 17 00:00:00 2001 From: Kritika Date: Mon, 12 Jun 2023 07:33:31 +0000 Subject: [PATCH 43/43] Fixed create proc/func/database drop database etc which were not tracked by extensions in BBF Signed-off-by: Kritika --- contrib/babelfishpg_tsql/src/pltsql_utils.c | 28 ++++++++++----------- 1 file changed, 13 insertions(+), 15 deletions(-) diff --git a/contrib/babelfishpg_tsql/src/pltsql_utils.c b/contrib/babelfishpg_tsql/src/pltsql_utils.c index ba4f6b2a35..7a9226d553 100644 --- a/contrib/babelfishpg_tsql/src/pltsql_utils.c +++ b/contrib/babelfishpg_tsql/src/pltsql_utils.c @@ -153,7 +153,7 @@ pltsql_createFunction(ParseState *pstate, PlannedStmt *pstmt, const char *queryS ParamListInfo params) { Node *parsetree = pstmt->utilityStmt; - CreateFunctionStmt *stmt = (CreateFunctionStmt *)parsetree; + CreateFunctionStmt *stmt = (CreateFunctionStmt *)parsetree; ListCell *option, *location_cell = NULL; DefElem *language_item = NULL; char *language = NULL; @@ -168,19 +168,19 @@ pltsql_createFunction(ParseState *pstate, PlannedStmt *pstmt, const char *queryS pstate->p_sourcetext = queryString; foreach(option, stmt->options) - { - DefElem *defel = (DefElem *)lfirst(option); + { + DefElem *defel = (DefElem *)lfirst(option); - if (strcmp(defel->defname, "language") == 0) - { - if (language_item) - ereport(ERROR, - (errcode(ERRCODE_SYNTAX_ERROR), - errmsg("conflicting or redundant options"), - parser_errposition(pstate, defel->location))); - language_item = defel; - } - } + if (strcmp(defel->defname, "language") == 0) + { + if (language_item) + ereport(ERROR, + (errcode(ERRCODE_SYNTAX_ERROR), + errmsg("conflicting or redundant options"), + parser_errposition(pstate, defel->location))); + language_item = defel; + } + } if (language_item) language = strVal(language_item->arg); @@ -189,7 +189,6 @@ pltsql_createFunction(ParseState *pstate, PlannedStmt *pstmt, const char *queryS { return false; } - else { /* All event trigger calls are done only when isCompleteQuery is true */ @@ -198,7 +197,6 @@ pltsql_createFunction(ParseState *pstate, PlannedStmt *pstmt, const char *queryS /* PG_TRY block is to ensure we call EventTriggerEndCompleteQuery */ PG_TRY(); { - if (isCompleteQuery) EventTriggerDDLCommandStart(parsetree);