diff --git a/contrib/babelfishpg_tds/src/backend/tds/tds.c b/contrib/babelfishpg_tds/src/backend/tds/tds.c index 82f9fd8ef4..52772244a0 100644 --- a/contrib/babelfishpg_tds/src/backend/tds/tds.c +++ b/contrib/babelfishpg_tds/src/backend/tds/tds.c @@ -594,6 +594,21 @@ tdsstat_fetch_stat_local_tdsentry(int beid) return localentry; } +/* ---------- + * tdsstat_fetch_stat_numbackends() - + * + * Support function for the SQL-callable pgstat* functions. Returns + * the number of sessions known in the localTdsStatusTable, i.e. + * the maximum 1-based index to pass to tdsstat_fetch_stat_local_tdsentry(). + * ---------- + */ +int +tdsstat_fetch_stat_numbackends(void) +{ + tdsstat_read_current_status(); + return localNumBackends; +} + /* ---------- * tdsstat_read_current_status() - * @@ -735,14 +750,16 @@ tdsstat_read_current_status(void) /* Only valid entries get included into the local array */ if (localentry->tdsStatus.st_procpid > 0) + { BackendIdGetTransactionIds(i, &localentry->backend_xid, &localentry->backend_xmin, &localentry->backend_subxact_count, &localentry->backend_subxact_overflowed); - localentry++; - localNumBackends++; + localentry++; + localNumBackends++; + } } localTdsStatusTable = localtable; diff --git a/contrib/babelfishpg_tds/src/backend/tds/tds_srv.c b/contrib/babelfishpg_tds/src/backend/tds/tds_srv.c index 63ce388c47..9a80d6a3a6 100644 --- a/contrib/babelfishpg_tds/src/backend/tds/tds_srv.c +++ b/contrib/babelfishpg_tds/src/backend/tds/tds_srv.c @@ -196,6 +196,7 @@ pe_tds_init(void) pltsql_plugin_handler_ptr->get_tds_database_backend_count = &get_tds_database_backend_count; pltsql_plugin_handler_ptr->get_stat_values = &tds_stat_get_activity; pltsql_plugin_handler_ptr->invalidate_stat_view = &invalidate_stat_table; + pltsql_plugin_handler_ptr->get_tds_numbackends = &tdsstat_fetch_stat_numbackends; pltsql_plugin_handler_ptr->get_host_name = &get_tds_host_name; pltsql_plugin_handler_ptr->get_client_pid = &get_tds_client_pid; pltsql_plugin_handler_ptr->get_context_info = &get_tds_context_info; diff --git a/contrib/babelfishpg_tds/src/include/tds_int.h b/contrib/babelfishpg_tds/src/include/tds_int.h index 4c5ec4d111..0b12085292 100644 --- a/contrib/babelfishpg_tds/src/include/tds_int.h +++ b/contrib/babelfishpg_tds/src/include/tds_int.h @@ -338,6 +338,7 @@ extern void TdsSetAtAtStatVariable(TdsAtAtVarType at_at_var, int intVal, uint64 extern void TdsSetDatabaseStatVariable(int16 db_id); extern bool get_tds_database_backend_count(int16 db_id, bool ignore_current_connection); extern bool tds_stat_get_activity(Datum *values, bool *nulls, int len, int pid, int curr_backend); +extern int tdsstat_fetch_stat_numbackends(void); extern void invalidate_stat_table(void); extern char *get_tds_host_name(void); extern uint32_t get_tds_client_pid(void); diff --git a/contrib/babelfishpg_tsql/runtime/functions.c b/contrib/babelfishpg_tsql/runtime/functions.c index 21f1e825b9..f2a11b63bb 100644 --- a/contrib/babelfishpg_tsql/runtime/functions.c +++ b/contrib/babelfishpg_tsql/runtime/functions.c @@ -1748,7 +1748,7 @@ Datum tsql_stat_get_activity(PG_FUNCTION_ARGS) { Oid sysadmin_oid = get_role_oid("sysadmin", false); - int num_backends = pgstat_fetch_stat_numbackends(); + int num_backends = 0; int curr_backend; char *view_name = text_to_cstring(PG_GETARG_TEXT_PP(0)); int pid = -1; @@ -1834,6 +1834,9 @@ tsql_stat_get_activity(PG_FUNCTION_ARGS) MemoryContextSwitchTo(oldcontext); + if (*pltsql_protocol_plugin_ptr && (*pltsql_protocol_plugin_ptr)->get_tds_numbackends) + num_backends = (*pltsql_protocol_plugin_ptr)->get_tds_numbackends(); + /* 1-based index */ for (curr_backend = 1; curr_backend <= num_backends; curr_backend++) { diff --git a/contrib/babelfishpg_tsql/src/backend_parser/gram-tsql-rule.y b/contrib/babelfishpg_tsql/src/backend_parser/gram-tsql-rule.y index cfdf11893f..684ff08741 100644 --- a/contrib/babelfishpg_tsql/src/backend_parser/gram-tsql-rule.y +++ b/contrib/babelfishpg_tsql/src/backend_parser/gram-tsql-rule.y @@ -4092,6 +4092,70 @@ tsql_AlterFunctionStmt: n->actions = list_concat(list_make3(lang, body, location), $5); // piggy-back on actions to just put the new proc body instead $$ = (Node *) n; } + | TSQL_ALTER FUNCTION func_name tsql_createfunc_args + RETURNS func_return tsql_createfunc_options opt_as tokens_remaining + { + ObjectWithArgs *owa = makeNode(ObjectWithArgs); + AlterFunctionStmt *n = makeNode(AlterFunctionStmt); + DefElem *lang = makeDefElem("language", (Node *) makeString("pltsql"), @1); + DefElem *body = makeDefElem("as", (Node *) list_make1(makeString($9)), @9); + DefElem *location = makeDefElem("location", (Node *) makeInteger(@3), @3); + /* + * Adding a option for volatility with value STABLE. + * Function created from tsql dialect will be created as STABLE + * by default + */ + DefElem *vol = makeDefElem("volatility", (Node *) makeString("stable"), @1); + + /* Remove return defelem from list after extracting in pl_handler*/ + DefElem *ret = makeDefElem("return", (Node *) $6, @6); + + /* Fill in the ObjectWithArgs node */ + owa->objname = $3; + owa->objargs = extractArgTypes($4); + owa->objfuncargs = $4; + + n->objtype = OBJECT_PROCEDURE; /* Set as proc to avoid psql alter func impl */ + n->func = owa; + n->actions = list_concat(list_make5(lang, body, location, vol, ret), $7); // piggy-back on actions to just put the new proc body instead + $$ = (Node *) n; + } + | TSQL_ALTER FUNCTION func_name tsql_createfunc_args + RETURNS TABLE opt_as tokens_remaining + { + ObjectWithArgs *owa = makeNode(ObjectWithArgs); + AlterFunctionStmt *n = makeNode(AlterFunctionStmt); + DefElem *lang = makeDefElem("language", (Node *) makeString("pltsql"), @1); + DefElem *body = makeDefElem("as", (Node *) list_make1(makeString($8)), @8); + DefElem *location = makeDefElem("location", (Node *) makeInteger(@3), @3); + TypeName *returnType = SystemTypeName("record"); + DefElem *ret; + + /* + * Do not include table parameters here, will be added in + * pltsql_validator() + */ + + owa->objname = $3; + owa->objargs = extractArgTypes($4); + owa->objfuncargs = $4; + + /* + * Use RECORD type here. In case of single result column, + * will be changed to that column's type in + * pltsql_validator() + */ + + returnType = SystemTypeName("record"); + returnType->setof = true; + returnType->location = @6; + ret = makeDefElem("return", (Node *) returnType, @6); + + n->objtype = OBJECT_PROCEDURE; /* Set as proc to avoid psql alter func impl */ + n->func = owa; + n->actions = list_make4(lang, body, location, ret); // piggy-back on actions to just put the new proc body instead + $$ = (Node *)n; + } ; /* diff --git a/contrib/babelfishpg_tsql/src/backend_parser/parser.c b/contrib/babelfishpg_tsql/src/backend_parser/parser.c index 640e8512ed..1e59ea861a 100644 --- a/contrib/babelfishpg_tsql/src/backend_parser/parser.c +++ b/contrib/babelfishpg_tsql/src/backend_parser/parser.c @@ -322,6 +322,7 @@ pgtsql_base_yylex(YYSTYPE *lvalp, YYLTYPE * llocp, core_yyscan_t yyscanner) { case PROCEDURE: case TSQL_PROC: + case FUNCTION: cur_token = TSQL_ALTER; break; } diff --git a/contrib/babelfishpg_tsql/src/guc.c b/contrib/babelfishpg_tsql/src/guc.c index 03bd375536..518e904ab6 100644 --- a/contrib/babelfishpg_tsql/src/guc.c +++ b/contrib/babelfishpg_tsql/src/guc.c @@ -1163,7 +1163,7 @@ define_custom_variables(void) gettext_noop("Temp oid buffer size"), NULL, &temp_oid_buffer_size, - 0, 0, 131072, + 65536, 0, 131072, PGC_SUSET, GUC_NOT_IN_SAMPLE | GUC_DISALLOW_IN_FILE | GUC_DISALLOW_IN_AUTO_FILE, NULL, NULL, NULL); diff --git a/contrib/babelfishpg_tsql/src/hooks.c b/contrib/babelfishpg_tsql/src/hooks.c index 4a5bce7e80..585bc829f2 100644 --- a/contrib/babelfishpg_tsql/src/hooks.c +++ b/contrib/babelfishpg_tsql/src/hooks.c @@ -55,6 +55,8 @@ #include "parser/scansup.h" #include "replication/logical.h" #include "rewrite/rewriteHandler.h" +#include "storage/lock.h" +#include "storage/sinvaladt.h" #include "tcop/utility.h" #include "utils/builtins.h" #include "utils/fmgroids.h" @@ -163,6 +165,8 @@ static void pltsql_GetNewObjectId(VariableCache variableCache); static Oid pltsql_GetNewTempObjectId(void); static Oid pltsql_GetNewTempOidWithIndex(Relation relation, Oid indexId, AttrNumber oidcolumn); static bool set_and_persist_temp_oid_buffer_start(Oid new_oid); +static bool pltsql_is_local_only_inval_msg(const SharedInvalidationMessage *msg); +static EphemeralNamedRelation pltsql_get_tsql_enr_from_oid(Oid oid); static void pltsql_validate_var_datatype_scale(const TypeName *typeName, Type typ); static bool pltsql_bbfCustomProcessUtility(ParseState *pstate, PlannedStmt *pstmt, @@ -240,6 +244,8 @@ static ExecutorEnd_hook_type prev_ExecutorEnd = NULL; static GetNewObjectId_hook_type prev_GetNewObjectId_hook = NULL; static GetNewTempObjectId_hook_type prev_GetNewTempObjectId_hook = NULL; static GetNewTempOidWithIndex_hook_type prev_GetNewTempOidWithIndex_hook = NULL; +static pltsql_is_local_only_inval_msg_hook_type prev_pltsql_is_local_only_inval_msg_hook = NULL; +static pltsql_get_tsql_enr_from_oid_hook_type prev_pltsql_get_tsql_enr_from_oid_hook = NULL; static inherit_view_constraints_from_table_hook_type prev_inherit_view_constraints_from_table = NULL; static bbfViewHasInsteadofTrigger_hook_type prev_bbfViewHasInsteadofTrigger_hook = NULL; static detect_numeric_overflow_hook_type prev_detect_numeric_overflow_hook = NULL; @@ -367,6 +373,12 @@ InstallExtendedHooks(void) prev_GetNewTempOidWithIndex_hook = GetNewTempOidWithIndex_hook; GetNewTempOidWithIndex_hook = pltsql_GetNewTempOidWithIndex; + prev_pltsql_is_local_only_inval_msg_hook = pltsql_is_local_only_inval_msg_hook; + pltsql_is_local_only_inval_msg_hook = pltsql_is_local_only_inval_msg; + + prev_pltsql_get_tsql_enr_from_oid_hook = pltsql_get_tsql_enr_from_oid_hook; + pltsql_get_tsql_enr_from_oid_hook = pltsql_get_tsql_enr_from_oid; + prev_inherit_view_constraints_from_table = inherit_view_constraints_from_table_hook; inherit_view_constraints_from_table_hook = preserve_view_constraints_from_base_table; TriggerRecuresiveCheck_hook = plsql_TriggerRecursiveCheck; @@ -4685,6 +4697,18 @@ static bool set_and_persist_temp_oid_buffer_start(Oid new_oid) return true; } +static bool +pltsql_is_local_only_inval_msg(const SharedInvalidationMessage *msg) +{ + return temp_oid_buffer_size > 0 && (msg->id == SHAREDINVALRELCACHE_ID && msg->rc.local_only); +} + +static EphemeralNamedRelation +pltsql_get_tsql_enr_from_oid(const Oid oid) +{ + return temp_oid_buffer_size > 0 ? get_ENR_withoid(currentQueryEnv, oid, ENR_TSQL_TEMP) : NULL; +} + /* * Modify the Tuple Descriptor to match the expected * result set. Currently used only for T-SQL OPENQUERY. diff --git a/contrib/babelfishpg_tsql/src/pl_handler.c b/contrib/babelfishpg_tsql/src/pl_handler.c index a415998b5d..128a28da38 100644 --- a/contrib/babelfishpg_tsql/src/pl_handler.c +++ b/contrib/babelfishpg_tsql/src/pl_handler.c @@ -139,7 +139,7 @@ static void call_prev_ProcessUtility(PlannedStmt *pstmt, DestReceiver *dest, QueryCompletion *qc); static void set_pgtype_byval(List *name, bool byval); -static void pltsql_proc_get_oid_proname_proacl(AlterFunctionStmt *stmt, ParseState *pstate, Oid *oid, Acl **acl, bool *isSameFunc); +static void pltsql_proc_get_oid_proname_proacl(AlterFunctionStmt *stmt, ParseState *pstate, Oid *oid, Acl **acl, bool *isSameFunc, bool is_proc); static void pg_proc_update_oid_acl(ObjectAddress address, Oid oid, Acl *acl); static void bbf_func_ext_update_proc_definition(Oid oid); static bool pltsql_truncate_identifier(char *ident, int len, bool warn); @@ -2406,13 +2406,13 @@ bbf_ProcessUtility(PlannedStmt *pstmt, { if (sql_dialect == SQL_DIALECT_TSQL) { - /* - * For ALTER PROC, we will: - * 1. Save important pg_proc metadata from the current proc (oid, proacl) - * 2. drop the current proc - * 3. create the new proc - * 4. update the pg_proc entry for the new proc with metadata from the old proc - * 5. update the babelfish_function_ext entry for the existing proc with new metadata based on the new proc + /* + * For ALTER PROC/FUNC, we will: + * 1. Save important pg_proc metadata from the current proc/func (oid, proacl) + * 2. drop the current proc/func + * 3. create the new proc/func + * 4. update the pg_proc entry for the new proc with metadata from the old proc/func + * 5. update the babelfish_function_ext entry for the existing proc/func with new metadata based on the new proc/func */ AlterFunctionStmt *stmt = (AlterFunctionStmt *) parsetree; bool isCompleteQuery = (context != PROCESS_UTILITY_SUBCOMMAND); @@ -2422,9 +2422,12 @@ bbf_ProcessUtility(PlannedStmt *pstmt, bool isSameProc; ObjectAddress address; CreateFunctionStmt *cfs; - ListCell *option, *location_cell = NULL; + ListCell *option, *location_cell = NULL, *return_cell = NULL; int origname_location = -1; bool with_recompile = false; + ListCell *parameter; + + cfs = makeNode(CreateFunctionStmt); if (!IS_TDS_CLIENT()) { @@ -2469,37 +2472,83 @@ bbf_ProcessUtility(PlannedStmt *pstmt, */ with_recompile = true; } + else if (strcmp(defel->defname, "return") == 0) + { + cfs->returnType = (TypeName *) defel->arg; + return_cell = option; + pfree(defel); + stmt->objtype = OBJECT_FUNCTION; + } } /* delete location cell if it exists as it is for internal use only */ if (location_cell) stmt->actions = list_delete_cell(stmt->actions, location_cell); + if (return_cell) + { + if(location_cell) + return_cell -= 1; + stmt->actions = list_delete_cell(stmt->actions, return_cell); + cfs->is_procedure = false; + } else + { + cfs->returnType = NULL; + cfs->is_procedure = true; + } + /* make a CreateFunctionStmt to pass into CreateFunction() */ - cfs = makeNode(CreateFunctionStmt); - cfs->is_procedure = true; cfs->replace = true; cfs->funcname = stmt->func->objname; cfs->parameters = stmt->func->objfuncargs; - cfs->returnType = NULL; cfs->options = stmt->actions; - pltsql_proc_get_oid_proname_proacl(stmt, pstate, &oldoid, &proacl, &isSameProc); - if (!isSameProc) /* i.e. different signature */ + foreach(parameter, cfs->parameters) + { + FunctionParameter* fp = (FunctionParameter*) lfirst(parameter); + if(fp->mode == FUNC_PARAM_TABLE) + { + fp->argType->setof = false; + } + } + + pltsql_proc_get_oid_proname_proacl(stmt, pstate, &oldoid, &proacl, &isSameProc, cfs->is_procedure); + if(get_bbf_function_tuple_from_proctuple(SearchSysCache1(PROCOID, ObjectIdGetDatum(oldoid))) == NULL) + { + /* Detect PSQL functions and throw error */ + ereport(ERROR, + (errcode(ERRCODE_INVALID_FUNCTION_DEFINITION), + errmsg("No existing TSQL procedure found with the name for ALTER PROCEDURE"))); + } + if(!cfs->is_procedure) + { + /* + * Postgres does not allow us to create functions with different return types + * so we need to delete and recreate them + */ RemoveFunctionById(oldoid); - address = CreateFunction(pstate, cfs); /* if this is the same proc, will just update the existing one */ - pg_proc_update_oid_acl(address, oldoid, proacl); + isSameProc = false; + CommandCounterIncrement(); + } + else if (!isSameProc) /* i.e. different signature */ + { + RemoveFunctionById(oldoid); + } + + /* if this is the same procedure, it will update the existing one */ + address = CreateFunction(pstate, cfs); /* Update function/procedure related metadata in babelfish catalog */ pltsql_store_func_default_positions(address, cfs->parameters, queryString, origname_location, with_recompile); - /* Increase counter after bbf_func_ext modified in pltsql_store_func_default_positions*/ + /* Increase counter after bbf_func_ext modified in pltsql_store_func_default_positions*/ CommandCounterIncrement(); - bbf_func_ext_update_proc_definition(oldoid); + bbf_func_ext_update_proc_definition(address.objectId); + pg_proc_update_oid_acl(address, oldoid, proacl); if (!isSameProc) { /* * When the signatures differ we need to manually update the 'function_args' column in * the 'bbf_schema_permissions' catalog */ - alter_bbf_schema_permissions_catalog(stmt->func, cfs->parameters, OBJECT_PROCEDURE, oldoid); + alter_bbf_schema_permissions_catalog(stmt->func, cfs->parameters, stmt->objtype, oldoid); } /* Clean up table entries for the create function statement */ deleteDependencyRecordsFor(DefaultAclRelationId, address.objectId, false); @@ -2652,6 +2701,8 @@ bbf_ProcessUtility(PlannedStmt *pstmt, if (from_windows && orig_loginname) { + char* domain_name = NULL; + /* * The login name must contain '\' if it is * windows login or else throw error. @@ -2691,6 +2742,16 @@ bbf_ProcessUtility(PlannedStmt *pstmt, ereport(ERROR, (errcode(ERRCODE_INVALID_PARAMETER_VALUE), errmsg("'%s' is not a valid name because it contains invalid characters.", orig_loginname))); + /* + * Check whether the domain name is supported + * or not + */ + domain_name = get_windows_domain_name(orig_loginname); + if(windows_domain_is_not_supported(domain_name)) + ereport(ERROR, + (errcode(ERRCODE_FEATURE_NOT_SUPPORTED), + errmsg("'%s' domain is not yet supported in Babelfish.", domain_name))); + /* * Check whether the domain name contains invalid characters or not. */ @@ -4206,12 +4267,13 @@ call_prev_ProcessUtility(PlannedStmt *pstmt, * the found proc is the exact same proc as requested (i.e. the parameters match). */ static void -pltsql_proc_get_oid_proname_proacl(AlterFunctionStmt *stmt, ParseState *pstate, Oid *oid, Acl **acl, bool *isSameFunc) +pltsql_proc_get_oid_proname_proacl(AlterFunctionStmt *stmt, ParseState *pstate, Oid *oid, Acl **acl, bool *isSameFunc, bool is_proc) { int spi_rc; char *funcname, *query; bool isnull; Oid schemaOid, funcOid; + Datum aclDatum; MemoryContext oldMemoryContext = CurrentMemoryContext; @@ -4238,7 +4300,11 @@ pltsql_proc_get_oid_proname_proacl(AlterFunctionStmt *stmt, ParseState *pstate, *oid = DatumGetObjectId(SPI_getbinval(SPI_tuptable->vals[0], SPI_tuptable->tupdesc, 1, &isnull)); MemoryContextSwitchTo(oldMemoryContext); - *acl = aclcopy(DatumGetAclP(SPI_getbinval(SPI_tuptable->vals[0], SPI_tuptable->tupdesc, 2, &isnull))); + aclDatum = SPI_getbinval(SPI_tuptable->vals[0], SPI_tuptable->tupdesc, 2, &isnull); + if(DatumGetPointer(aclDatum) == NULL) + *acl = NULL; + else + *acl = aclcopy(DatumGetAclP(aclDatum)); if ((spi_rc = SPI_finish()) != SPI_OK_FINISH) elog(ERROR, "SPI_finish() failed in pltsql_proc_get_oid_proname_proacl with return code %d", spi_rc); @@ -4294,7 +4360,10 @@ pg_proc_update_oid_acl(ObjectAddress address, Oid oid, Acl *acl) memset(replaces, 0, sizeof(replaces)); values[Anum_pg_proc_oid - 1] = ObjectIdGetDatum(oid); replaces[Anum_pg_proc_oid - 1] = true; - values[Anum_pg_proc_proacl - 1] = PointerGetDatum(acl); + if(acl) + values[Anum_pg_proc_proacl - 1] = PointerGetDatum(acl); + else + nulls[Anum_pg_proc_proacl - 1] = true; replaces[Anum_pg_proc_proacl - 1] = true; newtup = heap_modify_tuple(proctup, RelationGetDescr(rel), values, nulls, replaces); @@ -4302,6 +4371,7 @@ pg_proc_update_oid_acl(ObjectAddress address, Oid oid, Acl *acl) /* Clean up */ ReleaseSysCache(proctup); + heap_freetuple(newtup); table_close(rel, RowExclusiveLock); } diff --git a/contrib/babelfishpg_tsql/src/pltsql.h b/contrib/babelfishpg_tsql/src/pltsql.h index 7c4cbe1113..ce6bccfbc5 100644 --- a/contrib/babelfishpg_tsql/src/pltsql.h +++ b/contrib/babelfishpg_tsql/src/pltsql.h @@ -1693,6 +1693,7 @@ typedef struct PLtsql_protocol_plugin bool (*get_tds_database_backend_count) (int16 db_id, bool ignore_current_connection); bool (*get_stat_values) (Datum *values, bool *nulls, int len, int pid, int curr_backend); void (*invalidate_stat_view) (void); + int (*get_tds_numbackends) (void); char *(*get_host_name) (void); uint32_t (*get_client_pid) (void); Datum (*get_datum_from_byte_ptr) (StringInfo buf, int datatype, int scale); diff --git a/contrib/babelfishpg_tsql/src/rolecmds.c b/contrib/babelfishpg_tsql/src/rolecmds.c index 8f5e9d7067..6e97cc827e 100644 --- a/contrib/babelfishpg_tsql/src/rolecmds.c +++ b/contrib/babelfishpg_tsql/src/rolecmds.c @@ -2485,6 +2485,31 @@ windows_login_contains_invalid_chars(char *input) return false; } +/* + * Extract the domain name from the orig_loginname + */ +char* +get_windows_domain_name(char* input){ + char *pos_slash = strchr(input, '\\'); + int domain_len = pos_slash - input; + char *domain_name = palloc(domain_len+1); + strncpy(domain_name, input, domain_len); + domain_name[domain_len] = '\0'; + return domain_name; +} + +/* + * Check whether the domain name is supported or not + */ +bool +windows_domain_is_not_supported(char* domain_name) +{ + if(strcasecmp(domain_name, "nt service") == 0) { + return true; + } + return false; +} + /** * Domain name checks, doesnot allow characters like "<>&*|quotes spaces" * */ diff --git a/contrib/babelfishpg_tsql/src/rolecmds.h b/contrib/babelfishpg_tsql/src/rolecmds.h index 84a67b82a6..bfb147168c 100644 --- a/contrib/babelfishpg_tsql/src/rolecmds.h +++ b/contrib/babelfishpg_tsql/src/rolecmds.h @@ -81,6 +81,8 @@ extern char *convertToUPN(char *input); extern bool windows_login_contains_invalid_chars(char *input); extern bool windows_domain_contains_invalid_chars(char *input); extern bool check_windows_logon_length(char *input); +extern char* get_windows_domain_name(char* input); +extern bool windows_domain_is_not_supported(char* domain_name); extern void grant_dbo_to_login(const char* login, const char* db_name); extern void revoke_dbo_from_login(const char* login, const char* db_name); diff --git a/contrib/babelfishpg_tsql/src/tsqlUnsupportedFeatureHandler.cpp b/contrib/babelfishpg_tsql/src/tsqlUnsupportedFeatureHandler.cpp index f5be400969..fb8e5c5668 100644 --- a/contrib/babelfishpg_tsql/src/tsqlUnsupportedFeatureHandler.cpp +++ b/contrib/babelfishpg_tsql/src/tsqlUnsupportedFeatureHandler.cpp @@ -292,8 +292,8 @@ antlrcpp::Any TsqlUnsupportedFeatureHandlerImpl::visitKill_statement(TSqlParser: antlrcpp::Any TsqlUnsupportedFeatureHandlerImpl::visitCreate_or_alter_function(TSqlParser::Create_or_alter_functionContext *ctx) { - if (ctx->ALTER()) - handle(INSTR_UNSUPPORTED_TSQL_ALTER_FUNCTION, "ALTER FUNCTION", getLineAndPos(ctx->ALTER())); + if (ctx->ALTER() && ctx->func_body_returns_table()) + handle(INSTR_UNSUPPORTED_TSQL_ALTER_FUNCTION, "ALTER FUNCTION on multi-statement table valued functions", getLineAndPos(ctx->ALTER())); std::vector options; if (ctx->func_body_returns_select()) diff --git a/test/JDBC/expected/BABEL-UNSUPPORTED.out b/test/JDBC/expected/BABEL-UNSUPPORTED.out index b4572aace0..46b9b9d7b8 100644 --- a/test/JDBC/expected/BABEL-UNSUPPORTED.out +++ b/test/JDBC/expected/BABEL-UNSUPPORTED.out @@ -2992,3 +2992,117 @@ GO ~~ERROR (Message: 'EXTERNAL NAME' is not currently supported in Babelfish)~~ +-- create login from windows +-- Add 'dummydomain' domain entry +exec sys.babelfish_add_domain_mapping_entry 'dummydomain', 'dummydomain.babel'; +GO + +CREATE LOGIN [NT Service\MSSQLSERVER] FROM WINDOWS +GO +~~ERROR (Code: 33557097)~~ + +~~ERROR (Message: 'NT Service' domain is not yet supported in Babelfish.)~~ + + +CREATE LOGIN [\MSSQLSERVER] FROM WINDOWS +GO +~~ERROR (Code: 33557097)~~ + +~~ERROR (Message: The login name '\MSSQLSERVER' is invalid. The domain can not be empty.)~~ + + +CREATE LOGIN [NT Servicesomething\MSSQLSERVER] FROM WINDOWS +GO +~~ERROR (Code: 33557097)~~ + +~~ERROR (Message: 'NT Servicesomething\MSSQLSERVER' is not valid because the domain name contains invalid characters.)~~ + + +CREATE LOGIN [NT ServiceNT Service\MSSQLSERVER] FROM WINDOWS +GO +~~ERROR (Code: 33557097)~~ + +~~ERROR (Message: 'NT ServiceNT Service\MSSQLSERVER' is not valid because the domain name contains invalid characters.)~~ + + +CREATE LOGIN [NT ServiceNT SerViCe\MSSQLSERVER] FROM WINDOWS +GO +~~ERROR (Code: 33557097)~~ + +~~ERROR (Message: 'NT ServiceNT SerViCe\MSSQLSERVER' is not valid because the domain name contains invalid characters.)~~ + + +CREATE LOGIN [somethingNT Service\MSSQLSERVER] FROM WINDOWS +GO +~~ERROR (Code: 33557097)~~ + +~~ERROR (Message: 'somethingNT Service\MSSQLSERVER' is not valid because the domain name contains invalid characters.)~~ + + +CREATE LOGIN [NT Service\NT Service\MSSQLSERVER] FROM WINDOWS +GO +~~ERROR (Code: 33557097)~~ + +~~ERROR (Message: The login name 'NT Service\NT Service\MSSQLSERVER' has invalid length. Login name length should be between 1 and 20 for windows login.)~~ + + +CREATE LOGIN [NT S\ervice\MSSQLSERVER] FROM WINDOWS +GO +~~ERROR (Code: 33557097)~~ + +~~ERROR (Message: 'NT S\ervice\MSSQLSERVER' is not a valid name because it contains invalid characters.)~~ + + +CREATE LOGIN [NT Service\\MSSQLSERVER] FROM WINDOWS +GO +~~ERROR (Code: 33557097)~~ + +~~ERROR (Message: 'NT Service\\MSSQLSERVER' is not a valid name because it contains invalid characters.)~~ + + +CREATE LOGIN ["NT Service"\MSSQLSERVER] FROM WINDOWS +GO +~~ERROR (Code: 33557097)~~ + +~~ERROR (Message: '"NT Service"\MSSQLSERVER' is not valid because the domain name contains invalid characters.)~~ + + +CREATE LOGIN [[NT Service]\MSSQLSERVER] FROM WINDOWS +GO +~~ERROR (Code: 33557097)~~ + +~~ERROR (Message: syntax error near '\' at line 1 and character position 26)~~ + + +CREATE LOGIN [["NT Service"]\MSSQLSERVER] FROM WINDOWS +GO +~~ERROR (Code: 33557097)~~ + +~~ERROR (Message: syntax error near '\' at line 1 and character position 28)~~ + + +CREATE LOGIN [NT Service\MSSQLSERVER] FROM WINDOWS WITH DEFAULT_DATABASE=[test] +GO +~~ERROR (Code: 33557097)~~ + +~~ERROR (Message: 'NT Service' domain is not yet supported in Babelfish.)~~ + + +CREATE LOGIN [NT SerViCe\MSSQLSERVER] FROM WINDOWS WITH DEFAULT_DATABASE=[test] +GO +~~ERROR (Code: 33557097)~~ + +~~ERROR (Message: 'NT SerViCe' domain is not yet supported in Babelfish.)~~ + + +CREATE LOGIN [dummydomain\NT Service] FROM WINDOWS +GO + +-- Dropping 'nt service@DUMMYDOMAIN.BABEL' +DROP LOGIN [dummydomain\NT Service] +GO + +-- Remove entry for 'dummydomain' +exec babelfish_remove_domain_mapping_entry 'dummydomain' +GO + diff --git a/test/JDBC/expected/GRANT_SCHEMA.out b/test/JDBC/expected/GRANT_SCHEMA.out index f15ceda260..f8d07063ee 100644 --- a/test/JDBC/expected/GRANT_SCHEMA.out +++ b/test/JDBC/expected/GRANT_SCHEMA.out @@ -6073,12 +6073,12 @@ go -- psql -- should have 2 entries for master and babel_4344_d1 databases -select schema_name, object_name, permission, grantee from sys.babelfish_schema_permissions where object_name = 'babel_4344_t1'; +select schema_name, object_name, permission, grantee from sys.babelfish_schema_permissions where object_name = 'babel_4344_t1' ORDER BY grantee; go ~~START~~ "sys"."varchar"#!#"sys"."varchar"#!#int4#!#"sys"."varchar" -dbo#!#babel_4344_t1#!#2#!#master_guest dbo#!#babel_4344_t1#!#2#!#babel_4344_d1_guest +dbo#!#babel_4344_t1#!#2#!#master_guest ~~END~~ diff --git a/test/JDBC/expected/alter-function-schema.out b/test/JDBC/expected/alter-function-schema.out new file mode 100644 index 0000000000..af92ac1573 --- /dev/null +++ b/test/JDBC/expected/alter-function-schema.out @@ -0,0 +1,376 @@ +-- tsql +-- Test altering a basic function and an inline tvf function on same schema +create login alter_func_l1 with password = '12345678' +go + +ALTER ROLE sysadmin ADD MEMBER alter_func_l1 +GO + +-- tsql user=alter_func_l1 password=12345678 +create database alter_func_db1 +go + +use alter_func_db1 +go + +create schema alter_func_schema1 +go + + +CREATE TABLE alter_func_users_t ([Id] int, [firstname] varchar(50), [lastname] varchar(50), [email] varchar(50)); +CREATE TABLE alter_func_orders_t ([Id] int, [userid] int, [productid] int, [quantity] int, [orderdate] Date); +INSERT INTO alter_func_users_t VALUES (1, 'j', 'o', 'testemail'), (1, 'e', 'l', 'testemail2'); +INSERT INTO alter_func_orders_t VALUES (1, 1, 1, 5, '2023-06-25'), (2, 1, 1, 6, '2023-06-25'); +go +~~ROW COUNT: 2~~ + +~~ROW COUNT: 2~~ + + +create function alter_func_schema1.f1() returns int begin return 2 end +go + +create function alter_func_schema1.f2() returns TABLE as return (select * from alter_func_users_t) +go + +-- psql +select schema_name, object_name, permission, grantee, object_type, function_args, grantor from sys.babelfish_schema_permissions where schema_name = 'alter_func_schema1' collate sys.database_default order by object_name; +go +~~START~~ +"sys"."varchar"#!#"sys"."varchar"#!#int4#!#"sys"."varchar"#!#bpchar#!#text#!#"sys"."varchar" +~~END~~ + + +-- tsql user=alter_func_l1 password=12345678 +select alter_func_schema1.f1() +go +~~START~~ +int +2 +~~END~~ + + +select alter_func_schema1.f2() +go +~~START~~ +varchar +(1,j,o,testemail) +(1,e,l,testemail2) +~~END~~ + + +alter function alter_func_schema1.f1(@param1 int) returns int begin return @param1 end +go + +alter function alter_func_schema1.f2() returns TABLE as return (select * from alter_func_orders_t) +go + +select alter_func_schema1.f1(5) +go +~~START~~ +int +5 +~~END~~ + + +select alter_func_schema1.f2() +go +~~START~~ +varchar +(1,1,1,5,2023-06-25) +(2,1,1,6,2023-06-25) +~~END~~ + + +drop function alter_func_schema1.f1 +go + +drop function alter_func_schema1.f2 +go + +drop table alter_func_users_t +go + +drop table alter_func_orders_t +go + +-- psql +select schema_name, object_name, permission, grantee, object_type, function_args, grantor from sys.babelfish_schema_permissions where schema_name = 'alter_func_schema1' collate sys.database_default order by object_name; +go +~~START~~ +"sys"."varchar"#!#"sys"."varchar"#!#int4#!#"sys"."varchar"#!#bpchar#!#text#!#"sys"."varchar" +~~END~~ + + +-- tsql user=alter_func_l1 password=12345678 +drop schema alter_func_schema1; +go + +use master +go + +drop database alter_func_db1 +go + +-- psql +-- Need to terminate active session before cleaning up the login +SELECT pg_terminate_backend(pid) FROM pg_stat_get_activity(NULL) +WHERE sys.suser_name(usesysid) = 'alter_func_l1' AND backend_type = 'client backend' AND usesysid IS NOT NULL; +go +~~START~~ +bool +t +~~END~~ + + +-- Wait to sync with another session +SELECT pg_sleep(1); +go +~~START~~ +void + +~~END~~ + + +-- tsql +drop login alter_func_l1; +go + +-- psql currentSchema=master_dbo,public +-- Test defining two functions with same name in psql then attempting to alter in tsql +create function psql_func_f1() +returns int +language plpgsql +as +$$ +DECLARE +BEGIN +return 1; +end; +$$; +go + +create function psql_func_f1(a integer) +returns int +language plpgsql +as +$$ +BEGIN +return a; +end; +$$; +go + +-- psql currentSchema=master_dbo,public +drop function psql_func_f1(a integer) +go + + +CREATE TABLE cars ( + brand VARCHAR(255), + model VARCHAR(255), + year INT +); +INSERT INTO cars (brand, model, year) +VALUES ('Ford', 'Mustang', 1964); +go +~~ROW COUNT: 1~~ + + +create function psql_func_tvf1() returns table(brand VARCHAR(255), model VARCHAR(255), year INT) +language plpgsql +as $$ +begin + return query +select * from cars; +end; +$$; +go + +select psql_func_tvf1() +go +~~START~~ +record +(Ford,Mustang,1964) +~~END~~ + + +-- tsql +-- Test attempting to alter psql functions in tsql +alter function psql_func_f1() returns int begin return 2 end +go +~~ERROR (Code: 33557097)~~ + +~~ERROR (Message: No existing TSQL procedure found with the name for ALTER PROCEDURE)~~ + + +alter function psql_func_tvf1() returns table +as +return (select * from cars) +go +~~ERROR (Code: 33557097)~~ + +~~ERROR (Message: No existing TSQL procedure found with the name for ALTER PROCEDURE)~~ + + +-- psql currentSchema=master_dbo,public +drop function psql_func_f1() +go + +drop function psql_func_tvf1() +go + +drop table cars; +go + +-- tsql +-- Test creating two of the same functions on different schemas +create login alter_func_l2 with password = '12345678' +go + +ALTER ROLE sysadmin ADD MEMBER alter_func_l2 +GO + +-- tsql user=alter_func_l2 password=12345678 +create database alter_func_db2 +go + +use alter_func_db2 +go + +create schema alter_func_schema2 +go + +create schema alter_func_schema3 +go + +create function alter_func_schema2.f1() returns int begin return 2 end +go + +create function alter_func_schema3.f1() returns int begin return 2 end +go + +select alter_func_schema2.f1() +go +~~START~~ +int +2 +~~END~~ + + +select alter_func_schema3.f1() +go +~~START~~ +int +2 +~~END~~ + + +alter function alter_func_schema2.f1(@param1 int) returns int begin return @param1 end +go + +alter function alter_func_schema3.f1(@param1 int) returns int begin return @param1 end +go + +select alter_func_schema2.f1(5) +go +~~START~~ +int +5 +~~END~~ + + +select alter_func_schema3.f1(5) +go +~~START~~ +int +5 +~~END~~ + + +drop function alter_func_schema2.f1(@param1 int) +go + +drop function alter_func_schema3.f1(@param1 int) +go + +drop schema alter_func_schema2 +go + +drop schema alter_func_schema3 +go + +use master +go + +drop database alter_func_db2 +go + +-- psql +-- Need to terminate active session before cleaning up the login +SELECT pg_terminate_backend(pid) FROM pg_stat_get_activity(NULL) +WHERE sys.suser_name(usesysid) = 'alter_func_l2' AND backend_type = 'client backend' AND usesysid IS NOT NULL; +go +~~START~~ +bool +t +~~END~~ + + +-- Wait to sync with another session +SELECT pg_sleep(1); +go +~~START~~ +void + +~~END~~ + + +-- tsql +drop login alter_func_l2; +go + +-- psql currentSchema=master_dbo,public + +-- Test psql functions altered with security definer do not throw StartTransactionCommand: unexpected state STARTED error +create function psql_func_f2() +returns int +language plpgsql +as +$$ +DECLARE +BEGIN +return 1; +end; +$$; +alter function psql_func_f2() security definer; +go + +drop function psql_func_f2; +go + +set babelfishpg_tsql.sql_dialect = "tsql"; +GO + +create function f1() returns int begin return 2 end +go + +-- Test alter function using tsql dialect in PSQL port throws error +alter function f1() returns int begin return 3 end +go +~~ERROR (Code: 0)~~ + +~~ERROR (Message: ERROR: TSQL ALTER PROCEDURE is not supported from PostgreSQL endpoint. + Server SQLState: 0A000)~~ + + +drop function f1() +go + +select set_config('babelfishpg_tsql.sql_dialect', 'postgres', null); +go +~~START~~ +text +postgres +~~END~~ + diff --git a/test/JDBC/expected/alter-function-vu-cleanup.out b/test/JDBC/expected/alter-function-vu-cleanup.out new file mode 100644 index 0000000000..55e7aa2eef --- /dev/null +++ b/test/JDBC/expected/alter-function-vu-cleanup.out @@ -0,0 +1,22 @@ +drop function alter_func_f1 +go + +drop function alter_func_f2 +go + +drop function alter_func_f3 +go + +drop function alter_func_f4 +go + +drop function alter_func_f5; +go + +drop function alter_func_f6; +go + +drop table alter_func_users +go +drop table alter_func_orders +go diff --git a/test/JDBC/expected/alter-function-vu-prepare.out b/test/JDBC/expected/alter-function-vu-prepare.out new file mode 100644 index 0000000000..2bbad8bfc4 --- /dev/null +++ b/test/JDBC/expected/alter-function-vu-prepare.out @@ -0,0 +1,51 @@ + +CREATE TABLE alter_func_users ([Id] int, [firstname] varchar(50), [lastname] varchar(50), [email] varchar(50)); +CREATE TABLE alter_func_orders ([Id] int, [userid] int, [productid] int, [quantity] int, [orderdate] Date); +INSERT INTO alter_func_users VALUES (1, 'j', 'o', 'testemail'), (1, 'e', 'l', 'testemail2'); +INSERT INTO alter_func_orders VALUES (1, 1, 1, 5, '2023-06-25'), (2, 1, 1, 6, '2023-06-25'); +GO +~~ROW COUNT: 2~~ + +~~ROW COUNT: 2~~ + + +create function alter_func_f1() returns int begin return 2 end +go + +create function alter_func_f2(@param1 int) returns int begin return @param1 end +go + +create function alter_func_f3(@param1 int) returns int +begin + if (@param1 < 2) + begin + return 1 + end + else + begin + return @param1 + end +end +go + +create function alter_func_f4() returns TABLE as return (select * from alter_func_users) +go + +-- Test Case: Alter function in prepare file +alter function alter_func_f4() returns TABLE as return (select * from alter_func_orders) +go + +select alter_func_f4() +go +~~START~~ +varchar +(1,1,1,5,2023-06-25) +(2,1,1,6,2023-06-25) +~~END~~ + + +create function alter_func_f5() returns @result TABLE([Id] int) as begin insert @result select 1 return end +go + +create function alter_func_f6(@p1 int, @p2 int=123, @p3 int) returns int as begin return @p1 + @p2 + @p3 end +go diff --git a/test/JDBC/expected/alter-function-vu-verify.out b/test/JDBC/expected/alter-function-vu-verify.out new file mode 100644 index 0000000000..2b2a3ee48a --- /dev/null +++ b/test/JDBC/expected/alter-function-vu-verify.out @@ -0,0 +1,266 @@ +-- Test Case 1: Alter function body +alter function alter_func_f1() returns int begin return 2 end +go + +-- Expect to return 2 +select alter_func_f1() +go +~~START~~ +int +2 +~~END~~ + + +-- Confirm information schema is correctly updated with "CREATE FUNC [new definition]" +select ROUTINE_NAME, ROUTINE_BODY, ROUTINE_DEFINITION from information_schema.routines where SPECIFIC_NAME LIKE 'alter_func_f1'; +go +~~START~~ +nvarchar#!#nvarchar#!#nvarchar +alter_func_f1#!#SQL#!#CREATE function alter_func_f1() returns int begin return 2 end +~~END~~ + + +-- Test Case 2: Alter function parameters, body, and return type +ALTER function alter_func_f2(@param2 varchar(10)) returns varchar(10) begin return @param2 end +go + +select alter_func_f2('testing') +go +~~START~~ +varchar +testing +~~END~~ + + +-- Confirm information schema is correctly updated with "CREATE FUNC [new definition]" +select ROUTINE_NAME, ROUTINE_BODY, ROUTINE_DEFINITION from information_schema.routines where SPECIFIC_NAME LIKE 'alter_func_f2'; +go +~~START~~ +nvarchar#!#nvarchar#!#nvarchar +alter_func_f2#!#SQL#!#CREATE function alter_func_f2(@param2 varchar(10)) returns varchar(10) begin return @param2 end +~~END~~ + + +-- Expect error for no parameter provided +select alter_func_f2() +go +~~ERROR (Code: 201)~~ + +~~ERROR (Message: function alter_func_f2 expects parameter "@param2", which was not supplied.)~~ + + +-- Test Case 3: Expect error for altering func that does not exist +ALTER function alter_fake_func(@param1 int) returns int +begin + return 1 +end +GO +~~ERROR (Code: 33557097)~~ + +~~ERROR (Message: No existing procedure found with the name for ALTER PROCEDURE)~~ + + + +-- Test Case 4: Alter parameter type and function body +ALTER function alter_func_f2(@param2 int) returns varchar(10) +begin + if (@param2 = 1) + BEGIN + return @param2 + END + ELSE + BEGIN + return -1 + END +end +go + +select alter_func_f2(1) +go +~~START~~ +varchar +1 +~~END~~ + + +select alter_func_f2(2) +go +~~START~~ +varchar +-1 +~~END~~ + + +-- Confirm information schema is correctly updated with "CREATE FUNC [new definition]" +select ROUTINE_NAME, ROUTINE_BODY, ROUTINE_DEFINITION from information_schema.routines where SPECIFIC_NAME LIKE 'alter_func_f2'; +go +~~START~~ +nvarchar#!#nvarchar#!#nvarchar +alter_func_f2#!#SQL#!#CREATE function alter_func_f2(@param2 int) returns varchar(10) begin if (@param2 = 1) BEGIN return @param2 END ELSE BEGIN return -1 ENDend +~~END~~ + + +-- Test Case 5: Transaction - begin, alter func, rollback +-- - expect alter to not go through +BEGIN TRANSACTION +go + +ALTER function alter_func_f2(@param2 varchar(10)) returns varchar(10) begin return @param2 end +go + +ROLLBACK +go + +-- Expect error +select alter_func_f2('test') +go +~~ERROR (Code: 33557097)~~ + +~~ERROR (Message: invalid input syntax for type integer: "test")~~ + + +-- Expect return 1 +select alter_func_f2(1) +go +~~START~~ +varchar +1 +~~END~~ + + +-- Test Case 6: Transaction - begin, alter func, modify row, commit +-- - expect both changes to take place +BEGIN TRANSACTION +GO + +ALTER function alter_func_f2(@param2 varchar(10)) returns varchar(10) begin return @param2 end +go + +INSERT INTO alter_func_users VALUES (3, 'newuser', 'lastname', 'testemail3') +go +~~ROW COUNT: 1~~ + + +COMMIT +GO + +select alter_func_f2('test') +go +~~START~~ +varchar +test +~~END~~ + + +select * from alter_func_users +go +~~START~~ +int#!#varchar#!#varchar#!#varchar +1#!#j#!#o#!#testemail +1#!#e#!#l#!#testemail2 +3#!#newuser#!#lastname#!#testemail3 +~~END~~ + + +-- Confirm information schema is correctly updated with "CREATE FUNC [new definition]" +select ROUTINE_NAME, ROUTINE_BODY, ROUTINE_DEFINITION from information_schema.routines where SPECIFIC_NAME LIKE 'alter_func_f2'; +go +~~START~~ +nvarchar#!#nvarchar#!#nvarchar +alter_func_f2#!#SQL#!#CREATE function alter_func_f2(@param2 varchar(10)) returns varchar(10) begin return @param2 end +~~END~~ + + +-- Test Case 7: Transaction - begin, alter func, modify row, commit +-- - expect both changes to not go through +BEGIN TRANSACTION +GO + +alter function alter_func_f2() returns int begin return 2 end +go + +INSERT INTO alter_func_users VALUES (4, 'newest_user', 'lastname3', 'testemail4') +go +~~ROW COUNT: 1~~ + + +ROLLBACK +GO + +-- Expect error for no parameter +select alter_func_f2() +go +~~ERROR (Code: 201)~~ + +~~ERROR (Message: function alter_func_f2 expects parameter "@param2", which was not supplied.)~~ + + +-- Expect only 3 rows +select * from alter_func_users +go +~~START~~ +int#!#varchar#!#varchar#!#varchar +1#!#j#!#o#!#testemail +1#!#e#!#l#!#testemail2 +3#!#newuser#!#lastname#!#testemail3 +~~END~~ + + +-- Test Case 8: Expect error from altering function to select from +-- table row that does not exist +alter function alter_func_f2() returns TABLE +as + return ( + select address from alter_func_users + ) +go +~~ERROR (Code: 33557097)~~ + +~~ERROR (Message: column "address" does not exist)~~ + + +-- Test Case 9: Expect error for attempting to alter multi statement tvf +-- Alter Func Multi-statement tvf support will be added after BABEL-5149 is resolved +alter function alter_func_f5() +returns @result TABLE(Id int) as begin +insert into @result values (2) +return +end +go +~~ERROR (Code: 33557097)~~ + +~~ERROR (Message: 'ALTER FUNCTION on multi-statement table valued functions' is not currently supported in Babelfish)~~ + + +-- Test Case 10: Expect error for altering function in an illegal way +-- select statements are not allowed in functions not returning a table +alter function alter_func_f3(@param1 int) returns int +begin + select * from alter_func_users + return @param1 +end +go +~~ERROR (Code: 33557097)~~ + +~~ERROR (Message: SELECT statement returning result to a client cannot be used in a function)~~ + + +-- Test Case 11: Alter function with default values +select alter_func_f6(1, default, 100) +go +~~START~~ +int +224 +~~END~~ + + +alter function alter_func_f6 (@p1 int = 345, @p2 int=123, @p3 int) returns int as begin return @p1 + @p2 + @p3 end +go + +select alter_func_f6(default, default, 100) +go +~~START~~ +int +568 +~~END~~ + diff --git a/test/JDBC/expected/alter-procedure-15_8-or-16_4-vu-cleanup.out b/test/JDBC/expected/alter-procedure-15_8-or-16_4-vu-cleanup.out new file mode 100644 index 0000000000..85b1be8cf4 --- /dev/null +++ b/test/JDBC/expected/alter-procedure-15_8-or-16_4-vu-cleanup.out @@ -0,0 +1,21 @@ +DROP PROCEDURE alter_proc_p1 +GO + +DROP PROCEDURE alter_proc_p2 +GO + +DROP PROCEDURE alter_proc_p3 +GO + +DROP PROCEDURE alter_proc_p4 +GO + +DROP PROCEDURE alter_proc_p5 +GO + +DROP TABLE alter_proc_users +DROP TABLE alter_proc_orders +GO + +drop function alter_proc_f1 +go diff --git a/test/JDBC/expected/alter-procedure-15_8-or-16_4-vu-prepare.out b/test/JDBC/expected/alter-procedure-15_8-or-16_4-vu-prepare.out new file mode 100644 index 0000000000..b83c2dcbf9 --- /dev/null +++ b/test/JDBC/expected/alter-procedure-15_8-or-16_4-vu-prepare.out @@ -0,0 +1,53 @@ + +CREATE TABLE alter_proc_users ([Id] int, [firstname] varchar(50), [lastname] varchar(50), [email] varchar(50)); +CREATE TABLE alter_proc_orders ([Id] int, [userid] int, [productid] int, [quantity] int, [orderdate] Date); +INSERT INTO alter_proc_users VALUES (1, 'j', 'o', 'testemail'), (1, 'e', 'l', 'testemail2'); +INSERT INTO alter_proc_orders VALUES (1, 1, 1, 5, '2023-06-25'), (2, 1, 1, 6, '2023-06-25'); +GO +~~ROW COUNT: 2~~ + +~~ROW COUNT: 2~~ + + +CREATE PROCEDURE alter_proc_p1 +AS + select * from alter_proc_users +GO + +create procedure alter_proc_p2 +AS + exec alter_proc_p1 +go + +create procedure alter_proc_p3 as select 1 +go + +create procedure alter_proc_p4 as select 1 +go + + +create function alter_proc_f1() +returns int +AS BEGIN + return 1 +END +go + +create procedure alter_proc_p5 as select 10 +go + +alter procedure alter_proc_p5 @dateParam date as select @dateParam +go + +-- Test Case: attempt to alter function, expect error for being unsupported +alter function alter_proc_f1() +returns int +as +BEGIN + return 5 +END +go +~~ERROR (Code: 33557097)~~ + +~~ERROR (Message: 'ALTER FUNCTION' is not currently supported in Babelfish)~~ + diff --git a/test/JDBC/expected/alter-procedure-15_8-or-16_4-vu-verify.out b/test/JDBC/expected/alter-procedure-15_8-or-16_4-vu-verify.out new file mode 100644 index 0000000000..f7eb78bbb8 --- /dev/null +++ b/test/JDBC/expected/alter-procedure-15_8-or-16_4-vu-verify.out @@ -0,0 +1,368 @@ +exec alter_proc_p1 +go +~~START~~ +int#!#varchar#!#varchar#!#varchar +1#!#j#!#o#!#testemail +1#!#e#!#l#!#testemail2 +~~END~~ + + +-- Test Case: Expect error for procedure with same name +CREATE PROCEDURE alter_proc_p1 @param1 int +AS + select * from alter_proc_orders +GO +~~ERROR (Code: 2714)~~ + +~~ERROR (Message: Function 'alter_proc_p1' already exists with the same name)~~ + + +-- Test Case: Expect error for altering proc that does not exist +ALTER PROCEDURE alter_fake_proc @param1 int +AS + select * from alter_proc_orders +GO +~~ERROR (Code: 33557097)~~ + +~~ERROR (Message: No existing procedure found with the name for ALTER PROCEDURE)~~ + + +-- Test Case: Modify the procedure body, and check information_schema updated with spaces +/* Leading comment not included: BABEL-5140 */ ALTER -- test comment + PROCEDURE alter_proc_p1 +AS + select * from alter_proc_orders +GO + +exec alter_proc_p1 +go +~~START~~ +int#!#int#!#int#!#int#!#date +1#!#1#!#1#!#5#!#2023-06-25 +2#!#1#!#1#!#6#!#2023-06-25 +~~END~~ + + +exec alter_proc_p2 +go +~~START~~ +int#!#int#!#int#!#int#!#date +1#!#1#!#1#!#5#!#2023-06-25 +2#!#1#!#1#!#6#!#2023-06-25 +~~END~~ + + +-- Ensure information schema uses "CREATE" instead of "ALTER" with updated definition +select ROUTINE_NAME, ROUTINE_BODY, ROUTINE_DEFINITION from information_schema.routines where SPECIFIC_NAME LIKE 'alter_proc_p1'; +go +~~START~~ +nvarchar#!#nvarchar#!#nvarchar +alter_proc_p1#!#SQL#!#CREATE -- test comment PROCEDURE alter_proc_p1AS select * from alter_proc_orders +~~END~~ + + + +-- Test Case: Modify the procedure body, add a parameter, use "proc" +-- instead of "procedure" + ALTER /* TEST COMMENT */ + PROC alter_proc_p1 + @param INT +AS + IF (@param = 1) + BEGIN + select * from alter_proc_users + END + ELSE + BEGIN + select * from alter_proc_orders + END +GO + +exec alter_proc_p1 @param = 1 +GO +~~START~~ +int#!#varchar#!#varchar#!#varchar +1#!#j#!#o#!#testemail +1#!#e#!#l#!#testemail2 +~~END~~ + + +exec alter_proc_p1 @param = 2 +GO +~~START~~ +int#!#int#!#int#!#int#!#date +1#!#1#!#1#!#5#!#2023-06-25 +2#!#1#!#1#!#6#!#2023-06-25 +~~END~~ + + +-- Ensure information schema uses "CREATE" instead of "ALTER" with updated definition +select ROUTINE_NAME, ROUTINE_BODY, ROUTINE_DEFINITION from information_schema.routines where SPECIFIC_NAME LIKE 'alter_proc_p1'; +go +~~START~~ +nvarchar#!#nvarchar#!#nvarchar +alter_proc_p1#!#SQL#!#CREATE /* TEST COMMENT */ PROC alter_proc_p1 @param INTAS IF (@param = 1) BEGIN select * from alter_proc_users END ELSE BEGIN select * from alter_proc_orders END +~~END~~ + + +-- Test Case: Expect error because no parameter provided +exec alter_proc_p2 +go +~~ERROR (Code: 201)~~ + +~~ERROR (Message: procedure alter_proc_p1 expects parameter "@param", which was not supplied.)~~ + + + +-- Test Case: Alter the parameter type and procedure body +ALTER PROCEDURE alter_proc_p1 + @param date +AS + IF (@param = '2020-01-01') + BEGIN + select * from alter_proc_users + END + ELSE + BEGIN + select * from alter_proc_orders + END +GO + +exec alter_proc_p1 @param = '2020-01-01' +GO +~~START~~ +int#!#varchar#!#varchar#!#varchar +1#!#j#!#o#!#testemail +1#!#e#!#l#!#testemail2 +~~END~~ + + +exec alter_proc_p1 @param = '2020-01-02' +GO +~~START~~ +int#!#int#!#int#!#int#!#date +1#!#1#!#1#!#5#!#2023-06-25 +2#!#1#!#1#!#6#!#2023-06-25 +~~END~~ + + +-- Ensure information schema uses "CREATE" instead of "ALTER" with updated definition +select ROUTINE_NAME, ROUTINE_BODY, ROUTINE_DEFINITION from information_schema.routines where SPECIFIC_NAME LIKE 'alter_proc_p1'; +go +~~START~~ +nvarchar#!#nvarchar#!#nvarchar +alter_proc_p1#!#SQL#!#CREATE PROCEDURE alter_proc_p1 @param dateAS IF (@param = '2020-01-01') BEGIN select * from alter_proc_users END ELSE BEGIN select * from alter_proc_orders END +~~END~~ + + +-- Test Case: Modify the procedure body to call another modified proc +alter procedure alter_proc_p2 +AS + exec alter_proc_p1 @param = '2020-01-01' +GO + +exec alter_proc_p2 +go +~~START~~ +int#!#varchar#!#varchar#!#varchar +1#!#j#!#o#!#testemail +1#!#e#!#l#!#testemail2 +~~END~~ + + +-- Ensure information schema uses "CREATE" instead of "ALTER" with updated definition +select ROUTINE_NAME, ROUTINE_BODY, ROUTINE_DEFINITION from information_schema.routines where SPECIFIC_NAME LIKE 'alter_proc_p2'; +go +~~START~~ +nvarchar#!#nvarchar#!#nvarchar +alter_proc_p2#!#SQL#!#CREATE procedure alter_proc_p2AS exec alter_proc_p1 @param = '2020-01-01' +~~END~~ + + +-- Test Case: Transaction - begin, alter, rollback +-- - expect alter to not go through +BEGIN TRANSACTION +go + +alter procedure alter_proc_p3 as select 2 +go + +ROLLBACK +go + +exec alter_proc_p3 +go +~~START~~ +int +1 +~~END~~ + + +-- Test Case: Transaction - begin, alter proc, modify row, commit +-- - expect both changes to take place +BEGIN TRANSACTION +go + +alter procedure alter_proc_p3 @z int as select 500 + @z +go + +INSERT INTO alter_proc_users VALUES (3, 'newuser', 'lastname', 'testemail3') +go +~~ROW COUNT: 1~~ + + +COMMIT +GO + +exec alter_proc_p3 @z = 500 +go +~~START~~ +int +1000 +~~END~~ + + +select * from alter_proc_users +go +~~START~~ +int#!#varchar#!#varchar#!#varchar +1#!#j#!#o#!#testemail +1#!#e#!#l#!#testemail2 +3#!#newuser#!#lastname#!#testemail3 +~~END~~ + + +-- Ensure information schema uses "CREATE" instead of "ALTER" with updated definition +select ROUTINE_NAME, ROUTINE_BODY, ROUTINE_DEFINITION from information_schema.routines where SPECIFIC_NAME LIKE 'alter_proc_p3'; +go +~~START~~ +nvarchar#!#nvarchar#!#nvarchar +alter_proc_p3#!#SQL#!#CREATE procedure alter_proc_p3 @z int as select 500 + @z +~~END~~ + + + +-- Test Case: Transaction - begin, alter proc, modify row, commit +-- - expect both changes to not go through +BEGIN TRANSACTION +go + +alter procedure alter_proc_p3 as select 1000 +go + +INSERT INTO alter_proc_users VALUES (4, 'newest_user', 'lastname3', 'testemail4') +go +~~ROW COUNT: 1~~ + + +ROLLBACK +GO + +-- Expect this to error with no param provided +exec alter_proc_p3 +go +~~ERROR (Code: 201)~~ + +~~ERROR (Message: procedure alter_proc_p3 expects parameter "@z", which was not supplied.)~~ + + +select * from alter_proc_users +go +~~START~~ +int#!#varchar#!#varchar#!#varchar +1#!#j#!#o#!#testemail +1#!#e#!#l#!#testemail2 +3#!#newuser#!#lastname#!#testemail3 +~~END~~ + + + +-- Test Case: Transaction - alter procedure to select from table row that does not exist +-- which would result in error if committed +BEGIN TRANSACTION +go + +alter procedure alter_proc_p3 as + select fake_column from alter_proc_users +go + +ROLLBACK +GO + +-- Expect this to error with no param provided +exec alter_proc_p3 +go +~~ERROR (Code: 201)~~ + +~~ERROR (Message: procedure alter_proc_p3 expects parameter "@z", which was not supplied.)~~ + + + + + + +-- Test Case: confirm information_schema.routines is updated properly with comments +alter +/* + * test comment 1 + */ +-- test comment 2 +procedure alter_proc_p4 as select 3 +go + +exec alter_proc_p4 +go +~~START~~ +int +3 +~~END~~ + + +select ROUTINE_NAME, ROUTINE_BODY, ROUTINE_DEFINITION from information_schema.routines where SPECIFIC_NAME LIKE 'alter_proc_p4'; +go +~~START~~ +nvarchar#!#nvarchar#!#nvarchar +alter_proc_p4#!#SQL#!#CREATE /* * test comment 1 */-- test comment 2procedure alter_proc_p4 as select 3 +~~END~~ + + + + +-- Test Case: confirm information_schema.routines is updated properly with comments +alter +-- test comment 1 +procedure alter_proc_p4 as select 4 +go + +exec alter_proc_p4 +go +~~START~~ +int +4 +~~END~~ + + +select ROUTINE_NAME, ROUTINE_BODY, ROUTINE_DEFINITION from information_schema.routines where SPECIFIC_NAME LIKE 'alter_proc_p4'; +go +~~START~~ +nvarchar#!#nvarchar#!#nvarchar +alter_proc_p4#!#SQL#!#CREATE -- test comment 1procedure alter_proc_p4 as select 4 +~~END~~ + + +-- Test Case: confirm procedure altered in 'alter-procedure-vu-prepare' is properly updated +exec alter_proc_p5 @dateParam = '2000-01-01' +go +~~START~~ +date +2000-01-01 +~~END~~ + + +select ROUTINE_NAME, ROUTINE_BODY, ROUTINE_DEFINITION from information_schema.routines where SPECIFIC_NAME LIKE 'alter_proc_p4'; +go +~~START~~ +nvarchar#!#nvarchar#!#nvarchar +alter_proc_p4#!#SQL#!#CREATE -- test comment 1procedure alter_proc_p4 as select 4 +~~END~~ + diff --git a/test/JDBC/expected/alter-procedure-before-15_8-or-16_4-vu-prepare.out b/test/JDBC/expected/alter-procedure-before-15_8-or-16_4-vu-prepare.out index cc0b1922a7..8af8d46e86 100644 --- a/test/JDBC/expected/alter-procedure-before-15_8-or-16_4-vu-prepare.out +++ b/test/JDBC/expected/alter-procedure-before-15_8-or-16_4-vu-prepare.out @@ -73,3 +73,16 @@ go alter procedure alter_proc_p5 @dateParam date as select @dateParam go + +-- Test Case: attempt to alter function, expect error for being unsupported +alter function alter_proc_f1() +returns int +as +BEGIN + return 5 +END +go +~~ERROR (Code: 33557097)~~ + +~~ERROR (Message: 'ALTER FUNCTION' is not currently supported in Babelfish)~~ + diff --git a/test/JDBC/expected/alter-procedure-before-15_8-or-16_4-vu-verify.out b/test/JDBC/expected/alter-procedure-before-15_8-or-16_4-vu-verify.out index a5ef2b4435..9fbf8a4c3c 100644 --- a/test/JDBC/expected/alter-procedure-before-15_8-or-16_4-vu-verify.out +++ b/test/JDBC/expected/alter-procedure-before-15_8-or-16_4-vu-verify.out @@ -124,19 +124,6 @@ int#!#int#!#int#!#int#!#date ~~END~~ --- Test Case: attempt to alter function, expect error for being unsupported -alter function alter_proc_f1() -returns int -as -BEGIN - return 5 -END -go -~~ERROR (Code: 33557097)~~ - -~~ERROR (Message: 'ALTER FUNCTION' is not currently supported in Babelfish)~~ - - -- Test Case: Confirm transaction updates procedure correctly exec alter_proc_p3 @z = 500 go diff --git a/test/JDBC/expected/alter-procedure-vu-cleanup.out b/test/JDBC/expected/alter-procedure-vu-cleanup.out index 85b1be8cf4..a505d634af 100644 --- a/test/JDBC/expected/alter-procedure-vu-cleanup.out +++ b/test/JDBC/expected/alter-procedure-vu-cleanup.out @@ -16,6 +16,3 @@ GO DROP TABLE alter_proc_users DROP TABLE alter_proc_orders GO - -drop function alter_proc_f1 -go diff --git a/test/JDBC/expected/alter-procedure-vu-prepare.out b/test/JDBC/expected/alter-procedure-vu-prepare.out index c6dbecb129..faf95e5538 100644 --- a/test/JDBC/expected/alter-procedure-vu-prepare.out +++ b/test/JDBC/expected/alter-procedure-vu-prepare.out @@ -25,14 +25,6 @@ go create procedure alter_proc_p4 as select 1 go - -create function alter_proc_f1() -returns int -AS BEGIN - return 1 -END -go - create procedure alter_proc_p5 as select 10 go diff --git a/test/JDBC/expected/alter-procedure-vu-verify.out b/test/JDBC/expected/alter-procedure-vu-verify.out index ba6c7e137c..f7eb78bbb8 100644 --- a/test/JDBC/expected/alter-procedure-vu-verify.out +++ b/test/JDBC/expected/alter-procedure-vu-verify.out @@ -179,20 +179,6 @@ alter_proc_p2#!#SQL#!#CREATE procedure alter_proc_p2AS exec ~~END~~ - --- Test Case: attempt to alter function, expect error for being unsupported -alter function alter_proc_f1() -returns int -as -BEGIN - return 5 -END -go -~~ERROR (Code: 33557097)~~ - -~~ERROR (Message: 'ALTER FUNCTION' is not currently supported in Babelfish)~~ - - -- Test Case: Transaction - begin, alter, rollback -- - expect alter to not go through BEGIN TRANSACTION diff --git a/test/JDBC/expected/kill-vu-cleanup.out b/test/JDBC/expected/kill-vu-cleanup.out index 3c34eb7d8a..856c606229 100644 --- a/test/JDBC/expected/kill-vu-cleanup.out +++ b/test/JDBC/expected/kill-vu-cleanup.out @@ -17,3 +17,29 @@ go DROP TABLE tab_kill_test go +DROP Database test_kill_db1 +GO +DROP Database test_kill_db2 +GO +DROP Database test_kill_db3 +GO +DROP Database test_kill_db4 +GO +DROP Database test_kill_db5 +GO +DROP Database test_kill_db6 +GO +DROP Database test_kill_db7 +GO +DROP Database test_kill_db8 +GO +DROP Database test_kill_db9 +GO +DROP Database test_kill_db10 +GO +DROP Database test_kill_db11 +GO + +DROP LOGIN test_kill; +GO + diff --git a/test/JDBC/expected/kill-vu-verify.out b/test/JDBC/expected/kill-vu-verify.out index 71b11a7da9..ec919836f7 100644 --- a/test/JDBC/expected/kill-vu-verify.out +++ b/test/JDBC/expected/kill-vu-verify.out @@ -438,3 +438,328 @@ go int ~~END~~ + +-- tsql +-- BABEL-5219 Multiple Session Kill +CREATE LOGIN test_kill WITH PASSWORD = '12345678' +GO + +-- CREATE 11 Databases +create database test_kill_db1 +GO +use test_kill_db1 +GO +CREATE USER user_kill FOR LOGIN test_kill; +go + +create database test_kill_db2 +GO +use test_kill_db2 +GO +CREATE USER user_kill FOR LOGIN test_kill; +go + +create database test_kill_db3 +GO +use test_kill_db3 +GO +CREATE USER user_kill FOR LOGIN test_kill; +go + +create database test_kill_db4 +GO +use test_kill_db4 +GO +CREATE USER user_kill FOR LOGIN test_kill; +go + +create database test_kill_db5 +GO +use test_kill_db5 +GO +CREATE USER user_kill FOR LOGIN test_kill; +go + +create database test_kill_db6 +GO +use test_kill_db6 +GO +CREATE USER user_kill FOR LOGIN test_kill; +go + +create database test_kill_db7 +GO +use test_kill_db7 +GO +CREATE USER user_kill FOR LOGIN test_kill; +go + +create database test_kill_db8 +GO +use test_kill_db8 +GO +CREATE USER user_kill FOR LOGIN test_kill; +go + +create database test_kill_db9 +GO +use test_kill_db9 +GO +CREATE USER user_kill FOR LOGIN test_kill; +go + + +create database test_kill_db10 +GO +use test_kill_db10 +GO +CREATE USER user_kill FOR LOGIN test_kill; +go + +create database test_kill_db11 +GO +use test_kill_db11 +GO +CREATE USER user_kill FOR LOGIN test_kill; +go + +-- tsql user=test_kill password=12345678 database=test_kill_db1 +-- CREATE 11 sessions +SELECT 1 +GO +~~START~~ +int +1 +~~END~~ + + +-- tsql user=test_kill password=12345678 database=test_kill_db2 +SELECT 1 +GO +~~START~~ +int +1 +~~END~~ + + +-- tsql user=test_kill password=12345678 database=test_kill_db3 +SELECT 1 +GO +~~START~~ +int +1 +~~END~~ + + +-- tsql user=test_kill password=12345678 database=test_kill_db4 +SELECT 1 +GO +~~START~~ +int +1 +~~END~~ + + +-- tsql user=test_kill password=12345678 database=test_kill_db5 +SELECT 1 +GO +~~START~~ +int +1 +~~END~~ + + +-- tsql user=test_kill password=12345678 database=test_kill_db6 +SELECT 1 +GO +~~START~~ +int +1 +~~END~~ + + +-- tsql user=test_kill password=12345678 database=test_kill_db7 +SELECT 1 +GO +~~START~~ +int +1 +~~END~~ + + +-- tsql user=test_kill password=12345678 database=test_kill_db8 +SELECT 1 +GO +~~START~~ +int +1 +~~END~~ + + +-- tsql user=test_kill password=12345678 database=test_kill_db9 +SELECT 1 +GO +~~START~~ +int +1 +~~END~~ + + +-- tsql user=test_kill password=12345678 database=test_kill_db10 +SELECT 1 +GO +~~START~~ +int +1 +~~END~~ + + +-- tsql user=test_kill password=12345678 database=test_kill_db11 +SELECT 1 +GO +~~START~~ +int +1 +~~END~~ + + +-- tsql +SELECT count(*) from sys.dm_exec_sessions where login_name = 'test_kill' +GO +~~START~~ +int +11 +~~END~~ + + +SELECT COUNT(*) from pg_stat_activity where usename = 'test_kill' +GO +~~START~~ +int +11 +~~END~~ + + +-- Kill Sessions +USE [MASTER] +DECLARE @UserName NVARCHAR(255) = 'test_kill' +DECLARE @SPID INT +-- Creates temp table to store SPIDs +IF OBJECT_ID('tempdb..#UserSessions') IS NOT NULL +BEGIN +-- dropa tabela se existir +DROP TABLE #UserSessions +END +CREATE TABLE #UserSessions (SPID INT) +-- Inserting SPIDs from User Sessions into the Temporary Table +INSERT INTO #UserSessions (SPID) +SELECT session_id +FROM sys.dm_exec_sessions +WHERE login_name = @UserName +-- Loop to kill user sessions +DECLARE @RowCount INT = (SELECT COUNT(*) FROM #UserSessions) +DECLARE @Counter INT = 1 +DECLARE @CmdKill NVARCHAR(100) +WHILE @Counter <= @RowCount +BEGIN +SELECT TOP 1 @SPID = SPID FROM #UserSessions +SET @CmdKill = 'KILL ' + CAST(@SPID AS NVARCHAR(10)) +execute(@CmdKill) +DELETE FROM #UserSessions WHERE SPID = @SPID +SET @Counter = @Counter + 1 +END +-- Temporary Table Cleaning +DROP TABLE #UserSessions +GO +~~WARNING (Code: 0)~~ + +~~WARNING (Message: Changed database context to 'master'. Server SQLState: S0001)~~ + +~~ROW COUNT: 11~~ + +~~WARNING (Code: 0)~~ + +~~WARNING (Message: Changed database context to 'master'. Server SQLState: S0001)~~ + +~~ROW COUNT: 1~~ + +~~WARNING (Code: 0)~~ + +~~WARNING (Message: Changed database context to 'master'. Server SQLState: S0001)~~ + +~~ROW COUNT: 1~~ + +~~WARNING (Code: 0)~~ + +~~WARNING (Message: Changed database context to 'master'. Server SQLState: S0001)~~ + +~~ROW COUNT: 1~~ + +~~WARNING (Code: 0)~~ + +~~WARNING (Message: Changed database context to 'master'. Server SQLState: S0001)~~ + +~~ROW COUNT: 1~~ + +~~WARNING (Code: 0)~~ + +~~WARNING (Message: Changed database context to 'master'. Server SQLState: S0001)~~ + +~~ROW COUNT: 1~~ + +~~WARNING (Code: 0)~~ + +~~WARNING (Message: Changed database context to 'master'. Server SQLState: S0001)~~ + +~~ROW COUNT: 1~~ + +~~WARNING (Code: 0)~~ + +~~WARNING (Message: Changed database context to 'master'. Server SQLState: S0001)~~ + +~~ROW COUNT: 1~~ + +~~WARNING (Code: 0)~~ + +~~WARNING (Message: Changed database context to 'master'. Server SQLState: S0001)~~ + +~~ROW COUNT: 1~~ + +~~WARNING (Code: 0)~~ + +~~WARNING (Message: Changed database context to 'master'. Server SQLState: S0001)~~ + +~~ROW COUNT: 1~~ + +~~WARNING (Code: 0)~~ + +~~WARNING (Message: Changed database context to 'master'. Server SQLState: S0001)~~ + +~~ROW COUNT: 1~~ + +~~WARNING (Code: 0)~~ + +~~WARNING (Message: Changed database context to 'master'. Server SQLState: S0001)~~ + +~~ROW COUNT: 1~~ + + +-- allow the kill to complete; this might take a while under heavy workload +exec pg_sleep 5 +go + +SELECT count(*) from sys.dm_exec_sessions where login_name = 'test_kill' +GO +~~START~~ +int +0 +~~END~~ + + +SELECT COUNT(*) from pg_stat_activity where usename = 'test_kill' +GO +~~START~~ +int +0 +~~END~~ + diff --git a/test/JDBC/expected/non_default_server_collation/chinese_prc_ci_as/BABEL-UNSUPPORTED.out b/test/JDBC/expected/non_default_server_collation/chinese_prc_ci_as/BABEL-UNSUPPORTED.out index b4572aace0..46b9b9d7b8 100644 --- a/test/JDBC/expected/non_default_server_collation/chinese_prc_ci_as/BABEL-UNSUPPORTED.out +++ b/test/JDBC/expected/non_default_server_collation/chinese_prc_ci_as/BABEL-UNSUPPORTED.out @@ -2992,3 +2992,117 @@ GO ~~ERROR (Message: 'EXTERNAL NAME' is not currently supported in Babelfish)~~ +-- create login from windows +-- Add 'dummydomain' domain entry +exec sys.babelfish_add_domain_mapping_entry 'dummydomain', 'dummydomain.babel'; +GO + +CREATE LOGIN [NT Service\MSSQLSERVER] FROM WINDOWS +GO +~~ERROR (Code: 33557097)~~ + +~~ERROR (Message: 'NT Service' domain is not yet supported in Babelfish.)~~ + + +CREATE LOGIN [\MSSQLSERVER] FROM WINDOWS +GO +~~ERROR (Code: 33557097)~~ + +~~ERROR (Message: The login name '\MSSQLSERVER' is invalid. The domain can not be empty.)~~ + + +CREATE LOGIN [NT Servicesomething\MSSQLSERVER] FROM WINDOWS +GO +~~ERROR (Code: 33557097)~~ + +~~ERROR (Message: 'NT Servicesomething\MSSQLSERVER' is not valid because the domain name contains invalid characters.)~~ + + +CREATE LOGIN [NT ServiceNT Service\MSSQLSERVER] FROM WINDOWS +GO +~~ERROR (Code: 33557097)~~ + +~~ERROR (Message: 'NT ServiceNT Service\MSSQLSERVER' is not valid because the domain name contains invalid characters.)~~ + + +CREATE LOGIN [NT ServiceNT SerViCe\MSSQLSERVER] FROM WINDOWS +GO +~~ERROR (Code: 33557097)~~ + +~~ERROR (Message: 'NT ServiceNT SerViCe\MSSQLSERVER' is not valid because the domain name contains invalid characters.)~~ + + +CREATE LOGIN [somethingNT Service\MSSQLSERVER] FROM WINDOWS +GO +~~ERROR (Code: 33557097)~~ + +~~ERROR (Message: 'somethingNT Service\MSSQLSERVER' is not valid because the domain name contains invalid characters.)~~ + + +CREATE LOGIN [NT Service\NT Service\MSSQLSERVER] FROM WINDOWS +GO +~~ERROR (Code: 33557097)~~ + +~~ERROR (Message: The login name 'NT Service\NT Service\MSSQLSERVER' has invalid length. Login name length should be between 1 and 20 for windows login.)~~ + + +CREATE LOGIN [NT S\ervice\MSSQLSERVER] FROM WINDOWS +GO +~~ERROR (Code: 33557097)~~ + +~~ERROR (Message: 'NT S\ervice\MSSQLSERVER' is not a valid name because it contains invalid characters.)~~ + + +CREATE LOGIN [NT Service\\MSSQLSERVER] FROM WINDOWS +GO +~~ERROR (Code: 33557097)~~ + +~~ERROR (Message: 'NT Service\\MSSQLSERVER' is not a valid name because it contains invalid characters.)~~ + + +CREATE LOGIN ["NT Service"\MSSQLSERVER] FROM WINDOWS +GO +~~ERROR (Code: 33557097)~~ + +~~ERROR (Message: '"NT Service"\MSSQLSERVER' is not valid because the domain name contains invalid characters.)~~ + + +CREATE LOGIN [[NT Service]\MSSQLSERVER] FROM WINDOWS +GO +~~ERROR (Code: 33557097)~~ + +~~ERROR (Message: syntax error near '\' at line 1 and character position 26)~~ + + +CREATE LOGIN [["NT Service"]\MSSQLSERVER] FROM WINDOWS +GO +~~ERROR (Code: 33557097)~~ + +~~ERROR (Message: syntax error near '\' at line 1 and character position 28)~~ + + +CREATE LOGIN [NT Service\MSSQLSERVER] FROM WINDOWS WITH DEFAULT_DATABASE=[test] +GO +~~ERROR (Code: 33557097)~~ + +~~ERROR (Message: 'NT Service' domain is not yet supported in Babelfish.)~~ + + +CREATE LOGIN [NT SerViCe\MSSQLSERVER] FROM WINDOWS WITH DEFAULT_DATABASE=[test] +GO +~~ERROR (Code: 33557097)~~ + +~~ERROR (Message: 'NT SerViCe' domain is not yet supported in Babelfish.)~~ + + +CREATE LOGIN [dummydomain\NT Service] FROM WINDOWS +GO + +-- Dropping 'nt service@DUMMYDOMAIN.BABEL' +DROP LOGIN [dummydomain\NT Service] +GO + +-- Remove entry for 'dummydomain' +exec babelfish_remove_domain_mapping_entry 'dummydomain' +GO + diff --git a/test/JDBC/expected/single_db/GRANT_SCHEMA.out b/test/JDBC/expected/single_db/GRANT_SCHEMA.out index cedc4a6e56..119c2d1e1c 100644 --- a/test/JDBC/expected/single_db/GRANT_SCHEMA.out +++ b/test/JDBC/expected/single_db/GRANT_SCHEMA.out @@ -6073,12 +6073,12 @@ go -- psql -- should have 2 entries for master and babel_4344_d1 databases -select schema_name, object_name, permission, grantee from sys.babelfish_schema_permissions where object_name = 'babel_4344_t1'; +select schema_name, object_name, permission, grantee from sys.babelfish_schema_permissions where object_name = 'babel_4344_t1' ORDER BY grantee; go ~~START~~ "sys"."varchar"#!#"sys"."varchar"#!#int4#!#"sys"."varchar" -dbo#!#babel_4344_t1#!#2#!#master_guest dbo#!#babel_4344_t1#!#2#!#babel_4344_d1_guest +dbo#!#babel_4344_t1#!#2#!#master_guest ~~END~~ diff --git a/test/JDBC/expected/single_db/kill-vu-cleanup.out b/test/JDBC/expected/single_db/kill-vu-cleanup.out new file mode 100644 index 0000000000..65fa5863e2 --- /dev/null +++ b/test/JDBC/expected/single_db/kill-vu-cleanup.out @@ -0,0 +1,85 @@ +-- tsql +DROP LOGIN victim_user_tds +go + +DROP TABLE tab_kill_spid +go + +DROP PROCEDURE kill_proc_1 +go + +DROP PROCEDURE kill_proc_2 +go + +DROP PROCEDURE kill_proc_3 +go + +DROP TABLE tab_kill_test +go + +DROP Database test_kill_db1 +GO +DROP Database test_kill_db2 +GO +~~ERROR (Code: 911)~~ + +~~ERROR (Message: database "test_kill_db2" does not exist)~~ + +DROP Database test_kill_db3 +GO +~~ERROR (Code: 911)~~ + +~~ERROR (Message: database "test_kill_db3" does not exist)~~ + +DROP Database test_kill_db4 +GO +~~ERROR (Code: 911)~~ + +~~ERROR (Message: database "test_kill_db4" does not exist)~~ + +DROP Database test_kill_db5 +GO +~~ERROR (Code: 911)~~ + +~~ERROR (Message: database "test_kill_db5" does not exist)~~ + +DROP Database test_kill_db6 +GO +~~ERROR (Code: 911)~~ + +~~ERROR (Message: database "test_kill_db6" does not exist)~~ + +DROP Database test_kill_db7 +GO +~~ERROR (Code: 911)~~ + +~~ERROR (Message: database "test_kill_db7" does not exist)~~ + +DROP Database test_kill_db8 +GO +~~ERROR (Code: 911)~~ + +~~ERROR (Message: database "test_kill_db8" does not exist)~~ + +DROP Database test_kill_db9 +GO +~~ERROR (Code: 911)~~ + +~~ERROR (Message: database "test_kill_db9" does not exist)~~ + +DROP Database test_kill_db10 +GO +~~ERROR (Code: 911)~~ + +~~ERROR (Message: database "test_kill_db10" does not exist)~~ + +DROP Database test_kill_db11 +GO +~~ERROR (Code: 911)~~ + +~~ERROR (Message: database "test_kill_db11" does not exist)~~ + + +DROP LOGIN test_kill; +GO + diff --git a/test/JDBC/expected/single_db/kill-vu-verify.out b/test/JDBC/expected/single_db/kill-vu-verify.out new file mode 100644 index 0000000000..f88e73fb6a --- /dev/null +++ b/test/JDBC/expected/single_db/kill-vu-verify.out @@ -0,0 +1,865 @@ +-- tsql +create table tab_kill_spid(spid int) +go +create login victim_user_tds with password = '12345678'; +go + +-- tsql user=victim_user_tds password=12345678 +select 1 +go +~~START~~ +int +1 +~~END~~ + +-- not allowed: no sysadmin role +KILL 1 +go +~~ERROR (Code: 33557097)~~ + +~~ERROR (Message: User does not have permission to use the KILL statement)~~ + + +-- tsql user=jdbc_user password=12345678 +/* find a TDS session that is not the current one */ +declare @victim_user_tds int +declare @sql varchar(20) +select top 1 @victim_user_tds = session_id from sys.dm_exec_sessions where login_name = 'victim_user_tds' and session_id <> @@spid +if @victim_user_tds is null +begin +print 'ERROR: no victim spid found' +end +insert tab_kill_spid values(@victim_user_tds) +set @sql = 'kill ' + convert(varchar, @victim_user_tds) +execute(@sql) +go +~~ROW COUNT: 1~~ + + +-- allow the kill to complete; this might take a while under heavy workload +exec pg_sleep 10 +go + +-- verify session does not exist anymore +declare @victim_user_tds int +select @victim_user_tds = spid from tab_kill_spid +select count(distinct session_id) from sys.dm_exec_sessions where session_id = @victim_user_tds +go +~~START~~ +int +0 +~~END~~ + + + +/* Cannot currently be tested: trying to kill a PG session + * Reason is that the error message contains the spid number, which is not predicatable + * and will therefore always lead to a test failure + */ +go + +-- KILL in a procedure: allowed +CREATE PROC kill_proc_1 +as +KILL 1 +go +EXECUTE kill_proc_1 +go +~~ERROR (Code: 33557097)~~ + +~~ERROR (Message: Process ID 1 is not an active process ID)~~ + + +-- KILL not allowed in a SQL function: not allowed +CREATE FUNCTION kill_func() RETURNS INT +AS +BEGIN +KILL 1 +END +go +~~ERROR (Code: 33557097)~~ + +~~ERROR (Message: Invalid use of a side-effecting operator 'KILL' within a function.)~~ + + +-- try to kill current TDS session +declare @sql varchar(100) +set @sql = 'kill ' + convert(varchar, @@spid) +execute(@sql) +go +~~ERROR (Code: 33557097)~~ + +~~ERROR (Message: Cannot use KILL to kill your own process.)~~ + + +-- kill non-existing spid +KILL 1 +go +~~ERROR (Code: 33557097)~~ + +~~ERROR (Message: Process ID 1 is not an active process ID)~~ + + +KILL -123 +go +~~ERROR (Code: 33557097)~~ + +~~ERROR (Message: syntax error near '-' at line 1 and character position 5)~~ + + +KILL 999999999999999999999999999999999999999999999 +go +~~ERROR (Code: 33557097)~~ + +~~ERROR (Message: Session ID -1 is not valid)~~ + + +KILL 123 WITH STATUSONLY +go +~~ERROR (Code: 33557097)~~ + +~~ERROR (Message: 'KILL with STATUSONLY' is not currently supported in Babelfish)~~ + + +KILL UOW WITH STATUSONLY +go +~~ERROR (Code: 33557097)~~ + +~~ERROR (Message: 'KILL with STATUSONLY' is not currently supported in Babelfish)~~ + + +KILL 'A0499C66-F938-45CA-BF7E-E2B6194B48CF' +go +~~ERROR (Code: 33557097)~~ + +~~ERROR (Message: 'KILL with a session ID string' is not currently supported in Babelfish)~~ + + +KILL 'A0499C66-F938-45CA-BF7E-E2B6194B48CF' with statusonly +go +~~ERROR (Code: 33557097)~~ + +~~ERROR (Message: 'KILL with STATUSONLY' is not currently supported in Babelfish)~~ + + +KILL STATS JOB 123 +go +~~ERROR (Code: 33557097)~~ + +~~ERROR (Message: 'KILL with STATS JOB' is not currently supported in Babelfish)~~ + + +KILL QUERY NOTIFICATION SUBSCRIPTION ALL +go +~~ERROR (Code: 33557097)~~ + +~~ERROR (Message: 'KILL with QUERY NOTIFICATION' is not currently supported in Babelfish)~~ + + +KILL QUERY NOTIFICATION SUBSCRIPTION 123 +go +~~ERROR (Code: 33557097)~~ + +~~ERROR (Message: 'KILL with QUERY NOTIFICATION' is not currently supported in Babelfish)~~ + + + +-- error semantics tests: +-- basic: cannot use KILL inside a transaction +BEGIN TRAN +go +KILL 1 +go +~~ERROR (Code: 6615)~~ + +~~ERROR (Message: KILL command cannot be used inside user transactions.)~~ + +ROLLBACK +go + +CREATE TABLE tab_kill_test(a INT) +go + +-- cannot use KILL in a transaction, XACT_ABORT=OFF +SET XACT_ABORT OFF +go +BEGIN TRANSACTION +INSERT tab_kill_test values(1) +go +~~ROW COUNT: 1~~ + +PRINT 'before kill' +INSERT tab_kill_test values(2) +KILL 1 +PRINT 'after kill' +INSERT tab_kill_test values(3) +go +~~WARNING (Code: 0)~~ + +~~WARNING (Message: before kill Server SQLState: S0001)~~ + +~~ROW COUNT: 1~~ + +~~ERROR (Code: 6615)~~ + +~~ERROR (Message: KILL command cannot be used inside user transactions.)~~ + +~~WARNING (Code: 0)~~ + +~~WARNING (Message: before kill Server SQLState: S0001)~~~~WARNING (Message: after kill Server SQLState: S0001)~~ + +~~ROW COUNT: 1~~ + +SELECT @@TRANCOUNT +go +~~START~~ +int +1 +~~END~~ + +SELECT * FROM tab_kill_test +go +~~START~~ +int +1 +2 +3 +~~END~~ + +ROLLBACK +go + +-- cannot use KILL in a transaction, XACT_ABORT=ON +SET XACT_ABORT ON +go +BEGIN TRANSACTION +INSERT tab_kill_test values(1) +go +~~ROW COUNT: 1~~ + +PRINT 'before kill' +INSERT tab_kill_test values(2) +KILL 1 +PRINT 'after kill' +INSERT tab_kill_test values(3) +go +~~WARNING (Code: 0)~~ + +~~WARNING (Message: before kill Server SQLState: S0001)~~ + +~~ROW COUNT: 1~~ + +~~ERROR (Code: 6615)~~ + +~~ERROR (Message: KILL command cannot be used inside user transactions.)~~ + +SELECT @@TRANCOUNT +go +~~START~~ +int +0 +~~END~~ + +SELECT * FROM tab_kill_test +go +~~START~~ +int +~~END~~ + + +-- batch is not aborted when KILL in transaction, XACT_ABORT=OFF +SET XACT_ABORT OFF +go +BEGIN TRANSACTION +INSERT tab_kill_test values(1) +go +~~ROW COUNT: 1~~ + +PRINT 'before kill' +INSERT tab_kill_test values(2) +KILL 1 +PRINT 'after kill' +INSERT tab_kill_test values(3) +go +~~WARNING (Code: 0)~~ + +~~WARNING (Message: before kill Server SQLState: S0001)~~ + +~~ROW COUNT: 1~~ + +~~ERROR (Code: 6615)~~ + +~~ERROR (Message: KILL command cannot be used inside user transactions.)~~ + +~~WARNING (Code: 0)~~ + +~~WARNING (Message: before kill Server SQLState: S0001)~~~~WARNING (Message: after kill Server SQLState: S0001)~~ + +~~ROW COUNT: 1~~ + +SELECT @@TRANCOUNT +go +~~START~~ +int +1 +~~END~~ + +SELECT * FROM tab_kill_test +go +~~START~~ +int +1 +2 +3 +~~END~~ + +ROLLBACK +go + +-- respects XACT_ABORT=ON +SET XACT_ABORT ON +go +BEGIN TRANSACTION +INSERT tab_kill_test values(1) +go +~~ROW COUNT: 1~~ + +PRINT 'before kill' +INSERT tab_kill_test values(2) +KILL 1 +PRINT 'after kill' +INSERT tab_kill_test values(3) +go +~~WARNING (Code: 0)~~ + +~~WARNING (Message: before kill Server SQLState: S0001)~~ + +~~ROW COUNT: 1~~ + +~~ERROR (Code: 6615)~~ + +~~ERROR (Message: KILL command cannot be used inside user transactions.)~~ + +SELECT @@TRANCOUNT +go +~~START~~ +int +0 +~~END~~ + +SELECT * FROM tab_kill_test +go +~~START~~ +int +~~END~~ + + +-- KILL in procedure, XACT_ABORT=OFF +CREATE PROCEDURE kill_proc_2 +AS +BEGIN +PRINT 'before kill' +INSERT tab_kill_test values(2) +KILL 1 +PRINT 'after kill' +INSERT tab_kill_test values(3) +END +go +SET XACT_ABORT OFF +go +BEGIN TRANSACTION +INSERT tab_kill_test values(1) +EXECUTE kill_proc_2 +go +~~ROW COUNT: 1~~ + +~~ROW COUNT: 1~~ + +~~ERROR (Code: 6615)~~ + +~~ERROR (Message: KILL command cannot be used inside user transactions.)~~ + +~~ROW COUNT: 1~~ + +SELECT @@TRANCOUNT +go +~~START~~ +int +1 +~~END~~ + +SELECT * FROM tab_kill_test +go +~~START~~ +int +1 +2 +3 +~~END~~ + +ROLLBACK +go + +-- KILL in procedure, XACT_ABORT=ON +CREATE PROCEDURE kill_proc_3 +AS +BEGIN +PRINT 'before kill' +INSERT tab_kill_test values(2) +KILL 1 +PRINT 'after kill' +INSERT tab_kill_test values(3) +END +go +SET XACT_ABORT ON +go +BEGIN TRANSACTION +INSERT tab_kill_test values(1) +EXECUTE kill_proc_3 +go +~~ROW COUNT: 1~~ + +~~ROW COUNT: 1~~ + +~~ERROR (Code: 6615)~~ + +~~ERROR (Message: KILL command cannot be used inside user transactions.)~~ + +SELECT @@TRANCOUNT +go +~~START~~ +int +0 +~~END~~ + +SELECT * FROM tab_kill_test +go +~~START~~ +int +~~END~~ + + +-- tsql +-- BABEL-5219 Multiple Session Kill +CREATE LOGIN test_kill WITH PASSWORD = '12345678' +GO + +-- CREATE 11 Databases +create database test_kill_db1 +GO +use test_kill_db1 +GO +CREATE USER user_kill FOR LOGIN test_kill; +go + +create database test_kill_db2 +GO +~~ERROR (Code: 33557097)~~ + +~~ERROR (Message: Only one user database allowed under single-db mode. User database "test_kill_db1" already exists)~~ + +use test_kill_db2 +GO +~~ERROR (Code: 911)~~ + +~~ERROR (Message: database "test_kill_db2" does not exist)~~ + +CREATE USER user_kill FOR LOGIN test_kill; +go +~~ERROR (Code: 33557097)~~ + +~~ERROR (Message: role "test_kill_db1_user_kill" already exists)~~ + + +create database test_kill_db3 +GO +~~ERROR (Code: 33557097)~~ + +~~ERROR (Message: Only one user database allowed under single-db mode. User database "test_kill_db1" already exists)~~ + +use test_kill_db3 +GO +~~ERROR (Code: 911)~~ + +~~ERROR (Message: database "test_kill_db3" does not exist)~~ + +CREATE USER user_kill FOR LOGIN test_kill; +go +~~ERROR (Code: 33557097)~~ + +~~ERROR (Message: role "test_kill_db1_user_kill" already exists)~~ + + +create database test_kill_db4 +GO +~~ERROR (Code: 33557097)~~ + +~~ERROR (Message: Only one user database allowed under single-db mode. User database "test_kill_db1" already exists)~~ + +use test_kill_db4 +GO +~~ERROR (Code: 911)~~ + +~~ERROR (Message: database "test_kill_db4" does not exist)~~ + +CREATE USER user_kill FOR LOGIN test_kill; +go +~~ERROR (Code: 33557097)~~ + +~~ERROR (Message: role "test_kill_db1_user_kill" already exists)~~ + + +create database test_kill_db5 +GO +~~ERROR (Code: 33557097)~~ + +~~ERROR (Message: Only one user database allowed under single-db mode. User database "test_kill_db1" already exists)~~ + +use test_kill_db5 +GO +~~ERROR (Code: 911)~~ + +~~ERROR (Message: database "test_kill_db5" does not exist)~~ + +CREATE USER user_kill FOR LOGIN test_kill; +go +~~ERROR (Code: 33557097)~~ + +~~ERROR (Message: role "test_kill_db1_user_kill" already exists)~~ + + +create database test_kill_db6 +GO +~~ERROR (Code: 33557097)~~ + +~~ERROR (Message: Only one user database allowed under single-db mode. User database "test_kill_db1" already exists)~~ + +use test_kill_db6 +GO +~~ERROR (Code: 911)~~ + +~~ERROR (Message: database "test_kill_db6" does not exist)~~ + +CREATE USER user_kill FOR LOGIN test_kill; +go +~~ERROR (Code: 33557097)~~ + +~~ERROR (Message: role "test_kill_db1_user_kill" already exists)~~ + + +create database test_kill_db7 +GO +~~ERROR (Code: 33557097)~~ + +~~ERROR (Message: Only one user database allowed under single-db mode. User database "test_kill_db1" already exists)~~ + +use test_kill_db7 +GO +~~ERROR (Code: 911)~~ + +~~ERROR (Message: database "test_kill_db7" does not exist)~~ + +CREATE USER user_kill FOR LOGIN test_kill; +go +~~ERROR (Code: 33557097)~~ + +~~ERROR (Message: role "test_kill_db1_user_kill" already exists)~~ + + +create database test_kill_db8 +GO +~~ERROR (Code: 33557097)~~ + +~~ERROR (Message: Only one user database allowed under single-db mode. User database "test_kill_db1" already exists)~~ + +use test_kill_db8 +GO +~~ERROR (Code: 911)~~ + +~~ERROR (Message: database "test_kill_db8" does not exist)~~ + +CREATE USER user_kill FOR LOGIN test_kill; +go +~~ERROR (Code: 33557097)~~ + +~~ERROR (Message: role "test_kill_db1_user_kill" already exists)~~ + + +create database test_kill_db9 +GO +~~ERROR (Code: 33557097)~~ + +~~ERROR (Message: Only one user database allowed under single-db mode. User database "test_kill_db1" already exists)~~ + +use test_kill_db9 +GO +~~ERROR (Code: 911)~~ + +~~ERROR (Message: database "test_kill_db9" does not exist)~~ + +CREATE USER user_kill FOR LOGIN test_kill; +go +~~ERROR (Code: 33557097)~~ + +~~ERROR (Message: role "test_kill_db1_user_kill" already exists)~~ + + + +create database test_kill_db10 +GO +~~ERROR (Code: 33557097)~~ + +~~ERROR (Message: Only one user database allowed under single-db mode. User database "test_kill_db1" already exists)~~ + +use test_kill_db10 +GO +~~ERROR (Code: 911)~~ + +~~ERROR (Message: database "test_kill_db10" does not exist)~~ + +CREATE USER user_kill FOR LOGIN test_kill; +go +~~ERROR (Code: 33557097)~~ + +~~ERROR (Message: role "test_kill_db1_user_kill" already exists)~~ + + +create database test_kill_db11 +GO +~~ERROR (Code: 33557097)~~ + +~~ERROR (Message: Only one user database allowed under single-db mode. User database "test_kill_db1" already exists)~~ + +use test_kill_db11 +GO +~~ERROR (Code: 911)~~ + +~~ERROR (Message: database "test_kill_db11" does not exist)~~ + +CREATE USER user_kill FOR LOGIN test_kill; +go +~~ERROR (Code: 33557097)~~ + +~~ERROR (Message: role "test_kill_db1_user_kill" already exists)~~ + + +-- tsql user=test_kill password=12345678 database=test_kill_db1 +-- CREATE 11 sessions +SELECT 1 +GO +~~START~~ +int +1 +~~END~~ + + +-- tsql user=test_kill password=12345678 database=test_kill_db2 +~~ERROR (Code: 911)~~ + +~~ERROR (Message: database "test_kill_db2" does not exist )~~ + +SELECT 1 +GO +~~START~~ +int +1 +~~END~~ + + +-- tsql user=test_kill password=12345678 database=test_kill_db3 +~~ERROR (Code: 911)~~ + +~~ERROR (Message: database "test_kill_db3" does not exist )~~ + +SELECT 1 +GO +~~START~~ +int +1 +~~END~~ + + +-- tsql user=test_kill password=12345678 database=test_kill_db4 +~~ERROR (Code: 911)~~ + +~~ERROR (Message: database "test_kill_db4" does not exist )~~ + +SELECT 1 +GO +~~START~~ +int +1 +~~END~~ + + +-- tsql user=test_kill password=12345678 database=test_kill_db5 +~~ERROR (Code: 911)~~ + +~~ERROR (Message: database "test_kill_db5" does not exist )~~ + +SELECT 1 +GO +~~START~~ +int +1 +~~END~~ + + +-- tsql user=test_kill password=12345678 database=test_kill_db6 +~~ERROR (Code: 911)~~ + +~~ERROR (Message: database "test_kill_db6" does not exist )~~ + +SELECT 1 +GO +~~START~~ +int +1 +~~END~~ + + +-- tsql user=test_kill password=12345678 database=test_kill_db7 +~~ERROR (Code: 911)~~ + +~~ERROR (Message: database "test_kill_db7" does not exist )~~ + +SELECT 1 +GO +~~START~~ +int +1 +~~END~~ + + +-- tsql user=test_kill password=12345678 database=test_kill_db8 +~~ERROR (Code: 911)~~ + +~~ERROR (Message: database "test_kill_db8" does not exist )~~ + +SELECT 1 +GO +~~START~~ +int +1 +~~END~~ + + +-- tsql user=test_kill password=12345678 database=test_kill_db9 +~~ERROR (Code: 911)~~ + +~~ERROR (Message: database "test_kill_db9" does not exist )~~ + +SELECT 1 +GO +~~START~~ +int +1 +~~END~~ + + +-- tsql user=test_kill password=12345678 database=test_kill_db10 +~~ERROR (Code: 911)~~ + +~~ERROR (Message: database "test_kill_db10" does not exist )~~ + +SELECT 1 +GO +~~START~~ +int +1 +~~END~~ + + +-- tsql user=test_kill password=12345678 database=test_kill_db11 +~~ERROR (Code: 911)~~ + +~~ERROR (Message: database "test_kill_db11" does not exist )~~ + +SELECT 1 +GO +~~START~~ +int +1 +~~END~~ + + +-- tsql +SELECT count(*) from sys.dm_exec_sessions where login_name = 'test_kill' +GO +~~START~~ +int +1 +~~END~~ + + +SELECT COUNT(*) from pg_stat_activity where usename = 'test_kill' +GO +~~START~~ +int +1 +~~END~~ + + +-- Kill Sessions +USE [MASTER] +DECLARE @UserName NVARCHAR(255) = 'test_kill' +DECLARE @SPID INT +-- Creates temp table to store SPIDs +IF OBJECT_ID('tempdb..#UserSessions') IS NOT NULL +BEGIN +-- dropa tabela se existir +DROP TABLE #UserSessions +END +CREATE TABLE #UserSessions (SPID INT) +-- Inserting SPIDs from User Sessions into the Temporary Table +INSERT INTO #UserSessions (SPID) +SELECT session_id +FROM sys.dm_exec_sessions +WHERE login_name = @UserName +-- Loop to kill user sessions +DECLARE @RowCount INT = (SELECT COUNT(*) FROM #UserSessions) +DECLARE @Counter INT = 1 +DECLARE @CmdKill NVARCHAR(100) +WHILE @Counter <= @RowCount +BEGIN +SELECT TOP 1 @SPID = SPID FROM #UserSessions +SET @CmdKill = 'KILL ' + CAST(@SPID AS NVARCHAR(10)) +execute(@CmdKill) +DELETE FROM #UserSessions WHERE SPID = @SPID +SET @Counter = @Counter + 1 +END +-- Temporary Table Cleaning +DROP TABLE #UserSessions +GO +~~WARNING (Code: 0)~~ + +~~WARNING (Message: Changed database context to 'master'. Server SQLState: S0001)~~ + +~~ROW COUNT: 1~~ + +~~WARNING (Code: 0)~~ + +~~WARNING (Message: Changed database context to 'master'. Server SQLState: S0001)~~ + +~~ROW COUNT: 1~~ + + +-- allow the kill to complete; this might take a while under heavy workload +exec pg_sleep 5 +go + +SELECT count(*) from sys.dm_exec_sessions where login_name = 'test_kill' +GO +~~START~~ +int +0 +~~END~~ + + +SELECT COUNT(*) from pg_stat_activity where usename = 'test_kill' +GO +~~START~~ +int +0 +~~END~~ + diff --git a/test/JDBC/expected/temp_oid.out b/test/JDBC/expected/temp_oid.out index c0cedfe860..508f2ef726 100644 --- a/test/JDBC/expected/temp_oid.out +++ b/test/JDBC/expected/temp_oid.out @@ -3,7 +3,7 @@ show babelfishpg_tsql.temp_oid_buffer_size GO ~~START~~ text -0 +65536 ~~END~~ diff --git a/test/JDBC/expected/temp_table_jdbc.out b/test/JDBC/expected/temp_table_jdbc.out index 015a827d62..e69de29bb2 100644 --- a/test/JDBC/expected/temp_table_jdbc.out +++ b/test/JDBC/expected/temp_table_jdbc.out @@ -1 +0,0 @@ -Cannot create trigger on a temporary object. \ No newline at end of file diff --git a/test/JDBC/input/BABEL-UNSUPPORTED.sql b/test/JDBC/input/BABEL-UNSUPPORTED.sql index acc487bc66..16ba866f4e 100644 --- a/test/JDBC/input/BABEL-UNSUPPORTED.sql +++ b/test/JDBC/input/BABEL-UNSUPPORTED.sql @@ -1657,6 +1657,64 @@ AS EXTERNAL NAME babel_3571 GO +-- create login from windows +-- Add 'dummydomain' domain entry +exec sys.babelfish_add_domain_mapping_entry 'dummydomain', 'dummydomain.babel'; +GO + +CREATE LOGIN [NT Service\MSSQLSERVER] FROM WINDOWS +GO + +CREATE LOGIN [\MSSQLSERVER] FROM WINDOWS +GO + +CREATE LOGIN [NT Servicesomething\MSSQLSERVER] FROM WINDOWS +GO + +CREATE LOGIN [NT ServiceNT Service\MSSQLSERVER] FROM WINDOWS +GO + +CREATE LOGIN [NT ServiceNT SerViCe\MSSQLSERVER] FROM WINDOWS +GO + +CREATE LOGIN [somethingNT Service\MSSQLSERVER] FROM WINDOWS +GO + +CREATE LOGIN [NT Service\NT Service\MSSQLSERVER] FROM WINDOWS +GO + +CREATE LOGIN [NT S\ervice\MSSQLSERVER] FROM WINDOWS +GO + +CREATE LOGIN [NT Service\\MSSQLSERVER] FROM WINDOWS +GO + +CREATE LOGIN ["NT Service"\MSSQLSERVER] FROM WINDOWS +GO + +CREATE LOGIN [[NT Service]\MSSQLSERVER] FROM WINDOWS +GO + +CREATE LOGIN [["NT Service"]\MSSQLSERVER] FROM WINDOWS +GO + +CREATE LOGIN [NT Service\MSSQLSERVER] FROM WINDOWS WITH DEFAULT_DATABASE=[test] +GO + +CREATE LOGIN [NT SerViCe\MSSQLSERVER] FROM WINDOWS WITH DEFAULT_DATABASE=[test] +GO + +CREATE LOGIN [dummydomain\NT Service] FROM WINDOWS +GO + +-- Dropping 'nt service@DUMMYDOMAIN.BABEL' +DROP LOGIN [dummydomain\NT Service] +GO + +-- Remove entry for 'dummydomain' +exec babelfish_remove_domain_mapping_entry 'dummydomain' +GO + -- INSERT BULK is No op. No point in failing this INSERT BULK babel_3571 ( ID INT PRIMARY KEY NOT NULL IDENTITY(1,1), diff --git a/test/JDBC/input/GRANT_SCHEMA.mix b/test/JDBC/input/GRANT_SCHEMA.mix index 5c6e7da53b..b6a8412fa8 100644 --- a/test/JDBC/input/GRANT_SCHEMA.mix +++ b/test/JDBC/input/GRANT_SCHEMA.mix @@ -3277,7 +3277,7 @@ go -- psql -- should have 2 entries for master and babel_4344_d1 databases -select schema_name, object_name, permission, grantee from sys.babelfish_schema_permissions where object_name = 'babel_4344_t1'; +select schema_name, object_name, permission, grantee from sys.babelfish_schema_permissions where object_name = 'babel_4344_t1' ORDER BY grantee; go -- tsql diff --git a/test/JDBC/input/alter/alter-function-schema.mix b/test/JDBC/input/alter/alter-function-schema.mix new file mode 100644 index 0000000000..fb67a7b65e --- /dev/null +++ b/test/JDBC/input/alter/alter-function-schema.mix @@ -0,0 +1,277 @@ +-- Test altering a basic function and an inline tvf function on same schema +-- tsql +create login alter_func_l1 with password = '12345678' +go + +ALTER ROLE sysadmin ADD MEMBER alter_func_l1 +GO + +-- tsql user=alter_func_l1 password=12345678 +create database alter_func_db1 +go + +use alter_func_db1 +go + +create schema alter_func_schema1 +go + +CREATE TABLE alter_func_users_t ([Id] int, [firstname] varchar(50), [lastname] varchar(50), [email] varchar(50)); +CREATE TABLE alter_func_orders_t ([Id] int, [userid] int, [productid] int, [quantity] int, [orderdate] Date); + +INSERT INTO alter_func_users_t VALUES (1, 'j', 'o', 'testemail'), (1, 'e', 'l', 'testemail2'); +INSERT INTO alter_func_orders_t VALUES (1, 1, 1, 5, '2023-06-25'), (2, 1, 1, 6, '2023-06-25'); +go + +create function alter_func_schema1.f1() returns int begin return 2 end +go + +create function alter_func_schema1.f2() returns TABLE as return (select * from alter_func_users_t) +go + +-- psql +select schema_name, object_name, permission, grantee, object_type, function_args, grantor from sys.babelfish_schema_permissions where schema_name = 'alter_func_schema1' collate sys.database_default order by object_name; +go + +-- tsql user=alter_func_l1 password=12345678 +select alter_func_schema1.f1() +go + +select alter_func_schema1.f2() +go + +alter function alter_func_schema1.f1(@param1 int) returns int begin return @param1 end +go + +alter function alter_func_schema1.f2() returns TABLE as return (select * from alter_func_orders_t) +go + +select alter_func_schema1.f1(5) +go + +select alter_func_schema1.f2() +go + +drop function alter_func_schema1.f1 +go + +drop function alter_func_schema1.f2 +go + +drop table alter_func_users_t +go + +drop table alter_func_orders_t +go + +-- psql +select schema_name, object_name, permission, grantee, object_type, function_args, grantor from sys.babelfish_schema_permissions where schema_name = 'alter_func_schema1' collate sys.database_default order by object_name; +go + +-- tsql user=alter_func_l1 password=12345678 +drop schema alter_func_schema1; +go + +use master +go + +drop database alter_func_db1 +go + +-- psql +-- Need to terminate active session before cleaning up the login +SELECT pg_terminate_backend(pid) FROM pg_stat_get_activity(NULL) +WHERE sys.suser_name(usesysid) = 'alter_func_l1' AND backend_type = 'client backend' AND usesysid IS NOT NULL; +go + +-- Wait to sync with another session +SELECT pg_sleep(1); +go + +-- tsql +drop login alter_func_l1; +go + +-- psql currentSchema=master_dbo,public +-- Test defining two functions with same name in psql then attempting to alter in tsql +create function psql_func_f1() +returns int +language plpgsql +as +$$ +DECLARE +BEGIN +return 1; +end; +$$; +go + +create function psql_func_f1(a integer) +returns int +language plpgsql +as +$$ +BEGIN +return a; +end; +$$; +go + +-- psql currentSchema=master_dbo,public +drop function psql_func_f1(a integer) +go + +CREATE TABLE cars ( + brand VARCHAR(255), + model VARCHAR(255), + year INT +); + +INSERT INTO cars (brand, model, year) +VALUES ('Ford', 'Mustang', 1964); +go + +create function psql_func_tvf1() returns table(brand VARCHAR(255), model VARCHAR(255), year INT) +language plpgsql +as $$ +begin + return query +select * from cars; +end; +$$; +go + +select psql_func_tvf1() +go + +-- Test attempting to alter psql functions in tsql +-- tsql +alter function psql_func_f1() returns int begin return 2 end +go + +alter function psql_func_tvf1() returns table +as +return (select * from cars) +go + +-- psql currentSchema=master_dbo,public +drop function psql_func_f1() +go + +drop function psql_func_tvf1() +go + +drop table cars; +go + +-- Test creating two of the same functions on different schemas +-- tsql +create login alter_func_l2 with password = '12345678' +go + +ALTER ROLE sysadmin ADD MEMBER alter_func_l2 +GO + +-- tsql user=alter_func_l2 password=12345678 +create database alter_func_db2 +go + +use alter_func_db2 +go + +create schema alter_func_schema2 +go + +create schema alter_func_schema3 +go + +create function alter_func_schema2.f1() returns int begin return 2 end +go + +create function alter_func_schema3.f1() returns int begin return 2 end +go + +select alter_func_schema2.f1() +go + +select alter_func_schema3.f1() +go + +alter function alter_func_schema2.f1(@param1 int) returns int begin return @param1 end +go + +alter function alter_func_schema3.f1(@param1 int) returns int begin return @param1 end +go + +select alter_func_schema2.f1(5) +go + +select alter_func_schema3.f1(5) +go + +drop function alter_func_schema2.f1(@param1 int) +go + +drop function alter_func_schema3.f1(@param1 int) +go + +drop schema alter_func_schema2 +go + +drop schema alter_func_schema3 +go + +use master +go + +drop database alter_func_db2 +go + +-- psql +-- Need to terminate active session before cleaning up the login +SELECT pg_terminate_backend(pid) FROM pg_stat_get_activity(NULL) +WHERE sys.suser_name(usesysid) = 'alter_func_l2' AND backend_type = 'client backend' AND usesysid IS NOT NULL; +go + +-- Wait to sync with another session +SELECT pg_sleep(1); +go + +-- tsql +drop login alter_func_l2; +go + +-- psql currentSchema=master_dbo,public +-- Test psql functions altered with security definer do not throw StartTransactionCommand: unexpected state STARTED error +create function psql_func_f2() +returns int +language plpgsql +as +$$ +DECLARE +BEGIN +return 1; +end; +$$; + +alter function psql_func_f2() security definer; +go + +drop function psql_func_f2; +go + +set babelfishpg_tsql.sql_dialect = "tsql"; +GO + +create function f1() returns int begin return 2 end +go + +-- Test alter function using tsql dialect in PSQL port throws error +alter function f1() returns int begin return 3 end +go + +drop function f1() +go + +select set_config('babelfishpg_tsql.sql_dialect', 'postgres', null); +go \ No newline at end of file diff --git a/test/JDBC/input/alter/alter-function-vu-cleanup.sql b/test/JDBC/input/alter/alter-function-vu-cleanup.sql new file mode 100644 index 0000000000..20e3a75870 --- /dev/null +++ b/test/JDBC/input/alter/alter-function-vu-cleanup.sql @@ -0,0 +1,22 @@ +drop function alter_func_f1 +go + +drop function alter_func_f2 +go + +drop function alter_func_f3 +go + +drop function alter_func_f4 +go + +drop function alter_func_f5; +go + +drop function alter_func_f6; +go + +drop table alter_func_users +go +drop table alter_func_orders +go \ No newline at end of file diff --git a/test/JDBC/input/alter/alter-function-vu-prepare.sql b/test/JDBC/input/alter/alter-function-vu-prepare.sql new file mode 100644 index 0000000000..b4aea1bfbc --- /dev/null +++ b/test/JDBC/input/alter/alter-function-vu-prepare.sql @@ -0,0 +1,41 @@ +CREATE TABLE alter_func_users ([Id] int, [firstname] varchar(50), [lastname] varchar(50), [email] varchar(50)); +CREATE TABLE alter_func_orders ([Id] int, [userid] int, [productid] int, [quantity] int, [orderdate] Date); + +INSERT INTO alter_func_users VALUES (1, 'j', 'o', 'testemail'), (1, 'e', 'l', 'testemail2'); +INSERT INTO alter_func_orders VALUES (1, 1, 1, 5, '2023-06-25'), (2, 1, 1, 6, '2023-06-25'); +GO + +create function alter_func_f1() returns int begin return 2 end +go + +create function alter_func_f2(@param1 int) returns int begin return @param1 end +go + +create function alter_func_f3(@param1 int) returns int +begin + if (@param1 < 2) + begin + return 1 + end + else + begin + return @param1 + end +end +go + +create function alter_func_f4() returns TABLE as return (select * from alter_func_users) +go + +-- Test Case: Alter function in prepare file +alter function alter_func_f4() returns TABLE as return (select * from alter_func_orders) +go + +select alter_func_f4() +go + +create function alter_func_f5() returns @result TABLE([Id] int) as begin insert @result select 1 return end +go + +create function alter_func_f6(@p1 int, @p2 int=123, @p3 int) returns int as begin return @p1 + @p2 + @p3 end +go \ No newline at end of file diff --git a/test/JDBC/input/alter/alter-function-vu-verify.sql b/test/JDBC/input/alter/alter-function-vu-verify.sql new file mode 100644 index 0000000000..f17b688880 --- /dev/null +++ b/test/JDBC/input/alter/alter-function-vu-verify.sql @@ -0,0 +1,160 @@ +-- Test Case 1: Alter function body +alter function alter_func_f1() returns int begin return 2 end +go + +-- Expect to return 2 +select alter_func_f1() +go + +-- Confirm information schema is correctly updated with "CREATE FUNC [new definition]" +select ROUTINE_NAME, ROUTINE_BODY, ROUTINE_DEFINITION from information_schema.routines where SPECIFIC_NAME LIKE 'alter_func_f1'; +go + +-- Test Case 2: Alter function parameters, body, and return type +ALTER function alter_func_f2(@param2 varchar(10)) returns varchar(10) begin return @param2 end +go + +select alter_func_f2('testing') +go + +-- Confirm information schema is correctly updated with "CREATE FUNC [new definition]" +select ROUTINE_NAME, ROUTINE_BODY, ROUTINE_DEFINITION from information_schema.routines where SPECIFIC_NAME LIKE 'alter_func_f2'; +go + +-- Expect error for no parameter provided +select alter_func_f2() +go + +-- Test Case 3: Expect error for altering func that does not exist +ALTER function alter_fake_func(@param1 int) returns int +begin + return 1 +end +GO + +-- Test Case 4: Alter parameter type and function body +ALTER function alter_func_f2(@param2 int) returns varchar(10) +begin + if (@param2 = 1) + BEGIN + return @param2 + END + + ELSE + BEGIN + return -1 + END +end +go + +select alter_func_f2(1) +go + +select alter_func_f2(2) +go + +-- Confirm information schema is correctly updated with "CREATE FUNC [new definition]" +select ROUTINE_NAME, ROUTINE_BODY, ROUTINE_DEFINITION from information_schema.routines where SPECIFIC_NAME LIKE 'alter_func_f2'; +go + +-- Test Case 5: Transaction - begin, alter func, rollback +-- - expect alter to not go through +BEGIN TRANSACTION +go + +ALTER function alter_func_f2(@param2 varchar(10)) returns varchar(10) begin return @param2 end +go + +ROLLBACK +go + +-- Expect error +select alter_func_f2('test') +go + +-- Expect return 1 +select alter_func_f2(1) +go + +-- Test Case 6: Transaction - begin, alter func, modify row, commit +-- - expect both changes to take place +BEGIN TRANSACTION +GO + +ALTER function alter_func_f2(@param2 varchar(10)) returns varchar(10) begin return @param2 end +go + +INSERT INTO alter_func_users VALUES (3, 'newuser', 'lastname', 'testemail3') +go + +COMMIT +GO + +select alter_func_f2('test') +go + +select * from alter_func_users +go + +-- Confirm information schema is correctly updated with "CREATE FUNC [new definition]" +select ROUTINE_NAME, ROUTINE_BODY, ROUTINE_DEFINITION from information_schema.routines where SPECIFIC_NAME LIKE 'alter_func_f2'; +go + +-- Test Case 7: Transaction - begin, alter func, modify row, commit +-- - expect both changes to not go through +BEGIN TRANSACTION +GO + +alter function alter_func_f2() returns int begin return 2 end +go + +INSERT INTO alter_func_users VALUES (4, 'newest_user', 'lastname3', 'testemail4') +go + +ROLLBACK +GO + +-- Expect error for no parameter +select alter_func_f2() +go + +-- Expect only 3 rows +select * from alter_func_users +go + +-- Test Case 8: Expect error from altering function to select from +-- table row that does not exist +alter function alter_func_f2() returns TABLE +as + return ( + select address from alter_func_users + ) +go + +-- Test Case 9: Expect error for attempting to alter multi statement tvf +-- Alter Func Multi-statement tvf support will be added after BABEL-5149 is resolved +alter function alter_func_f5() +returns @result TABLE(Id int) as begin +insert into @result values (2) +return +end +go + +-- Test Case 10: Expect error for altering function in an illegal way +-- select statements are not allowed in functions not returning a table +alter function alter_func_f3(@param1 int) returns int +begin + select * from alter_func_users + return @param1 +end +go + +-- Test Case 11: Alter function with default values +select alter_func_f6(1, default, 100) +go + +alter function alter_func_f6 (@p1 int = 345, @p2 int=123, @p3 int) returns int as begin return @p1 + @p2 + @p3 end +go + +select alter_func_f6(default, default, 100) +go \ No newline at end of file diff --git a/test/JDBC/input/alter/alter-procedure-15_8-or-16_4-vu-cleanup.sql b/test/JDBC/input/alter/alter-procedure-15_8-or-16_4-vu-cleanup.sql new file mode 100644 index 0000000000..71b54d0e92 --- /dev/null +++ b/test/JDBC/input/alter/alter-procedure-15_8-or-16_4-vu-cleanup.sql @@ -0,0 +1,21 @@ +DROP PROCEDURE alter_proc_p1 +GO + +DROP PROCEDURE alter_proc_p2 +GO + +DROP PROCEDURE alter_proc_p3 +GO + +DROP PROCEDURE alter_proc_p4 +GO + +DROP PROCEDURE alter_proc_p5 +GO + +DROP TABLE alter_proc_users +DROP TABLE alter_proc_orders +GO + +drop function alter_proc_f1 +go \ No newline at end of file diff --git a/test/JDBC/input/alter/alter-procedure-15_8-or-16_4-vu-prepare.sql b/test/JDBC/input/alter/alter-procedure-15_8-or-16_4-vu-prepare.sql new file mode 100644 index 0000000000..4964a86bd1 --- /dev/null +++ b/test/JDBC/input/alter/alter-procedure-15_8-or-16_4-vu-prepare.sql @@ -0,0 +1,45 @@ +CREATE TABLE alter_proc_users ([Id] int, [firstname] varchar(50), [lastname] varchar(50), [email] varchar(50)); +CREATE TABLE alter_proc_orders ([Id] int, [userid] int, [productid] int, [quantity] int, [orderdate] Date); + +INSERT INTO alter_proc_users VALUES (1, 'j', 'o', 'testemail'), (1, 'e', 'l', 'testemail2'); +INSERT INTO alter_proc_orders VALUES (1, 1, 1, 5, '2023-06-25'), (2, 1, 1, 6, '2023-06-25'); +GO + +CREATE PROCEDURE alter_proc_p1 +AS + select * from alter_proc_users +GO + +create procedure alter_proc_p2 +AS + exec alter_proc_p1 +go + +create procedure alter_proc_p3 as select 1 +go + +create procedure alter_proc_p4 as select 1 +go + +create function alter_proc_f1() +returns int +AS BEGIN + return 1 +END + +go + +create procedure alter_proc_p5 as select 10 +go + +alter procedure alter_proc_p5 @dateParam date as select @dateParam +go + +-- Test Case: attempt to alter function, expect error for being unsupported +alter function alter_proc_f1() +returns int +as +BEGIN + return 5 +END +go diff --git a/test/JDBC/input/alter/alter-procedure-15_8-or-16_4-vu-verify.sql b/test/JDBC/input/alter/alter-procedure-15_8-or-16_4-vu-verify.sql new file mode 100644 index 0000000000..64277e060a --- /dev/null +++ b/test/JDBC/input/alter/alter-procedure-15_8-or-16_4-vu-verify.sql @@ -0,0 +1,217 @@ +exec alter_proc_p1 +go + +-- Test Case: Expect error for procedure with same name +CREATE PROCEDURE alter_proc_p1 @param1 int +AS + select * from alter_proc_orders +GO + +-- Test Case: Expect error for altering proc that does not exist +ALTER PROCEDURE alter_fake_proc @param1 int +AS + select * from alter_proc_orders +GO + +-- Test Case: Modify the procedure body, and check information_schema updated with spaces +/* Leading comment not included: BABEL-5140 */ ALTER -- test comment + PROCEDURE alter_proc_p1 +AS + select * from alter_proc_orders +GO + +exec alter_proc_p1 +go + +exec alter_proc_p2 +go + +-- Ensure information schema uses "CREATE" instead of "ALTER" with updated definition +select ROUTINE_NAME, ROUTINE_BODY, ROUTINE_DEFINITION from information_schema.routines where SPECIFIC_NAME LIKE 'alter_proc_p1'; +go + +-- Test Case: Modify the procedure body, add a parameter, use "proc" +-- instead of "procedure" + ALTER /* TEST COMMENT */ + PROC alter_proc_p1 + @param INT +AS + IF (@param = 1) + BEGIN + select * from alter_proc_users + END + + ELSE + BEGIN + select * from alter_proc_orders + END +GO + +exec alter_proc_p1 @param = 1 +GO + +exec alter_proc_p1 @param = 2 +GO + +-- Ensure information schema uses "CREATE" instead of "ALTER" with updated definition +select ROUTINE_NAME, ROUTINE_BODY, ROUTINE_DEFINITION from information_schema.routines where SPECIFIC_NAME LIKE 'alter_proc_p1'; +go + +-- Test Case: Expect error because no parameter provided +exec alter_proc_p2 +go + +-- Test Case: Alter the parameter type and procedure body +ALTER PROCEDURE alter_proc_p1 + @param date +AS + IF (@param = '2020-01-01') + BEGIN + select * from alter_proc_users + END + + ELSE + BEGIN + select * from alter_proc_orders + END +GO + +exec alter_proc_p1 @param = '2020-01-01' +GO + +exec alter_proc_p1 @param = '2020-01-02' +GO + +-- Ensure information schema uses "CREATE" instead of "ALTER" with updated definition +select ROUTINE_NAME, ROUTINE_BODY, ROUTINE_DEFINITION from information_schema.routines where SPECIFIC_NAME LIKE 'alter_proc_p1'; +go + +-- Test Case: Modify the procedure body to call another modified proc +alter procedure alter_proc_p2 +AS + exec alter_proc_p1 @param = '2020-01-01' +GO + +exec alter_proc_p2 +go + +-- Ensure information schema uses "CREATE" instead of "ALTER" with updated definition +select ROUTINE_NAME, ROUTINE_BODY, ROUTINE_DEFINITION from information_schema.routines where SPECIFIC_NAME LIKE 'alter_proc_p2'; +go + +-- Test Case: Transaction - begin, alter, rollback +-- - expect alter to not go through +BEGIN TRANSACTION +go + +alter procedure alter_proc_p3 as select 2 +go + +ROLLBACK +go + +exec alter_proc_p3 +go + +-- Test Case: Transaction - begin, alter proc, modify row, commit +-- - expect both changes to take place +BEGIN TRANSACTION +go + +alter procedure alter_proc_p3 @z int as select 500 + @z +go + +INSERT INTO alter_proc_users VALUES (3, 'newuser', 'lastname', 'testemail3') +go + +COMMIT +GO + +exec alter_proc_p3 @z = 500 +go + +select * from alter_proc_users +go + +-- Ensure information schema uses "CREATE" instead of "ALTER" with updated definition +select ROUTINE_NAME, ROUTINE_BODY, ROUTINE_DEFINITION from information_schema.routines where SPECIFIC_NAME LIKE 'alter_proc_p3'; +go + +-- Test Case: Transaction - begin, alter proc, modify row, commit +-- - expect both changes to not go through + +BEGIN TRANSACTION +go + +alter procedure alter_proc_p3 as select 1000 +go + +INSERT INTO alter_proc_users VALUES (4, 'newest_user', 'lastname3', 'testemail4') +go + +ROLLBACK +GO + +-- Expect this to error with no param provided +exec alter_proc_p3 +go + +select * from alter_proc_users +go + +-- Test Case: Transaction - alter procedure to select from table row that does not exist +-- which would result in error if committed + +BEGIN TRANSACTION +go + +alter procedure alter_proc_p3 as + select fake_column from alter_proc_users +go + +ROLLBACK +GO + +-- Expect this to error with no param provided +exec alter_proc_p3 +go + + +-- Test Case: confirm information_schema.routines is updated properly with comments +alter + +/* + * test comment 1 + */ + +-- test comment 2 + +procedure alter_proc_p4 as select 3 +go + +exec alter_proc_p4 +go + +select ROUTINE_NAME, ROUTINE_BODY, ROUTINE_DEFINITION from information_schema.routines where SPECIFIC_NAME LIKE 'alter_proc_p4'; +go + +-- Test Case: confirm information_schema.routines is updated properly with comments +alter + +-- test comment 1 + +procedure alter_proc_p4 as select 4 +go + +exec alter_proc_p4 +go + +select ROUTINE_NAME, ROUTINE_BODY, ROUTINE_DEFINITION from information_schema.routines where SPECIFIC_NAME LIKE 'alter_proc_p4'; +go + +-- Test Case: confirm procedure altered in 'alter-procedure-vu-prepare' is properly updated +exec alter_proc_p5 @dateParam = '2000-01-01' +go + +select ROUTINE_NAME, ROUTINE_BODY, ROUTINE_DEFINITION from information_schema.routines where SPECIFIC_NAME LIKE 'alter_proc_p4'; +go \ No newline at end of file diff --git a/test/JDBC/input/alter/alter-procedure-before-15_8-or-16_4-vu-prepare.sql b/test/JDBC/input/alter/alter-procedure-before-15_8-or-16_4-vu-prepare.sql index 0e29df5320..9faef12e1d 100644 --- a/test/JDBC/input/alter/alter-procedure-before-15_8-or-16_4-vu-prepare.sql +++ b/test/JDBC/input/alter/alter-procedure-before-15_8-or-16_4-vu-prepare.sql @@ -66,4 +66,13 @@ create procedure alter_proc_p5 as select 10 go alter procedure alter_proc_p5 @dateParam date as select @dateParam -go \ No newline at end of file +go + +-- Test Case: attempt to alter function, expect error for being unsupported +alter function alter_proc_f1() +returns int +as +BEGIN + return 5 +END +go diff --git a/test/JDBC/input/alter/alter-procedure-before-15_8-or-16_4-vu-verify.sql b/test/JDBC/input/alter/alter-procedure-before-15_8-or-16_4-vu-verify.sql index 5a4f19673d..38e6a00e4e 100644 --- a/test/JDBC/input/alter/alter-procedure-before-15_8-or-16_4-vu-verify.sql +++ b/test/JDBC/input/alter/alter-procedure-before-15_8-or-16_4-vu-verify.sql @@ -69,15 +69,6 @@ GO exec alter_proc_p1 @param = '2020-01-02' GO --- Test Case: attempt to alter function, expect error for being unsupported -alter function alter_proc_f1() -returns int -as -BEGIN - return 5 -END -go - -- Test Case: Confirm transaction updates procedure correctly exec alter_proc_p3 @z = 500 go diff --git a/test/JDBC/input/alter/alter-procedure-vu-cleanup.sql b/test/JDBC/input/alter/alter-procedure-vu-cleanup.sql index 71b54d0e92..a505d634af 100644 --- a/test/JDBC/input/alter/alter-procedure-vu-cleanup.sql +++ b/test/JDBC/input/alter/alter-procedure-vu-cleanup.sql @@ -16,6 +16,3 @@ GO DROP TABLE alter_proc_users DROP TABLE alter_proc_orders GO - -drop function alter_proc_f1 -go \ No newline at end of file diff --git a/test/JDBC/input/alter/alter-procedure-vu-prepare.sql b/test/JDBC/input/alter/alter-procedure-vu-prepare.sql index d7d78d6cf4..b2753a5a28 100644 --- a/test/JDBC/input/alter/alter-procedure-vu-prepare.sql +++ b/test/JDBC/input/alter/alter-procedure-vu-prepare.sql @@ -21,14 +21,6 @@ go create procedure alter_proc_p4 as select 1 go -create function alter_proc_f1() -returns int -AS BEGIN - return 1 -END - -go - create procedure alter_proc_p5 as select 10 go diff --git a/test/JDBC/input/alter/alter-procedure-vu-verify.sql b/test/JDBC/input/alter/alter-procedure-vu-verify.sql index aef3b214fa..64277e060a 100644 --- a/test/JDBC/input/alter/alter-procedure-vu-verify.sql +++ b/test/JDBC/input/alter/alter-procedure-vu-verify.sql @@ -99,16 +99,6 @@ go select ROUTINE_NAME, ROUTINE_BODY, ROUTINE_DEFINITION from information_schema.routines where SPECIFIC_NAME LIKE 'alter_proc_p2'; go --- Test Case: attempt to alter function, expect error for being unsupported - -alter function alter_proc_f1() -returns int -as -BEGIN - return 5 -END -go - -- Test Case: Transaction - begin, alter, rollback -- - expect alter to not go through BEGIN TRANSACTION diff --git a/test/JDBC/input/kill-vu-cleanup.mix b/test/JDBC/input/kill-vu-cleanup.mix index 3c34eb7d8a..a94e770e8a 100644 --- a/test/JDBC/input/kill-vu-cleanup.mix +++ b/test/JDBC/input/kill-vu-cleanup.mix @@ -1,3 +1,4 @@ +-- single_db_mode_expected -- tsql DROP LOGIN victim_user_tds go @@ -17,3 +18,29 @@ go DROP TABLE tab_kill_test go +DROP Database test_kill_db1 +GO +DROP Database test_kill_db2 +GO +DROP Database test_kill_db3 +GO +DROP Database test_kill_db4 +GO +DROP Database test_kill_db5 +GO +DROP Database test_kill_db6 +GO +DROP Database test_kill_db7 +GO +DROP Database test_kill_db8 +GO +DROP Database test_kill_db9 +GO +DROP Database test_kill_db10 +GO +DROP Database test_kill_db11 +GO + +DROP LOGIN test_kill; +GO + diff --git a/test/JDBC/input/kill-vu-verify.mix b/test/JDBC/input/kill-vu-verify.mix index 39c8e18ca4..784f86c86f 100644 --- a/test/JDBC/input/kill-vu-verify.mix +++ b/test/JDBC/input/kill-vu-verify.mix @@ -1,3 +1,4 @@ +-- single_db_mode_expected -- tsql create table tab_kill_spid(spid int) go @@ -225,3 +226,181 @@ SELECT @@TRANCOUNT go SELECT * FROM tab_kill_test go + +-- BABEL-5219 Multiple Session Kill +-- tsql +CREATE LOGIN test_kill WITH PASSWORD = '12345678' +GO + +-- CREATE 11 Databases +create database test_kill_db1 +GO +use test_kill_db1 +GO +CREATE USER user_kill FOR LOGIN test_kill; +go + +create database test_kill_db2 +GO +use test_kill_db2 +GO +CREATE USER user_kill FOR LOGIN test_kill; +go + +create database test_kill_db3 +GO +use test_kill_db3 +GO +CREATE USER user_kill FOR LOGIN test_kill; +go + +create database test_kill_db4 +GO +use test_kill_db4 +GO +CREATE USER user_kill FOR LOGIN test_kill; +go + +create database test_kill_db5 +GO +use test_kill_db5 +GO +CREATE USER user_kill FOR LOGIN test_kill; +go + +create database test_kill_db6 +GO +use test_kill_db6 +GO +CREATE USER user_kill FOR LOGIN test_kill; +go + +create database test_kill_db7 +GO +use test_kill_db7 +GO +CREATE USER user_kill FOR LOGIN test_kill; +go + +create database test_kill_db8 +GO +use test_kill_db8 +GO +CREATE USER user_kill FOR LOGIN test_kill; +go + +create database test_kill_db9 +GO +use test_kill_db9 +GO +CREATE USER user_kill FOR LOGIN test_kill; +go + + +create database test_kill_db10 +GO +use test_kill_db10 +GO +CREATE USER user_kill FOR LOGIN test_kill; +go + +create database test_kill_db11 +GO +use test_kill_db11 +GO +CREATE USER user_kill FOR LOGIN test_kill; +go + +-- CREATE 11 sessions +-- tsql user=test_kill password=12345678 database=test_kill_db1 +SELECT 1 +GO + +-- tsql user=test_kill password=12345678 database=test_kill_db2 +SELECT 1 +GO + +-- tsql user=test_kill password=12345678 database=test_kill_db3 +SELECT 1 +GO + +-- tsql user=test_kill password=12345678 database=test_kill_db4 +SELECT 1 +GO + +-- tsql user=test_kill password=12345678 database=test_kill_db5 +SELECT 1 +GO + +-- tsql user=test_kill password=12345678 database=test_kill_db6 +SELECT 1 +GO + +-- tsql user=test_kill password=12345678 database=test_kill_db7 +SELECT 1 +GO + +-- tsql user=test_kill password=12345678 database=test_kill_db8 +SELECT 1 +GO + +-- tsql user=test_kill password=12345678 database=test_kill_db9 +SELECT 1 +GO + +-- tsql user=test_kill password=12345678 database=test_kill_db10 +SELECT 1 +GO + +-- tsql user=test_kill password=12345678 database=test_kill_db11 +SELECT 1 +GO + +-- tsql +SELECT count(*) from sys.dm_exec_sessions where login_name = 'test_kill' +GO + +SELECT COUNT(*) from pg_stat_activity where usename = 'test_kill' +GO + +-- Kill Sessions +USE [MASTER] +DECLARE @UserName NVARCHAR(255) = 'test_kill' +DECLARE @SPID INT +-- Creates temp table to store SPIDs +IF OBJECT_ID('tempdb..#UserSessions') IS NOT NULL +BEGIN +-- dropa tabela se existir +DROP TABLE #UserSessions +END +CREATE TABLE #UserSessions (SPID INT) +-- Inserting SPIDs from User Sessions into the Temporary Table +INSERT INTO #UserSessions (SPID) +SELECT session_id +FROM sys.dm_exec_sessions +WHERE login_name = @UserName +-- Loop to kill user sessions +DECLARE @RowCount INT = (SELECT COUNT(*) FROM #UserSessions) +DECLARE @Counter INT = 1 +DECLARE @CmdKill NVARCHAR(100) +WHILE @Counter <= @RowCount +BEGIN +SELECT TOP 1 @SPID = SPID FROM #UserSessions +SET @CmdKill = 'KILL ' + CAST(@SPID AS NVARCHAR(10)) +execute(@CmdKill) +DELETE FROM #UserSessions WHERE SPID = @SPID +SET @Counter = @Counter + 1 +END +-- Temporary Table Cleaning +DROP TABLE #UserSessions +GO + +-- allow the kill to complete; this might take a while under heavy workload +exec pg_sleep 5 +go + +SELECT count(*) from sys.dm_exec_sessions where login_name = 'test_kill' +GO + +SELECT COUNT(*) from pg_stat_activity where usename = 'test_kill' +GO \ No newline at end of file diff --git a/test/JDBC/jdbc_schedule b/test/JDBC/jdbc_schedule index 9f6416b2a3..795c4f4e0e 100644 --- a/test/JDBC/jdbc_schedule +++ b/test/JDBC/jdbc_schedule @@ -369,6 +369,11 @@ ignore#!#alter-procedure-before-15_8-or-16_4-vu-prepare ignore#!#alter-procedure-before-15_8-or-16_4-vu-verify ignore#!#alter-procedure-before-15_8-or-16_4-vu-cleanup + +# These tests are meant for upgrade scenario prior to 15_9 or 16_5 release +ignore#!#alter-procedure-15_8-or-16_4-vu-prepare +ignore#!#alter-procedure-15_8-or-16_4-vu-verify +ignore#!#alter-procedure-15_8-or-16_4-vu-cleanup ignore#!#string_agg-before-15_9-or-16_5-vu-prepare ignore#!#string_agg-before-15_9-or-16_5-vu-verify ignore#!#string_agg-before-15_9-or-16_5-vu-cleanup @@ -378,3 +383,4 @@ ignore#!#string_agg-before-14_5-vu-cleanup ignore#!#string_agg_within-16_4-vu-prepare ignore#!#string_agg_within-16_4-vu-verify ignore#!#string_agg_within-16_4-vu-cleanup + diff --git a/test/JDBC/src/main/java/com/sqlsamples/JDBCTempTable.java b/test/JDBC/src/main/java/com/sqlsamples/JDBCTempTable.java index f115e522e8..82e3785c71 100644 --- a/test/JDBC/src/main/java/com/sqlsamples/JDBCTempTable.java +++ b/test/JDBC/src/main/java/com/sqlsamples/JDBCTempTable.java @@ -28,11 +28,13 @@ public static void runTest(BufferedWriter bw, Logger logger) { long startTime = System.nanoTime(); try { - // TODO: re-enable the temp table OID tests when the full fix is ready - // check_oids_equal(bw); - // test_oid_buffer(bw, logger); - // concurrency_test(bw); - // psql_test(bw, logger); + if (check_temp_oid_buffer_enabled(bw, logger)) { + check_oids_equal(bw); + test_oid_buffer(bw, logger); + psql_test(bw, logger); + test_lock_contention(bw, logger); + } + concurrency_test(bw); test_trigger_on_temp_table(bw, logger); } catch (Exception e) { try { @@ -46,6 +48,21 @@ public static void runTest(BufferedWriter bw, Logger logger) { curr_exec_time = endTime - startTime; } + private static boolean check_temp_oid_buffer_enabled(BufferedWriter bw, Logger logger) throws Exception { + String temp_oid_buffer_size = "babelfishpg_tsql.temp_oid_buffer_size"; + Connection c = DriverManager.getConnection(connectionString); + JDBCCrossDialect cx = new JDBCCrossDialect(c); + Connection psql = cx.getPsqlConnection("-- psql", bw, logger); + Statement check_guc = psql.createStatement(); + ResultSet rs = check_guc.executeQuery("SHOW " + temp_oid_buffer_size); + if (!rs.next()) { + bw.write("Table is missing."); + bw.newLine(); + } + int buffer_size = Integer.parseInt(rs.getString(temp_oid_buffer_size)); + return buffer_size != 0; + } + /* * Helper function that creates the specified number of connections, creates a temp table on each connection, and returns whether all the OIDs are equal or not. */ @@ -320,8 +337,14 @@ private static void test_trigger_on_temp_table(BufferedWriter bw, Logger logger) queryString = "CREATE TABLE #t1(a int)"; s.execute(queryString); queryString = "CREATE TRIGGER bar ON #t1 FOR INSERT AS BEGIN SELECT 1 END"; - s.execute(queryString); - + try { + s.execute(queryString); + } catch (Exception e) { + if (!e.getMessage().equals("Cannot create trigger on a temporary object.")) { + bw.write(e.getMessage()); + bw.newLine(); + } + } Connection c2 = connections.get(1); s = c2.createStatement(); queryString = "DROP TRIGGER bar"; @@ -334,6 +357,65 @@ private static void test_trigger_on_temp_table(BufferedWriter bw, Logger logger) } } } + + private static void test_lock_contention(BufferedWriter bw, Logger logger) throws Exception { + String connectionString = initializeConnectionString(); + + /* Sanity check of pg_locks catalog */ + Connection c = DriverManager.getConnection(connectionString); + Statement s = c.createStatement(); + ResultSet rs; + s.execute("BEGIN TRAN"); + s.execute("CREATE TABLE #t1 (a INT)"); + rs = s.executeQuery("SELECT relation FROM pg_locks JOIN sys.babelfish_get_enr_list() ON (relation = reloid) where relname = '#t1'"); + if (rs.next()) { + bw.write("Unexpected lock acquisition on a TSQL temp table.\n"); + } + s.execute("ALTER TABLE #t1 ADD b AS a + 1"); + rs = s.executeQuery("SELECT relation FROM pg_locks JOIN sys.babelfish_get_enr_list() ON (relation = reloid) where relname = '#t1'"); + if (rs.next()) { + bw.write("Unexpected lock acquisition on a TSQL temp table.\n"); + } + s.execute("ALTER TABLE #t1 DROP COLUMN b"); + rs = s.executeQuery("SELECT relation FROM pg_locks JOIN sys.babelfish_get_enr_list() ON (relation = reloid) where relname = '#t1'"); + if (rs.next()) { + bw.write("Unexpected lock acquisition on a TSQL temp table.\n"); + } + s.execute("DROP TABLE #t1"); + rs = s.executeQuery("SELECT relation FROM pg_locks JOIN sys.babelfish_get_enr_list() ON (relation = reloid) where relname = '#t1'"); + if (rs.next()) { + bw.write("Unexpected lock acquisition on a TSQL temp table.\n"); + } + c.close(); + + int num_connections = 2; + + ArrayList cxns = new ArrayList<>(); + + ArrayList threads = new ArrayList<>(); + + /* Create connections */ + for (int i = 0; i < num_connections; i++) { + Connection connection = DriverManager.getConnection(connectionString); + cxns.add(connection); + Thread t = new Thread(new LockContentionWorker(connection, bw)); + threads.add(t); + t.start(); + } + + /* + * Unfortunately, setQueryTimeout (used in the worker thread) does not always work correctly. + * So we need to manaully try to detect a hanging thread. + */ + Thread.sleep(1000); + for (Thread t : threads) + { + if (t.isAlive()) { + bw.write("Lock contention detected.\n"); + return; + } + } + } } class Worker implements Runnable { @@ -381,4 +463,31 @@ public void run() { e.printStackTrace(); } } +} + +class LockContentionWorker implements Runnable { + + private Connection c; + private BufferedWriter bw; + + LockContentionWorker(Connection c, BufferedWriter bw) { + this.c = c; + this.bw = bw; + } + + public void run() { + try { + try { + Statement s = c.createStatement(); + s.setQueryTimeout(1); + s.execute("BEGIN TRAN;"); + s.execute("CREATE TABLE #temp_table1 (a int primary key not null identity, b as a + 1, c text);"); + } catch (Exception e) { + bw.write(e.getMessage()); + bw.newLine(); + } + } catch (IOException e) { + e.printStackTrace(); + } + } } \ No newline at end of file diff --git a/test/JDBC/target/JDBC-testsuite-1.0.0.jar b/test/JDBC/target/JDBC-testsuite-1.0.0.jar new file mode 100644 index 0000000000..80377cab5f Binary files /dev/null and b/test/JDBC/target/JDBC-testsuite-1.0.0.jar differ diff --git a/test/JDBC/upgrade/15_8/schedule b/test/JDBC/upgrade/15_8/schedule index 55266cf2c0..7c0549cad4 100644 --- a/test/JDBC/upgrade/15_8/schedule +++ b/test/JDBC/upgrade/15_8/schedule @@ -537,6 +537,7 @@ replicate string_agg-before-15_9-or-16_5 space replace +alter-procedure-15_8-or-16_4 binary-datatype-operators cast-varchar-to-time diff --git a/test/JDBC/upgrade/16_4/schedule b/test/JDBC/upgrade/16_4/schedule index 6fef4112ae..e1cf508fb2 100644 --- a/test/JDBC/upgrade/16_4/schedule +++ b/test/JDBC/upgrade/16_4/schedule @@ -526,7 +526,7 @@ babel-4475 babel-3254 babel-4517 babel_table_type -alter-procedure +alter-procedure-15_8-or-16_4 1_GRANT_SCHEMA BABEL-4707 BABEL_4817 diff --git a/test/JDBC/upgrade/latest/schedule b/test/JDBC/upgrade/latest/schedule index 15729b6ecf..f56a5f4b77 100644 --- a/test/JDBC/upgrade/latest/schedule +++ b/test/JDBC/upgrade/latest/schedule @@ -527,6 +527,7 @@ babel-3254 babel-4517 babel_table_type alter-procedure +alter-function 1_GRANT_SCHEMA BABEL-4707 BABEL_4817 diff --git a/test/dotnet/dotnet.csproj b/test/dotnet/dotnet.csproj index c5e9aed6b8..a45cff35d1 100644 --- a/test/dotnet/dotnet.csproj +++ b/test/dotnet/dotnet.csproj @@ -10,7 +10,7 @@ - +