diff --git a/contrib/babelfishpg_common/src/typecode.c b/contrib/babelfishpg_common/src/typecode.c index c988e63ec16..60d21629e3c 100644 --- a/contrib/babelfishpg_common/src/typecode.c +++ b/contrib/babelfishpg_common/src/typecode.c @@ -53,6 +53,11 @@ type_info_t type_infos[TOTAL_TYPECODE_COUNT] = {0, 1, "rowversion", "timestamp", 8, 32, 3}, {0, 1, "timestamp", "timestamp", 8, 33, 3}, {0, 1, "vector", "vector", 9, 34, 3} + /* + * Geospatial types cannot be stored in SQL variant so setting sqlvariant header size to 1 + */ + {0, 1, "geometry", "geometry", 5, 34, 1}, + {0, 1, "geography", "geography", 5, 35, 1} }; /* Hash tables to help backward searching (from OID to Persist ID) */ diff --git a/contrib/babelfishpg_common/src/typecode.h b/contrib/babelfishpg_common/src/typecode.h index e74be5ee1f8..71ccb9bbad4 100644 --- a/contrib/babelfishpg_common/src/typecode.h +++ b/contrib/babelfishpg_common/src/typecode.h @@ -45,7 +45,7 @@ #define FIXEDDECIMAL_MULTIPLIER 10000LL #endif -#define TOTAL_TYPECODE_COUNT 34 +#define TOTAL_TYPECODE_COUNT 36 struct Node; diff --git a/contrib/babelfishpg_tds/error_mapping.txt b/contrib/babelfishpg_tds/error_mapping.txt index 442f490f704..f87297c06e2 100644 --- a/contrib/babelfishpg_tds/error_mapping.txt +++ b/contrib/babelfishpg_tds/error_mapping.txt @@ -185,5 +185,5 @@ XX000 ERRCODE_INTERNAL_ERROR "The table-valued parameter \"%s\" must be declared 22023 ERRCODE_INVALID_PARAMETER_VALUE "The datepart %s is not supported by date function %s for data type %s." SQL_ERROR_9810 16 22008 ERRCODE_DATETIME_VALUE_OUT_OF_RANGE "Adding a value to a \'%s\' column caused an overflow." SQL_ERROR_517 16 42P01 ERRCODE_UNDEFINED_TABLE "FOR JSON AUTO requires at least one table for generating JSON objects. Use FOR JSON PATH or add a FROM clause with a table name." SQL_ERROR_13600 16 -42P01 ERRCODE_FEATURE_NOT_SUPPORTED "Values for json auto is not currently supported." SQL_ERROR_13600 16 +42P01 ERRCODE_FEATURE_NOT_SUPPORTED "sub-select and values for json auto are not currently supported." SQL_ERROR_13600 16 diff --git a/contrib/babelfishpg_tds/src/backend/tds/tdsresponse.c b/contrib/babelfishpg_tds/src/backend/tds/tdsresponse.c index e3017bc1bd4..018a85ef155 100644 --- a/contrib/babelfishpg_tds/src/backend/tds/tdsresponse.c +++ b/contrib/babelfishpg_tds/src/backend/tds/tdsresponse.c @@ -2773,7 +2773,13 @@ TdsPrintTup(TupleTableSlot *slot, DestReceiver *self) * NBCROW (0xD2). Count the number of nullable columns and build the * null bitmap just in case while we are at it. */ - nullMapSize = (natts + 7) / 8; + + if (sendRowStat) + /* Extra bit for the ROWSTAT column */ + nullMapSize = (natts + 1 + 7) >> 3; + else + nullMapSize = (natts + 7) >> 3; + nullMap = palloc0(nullMapSize); MemSet(nullMap, 0, nullMapSize * sizeof(int8_t)); for (attno = 0; attno < natts; attno++) diff --git a/contrib/babelfishpg_tds/src/backend/tds/tdsrpc.c b/contrib/babelfishpg_tds/src/backend/tds/tdsrpc.c index 1e960cc1a1c..e6a29a980c4 100644 --- a/contrib/babelfishpg_tds/src/backend/tds/tdsrpc.c +++ b/contrib/babelfishpg_tds/src/backend/tds/tdsrpc.c @@ -151,6 +151,8 @@ static void SPPrepExec(TDSRequestSP req); static void SPCustomType(TDSRequestSP req); static void SPUnprepare(TDSRequestSP req); static void TDSLogStatementCursorHandler(TDSRequestSP req, char *stmt, int option); +static void LogStatementNoError(const char *header, const int handle, const char *msg, const uint16 nparams); + static InlineCodeBlockArgs *DeclareVariables(TDSRequestSP req, FunctionCallInfo *fcinfo, unsigned long options); List *tvp_lookup_list = NIL; bool lockForFaultInjection = false; @@ -580,35 +582,7 @@ SPExecuteSQL(TDSRequestSP req) /* command type - execute (0xe0) */ TdsSendDone(TDS_TOKEN_DONEPROC, TDS_DONE_FINAL, 0xe0, 0); - /* - * Log immediately if dictated by log_statement - */ - if (pltsql_plugin_handler_ptr->stmt_needs_logging || TDS_DEBUG_ENABLED(TDS_DEBUG2)) - { - - ErrorContextCallback *plerrcontext = error_context_stack; - - error_context_stack = plerrcontext->previous; - - /* In certain cases TVP can throw error for errdetail_params. */ - PG_TRY(); - { - ereport(LOG, - (errmsg("sp_executesql statement: %s", s.data), - errhidestmt(true), - errdetail_params(req->nTotalParams))); - } - PG_CATCH(); - { - ereport(LOG, - (errmsg("sp_executesql statement: %s", s.data), - errhidestmt(true))); - } - PG_END_TRY(); - - pltsql_plugin_handler_ptr->stmt_needs_logging = false; - error_context_stack = plerrcontext; - } + LogStatementNoError("sp_executesql:", -1, s.data, req->nTotalParams); /* * Print TDS log duration, if log_duration is set @@ -796,34 +770,7 @@ SPExecute(TDSRequestSP req) /* Command type - execute (0xe0). */ TdsSendDone(TDS_TOKEN_DONEPROC, TDS_DONE_FINAL, 0xe0, 0); - /* - * Log immediately if dictated by log_statement - */ - if (pltsql_plugin_handler_ptr->stmt_needs_logging || TDS_DEBUG_ENABLED(TDS_DEBUG2)) - { - ErrorContextCallback *plerrcontext = error_context_stack; - - error_context_stack = plerrcontext->previous; - - /* In certain cases TVP can throw error for errdetail_params. */ - PG_TRY(); - { - ereport(LOG, - (errmsg("sp_execute handle: %d", req->handle), - errhidestmt(true), - errdetail_params(req->nTotalParams))); - } - PG_CATCH(); - { - ereport(LOG, - (errmsg("sp_execute handle: %d", req->handle), - errhidestmt(true))); - } - PG_END_TRY(); - - pltsql_plugin_handler_ptr->stmt_needs_logging = false; - error_context_stack = plerrcontext; - } + LogStatementNoError("sp_execute", req->handle, "", req->nTotalParams); /* * Print TDS log duration, if log_duration is set @@ -938,36 +885,7 @@ SPPrepExec(TDSRequestSP req) /* command type - execute (0xe0) */ TdsSendDone(TDS_TOKEN_DONEPROC, TDS_DONE_FINAL, 0xe0, 0); - /* - * Log immediately if dictated by log_statement - */ - if (pltsql_plugin_handler_ptr->stmt_needs_logging || TDS_DEBUG_ENABLED(TDS_DEBUG2)) - { - ErrorContextCallback *plerrcontext = error_context_stack; - - error_context_stack = plerrcontext->previous; - - /* In certain cases TVP can throw error for errdetail_params. */ - PG_TRY(); - { - ereport(LOG, - (errmsg("sp_prepexec handle: %d, " - "statement: %s", req->handle, s.data), - errhidestmt(true), - errdetail_params(req->nTotalParams))); - } - PG_CATCH(); - { - ereport(LOG, - (errmsg("sp_prepexec handle: %d, " - "statement: %s", req->handle, s.data), - errhidestmt(true))); - } - PG_END_TRY(); - - pltsql_plugin_handler_ptr->stmt_needs_logging = false; - error_context_stack = plerrcontext; - } + LogStatementNoError("sp_prepexec", req->handle, s.data, req->nTotalParams); /* * Print TDS log duration, if log_duration is set @@ -1190,34 +1108,7 @@ SPCustomType(TDSRequestSP req) /* command type - execute (0xe0) */ TdsSendDone(TDS_TOKEN_DONEPROC, TDS_DONE_FINAL, 0xe0, 0); - /* - * Log immediately if dictated by log_statement - */ - if (pltsql_plugin_handler_ptr->stmt_needs_logging || TDS_DEBUG_ENABLED(TDS_DEBUG2)) - { - ErrorContextCallback *plerrcontext = error_context_stack; - - error_context_stack = plerrcontext->previous; - - /* In certain cases TVP can throw error for errdetail_params. */ - PG_TRY(); - { - ereport(LOG, - (errmsg("stored procedure: %s", req->name.data), - errhidestmt(true), - errdetail_params(req->nTotalParams))); - } - PG_CATCH(); - { - ereport(LOG, - (errmsg("stored procedure: %s", req->name.data), - errhidestmt(true))); - } - PG_END_TRY(); - - pltsql_plugin_handler_ptr->stmt_needs_logging = false; - error_context_stack = plerrcontext; - } + LogStatementNoError("stored procedure:", -1, req->name.data, req->nTotalParams); /* * Print TDS log duration, if log_duration is set @@ -4025,11 +3916,11 @@ TDSLogStatementCursorHandler(TDSRequestSP req, char *stmt, int option) if (pltsql_plugin_handler_ptr->stmt_needs_logging || TDS_DEBUG_ENABLED(TDS_DEBUG2)) { ErrorContextCallback *plerrcontext = error_context_stack; - error_context_stack = plerrcontext->previous; switch (option) { + case PRINT_CURSOR_HANDLE: ereport(LOG, (errmsg("sp_cursor handle: %d; statement: %s", @@ -4050,6 +3941,7 @@ TDSLogStatementCursorHandler(TDSRequestSP req, char *stmt, int option) req->cursorHandle, req->cursorPreparedHandle, stmt), errhidestmt(true), errdetail_params(req->nTotalParams))); + break; default: break; @@ -4062,3 +3954,42 @@ TDSLogStatementCursorHandler(TDSRequestSP req, char *stmt, int option) /* Print TDS log duration, if log_duration is set */ TDSLogDuration(stmt); } + +/* + * Log msg ignoring any error during ereport. + * This should only be called when it is safe to call FlushErrorState + * ie: ignoring any previous error that happened prior + * */ +static void LogStatementNoError(const char *header, const int handle, const char *msg, const uint16 nparams) +{ + MemoryContext curr = CurrentMemoryContext; + + ErrorContextCallback *plerrcontext = error_context_stack; + error_context_stack = plerrcontext->previous; + + if (pltsql_plugin_handler_ptr->stmt_needs_logging || TDS_DEBUG_ENABLED(TDS_DEBUG2)) + { + PG_TRY(); + { + ereport(LOG, + (errmsg("%s handle: %d " + "statement: %s", + header, handle, msg), + errhidestmt(true), + errdetail_params(nparams))); + } + PG_CATCH(); + { + MemoryContextSwitchTo(curr); + FlushErrorState(); + + ereport(LOG, + (errmsg("%s statement: %s", header, msg), + errhidestmt(true))); + } + PG_END_TRY(); + } + + pltsql_plugin_handler_ptr->stmt_needs_logging = false; + error_context_stack = plerrcontext; +} diff --git a/contrib/babelfishpg_tsql/antlr/TSqlLexer.g4 b/contrib/babelfishpg_tsql/antlr/TSqlLexer.g4 index 9b0505f8c26..f3fe695a649 100644 --- a/contrib/babelfishpg_tsql/antlr/TSqlLexer.g4 +++ b/contrib/babelfishpg_tsql/antlr/TSqlLexer.g4 @@ -506,6 +506,9 @@ LAG: L A G; LANGUAGE: L A N G U A G E; LAST: L A S T; LAST_VALUE: L A S T UNDERLINE V A L U E; +LAT: 'Lat'; +LAT_DOUBLE_QUOTE: ["] LAT ["] {pltsql_quoted_identifier == true}?; +LAT_SQBRACKET: '[' LAT ']'; LEAD: L E A D; LEDGER: L E D G E R; LEFT: L E F T; @@ -531,6 +534,9 @@ LOCK_ESCALATION: L O C K UNDERLINE E S C A L A LOG: L O G; LOG10: L O G '10'; LOGIN: L O G I N; +LONG: 'Long'; +LONG_DOUBLE_QUOTE: ["] LONG ["] {pltsql_quoted_identifier == true}?; +LONG_SQBRACKET: '[' LONG ']'; LOOP: L O O P; LOW: L O W; MANUAL: M A N U A L; @@ -933,6 +939,8 @@ START: S T A R T; STARTED: S T A R T E D; STARTUP_STATE: S T A R T U P UNDERLINE S T A T E; START_DATE: S T A R T UNDERLINE D A T E; +STASBINARY: 'STAsBinary'; +STASTEXT: 'STAsText'; STATE: S T A T E; STATEMENT: S T A T E M E N T; STATIC: S T A T I C; @@ -944,6 +952,7 @@ STATUS: S T A T U S; STATUSONLY: S T A T U S O N L Y; STDEV: S T D E V; STDEVP: S T D E V P; +STDISTANCE: 'STDistance'; STOP: S T O P; STOPAT: S T O P A T; STOPATMARK: S T O P A T M A R K; @@ -954,6 +963,12 @@ STOP_ON_ERROR: S T O P UNDERLINE O N UNDERL STRING_AGG: S T R I N G UNDERLINE A G G; STRING_DELIMITER: S T R I N G UNDERLINE D E L I M I T E R; STUFF: S T U F F; +STX: 'STX'; +STX_DOUBLE_QUOTE: ["] STX ["] {pltsql_quoted_identifier == true}?; +STX_SQBRACKET: '[' STX ']'; +STY: 'STY'; +STY_DOUBLE_QUOTE: ["] STY ["] {pltsql_quoted_identifier == true}?; +STY_SQBRACKET: '[' STY ']'; SUBJECT: S U B J E C T; SUBSCRIBE: S U B S C R I B E; SUBSCRIPTION: S U B S C R I P T I O N; diff --git a/contrib/babelfishpg_tsql/antlr/TSqlParser.g4 b/contrib/babelfishpg_tsql/antlr/TSqlParser.g4 index e7c64c0d3cc..5e7c71f6b01 100644 --- a/contrib/babelfishpg_tsql/antlr/TSqlParser.g4 +++ b/contrib/babelfishpg_tsql/antlr/TSqlParser.g4 @@ -3773,6 +3773,7 @@ function_call : ranking_windowed_function | aggregate_windowed_function | analytic_windowed_function + | spatial_proc_name_server_database_schema LR_BRACKET function_arg_list? RR_BRACKET | func_proc_name_server_database_schema LR_BRACKET allOrDistinct=(DISTINCT|ALL)? function_arg_list? RR_BRACKET | built_in_functions | freetext_function @@ -3857,11 +3858,34 @@ trigger_column_updated : UPDATE LR_BRACKET full_column_name RR_BRACKET ; -spatial_methods // we could expand the entire list here, but it is very long - : method=id (LR_BRACKET expression_list? RR_BRACKET)? - | NULL_P // no bracket +spatial_methods + : ( geospatial_col | geospatial_func_no_arg | geospatial_func_arg ) (LR_BRACKET expression_list? RR_BRACKET)? ; +geospatial_col + : STX + | STX_SQBRACKET + | STX_DOUBLE_QUOTE + | STY + | STY_SQBRACKET + | STY_DOUBLE_QUOTE + | LAT + | LAT_SQBRACKET + | LAT_DOUBLE_QUOTE + | LONG + | LONG_SQBRACKET + | LONG_DOUBLE_QUOTE + ; + +geospatial_func_no_arg + : STASTEXT + | STASBINARY + ; + +geospatial_func_arg + : STDISTANCE + ; + hierarchyid_methods : method=( GETANCESTOR | GETDESCENDANT | GETLEVEL | ISDESCENDANTOF | READ | GETREPARENTEDVALUE | TOSTRING ) LR_BRACKET expression_list? RR_BRACKET ; @@ -4598,6 +4622,9 @@ keyword | LANGUAGE | LAST | LAST_VALUE + | LAT + | LAT_DOUBLE_QUOTE + | LAT_SQBRACKET | LEAD | LEDGER | LEFT @@ -4621,6 +4648,9 @@ keyword | LOG | LOG10 | LOGIN + | LONG + | LONG_DOUBLE_QUOTE + | LONG_SQBRACKET | LOOP | LOW | MANUAL @@ -4959,6 +4989,8 @@ keyword | STARTED | STARTUP_STATE | START_DATE + | STASBINARY + | STASTEXT | STATE | STATEMENT | STATIC @@ -4969,6 +5001,7 @@ keyword | STATUSONLY | STDEV | STDEVP + | STDISTANCE | STOP | STOPAT | STOPATMARK @@ -4979,6 +5012,12 @@ keyword | STRING_AGG | STRING_DELIMITER | STUFF + | STX + | STX_DOUBLE_QUOTE + | STX_SQBRACKET + | STY + | STY_DOUBLE_QUOTE + | STY_SQBRACKET | SUBJECT | SUBSCRIBE | SUBSCRIPTION @@ -5129,6 +5168,10 @@ func_proc_name_database_schema | (schema=id? DOT)? procedure=id ; +spatial_proc_name_server_database_schema + : ((schema=id? DOT)? table=id? DOT)? column=id DOT ( geospatial_func_no_arg | geospatial_func_arg ) + ; + func_proc_name_server_database_schema : (server=id? DOT)? database=id? DOT schema=id? DOT procedure=id | (schema=id? DOT)? procedure=id @@ -5149,7 +5192,8 @@ collation ; full_column_name - : (((server=id? DOT)? schema=id? DOT)? tablename=id? DOT)? column_name=id + : ((schema=id? DOT)? table=id? DOT)? column=id DOT geospatial_col + | (((server=id? DOT)? schema=id? DOT)? tablename=id? DOT)? column_name=id ; column_name_list_with_order diff --git a/contrib/babelfishpg_tsql/runtime/functions.c b/contrib/babelfishpg_tsql/runtime/functions.c index 1bf565d02a5..34f3418219f 100644 --- a/contrib/babelfishpg_tsql/runtime/functions.c +++ b/contrib/babelfishpg_tsql/runtime/functions.c @@ -2091,6 +2091,10 @@ object_id(PG_FUNCTION_ARGS) { result = enr->md.reliddesc; } + else if (enr == NULL) + { + result = get_relname_relid((const char *) object_name, LookupNamespaceNoError("pg_temp")); + } } else if (!strcmp(object_type, "r") || !strcmp(object_type, "ec") || !strcmp(object_type, "pg") || !strcmp(object_type, "sn") || !strcmp(object_type, "sq") || !strcmp(object_type, "tt")) @@ -2156,6 +2160,10 @@ object_id(PG_FUNCTION_ARGS) if (enr != NULL && enr->md.enrtype == ENR_TSQL_TEMP) { result = enr->md.reliddesc; + } + else if (enr == NULL) + { + result = get_relname_relid((const char *) object_name, LookupNamespaceNoError("pg_temp")); } } else @@ -2187,6 +2195,7 @@ object_id(PG_FUNCTION_ARGS) } } } + pfree(object_name); if (object_type) pfree(object_type); @@ -2363,7 +2372,8 @@ object_name(PG_FUNCTION_ARGS) if (!OidIsValid(schema_id) || is_schema_from_db(schema_id, database_id) || (schema_id == get_namespace_oid("sys", true)) || - (schema_id == get_namespace_oid("information_schema_tsql", true))) + (schema_id == get_namespace_oid("information_schema_tsql", true)) || + (isTempNamespace(schema_id))) { PG_RETURN_VARCHAR_P((VarChar *) result_text); } diff --git a/contrib/babelfishpg_tsql/sql/babelfishpg_tsql.sql b/contrib/babelfishpg_tsql/sql/babelfishpg_tsql.sql index daeda4fbde5..053fbc7abf9 100644 --- a/contrib/babelfishpg_tsql/sql/babelfishpg_tsql.sql +++ b/contrib/babelfishpg_tsql/sql/babelfishpg_tsql.sql @@ -157,6 +157,8 @@ GRANT SELECT ON sys.spt_datatype_info_table TO PUBLIC; INSERT INTO sys.spt_datatype_info_table VALUES (N'datetimeoffset', -155, 34, N'''', N'''', N'scale ', 1, 0, 3, NULL, 0, NULL, N'datetimeoffset', 0, 7, -155, 0, NULL, NULL, 0, 68, 0, 'datetimeoffset'); INSERT INTO sys.spt_datatype_info_table VALUES (N'time', -154, 16, N'''', N'''', N'scale ', 1, 0, 3, NULL, 0, NULL, N'time', 0, 7, -154, 0, NULL, NULL, 0, 32, 0, 'time'); INSERT INTO sys.spt_datatype_info_table VALUES (N'xml', -152, 0, N'N''', N'''', NULL, 1, 1, 0, NULL, 0, NULL, N'xml', NULL, NULL, -152, NULL, NULL, NULL, 0, 2147483646, 0, N'xml'); +INSERT INTO sys.spt_datatype_info_table VALUES (N'geometry', -151, 0, NULL, NULL, NULL, 1, 1, 0, NULL, 0, NULL, N'geometry', NULL, NULL, -151, NULL, NULL, NULL, 0, 2147483646, 23, NULL); +INSERT INTO sys.spt_datatype_info_table VALUES (N'geography', -151, 0, NULL, NULL, NULL, 1, 1, 0, NULL, 0, NULL, N'geography', NULL, NULL, -151, NULL, NULL, NULL, 0, 2147483646, 23, NULL); INSERT INTO sys.spt_datatype_info_table VALUES (N'sql_variant', -150, 8000, NULL, NULL, NULL, 1, 0, 2, NULL, 0, NULL, N'sql_variant', 0, 0, -150, NULL, 10, NULL, 0, 8000, 39, 'sql_variant'); INSERT INTO sys.spt_datatype_info_table VALUES (N'uniqueidentifier', -11, 36, N'''', N'''', NULL, 1, 0, 2, NULL, 0, NULL, N'uniqueidentifier', NULL, NULL, -11, NULL, NULL, NULL, 0, 16, 37, 'uniqueidentifier'); INSERT INTO sys.spt_datatype_info_table VALUES (N'ntext', -10, 1073741823, N'N''', N'''', NULL, 1, 1, 1, NULL, 0, NULL, N'ntext', NULL, NULL, -10, NULL, NULL, NULL, 0, 2147483646, 35, NULL); @@ -283,6 +285,7 @@ BEGIN WHEN type in ('text', 'image') THEN length = 2147483647; WHEN type = 'ntext' THEN length = 2147483646; WHEN type = 'xml' THEN length = 0; + WHEN type IN ('geometry', 'geography') THEN length = -1; WHEN type = 'sql_variant' THEN length = 8000; WHEN type = 'money' THEN length = 21; WHEN type = 'sysname' THEN length = (typemod - 4) * 2; @@ -637,6 +640,8 @@ BEGIN WHEN 'datetimeoffset' THEN tds_id = 43; WHEN 'timestamp' THEN tds_id = 173; WHEN 'vector' THEN tds_id = 167; -- Same as varchar + WHEN 'geometry' THEN tds_id = 240; + WHEN 'geography' THEN tds_id = 240; ELSE tds_id = 0; END CASE; RETURN tds_id; @@ -707,11 +712,10 @@ GRANT ALL on PROCEDURE sys.sp_describe_first_result_set TO PUBLIC; CREATE OR REPLACE VIEW sys.spt_tablecollations_view AS SELECT - o.object_id AS object_id, - o.schema_id AS schema_id, - c.column_id AS colid, - CASE WHEN p.attoptions[1] LIKE 'bbf_original_name=%' THEN CAST(split_part(p.attoptions[1], '=', 2) AS sys.VARCHAR) - ELSE c.name COLLATE sys.database_default END AS name, + c.object_id AS object_id, + CAST(p.relnamespace AS int) AS schema_id, + c.column_id AS colid, + CAST(c.name AS sys.varchar) AS name, CAST(CollationProperty(c.collation_name,'tdscollation') AS binary(5)) AS tds_collation_28, CAST(CollationProperty(c.collation_name,'tdscollation') AS binary(5)) AS tds_collation_90, CAST(CollationProperty(c.collation_name,'tdscollation') AS binary(5)) AS tds_collation_100, @@ -719,11 +723,10 @@ CREATE OR REPLACE VIEW sys.spt_tablecollations_view AS CAST(c.collation_name AS nvarchar(128)) AS collation_90, CAST(c.collation_name AS nvarchar(128)) AS collation_100 FROM - sys.all_columns c INNER JOIN - sys.all_objects o ON (c.object_id = o.object_id) JOIN - pg_attribute p ON (c.name = p.attname COLLATE sys.database_default AND c.object_id = p.attrelid) + sys.all_columns c + INNER JOIN pg_catalog.pg_class p ON (c.object_id = p.oid) WHERE - c.is_sparse = 0 AND p.attnum >= 0; + c.is_sparse = 0; GRANT SELECT ON sys.spt_tablecollations_view TO PUBLIC; -- We are limited by what postgres procedures can return here, but IEW may not diff --git a/contrib/babelfishpg_tsql/sql/information_schema_tsql.sql b/contrib/babelfishpg_tsql/sql/information_schema_tsql.sql index 4a5224e3c79..668b5ae53a1 100644 --- a/contrib/babelfishpg_tsql/sql/information_schema_tsql.sql +++ b/contrib/babelfishpg_tsql/sql/information_schema_tsql.sql @@ -57,7 +57,7 @@ $$SELECT THEN 1073741823 WHEN type = 'sysname' THEN 128 - WHEN type IN ('xml', 'vector') + WHEN type IN ('xml', 'vector', 'geometry', 'geography') THEN -1 WHEN type = 'sql_variant' THEN 0 @@ -89,7 +89,7 @@ $$SELECT THEN 256 WHEN type = 'sql_variant' THEN 0 - WHEN type = 'xml' + WHEN type IN ('xml', 'geometry', 'geography') THEN -1 ELSE null END$$; @@ -112,7 +112,7 @@ $$SELECT THEN 1073741823 WHEN type = 'sysname' THEN 128 - WHEN type = 'xml' + WHEN type IN ('xml', 'geometry', 'geography') THEN -1 WHEN type = 'sql_variant' THEN 0 diff --git a/contrib/babelfishpg_tsql/sql/ownership.sql b/contrib/babelfishpg_tsql/sql/ownership.sql index b4180aaebdb..618af0a7b1d 100644 --- a/contrib/babelfishpg_tsql/sql/ownership.sql +++ b/contrib/babelfishpg_tsql/sql/ownership.sql @@ -14,6 +14,19 @@ CREATE TABLE sys.babelfish_sysdatabases ( GRANT SELECT on sys.babelfish_sysdatabases TO PUBLIC; +-- BABELFISH_SCHEMA_PERMISSIONS +-- This catalog is implemented specially to support GRANT/REVOKE .. ON SCHEMA .. +-- Please avoid using this catalog anywhere else. +CREATE TABLE sys.babelfish_schema_permissions ( + dbid smallint NOT NULL, + schema_name sys.NVARCHAR(128) NOT NULL COLLATE sys.database_default, + object_name sys.NVARCHAR(128) NOT NULL COLLATE sys.database_default, + permission INT NOT NULL, + grantee sys.NVARCHAR(128) NOT NULL COLLATE sys.database_default, + object_type CHAR(1) NOT NULL COLLATE sys.database_default, + PRIMARY KEY(dbid, schema_name, object_name, grantee, object_type) +); + -- BABELFISH_FUNCTION_EXT CREATE TABLE sys.babelfish_function_ext ( nspname NAME NOT NULL, diff --git a/contrib/babelfishpg_tsql/sql/sys_views.sql b/contrib/babelfishpg_tsql/sql/sys_views.sql index 859e686c6b6..f33c717ab71 100644 --- a/contrib/babelfishpg_tsql/sql/sys_views.sql +++ b/contrib/babelfishpg_tsql/sql/sys_views.sql @@ -369,6 +369,7 @@ BEGIN END IF; WHEN v_type in ('binary', 'char', 'bpchar', 'nchar') THEN max_length = 8000; WHEN v_type in ('decimal', 'numeric') THEN max_length = 17; + WHEN v_type in ('geometry', 'geography') THEN max_length = -1; ELSE max_length = typemod; END CASE; RETURN max_length; @@ -1106,7 +1107,12 @@ select END as collation_name , case when typnotnull then cast(0 as sys.bit) else cast(1 as sys.bit) end as is_nullable , CAST(0 as sys.bit) as is_user_defined - , CAST(0 as sys.bit) as is_assembly_type + , CASE tsql_type_name + -- CLR UDT have is_assembly_type = 1 + WHEN 'geometry' THEN CAST(1 as sys.bit) + WHEN 'geography' THEN CAST(1 as sys.bit) + ELSE CAST(0 as sys.bit) + END as is_assembly_type , CAST(0 as int) as default_object_id , CAST(0 as int) as rule_object_id , CAST(0 as sys.bit) as is_table_type @@ -1139,7 +1145,12 @@ select cast(t.typname as sys.sysname) as name as is_nullable -- CREATE TYPE ... FROM is implemented as CREATE DOMAIN in babel , CAST(1 as sys.bit) as is_user_defined - , CAST(0 as sys.bit) as is_assembly_type + , CASE tsql_type_name + -- CLR UDT have is_assembly_type = 1 + WHEN 'geometry' THEN CAST(1 as sys.bit) + WHEN 'geography' THEN CAST(1 as sys.bit) + ELSE CAST(0 as sys.bit) + END as is_assembly_type , CAST(0 as int) as default_object_id , CAST(0 as int) as rule_object_id , case when tt.typrelid is not null then CAST(1 as sys.bit) else CAST(0 as sys.bit) end as is_table_type diff --git a/contrib/babelfishpg_tsql/sql/upgrades/babelfishpg_tsql--3.4.0--3.5.0.sql b/contrib/babelfishpg_tsql/sql/upgrades/babelfishpg_tsql--3.4.0--3.5.0.sql index e7ae2dcad8b..b70de1a5c1c 100644 --- a/contrib/babelfishpg_tsql/sql/upgrades/babelfishpg_tsql--3.4.0--3.5.0.sql +++ b/contrib/babelfishpg_tsql/sql/upgrades/babelfishpg_tsql--3.4.0--3.5.0.sql @@ -880,7 +880,12 @@ select END as collation_name , case when typnotnull then cast(0 as sys.bit) else cast(1 as sys.bit) end as is_nullable , CAST(0 as sys.bit) as is_user_defined - , CAST(0 as sys.bit) as is_assembly_type + , CASE tsql_type_name + -- CLR UDT have is_assembly_type = 1 + WHEN 'geometry' THEN CAST(1 as sys.bit) + WHEN 'geography' THEN CAST(1 as sys.bit) + ELSE CAST(0 as sys.bit) + END as is_assembly_type , CAST(0 as int) as default_object_id , CAST(0 as int) as rule_object_id , CAST(0 as sys.bit) as is_table_type @@ -913,7 +918,12 @@ select cast(t.typname as sys.sysname) as name as is_nullable -- CREATE TYPE ... FROM is implemented as CREATE DOMAIN in babel , CAST(1 as sys.bit) as is_user_defined - , CAST(0 as sys.bit) as is_assembly_type + , CASE tsql_type_name + -- CLR UDT have is_assembly_type = 1 + WHEN 'geometry' THEN CAST(1 as sys.bit) + WHEN 'geography' THEN CAST(1 as sys.bit) + ELSE CAST(0 as sys.bit) + END as is_assembly_type , CAST(0 as int) as default_object_id , CAST(0 as int) as rule_object_id , case when tt.typrelid is not null then CAST(1 as sys.bit) else CAST(0 as sys.bit) end as is_table_type @@ -2201,175 +2211,17 @@ AS SELECT WHERE FALSE; GRANT SELECT ON sys.availability_groups TO PUBLIC; -CREATE OR REPLACE FUNCTION sys.tsql_type_max_length_helper(IN type TEXT, IN typelen INT, IN typemod INT, IN for_sys_types boolean DEFAULT false, IN used_typmod_array boolean DEFAULT false) -RETURNS SMALLINT -AS $$ -DECLARE - max_length SMALLINT; - precision INT; - v_type TEXT COLLATE sys.database_default := type; -BEGIN - -- unknown tsql type - IF v_type IS NULL THEN - RETURN CAST(typelen as SMALLINT); - END IF; - - -- if using typmod_array from pg_proc.probin - IF used_typmod_array THEN - IF v_type = 'sysname' THEN - RETURN 256; - ELSIF (v_type in ('char', 'bpchar', 'varchar', 'binary', 'varbinary', 'nchar', 'nvarchar')) - THEN - IF typemod < 0 THEN -- max value. - RETURN -1; - ELSIF v_type in ('nchar', 'nvarchar') THEN - RETURN (2 * typemod); - ELSE - RETURN typemod; - END IF; - END IF; - END IF; - - IF typelen != -1 THEN - CASE v_type - WHEN 'tinyint' THEN max_length = 1; - WHEN 'date' THEN max_length = 3; - WHEN 'smalldatetime' THEN max_length = 4; - WHEN 'smallmoney' THEN max_length = 4; - WHEN 'datetime2' THEN - IF typemod = -1 THEN max_length = 8; - ELSIF typemod <= 2 THEN max_length = 6; - ELSIF typemod <= 4 THEN max_length = 7; - ELSEIF typemod <= 7 THEN max_length = 8; - -- typemod = 7 is not possible for datetime2 in Babel - END IF; - WHEN 'datetimeoffset' THEN - IF typemod = -1 THEN max_length = 10; - ELSIF typemod <= 2 THEN max_length = 8; - ELSIF typemod <= 4 THEN max_length = 9; - ELSIF typemod <= 7 THEN max_length = 10; - -- typemod = 7 is not possible for datetimeoffset in Babel - END IF; - WHEN 'time' THEN - IF typemod = -1 THEN max_length = 5; - ELSIF typemod <= 2 THEN max_length = 3; - ELSIF typemod <= 4 THEN max_length = 4; - ELSIF typemod <= 7 THEN max_length = 5; - END IF; - WHEN 'timestamp' THEN max_length = 8; - WHEN 'vector' THEN max_length = -1; -- dummy as varchar max - ELSE max_length = typelen; - END CASE; - RETURN max_length; - END IF; - IF typemod = -1 THEN - CASE - WHEN v_type in ('image', 'text', 'ntext') THEN max_length = 16; - WHEN v_type = 'sql_variant' THEN max_length = 8016; - WHEN v_type in ('varbinary', 'varchar', 'nvarchar') THEN - IF for_sys_types THEN max_length = 8000; - ELSE max_length = -1; - END IF; - WHEN v_type in ('binary', 'char', 'bpchar', 'nchar') THEN max_length = 8000; - WHEN v_type in ('decimal', 'numeric') THEN max_length = 17; - ELSE max_length = typemod; - END CASE; - RETURN max_length; - END IF; - - CASE - WHEN v_type in ('char', 'bpchar', 'varchar', 'binary', 'varbinary') THEN max_length = typemod - 4; - WHEN v_type in ('nchar', 'nvarchar') THEN max_length = (typemod - 4) * 2; - WHEN v_type = 'sysname' THEN max_length = (typemod - 4) * 2; - WHEN v_type in ('numeric', 'decimal') THEN - precision = ((typemod - 4) >> 16) & 65535; - IF precision >= 1 and precision <= 9 THEN max_length = 5; - ELSIF precision <= 19 THEN max_length = 9; - ELSIF precision <= 28 THEN max_length = 13; - ELSIF precision <= 38 THEN max_length = 17; - ELSE max_length = typelen; - END IF; - ELSE - max_length = typemod; - END CASE; - RETURN max_length; -END; -$$ LANGUAGE plpgsql IMMUTABLE STRICT; - -create or replace function sys.get_tds_id( - datatype sys.varchar(50) -) -returns INT -AS $$ -DECLARE - tds_id INT; -BEGIN - IF datatype IS NULL THEN - RETURN 0; - END IF; - CASE datatype - WHEN 'text' THEN tds_id = 35; - WHEN 'uniqueidentifier' THEN tds_id = 36; - WHEN 'tinyint' THEN tds_id = 38; - WHEN 'smallint' THEN tds_id = 38; - WHEN 'int' THEN tds_id = 38; - WHEN 'bigint' THEN tds_id = 38; - WHEN 'ntext' THEN tds_id = 99; - WHEN 'bit' THEN tds_id = 104; - WHEN 'float' THEN tds_id = 109; - WHEN 'real' THEN tds_id = 109; - WHEN 'varchar' THEN tds_id = 167; - WHEN 'nvarchar' THEN tds_id = 231; - WHEN 'nchar' THEN tds_id = 239; - WHEN 'money' THEN tds_id = 110; - WHEN 'smallmoney' THEN tds_id = 110; - WHEN 'char' THEN tds_id = 175; - WHEN 'date' THEN tds_id = 40; - WHEN 'datetime' THEN tds_id = 111; - WHEN 'smalldatetime' THEN tds_id = 111; - WHEN 'numeric' THEN tds_id = 108; - WHEN 'xml' THEN tds_id = 241; - WHEN 'decimal' THEN tds_id = 106; - WHEN 'varbinary' THEN tds_id = 165; - WHEN 'binary' THEN tds_id = 173; - WHEN 'image' THEN tds_id = 34; - WHEN 'time' THEN tds_id = 41; - WHEN 'datetime2' THEN tds_id = 42; - WHEN 'sql_variant' THEN tds_id = 98; - WHEN 'datetimeoffset' THEN tds_id = 43; - WHEN 'timestamp' THEN tds_id = 173; - WHEN 'vector' THEN tds_id = 167; -- Same as varchar - ELSE tds_id = 0; - END CASE; - RETURN tds_id; -END; -$$ LANGUAGE plpgsql IMMUTABLE STRICT; - -CREATE OR REPLACE FUNCTION information_schema_tsql._pgtsql_char_max_length(type text, typmod int4) RETURNS integer - LANGUAGE sql - IMMUTABLE - PARALLEL SAFE - RETURNS NULL ON NULL INPUT - AS -$$SELECT - CASE WHEN type IN ('char', 'nchar', 'varchar', 'nvarchar', 'binary', 'varbinary') - THEN CASE WHEN typmod = -1 - THEN -1 - ELSE typmod - 4 - END - WHEN type IN ('text', 'image') - THEN 2147483647 - WHEN type = 'ntext' - THEN 1073741823 - WHEN type = 'sysname' - THEN 128 - WHEN type IN ('xml', 'vector') - THEN -1 - WHEN type = 'sql_variant' - THEN 0 - ELSE null - END$$; +-- BABELFISH_SCHEMA_PERMISSIONS +CREATE TABLE IF NOT EXISTS sys.babelfish_schema_permissions ( + dbid smallint NOT NULL, + schema_name sys.NVARCHAR(128) NOT NULL COLLATE sys.database_default, + object_name sys.NVARCHAR(128) NOT NULL COLLATE sys.database_default, + permission INT NOT NULL, + grantee sys.NVARCHAR(128) NOT NULL COLLATE sys.database_default, + object_type CHAR(1) NOT NULL COLLATE sys.database_default, + PRIMARY KEY(dbid, schema_name, object_name, grantee, object_type) +); create or replace view sys.all_objects as select @@ -2777,6 +2629,322 @@ left join sys.shipped_objects_not_in_sys nis on nis.name = ('TT_' || tt.name || ) ot; GRANT SELECT ON sys.all_objects TO PUBLIC; +CREATE OR REPLACE VIEW sys.spt_tablecollations_view AS + SELECT + c.object_id AS object_id, + CAST(p.relnamespace AS int) AS schema_id, + c.column_id AS colid, + CAST(c.name AS sys.varchar) AS name, + CAST(CollationProperty(c.collation_name,'tdscollation') AS binary(5)) AS tds_collation_28, + CAST(CollationProperty(c.collation_name,'tdscollation') AS binary(5)) AS tds_collation_90, + CAST(CollationProperty(c.collation_name,'tdscollation') AS binary(5)) AS tds_collation_100, + CAST(c.collation_name AS nvarchar(128)) AS collation_28, + CAST(c.collation_name AS nvarchar(128)) AS collation_90, + CAST(c.collation_name AS nvarchar(128)) AS collation_100 + FROM + sys.all_columns c + INNER JOIN pg_catalog.pg_class p ON (c.object_id = p.oid) + WHERE + c.is_sparse = 0; +GRANT SELECT ON sys.spt_tablecollations_view TO PUBLIC; + +CREATE OR REPLACE FUNCTION sys.tsql_type_max_length_helper(IN type TEXT, IN typelen INT, IN typemod INT, IN for_sys_types boolean DEFAULT false, IN used_typmod_array boolean DEFAULT false) +RETURNS SMALLINT +AS $$ +DECLARE + max_length SMALLINT; + precision INT; + v_type TEXT COLLATE sys.database_default := type; +BEGIN + -- unknown tsql type + IF v_type IS NULL THEN + RETURN CAST(typelen as SMALLINT); + END IF; + + -- if using typmod_array from pg_proc.probin + IF used_typmod_array THEN + IF v_type = 'sysname' THEN + RETURN 256; + ELSIF (v_type in ('char', 'bpchar', 'varchar', 'binary', 'varbinary', 'nchar', 'nvarchar')) + THEN + IF typemod < 0 THEN -- max value. + RETURN -1; + ELSIF v_type in ('nchar', 'nvarchar') THEN + RETURN (2 * typemod); + ELSE + RETURN typemod; + END IF; + END IF; + END IF; + + IF typelen != -1 THEN + CASE v_type + WHEN 'tinyint' THEN max_length = 1; + WHEN 'date' THEN max_length = 3; + WHEN 'smalldatetime' THEN max_length = 4; + WHEN 'smallmoney' THEN max_length = 4; + WHEN 'datetime2' THEN + IF typemod = -1 THEN max_length = 8; + ELSIF typemod <= 2 THEN max_length = 6; + ELSIF typemod <= 4 THEN max_length = 7; + ELSEIF typemod <= 7 THEN max_length = 8; + -- typemod = 7 is not possible for datetime2 in Babel + END IF; + WHEN 'datetimeoffset' THEN + IF typemod = -1 THEN max_length = 10; + ELSIF typemod <= 2 THEN max_length = 8; + ELSIF typemod <= 4 THEN max_length = 9; + ELSIF typemod <= 7 THEN max_length = 10; + -- typemod = 7 is not possible for datetimeoffset in Babel + END IF; + WHEN 'time' THEN + IF typemod = -1 THEN max_length = 5; + ELSIF typemod <= 2 THEN max_length = 3; + ELSIF typemod <= 4 THEN max_length = 4; + ELSIF typemod <= 7 THEN max_length = 5; + END IF; + WHEN 'timestamp' THEN max_length = 8; + WHEN 'vector' THEN max_length = -1; -- dummy as varchar max + ELSE max_length = typelen; + END CASE; + RETURN max_length; + END IF; + + IF typemod = -1 THEN + CASE + WHEN v_type in ('image', 'text', 'ntext') THEN max_length = 16; + WHEN v_type = 'sql_variant' THEN max_length = 8016; + WHEN v_type in ('varbinary', 'varchar', 'nvarchar') THEN + IF for_sys_types THEN max_length = 8000; + ELSE max_length = -1; + END IF; + WHEN v_type in ('binary', 'char', 'bpchar', 'nchar') THEN max_length = 8000; + WHEN v_type in ('decimal', 'numeric') THEN max_length = 17; + WHEN v_type in ('geometry', 'geography') THEN max_length = -1; + ELSE max_length = typemod; + END CASE; + RETURN max_length; + END IF; + + CASE + WHEN v_type in ('char', 'bpchar', 'varchar', 'binary', 'varbinary') THEN max_length = typemod - 4; + WHEN v_type in ('nchar', 'nvarchar') THEN max_length = (typemod - 4) * 2; + WHEN v_type = 'sysname' THEN max_length = (typemod - 4) * 2; + WHEN v_type in ('numeric', 'decimal') THEN + precision = ((typemod - 4) >> 16) & 65535; + IF precision >= 1 and precision <= 9 THEN max_length = 5; + ELSIF precision <= 19 THEN max_length = 9; + ELSIF precision <= 28 THEN max_length = 13; + ELSIF precision <= 38 THEN max_length = 17; + ELSE max_length = typelen; + END IF; + ELSE + max_length = typemod; + END CASE; + RETURN max_length; +END; +$$ LANGUAGE plpgsql IMMUTABLE STRICT; + +CREATE OR REPLACE FUNCTION information_schema_tsql._pgtsql_char_max_length(type text, typmod int4) RETURNS integer + LANGUAGE sql + IMMUTABLE + PARALLEL SAFE + RETURNS NULL ON NULL INPUT + AS +$$SELECT + CASE WHEN type IN ('char', 'nchar', 'varchar', 'nvarchar', 'binary', 'varbinary') + THEN CASE WHEN typmod = -1 + THEN -1 + ELSE typmod - 4 + END + WHEN type IN ('text', 'image') + THEN 2147483647 + WHEN type = 'ntext' + THEN 1073741823 + WHEN type = 'sysname' + THEN 128 + WHEN type IN ('xml', 'vector', 'geometry', 'geography') + THEN -1 + WHEN type = 'sql_variant' + THEN 0 + ELSE null + END$$; + +create or replace function sys.get_tds_id( + datatype sys.varchar(50) +) +returns INT +AS $$ +DECLARE + tds_id INT; +BEGIN + IF datatype IS NULL THEN + RETURN 0; + END IF; + CASE datatype + WHEN 'text' THEN tds_id = 35; + WHEN 'uniqueidentifier' THEN tds_id = 36; + WHEN 'tinyint' THEN tds_id = 38; + WHEN 'smallint' THEN tds_id = 38; + WHEN 'int' THEN tds_id = 38; + WHEN 'bigint' THEN tds_id = 38; + WHEN 'ntext' THEN tds_id = 99; + WHEN 'bit' THEN tds_id = 104; + WHEN 'float' THEN tds_id = 109; + WHEN 'real' THEN tds_id = 109; + WHEN 'varchar' THEN tds_id = 167; + WHEN 'nvarchar' THEN tds_id = 231; + WHEN 'nchar' THEN tds_id = 239; + WHEN 'money' THEN tds_id = 110; + WHEN 'smallmoney' THEN tds_id = 110; + WHEN 'char' THEN tds_id = 175; + WHEN 'date' THEN tds_id = 40; + WHEN 'datetime' THEN tds_id = 111; + WHEN 'smalldatetime' THEN tds_id = 111; + WHEN 'numeric' THEN tds_id = 108; + WHEN 'xml' THEN tds_id = 241; + WHEN 'decimal' THEN tds_id = 106; + WHEN 'varbinary' THEN tds_id = 165; + WHEN 'binary' THEN tds_id = 173; + WHEN 'image' THEN tds_id = 34; + WHEN 'time' THEN tds_id = 41; + WHEN 'datetime2' THEN tds_id = 42; + WHEN 'sql_variant' THEN tds_id = 98; + WHEN 'datetimeoffset' THEN tds_id = 43; + WHEN 'timestamp' THEN tds_id = 173; + WHEN 'vector' THEN tds_id = 167; -- Same as varchar + WHEN 'geometry' THEN tds_id = 240; + WHEN 'geography' THEN tds_id = 240; + ELSE tds_id = 0; + END CASE; + RETURN tds_id; +END; +$$ LANGUAGE plpgsql IMMUTABLE STRICT; + +CREATE OR REPLACE FUNCTION information_schema_tsql._pgtsql_char_octet_length(type text, typmod int4) RETURNS integer + LANGUAGE sql + IMMUTABLE + PARALLEL SAFE + RETURNS NULL ON NULL INPUT + AS +$$SELECT + CASE WHEN type IN ('char', 'varchar', 'binary', 'varbinary') + THEN CASE WHEN typmod = -1 /* default typmod */ + THEN -1 + ELSE typmod - 4 + END + WHEN type IN ('nchar', 'nvarchar') + THEN CASE WHEN typmod = -1 /* default typmod */ + THEN -1 + ELSE (typmod - 4) * 2 + END + WHEN type IN ('text', 'image') + THEN 2147483647 /* 2^30 + 1 */ + WHEN type = 'ntext' + THEN 2147483646 /* 2^30 */ + WHEN type = 'sysname' + THEN 256 + WHEN type = 'sql_variant' + THEN 0 + WHEN type IN ('xml', 'geometry', 'geography') + THEN -1 + ELSE null + END$$; + +CREATE OR REPLACE FUNCTION information_schema_tsql._pgtsql_char_max_length_for_routines(type text, typmod int4) RETURNS integer + LANGUAGE sql + IMMUTABLE + PARALLEL SAFE + RETURNS NULL ON NULL INPUT + AS +$$SELECT + CASE WHEN type IN ('char', 'nchar', 'varchar', 'nvarchar', 'binary', 'varbinary') + THEN CASE WHEN typmod = -1 + THEN 1 + ELSE typmod - 4 + END + WHEN type IN ('text', 'image') + THEN 2147483647 + WHEN type = 'ntext' + THEN 1073741823 + WHEN type = 'sysname' + THEN 128 + WHEN type IN ('xml', 'geometry', 'geography') + THEN -1 + WHEN type = 'sql_variant' + THEN 0 + ELSE null + END$$; + +CREATE OR REPLACE FUNCTION sys.tsql_type_length_for_sp_columns_helper(IN type TEXT, IN typelen INT, IN typemod INT) +RETURNS INT +AS $$ +DECLARE + length INT; + precision INT; +BEGIN + -- unknown tsql type + IF type IS NULL THEN + RETURN typelen::INT; + END IF; + + IF typemod = -1 AND (type = 'varchar' OR type = 'nvarchar' OR type = 'varbinary') THEN + length = 0; + RETURN length; + END IF; + + IF typelen != -1 THEN + CASE type + WHEN 'tinyint' THEN length = 1; + WHEN 'date' THEN length = 6; + WHEN 'smalldatetime' THEN length = 16; + WHEN 'smallmoney' THEN length = 12; + WHEN 'money' THEN length = 21; + WHEN 'datetime' THEN length = 16; + WHEN 'datetime2' THEN length = 16; + WHEN 'datetimeoffset' THEN length = 20; + WHEN 'time' THEN length = 12; + WHEN 'timestamp' THEN length = 8; + ELSE length = typelen; + END CASE; + RETURN length; + END IF; + + CASE + WHEN type in ('char', 'bpchar', 'varchar', 'binary', 'varbinary') THEN length = typemod - 4; + WHEN type in ('nchar', 'nvarchar') THEN length = (typemod - 4) * 2; + WHEN type in ('text', 'image') THEN length = 2147483647; + WHEN type = 'ntext' THEN length = 2147483646; + WHEN type = 'xml' THEN length = 0; + WHEN type IN ('geometry', 'geography') THEN length = -1; + WHEN type = 'sql_variant' THEN length = 8000; + WHEN type = 'money' THEN length = 21; + WHEN type = 'sysname' THEN length = (typemod - 4) * 2; + WHEN type in ('numeric', 'decimal') THEN + precision = ((typemod - 4) >> 16) & 65535; + length = precision + 2; + ELSE + length = typemod; + END CASE; + RETURN length; +END; +$$ LANGUAGE plpgsql IMMUTABLE STRICT; + +DO $$ +BEGIN + IF NOT EXISTS (SELECT 1 FROM sys.spt_datatype_info_table WHERE TYPE_NAME = N'geometry') THEN + BEGIN + INSERT INTO sys.spt_datatype_info_table VALUES (N'geometry', -151, 0, NULL, NULL, NULL, 1, 1, 0, NULL, 0, NULL, N'geometry', NULL, NULL, -151, NULL, NULL, NULL, 0, 2147483646, 23, NULL); + END; + END IF; + IF NOT EXISTS (SELECT 1 FROM sys.spt_datatype_info_table WHERE TYPE_NAME = N'geography') THEN + BEGIN + INSERT INTO sys.spt_datatype_info_table VALUES (N'geography', -151, 0, NULL, NULL, NULL, 1, 1, 0, NULL, 0, NULL, N'geography', NULL, NULL, -151, NULL, NULL, NULL, 0, 2147483646, 23, NULL); + END; + END IF; +END; +$$ LANGUAGE plpgsql; + CALL sys.babelfish_drop_deprecated_object('view', 'sys', 'sysforeignkeys_deprecated_3_5_0'); CALL sys.babelfish_drop_deprecated_object('view', 'sys', 'system_objects_deprecated_3_5_0'); CALL sys.babelfish_drop_deprecated_object('view', 'sys', 'syscolumns_deprecated_3_5_0'); diff --git a/contrib/babelfishpg_tsql/src/catalog.c b/contrib/babelfishpg_tsql/src/catalog.c index 1032acfb905..1b0ac3f0cc0 100644 --- a/contrib/babelfishpg_tsql/src/catalog.c +++ b/contrib/babelfishpg_tsql/src/catalog.c @@ -83,6 +83,12 @@ Oid bbf_servers_def_idx_oid; Oid bbf_function_ext_oid; Oid bbf_function_ext_idx_oid; +/***************************************** + * SCHEMA + *****************************************/ +Oid bbf_schema_perms_oid; +Oid bbf_schema_perms_idx_oid; + /***************************************** * DOMAIN MAPPING *****************************************/ @@ -1435,6 +1441,29 @@ clean_up_bbf_function_ext(int16 dbid) table_close(bbf_function_ext_rel, RowExclusiveLock); } + +/***************************************** + * SCHEMA + *****************************************/ + +static Oid +get_bbf_schema_perms_oid() +{ + if (!OidIsValid(bbf_schema_perms_oid)) + bbf_schema_perms_oid = get_relname_relid(BBF_SCHEMA_PERMS_TABLE_NAME, + get_namespace_oid("sys", false)); + return bbf_schema_perms_oid; +} + +static Oid +get_bbf_schema_perms_idx_oid() +{ + if (!OidIsValid(bbf_schema_perms_idx_oid)) + bbf_schema_perms_idx_oid = get_relname_relid(BBF_SCHEMA_PERMS_IDX_NAME, + get_namespace_oid("sys", false)); + return bbf_schema_perms_idx_oid; +} + /***************************************** * DOMAIN MAPPING *****************************************/ @@ -1555,6 +1584,8 @@ static void alter_guest_schema_for_db(const char *dbname); static void rename_view_update_bbf_catalog(RenameStmt *stmt); static void rename_procfunc_update_bbf_catalog(RenameStmt *stmt); +static int get_privilege_of_object(const char *schema_name, const char *object_name, const char *grantee, const char *object_type); + /***************************************** * Catalog Extra Info * --------------------------------------- @@ -2799,6 +2830,609 @@ rename_procfunc_update_bbf_catalog(RenameStmt *stmt) table_close(bbf_func_ext_rel, RowExclusiveLock); } +/* + * Add an entry to catalog BABELFISH_SCHEMA_PERMISSIONS. + */ +void +add_entry_to_bbf_schema_perms(const char *schema_name, + const char *object_name, + int permission, + const char *grantee, + const char *object_type) +{ + Relation bbf_schema_rel; + TupleDesc bbf_schema_dsc; + HeapTuple tuple_bbf_schema; + Datum new_record_bbf_schema[BBF_SCHEMA_PERMS_NUM_OF_COLS]; + bool new_record_nulls_bbf_schema[BBF_SCHEMA_PERMS_NUM_OF_COLS]; + int16 dbid = get_cur_db_id(); + + /* Immediately return, if grantee is NULL or PUBLIC. */ + if ((grantee == NULL) || (strcmp(grantee, PUBLIC_ROLE_NAME) == 0)) + return; + + /* Fetch the relation */ + bbf_schema_rel = table_open(get_bbf_schema_perms_oid(), + RowExclusiveLock); + bbf_schema_dsc = RelationGetDescr(bbf_schema_rel); + + /* Build a tuple to insert */ + MemSet(new_record_bbf_schema, 0, sizeof(new_record_bbf_schema)); + MemSet(new_record_nulls_bbf_schema, false, sizeof(new_record_nulls_bbf_schema)); + + new_record_bbf_schema[Anum_bbf_schema_perms_dbid - 1] = Int16GetDatum(dbid); + new_record_bbf_schema[Anum_bbf_schema_perms_schema_name - 1] = CStringGetTextDatum(pstrdup(schema_name)); + new_record_bbf_schema[Anum_bbf_schema_perms_object_name - 1] = CStringGetTextDatum(pstrdup(object_name)); + new_record_bbf_schema[Anum_bbf_schema_perms_permission - 1] = Int32GetDatum(permission); + new_record_bbf_schema[Anum_bbf_schema_perms_grantee - 1] = CStringGetTextDatum(pstrdup(grantee)); + new_record_bbf_schema[Anum_bbf_schema_perms_object_type - 1] = CStringGetTextDatum(pstrdup(object_type)); + + tuple_bbf_schema = heap_form_tuple(bbf_schema_dsc, + new_record_bbf_schema, + new_record_nulls_bbf_schema); + + /* Insert new record in the bbf_authid_user_ext table */ + CatalogTupleInsert(bbf_schema_rel, tuple_bbf_schema); + + /* Close bbf_authid_user_ext, but keep lock till commit */ + table_close(bbf_schema_rel, RowExclusiveLock); + + /* Advance cmd counter to make the insert visible */ + CommandCounterIncrement(); +} + +/* + * Updates the permission column for a particular row in BABELFISH_SCHEMA_PERMISSIONS table. + */ +void +update_privileges_of_object(const char *schema_name, + const char *object_name, + int new_permission, + const char *grantee, + const char *object_type, + bool is_grant) +{ + Relation bbf_schema_rel; + HeapTuple tuple_bbf_schema; + TupleDesc bbf_schema_dsc; + HeapTuple new_tuple; + ScanKeyData scanKey[5]; + SysScanDesc scan; + int16 dbid = get_cur_db_id(); + int old_permission = 0; + int current_permission = 0; + Datum new_record_bbf_schema[BBF_SCHEMA_PERMS_NUM_OF_COLS]; + bool new_record_nulls_bbf_schema[BBF_SCHEMA_PERMS_NUM_OF_COLS]; + bool new_record_repl_bbf_schema[BBF_SCHEMA_PERMS_NUM_OF_COLS]; + + /* Immediately return false, if SCHEMA name is NULL or it's a shared schema. */ + if (schema_name == NULL || is_shared_schema(schema_name)) + return; + + /* Immediately return, if grantee is NULL or PUBLIC. */ + if ((grantee == NULL) || (strcmp(grantee, PUBLIC_ROLE_NAME) == 0)) + return; + + /* Get existing privilege of an object. */ + old_permission = get_privilege_of_object(schema_name, object_name, grantee, object_type); + + if (is_grant) + { + /* + * In case of GRANT, we add the new privilege along with the previous privilege in the column. + */ + current_permission = old_permission | new_permission; + } + else + { + /* + * In case of REVOKE, we remove the new privilege and keep the previous privilege as it is. + */ + current_permission = old_permission & ~new_permission; + } + + if (current_permission == 0) + { + remove_entry_from_bbf_schema_perms(schema_name, object_name, grantee, object_type); + return; + } + + bbf_schema_rel = table_open(get_bbf_schema_perms_oid(), + RowExclusiveLock); + + ScanKeyInit(&scanKey[0], + Anum_bbf_schema_perms_dbid, + BTEqualStrategyNumber, F_INT2EQ, + Int16GetDatum(dbid)); + ScanKeyEntryInitialize(&scanKey[1], 0, + Anum_bbf_schema_perms_schema_name, + BTEqualStrategyNumber, + InvalidOid, + tsql_get_server_collation_oid_internal(false), + F_TEXTEQ, + CStringGetTextDatum(schema_name)); + ScanKeyEntryInitialize(&scanKey[2], 0, + Anum_bbf_schema_perms_object_name, + BTEqualStrategyNumber, + InvalidOid, + tsql_get_server_collation_oid_internal(false), + F_TEXTEQ, + CStringGetTextDatum(object_name)); + ScanKeyInit(&scanKey[3], + Anum_bbf_schema_perms_permission, + BTEqualStrategyNumber, F_INT4EQ, + Int32GetDatum(old_permission)); + ScanKeyEntryInitialize(&scanKey[4], 0, + Anum_bbf_schema_perms_grantee, + BTEqualStrategyNumber, + InvalidOid, + tsql_get_server_collation_oid_internal(false), + F_TEXTEQ, + CStringGetTextDatum(grantee)); + + scan = systable_beginscan(bbf_schema_rel, + get_bbf_schema_perms_idx_oid(), + false, NULL, 5, scanKey); + + tuple_bbf_schema = systable_getnext(scan); + if (HeapTupleIsValid(tuple_bbf_schema)) + { + bbf_schema_dsc = RelationGetDescr(bbf_schema_rel); + /* Build a tuple to insert */ + MemSet(new_record_bbf_schema, 0, sizeof(new_record_bbf_schema)); + MemSet(new_record_nulls_bbf_schema, false, sizeof(new_record_nulls_bbf_schema)); + MemSet(new_record_repl_bbf_schema, false, sizeof(new_record_repl_bbf_schema)); + + new_record_bbf_schema[Anum_bbf_schema_perms_permission - 1] = Int32GetDatum(current_permission); + new_record_repl_bbf_schema[Anum_bbf_schema_perms_permission - 1] = true; + + new_tuple = heap_modify_tuple(tuple_bbf_schema, + bbf_schema_dsc, + new_record_bbf_schema, + new_record_nulls_bbf_schema, + new_record_repl_bbf_schema); + + CatalogTupleUpdate(bbf_schema_rel, &new_tuple->t_self, new_tuple); + heap_freetuple(new_tuple); + } + + systable_endscan(scan); + table_close(bbf_schema_rel, RowExclusiveLock); +} + +/* + * Checks if a particular privilege exists in catalog BABELFISH_SCHEMA_PERMISSIONS. + */ +bool +privilege_exists_in_bbf_schema_permissions(const char *schema_name, + const char *object_name, + const char *grantee, + bool missing_ok) +{ + Relation bbf_schema_rel; + HeapTuple tuple_bbf_schema; + SysScanDesc scan; + bool catalog_entry_exists = false; + int16 dbid = get_cur_db_id(); + + /* Immediately return false, if SCHEMA name is NULL or it's a shared schema. */ + if (schema_name == NULL || is_shared_schema(schema_name)) + return false; + + if (!missing_ok) + { + ScanKeyData scanKey[4]; + /* Immediately return false, if grantee is NULL or PUBLIC. */ + if ((grantee == NULL) || (strcmp(grantee, PUBLIC_ROLE_NAME) == 0)) + return false; + + bbf_schema_rel = table_open(get_bbf_schema_perms_oid(), + AccessShareLock); + ScanKeyInit(&scanKey[0], + Anum_bbf_schema_perms_dbid, + BTEqualStrategyNumber, F_INT2EQ, + Int16GetDatum(dbid)); + ScanKeyEntryInitialize(&scanKey[1], 0, + Anum_bbf_schema_perms_schema_name, + BTEqualStrategyNumber, + InvalidOid, + tsql_get_server_collation_oid_internal(false), + F_TEXTEQ, + CStringGetTextDatum(schema_name)); + ScanKeyEntryInitialize(&scanKey[2], 0, + Anum_bbf_schema_perms_object_name, + BTEqualStrategyNumber, + InvalidOid, + tsql_get_server_collation_oid_internal(false), + F_TEXTEQ, + CStringGetTextDatum(object_name)); + ScanKeyEntryInitialize(&scanKey[3], 0, + Anum_bbf_schema_perms_grantee, + BTEqualStrategyNumber, + InvalidOid, + tsql_get_server_collation_oid_internal(false), + F_TEXTEQ, + CStringGetTextDatum(grantee)); + scan = systable_beginscan(bbf_schema_rel, + get_bbf_schema_perms_idx_oid(), + true, NULL, 4, scanKey); + } + else + { + ScanKeyData scanKey[3]; + bbf_schema_rel = table_open(get_bbf_schema_perms_oid(), + AccessShareLock); + ScanKeyInit(&scanKey[0], + Anum_bbf_schema_perms_dbid, + BTEqualStrategyNumber, F_INT2EQ, + Int16GetDatum(dbid)); + ScanKeyEntryInitialize(&scanKey[1], 0, + Anum_bbf_schema_perms_schema_name, + BTEqualStrategyNumber, + InvalidOid, + tsql_get_server_collation_oid_internal(false), + F_TEXTEQ, + CStringGetTextDatum(schema_name)); + ScanKeyEntryInitialize(&scanKey[2], 0, + Anum_bbf_schema_perms_object_name, + BTEqualStrategyNumber, + InvalidOid, + tsql_get_server_collation_oid_internal(false), + F_TEXTEQ, + CStringGetTextDatum(object_name)); + + scan = systable_beginscan(bbf_schema_rel, + get_bbf_schema_perms_idx_oid(), + true, NULL, 3, scanKey); + } + + tuple_bbf_schema = systable_getnext(scan); + if (HeapTupleIsValid(tuple_bbf_schema)) + catalog_entry_exists = true; + + systable_endscan(scan); + table_close(bbf_schema_rel, AccessShareLock); + return catalog_entry_exists; +} + +/* + * Get the value of permission column from BABELFISH_SCHEMA_PERMISSIONS table. + */ +static int +get_privilege_of_object(const char *schema_name, + const char *object_name, + const char *grantee, + const char *object_type) +{ + Relation bbf_schema_rel; + HeapTuple tuple_bbf_schema; + ScanKeyData scanKey[5]; + SysScanDesc scan; + int16 dbid = get_cur_db_id(); + int permission = 0; + + bbf_schema_rel = table_open(get_bbf_schema_perms_oid(), + AccessShareLock); + ScanKeyInit(&scanKey[0], + Anum_bbf_schema_perms_dbid, + BTEqualStrategyNumber, F_INT2EQ, + Int16GetDatum(dbid)); + ScanKeyEntryInitialize(&scanKey[1], 0, + Anum_bbf_schema_perms_schema_name, + BTEqualStrategyNumber, + InvalidOid, + tsql_get_server_collation_oid_internal(false), + F_TEXTEQ, + CStringGetTextDatum(schema_name)); + ScanKeyEntryInitialize(&scanKey[2], 0, + Anum_bbf_schema_perms_object_name, + BTEqualStrategyNumber, + InvalidOid, + tsql_get_server_collation_oid_internal(false), + F_TEXTEQ, + CStringGetTextDatum(object_name)); + ScanKeyEntryInitialize(&scanKey[3], 0, + Anum_bbf_schema_perms_grantee, + BTEqualStrategyNumber, + InvalidOid, + tsql_get_server_collation_oid_internal(false), + F_TEXTEQ, + CStringGetTextDatum(grantee)); + ScanKeyEntryInitialize(&scanKey[4], 0, + Anum_bbf_schema_perms_object_type, + BTEqualStrategyNumber, + InvalidOid, + tsql_get_server_collation_oid_internal(false), + F_TEXTEQ, + CStringGetTextDatum(object_type)); + scan = systable_beginscan(bbf_schema_rel, + get_bbf_schema_perms_idx_oid(), + true, NULL, 5, scanKey); + tuple_bbf_schema = systable_getnext(scan); + + if (HeapTupleIsValid(tuple_bbf_schema)) + { + Datum datum; + bool isnull; + datum = heap_getattr(tuple_bbf_schema, Anum_bbf_schema_perms_permission, RelationGetDescr(bbf_schema_rel), &isnull); + permission = DatumGetInt32(datum); + } + + systable_endscan(scan); + table_close(bbf_schema_rel, AccessShareLock); + return permission; +} + +/* + * Removes a row from the catalog BABELFISH_SCHEMA_PERMISSIONS. + */ +void +remove_entry_from_bbf_schema_perms(const char *schema_name, + const char *object_name, + const char *grantee, + const char *object_type) +{ + Relation bbf_schema_rel; + HeapTuple tuple_bbf_schema; + ScanKeyData scanKey[5]; + SysScanDesc scan; + int16 dbid = get_cur_db_id(); + + /* Immediately return false, if SCHEMA name is NULL or it's a shared schema. */ + if (schema_name == NULL || is_shared_schema(schema_name)) + return; + + /* Immediately return, if grantee is NULL or PUBLIC. */ + if ((grantee == NULL) || (strcmp(grantee, PUBLIC_ROLE_NAME) == 0)) + return; + + bbf_schema_rel = table_open(get_bbf_schema_perms_oid(), + RowExclusiveLock); + ScanKeyInit(&scanKey[0], + Anum_bbf_schema_perms_dbid, + BTEqualStrategyNumber, F_INT2EQ, + Int16GetDatum(dbid)); + ScanKeyEntryInitialize(&scanKey[1], 0, + Anum_bbf_schema_perms_schema_name, + BTEqualStrategyNumber, + InvalidOid, + tsql_get_server_collation_oid_internal(false), + F_TEXTEQ, + CStringGetTextDatum(schema_name)); + ScanKeyEntryInitialize(&scanKey[2], 0, + Anum_bbf_schema_perms_object_name, + BTEqualStrategyNumber, + InvalidOid, + tsql_get_server_collation_oid_internal(false), + F_TEXTEQ, + CStringGetTextDatum(object_name)); + ScanKeyEntryInitialize(&scanKey[3], 0, + Anum_bbf_schema_perms_grantee, + BTEqualStrategyNumber, + InvalidOid, + tsql_get_server_collation_oid_internal(false), + F_TEXTEQ, + CStringGetTextDatum(grantee)); + ScanKeyEntryInitialize(&scanKey[4], 0, + Anum_bbf_schema_perms_object_type, + BTEqualStrategyNumber, + InvalidOid, + tsql_get_server_collation_oid_internal(false), + F_TEXTEQ, + CStringGetTextDatum(object_type)); + scan = systable_beginscan(bbf_schema_rel, + get_bbf_schema_perms_idx_oid(), + true, NULL, 5, scanKey); + + tuple_bbf_schema = systable_getnext(scan); + + if (HeapTupleIsValid(tuple_bbf_schema)) + CatalogTupleDelete(bbf_schema_rel, &tuple_bbf_schema->t_self); + + systable_endscan(scan); + table_close(bbf_schema_rel, RowExclusiveLock); +} + +/* + * Add an entry to BABELFISH_SCHEMA_PERMISSIONS table, if it doesn't exist already. + * If exists, updates the PERMISSION column in the table. + */ +void +add_or_update_object_in_bbf_schema(const char *schema_name, + const char *object_name, + int new_permission, + const char *grantee, + const char *object_type, + bool is_grant) +{ + if (!privilege_exists_in_bbf_schema_permissions(schema_name, object_name, grantee, false)) + add_entry_to_bbf_schema_perms(schema_name, object_name, new_permission, grantee, object_type); + else + update_privileges_of_object(schema_name, object_name, new_permission, grantee, object_type, is_grant); +} + +/* + * Removes all the rows corresponding to an OBJECT/SCHEMA from the catalog BABELFISH_SCHEMA_PERMISSIONS. + */ +void +clean_up_bbf_schema_permissions(const char *schema_name, + const char *object_name, + bool is_schema) +{ + SysScanDesc scan; + Relation bbf_schema_rel; + HeapTuple tuple_bbf_schema; + int16 dbid = get_cur_db_id(); + + /* Immediately return false, if SCHEMA name is NULL or it's a shared schema. */ + if (schema_name == NULL || is_shared_schema(schema_name)) + return; + + /* Fetch the relation */ + bbf_schema_rel = table_open(get_bbf_schema_perms_oid(), + RowExclusiveLock); + + if (is_schema) + { + ScanKeyData scanKey[2]; + ScanKeyInit(&scanKey[0], + Anum_bbf_schema_perms_dbid, + BTEqualStrategyNumber, F_INT2EQ, + Int16GetDatum(dbid)); + ScanKeyEntryInitialize(&scanKey[1], 0, + Anum_bbf_schema_perms_schema_name, + BTEqualStrategyNumber, + InvalidOid, + tsql_get_server_collation_oid_internal(false), + F_TEXTEQ, + CStringGetTextDatum(schema_name)); + scan = systable_beginscan(bbf_schema_rel, + get_bbf_schema_perms_idx_oid(), + true, NULL, 2, scanKey); + } + else + { + ScanKeyData scanKey[3]; + ScanKeyInit(&scanKey[0], + Anum_bbf_schema_perms_dbid, + BTEqualStrategyNumber, F_INT2EQ, + Int16GetDatum(dbid)); + ScanKeyEntryInitialize(&scanKey[1], 0, + Anum_bbf_schema_perms_schema_name, + BTEqualStrategyNumber, + InvalidOid, + tsql_get_server_collation_oid_internal(false), + F_TEXTEQ, + CStringGetTextDatum(schema_name)); + ScanKeyEntryInitialize(&scanKey[2], 0, + Anum_bbf_schema_perms_object_name, + BTEqualStrategyNumber, + InvalidOid, + tsql_get_server_collation_oid_internal(false), + F_TEXTEQ, + CStringGetTextDatum(object_name)); + scan = systable_beginscan(bbf_schema_rel, + get_bbf_schema_perms_idx_oid(), + true, NULL, 3, scanKey); + } + + while ((tuple_bbf_schema = systable_getnext(scan)) != NULL) + { + if (HeapTupleIsValid(tuple_bbf_schema)) + CatalogTupleDelete(bbf_schema_rel, + &tuple_bbf_schema->t_self); + } + + systable_endscan(scan); + table_close(bbf_schema_rel, RowExclusiveLock); +} + +/* + * For all objects belonging to a schema which has OBJECT level permission, + * It grants the permission explicitly when REVOKE has been executed on that + * specific schema. + */ +void +grant_perms_to_objects_in_schema(const char *schema_name, + int permission, + const char *grantee) +{ + SysScanDesc scan; + Relation bbf_schema_rel; + TupleDesc dsc; + HeapTuple tuple_bbf_schema; + const char *object_name; + const char *object_type; + int current_permission; + ScanKeyData scanKey[3]; + int16 dbid = get_cur_db_id(); + const char *db_name = get_cur_db_name(); + + /* Fetch the relation */ + bbf_schema_rel = table_open(get_bbf_schema_perms_oid(), + AccessShareLock); + dsc = RelationGetDescr(bbf_schema_rel); + ScanKeyInit(&scanKey[0], + Anum_bbf_schema_perms_dbid, + BTEqualStrategyNumber, F_INT2EQ, + Int16GetDatum(dbid)); + ScanKeyEntryInitialize(&scanKey[1], 0, + Anum_bbf_schema_perms_schema_name, + BTEqualStrategyNumber, + InvalidOid, + tsql_get_server_collation_oid_internal(false), + F_TEXTEQ, + CStringGetTextDatum(schema_name)); + ScanKeyEntryInitialize(&scanKey[2], 0, + Anum_bbf_schema_perms_grantee, + BTEqualStrategyNumber, + InvalidOid, + tsql_get_server_collation_oid_internal(false), + F_TEXTEQ, + CStringGetTextDatum(grantee)); + + scan = systable_beginscan(bbf_schema_rel, get_bbf_schema_perms_idx_oid(), + true, NULL, 3, scanKey); + tuple_bbf_schema = systable_getnext(scan); + + while (HeapTupleIsValid(tuple_bbf_schema)) + { + bool isnull; + object_name = pstrdup(TextDatumGetCString(heap_getattr(tuple_bbf_schema, Anum_bbf_schema_perms_object_name, dsc, &isnull))); + object_type = pstrdup(TextDatumGetCString(heap_getattr(tuple_bbf_schema, Anum_bbf_schema_perms_object_type, dsc, &isnull))); + current_permission = DatumGetInt32(heap_getattr(tuple_bbf_schema, Anum_bbf_schema_perms_permission, dsc, &isnull)); + + /* For each object, grant the permission explicitly. */ + if (strcmp(object_name, PERMISSIONS_FOR_ALL_OBJECTS_IN_SCHEMA) != 0) + { + StringInfoData query; + char *schema; + List *res; + Node *res_stmt; + PlannedStmt *wrapper; + const char *priv_name; + + schema = get_physical_schema_name((char *)db_name, schema_name); + initStringInfo(&query); + /* Check if the permission to be REVOKED on SCHEMA exists on the OBJECT. */ + + if (current_permission & permission) + { + priv_name = privilege_to_string(permission); + if (strcmp(object_type, OBJ_RELATION) == 0) + appendStringInfo(&query, "GRANT \"%s\" ON \"%s\".\"%s\" TO \"%s\"; ", priv_name, schema, object_name, grantee); + else if (strcmp(object_type, OBJ_FUNCTION) == 0) + appendStringInfo(&query, "GRANT \"%s\" ON FUNCTION \"%s\".\"%s\" TO \"%s\"; ", priv_name, schema, object_name, grantee); + else if (strcmp(object_type, OBJ_PROCEDURE) == 0) + appendStringInfo(&query, "GRANT \"%s\" ON PROCEDURE \"%s\".\"%s\" TO \"%s\"; ", priv_name, schema, object_name, grantee); + res = raw_parser(query.data, RAW_PARSE_DEFAULT); + res_stmt = ((RawStmt *) linitial(res))->stmt; + + /* need to make a wrapper PlannedStmt */ + wrapper = makeNode(PlannedStmt); + wrapper->commandType = CMD_UTILITY; + wrapper->canSetTag = false; + wrapper->utilityStmt = res_stmt; + wrapper->stmt_location = 0; + wrapper->stmt_len = 1; + + /* do this step */ + ProcessUtility(wrapper, + "(GRANT STATEMENT )", + false, + PROCESS_UTILITY_SUBCOMMAND, + NULL, + NULL, + None_Receiver, + NULL); + } + } + tuple_bbf_schema = systable_getnext(scan); + } + systable_endscan(scan); + table_close(bbf_schema_rel, AccessShareLock); +} + PG_FUNCTION_INFO_V1(update_user_catalog_for_guest_schema); Datum update_user_catalog_for_guest_schema(PG_FUNCTION_ARGS) diff --git a/contrib/babelfishpg_tsql/src/catalog.h b/contrib/babelfishpg_tsql/src/catalog.h index 558969b7583..c8a1475b9fe 100644 --- a/contrib/babelfishpg_tsql/src/catalog.h +++ b/contrib/babelfishpg_tsql/src/catalog.h @@ -280,6 +280,51 @@ typedef struct FormData_bbf_function_ext typedef FormData_bbf_function_ext *Form_bbf_function_ext; +/***************************************** + * SCHEMA_PERMISSIONS + *****************************************/ +#define BBF_SCHEMA_PERMS_TABLE_NAME "babelfish_schema_permissions" +#define BBF_SCHEMA_PERMS_IDX_NAME "babelfish_schema_permissions_pkey" +#define BBF_SCHEMA_PERMS_NUM_OF_COLS 6 +#define Anum_bbf_schema_perms_dbid 1 +#define Anum_bbf_schema_perms_schema_name 2 +#define Anum_bbf_schema_perms_object_name 3 +#define Anum_bbf_schema_perms_permission 4 +#define Anum_bbf_schema_perms_grantee 5 +#define Anum_bbf_schema_perms_object_type 6 + +#define PUBLIC_ROLE_NAME "public" +#define PERMISSIONS_FOR_ALL_OBJECTS_IN_SCHEMA "ALL" +#define ALL_PERMISSIONS_ON_RELATION 47 /* last 6 bits as 101111 represents ALL privileges on a relation. */ +#define ALL_PERMISSIONS_ON_FUNCTION 128 /* last 8 bits as 10000000 represents ALL privileges on a procedure/function. */ +#define OBJ_SCHEMA "s" +#define OBJ_RELATION "r" +#define OBJ_PROCEDURE "p" +#define OBJ_FUNCTION "f" + +extern Oid bbf_schema_perms_oid; +extern Oid bbf_schema_perms_idx_oid; + +typedef struct FormData_bbf_schema_perms +{ + int16 dbid; + VarChar schema_name; + VarChar object_name; + int32 permission; + VarChar grantee; + char object_type; +} FormData_bbf_schema_perms; + +typedef FormData_bbf_schema_perms *Form_bbf_schema_perms; + +extern void add_entry_to_bbf_schema_perms(const char *schema_name, const char *object_name, int permission, const char *grantee, const char *object_type); +extern bool privilege_exists_in_bbf_schema_permissions(const char *schema_name, const char *object_name, const char *grantee, bool missing_ok); +extern void update_privileges_of_object(const char *schema_name, const char *object_name, int new_permission, const char *grantee, const char *object_type, bool is_grant); +extern void remove_entry_from_bbf_schema_perms(const char *schema_name, const char *object_name, const char *grantee, const char *object_type); +extern void add_or_update_object_in_bbf_schema(const char *schema_name, const char *object_name, int new_permission, const char *grantee, const char *object_type, bool is_grant); +extern void clean_up_bbf_schema_permissions(const char *schema_name, const char *object_name, bool is_schema); +extern void grant_perms_to_objects_in_schema(const char *schema_name, int permission, const char *grantee); + /***************************************** * DOMAIN MAPPING *****************************************/ diff --git a/contrib/babelfishpg_tsql/src/codegen.c b/contrib/babelfishpg_tsql/src/codegen.c index 745152d1ddb..c42eefa3d7e 100644 --- a/contrib/babelfishpg_tsql/src/codegen.c +++ b/contrib/babelfishpg_tsql/src/codegen.c @@ -302,6 +302,7 @@ stmt_default_act(Walker_context *ctx, PLtsql_stmt *stmt) case PLTSQL_STMT_GRANTDB: case PLTSQL_STMT_CHANGE_DBOWNER: case PLTSQL_STMT_FULLTEXTINDEX: + case PLTSQL_STMT_GRANTSCHEMA: case PLTSQL_STMT_INSERT_BULK: case PLTSQL_STMT_DBCC: case PLTSQL_STMT_SET_EXPLAIN_MODE: diff --git a/contrib/babelfishpg_tsql/src/datatype_info.h b/contrib/babelfishpg_tsql/src/datatype_info.h index 4e790f03332..1f4f5cc61a1 100644 --- a/contrib/babelfishpg_tsql/src/datatype_info.h +++ b/contrib/babelfishpg_tsql/src/datatype_info.h @@ -4,7 +4,7 @@ #define NULLVAL PG_INT32_MIN #define NULLVAL_STR "NULL" -#define DATATYPE_INFO_TABLE_ROWS 38 +#define DATATYPE_INFO_TABLE_ROWS 40 typedef struct DatatypeInfo { @@ -500,7 +500,30 @@ static const DatatypeInfo datatype_info_table[DATATYPE_INFO_TABLE_ROWS] = { "vector", NULLVAL, NULLVAL, NULLVAL, NULLVAL, NULLVAL, NULLVAL, NULLVAL, NULLVAL, NULLVAL, "vector" - + }, + { + "geometry", + -4, -4, -151, -151, + 0, + NULLVAL_STR, + NULLVAL_STR, + NULLVAL_STR, + 1, 1, 0, NULLVAL, 0, NULLVAL, + "geometry", + NULLVAL, NULLVAL, -151, NULLVAL, NULLVAL, NULLVAL, 0, 2147483646, 23, + NULLVAL_STR + }, + { + "geography", + -4, -4, -151, -151, + 0, + NULLVAL_STR, + NULLVAL_STR, + NULLVAL_STR, + 1, 1, 0, NULLVAL, 0, NULLVAL, + "geography", + NULLVAL, NULLVAL, -151, NULLVAL, NULLVAL, NULLVAL, 0, 2147483646, 23, + NULLVAL_STR } }; diff --git a/contrib/babelfishpg_tsql/src/dbcmds.c b/contrib/babelfishpg_tsql/src/dbcmds.c index c319eabbf9d..577d8cd16e4 100644 --- a/contrib/babelfishpg_tsql/src/dbcmds.c +++ b/contrib/babelfishpg_tsql/src/dbcmds.c @@ -154,7 +154,7 @@ gen_createdb_subcmds(const char *schema, const char *dbo, const char *db_owner, update_CreateRoleStmt(stmt, dbo, NULL, db_owner); stmt = parsetree_nth_stmt(res, i++); - update_GrantStmt(stmt, get_database_name(MyDatabaseId), NULL, dbo); + update_GrantStmt(stmt, get_database_name(MyDatabaseId), NULL, dbo, NULL); if (guest) { @@ -261,7 +261,7 @@ gen_dropdb_subcmds(const char *schema, update_DropOwnedStmt(stmt, list_make2(pstrdup(db_owner), pstrdup(dbo))); stmt = parsetree_nth_stmt(stmt_list, i++); - update_GrantStmt(stmt, get_database_name(MyDatabaseId), NULL, dbo); + update_GrantStmt(stmt, get_database_name(MyDatabaseId), NULL, dbo, NULL); stmt = parsetree_nth_stmt(stmt_list, i++); update_DropRoleStmt(stmt, db_owner); diff --git a/contrib/babelfishpg_tsql/src/iterative_exec.c b/contrib/babelfishpg_tsql/src/iterative_exec.c index 7e6abf340d6..af84c95ea1f 100644 --- a/contrib/babelfishpg_tsql/src/iterative_exec.c +++ b/contrib/babelfishpg_tsql/src/iterative_exec.c @@ -809,6 +809,9 @@ dispatch_stmt(PLtsql_execstate *estate, PLtsql_stmt *stmt) } exec_stmt_change_dbowner(estate, (PLtsql_stmt_change_dbowner *) stmt); break; + case PLTSQL_STMT_GRANTSCHEMA: + exec_stmt_grantschema(estate, (PLtsql_stmt_grantschema *) stmt); + break; case PLTSQL_STMT_FULLTEXTINDEX: if (pltsql_explain_only) { diff --git a/contrib/babelfishpg_tsql/src/pl_exec-2.c b/contrib/babelfishpg_tsql/src/pl_exec-2.c index d4a312669bf..ae8cc0b4404 100644 --- a/contrib/babelfishpg_tsql/src/pl_exec-2.c +++ b/contrib/babelfishpg_tsql/src/pl_exec-2.c @@ -54,6 +54,7 @@ static int exec_stmt_usedb(PLtsql_execstate *estate, PLtsql_stmt_usedb *stmt); static int exec_stmt_usedb_explain(PLtsql_execstate *estate, PLtsql_stmt_usedb *stmt, bool shouldRestoreDb); static int exec_stmt_grantdb(PLtsql_execstate *estate, PLtsql_stmt_grantdb *stmt); static int exec_stmt_fulltextindex(PLtsql_execstate *estate, PLtsql_stmt_fulltextindex *stmt); +static int exec_stmt_grantschema(PLtsql_execstate *estate, PLtsql_stmt_grantschema *stmt); static int exec_stmt_insert_execute_select(PLtsql_execstate *estate, PLtsql_expr *expr); static int exec_stmt_insert_bulk(PLtsql_execstate *estate, PLtsql_stmt_insert_bulk *expr); static int exec_stmt_dbcc(PLtsql_execstate *estate, PLtsql_stmt_dbcc *stmt); @@ -3687,6 +3688,135 @@ get_insert_bulk_kilobytes_per_batch() return insert_bulk_kilobytes_per_batch; } +static int +exec_stmt_grantschema(PLtsql_execstate *estate, PLtsql_stmt_grantschema *stmt) +{ + char *dbname = get_cur_db_name(); + char *login = GetUserNameFromId(GetSessionUserId(), false); + bool login_is_db_owner; + char *schema_name; + ListCell *lc; + Oid schemaOid; + char *user = GetUserNameFromId(GetUserId(), false); + const char *db_owner = get_owner_of_db(dbname); + + login_is_db_owner = 0 == strcmp(login, db_owner); + schema_name = get_physical_schema_name(dbname, stmt->schema_name); + + if(schema_name) + { + /* Return immediately for shared schema. */ + if(is_shared_schema(schema_name)) + return PLTSQL_RC_OK; + + schemaOid = LookupExplicitNamespace(schema_name, true); + } + else + { + ereport(ERROR, + (errcode(ERRCODE_UNDEFINED_SCHEMA), + errmsg("An object or column name is missing or empty. For SELECT INTO statements, verify each column has a name. For other statements, look for empty alias names. Aliases defined as \"\" or [] are not allowed. Change the alias to a valid name."))); + } + + if (!OidIsValid(schemaOid)) + ereport(ERROR, + (errcode(ERRCODE_UNDEFINED_SCHEMA), + errmsg("schema \"%s\" does not exist", + stmt->schema_name))); + + foreach(lc, stmt->grantees) + { + char *rolname = NULL; + char *grantee_name = (char *) lfirst(lc); + Oid role_oid; + bool is_public = 0 == strcmp(grantee_name, PUBLIC_ROLE_NAME); + if (!is_public) + rolname = get_physical_user_name(dbname, grantee_name); + else + rolname = pstrdup(PUBLIC_ROLE_NAME); + role_oid = get_role_oid(rolname, true); + + /* Special database roles should throw an error. */ + if (strcmp(grantee_name, "db_owner") == 0) + ereport(ERROR, (errcode(ERRCODE_INSUFFICIENT_PRIVILEGE), + errmsg("Cannot grant, deny or revoke permissions to or from special roles."))); + + if (!is_public && !OidIsValid(role_oid)) + { + /* sys or information_schema roles should throw an error. */ + if ((strcmp(grantee_name, "sys") == 0) || (strcmp(grantee_name, "information_schema") == 0)) + ereport(ERROR, + (errcode(ERRCODE_INSUFFICIENT_PRIVILEGE), + errmsg("Cannot grant, deny, or revoke permissions to sa, dbo, entity owner, information_schema, sys, or yourself."))); + else + ereport(ERROR, + (errcode(ERRCODE_INSUFFICIENT_PRIVILEGE), + errmsg("Cannot find the principal '%s', because it does not exist or you do not have permission.", grantee_name))); + } + + if ((strcmp(rolname, user) == 0) || (!is_public && pg_namespace_ownercheck(schemaOid, role_oid)) || is_member_of_role(role_oid, get_sysadmin_oid())) + ereport(ERROR, + (errcode(ERRCODE_INSUFFICIENT_PRIVILEGE), + errmsg("Cannot grant, deny, or revoke permissions to sa, dbo, entity owner, information_schema, sys, or yourself."))); + + /* + * If the login is not the db owner or the login is not the member of + * sysadmin or login is not the schema owner, then it doesn't have the permission to GRANT/REVOKE. + */ + if (!is_member_of_role(GetSessionUserId(), get_sysadmin_oid()) && !login_is_db_owner && !pg_namespace_ownercheck(schemaOid, GetUserId())) + ereport(ERROR, + (errcode(ERRCODE_INSUFFICIENT_PRIVILEGE), + errmsg("Cannot find the schema \"%s\", because it does not exist or you do not have permission.", stmt->schema_name))); + + /* Execute the GRANT SCHEMA subcommands. */ + if (stmt->privileges & ACL_EXECUTE) + exec_grantschema_subcmds(schema_name, rolname, stmt->is_grant, stmt->with_grant_option, ACL_EXECUTE); + if (stmt->privileges & ACL_SELECT) + exec_grantschema_subcmds(schema_name, rolname, stmt->is_grant, stmt->with_grant_option, ACL_SELECT); + if (stmt->privileges & ACL_INSERT) + exec_grantschema_subcmds(schema_name, rolname, stmt->is_grant, stmt->with_grant_option, ACL_INSERT); + if (stmt->privileges & ACL_UPDATE) + exec_grantschema_subcmds(schema_name, rolname, stmt->is_grant, stmt->with_grant_option, ACL_UPDATE); + if (stmt->privileges & ACL_DELETE) + exec_grantschema_subcmds(schema_name, rolname, stmt->is_grant, stmt->with_grant_option, ACL_DELETE); + if (stmt->privileges & ACL_REFERENCES) + exec_grantschema_subcmds(schema_name, rolname, stmt->is_grant, stmt->with_grant_option, ACL_REFERENCES); + + if (stmt->is_grant) + { + /* For GRANT statement, add or update privileges in the catalog. */ + add_or_update_object_in_bbf_schema(stmt->schema_name, PERMISSIONS_FOR_ALL_OBJECTS_IN_SCHEMA, stmt->privileges, rolname, OBJ_SCHEMA, true); + } + else + { + /* For REVOKE statement, update privileges in the catalog. */ + if (privilege_exists_in_bbf_schema_permissions(stmt->schema_name, PERMISSIONS_FOR_ALL_OBJECTS_IN_SCHEMA, rolname, false)) + { + /* If any object in the schema has the OBJECT level permission. Then, internally grant that permission back. */ + if (stmt->privileges & ACL_EXECUTE) + grant_perms_to_objects_in_schema(stmt->schema_name, ACL_EXECUTE, rolname); + if (stmt->privileges & ACL_SELECT) + grant_perms_to_objects_in_schema(stmt->schema_name, ACL_SELECT, rolname); + if (stmt->privileges & ACL_INSERT) + grant_perms_to_objects_in_schema(stmt->schema_name, ACL_INSERT, rolname); + if (stmt->privileges & ACL_UPDATE) + grant_perms_to_objects_in_schema(stmt->schema_name, ACL_UPDATE, rolname); + if (stmt->privileges & ACL_DELETE) + grant_perms_to_objects_in_schema(stmt->schema_name, ACL_DELETE, rolname); + if (stmt->privileges & ACL_REFERENCES) + grant_perms_to_objects_in_schema(stmt->schema_name, ACL_REFERENCES, rolname); + update_privileges_of_object(stmt->schema_name, PERMISSIONS_FOR_ALL_OBJECTS_IN_SCHEMA, stmt->privileges, rolname, OBJ_SCHEMA, false); + } + } + pfree(rolname); + } + pfree(user); + pfree(schema_name); + pfree(dbname); + pfree(login); + return PLTSQL_RC_OK; +} + /* * ALTER AUTHORIZATION ON DATABASE::dbname TO loginname */ diff --git a/contrib/babelfishpg_tsql/src/pl_funcs-2.c b/contrib/babelfishpg_tsql/src/pl_funcs-2.c index 80352240b6e..4e2c77f82dd 100644 --- a/contrib/babelfishpg_tsql/src/pl_funcs-2.c +++ b/contrib/babelfishpg_tsql/src/pl_funcs-2.c @@ -485,6 +485,7 @@ free_stmt2(PLtsql_stmt *stmt) case PLTSQL_STMT_GRANTDB: case PLTSQL_STMT_CHANGE_DBOWNER: case PLTSQL_STMT_FULLTEXTINDEX: + case PLTSQL_STMT_GRANTSCHEMA: case PLTSQL_STMT_SET_EXPLAIN_MODE: { /* Nothing to free */ diff --git a/contrib/babelfishpg_tsql/src/pl_handler.c b/contrib/babelfishpg_tsql/src/pl_handler.c index 9243083eacb..4f3c4838329 100644 --- a/contrib/babelfishpg_tsql/src/pl_handler.c +++ b/contrib/babelfishpg_tsql/src/pl_handler.c @@ -128,6 +128,14 @@ static void bbf_ProcessUtility(PlannedStmt *pstmt, QueryEnvironment *queryEnv, DestReceiver *dest, QueryCompletion *qc); +static void call_prev_ProcessUtility(PlannedStmt *pstmt, + const char *queryString, + bool readOnlyTree, + ProcessUtilityContext context, + ParamListInfo params, + QueryEnvironment *queryEnv, + DestReceiver *dest, + QueryCompletion *qc); static void set_pgtype_byval(List *name, bool byval); static bool pltsql_truncate_identifier(char *ident, int len, bool warn); static Name pltsql_cstr_to_name(char *s, int len); @@ -176,10 +184,11 @@ typedef struct { int nestLevel; } forjson_table; -static bool handleForJsonAuto(Query *query); +static bool handleForJsonAuto(Query *query, forjson_table **tableInfoArr, int numTables); static bool isJsonAuto(List* target); static bool check_json_auto_walker(Node *node, ParseState *pstate); -static TargetEntry* buildJsonEntry(forjson_table *table, TargetEntry* te); +static TargetEntry* buildJsonEntry(int nestLevel, char* tableAlias, TargetEntry* te); +static void modifyColumnEntries(List* targetList, forjson_table **tableInfoArr, int numTables, Alias *colnameAlias, bool isCve); extern bool pltsql_ansi_defaults; extern bool pltsql_quoted_identifier; @@ -1347,7 +1356,7 @@ pltsql_post_parse_analyze(ParseState *pstate, Query *query, JumbleState *jstate) } static bool -handleForJsonAuto(Query *query) +handleForJsonAuto(Query *query, forjson_table **tableInfoArr, int numTables) { Query* subq; List* target = query->targetList; @@ -1359,11 +1368,8 @@ handleForJsonAuto(Query *query) RangeTblEntry* subqRte; RangeTblEntry* queryRte; Alias *colnameAlias; - forjson_table **tableInfoArr; - int numTables = 0; - int currTables = 0; - int currMax = 0; - int i = 0; + int newTables = 0; + int currTables = numTables; if(!isJsonAuto(target)) return false; @@ -1377,24 +1383,30 @@ handleForJsonAuto(Query *query) if(subq != NULL && (subq->cteList == NULL || list_length(subq->cteList) == 0)) { subqRtable = (List*) subq->rtable; if(subqRtable != NULL && list_length(subqRtable) > 0) { + forjson_table **tempArr; foreach(lc, subqRtable) { subqRte = castNode(RangeTblEntry, lfirst(lc)); if(subqRte->rtekind == RTE_RELATION) { - numTables++; + newTables++; } else if(subqRte->rtekind == RTE_SUBQUERY) { ereport(ERROR, (errcode(ERRCODE_FEATURE_NOT_SUPPORTED), - errmsg("Values for json auto is not currently supported "))); + errmsg("sub-select and values for json auto are not currently supported."))); } } - if(numTables == 0) { + if(numTables + newTables == 0) { ereport(ERROR, (errcode(ERRCODE_UNDEFINED_TABLE), errmsg("FOR JSON AUTO requires at least one table for generating JSON objects. Use FOR JSON PATH or add a FROM clause with a table name."))); } - tableInfoArr = malloc(numTables * sizeof(forjson_table)); + tempArr = palloc((numTables + newTables) * sizeof(forjson_table)); + for(int j = 0; j < numTables; j++) { + tempArr[j] = tableInfoArr[j]; + } + tableInfoArr = tempArr; + tempArr = NULL; queryRte = linitial_node(RangeTblEntry, query->rtable); colnameAlias = (Alias*) queryRte->eref; @@ -1410,52 +1422,43 @@ handleForJsonAuto(Query *query) currTables++; } } - - foreach(lc, subq->targetList) { - TargetEntry* te = castNode(TargetEntry, lfirst(lc)); - int oid = te->resorigtbl; - for(int j = 0; j < numTables; j++) { - if(tableInfoArr[j]->oid == oid) { - // build entry - String* s = castNode(String, lfirst(list_nth_cell(colnameAlias->colnames, i))); - if(tableInfoArr[j]->nestLevel == -1) { - currMax++; - tableInfoArr[j]->nestLevel = currMax; - } - te = buildJsonEntry(tableInfoArr[j], te); - s->sval = te->resname; - break; - } - } - i++; - } - free(tableInfoArr); + numTables = numTables + newTables; + modifyColumnEntries(subq->targetList, tableInfoArr, numTables, colnameAlias, false); return true; } } else if(subq->cteList != NULL && list_length(subq->cteList) > 0) { Query* ctequery; CommonTableExpr* cte; + forjson_table **tempArr; foreach(lc, subq->cteList) { cte = castNode(CommonTableExpr, lfirst(lc)); ctequery = (Query*) cte->ctequery; foreach(lc2, ctequery->rtable) { subqRte = castNode(RangeTblEntry, lfirst(lc2)); if(subqRte->rtekind == RTE_RELATION) - numTables++; + newTables++; } } - if(numTables == 0) { + if(newTables == 0) { forjson_table *table = palloc(sizeof(forjson_table)); - tableInfoArr = malloc(sizeof(forjson_table)); + tempArr = palloc((numTables + 1) * sizeof(forjson_table)); table->oid = 0; table->nestLevel = -1; table->alias = "cteplaceholder"; - tableInfoArr[numTables] = table; - numTables++; + tempArr[numTables] = table; + newTables++; } else { - tableInfoArr = malloc(numTables * sizeof(forjson_table)); + tempArr = palloc((numTables + newTables) * sizeof(forjson_table)); + } + + for(int j = 0; j < numTables; j++) { + tempArr[j] = tableInfoArr[j]; } + + tableInfoArr = tempArr; + tempArr = NULL; + numTables = numTables + newTables; queryRte = linitial_node(RangeTblEntry, query->rtable); colnameAlias = (Alias*) queryRte->eref; @@ -1475,26 +1478,9 @@ handleForJsonAuto(Query *query) } } } + + modifyColumnEntries(subq->targetList, tableInfoArr, numTables, colnameAlias, true); - foreach(lc, subq->targetList) { - TargetEntry* te = castNode(TargetEntry, lfirst(lc)); - int oid = te->resorigtbl; - for(int j = 0; j < numTables; j++) { - if(tableInfoArr[j]->oid == oid) { - // build entry - String* s = castNode(String, lfirst(list_nth_cell(colnameAlias->colnames, i))); - if(tableInfoArr[j]->nestLevel == -1) { - currMax++; - tableInfoArr[j]->nestLevel = currMax; - } - te = buildJsonEntry(tableInfoArr[j], te); - s->sval = te->resname; - break; - } - } - i++; - } - free(tableInfoArr); return true; } } @@ -1534,35 +1520,79 @@ isJsonAuto(List* target) } static TargetEntry* -buildJsonEntry(forjson_table *table, TargetEntry* te) +buildJsonEntry(int nestLevel, char* tableAlias, TargetEntry* te) { char nest[NAMEDATALEN]; // check size appropriate StringInfo new_resname = makeStringInfo(); - sprintf(nest, "%d", table->nestLevel); + sprintf(nest, "%d", nestLevel); // Adding JSONAUTOALIAS prevents us from modifying // a column more than once if(!strcmp(te->resname, "\?column\?")) { ereport(ERROR, (errcode(ERRCODE_FEATURE_NOT_SUPPORTED), errmsg("column expressions and data sources without names or aliases cannot be formatted as JSON text using FOR JSON clause. Add alias to the unnamed column or table"))); - } - if(!strncmp(te->resname, "JSONAUTOALIAS", 13)) - return te; + } appendStringInfoString(new_resname, "JSONAUTOALIAS."); appendStringInfoString(new_resname, nest); appendStringInfoChar(new_resname, '.'); - appendStringInfoString(new_resname, table->alias); + appendStringInfoString(new_resname, tableAlias); appendStringInfoChar(new_resname, '.'); appendStringInfoString(new_resname, te->resname); te->resname = new_resname->data; return te; } -static bool check_json_auto_walker(Node *node, ParseState *pstate) { +static void modifyColumnEntries(List* targetList, forjson_table **tableInfoArr, int numTables, Alias *colnameAlias, bool isCve) +{ + int i = 0; + int currMax = 0; + ListCell* lc; + foreach(lc, targetList) { + TargetEntry* te = castNode(TargetEntry, lfirst(lc)); + int oid = te->resorigtbl; + String* s = castNode(String, lfirst(list_nth_cell(colnameAlias->colnames, i))); + if(te->expr != NULL && nodeTag(te->expr) == T_SubLink) { + SubLink *sl = castNode(SubLink, te->expr); + if(sl->subselect != NULL && nodeTag(sl->subselect) == T_Query) { + if(handleForJsonAuto(castNode(Query, sl->subselect), tableInfoArr, numTables)) { + CoerceViaIO *iocoerce = makeNode(CoerceViaIO); + iocoerce->arg = (Expr*) sl; + iocoerce->resulttype = 114; + iocoerce->resultcollid = 0; + iocoerce->coerceformat = COERCE_EXPLICIT_CAST; + buildJsonEntry(1, "temp", te); + s->sval = te->resname; + te->expr = (Expr*) iocoerce; + continue; + } + } + } + for(int j = 0; j < numTables; j++) { + if(tableInfoArr[j]->oid == oid) { + // build entry + if(tableInfoArr[j]->nestLevel == -1) { + currMax++; + tableInfoArr[j]->nestLevel = currMax; + } + te = buildJsonEntry(tableInfoArr[j]->nestLevel, tableInfoArr[j]->alias, te); + s->sval = te->resname; + break; + } else if(!isCve && oid == 0 && j == numTables - 1) { + te = buildJsonEntry(1, "temp", te); + s->sval = te->resname; + break; + } + } + i++; + } +} + +static bool check_json_auto_walker(Node *node, ParseState *pstate) +{ if (node == NULL) return false; if (IsA(node, Query)) { - if(handleForJsonAuto((Query*) node)) + if(handleForJsonAuto((Query*) node, NULL, 0)) return true; else { return query_tree_walker((Query*) node, @@ -3486,6 +3516,7 @@ bbf_ProcessUtility(PlannedStmt *pstmt, List *res; GrantStmt *stmt; PlannedStmt *wrapper; + RoleSpec *rolspec = create_schema->authrole; if (strcmp(queryString, "(CREATE LOGICAL DATABASE )") == 0 && context == PROCESS_UTILITY_SUBCOMMAND) @@ -3534,7 +3565,17 @@ bbf_ProcessUtility(PlannedStmt *pstmt, NULL); CommandCounterIncrement(); - + /* Grant ALL schema privileges to the user.*/ + if (rolspec && strcmp(queryString, "(CREATE LOGICAL DATABASE )") != 0) + { + int permissions[6] = {ACL_INSERT, ACL_SELECT, ACL_UPDATE, ACL_DELETE, ACL_REFERENCES, ACL_EXECUTE}; + int i; + for (i = 0; i < 6; i++) + { + /* Execute the GRANT SCHEMA subcommands. */ + exec_grantschema_subcmds(create_schema->schemaname, rolspec->rolename, true, false, permissions[i]); + } + } return; } else @@ -3548,7 +3589,6 @@ bbf_ProcessUtility(PlannedStmt *pstmt, { if (sql_dialect == SQL_DIALECT_TSQL) bbf_ExecDropStmt(drop_stmt); - break; } @@ -3560,10 +3600,11 @@ bbf_ProcessUtility(PlannedStmt *pstmt, * database command. */ const char *schemaname = strVal(lfirst(list_head(drop_stmt->objects))); + char *cur_db = get_cur_db_name(); + const char *logicalschema = get_logical_schema_name(schemaname, true); if (strcmp(queryString, "(DROP DATABASE )") != 0) { - char *cur_db = get_cur_db_name(); char *guest_schema_name = get_physical_schema_name(cur_db, "guest"); if (strcmp(schemaname, guest_schema_name) == 0) @@ -3576,6 +3617,7 @@ bbf_ProcessUtility(PlannedStmt *pstmt, bbf_ExecDropStmt(drop_stmt); del_ns_ext_info(schemaname, drop_stmt->missing_ok); + clean_up_bbf_schema_permissions(logicalschema, NULL, true); if (prev_ProcessUtility) prev_ProcessUtility(pstmt, queryString, readOnlyTree, context, params, @@ -3824,16 +3866,176 @@ bbf_ProcessUtility(PlannedStmt *pstmt, } break; } + case T_GrantStmt: + { + GrantStmt *grant = (GrantStmt *) parsetree; + char *dbname = get_cur_db_name(); + const char *current_user = GetUserNameFromId(GetUserId(), false); + /* Ignore when GRANT statement has no specific named object. */ + if (sql_dialect != SQL_DIALECT_TSQL || grant->targtype != ACL_TARGET_OBJECT) + break; + Assert(list_length(grant->objects) == 1); + if (grant->objtype == OBJECT_SCHEMA) + break; + else if (grant->objtype == OBJECT_TABLE) + { + /* Ignore CREATE database subcommands */ + if (strcmp("(CREATE LOGICAL DATABASE )", queryString) != 0) + { + RangeVar *rv = (RangeVar *) linitial(grant->objects); + const char *logical_schema = NULL; + char *obj = rv->relname; + ListCell *lc; + ListCell *lc1; + if (rv->schemaname != NULL) + logical_schema = get_logical_schema_name(rv->schemaname, true); + else + logical_schema = get_authid_user_ext_schema_name(dbname, current_user); + + /* If ALL PRIVILEGES is granted/revoked. */ + if (list_length(grant->privileges) == 0) + { + foreach(lc, grant->grantees) + { + RoleSpec *rol_spec = (RoleSpec *) lfirst(lc); + if (grant->is_grant) + add_or_update_object_in_bbf_schema(logical_schema, obj, ALL_PERMISSIONS_ON_RELATION, rol_spec->rolename, OBJ_RELATION, true); + else + { + /* + * 1. If permission on schema exists, don't revoke any permission from the object. + * 2. If permission on object exists, update the privilege in the catalog and revoke permission. + */ + update_privileges_of_object(logical_schema, obj, ALL_PERMISSIONS_ON_RELATION, rol_spec->rolename, OBJ_RELATION, false); + if (privilege_exists_in_bbf_schema_permissions(logical_schema, PERMISSIONS_FOR_ALL_OBJECTS_IN_SCHEMA, rol_spec->rolename, false)) + return; + } + } + call_prev_ProcessUtility(pstmt, queryString, readOnlyTree, context, params, queryEnv, dest, qc); + } + foreach(lc1, grant->privileges) + { + AccessPriv *ap = (AccessPriv *) lfirst(lc1); + AclMode privilege = string_to_privilege(ap->priv_name); + foreach(lc, grant->grantees) + { + RoleSpec *rol_spec = (RoleSpec *) lfirst(lc); + if (grant->is_grant) + { + call_prev_ProcessUtility(pstmt, queryString, readOnlyTree, context, params, queryEnv, dest, qc); + /* Don't add/update an entry, if the permission is granted on column list.*/ + if (ap->cols == NULL) + add_or_update_object_in_bbf_schema(logical_schema, obj, privilege, rol_spec->rolename, OBJ_RELATION, true); + } + else + { + /* + * If permission on schema exists, don't revoke any permission from the object. + */ + if (!privilege_exists_in_bbf_schema_permissions(logical_schema, PERMISSIONS_FOR_ALL_OBJECTS_IN_SCHEMA, rol_spec->rolename, false)) + { + call_prev_ProcessUtility(pstmt, queryString, readOnlyTree, context, params, queryEnv, dest, qc); + } + /* Don't update an entry, if the permission is granted on column list.*/ + if (ap->cols == NULL) + update_privileges_of_object(logical_schema, obj, privilege, rol_spec->rolename, OBJ_RELATION, false); + } + } + } + return; + } + } + else if ((grant->objtype == OBJECT_PROCEDURE) || (grant->objtype == OBJECT_FUNCTION)) + { + ObjectWithArgs *ob = (ObjectWithArgs *) linitial(grant->objects); + ListCell *lc; + ListCell *lc1; + const char *logicalschema = NULL; + char *funcname = NULL; + const char *obj_type = NULL; + if (grant->objtype == OBJECT_FUNCTION) + obj_type = OBJ_FUNCTION; + else + obj_type = OBJ_PROCEDURE; + if (list_length(ob->objname) == 1) + { + Node *func = (Node *) linitial(ob->objname); + funcname = strVal(func); + logicalschema = get_authid_user_ext_schema_name(dbname, current_user); + } + else + { + Node *schema = (Node *) linitial(ob->objname); + char *schemaname = strVal(schema); + Node *func = (Node *) lsecond(ob->objname); + logicalschema = get_logical_schema_name(schemaname, true); + funcname = strVal(func); + } + + /* If ALL PRIVILEGES is granted/revoked. */ + if (list_length(grant->privileges) == 0) + { + /* + * Case: When ALL PRIVILEGES is revoked internally during create function. + * Check if schema entry exists in the catalog, do not revoke any permission if exists. + */ + if ((pstmt->stmt_len == 0) && privilege_exists_in_bbf_schema_permissions(logicalschema, PERMISSIONS_FOR_ALL_OBJECTS_IN_SCHEMA, NULL, true)) + return; + + foreach(lc, grant->grantees) + { + RoleSpec *rol_spec = (RoleSpec *) lfirst(lc); + if (grant->is_grant) + { + add_or_update_object_in_bbf_schema(logicalschema, funcname, ALL_PERMISSIONS_ON_FUNCTION, rol_spec->rolename, obj_type, true); + } + else + { + /* + * 1. If permission on schema exists, don't revoke any permission from the object. + * 2. If permission on object exists, update the privilege in the catalog and revoke permission. + */ + update_privileges_of_object(logicalschema, funcname, ALL_PERMISSIONS_ON_FUNCTION, rol_spec->rolename, obj_type, false); + if (privilege_exists_in_bbf_schema_permissions(logicalschema, PERMISSIONS_FOR_ALL_OBJECTS_IN_SCHEMA, rol_spec->rolename, false)) + return; + } + } + call_prev_ProcessUtility(pstmt, queryString, readOnlyTree, context, params, queryEnv, dest, qc); + } + foreach(lc1, grant->privileges) + { + AccessPriv *ap = (AccessPriv *) lfirst(lc1); + AclMode privilege = string_to_privilege(ap->priv_name); + foreach(lc, grant->grantees) + { + RoleSpec *rol_spec = (RoleSpec *) lfirst(lc); + if (grant->is_grant) + { + call_prev_ProcessUtility(pstmt, queryString, readOnlyTree, context, params, queryEnv, dest, qc); + add_or_update_object_in_bbf_schema(logicalschema, funcname, privilege, rol_spec->rolename, obj_type, true); + } + else + { + /* + * If permission on schema exists, don't revoke any permission from the object. + */ + if (!privilege_exists_in_bbf_schema_permissions(logicalschema, PERMISSIONS_FOR_ALL_OBJECTS_IN_SCHEMA, rol_spec->rolename, false)) + { + call_prev_ProcessUtility(pstmt, queryString, readOnlyTree, context, params, queryEnv, dest, qc); + } + /* Update the privilege in the catalog. */ + update_privileges_of_object(logicalschema, funcname, privilege, rol_spec->rolename, obj_type, false); + } + } + } + return; + } + } default: break; } - if (prev_ProcessUtility) - prev_ProcessUtility(pstmt, queryString, readOnlyTree, context, params, - queryEnv, dest, qc); - else - standard_ProcessUtility(pstmt, queryString, readOnlyTree, context, params, - queryEnv, dest, qc); + call_prev_ProcessUtility(pstmt, queryString, readOnlyTree, context, params, queryEnv, dest, qc); /* Cleanup babelfish_server_options catalog when tds_fdw extension is dropped */ if (sql_dialect == SQL_DIALECT_PG && nodeTag(parsetree) == T_DropStmt) @@ -3850,6 +4052,24 @@ bbf_ProcessUtility(PlannedStmt *pstmt, } } +static void +call_prev_ProcessUtility(PlannedStmt *pstmt, + const char *queryString, + bool readOnlyTree, + ProcessUtilityContext context, + ParamListInfo params, + QueryEnvironment *queryEnv, + DestReceiver *dest, + QueryCompletion *qc) +{ + if (prev_ProcessUtility) + prev_ProcessUtility(pstmt, queryString, readOnlyTree, context, params, + queryEnv, dest, qc); + else + standard_ProcessUtility(pstmt, queryString, readOnlyTree, context, params, + queryEnv, dest, qc); +} + /* * Update the pg_type catalog entry for the given name to have * typbyval set to the given value. @@ -5931,6 +6151,7 @@ bbf_ExecDropStmt(DropStmt *stmt) Relation relation = NULL; Oid schema_oid; ListCell *cell; + const char *logicalschema = NULL; db_id = get_cur_db_id(); @@ -5971,6 +6192,8 @@ bbf_ExecDropStmt(DropStmt *stmt) schema_oid = get_object_namespace(&address); if (OidIsValid(schema_oid)) schema_name = get_namespace_name(schema_oid); + if (schema_name != NULL) + logicalschema = get_logical_schema_name(schema_name, true); if (schema_name && major_name) { @@ -5996,6 +6219,7 @@ bbf_ExecDropStmt(DropStmt *stmt) major_name, NULL); } } + clean_up_bbf_schema_permissions(logicalschema, major_name, false); } } else if (stmt->removeType == OBJECT_PROCEDURE || @@ -6039,6 +6263,8 @@ bbf_ExecDropStmt(DropStmt *stmt) schema_oid = get_object_namespace(&address); if (OidIsValid(schema_oid)) schema_name = get_namespace_name(schema_oid); + if (schema_name != NULL) + logicalschema = get_logical_schema_name(schema_name, true); if (schema_name && major_name) { @@ -6052,6 +6278,7 @@ bbf_ExecDropStmt(DropStmt *stmt) delete_extended_property(db_id, type, schema_name, major_name, NULL); } + clean_up_bbf_schema_permissions(logicalschema, major_name, false); } } } diff --git a/contrib/babelfishpg_tsql/src/pltsql.h b/contrib/babelfishpg_tsql/src/pltsql.h index 1fac4546099..15223c2b7af 100644 --- a/contrib/babelfishpg_tsql/src/pltsql.h +++ b/contrib/babelfishpg_tsql/src/pltsql.h @@ -197,6 +197,7 @@ typedef enum PLtsql_stmt_type PLTSQL_STMT_CHANGE_DBOWNER, PLTSQL_STMT_DBCC, PLTSQL_STMT_FULLTEXTINDEX, + PLTSQL_STMT_GRANTSCHEMA } PLtsql_stmt_type; /* @@ -1067,6 +1068,20 @@ typedef struct PLtsql_stmt_fulltextindex bool is_create; /* flag for create index */ } PLtsql_stmt_fulltextindex; +/* + * Grant on schema stmt + */ +typedef struct PLtsql_stmt_grantschema +{ + PLtsql_stmt_type cmd_type; + int lineno; + bool is_grant; + int privileges; + List *grantees; /* list of users */ + bool with_grant_option; + char *schema_name; /* schema name */ +} PLtsql_stmt_grantschema; + /* * ASSERT statement */ @@ -1988,6 +2003,8 @@ extern void pltsql_exec_get_datum_type_info(PLtsql_execstate *estate, extern int get_insert_bulk_rows_per_batch(void); extern int get_insert_bulk_kilobytes_per_batch(void); extern char *get_original_query_string(void); +extern AclMode string_to_privilege(const char *privname); +extern const char *privilege_to_string(AclMode privilege); /* * Functions for namespace handling in pl_funcs.c @@ -2049,6 +2066,7 @@ extern char *get_fulltext_index_name(Oid relid, const char *table_name); extern const char *gen_schema_name_for_fulltext_index(const char *schema_name); extern bool check_fulltext_exist(const char *schema_name, const char *table_name); extern bool is_unique_index(Oid relid, const char *index_name); +extern void exec_grantschema_subcmds(const char *schema, const char *rolname, bool is_grant, bool with_grant_option, AclMode privilege); extern int TsqlUTF8LengthInUTF16(const void *vin, int len); extern void TsqlCheckUTF16Length_bpchar(const char *s, int32 len, int32 maxlen, int charlen, bool isExplicit); extern void TsqlCheckUTF16Length_varchar(const char *s, int32 len, int32 maxlen, bool isExplicit); @@ -2087,7 +2105,7 @@ extern void update_DropOwnedStmt(Node *n, List *role_list); extern void update_DropRoleStmt(Node *n, const char *role); extern void update_DropStmt(Node *n, const char *object); extern void update_GrantRoleStmt(Node *n, List *privs, List *roles); -extern void update_GrantStmt(Node *n, const char *object, const char *obj_schema, const char *grantee); +extern void update_GrantStmt(Node *n, const char *object, const char *obj_schema, const char *grantee, const char *priv); extern void update_RenameStmt(Node *n, const char *old_name, const char *new_name); extern void update_ViewStmt(Node *n, const char *view_schema); extern void pltsql_check_or_set_default_typmod(TypeName *typeName, int32 *typmod, bool is_cast); diff --git a/contrib/babelfishpg_tsql/src/pltsql_utils.c b/contrib/babelfishpg_tsql/src/pltsql_utils.c index bc272aab1d7..74d23482749 100644 --- a/contrib/babelfishpg_tsql/src/pltsql_utils.c +++ b/contrib/babelfishpg_tsql/src/pltsql_utils.c @@ -1021,7 +1021,7 @@ update_GrantRoleStmt(Node *n, List *privs, List *roles) } void -update_GrantStmt(Node *n, const char *object, const char *obj_schema, const char *grantee) +update_GrantStmt(Node *n, const char *object, const char *obj_schema, const char *grantee, const char *priv) { GrantStmt *stmt = (GrantStmt *) n; @@ -1033,16 +1033,49 @@ update_GrantStmt(Node *n, const char *object, const char *obj_schema, const char else if (obj_schema && stmt->objects) { RangeVar *tmp = (RangeVar *) llast(stmt->objects); - tmp->schemaname = pstrdup(obj_schema); } if (grantee && stmt->grantees) { RoleSpec *tmp = (RoleSpec *) llast(stmt->grantees); - + if (strcmp(grantee, PUBLIC_ROLE_NAME) == 0) + { + tmp->roletype = ROLESPEC_PUBLIC; + } tmp->rolename = pstrdup(grantee); } + + if (priv && stmt->privileges) + { + AccessPriv *tmp = (AccessPriv *) llast(stmt->privileges); + tmp->priv_name = pstrdup(priv); + } +} + +static void +update_AlterDefaultPrivilegesStmt(Node *n, const char *object, const char *grantee, const char *priv) +{ + AlterDefaultPrivilegesStmt *stmt = (AlterDefaultPrivilegesStmt *) n; + ListCell *lc; + + if (!IsA(stmt, AlterDefaultPrivilegesStmt)) + ereport(ERROR, (errcode(ERRCODE_SYNTAX_ERROR), errmsg("query is not a AlterDefaultPrivilegesStmt"))); + + if (grantee && priv && stmt->action) + { + update_GrantStmt((Node *)(stmt->action), NULL, NULL, grantee, priv); + } + + foreach(lc, stmt->options) + { + if (object) + { + DefElem *tmp = (DefElem *) lfirst(lc); + tmp->defname = pstrdup("schemas"); + tmp->arg = (Node *)list_make1(makeString((char *)object)); + } + } } void @@ -1978,3 +2011,152 @@ exec_alter_role_cmd(char *query_str, RoleSpec *role) /* make sure later steps can see the object created here */ CommandCounterIncrement(); } + +/* + * Helper function to generate GRANT on SCHEMA subcommands. + */ +static List +*gen_grantschema_subcmds(const char *schema, const char *rolname, bool is_grant, bool with_grant_option, AclMode privilege) +{ + StringInfoData query; + List *stmt_list; + Node *stmt; + int expected_stmts = 2; + int i = 0; + initStringInfo(&query); + if (is_grant) + { + if (privilege == ACL_EXECUTE) + { + if (with_grant_option) + { + appendStringInfo(&query, "GRANT dummy ON ALL FUNCTIONS IN SCHEMA dummy TO dummy WITH GRANT OPTION; "); + appendStringInfo(&query, "GRANT dummy ON ALL PROCEDURES IN SCHEMA dummy TO dummy WITH GRANT OPTION; "); + } + else + { + appendStringInfo(&query, "GRANT dummy ON ALL FUNCTIONS IN SCHEMA dummy TO dummy; "); + appendStringInfo(&query, "GRANT dummy ON ALL PROCEDURES IN SCHEMA dummy TO dummy; "); + } + } + else + { + if (with_grant_option) + appendStringInfo(&query, "GRANT dummy ON ALL TABLES IN SCHEMA dummy TO dummy WITH GRANT OPTION; "); + else + appendStringInfo(&query, "GRANT dummy ON ALL TABLES IN SCHEMA dummy TO dummy; "); + appendStringInfo(&query, "ALTER DEFAULT PRIVILEGES IN SCHEMA dummy GRANT dummy ON TABLES TO dummy; "); + } + } + else + { + if (privilege == ACL_EXECUTE) + { + appendStringInfo(&query, "REVOKE dummy ON ALL FUNCTIONS IN SCHEMA dummy FROM dummy; "); + appendStringInfo(&query, "REVOKE dummy ON ALL PROCEDURES IN SCHEMA dummy FROM dummy; "); + } + else + { + appendStringInfo(&query, "REVOKE dummy ON ALL TABLES IN SCHEMA dummy FROM dummy; "); + appendStringInfo(&query, "ALTER DEFAULT PRIVILEGES IN SCHEMA dummy REVOKE dummy ON TABLES FROM dummy; "); + } + } + stmt_list = raw_parser(query.data, RAW_PARSE_DEFAULT); + if (list_length(stmt_list) != expected_stmts) + ereport(ERROR, + (errcode(ERRCODE_SYNTAX_ERROR), + errmsg("Expected %d statements, but got %d statements after parsing", + expected_stmts, list_length(stmt_list)))); + /* Replace dummy elements in parsetree with real values */ + stmt = parsetree_nth_stmt(stmt_list, i++); + update_GrantStmt(stmt, schema, NULL, rolname, privilege_to_string(privilege)); + + stmt = parsetree_nth_stmt(stmt_list, i++); + if (privilege == ACL_EXECUTE) + update_GrantStmt(stmt, schema, NULL, rolname, privilege_to_string(privilege)); + else + update_AlterDefaultPrivilegesStmt(stmt, schema, rolname, privilege_to_string(privilege)); + + pfree(query.data); + return stmt_list; +} + +/* + * Helper function to execute GRANT on SCHEMA subcommands using + * ProcessUtility(). Caller should make sure their + * inputs are sanitized to prevent unexpected behaviour. + */ +void +exec_grantschema_subcmds(const char *schema, const char *rolname, bool is_grant, bool with_grant_option, AclMode privilege) +{ + List *parsetree_list; + ListCell *parsetree_item; + + parsetree_list = gen_grantschema_subcmds(schema, rolname, is_grant, with_grant_option, privilege); + /* Run all subcommands */ + foreach(parsetree_item, parsetree_list) + { + Node *stmt = ((RawStmt *) lfirst(parsetree_item))->stmt; + PlannedStmt *wrapper; + + /* need to make a wrapper PlannedStmt */ + wrapper = makeNode(PlannedStmt); + wrapper->commandType = CMD_UTILITY; + wrapper->canSetTag = false; + wrapper->utilityStmt = stmt; + wrapper->stmt_location = 0; + wrapper->stmt_len = 0; + + /* do this step */ + ProcessUtility(wrapper, + "(GRANT SCHEMA )", + false, + PROCESS_UTILITY_SUBCOMMAND, + NULL, + NULL, + None_Receiver, + NULL); + } +} + +AclMode +string_to_privilege(const char *privname) +{ + if (strcmp(privname, "insert") == 0) + return ACL_INSERT; + if (strcmp(privname, "select") == 0) + return ACL_SELECT; + if (strcmp(privname, "update") == 0) + return ACL_UPDATE; + if (strcmp(privname, "delete") == 0) + return ACL_DELETE; + if (strcmp(privname, "references") == 0) + return ACL_REFERENCES; + if (strcmp(privname, "execute") == 0) + return ACL_EXECUTE; + else + return 0; +} + +const char * +privilege_to_string(AclMode privilege) +{ + switch (privilege) + { + case ACL_INSERT: + return "insert"; + case ACL_SELECT: + return "select"; + case ACL_UPDATE: + return "update"; + case ACL_DELETE: + return "delete"; + case ACL_REFERENCES: + return "references"; + case ACL_EXECUTE: + return "execute"; + default: + elog(ERROR, "unrecognized privilege: %d", (int) privilege); + } + return NULL; +} \ No newline at end of file diff --git a/contrib/babelfishpg_tsql/src/stmt_walker.c b/contrib/babelfishpg_tsql/src/stmt_walker.c index 6d996059d87..b606a4f7f31 100644 --- a/contrib/babelfishpg_tsql/src/stmt_walker.c +++ b/contrib/babelfishpg_tsql/src/stmt_walker.c @@ -110,6 +110,7 @@ stmt_walker(PLtsql_stmt *stmt, WalkerFunc walker, void *context) case PLTSQL_STMT_CHANGE_DBOWNER: case PLTSQL_STMT_FULLTEXTINDEX: case PLTSQL_STMT_DBCC: + case PLTSQL_STMT_GRANTSCHEMA: break; /* TSQL-only executable node */ case PLTSQL_STMT_SAVE_CTX: @@ -211,6 +212,7 @@ general_walker_func(PLtsql_stmt *stmt, void *context) DISPATCH(CHANGE_DBOWNER, change_dbowner) DISPATCH(DBCC, dbcc) DISPATCH(FULLTEXTINDEX, fulltextindex) + DISPATCH(GRANTSCHEMA, grantschema) /* TSQL-only executable node */ DISPATCH(SAVE_CTX, save_ctx) diff --git a/contrib/babelfishpg_tsql/src/stmt_walker.h b/contrib/babelfishpg_tsql/src/stmt_walker.h index 885f0058a56..7704d9c4f1d 100644 --- a/contrib/babelfishpg_tsql/src/stmt_walker.h +++ b/contrib/babelfishpg_tsql/src/stmt_walker.h @@ -90,6 +90,7 @@ typedef bool (*Stmt_grantdb_act) ACTION_SIGNITURE(grantdb); typedef bool (*Stmt_change_dbowner_act) ACTION_SIGNITURE(change_dbowner); typedef bool (*Stmt_dbcc_act) ACTION_SIGNITURE(dbcc); typedef bool (*Stmt_fulltextindex_act) ACTION_SIGNITURE(fulltextindex); +typedef bool (*Stmt_grantschema_act) ACTION_SIGNITURE(grantschema); /* TSQL-only executable node */ typedef bool (*Stmt_save_ctx) ACTION_SIGNITURE(save_ctx); @@ -143,6 +144,7 @@ typedef struct Walker_context Stmt_change_dbowner_act change_dbowner_act; Stmt_dbcc_act dbcc_act; Stmt_fulltextindex_act fulltextindex_act; + Stmt_grantschema_act grantschema_act; /* TSQL-only executable node */ Stmt_save_ctx save_ctx_act; diff --git a/contrib/babelfishpg_tsql/src/tsqlIface.cpp b/contrib/babelfishpg_tsql/src/tsqlIface.cpp index 31ec423df02..71582b572ae 100644 --- a/contrib/babelfishpg_tsql/src/tsqlIface.cpp +++ b/contrib/babelfishpg_tsql/src/tsqlIface.cpp @@ -25,6 +25,7 @@ #define JOIN_HINTS_INFO_VECTOR_SIZE 6 #define RAISE_ERROR_PARAMS_LIMIT 20 +#define PUBLIC_ROLE_NAME "public" #pragma GCC diagnostic push @@ -173,6 +174,12 @@ static void process_select_statement_standalone(TSqlParser::Select_statement_sta template static std::string rewrite_object_name_with_omitted_db_and_schema_name(T ctx, GetCtxFunc getDatabase, GetCtxFunc getSchema); template static std::string rewrite_information_schema_to_information_schema_tsql(T ctx, GetCtxFunc getSchema); template static std::string rewrite_column_name_with_omitted_schema_name(T ctx, GetCtxFunc getSchema, GetCtxFunc getTableName); +template static void rewrite_geospatial_query_helper(T ctx, TSqlParser::Method_callContext *method, size_t geospatial_start_index); +template static void rewrite_geospatial_col_ref_query_helper(T ctx, TSqlParser::Method_callContext *method, size_t geospatial_start_index); +template static void rewrite_geospatial_func_ref_no_arg_query_helper(T ctx, TSqlParser::Method_callContext *method, size_t geospatial_start_index); +template static void rewrite_geospatial_func_ref_args_query_helper(T ctx, TSqlParser::Method_callContext *method, size_t geospatial_start_index); +template static void rewrite_function_call_geospatial_func_ref_args(T ctx); +template static void rewrite_function_call_geospatial_func_ref_no_arg(T ctx); static bool does_object_name_need_delimiter(TSqlParser::IdContext *id); static std::string delimit_identifier(TSqlParser::IdContext *id); static bool does_msg_exceeds_params_limit(const std::string& msg); @@ -186,9 +193,12 @@ static const std::string fragment_SELECT_prefix = "SELECT "; // fragment prefix static const std::string fragment_EXEC_prefix = "EXEC "; // fragment prefix for execute_body_batch static PLtsql_stmt *makeChangeDbOwnerStatement(TSqlParser::Alter_authorizationContext *ctx); static void handleFloatWithoutExponent(TSqlParser::ConstantContext *ctx); +static void handleTableConstraintWithoutComma(TSqlParser::Column_def_table_constraintsContext *ctx); static void handleBitNotOperator(TSqlParser::Unary_op_exprContext *ctx); static void handleBitOperators(TSqlParser::Plus_minus_bit_exprContext *ctx); static void handleModuloOperator(TSqlParser::Mult_div_percent_exprContext *ctx); +static void handleAtAtVarInPredicate(TSqlParser::PredicateContext *ctx); +static void handleOrderByOffsetFetch(TSqlParser::Order_by_clauseContext *ctx); /* * Structure / Utility function for general purpose of query string modification @@ -651,9 +661,14 @@ void PLtsql_expr_query_mutator::run() const std::u32string& orig_text = utf8_to_utf32(entry.second.first.c_str()); const std::u32string& repl_text = utf8_to_utf32(entry.second.second.c_str()); if (isSelectFragment) offset += fragment_SELECT_prefix.length(); // because this is an expression prefixed with 'SELECT ' - + if (orig_text.length() == 0 || orig_text.c_str(), query.substr(offset, orig_text.length()) == orig_text) // local_id maybe already deleted in some cases such as select-assignment. check here if it still exists) { + // Note: the test below does not work, and has never worked, because size_t will not be negative, + // and the result of the subtraction is also of type size_t. + // This test has been in the code since day 1. + // When making the test work, some test cases will start failing as they run into this condition + // (test table_variable_xact_errors and two variants). Therefore, not touching the test for now. if (offset - cursor < 0) throw PGErrorWrapperException(ERROR, ERRCODE_INTERNAL_ERROR, "can't mutate an internal query. might be due to multiple mutations on the same position", 0, 0); if (offset - cursor > 0) // if offset==cursor, no need to copy @@ -881,10 +896,149 @@ class tsqlCommonMutator : public TSqlParserBaseListener rewritten_query_fragment.emplace(std::make_pair(ctx->id().back()->start->getStartIndex(), std::make_pair(::getFullText(ctx->id().back()), delimit_identifier(ctx->id().back())))); } + void exitFunction_call(TSqlParser::Function_callContext *ctx) override + { + /* Handles rewrite of geospatial function calls but inside body of CREATE/ALTER View, Procedure, Function */ + if (ctx->spatial_proc_name_server_database_schema()) + { + if (ctx->spatial_proc_name_server_database_schema()->schema) throw PGErrorWrapperException(ERROR, ERRCODE_FEATURE_NOT_SUPPORTED, "Remote procedure/function reference with 4-part object name is not currently supported in Babelfish", getLineAndPos(ctx)); + + /* This if-elseIf clause rewrites the query in case of Geospatial function Call */ + if (ctx->spatial_proc_name_server_database_schema()->geospatial_func_arg() && ctx->function_arg_list()) + rewrite_function_call_geospatial_func_ref_args(ctx); + else if (ctx->spatial_proc_name_server_database_schema()->geospatial_func_no_arg() && !ctx->function_arg_list()) + rewrite_function_call_geospatial_func_ref_no_arg(ctx); + } + } + + /* We are adding handling for Spatial Types in: + * tsqlCommonMutator: for CREATE/ALTER View, Procedure, Function + * tsqlBuilder: for other cases handling + */ + /* Here we are Rewriting Geospatial query query: Func_call DOT Geospatial_Func: + * Func_call DOT Geospatial_col -> ( Func_call ) DOT Geospatial_col + * Func_call DOT Geospatial_func (arg_list) -> Geospatial_func (agr_list, Func_call) + */ + void exitFunc_call_expr(TSqlParser::Func_call_exprContext *ctx) override + { + if(ctx != NULL && !ctx->DOT().empty()) + { + std::vector method_calls = ctx->method_call(); + for (size_t i = 0; i < method_calls.size(); ++i) + { + TSqlParser::Method_callContext *method = method_calls[i]; + /* rewriting the query in case of Geospatial function Call -> function_call.method_call */ + if(method->spatial_methods()) + { + size_t ind; + if (i == 0) ind = ctx->function_call()->stop->getStopIndex(); + else ind = method_calls[i-1]->stop->getStopIndex(); + rewrite_geospatial_query_helper(ctx, method, ind); + } + } + } + } + + /* Handles rewrite of geospatial query but inside body of CREATE/ALTER View, Procedure, Function: + * local_id DOT Geospatial_col -> ( local_id ) DOT Geospatial_col + * local_id DOT Geospatial_func (arg_list) -> Geospatial_func (agr_list, local_id) + */ + void exitLocal_id_expr(TSqlParser::Local_id_exprContext *ctx) override + { + if(ctx != NULL && !ctx->DOT().empty()) + { + std::vector method_calls = ctx->method_call(); + for (size_t i = 0; i < method_calls.size(); ++i) + { + TSqlParser::Method_callContext *method = method_calls[i]; + /* rewriting the query in case of Geospatial function Call -> local_id.method_call */ + if(method->spatial_methods()) + { + size_t ind; + if (i == 0) ind = ctx->local_id()->stop->getStopIndex(); + else ind = method_calls[i-1]->stop->getStopIndex(); + rewrite_geospatial_query_helper(ctx, method, ind); + } + } + } + } + + /* Handles rewrite of geospatial query but inside body of CREATE/ALTER View, Procedure, Function: + * bracket_expr DOT Geospatial_col -> ( bracket_expr ) DOT Geospatial_col + * bracket_expr DOT Geospatial_func (arg_list) -> Geospatial_func (agr_list, bracket_expr) + */ + void exitBracket_expr(TSqlParser::Bracket_exprContext *ctx) override + { + if(ctx != NULL && !ctx->DOT().empty()) + { + std::vector method_calls = ctx->method_call(); + for (size_t i = 0; i < method_calls.size(); ++i) + { + TSqlParser::Method_callContext *method = method_calls[i]; + /* rewriting the query in case of Geospatial function Call -> LR_BRACKET expression RR_BRACKET.method_call */ + if(method->spatial_methods()) + { + size_t ind; + std::string context = ::getFullText(ctx); + size_t spaces = 0; + for (size_t x = ctx->expression()->stop->getStopIndex() + 1 - ctx->start->getStartIndex(); x <= ctx->stop->getStopIndex() - ctx->start->getStartIndex(); x++) + { + if(context[x] == ' ') spaces++; + else if(context[x] == ')') break; + } + if (i == 0) ind = ctx->expression()->stop->getStopIndex() + 1 + spaces; + else ind = method_calls[i-1]->stop->getStopIndex(); + rewrite_geospatial_query_helper(ctx, method, ind); + } + } + } + } + + /* Handles rewrite of geospatial query but inside body of CREATE/ALTER View, Procedure, Function: + * Subquery_expr DOT Geospatial_col -> ( Subquery_expr ) DOT Geospatial_col + * Subquery_expr DOT Geospatial_func (arg_list) -> Geospatial_func (agr_list, Subquery_expr) + */ + void exitSubquery_expr(TSqlParser::Subquery_exprContext *ctx) override + { + if(ctx != NULL && !ctx->DOT().empty()) + { + std::vector method_calls = ctx->method_call(); + for (size_t i = 0; i < method_calls.size(); ++i) + { + TSqlParser::Method_callContext *method = method_calls[i]; + /* rewriting the query in case of Geospatial function Call -> subquery.method_call */ + if(method->spatial_methods()) + { + size_t ind; + if (i == 0) ind = ctx->subquery()->stop->getStopIndex(); + else ind = method_calls[i-1]->stop->getStopIndex(); + rewrite_geospatial_query_helper(ctx, method, ind); + } + } + } + } + void exitFull_column_name(TSqlParser::Full_column_nameContext *ctx) override { GetCtxFunc getSchema = [](TSqlParser::Full_column_nameContext *o) { return o->schema; }; GetCtxFunc getTablename = [](TSqlParser::Full_column_nameContext *o) { return o->tablename; }; + + /* This if clause rewrites the query in case of Geospatial function Call */ + std::string func_name; + /* Handles rewrite of geospatial query but inside body of CREATE/ALTER View, Procedure, Function: */ + if(ctx->column_name) func_name = stripQuoteFromId(ctx->column_name); + else if (ctx->geospatial_col()) + { + /* Throwing error similar to TSQL as we do not allow 4-Part name for geospatial function call */ + if(ctx->schema) throw PGErrorWrapperException(ERROR, ERRCODE_SYNTAX_ERROR, format_errmsg("The multi-part identifier \"%s\" could not be bound.", ::getFullText(ctx).c_str()), getLineAndPos(ctx)); + + /* Rewriting the query as: table.col.STX -> (table.col).STX */ + std::string rewritten_func_name = "("; + if(ctx->table) rewritten_func_name += stripQuoteFromId(ctx->table) + "."; + rewritten_func_name += stripQuoteFromId(ctx->column) + ")." + ::getFullText(ctx->geospatial_col()); + rewritten_query_fragment.emplace(std::make_pair(ctx->start->getStartIndex(), std::make_pair(::getFullText(ctx), rewritten_func_name.c_str()))); + } + std::string rewritten_name = rewrite_column_name_with_omitted_schema_name(ctx, getSchema, getTablename); std::string rewritten_schema_name = rewrite_information_schema_to_information_schema_tsql(ctx, getSchema); if (!rewritten_name.empty()) @@ -1045,26 +1199,6 @@ class tsqlCommonMutator : public TSqlParserBaseListener { rewritten_query_fragment.emplace(std::make_pair(ctx->schema->start->getStartIndex(), std::make_pair(::getFullText(ctx->schema), rewritten_schema_name))); } - - #ifdef ENABLE_SPATIAL_TYPES - if(!ctx->id().empty() && ctx->id()[0]->id().size() == 2) - { - TSqlParser::IdContext *idctx = ctx->id()[0]; - if(idctx->id()[0] && idctx->colon_colon() && idctx->id()[1]) - { - std::string idText = ::getFullText(idctx->id()[0]); - transform(idText.begin(), idText.end(), idText.begin(), ::tolower); - size_t start = idText.find_first_not_of(" \n\r\t\f\v"); - idText = (start == std::string::npos) ? "" : idText.substr(start); - size_t end = idText.find_last_not_of(" \n\r\t\f\v"); - idText = (end == std::string::npos) ? "" : idText.substr(0, end + 1); - if(idText == "geography" || idText == "geometry"){ - rewritten_query_fragment.emplace(std::make_pair(idctx->start->getStartIndex(), std::make_pair(::getFullText(idctx->id()[0]), idText))); - rewritten_query_fragment.emplace(std::make_pair(idctx->colon_colon()->start->getStartIndex(), std::make_pair(::getFullText(idctx->colon_colon()), "__"))); - } - } - } - #endif // don't need to call does_object_name_need_delimiter() because problematic keywords are already allowed as function name } @@ -1893,32 +2027,80 @@ class tsqlBuilder : public tsqlCommonMutator void exitSecurity_statement(TSqlParser::Security_statementContext *ctx) override { - if (ctx->grant_statement() && ctx->grant_statement()->TO() && !ctx->grant_statement()->permission_object() - && ctx->grant_statement()->permissions()) + if (ctx->grant_statement()) { - for (auto perm : ctx->grant_statement()->permissions()->permission()) + auto grant = ctx->grant_statement(); + if (grant->TO() && !grant->permission_object() && grant->permissions()) { - auto single_perm = perm->single_permission(); - if (single_perm->CONNECT()) + for (auto perm : grant->permissions()->permission()) { - clear_rewritten_query_fragment(); - return; + auto single_perm = perm->single_permission(); + if (single_perm->CONNECT()) + { + clear_rewritten_query_fragment(); + return; + } + } + } + else if (grant->ON() && grant->permission_object() && grant->permission_object()->object_type() && grant->permission_object()->object_type()->SCHEMA()) + { + if (grant->TO() && grant->principals() && grant->permissions()) + { + for (auto perm: grant->permissions()->permission()) + { + auto single_perm = perm->single_permission(); + if (single_perm->EXECUTE() + || single_perm->EXEC() + || single_perm->SELECT() + || single_perm->INSERT() + || single_perm->UPDATE() + || single_perm->DELETE() + || single_perm->REFERENCES()) + { + return; + } + } } } } - else if (ctx->revoke_statement() && ctx->revoke_statement()->FROM() && !ctx->revoke_statement()->permission_object() - && ctx->revoke_statement()->permissions()) + else if (ctx->revoke_statement()) { - for (auto perm : ctx->revoke_statement()->permissions()->permission()) + auto revoke = ctx->revoke_statement(); + if (revoke->FROM() && !revoke->permission_object() && revoke->permissions()) { - auto single_perm = perm->single_permission(); - if (single_perm->CONNECT()) + for (auto perm : revoke->permissions()->permission()) { - clear_rewritten_query_fragment(); - return; + auto single_perm = perm->single_permission(); + if (single_perm->CONNECT()) + { + clear_rewritten_query_fragment(); + return; + } + } + } + + else if (revoke->ON() && revoke->permission_object() && revoke->permission_object()->object_type() && revoke->permission_object()->object_type()->SCHEMA()) + { + if (revoke->FROM() && revoke->principals() && revoke->permissions()) + { + for (auto perm: revoke->permissions()->permission()) + { + auto single_perm = perm->single_permission(); + if (single_perm->EXECUTE() + || single_perm->EXEC() + || single_perm->SELECT() + || single_perm->INSERT() + || single_perm->UPDATE() + || single_perm->DELETE() + || single_perm->REFERENCES()) + { + return; + } + } } } } + PLtsql_stmt_execsql *stmt = (PLtsql_stmt_execsql *) getPLtsql_fragment(ctx); Assert(stmt); @@ -2132,47 +2314,6 @@ class tsqlBuilder : public tsqlCommonMutator // TO-DO } - // NB: this is copied in tsqlMutator - void exitConstant(TSqlParser::ConstantContext *ctx) override - { - // Check for floating-point number without exponent - handleFloatWithoutExponent(ctx); - } - - void exitPredicate(TSqlParser::PredicateContext *ctx) override - { - // For comparison operators directly followed by an '@@' variable, insert a space - // to avoid these being parsed incorrectly by PG; this applies to the following - // character sequences: =@@, >@@, <@@ as well as !=@ (i.e. a single-@ variable) - // Note: this issue does not occur for assignments like 'SET @v=@@spid' or column aliases like 'SELECT a=@@spid' - - if ((ctx->comparison_operator()) && (ctx->expression().size() > 1)) - { - std::string op = getFullText(ctx->comparison_operator()); - if ((op.back() == '=') || - (op.back() == '>') || - (op.back() == '<')) - { - // The operator must be followed immediately by the variable without any character in between - Assert(ctx->expression(1)); - size_t startPosition = ctx->expression(1)->start->getStartIndex(); - if ((startPosition - ctx->comparison_operator()->stop->getStopIndex()) == 1) - { - std::string var = getFullText(ctx->expression(1)); - // The subsequent expression must be a variable starting with '@@' - if (var.front() == '@') - { - if ((var.at(1) == '@') || (pg_strncasecmp(op.c_str(), "!=", 2) == 0)) - { - // Insert a space before the variable name - rewritten_query_fragment.emplace(std::make_pair(startPosition, std::make_pair(var, " "+var))); - } - } - } - } - } - } - void exitExecute_statement_arg_named(TSqlParser::Execute_statement_arg_namedContext *ctx) override { // Look for named arguments with an @@variable with no preceding whitespace, i.e. 'exec myproc @p=@@spid' @@ -2195,8 +2336,27 @@ class tsqlBuilder : public tsqlCommonMutator } } } - - // NB: this is copied in TsqlMutator + + void exitOrder_by_clause(TSqlParser::Order_by_clauseContext *ctx) override + { + handleOrderByOffsetFetch(ctx); + } + + // NB: the following are copied in tsqlMutator + void exitColumn_def_table_constraints(TSqlParser::Column_def_table_constraintsContext *ctx) + { + handleTableConstraintWithoutComma(ctx); + } + void exitConstant(TSqlParser::ConstantContext *ctx) override + { + // Check for floating-point number without exponent + handleFloatWithoutExponent(ctx); + } + void exitPredicate(TSqlParser::PredicateContext *ctx) override + { + // Check for comparison operators directly followed by an '@@' variable, like =@@ + handleAtAtVarInPredicate(ctx); + } void exitUnary_op_expr(TSqlParser::Unary_op_exprContext *ctx) override { handleBitNotOperator(ctx); @@ -2260,6 +2420,132 @@ class tsqlBuilder : public tsqlCommonMutator } } + void exitFull_column_name(TSqlParser::Full_column_nameContext *ctx) override + { + GetCtxFunc getSchema = [](TSqlParser::Full_column_nameContext *o) { return o->schema; }; + GetCtxFunc getTablename = [](TSqlParser::Full_column_nameContext *o) { return o->tablename; }; + + /* Handles rewrite of geospatial query except inside body of CREATE/ALTER View, Procedure, Function: */ + std::string func_name; + if(ctx->column_name) func_name = stripQuoteFromId(ctx->column_name); + else if (ctx->geospatial_col()) + { + /* Throwing error similar to TSQL as we do not allow 4-Part name for geospatial function call */ + if(ctx->schema) throw PGErrorWrapperException(ERROR, ERRCODE_SYNTAX_ERROR, format_errmsg("The multi-part identifier \"%s\" could not be bound.", ::getFullText(ctx).c_str()), getLineAndPos(ctx)); + + /* Rewriting the query as: table.col.STX -> (table.col).STX */ + std::string rewritten_func_name = "("; + if(ctx->table) rewritten_func_name += stripQuoteFromId(ctx->table) + "."; + rewritten_func_name += stripQuoteFromId(ctx->column) + ")." + ::getFullText(ctx->geospatial_col()); + rewritten_query_fragment.emplace(std::make_pair(ctx->start->getStartIndex(), std::make_pair(::getFullText(ctx), rewritten_func_name.c_str()))); + } + + std::string rewritten_name = rewrite_column_name_with_omitted_schema_name(ctx, getSchema, getTablename); + std::string rewritten_schema_name = rewrite_information_schema_to_information_schema_tsql(ctx, getSchema); + if (!rewritten_name.empty()) + rewritten_query_fragment.emplace(std::make_pair(ctx->start->getStartIndex(), std::make_pair(::getFullText(ctx), rewritten_name))); + if (pltsql_enable_tsql_information_schema && !rewritten_schema_name.empty()) + rewritten_query_fragment.emplace(std::make_pair(ctx->schema->start->getStartIndex(), std::make_pair(::getFullText(ctx->schema), rewritten_schema_name))); + + if (does_object_name_need_delimiter(ctx->tablename)) + rewritten_query_fragment.emplace(std::make_pair(ctx->tablename->start->getStartIndex(), std::make_pair(::getFullText(ctx->tablename), delimit_identifier(ctx->tablename)))); + + /* qualified identifier doesn't need delimiter */ + if (ctx->DOT().empty() && does_object_name_need_delimiter(ctx->column_name)) + rewritten_query_fragment.emplace(std::make_pair(ctx->column_name->start->getStartIndex(), std::make_pair(::getFullText(ctx->column_name), delimit_identifier(ctx->column_name)))); + } + + /* Handles rewrite of geospatial query except inside body of CREATE/ALTER View, Procedure, Function: */ + void exitFunc_call_expr(TSqlParser::Func_call_exprContext *ctx) override + { + if(ctx != NULL && !ctx->DOT().empty()) + { + std::vector method_calls = ctx->method_call(); + for (size_t i = 0; i < method_calls.size(); ++i) + { + TSqlParser::Method_callContext *method = method_calls[i]; + /* rewriting the query in case of Geospatial function Call -> function_call.method_call */ + if(method->spatial_methods()) + { + size_t ind; + if (i == 0) ind = ctx->function_call()->stop->getStopIndex(); + else ind = method_calls[i-1]->stop->getStopIndex(); + rewrite_geospatial_query_helper(ctx, method, ind); + } + } + } + } + + /* Handles rewrite of geospatial query except inside body of CREATE/ALTER View, Procedure, Function: */ + void exitLocal_id_expr(TSqlParser::Local_id_exprContext *ctx) override + { + if(ctx != NULL && !ctx->DOT().empty()) + { + std::vector method_calls = ctx->method_call(); + for (size_t i = 0; i < method_calls.size(); ++i) + { + TSqlParser::Method_callContext *method = method_calls[i]; + /* rewriting the query in case of Geospatial function Call -> local_id.method_call */ + if(method->spatial_methods()) + { + size_t ind; + if (i == 0) ind = ctx->local_id()->stop->getStopIndex(); + else ind = method_calls[i-1]->stop->getStopIndex(); + rewrite_geospatial_query_helper(ctx, method, ind); + } + } + } + } + + /* Handles rewrite of geospatial query except inside body of CREATE/ALTER View, Procedure, Function: */ + void exitBracket_expr(TSqlParser::Bracket_exprContext *ctx) override + { + if(ctx != NULL && !ctx->DOT().empty()) + { + std::vector method_calls = ctx->method_call(); + for (size_t i = 0; i < method_calls.size(); ++i) + { + TSqlParser::Method_callContext *method = method_calls[i]; + /* rewriting the query in case of Geospatial function Call -> LR_BRACKET expression RR_BRACKET.method_call */ + if(method->spatial_methods()) + { + size_t ind; + std::string context = ::getFullText(ctx); + size_t spaces = 0; + for (size_t x = ctx->expression()->stop->getStopIndex() + 1 - ctx->start->getStartIndex(); x <= ctx->stop->getStopIndex() - ctx->start->getStartIndex(); x++) + { + if(context[x] == ' ') spaces++; + else if(context[x] == ')') break; + } + if (i == 0) ind = ctx->expression()->stop->getStopIndex() + 1 + spaces; + else ind = method_calls[i-1]->stop->getStopIndex(); + rewrite_geospatial_query_helper(ctx, method, ind); + } + } + } + } + + /* Handles rewrite of geospatial query except inside body of CREATE/ALTER View, Procedure, Function: */ + void exitSubquery_expr(TSqlParser::Subquery_exprContext *ctx) override + { + if(ctx != NULL && !ctx->DOT().empty()) + { + std::vector method_calls = ctx->method_call(); + for (size_t i = 0; i < method_calls.size(); ++i) + { + TSqlParser::Method_callContext *method = method_calls[i]; + /* rewriting the query in case of Geospatial function Call -> subquery.method_call */ + if(method->spatial_methods()) + { + size_t ind; + if (i == 0) ind = ctx->subquery()->stop->getStopIndex(); + else ind = method_calls[i-1]->stop->getStopIndex(); + rewrite_geospatial_query_helper(ctx, method, ind); + } + } + } + } + ////////////////////////////////////////////////////////////////////////////// // function/procedure call analysis ////////////////////////////////////////////////////////////////////////////// @@ -2333,6 +2619,18 @@ class tsqlBuilder : public tsqlCommonMutator rewritten_query_fragment.emplace(std::make_pair(bctx->bif_no_brackets->getStartIndex(), std::make_pair(::getFullText(bctx->SESSION_USER()), "sys.session_user()"))); } + /* Handles rewrite of geospatial query except inside body of CREATE/ALTER View, Procedure, Function: */ + if (ctx->spatial_proc_name_server_database_schema()) + { + if (ctx->spatial_proc_name_server_database_schema()->schema) throw PGErrorWrapperException(ERROR, ERRCODE_FEATURE_NOT_SUPPORTED, "Remote procedure/function reference with 4-part object name is not currently supported in Babelfish", getLineAndPos(ctx)); + + /* This if-elseIf clause rewrites the query in case of Geospatial function Call */ + if (ctx->spatial_proc_name_server_database_schema()->geospatial_func_arg() && ctx->function_arg_list()) + rewrite_function_call_geospatial_func_ref_args(ctx); + else if (ctx->spatial_proc_name_server_database_schema()->geospatial_func_no_arg() && !ctx->function_arg_list()) + rewrite_function_call_geospatial_func_ref_no_arg(ctx); + } + /* analyze scalar function call */ if (ctx->func_proc_name_server_database_schema()) { @@ -2438,31 +2736,6 @@ class tsqlBuilder : public tsqlCommonMutator process_query_specification(ctx, statementMutator.get()); } - void exitColumn_def_table_constraints(TSqlParser::Column_def_table_constraintsContext *ctx) - { - /* - * It is not documented but it seems T-SQL allows that column-definition is followed by table-constraint without COMMA. - * PG backend parser will throw a syntax error when this kind of query is inputted. - * It is not easy to add a rule accepting this syntax to backend parser because of many shift/reduce conflicts. - * To handle this case, add a compensation COMMA between column-definition and table-constraint here. - * - * This handling should be only applied to table-constraint following column-definition. Other cases (such as two column definitions without comma) should still throw a syntax error. - */ - - ParseTree* prev_child = nullptr; - for (ParseTree* child : ctx->children) - { - TSqlParser::Column_def_table_constraintContext* cdtctx = dynamic_cast(child); - if (cdtctx && cdtctx->table_constraint()) - { - TSqlParser::Column_def_table_constraintContext* prev_cdtctx = (prev_child ? dynamic_cast(prev_child) : nullptr); - if (prev_cdtctx && prev_cdtctx->column_definition()) - rewritten_query_fragment.emplace(std::make_pair(cdtctx->start->getStartIndex(), std::make_pair("", ","))); // add comma - } - prev_child = child; - } - } - void exitDrop_relational_or_xml_or_spatial_index(TSqlParser::Drop_relational_or_xml_or_spatial_indexContext *ctx) override { /* @@ -2947,14 +3220,21 @@ class tsqlMutator : public TSqlParserBaseListener } } - // NB: this is copied in tsqlBuilder + // NB: the following are copied in tsqlBuilder + void exitColumn_def_table_constraints(TSqlParser::Column_def_table_constraintsContext *ctx) + { + handleTableConstraintWithoutComma(ctx); + } void exitConstant(TSqlParser::ConstantContext *ctx) override { // Check for floating-point number without exponent handleFloatWithoutExponent(ctx); } - - // NB: this is copied in tsqlBuilder + void exitPredicate(TSqlParser::PredicateContext *ctx) override + { + // Check for comparison operators directly followed by an '@@' variable, like =@@ + handleAtAtVarInPredicate(ctx); + } void exitUnary_op_expr(TSqlParser::Unary_op_exprContext *ctx) override { handleBitNotOperator(ctx); @@ -5747,61 +6027,190 @@ makeKillStatement(TSqlParser::Kill_statementContext *ctx) PLtsql_stmt * makeGrantdbStatement(TSqlParser::Security_statementContext *ctx) { - if (ctx->grant_statement() && ctx->grant_statement()->TO() && !ctx->grant_statement()->permission_object() - && ctx->grant_statement()->permissions()) + if (ctx->grant_statement()) { - for (auto perm : ctx->grant_statement()->permissions()->permission()) + auto grant = ctx->grant_statement(); + if (grant->TO() && !grant->permission_object() && grant->permissions()) { - auto single_perm = perm->single_permission(); - if (single_perm->CONNECT()) + for (auto perm : grant->permissions()->permission()) { - PLtsql_stmt_grantdb *result = (PLtsql_stmt_grantdb *) palloc0(sizeof(PLtsql_stmt_grantdb)); - result->cmd_type = PLTSQL_STMT_GRANTDB; - result->lineno = getLineNo(ctx->grant_statement()); + auto single_perm = perm->single_permission(); + if (single_perm->CONNECT()) + { + PLtsql_stmt_grantdb *result = (PLtsql_stmt_grantdb *) palloc0(sizeof(PLtsql_stmt_grantdb)); + result->cmd_type = PLTSQL_STMT_GRANTDB; + result->lineno = getLineNo(grant); + result->is_grant = true; + List *grantee_list = NIL; + for (auto prin : grant->principals()->principal_id()) + { + if (prin->id()) + { + std::string id_str = ::getFullText(prin->id()); + char *grantee_name = pstrdup(downcase_truncate_identifier(id_str.c_str(), id_str.length(), true)); + grantee_list = lappend(grantee_list, grantee_name); + } + if (prin->PUBLIC()) + { + char *grantee_name = pstrdup(PUBLIC_ROLE_NAME); + grantee_list = lappend(grantee_list, grantee_name); + } + } + result->grantees = grantee_list; + return (PLtsql_stmt *) result; + } + } + } + else if (grant->ON() && grant->permission_object() && grant->permission_object()->object_type() && grant->permission_object()->object_type()->SCHEMA()) + { + if (grant->TO() && grant->principals() && grant->permissions()) + { + PLtsql_stmt_grantschema *result = (PLtsql_stmt_grantschema *) palloc0(sizeof(PLtsql_stmt_grantschema)); + result->cmd_type = PLTSQL_STMT_GRANTSCHEMA; + result->lineno = getLineNo(grant); result->is_grant = true; + std::string schema_name; + if (grant->permission_object()->full_object_name()->object_name) + { + schema_name = stripQuoteFromId(grant->permission_object()->full_object_name()->object_name); + if (string_matches(schema_name.c_str(), "information_schema")) + schema_name = "information_schema_tsql"; + result->schema_name = pstrdup(downcase_truncate_identifier(schema_name.c_str(), schema_name.length(), true)); + } List *grantee_list = NIL; - for (auto prin : ctx->grant_statement()->principals()->principal_id()) + for (auto prin : grant->principals()->principal_id()) { if (prin->id()) { - std::string id_str = ::getFullText(prin->id()); + std::string id_str = stripQuoteFromId(prin->id()); char *grantee_name = pstrdup(downcase_truncate_identifier(id_str.c_str(), id_str.length(), true)); grantee_list = lappend(grantee_list, grantee_name); } + if (prin->PUBLIC()) + { + char *grantee_name = pstrdup(PUBLIC_ROLE_NAME); + grantee_list = lappend(grantee_list, grantee_name); + } } + int privileges = 0; + for (auto perm: grant->permissions()->permission()) + { + auto single_perm = perm->single_permission(); + if (single_perm->EXECUTE()) + privileges |= ACL_EXECUTE; + if (single_perm->EXEC()) + privileges |= ACL_EXECUTE; + if (single_perm->SELECT()) + privileges |= ACL_SELECT; + if (single_perm->INSERT()) + privileges |= ACL_INSERT; + if (single_perm->UPDATE()) + privileges |= ACL_UPDATE; + if (single_perm->DELETE()) + privileges |= ACL_DELETE; + if (single_perm->REFERENCES()) + privileges |= ACL_REFERENCES; + } + result->privileges = privileges; + if (grant->WITH()) + result->with_grant_option = true; result->grantees = grantee_list; return (PLtsql_stmt *) result; } } } - if (ctx->revoke_statement() && ctx->revoke_statement()->FROM() && !ctx->revoke_statement()->permission_object() - && ctx->revoke_statement()->permissions()) + + else if (ctx->revoke_statement()) { - for (auto perm : ctx->revoke_statement()->permissions()->permission()) + auto revoke = ctx->revoke_statement(); + if (revoke->FROM() && !revoke->permission_object() && revoke->permissions()) { - auto single_perm = perm->single_permission(); - if (single_perm->CONNECT()) + for (auto perm : revoke->permissions()->permission()) { - PLtsql_stmt_grantdb *result = (PLtsql_stmt_grantdb *) palloc0(sizeof(PLtsql_stmt_grantdb)); - result->cmd_type = PLTSQL_STMT_GRANTDB; - result->lineno = getLineNo(ctx->revoke_statement()); + auto single_perm = perm->single_permission(); + if (single_perm->CONNECT()) + { + PLtsql_stmt_grantdb *result = (PLtsql_stmt_grantdb *) palloc0(sizeof(PLtsql_stmt_grantdb)); + result->cmd_type = PLTSQL_STMT_GRANTDB; + result->lineno = getLineNo(revoke); + result->is_grant = false; + List *grantee_list = NIL; + + for (auto prin : revoke->principals()->principal_id()) + { + if (prin->id()) + { + std::string id_str = ::getFullText(prin->id()); + char *grantee_name = pstrdup(downcase_truncate_identifier(id_str.c_str(), id_str.length(), true)); + grantee_list = lappend(grantee_list, grantee_name); + } + if (prin->PUBLIC()) + { + char *grantee_name = pstrdup(PUBLIC_ROLE_NAME); + grantee_list = lappend(grantee_list, grantee_name); + } + } + result->grantees = grantee_list; + return (PLtsql_stmt *) result; + } + } + } + + else if (revoke->ON() && revoke->permission_object() && revoke->permission_object()->object_type() && revoke->permission_object()->object_type()->SCHEMA()) + { + if (revoke->FROM() && revoke->principals() && revoke->permissions()) + { + PLtsql_stmt_grantschema *result = (PLtsql_stmt_grantschema *) palloc0(sizeof(PLtsql_stmt_grantschema)); + result->cmd_type = PLTSQL_STMT_GRANTSCHEMA; + result->lineno = getLineNo(revoke); result->is_grant = false; + std::string schema_name; + if (revoke->permission_object()->full_object_name()->object_name) + { + schema_name = stripQuoteFromId(revoke->permission_object()->full_object_name()->object_name); + result->schema_name = pstrdup(downcase_truncate_identifier(schema_name.c_str(), schema_name.length(), true)); + } List *grantee_list = NIL; - - for (auto prin : ctx->revoke_statement()->principals()->principal_id()) + for (auto prin : revoke->principals()->principal_id()) { if (prin->id()) { - std::string id_str = ::getFullText(prin->id()); + std::string id_str = stripQuoteFromId(prin->id()); char *grantee_name = pstrdup(downcase_truncate_identifier(id_str.c_str(), id_str.length(), true)); grantee_list = lappend(grantee_list, grantee_name); } + if (prin->PUBLIC()) + { + char *grantee_name = pstrdup(PUBLIC_ROLE_NAME); + grantee_list = lappend(grantee_list, grantee_name); + } } + int privileges = 0; + for (auto perm: revoke->permissions()->permission()) + { + auto single_perm = perm->single_permission(); + if (single_perm->EXECUTE()) + privileges |= ACL_EXECUTE; + if (single_perm->EXEC()) + privileges |= ACL_EXECUTE; + if (single_perm->SELECT()) + privileges |= ACL_SELECT; + if (single_perm->INSERT()) + privileges |= ACL_INSERT; + if (single_perm->UPDATE()) + privileges |= ACL_UPDATE; + if (single_perm->DELETE()) + privileges |= ACL_DELETE; + if (single_perm->REFERENCES()) + privileges |= ACL_REFERENCES; + } + result->privileges = privileges; result->grantees = grantee_list; return (PLtsql_stmt *) result; } } } + PLtsql_stmt *result; result = makeExecSql(ctx); attachPLtsql_fragment(ctx, result); @@ -7026,8 +7435,6 @@ post_process_declare_table_statement(PLtsql_stmt_decl_table *stmt, TSqlParser::T { if (ctx->column_def_table_constraints()) { - bool rewrite = false; - for (auto cdtctx : ctx->column_def_table_constraints()->column_def_table_constraint()) { /* @@ -7041,17 +7448,22 @@ post_process_declare_table_statement(PLtsql_stmt_decl_table *stmt, TSqlParser::T auto tctx = cdtctx->column_definition()->TIMESTAMP(); std::string rewritten_text = "timestamp " + ::getFullText(tctx); rewritten_query_fragment.emplace(std::make_pair(tctx->getSymbol()->getStartIndex(), std::make_pair(::getFullText(tctx), rewritten_text))); - rewrite = true; } } - if (rewrite) + /* + * Need to run the mutator to perform rewriting not only when items were added above, + * but also if rewrite items were added earlier - for example, in exitColumn_def_table_constraints() + * in case a table constraint was specified without a separator comma. + */ + if (rewritten_query_fragment.size() > 0) { PLtsql_expr *expr = makeTsqlExpr(ctx, false); PLtsql_expr_query_mutator mutator(expr, ctx); add_rewritten_query_fragment_to_mutator(&mutator); mutator.run(); char *rewritten_query = expr->query; + // Save the rewritten column definition list stmt->coldef = pstrdup(&rewritten_query[5]); } @@ -7722,6 +8134,274 @@ rewrite_column_name_with_omitted_schema_name(T ctx, GetCtxFunc getSchema, Get return ""; } +/////////////////////////////////////////////////////////////////////////////// +// Spatial Query Helper +//////////////////////////////////////////////////////////////////////////////// + +/* + * In this helper function we Rewrite the Query for Geospatial Handling + * For Col_Ref Functions (such as STX, STY, Lat, Long) : ColRef.Func_name -> (ColRef).Func_name + */ +template +void +rewrite_geospatial_col_ref_query_helper(T ctx, TSqlParser::Method_callContext *method, size_t geospatial_start_index) +{ + std::vector keysToRemove; + std::string ctx_str = ::getFullText(ctx); + int func_call_len = (int)geospatial_start_index - ctx->start->getStartIndex(); + int method_len = (int)method->stop->getStopIndex() - method->start->getStartIndex(); + std::string expr = ""; + int index = 0; + int offset1 = 0; + int offset2 = 0; + + /* writting the previously rewritten Geospatial context */ + for (auto &entry : rewritten_query_fragment) + { + if(entry.first >= ctx->start->getStartIndex() && entry.first <= ctx->stop->getStopIndex()) + { + expr += ctx_str.substr(index, (int)entry.first - ctx->start->getStartIndex() - index) + entry.second.second; + index = (int)entry.first - ctx->start->getStartIndex() + entry.second.first.size(); + keysToRemove.push_back(entry.first); + if(entry.first <= geospatial_start_index) offset1 += (int)entry.second.second.size() - entry.second.first.size(); + else offset2 += (int)entry.second.second.size() - entry.second.first.size(); + } + } + for (const auto &key : keysToRemove) rewritten_query_fragment.erase(key); + keysToRemove.clear(); + + /* shifting the local id positions to new positions after rewriting the query since they will be quoted later */ + for (auto &entry : local_id_positions) + { + if(entry.first >= ctx->start->getStartIndex() && entry.first <= geospatial_start_index) + { + keysToRemove.push_back(entry.first); + local_id_positions.emplace(std::make_pair(entry.first + 1, entry.second)); + } + } + for (const auto &key : keysToRemove) local_id_positions.erase(key); + keysToRemove.clear(); + expr += ctx_str.substr(index); + std::string rewritten_exp = "(" + expr.substr(0, func_call_len + offset1 + 1) + ")." + expr.substr((int)method->start->getStartIndex() - ctx->start->getStartIndex() + offset1, method_len + offset2 + 1); + if ((int)method->stop->getStopIndex() - ctx->start->getStartIndex() + 1 < ctx_str.size()) rewritten_exp += expr.substr(method->stop->getStopIndex() + offset1 - ctx->start->getStartIndex() + 1); + rewritten_query_fragment.emplace(std::make_pair(ctx->start->getStartIndex(), std::make_pair(ctx_str.c_str(), rewritten_exp.c_str()))); +} + +/* + * In this helper function we Rewrite the Query for Geospatial Handling + * For Func_Ref Functions with no args (such as STAsText(), STAsBinary()) : ColRef.Func_name() -> Func_name(ColRef) + */ +template +void +rewrite_geospatial_func_ref_no_arg_query_helper(T ctx, TSqlParser::Method_callContext *method, size_t geospatial_start_index) +{ + std::vector keysToRemove; + std::string ctx_str = ::getFullText(ctx); + int func_call_len = (int)geospatial_start_index - ctx->start->getStartIndex(); + int method_len = (int)method->stop->getStopIndex() - method->start->getStartIndex(); + std::string expr = ""; + int index = 0; + int offset1 = 0; + int offset2 = 0; + + /* writting the previously rewritten Geospatial context */ + for (auto &entry : rewritten_query_fragment) + { + if(entry.first >= ctx->start->getStartIndex() && entry.first <= ctx->stop->getStopIndex()) + { + expr += ctx_str.substr(index, (int)entry.first - ctx->start->getStartIndex() - index) + entry.second.second; + index = (int)entry.first - ctx->start->getStartIndex() + entry.second.first.size(); + keysToRemove.push_back(entry.first); + if(entry.first <= geospatial_start_index) offset1 += (int)entry.second.second.size() - entry.second.first.size(); + else offset2 += (int)entry.second.second.size() - entry.second.first.size(); + } + } + for (const auto &key : keysToRemove) rewritten_query_fragment.erase(key); + keysToRemove.clear(); + + /* shifting the local id positions to new positions after rewriting the query since they will be quoted later */ + for (auto &entry : local_id_positions) + { + if(entry.first >= ctx->start->getStartIndex() && entry.first <= geospatial_start_index) + { + keysToRemove.push_back(entry.first); + local_id_positions.emplace(std::make_pair(entry.first + method->spatial_methods()->geospatial_func_no_arg()->stop->getStopIndex() - method->spatial_methods()->geospatial_func_no_arg()->start->getStartIndex() + 1, entry.second)); + } + } + for (const auto &key : keysToRemove) local_id_positions.erase(key); + keysToRemove.clear(); + expr += ctx_str.substr(index); + std::string rewritten_exp = expr.substr((int)method->start->getStartIndex() - ctx->start->getStartIndex() + offset1, method_len + offset2) + expr.substr(0, func_call_len + offset1 + 1) + ")"; + if ((int)method->stop->getStopIndex() - ctx->start->getStartIndex() + 1 < ctx_str.size()) rewritten_exp += expr.substr(method->stop->getStopIndex() + offset1 - ctx->start->getStartIndex() + 1); + rewritten_query_fragment.emplace(std::make_pair(ctx->start->getStartIndex(), std::make_pair(ctx_str.c_str(), rewritten_exp.c_str()))); +} + +/* + * In this helper function we Rewrite the Query for Geospatial Handling + * For Func_Ref Functions with args (such as STDistance(arg)) : ColRef.Func_name(arg_list) -> Func_name(arg_list, ColRef) + */ +template +void +rewrite_geospatial_func_ref_args_query_helper(T ctx, TSqlParser::Method_callContext *method, size_t geospatial_start_index) +{ + std::vector keysToRemove; + std::string ctx_str = ::getFullText(ctx); + int func_call_len = (int)geospatial_start_index - ctx->start->getStartIndex(); + int method_len = (int)method->stop->getStopIndex() - method->start->getStartIndex(); + std::string expr = ""; + int index = 0; + int offset1 = 0; + int offset2 = 0; + + /* writting the previously rewritten Geospatial context */ + for (auto &entry : rewritten_query_fragment) + { + if(entry.first >= ctx->start->getStartIndex() && entry.first <= ctx->stop->getStopIndex()) + { + expr += ctx_str.substr(index, (int)entry.first - ctx->start->getStartIndex() - index) + entry.second.second; + index = (int)entry.first - ctx->start->getStartIndex() + entry.second.first.size(); + keysToRemove.push_back(entry.first); + if(entry.first <= geospatial_start_index) offset1 += (int)entry.second.second.size() - entry.second.first.size(); + else offset2 += (int)entry.second.second.size() - entry.second.first.size(); + } + } + for (const auto &key : keysToRemove) rewritten_query_fragment.erase(key); + keysToRemove.clear(); + + /* shifting the local id positions to new positions after rewriting the query since they will be quoted later */ + for (auto &entry : local_id_positions) + { + if(entry.first >= ctx->start->getStartIndex() && entry.first <= geospatial_start_index) + { + keysToRemove.push_back(entry.first); + local_id_positions.emplace(std::make_pair(entry.first + method->spatial_methods()->expression_list()->stop->getStopIndex() - method->spatial_methods()->geospatial_func_arg()->start->getStartIndex() + 2, entry.second)); + } + else if(entry.first >= method->spatial_methods()->expression_list()->start->getStartIndex() && entry.first <= method->spatial_methods()->expression_list()->stop->getStopIndex()) + { + size_t pos = entry.first; + size_t offset = method->start->getStartIndex() - ctx->start->getStartIndex(); + pos -= offset; + keysToRemove.push_back(entry.first); + local_id_positions.emplace(std::make_pair(pos, entry.second)); + } + } + for (const auto &key : keysToRemove) local_id_positions.erase(key); + keysToRemove.clear(); + expr += ctx_str.substr(index); + std::string rewritten_exp = expr.substr((int)method->start->getStartIndex() - ctx->start->getStartIndex() + offset1, method_len + offset2) + "," + expr.substr(0, func_call_len + offset1 + 1) + ")"; + if ((int)method->stop->getStopIndex() - ctx->start->getStartIndex() + 1 < ctx_str.size()) rewritten_exp += expr.substr(method->stop->getStopIndex() + offset1 - ctx->start->getStartIndex() + 1); + rewritten_query_fragment.emplace(std::make_pair(ctx->start->getStartIndex(), std::make_pair(ctx_str.c_str(), rewritten_exp.c_str()))); +} + +/* + * In this helper function we Rewrite the Query for Geospatial Handling + * For Col_Ref Functions (such as STX, STY, Lat, Long) : ColRef.Func_name -> (ColRef).Func_name + * For Func_Ref Functions (such as STAsText, STAsBinary, STDistance) : ColRef.Func_name (arg_list) -> Func_name (arg_list, ColRef) + */ +template +void +rewrite_geospatial_query_helper(T ctx, TSqlParser::Method_callContext *method, size_t geospatial_start_index) +{ + /* Check whether it is a Col_Ref Function or a Func_Ref Function */ + if(method->spatial_methods()->geospatial_col() && !method->spatial_methods()->LR_BRACKET() ) + rewrite_geospatial_col_ref_query_helper(ctx, method, geospatial_start_index); + else if(method->spatial_methods()->geospatial_func_no_arg() && !method->spatial_methods()->expression_list() ) + rewrite_geospatial_func_ref_no_arg_query_helper(ctx, method, geospatial_start_index); + else if(method->spatial_methods()->geospatial_func_arg() && method->spatial_methods()->expression_list() ) + rewrite_geospatial_func_ref_args_query_helper(ctx, method, geospatial_start_index); +} + +/////////////////////////////////////////////////////////////////////////////// +// End of Spatial Query Helper +//////////////////////////////////////////////////////////////////////////////// + +/////////////////////////////////////////////////////////////////////////////// +// Spatial Query Helper for Function Calls +//////////////////////////////////////////////////////////////////////////////// + +/* + * In this helper function we Rewrite the Query for Geospatial Handling + * This implementation is different for Function_Call Rule + * For Func_Ref Functions with no args (such as STAsText(), STAsBinary()) : ColRef.Func_name() -> Func_name(ColRef) + */ +template +void +rewrite_function_call_geospatial_func_ref_no_arg(T ctx) +{ + std::vector keysToRemove; + std::string func_ctx = ::getFullText(ctx); + + std::string arg_ctx = ""; + int index = (int) ctx->spatial_proc_name_server_database_schema()->stop->getStopIndex() - ctx->spatial_proc_name_server_database_schema()->start->getStartIndex() + 1; + int length = (int) ctx->stop->getStopIndex() - ctx->spatial_proc_name_server_database_schema()->stop->getStopIndex() - 1; + + /* rewriting the query as: table.col.STAsText() -> STAsText(table.col) */ + if (ctx->spatial_proc_name_server_database_schema()->table) arg_ctx += stripQuoteFromId(ctx->spatial_proc_name_server_database_schema()->table) + "."; + arg_ctx += stripQuoteFromId(ctx->spatial_proc_name_server_database_schema()->column); + std::string rewritten_func = ::getFullText(ctx->spatial_proc_name_server_database_schema()->geospatial_func_no_arg()) + func_ctx.substr(index, length) + arg_ctx + ")"; + rewritten_query_fragment.emplace(std::make_pair(ctx->spatial_proc_name_server_database_schema()->start->getStartIndex(), std::make_pair(::getFullText(ctx), rewritten_func.c_str()))); +} + +/* + * In this helper function we Rewrite the Query for Geospatial Handling + * This implementation is different for Function_Call Rule + * For Func_Ref Functions with args (such as STDistance(arg)) : ColRef.Func_name(arg_list) -> Func_name(arg_list, ColRef) + */ +template +void +rewrite_function_call_geospatial_func_ref_args(T ctx) +{ + std::vector keysToRemove; + std::string func_ctx = ::getFullText(ctx); + int col_len = (int)ctx->spatial_proc_name_server_database_schema()->column->stop->getStopIndex() - ctx->start->getStartIndex(); + int method_len = (int)ctx->stop->getStopIndex() - ctx->spatial_proc_name_server_database_schema()->geospatial_func_arg()->start->getStartIndex(); + std::string expr = ""; + int index = 0; + int offset1 = 0; + int offset2 = 0; + + /* writting the previously rewritten Geospatial context */ + for (auto &entry : rewritten_query_fragment) + { + if(entry.first >= ctx->start->getStartIndex() && entry.first <= ctx->stop->getStopIndex()) + { + expr += func_ctx.substr(index, (int)entry.first - ctx->start->getStartIndex() - index) + entry.second.second; + index = (int)entry.first - ctx->start->getStartIndex() + entry.second.first.size(); + keysToRemove.push_back(entry.first); + if(entry.first <= ctx->spatial_proc_name_server_database_schema()->column->stop->getStopIndex()) offset1 += (int)entry.second.second.size() - entry.second.first.size(); + else offset2 += (int)entry.second.second.size() - entry.second.first.size(); + } + } + for (const auto &key : keysToRemove) rewritten_query_fragment.erase(key); + keysToRemove.clear(); + + /* Shifting the local id positions to new positions after rewriting the query since they will be quoted later */ + for (auto &entry : local_id_positions) + { + if(entry.first >= ctx->function_arg_list()->start->getStartIndex() && entry.first <= ctx->function_arg_list()->stop->getStopIndex()) + { + size_t pos = entry.first; + size_t offset = ctx->spatial_proc_name_server_database_schema()->geospatial_func_arg()->start->getStartIndex() - ctx->spatial_proc_name_server_database_schema()->start->getStartIndex(); + pos -= offset; + keysToRemove.push_back(entry.first); + local_id_positions.emplace(std::make_pair(pos, entry.second)); + } + } + for (const auto &key : keysToRemove) local_id_positions.erase(key); + keysToRemove.clear(); + + /* + * Rewriting the query as: table.col.STDistance(arg) -> STDistance(arg, table.col) + */ + expr += func_ctx.substr(index); + std::string rewritten_func = expr.substr((int)ctx->spatial_proc_name_server_database_schema()->geospatial_func_arg()->start->getStartIndex() - ctx->start->getStartIndex() + offset1, method_len + offset2) + "," + expr.substr(0, col_len + offset1 + 1) + ")"; + rewritten_query_fragment.emplace(std::make_pair(ctx->spatial_proc_name_server_database_schema()->start->getStartIndex(), std::make_pair(::getFullText(ctx), rewritten_func.c_str()))); +} + +/////////////////////////////////////////////////////////////////////////////// +// End of Spatial Query Helper for Function Calls +//////////////////////////////////////////////////////////////////////////////// + static bool does_object_name_need_delimiter(TSqlParser::IdContext *id) { @@ -7984,6 +8664,34 @@ handleBitNotOperator(TSqlParser::Unary_op_exprContext *ctx) return; } +static void +handleTableConstraintWithoutComma(TSqlParser::Column_def_table_constraintsContext *ctx) +{ + /* + * It is not documented but it seems T-SQL allows that column-definition is followed by table-constraint without COMMA. + * PG backend parser will throw a syntax error when this kind of query is inputted. + * It is not easy to add a rule accepting this syntax to backend parser because of many shift/reduce conflicts. + * To handle this case, add a compensation COMMA between column-definition and table-constraint here. + * + * This handling should be only applied to table-constraint following column-definition. Other cases (such as two column definitions without comma) should still throw a syntax error. + */ + ParseTree* prev_child = nullptr; + for (ParseTree* child : ctx->children) + { + TSqlParser::Column_def_table_constraintContext* cdtctx = dynamic_cast(child); + if (cdtctx && cdtctx->table_constraint()) + { + TSqlParser::Column_def_table_constraintContext* prev_cdtctx = (prev_child ? dynamic_cast(prev_child) : nullptr); + if (prev_cdtctx && prev_cdtctx->column_definition()) + { + rewritten_query_fragment.emplace(std::make_pair(cdtctx->start->getStartIndex(), std::make_pair("", ","))); // add comma + } + } + prev_child = child; + } + return; +} + static void handleBitOperators(TSqlParser::Plus_minus_bit_exprContext *ctx) { @@ -8018,4 +8726,67 @@ handleModuloOperator(TSqlParser::Mult_div_percent_exprContext *ctx) } } return; -} \ No newline at end of file +} + +void handleAtAtVarInPredicate(TSqlParser::PredicateContext *ctx) +{ + // For comparison operators directly followed by an '@@' variable, insert a space + // to avoid these being parsed incorrectly by PG; this applies to these following + // character sequences: =@@, >@@, <@@ as well as !=@ (single-@ variable) + // Note: this issue does occur for assignments like 'SET @v=@@spid' or column aliases like 'SELECT a=@@spid' + // Note: parameter defaults and named parameters are handled separately + + if ((ctx->comparison_operator()) && (ctx->expression().size() > 1)) + { + std::string op = getFullText(ctx->comparison_operator()); + if ((op.back() == '=') || + (op.back() == '>') || + (op.back() == '<')) + { + // The operator must be followed immediately by the variable without any character in between + Assert(ctx->expression(1)); + size_t startPosition = ctx->expression(1)->start->getStartIndex(); + if ((startPosition - ctx->comparison_operator()->stop->getStopIndex()) == 1) + { + std::string var = getFullText(ctx->expression(1)); + // The subsequent expression must be a variable starting with '@@' + if (var.front() == '@') + { + if ((var.at(1) == '@') || (pg_strncasecmp(op.c_str(), "!=", 2) == 0)) + { + // Insert a space before the variable name + rewritten_query_fragment.emplace(std::make_pair(startPosition, std::make_pair(var, " "+var))); + } + } + } + } + } + return; +} + +static void +handleOrderByOffsetFetch(TSqlParser::Order_by_clauseContext *ctx) +{ + // Add brackets around the expressions for OFFSET..ROWS and FETCH..ROWS + + if (ctx->offset_exp) + { + // Do not rewrite the entire expression since that will break the logic in the mutator when there is something inside the + // expression that also needs rewriting (like a local variable @p which needs to be rewritten as "@p"). + // Instead, insert an opening and closing bracket in the right places. + // Also, do not add a rewrite at the start position of the expression since there may be an '@' for a local var + // at that position and the rewrite to double-quote the variable will be lost as a result. + rewritten_query_fragment.emplace(std::make_pair((ctx->offset_exp->start->getStartIndex() - 1), std::make_pair("", " ("))); + rewritten_query_fragment.emplace(std::make_pair((ctx->offset_exp->stop->getStopIndex() + 1), std::make_pair("", ") "))); + } + + if (ctx->fetch_exp) + { + // See comment for offset_exp above. + rewritten_query_fragment.emplace(std::make_pair((ctx->fetch_exp->start->getStartIndex() - 1), std::make_pair("", " ("))); + rewritten_query_fragment.emplace(std::make_pair((ctx->fetch_exp->stop->getStopIndex() + 1), std::make_pair("", ") "))); + } + + return; +} + diff --git a/contrib/babelfishpg_tsql/src/tsqlNodes.h b/contrib/babelfishpg_tsql/src/tsqlNodes.h index e41e61ca87e..65b3b27d767 100644 --- a/contrib/babelfishpg_tsql/src/tsqlNodes.h +++ b/contrib/babelfishpg_tsql/src/tsqlNodes.h @@ -52,6 +52,7 @@ typedef enum pltsql_stmt_type PLTSQL_STMT_CHANGE_DBOWNER, PLTSQL_STMT_DBCC, PLTSQL_STMT_FULLTEXTINDEX + PLTSQL_STMT_GRANTSCHEMA } PLtsql_stmt_type; typedef struct PLtsql_expr diff --git a/contrib/babelfishpg_tsql/src/tsqlUnsupportedFeatureHandler.cpp b/contrib/babelfishpg_tsql/src/tsqlUnsupportedFeatureHandler.cpp index ffec553a308..650e85a3bcd 100644 --- a/contrib/babelfishpg_tsql/src/tsqlUnsupportedFeatureHandler.cpp +++ b/contrib/babelfishpg_tsql/src/tsqlUnsupportedFeatureHandler.cpp @@ -1763,10 +1763,10 @@ void TsqlUnsupportedFeatureHandlerImpl::checkSupportedGrantStmt(TSqlParser::Gran continue; else { - unsupported_feature = "GRANT PERMISSION " + perm->getText(); + unsupported_feature = "GRANT PERMISSION " + ::getFullText(single_perm); + std::transform(unsupported_feature.begin(), unsupported_feature.end(), unsupported_feature.begin(), ::toupper); handle(INSTR_UNSUPPORTED_TSQL_REVOKE_STMT, unsupported_feature.c_str(), getLineAndPos(perm)); } - } } @@ -1774,9 +1774,12 @@ void TsqlUnsupportedFeatureHandlerImpl::checkSupportedGrantStmt(TSqlParser::Gran { auto perm_obj = grant->permission_object(); auto obj_type = perm_obj->object_type(); - if (obj_type && !obj_type->OBJECT()) + if (grant->ALL() && obj_type && obj_type->SCHEMA()) + throw PGErrorWrapperException(ERROR, ERRCODE_FEATURE_NOT_SUPPORTED, "The all permission has been deprecated and is not available for this class of entity.", getLineAndPos(grant)); + if (obj_type && !(obj_type->OBJECT() || obj_type->SCHEMA())) { unsupported_feature = "GRANT ON " + obj_type->getText(); + std::transform(unsupported_feature.begin(), unsupported_feature.end(), unsupported_feature.begin(), ::toupper); handle(INSTR_UNSUPPORTED_TSQL_REVOKE_STMT, unsupported_feature.c_str(), getLineAndPos(obj_type)); } } @@ -1856,10 +1859,10 @@ void TsqlUnsupportedFeatureHandlerImpl::checkSupportedRevokeStmt(TSqlParser::Rev continue; else { - unsupported_feature = "REVOKE PERMISSION " + perm->getText(); + unsupported_feature = "REVOKE PERMISSION " + ::getFullText(single_perm); + std::transform(unsupported_feature.begin(), unsupported_feature.end(), unsupported_feature.begin(), ::toupper); handle(INSTR_UNSUPPORTED_TSQL_REVOKE_STMT, unsupported_feature.c_str(), getLineAndPos(perm)); } - } } @@ -1867,9 +1870,12 @@ void TsqlUnsupportedFeatureHandlerImpl::checkSupportedRevokeStmt(TSqlParser::Rev { auto perm_obj = revoke->permission_object(); auto obj_type = perm_obj->object_type(); - if (obj_type && !obj_type->OBJECT()) + if (revoke->ALL() && obj_type && obj_type->SCHEMA()) + throw PGErrorWrapperException(ERROR, ERRCODE_FEATURE_NOT_SUPPORTED, "The all permission has been deprecated and is not available for this class of entity.", getLineAndPos(revoke)); + if (obj_type && !(obj_type->OBJECT() || obj_type->SCHEMA())) { unsupported_feature = "REVOKE ON " + obj_type->getText(); + std::transform(unsupported_feature.begin(), unsupported_feature.end(), unsupported_feature.begin(), ::toupper); handle(INSTR_UNSUPPORTED_TSQL_REVOKE_STMT, unsupported_feature.c_str(), getLineAndPos(obj_type)); } } diff --git a/contrib/babelfishpg_tsql/src/tsql_for/forjson.c b/contrib/babelfishpg_tsql/src/tsql_for/forjson.c index e908c2fd3ac..afba6e65800 100644 --- a/contrib/babelfishpg_tsql/src/tsql_for/forjson.c +++ b/contrib/babelfishpg_tsql/src/tsql_for/forjson.c @@ -325,6 +325,11 @@ tsql_auto_row_to_json(JsonbValue* jsonbArray, Datum record, bool include_null_va // Determine if the value should be inserted as a nested json object parts = determine_parts(colname, &num); + if(strcmp(parts[0], "JSONAUTOALIAS") != 0) { + ereport(ERROR, + (errcode(ERRCODE_FEATURE_NOT_SUPPORTED), + errmsg("sub-select and values for json auto are not currently supported."))); + } colname = remove_index_and_alias(colname); nestedVal = value; diff --git a/test/JDBC/expected/13_5__preparation__sys-assembly_types-vu-prepare.out b/test/JDBC/expected/13_5__preparation__sys-assembly_types-vu-prepare.out index 08bffefed13..ef7c296a506 100644 --- a/test/JDBC/expected/13_5__preparation__sys-assembly_types-vu-prepare.out +++ b/test/JDBC/expected/13_5__preparation__sys-assembly_types-vu-prepare.out @@ -3,7 +3,7 @@ SELECT * FROM sys.assembly_types GO CREATE PROC sys_assembly_types_proc_vu_prepare AS -SELECT * FROM sys.assembly_types +SELECT name, principal_id, max_length, precision, scale, collation_name, is_nullable, is_user_defined, is_assembly_type, default_object_id, rule_object_id, assembly_id, assembly_class, is_binary_ordered, is_fixed_length, prog_id, assembly_qualified_name, is_table_type FROM sys.assembly_types GO CREATE FUNCTION sys_assembly_types_func_vu_prepare() diff --git a/test/JDBC/expected/13_6__preparation__sys-assembly_types-vu-prepare.out b/test/JDBC/expected/13_6__preparation__sys-assembly_types-vu-prepare.out index 08bffefed13..ef7c296a506 100644 --- a/test/JDBC/expected/13_6__preparation__sys-assembly_types-vu-prepare.out +++ b/test/JDBC/expected/13_6__preparation__sys-assembly_types-vu-prepare.out @@ -3,7 +3,7 @@ SELECT * FROM sys.assembly_types GO CREATE PROC sys_assembly_types_proc_vu_prepare AS -SELECT * FROM sys.assembly_types +SELECT name, principal_id, max_length, precision, scale, collation_name, is_nullable, is_user_defined, is_assembly_type, default_object_id, rule_object_id, assembly_id, assembly_class, is_binary_ordered, is_fixed_length, prog_id, assembly_qualified_name, is_table_type FROM sys.assembly_types GO CREATE FUNCTION sys_assembly_types_func_vu_prepare() diff --git a/test/JDBC/expected/13_7__preparation__sys-assembly_types-vu-prepare.out b/test/JDBC/expected/13_7__preparation__sys-assembly_types-vu-prepare.out index 08bffefed13..ef7c296a506 100644 --- a/test/JDBC/expected/13_7__preparation__sys-assembly_types-vu-prepare.out +++ b/test/JDBC/expected/13_7__preparation__sys-assembly_types-vu-prepare.out @@ -3,7 +3,7 @@ SELECT * FROM sys.assembly_types GO CREATE PROC sys_assembly_types_proc_vu_prepare AS -SELECT * FROM sys.assembly_types +SELECT name, principal_id, max_length, precision, scale, collation_name, is_nullable, is_user_defined, is_assembly_type, default_object_id, rule_object_id, assembly_id, assembly_class, is_binary_ordered, is_fixed_length, prog_id, assembly_qualified_name, is_table_type FROM sys.assembly_types GO CREATE FUNCTION sys_assembly_types_func_vu_prepare() diff --git a/test/JDBC/expected/13_8__preparation__sys-assembly_types-vu-prepare.out b/test/JDBC/expected/13_8__preparation__sys-assembly_types-vu-prepare.out index 08bffefed13..ef7c296a506 100644 --- a/test/JDBC/expected/13_8__preparation__sys-assembly_types-vu-prepare.out +++ b/test/JDBC/expected/13_8__preparation__sys-assembly_types-vu-prepare.out @@ -3,7 +3,7 @@ SELECT * FROM sys.assembly_types GO CREATE PROC sys_assembly_types_proc_vu_prepare AS -SELECT * FROM sys.assembly_types +SELECT name, principal_id, max_length, precision, scale, collation_name, is_nullable, is_user_defined, is_assembly_type, default_object_id, rule_object_id, assembly_id, assembly_class, is_binary_ordered, is_fixed_length, prog_id, assembly_qualified_name, is_table_type FROM sys.assembly_types GO CREATE FUNCTION sys_assembly_types_func_vu_prepare() diff --git a/test/JDBC/expected/13_9__preparation__sys-assembly_types-vu-prepare.out b/test/JDBC/expected/13_9__preparation__sys-assembly_types-vu-prepare.out index 08bffefed13..ef7c296a506 100644 --- a/test/JDBC/expected/13_9__preparation__sys-assembly_types-vu-prepare.out +++ b/test/JDBC/expected/13_9__preparation__sys-assembly_types-vu-prepare.out @@ -3,7 +3,7 @@ SELECT * FROM sys.assembly_types GO CREATE PROC sys_assembly_types_proc_vu_prepare AS -SELECT * FROM sys.assembly_types +SELECT name, principal_id, max_length, precision, scale, collation_name, is_nullable, is_user_defined, is_assembly_type, default_object_id, rule_object_id, assembly_id, assembly_class, is_binary_ordered, is_fixed_length, prog_id, assembly_qualified_name, is_table_type FROM sys.assembly_types GO CREATE FUNCTION sys_assembly_types_func_vu_prepare() diff --git a/test/JDBC/expected/14_3__preparation__sys-assembly_types-vu-prepare.out b/test/JDBC/expected/14_3__preparation__sys-assembly_types-vu-prepare.out index 08bffefed13..ef7c296a506 100644 --- a/test/JDBC/expected/14_3__preparation__sys-assembly_types-vu-prepare.out +++ b/test/JDBC/expected/14_3__preparation__sys-assembly_types-vu-prepare.out @@ -3,7 +3,7 @@ SELECT * FROM sys.assembly_types GO CREATE PROC sys_assembly_types_proc_vu_prepare AS -SELECT * FROM sys.assembly_types +SELECT name, principal_id, max_length, precision, scale, collation_name, is_nullable, is_user_defined, is_assembly_type, default_object_id, rule_object_id, assembly_id, assembly_class, is_binary_ordered, is_fixed_length, prog_id, assembly_qualified_name, is_table_type FROM sys.assembly_types GO CREATE FUNCTION sys_assembly_types_func_vu_prepare() diff --git a/test/JDBC/expected/AUTO_ANALYZE-vu-prepare.out b/test/JDBC/expected/AUTO_ANALYZE-vu-prepare.out index a5551563705..d569a9922d3 100644 --- a/test/JDBC/expected/AUTO_ANALYZE-vu-prepare.out +++ b/test/JDBC/expected/AUTO_ANALYZE-vu-prepare.out @@ -22,6 +22,7 @@ babelfish_extended_properties babelfish_function_ext babelfish_helpcollation babelfish_namespace_ext +babelfish_schema_permissions babelfish_server_options babelfish_sysdatabases babelfish_syslanguages diff --git a/test/JDBC/expected/BABEL-2869.out b/test/JDBC/expected/BABEL-2869.out index aef905b9f5e..f6de5eae1e8 100644 --- a/test/JDBC/expected/BABEL-2869.out +++ b/test/JDBC/expected/BABEL-2869.out @@ -48,6 +48,8 @@ datetime2 datetimeoffset decimal float +geography +geometry image int money diff --git a/test/JDBC/expected/BABEL-4554-vu-cleanup.out b/test/JDBC/expected/BABEL-4554-vu-cleanup.out new file mode 100644 index 00000000000..fcb11b3f99e --- /dev/null +++ b/test/JDBC/expected/BABEL-4554-vu-cleanup.out @@ -0,0 +1,2 @@ +DROP TYPE babel_4554_type +GO diff --git a/test/JDBC/expected/BABEL-4554-vu-prepare.out b/test/JDBC/expected/BABEL-4554-vu-prepare.out new file mode 100644 index 00000000000..1e6573b1cdf --- /dev/null +++ b/test/JDBC/expected/BABEL-4554-vu-prepare.out @@ -0,0 +1,64 @@ + +-- Verify that newly created temp tables have toasts in ENR. +CREATE TABLE #babel_4554_temp_table(a varchar(4000), b nvarchar(MAX), c sysname) +GO + +-- 3: table, toast, index on toast +SELECT COUNT(*) FROM sys.babelfish_get_enr_list() +GO +~~START~~ +int +3 +~~END~~ + + +DROP TABLE #babel_4554_temp_table +GO + +-- 4: table, toast, index on toast, pkey +CREATE TABLE #babel_4554_temp_table_2(a sysname primary key, b nvarchar(MAX)) +GO + +SELECT COUNT(*) FROM sys.babelfish_get_enr_list() +GO +~~START~~ +int +4 +~~END~~ + + +-- 1: index +CREATE INDEX #babel_4554_idx1 ON #babel_4554_temp_table_2(b) +GO + +SELECT COUNT(*) FROM sys.babelfish_get_enr_list() +GO +~~START~~ +int +5 +~~END~~ + + +DROP INDEX #babel_4554_idx1 ON #babel_4554_temp_table_2 +GO + +DROP TABLE #babel_4554_temp_table_2 +GO + +-- Verify that non-ENR tables don't put their toasts in ENR. +CREATE TYPE babel_4554_type FROM INT +GO + +CREATE TABLE #babel_4554_temp_table_not_enr(a babel_4554_type, b nvarchar(MAX)) +GO + +SELECT COUNT(*) FROM sys.babelfish_get_enr_list() +GO +~~START~~ +int +0 +~~END~~ + + +DROP TABLE #babel_4554_temp_table_not_enr +GO diff --git a/test/JDBC/expected/BABEL-4554-vu-verify.out b/test/JDBC/expected/BABEL-4554-vu-verify.out new file mode 100644 index 00000000000..5d6edf026ab --- /dev/null +++ b/test/JDBC/expected/BABEL-4554-vu-verify.out @@ -0,0 +1,25 @@ + +-- We should have no dangling entries here (taken from BABEL-4554 DA) +select * +from pg_class where relname in +( + select relname + from pg_class c + where not exists + ( + SELECT * from pg_class d + WHERE c.oid = d.reltoastrelid + ) + AND relname in + ( + select s.relname from pg_stat_all_tables s where s.relname LIKE 'pg_toast_%' + ) + AND pg_table_size(c.oid) = 0 + AND c.relkind = 't' + AND c.relpersistence = 't' +) +GO +~~START~~ +int#!#varchar#!#int#!#int#!#int#!#int#!#int#!#int#!#int#!#int#!#real#!#int#!#int#!#bit#!#bit#!#varchar#!#varchar#!#smallint#!#smallint#!#bit#!#bit#!#bit#!#bit#!#bit#!#bit#!#varchar#!#bit#!#int#!#int#!#int#!#varchar#!#varchar#!#varchar +~~END~~ + diff --git a/test/JDBC/expected/BABEL-CROSS-DB.out b/test/JDBC/expected/BABEL-CROSS-DB.out index bf13b5f26f5..2273c92e4f2 100644 --- a/test/JDBC/expected/BABEL-CROSS-DB.out +++ b/test/JDBC/expected/BABEL-CROSS-DB.out @@ -522,6 +522,12 @@ DROP PROCEDURE p1 GO -- tsql +USE db1; +GO + +DROP TABLE db1_t1; +GO + USE master; GO diff --git a/test/JDBC/expected/BABEL-GRANT.out b/test/JDBC/expected/BABEL-GRANT.out index 7847a641567..2a59cf3dead 100644 --- a/test/JDBC/expected/BABEL-GRANT.out +++ b/test/JDBC/expected/BABEL-GRANT.out @@ -20,6 +20,10 @@ GO --- --- Prepare Objects --- +---- SCHEMA +CREATE SCHEMA scm; +GO + ---- TABLE CREATE TABLE t1 ( a int, b int); GO @@ -57,6 +61,18 @@ GO --- --- Basic Grant / Revoke --- +GRANT SELECT ON SCHEMA::scm TO guest; +GO + +GRANT SELECT ON SCHEMA::scm TO PUBLIC; +GO + +REVOKE SELECT ON SCHEMA::scm FROM PUBLIC; +GO + +GRANT INSERT ON SCHEMA::scm TO guest; +GO + GRANT ALL ON OBJECT::t1 TO guest WITH GRANT OPTION; GO @@ -155,7 +171,10 @@ GO ~~ERROR (Message: 'REVOKE ALL on Database' is not currently supported in Babelfish)~~ -GRANT SHOWPLAN ON OBJECT::t1 TO guest; -- unsupported permission +REVOKE SELECT ON SCHEMA::scm FROM guest; +GO + +GRANT showplan ON OBJECT::t1 TO guest; -- unsupported permission GO ~~ERROR (Code: 33557097)~~ @@ -169,18 +188,46 @@ GO ~~ERROR (Message: 'REVOKE PERMISSION SHOWPLAN' is not currently supported in Babelfish)~~ -GRANT ALL ON SCHEMA::scm TO guest; -- unsupported class +GRANT ALL ON SCHEMA::scm TO guest; +GO +~~ERROR (Code: 33557097)~~ + +~~ERROR (Message: The all permission has been deprecated and is not available for this class of entity.)~~ + + +REVOKE ALL ON SCHEMA::scm TO guest; GO ~~ERROR (Code: 33557097)~~ -~~ERROR (Message: 'GRANT ON SCHEMA' is not currently supported in Babelfish)~~ +~~ERROR (Message: The all permission has been deprecated and is not available for this class of entity.)~~ -REVOKE ALL ON SCHEMA::scm TO guest; -- unsupported class +GRANT create table ON OBJECT::t1 TO guest; -- unsupported permission GO ~~ERROR (Code: 33557097)~~ -~~ERROR (Message: 'REVOKE ON SCHEMA' is not currently supported in Babelfish)~~ +~~ERROR (Message: 'GRANT PERMISSION CREATE TABLE' is not currently supported in Babelfish)~~ + + +REVOKE create table ON OBJECT::t2 FROM alogin; -- unsupported permission +GO +~~ERROR (Code: 33557097)~~ + +~~ERROR (Message: 'REVOKE PERMISSION CREATE TABLE' is not currently supported in Babelfish)~~ + + +GRANT SELECT ON table::t1 TO guest; -- unsupported object +GO +~~ERROR (Code: 33557097)~~ + +~~ERROR (Message: 'GRANT ON TABLE' is not currently supported in Babelfish)~~ + + +REVOKE SELECT ON table::t1 FROM guest; -- unsupported object +GO +~~ERROR (Code: 33557097)~~ + +~~ERROR (Message: 'REVOKE ON TABLE' is not currently supported in Babelfish)~~ GRANT ALL ON OBJECT::t1 TO guest WITH GRANT OPTION AS superuser; @@ -213,6 +260,9 @@ GO --- --- Clean Up --- +DROP SCHEMA scm; +GO + DROP VIEW IF EXISTS my_view; GO diff --git a/test/JDBC/expected/BABEL-SESSION.out b/test/JDBC/expected/BABEL-SESSION.out index 87d51024a55..6e9888edd58 100644 --- a/test/JDBC/expected/BABEL-SESSION.out +++ b/test/JDBC/expected/BABEL-SESSION.out @@ -153,6 +153,21 @@ USE master; GO -- tsql +USE db1; +GO + +DROP TABLE tb1; +GO + +DROP TABLE janedoe_schema.t1; +GO + +DROP SCHEMA janedoe_schema; +GO + +USE master; +go + DROP DATABASE db1; GO diff --git a/test/JDBC/expected/BABEL_OBJECT_ID-vu-cleanup.out b/test/JDBC/expected/BABEL_OBJECT_ID-vu-cleanup.out index ed603c01cf6..5b12a9b58f8 100644 --- a/test/JDBC/expected/BABEL_OBJECT_ID-vu-cleanup.out +++ b/test/JDBC/expected/BABEL_OBJECT_ID-vu-cleanup.out @@ -39,6 +39,9 @@ GO DROP SCHEMA [babel_object_id_schema .with .dot_and_spaces] GO +DROP TYPE babel_object_id_type +GO + DROP TABLE [babel_object_id_t2 .with .dot_an_spaces] GO diff --git a/test/JDBC/expected/BABEL_OBJECT_ID-vu-prepare.out b/test/JDBC/expected/BABEL_OBJECT_ID-vu-prepare.out index 5c3da143f99..7ab81a7644d 100644 --- a/test/JDBC/expected/BABEL_OBJECT_ID-vu-prepare.out +++ b/test/JDBC/expected/BABEL_OBJECT_ID-vu-prepare.out @@ -46,6 +46,9 @@ GO CREATE TABLE [babel_object_id_schema .with .dot_and_spaces]."babel_object_id_t3 .with .dot_and_spaces" (a int); GO +CREATE TYPE babel_object_id_type FROM int +GO + -- To test lookup in different database CREATE DATABASE babel_object_id_db; GO diff --git a/test/JDBC/expected/BABEL_OBJECT_ID-vu-verify.out b/test/JDBC/expected/BABEL_OBJECT_ID-vu-verify.out index ff2c0a164eb..4979842ba25 100644 --- a/test/JDBC/expected/BABEL_OBJECT_ID-vu-verify.out +++ b/test/JDBC/expected/BABEL_OBJECT_ID-vu-verify.out @@ -255,6 +255,18 @@ varchar ~~END~~ +-- Test temp objects not in ENR +CREATE TABLE #babel_object_id_temp_t2(a babel_object_id_type); +GO + +SELECT OBJECT_NAME(OBJECT_ID('#babel_object_id_temp_t2')) +GO +~~START~~ +varchar +#babel_object_id_temp_t2 +~~END~~ + + -- We can also specify object_type as parameter SELECT OBJECT_NAME(OBJECT_ID('#babel_object_id_temp_t1', 'U')) GO diff --git a/test/JDBC/expected/GRANT_SCHEMA-vu-cleanup.out b/test/JDBC/expected/GRANT_SCHEMA-vu-cleanup.out new file mode 100644 index 00000000000..af83d2ea36d --- /dev/null +++ b/test/JDBC/expected/GRANT_SCHEMA-vu-cleanup.out @@ -0,0 +1,75 @@ +-- tsql +-- Drop objects +use grant_schema_d1; +go + +drop table grant_schema_s1.grant_schema_t1; +go + +drop table grant_schema_s1.grant_schema_t2; +go + +drop table grant_schema_s1.grant_schema_t3; +go + +drop view grant_schema_s1.grant_schema_v1; +go + +drop view grant_schema_s1.grant_schema_v2; +go + +drop proc grant_schema_s1.grant_schema_p1; +go + +drop proc grant_schema_s1.grant_schema_p2; +go + +drop function grant_schema_s1.grant_schema_f1; +go + +drop function grant_schema_s1.grant_schema_f2; +go + +drop schema grant_schema_s1; +go + +drop table grant_schema_s2.grant_schema_t1; +go + +drop table grant_schema_s2.grant_schema_t2; +go + +drop schema grant_schema_s2; +go + +drop user grant_schema_u1; +go + +use master; +go + +drop database grant_schema_d1; +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) = 'grant_schema_l1' AND backend_type = 'client backend' AND usesysid IS NOT NULL; +go +~~START~~ +bool +~~END~~ + + +-- Wait to sync with another session +SELECT pg_sleep(1); +go +~~START~~ +void + +~~END~~ + + +-- tsql +drop login grant_schema_l1; +go diff --git a/test/JDBC/expected/GRANT_SCHEMA-vu-prepare.out b/test/JDBC/expected/GRANT_SCHEMA-vu-prepare.out new file mode 100644 index 00000000000..069a323b573 --- /dev/null +++ b/test/JDBC/expected/GRANT_SCHEMA-vu-prepare.out @@ -0,0 +1,74 @@ +-- tsql +-- create objects +create database grant_schema_d1; +go + +use grant_schema_d1; +go + +create login grant_schema_l1 with password = '12345678' +go + +create user grant_schema_u1 for login grant_schema_l1; +go + +create schema grant_schema_s1; +go + +create table grant_schema_s1.grant_schema_t1(a int); +go + +create table grant_schema_s1.grant_schema_t2(b int); +go + +create table grant_schema_s1.grant_schema_t3(c int); +go + +create view grant_schema_s1.grant_schema_v1 as select 2; +go + +create view grant_schema_s1.grant_schema_v2 as select 2; +go + +create proc grant_schema_s1.grant_schema_p1 as select 2; +go + +create proc grant_schema_s1.grant_schema_p2 as select 2; +go + +CREATE FUNCTION grant_schema_s1.grant_schema_f1() RETURNS INT AS BEGIN RETURN (SELECT COUNT(*) FROM sys.objects) END +go + +CREATE FUNCTION grant_schema_s1.grant_schema_f2() RETURNS INT AS BEGIN RETURN (SELECT COUNT(*) FROM sys.objects) END +go + +create schema grant_schema_s2; +go + +create table grant_schema_s2.grant_schema_t1(a int); +go + +create table grant_schema_s2.grant_schema_t2(a int); +go + +-- GRANT OBJECT privilege +grant select on grant_schema_s1.grant_schema_t1 to grant_schema_u1; +go +grant select on grant_schema_s1.grant_schema_t3 to grant_schema_u1; +go +grant select on grant_schema_s1.grant_schema_v1 to grant_schema_u1; +go +grant select on grant_schema_s1.grant_schema_v2 to grant_schema_u1; +go +grant execute on grant_schema_s1.grant_schema_p1 to grant_schema_u1; +go +grant execute on grant_schema_s1.grant_schema_p2 to grant_schema_u1; +go +grant execute on grant_schema_s1.grant_schema_f1 to grant_schema_u1; +go +grant execute on grant_schema_s1.grant_schema_f2 to grant_schema_u1; +go +grant select on grant_schema_s2.grant_schema_t1 to grant_schema_u1; +go +grant select on grant_schema_s2.grant_schema_t2 to grant_schema_u1; +go diff --git a/test/JDBC/expected/GRANT_SCHEMA-vu-verify.out b/test/JDBC/expected/GRANT_SCHEMA-vu-verify.out new file mode 100644 index 00000000000..16a45233e29 --- /dev/null +++ b/test/JDBC/expected/GRANT_SCHEMA-vu-verify.out @@ -0,0 +1,291 @@ +-- tsql user=grant_schema_l1 password=12345678 +-- User has OBJECT privileges, should be accessible. +use grant_schema_d1; +go + +select * from grant_schema_s1.grant_schema_t1; +go +~~START~~ +int +~~END~~ + + +select * from grant_schema_s1.grant_schema_t2; -- case 1: has no permission +go +~~ERROR (Code: 33557097)~~ + +~~ERROR (Message: permission denied for table grant_schema_t2)~~ + + +select * from grant_schema_s1.grant_schema_v1; +go +~~START~~ +int +2 +~~END~~ + + +exec grant_schema_s1.grant_schema_p1; +go +~~START~~ +int +2 +~~END~~ + + +select * from grant_schema_s1.grant_schema_f1(); +go +~~START~~ +int +10 +~~END~~ + + +-- tsql +-- REVOKE OBJECT privilege +use grant_schema_d1; +go +revoke select on grant_schema_s1.grant_schema_t1 from grant_schema_u1; +go +revoke select on grant_schema_s1.grant_schema_v1 from grant_schema_u1; +go +revoke execute on grant_schema_s1.grant_schema_p1 from grant_schema_u1; +go +revoke execute on grant_schema_s1.grant_schema_f1 from grant_schema_u1; +go + +-- tsql user=grant_schema_l1 password=12345678 +-- User has no privileges, should not be accessible. +use grant_schema_d1; +go + +select * from grant_schema_s1.grant_schema_t1; +go +~~ERROR (Code: 33557097)~~ + +~~ERROR (Message: permission denied for table grant_schema_t1)~~ + + +select * from grant_schema_s1.grant_schema_v1; +go +~~ERROR (Code: 33557097)~~ + +~~ERROR (Message: permission denied for view grant_schema_v1)~~ + + +exec grant_schema_s1.grant_schema_p1; +go +~~ERROR (Code: 33557097)~~ + +~~ERROR (Message: permission denied for procedure grant_schema_p1)~~ + + +select * from grant_schema_s1.grant_schema_f1(); +go +~~ERROR (Code: 33557097)~~ + +~~ERROR (Message: permission denied for function grant_schema_f1)~~ + + +-- tsql +-- GRANT SCHEMA privilege +use grant_schema_d1; +go +grant select, execute on schema::grant_schema_s1 to grant_schema_u1; +go +use master; +go + +-- tsql user=grant_schema_l1 password=12345678 +-- User has SCHEMA privileges, should be accessible. +use grant_schema_d1; +go + +select * from grant_schema_s1.grant_schema_t1; +go +~~START~~ +int +~~END~~ + + +select * from grant_schema_s1.grant_schema_t2; +go +~~START~~ +int +~~END~~ + + +select * from grant_schema_s1.grant_schema_v1; +go +~~START~~ +int +2 +~~END~~ + + +exec grant_schema_s1.grant_schema_p1; +go +~~START~~ +int +2 +~~END~~ + + +select * from grant_schema_s1.grant_schema_f1(); +go +~~START~~ +int +11 +~~END~~ + + +-- User has OBJECT and SCHEMA privileges, should be accessible. +use grant_schema_d1; +go + +select * from grant_schema_s1.grant_schema_t3; +go +~~START~~ +int +~~END~~ + + +select * from grant_schema_s1.grant_schema_v2; +go +~~START~~ +int +2 +~~END~~ + + +exec grant_schema_s1.grant_schema_p2; +go +~~START~~ +int +2 +~~END~~ + + +select * from grant_schema_s1.grant_schema_f2(); +go +~~START~~ +int +11 +~~END~~ + + +-- tsql +-- Case 6: User has SCHEMA privilege, REVOKE OBJECT privilege +use grant_schema_d1; +go +revoke select on grant_schema_s1.grant_schema_t3 from grant_schema_u1; +go +revoke select on grant_schema_s1.grant_schema_v2 from grant_schema_u1; +go +revoke execute on grant_schema_s1.grant_schema_p2 from grant_schema_u1; +go +revoke execute on grant_schema_s1.grant_schema_f2 from grant_schema_u1; +go + +-- tsql user=grant_schema_l1 password=12345678 +-- User has SCHEMA privileges, should be accessible. +use grant_schema_d1; +go + +select * from grant_schema_s1.grant_schema_t3; +go +~~START~~ +int +~~END~~ + + +select * from grant_schema_s1.grant_schema_v2; +go +~~START~~ +int +2 +~~END~~ + + +exec grant_schema_s1.grant_schema_p2; +go +~~START~~ +int +2 +~~END~~ + + +select * from grant_schema_s1.grant_schema_f2(); +go +~~START~~ +int +11 +~~END~~ + + +-- tsql +-- User has OBJECT privilege, REVOKE OBJECT privilege +-- case 7: User has no privileges, should not be accessible. +use grant_schema_d1; +go +revoke select on grant_schema_s2.grant_schema_t2 from grant_schema_u1; +go +use master; +go + +-- tsql user=grant_schema_l1 password=12345678 +use grant_schema_d1; +go + +select * from grant_schema_s2.grant_schema_t2; +go +~~ERROR (Code: 33557097)~~ + +~~ERROR (Message: permission denied for table grant_schema_t2)~~ + + +-- tsql +-- User has OBJECT privilege, REVOKE SCHEMA privilege +-- case 8: User has OBJECT privileges, would not be accessible. +use grant_schema_d1; +go +revoke select on schema::grant_schema_s2 from grant_schema_u1; +go +use master; +go + +-- tsql user=grant_schema_l1 password=12345678 +use grant_schema_d1; +go + +select * from grant_schema_s2.grant_schema_t1; +go +~~ERROR (Code: 33557097)~~ + +~~ERROR (Message: permission denied for table grant_schema_t1)~~ + + +-- tsql +-- User has OBJECT privilege, GRANT and REVOKE SCHEMA privilege +-- case 5: User has OBJECT privileges, would not be accessible. +use grant_schema_d1; +go +grant select on schema::grant_schema_s2 to grant_schema_u1; +go + +revoke select on schema::grant_schema_s2 from grant_schema_u1; +go +use master; +go + +-- tsql user=grant_schema_l1 password=12345678 +use grant_schema_d1; +go + +select * from grant_schema_s2.grant_schema_t1; +go +~~ERROR (Code: 33557097)~~ + +~~ERROR (Message: permission denied for table grant_schema_t1)~~ + + diff --git a/test/JDBC/expected/GRANT_SCHEMA.out b/test/JDBC/expected/GRANT_SCHEMA.out new file mode 100644 index 00000000000..6b72d81f49b --- /dev/null +++ b/test/JDBC/expected/GRANT_SCHEMA.out @@ -0,0 +1,1054 @@ +-- tsql +-- create objects +create database babel_4344_d1; +go + +use babel_4344_d1; +go + +create login babel_4344_l1 with password = '12345678' +go + +create user babel_4344_u1 for login babel_4344_l1; +go + +create login αιώνια with password = '12345678' +go + +create user αιώνια for login αιώνια; +go + +create login ログイン with password = '12345678' +go + +create user ログイン for login ログイン; +go + +create schema babel_4344_s1; +go + +create schema "BAbel_4344 S1"; +go + +create table "babel_4344 s1"."babel_4344 t1"(a int); +go + +create schema αγάπη; +go + +create schema スキーマ; +go + +create schema babel_4344_s2 authorization babel_4344_u1; +go + +create table babel_4344_t1(a int); +go + +create table babel_4344_s1.babel_4344_t1(a int); +go + +create table babel_4344_s2.babel_4344_t1(a int); +go + +create table αγάπη.abc(a int); +go + +create table スキーマ.abc(a int); +go + +create table babel_4344_t3(a int, b int); +go + +create table babel_4344_s1.babel_4344_t3(a int, b int); +go + +create schema "update pg_class set oid = 0 where relname = 'babel_4344_t1'"; +go + +create view babel_4344_v1 as select 1; +go + +create view babel_4344_s1.babel_4344_v1 as select 2; +go + +create proc babel_4344_p1 as select 1; +go + +create proc babel_4344_s1.babel_4344_p1 as select 2; +go + +create proc babel_4344_s1.babel_4344_p3 as select 3; +go + +CREATE FUNCTION babel_4344_f1() returns int begin declare @a int; set @a = 1; return @a; end +go + +CREATE FUNCTION babel_4344_s1.babel_4344_f1() returns int begin declare @a int; set @a = 1; return @a; END +go + +-- tests with greek character (one byte) and japanese character (muti bytes) +grant SELECT on schema::babel_4344_S1 to public, αιώνια, ログイン; +go + +grant select on schema::αγάπη to αιώνια, ログイン; +go + +grant select on schema::スキーマ to ログイン, αιώνια; +go + +-- test special database roles +grant SELECT on schema::babel_4344_S1 to db_owner; -- throws an error +go +~~ERROR (Code: 33557097)~~ + +~~ERROR (Message: Cannot grant, deny or revoke permissions to or from special roles.)~~ + + +grant SELECT on schema::babel_4344_S1 to sys; -- throws an error +go +~~ERROR (Code: 33557097)~~ + +~~ERROR (Message: Cannot grant, deny, or revoke permissions to sa, dbo, entity owner, information_schema, sys, or yourself.)~~ + + +grant SELECT on schema::babel_4344_S1 to information_schema; -- throws an error +go +~~ERROR (Code: 33557097)~~ + +~~ERROR (Message: Cannot grant, deny, or revoke permissions to sa, dbo, entity owner, information_schema, sys, or yourself.)~~ + + +grant SELECT on schema::babel_4344_S1 to dbo; -- throws an error +go +~~ERROR (Code: 33557097)~~ + +~~ERROR (Message: Cannot grant, deny, or revoke permissions to sa, dbo, entity owner, information_schema, sys, or yourself.)~~ + + +-- tsql user=ログイン password=12345678 +use babel_4344_d1; +go + +select * from αγάπη.abc; +go +~~START~~ +int +~~END~~ + + +select * from スキーマ.abc; +go +~~START~~ +int +~~END~~ + + +select * from babel_4344_S1.babel_4344_t1; +go +~~START~~ +int +~~END~~ + + +use master; +go + +-- tsql user=αιώνια password=12345678 +use babel_4344_d1; +go + +select * from αγάπη.abc; +go +~~START~~ +int +~~END~~ + + +select * from スキーマ.abc; +go +~~START~~ +int +~~END~~ + + +select * from babel_4344_S1.babel_4344_t1; +go +~~START~~ +int +~~END~~ + + +use master; +go + +-- tsql user=babel_4344_l1 password=12345678 +use babel_4344_d1; +go + +-- User has select privileges, tables and views be accessible +select * from babel_4344_s1.babel_4344_t1 +go +~~START~~ +int +~~END~~ + +select * from babel_4344_s1.babel_4344_v1; +go +~~START~~ +int +2 +~~END~~ + +use master; +go + +-- tsql +-- object names having more than 64 bytes +create schema abcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwzyzabcdefghijklmnopqrstuvwzyz +go + +create table abcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwzyzabcdefghijklmnopqrstuvwzyz.abcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwzyzabcdefghijklmnopqrstuvwzyz(a int); +go + +grant select on schema::abcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwzyzabcdefghijklmnopqrstuvwzyz to babel_4344_u1; +go + +revoke select on schema::abcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwzyzabcdefghijklmnopqrstuvwzyz from babel_4344_u1; +go + +grant select on abcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwzyzabcdefghijklmnopqrstuvwzyz.abcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwzyzabcdefghijklmnopqrstuvwzyz to babel_4344_u1; +go + +revoke select on abcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwzyzabcdefghijklmnopqrstuvwzyz.abcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwzyzabcdefghijklmnopqrstuvwzyz from babel_4344_u1; +go + +drop table abcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwzyzabcdefghijklmnopqrstuvwzyz.abcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwzyzabcdefghijklmnopqrstuvwzyz +go + +drop schema abcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwzyzabcdefghijklmnopqrstuvwzyz +go + +use babel_4344_d1; +go +revoke select on schema::babel_4344_s1 from public, αιώνια, ログイン; +go + +-- tsql user=babel_4344_l1 password=12345678 +use babel_4344_d1; +go + +-- User doesn't have any privileges, objects should not be accessible +select * from babel_4344_t1; +go +~~ERROR (Code: 33557097)~~ + +~~ERROR (Message: permission denied for table babel_4344_t1)~~ + +select * from babel_4344_s1.babel_4344_t1 +go +~~ERROR (Code: 33557097)~~ + +~~ERROR (Message: permission denied for table babel_4344_t1)~~ + +insert into babel_4344_s1.babel_4344_t1 values(1); +go +~~ERROR (Code: 33557097)~~ + +~~ERROR (Message: permission denied for table babel_4344_t1)~~ + +select * from babel_4344_v1; +go +~~ERROR (Code: 33557097)~~ + +~~ERROR (Message: permission denied for view babel_4344_v1)~~ + +select * from babel_4344_s1.babel_4344_v1; +go +~~ERROR (Code: 33557097)~~ + +~~ERROR (Message: permission denied for view babel_4344_v1)~~ + +exec babel_4344_p1; +go +~~ERROR (Code: 33557097)~~ + +~~ERROR (Message: permission denied for procedure babel_4344_p1)~~ + +exec babel_4344_s1.babel_4344_p1; +go +~~ERROR (Code: 33557097)~~ + +~~ERROR (Message: permission denied for procedure babel_4344_p1)~~ + +select * from babel_4344_f1(); +go +~~ERROR (Code: 33557097)~~ + +~~ERROR (Message: permission denied for function babel_4344_f1)~~ + +select * from babel_4344_s1.babel_4344_f1(); +go +~~ERROR (Code: 33557097)~~ + +~~ERROR (Message: permission denied for function babel_4344_f1)~~ + +use master; +go + +-- tsql +-- GRANT OBJECT privilege +use babel_4344_d1; +go +grant SELECT on schema::"bAbel_4344 s1" to BABEL_4344_U1; +go +grant SELECT on schema::"update pg_class set oid = 0 where relname = 'babel_4344_t1'" to BABEL_4344_U1; +go +grant SELECT on "babel_4344_t1" to BABEL_4344_U1; +go +grant SELECT on "babel_4344_s1".babel_4344_t1 to babel_4344_u1; +go +grant all on babel_4344_s1.babel_4344_t1 to "babel_4344_u1"; +go +grant select on babel_4344_t3(a) to babel_4344_u1; -- column privilege +go +grant select on babel_4344_s1.babel_4344_t3(a) to babel_4344_u1; -- column privilege +go +grant select on babel_4344_v1 to babel_4344_u1; +go +grant select on babel_4344_s1.babel_4344_v1 to babel_4344_u1; +go +grant execute on babel_4344_p1 to babel_4344_u1; +go +grant execute on babel_4344_s1.babel_4344_p1 to babel_4344_u1; +go +-- inside a transaction, permission will not be granted since it is rolled back +begin transaction; +exec sp_executesql N'grant execute on babel_4344_s1.babel_4344_p3 to babel_4344_u1;'; +rollback transaction; +go + +-- Mixed case +grant Execute on Babel_4344_F1 to Babel_4344_u1; +go +grant execute on BABEL_4344_s1.babel_4344_f1 to babEL_4344_u1; +go +-- Grant schema permission to its owner, should fail +grant select on schema::babel_4344_s2 to babel_4344_u1; -- should fail +go +~~ERROR (Code: 33557097)~~ + +~~ERROR (Message: Cannot grant, deny, or revoke permissions to sa, dbo, entity owner, information_schema, sys, or yourself.)~~ + +grant select on schema::babel_4344_s2 to jdbc_user; -- should fail +go +~~ERROR (Code: 33557097)~~ + +~~ERROR (Message: Cannot find the principal 'jdbc_user', because it does not exist or you do not have permission.)~~ + +grant SELECT on schema::"babel_4344_s2" to guest; -- should pass +go +grant select on schema::"" to guest; -- should fail +go +~~ERROR (Code: 33557097)~~ + +~~ERROR (Message: An object or column name is missing or empty. For SELECT INTO statements, verify each column has a name. For other statements, look for empty alias names. Aliases defined as "" or [] are not allowed. Change the alias to a valid name.)~~ + +grant select on schema::non_existing_schema to guest; -- should fail +go +~~ERROR (Code: 33557097)~~ + +~~ERROR (Message: schema "non_existing_schema" does not exist)~~ + +-- grant statement via a procedure +create procedure grant_perm_proc as begin exec('grant select on schema::[] to guest') end; +go +exec grant_perm_proc; -- should fail, invalid GRANT statement +go +~~ERROR (Code: 33557097)~~ + +~~ERROR (Message: An object or column name is missing or empty. For SELECT INTO statements, verify each column has a name. For other statements, look for empty alias names. Aliases defined as "" or [] are not allowed. Change the alias to a valid name.)~~ + +-- non-existing role +grant SELECT on schema::dbo to guest, babel_4344_u3; -- should fail +go +~~ERROR (Code: 33557097)~~ + +~~ERROR (Message: Cannot find the principal 'babel_4344_u3', because it does not exist or you do not have permission.)~~ + + +-- tsql user=babel_4344_l1 password=12345678 +-- User has OBJECT privileges, should be accessible. +use babel_4344_d1; +go +select * from babel_4344_t1; +go +~~START~~ +int +~~END~~ + +select * from babel_4344_s1.babel_4344_t1 +go +~~START~~ +int +~~END~~ + +insert into babel_4344_s1.babel_4344_t1 values(2); +go +~~ROW COUNT: 1~~ + +select * from babel_4344_t3; -- not accessible, only column privilege is granted +go +~~ERROR (Code: 33557097)~~ + +~~ERROR (Message: permission denied for table babel_4344_t3)~~ + +select * from babel_4344_s1.babel_4344_t3 -- not accessible, only column privilege is granted +go +~~ERROR (Code: 33557097)~~ + +~~ERROR (Message: permission denied for table babel_4344_t3)~~ + +select * from babel_4344_v1; +go +~~START~~ +int +1 +~~END~~ + +select * from babel_4344_s1.babel_4344_v1; +go +~~START~~ +int +2 +~~END~~ + +exec babel_4344_p1; +go +~~START~~ +int +1 +~~END~~ + +exec babel_4344_s1.babel_4344_p1; +go +~~START~~ +int +2 +~~END~~ + +exec babel_4344_s1.babel_4344_p3; -- should fail, grant statement was rolled back +go +~~ERROR (Code: 33557097)~~ + +~~ERROR (Message: permission denied for procedure babel_4344_p3)~~ + +select * from BABEl_4344_f1(); +go +~~START~~ +int +1 +~~END~~ + +select * from babEL_4344_s1.babel_4344_f1(); +go +~~START~~ +int +1 +~~END~~ + +-- Grant schema permission to its owner +grant select on schema::babel_4344_s2 to babel_4344_u1; -- should fail +go +~~ERROR (Code: 33557097)~~ + +~~ERROR (Message: Cannot grant, deny, or revoke permissions to sa, dbo, entity owner, information_schema, sys, or yourself.)~~ + +grant select on schema::babel_4344_s2 to guest; -- should pass +go +grant select on schema::babel_4344_s1 to babel_4344_u1; -- should fail +go +~~ERROR (Code: 33557097)~~ + +~~ERROR (Message: Cannot grant, deny, or revoke permissions to sa, dbo, entity owner, information_schema, sys, or yourself.)~~ + +use master; +go + +-- tsql +-- GRANT SCHEMA privilege +use babel_4344_d1; +go +grant control on schema::babel_4344_s1 to babel_4344_u1; -- should fail, 'control' is not supported +go +~~ERROR (Code: 33557097)~~ + +~~ERROR (Message: 'GRANT PERMISSION CONTROL' is not currently supported in Babelfish)~~ + +grant select, insert, execute on schema::babel_4344_s1 to babel_4344_u1; +go +use master; +go + +-- psql +-- GRANT statement add an entry to the catalog +select schema_name, object_name, permission, grantee from sys.babelfish_schema_permissions +where schema_name = 'babel_4344_s1' collate "C" order by permission; -- and object_name = 'ALL' collate "C" +go +~~START~~ +"sys"."varchar"#!#"sys"."varchar"#!#int4#!#"sys"."varchar" +babel_4344_s1#!#babel_4344_v1#!#2#!#babel_4344_d1_babel_4344_u1 +babel_4344_s1#!#babel_4344_t1#!#47#!#babel_4344_d1_babel_4344_u1 +babel_4344_s1#!#babel_4344_p1#!#128#!#babel_4344_d1_babel_4344_u1 +babel_4344_s1#!#babel_4344_f1#!#128#!#babel_4344_d1_babel_4344_u1 +babel_4344_s1#!#ALL#!#131#!#babel_4344_d1_babel_4344_u1 +~~END~~ + + +-- tsql +-- GRANT SCHEMA privilege again +use babel_4344_d1; +go +grant select, insert, execute on schema::babel_4344_s1 to babel_4344_u1; +go +-- GRANT OBJECT privilege again +grant select on babel_4344_s1.babel_4344_v1 to babel_4344_u1; +go +use master; +go + +-- psql +-- check the consistency of catalog +select schema_name, object_name, permission, grantee from sys.babelfish_schema_permissions +where schema_name = 'babel_4344_s1' collate "C" order by permission; +go +~~START~~ +"sys"."varchar"#!#"sys"."varchar"#!#int4#!#"sys"."varchar" +babel_4344_s1#!#babel_4344_v1#!#2#!#babel_4344_d1_babel_4344_u1 +babel_4344_s1#!#babel_4344_t1#!#47#!#babel_4344_d1_babel_4344_u1 +babel_4344_s1#!#babel_4344_p1#!#128#!#babel_4344_d1_babel_4344_u1 +babel_4344_s1#!#babel_4344_f1#!#128#!#babel_4344_d1_babel_4344_u1 +babel_4344_s1#!#ALL#!#131#!#babel_4344_d1_babel_4344_u1 +~~END~~ + + +-- tsql user=babel_4344_l1 password=12345678 +-- User has OBJECT and SCHEMA privileges, should be accessible. +use babel_4344_d1; +go +select * from babel_4344_s1.babel_4344_t1 +go +~~START~~ +int +2 +~~END~~ + +insert into babel_4344_s1.babel_4344_t1 values(3); +go +~~ROW COUNT: 1~~ + +select * from babel_4344_s1.babel_4344_t3 +go +~~START~~ +int#!#int +~~END~~ + +select * from babel_4344_s1.babel_4344_v1; +go +~~START~~ +int +2 +~~END~~ + +exec babel_4344_s1.babel_4344_p1; +go +~~START~~ +int +2 +~~END~~ + +select * from babel_4344_s1.babel_4344_f1(); +go +~~START~~ +int +1 +~~END~~ + +use master; +go + +-- tsql +-- REVOKE SCHEMA privilege +use babel_4344_d1; +go +revoke select, insert, execute on schema::babel_4344_s1 from babel_4344_u1; +go +use master; +go + +-- tsql user=babel_4344_l1 password=12345678 +-- User has OBJECT privileges, should be accessible. +use babel_4344_d1; +go +select * from babel_4344_s1.babel_4344_t1 +go +~~START~~ +int +2 +3 +~~END~~ + +insert into babel_4344_s1.babel_4344_t1 values(3); +go +~~ROW COUNT: 1~~ + +select * from babel_4344_s1.babel_4344_t3 -- not accessible +go +~~ERROR (Code: 33557097)~~ + +~~ERROR (Message: permission denied for table babel_4344_t3)~~ + +select * from babel_4344_s1.babel_4344_v1; +go +~~START~~ +int +2 +~~END~~ + +exec babel_4344_s1.babel_4344_p1; +go +~~START~~ +int +2 +~~END~~ + +select * from babel_4344_s1.babel_4344_f1(); +go +~~START~~ +int +1 +~~END~~ + +select * from babel_4344_s2.babel_4344_t1; +go +~~START~~ +int +~~END~~ + +use master; +go + +-- tsql +-- create new objects in same schema +use babel_4344_d1; +go +-- Grant the permissions again +grant select, insert, execute on schema::babel_4344_s1 to babel_4344_u1; +go +grant select, insert, execute on schema::information_schema to babel_4344_u1; +go +create table babel_4344_s1.babel_4344_t2(a int); +go +create view babel_4344_s1.babel_4344_v2 as select 2; +go +create proc babel_4344_s1.babel_4344_p2 as select 2; +go +CREATE FUNCTION babel_4344_s1.babel_4344_f2() RETURNS INT AS BEGIN RETURN (SELECT COUNT(*) FROM sys.objects) END +go +use master; +go + +-- tsql user=babel_4344_l1 password=12345678 +-- User has SCHEMA privileges,objects should be accessible. +use babel_4344_d1; +go +select * from babel_4344_s1.babel_4344_t2 +go +~~START~~ +int +~~END~~ + +insert into babel_4344_s1.babel_4344_t1 values(4); +go +~~ROW COUNT: 1~~ + +select * from babel_4344_s1.babel_4344_v2; +go +~~START~~ +int +2 +~~END~~ + +exec babel_4344_s1.babel_4344_p2; +go +~~START~~ +int +2 +~~END~~ + +select * from babel_4344_s1.babel_4344_f2(); +go +~~START~~ +int +16 +~~END~~ + +select * from "bAbel_4344 s1"."bAbel_4344 t1"; +go +~~START~~ +int +~~END~~ + +use master; +go + +-- tsql +-- REVOKE OBJECT privileges +use babel_4344_d1; +go +REVOKE SELECT on schema::"bAbel_4344 s1" from "BABEL_4344_U1"; +go +REVOKE SELECT on schema::"update pg_class set oid = 0 where relname = 'babel_4344_t1'" from BABEL_4344_U1; +go +REVOKE all on babel_4344_s1.babel_4344_t1 FROM babel_4344_u1; +go +REVOKE select on babel_4344_s1.babel_4344_t3(a) FROM babel_4344_u1; +go +REVOKE select on babel_4344_s1.babel_4344_v1 FROM babel_4344_u1; +go +REVOKE execute on babel_4344_s1.babel_4344_p1 FROM babel_4344_u1; +go +REVOKE execute on babel_4344_s1.babel_4344_f1 FROM babel_4344_u1; +go +REVOKE all on babel_4344_s1.babel_4344_f1 FROM babel_4344_u1; +go + +-- tsql user=babel_4344_l1 password=12345678 +-- User has SCHEMA privileges, should be accessible. +use babel_4344_d1; +go +select * from babel_4344_s1.babel_4344_t1 +go +~~START~~ +int +2 +3 +3 +4 +~~END~~ + +insert into babel_4344_s1.babel_4344_t1 values(5); +go +~~ROW COUNT: 1~~ + +select * from babel_4344_s1.babel_4344_t3; +go +~~START~~ +int#!#int +~~END~~ + +select * from babel_4344_s1.babel_4344_v1; +go +~~START~~ +int +2 +~~END~~ + +exec babel_4344_s1.babel_4344_p1; +go +~~START~~ +int +2 +~~END~~ + +select * from babel_4344_s1.babel_4344_f1(); +go +~~START~~ +int +1 +~~END~~ + +select * from babel_4344_s2.babel_4344_t1; +go +~~START~~ +int +~~END~~ + +use master; +go + +-- tsql +-- REVOKE SCHEMA privileges +use babel_4344_d1; +go +revoke select, insert, execute on schema::babel_4344_s1 from babel_4344_u1; +go +use master; +go + +-- psql +-- REVOKE on schema removes the entry from the catalog +select * from sys.babelfish_schema_permissions where schema_name = 'babel_4344_s1' collate sys.database_default; +go +~~START~~ +int2#!#"sys"."varchar"#!#"sys"."varchar"#!#int4#!#"sys"."varchar"#!#bpchar +~~END~~ + + +-- tsql user=babel_4344_l1 password=12345678 +-- User has no privileges, shouldn't be accessible. +use babel_4344_d1; +go +select * from babel_4344_s1.babel_4344_t1; +go +~~ERROR (Code: 33557097)~~ + +~~ERROR (Message: permission denied for table babel_4344_t1)~~ + +insert into babel_4344_s1.babel_4344_t1 values(5); +go +~~ERROR (Code: 33557097)~~ + +~~ERROR (Message: permission denied for table babel_4344_t1)~~ + +select * from babel_4344_s1.babel_4344_t3; +go +~~ERROR (Code: 33557097)~~ + +~~ERROR (Message: permission denied for table babel_4344_t3)~~ + +select * from babel_4344_s1.babel_4344_v1; +go +~~ERROR (Code: 33557097)~~ + +~~ERROR (Message: permission denied for view babel_4344_v1)~~ + +exec babel_4344_s1.babel_4344_p1; +go +~~ERROR (Code: 33557097)~~ + +~~ERROR (Message: permission denied for procedure babel_4344_p1)~~ + +select * from babel_4344_s1.babel_4344_f1(); +go +~~ERROR (Code: 33557097)~~ + +~~ERROR (Message: permission denied for function babel_4344_f1)~~ + +use master; +go + +-- psql +-- grant object permission +grant select on babel_4344_s1.babel_4344_t1 to babel_4344_d1_babel_4344_u1; +go + +-- tsql +-- grant schema permission +use babel_4344_d1; +go +grant select on schema::babel_4344_s1 to babel_4344_u1; +go +use master +go + +-- tsql user=babel_4344_l1 password=12345678 +use babel_4344_d1; +go +select * from babel_4344_s1.babel_4344_t1; -- accessible +go +~~START~~ +int +2 +3 +3 +4 +5 +~~END~~ + +use master +go + +-- psql +-- revoke schema permission +revoke select on all tables in schema babel_4344_s1 from babel_4344_d1_babel_4344_u1; +go + +-- tsql user=babel_4344_l1 password=12345678 +use babel_4344_d1; +go +select * from babel_4344_s1.babel_4344_t1; -- not accessible +go +~~ERROR (Code: 33557097)~~ + +~~ERROR (Message: permission denied for table babel_4344_t1)~~ + +use master +go + +-- tsql +-- Drop objects +use babel_4344_d1; +go + +drop schema "update pg_class set oid = 0 where relname = 'babel_4344_t1'"; +go + +drop table babel_4344_t1; +go + +drop table babel_4344_s1.babel_4344_t1; +go + +drop table babel_4344_t3; +go + +drop table babel_4344_s1.babel_4344_t3; +go + +drop table babel_4344_s1.babel_4344_t2; +go + +drop view babel_4344_v1; +go + +drop view babel_4344_s1.babel_4344_v1; +go + +drop view babel_4344_s1.babel_4344_v2; +go + +drop proc babel_4344_p1; +go + +drop proc babel_4344_s1.babel_4344_p1; +go + +drop proc babel_4344_s1.babel_4344_p2; +go + +drop proc babel_4344_s1.babel_4344_p3; +go + +drop function babel_4344_f1; +go + +drop function babel_4344_s1.babel_4344_f1; +go + +drop function babel_4344_s1.babel_4344_f2; +go + +drop schema babel_4344_s1; +go + +drop table babel_4344_s2.babel_4344_t1; +go + +drop schema babel_4344_s2; +go + +drop table αγάπη.abc; +go + +drop schema αγάπη; +go + +drop table スキーマ.abc; +go + +drop schema スキーマ; +go + +drop table "babel_4344 s1"."babel_4344 t1"; +go + +drop schema "BAbel_4344 s1"; +go + +drop user babel_4344_u1; +go + +drop user αιώνια; +go + +drop user ログイン; +go + +use master; +go + +drop database babel_4344_d1; +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) = 'babel_4344_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 babel_4344_l1; +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) = 'αιώνια' 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 αιώνια; +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) = 'ログイン' 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 ログイン; +go diff --git a/test/JDBC/expected/TestErrorHelperFunctions.out b/test/JDBC/expected/TestErrorHelperFunctions.out index ee83dcc37a0..a4ff58c1852 100644 --- a/test/JDBC/expected/TestErrorHelperFunctions.out +++ b/test/JDBC/expected/TestErrorHelperFunctions.out @@ -208,7 +208,7 @@ XX000#!#The table-valued parameter "%s" must be declared with the READONLY optio 22023#!#The datepart %s is not supported by date function %s for data type %s.#!##!#9810 22008#!#Adding a value to a '%s' column caused an overflow.#!##!#517 42P01#!#FOR JSON AUTO requires at least one table for generating JSON objects. Use FOR JSON PATH or add a FROM clause with a table name.#!##!#13600 -42P01#!#Values for json auto is not currently supported.#!##!#13600 +42P01#!#sub-select and values for json auto are not currently supported.#!##!#13600 ~~END~~ diff --git a/test/JDBC/expected/TestSpatialPoint-vu-cleanup.out b/test/JDBC/expected/TestSpatialPoint-vu-cleanup.out index cfd1c8615f3..1b87814a1ea 100644 --- a/test/JDBC/expected/TestSpatialPoint-vu-cleanup.out +++ b/test/JDBC/expected/TestSpatialPoint-vu-cleanup.out @@ -18,8 +18,34 @@ DROP VIEW IF EXISTS TransformFromGeog DROP VIEW IF EXISTS equal_geog +DROP VIEW IF EXISTS GeomView + +DROP PROCEDURE IF EXISTS dbo.p_getcoordinates + +DROP FUNCTION IF EXISTS f_getval + +DROP VIEW IF EXISTS ValFromGeom + +DROP VIEW IF EXISTS GeogView + +DROP VIEW IF EXISTS SubqueryView + +DROP VIEW IF EXISTS FuncExprView + +DROP VIEW IF EXISTS BrackExprView + +DROP TABLE IF EXISTS test_table + +DROP PROCEDURE IF EXISTS dbo.proc_getdata + +DROP FUNCTION IF EXISTS func_getval + DROP VIEW IF EXISTS point_distances_geog +DROP function IF EXISTS testspatial_tvf; + +DROP TABLE IF EXISTS SpatialData; + DROP TABLE IF EXISTS SPATIALPOINTGEOM_dt DROP TABLE IF EXISTS GeomToVarbinary @@ -45,3 +71,53 @@ DROP TABLE IF EXISTS GeogToVarchar DROP TABLE IF EXISTS TypeToGeog DROP TABLE IF EXISTS SPATIALPOINT_dt + +drop procedure IF EXISTS geometry_proc_1; + +drop procedure IF EXISTS geography_proc_1; + +drop table IF EXISTS geo_view_test; + +DROP PROCEDURE IF EXISTS GetPointsByXCoordinate + +DROP PROCEDURE IF EXISTS GetPointsByXCoordinate1 + +DROP PROCEDURE IF EXISTS GetDistanceByXCoordinate + +DROP FUNCTION IF EXISTS dbo.GetXCoordinate + +DROP FUNCTION IF EXISTS GetGeometry + +DROP TRIGGER IF EXISTS trg_LogXCoordinateChange + +DROP TABLE IF EXISTS XCoordinateChangeLog + +DROP TRIGGER IF EXISTS trg_LogDistanceChange + +DROP TABLE IF EXISTS DistanceChangeLog + +DROP TABLE IF EXISTS YourTable + +DROP TABLE IF EXISTS GeomTab + +DROP TABLE IF EXISTS YourTable1 + +DROP TABLE IF EXISTS TableA + +DROP TABLE IF EXISTS TableB + +DROP PROCEDURE IF EXISTS GetPointsWithinDistance + +DROP FUNCTION IF EXISTS dbo.CalculateDistance + +DROP TABLE IF EXISTS YourTable2 + +Drop Table IF EXISTS babelfish_migration_mode_table + +DROP TABLE IF EXISTS geometry_test + +DROP FUNCTION IF EXISTS geom_schema.STDistance + +DROP SCHEMA IF EXISTS geom_schema + +DROP TABLE IF EXISTS STX diff --git a/test/JDBC/expected/TestSpatialPoint-vu-prepare.out b/test/JDBC/expected/TestSpatialPoint-vu-prepare.out index e644e6d4de3..2b511d69481 100644 --- a/test/JDBC/expected/TestSpatialPoint-vu-prepare.out +++ b/test/JDBC/expected/TestSpatialPoint-vu-prepare.out @@ -76,6 +76,59 @@ INSERT INTO SPATIALPOINTGEOM_dt (location) VALUES ( geometry::Point(47.65100, -2 ~~ROW COUNT: 1~~ +CREATE TABLE YourTable ( ID INT PRIMARY KEY, PointColumn geometry ); + +INSERT INTO YourTable (ID, PointColumn) VALUES (1, geometry::Point(3.0, 4.0, 4326)), (2, geometry::Point(5.0, 6.0, 4326)); +~~ROW COUNT: 2~~ + + +CREATE TABLE GeomTab ( ID INT PRIMARY KEY, PointColumn geometry ); + +INSERT INTO GeomTab (ID, PointColumn) VALUES (1, geometry::Point(3.0, 4.0, 4326)), (2, geometry::Point(3.0, 6.0, 4326)); +~~ROW COUNT: 2~~ + + +CREATE FUNCTION dbo.GetXCoordinate(@point geometry) RETURNS float AS BEGIN RETURN @point.STX; END; + +CREATE PROCEDURE GetDistanceByXCoordinate @xCoordinate FLOAT AS BEGIN DECLARE @point geometry = geometry::Point(@xCoordinate, 0.0, 4326); SELECT @point.STY, YourTable.PointColumn.STDistance(@point) AS Distance FROM YourTable ORDER BY PointColumn.STX; END; + +CREATE TABLE TableA (ID INT PRIMARY KEY, PointA geometry); +CREATE TABLE TableB (ID INT PRIMARY KEY, PointB geometry); +INSERT INTO TableA (ID, PointA) VALUES (1, geometry::Point(1.0, 2.0, 4326)); +~~ROW COUNT: 1~~ + +INSERT INTO TableB (ID, PointB) VALUES (1, geometry::Point(3.0, 4.0, 4326)); +~~ROW COUNT: 1~~ + + +CREATE PROCEDURE GetPointsByXCoordinate @XCoordinate FLOAT AS BEGIN SELECT * FROM YourTable WHERE PointColumn.STX = @XCoordinate ORDER BY PointColumn.STX; END; + +CREATE PROCEDURE GetPointsByXCoordinate1 @XCoordinate FLOAT AS BEGIN DECLARE @Sql NVARCHAR(MAX); SET @Sql = N'SELECT ID, PointColumn.STX AS XCoordinate FROM YourTable WHERE PointColumn.STX = @ParamXCoordinate ORDER BY PointColumn.STX'; EXEC sp_executesql @Sql,N'@ParamXCoordinate FLOAT',@XCoordinate; END; + +CREATE TABLE YourTable1 ( ID INT PRIMARY KEY, STX geometry ); +INSERT INTO YourTable1 (ID, STX) VALUES (1, geometry::Point(3.0, 4.0, 4326)), (2, geometry::Point(5.0, 6.0, 4326)); +~~ROW COUNT: 2~~ + + +CREATE FUNCTION GetGeometry() RETURNS geometry AS BEGIN RETURN geometry::Point(1.0, 2.0, 4326); END; + +CREATE TABLE XCoordinateChangeLog (PointID INT,OldXCoordinate FLOAT,NewXCoordinate FLOAT,ChangeDate DATETIME); + +CREATE TRIGGER trg_LogXCoordinateChange ON YourTable AFTER UPDATE AS BEGIN INSERT INTO XCoordinateChangeLog (PointID, OldXCoordinate, NewXCoordinate, ChangeDate) SELECT i.ID, d.PointColumn.STX, i.PointColumn.STX, GETDATE() FROM inserted i JOIN deleted d ON i.ID = d.ID WHERE i.PointColumn.STX <> d.PointColumn.STX; END; + +CREATE TABLE YourTable2 ( ID INT PRIMARY KEY, PointColumn1 geometry, PointColumn2 geometry ); +INSERT INTO YourTable2 (ID, PointColumn1, PointColumn2) VALUES (1, geometry::Point(3.0, 4.0, 4326), geometry::Point(4.0, 5.0, 4326)); +~~ROW COUNT: 1~~ + + +CREATE FUNCTION dbo.CalculateDistance(@point1 geometry,@point2 geometry) RETURNS float AS BEGIN RETURN @point1.STDistance(@point2); END; + +CREATE PROCEDURE GetPointsWithinDistance @referencePoint geometry, @maxDistance float AS BEGIN SELECT * FROM YourTable WHERE PointColumn.STDistance(@referencePoint) <= @maxDistance ORDER BY PointColumn.STX; END; + +CREATE TABLE DistanceChangeLog (PointID INT,OldDistance FLOAT,NewDistance FLOAT,ChangeDate DATETIME); + +CREATE TRIGGER trg_LogDistanceChange ON YourTable AFTER UPDATE AS BEGIN DECLARE @referencePoint geometry = geometry::Point(0.0, 0.0, 4326); INSERT INTO DistanceChangeLog (PointID, OldDistance, NewDistance, ChangeDate) SELECT i.ID, d.PointColumn.STDistance(@referencePoint), i.PointColumn.STDistance(@referencePoint), GETDATE() FROM inserted i JOIN deleted d ON i.ID = d.ID WHERE i.PointColumn.STDistance(@referencePoint) <> d.PointColumn.STDistance(@referencePoint); END; + #Tests for Geometry type Prepared Statements prepst#!#INSERT INTO SPATIALPOINTGEOM_dt(location) values(?) #!#GEOMETRY|-|location|-|Point(47.65100 -22.34900):4326 ~~ROW COUNT: 1~~ @@ -122,15 +175,23 @@ prepst#!#exec#!#GEOMETRY|-|location|-|LINESTRING(1 2, 3 4):4326 ~~ERROR (Message: Unsupported geometry type)~~ -CREATE VIEW TextFromGeom AS SELECT STAsText(location) AS TextRepresentation FROM SPATIALPOINTGEOM_dt; +CREATE VIEW TextFromGeom AS SELECT STAsText(location) AS TextRepresentation FROM SPATIALPOINTGEOM_dt ORDER BY location.STX; + +CREATE VIEW BinaryFromGeom AS SELECT STAsBinary(location) AS BinaryRepresentation FROM SPATIALPOINTGEOM_dt ORDER BY location.STX; + +CREATE VIEW CoordsFromGeom AS SELECT STX(location), STY(location) AS Coordinates FROM SPATIALPOINTGEOM_dt ORDER BY location.STX; + +CREATE VIEW GeomView AS SELECT location.STX, location.STY AS Coordinates FROM SPATIALPOINTGEOM_dt ORDER BY location.STX; + +CREATE VIEW ValFromGeom AS SELECT location.STAsText(), location.STAsBinary() FROM SPATIALPOINTGEOM_dt ORDER BY location.STX; -CREATE VIEW BinaryFromGeom AS SELECT STAsBinary(location) AS BinaryRepresentation FROM SPATIALPOINTGEOM_dt; +CREATE FUNCTION f_getval() RETURNS TABLE AS RETURN ( SELECT location.STX AS XCoordinate, location.STY AS YCoordinate FROM SPATIALPOINTGEOM_dt ORDER BY location.STX ); -CREATE VIEW CoordsFromGeom AS SELECT STX(location), STY(location) AS Coordinates FROM SPATIALPOINTGEOM_dt; +CREATE PROCEDURE dbo.p_getcoordinates AS BEGIN DECLARE @Coordinates TABLE ( XCoordinate float, YCoordinate float ); INSERT INTO @Coordinates SELECT * FROM dbo.f_getval(); SELECT * FROM @Coordinates; END; -CREATE VIEW equal_geom AS SELECT p1.location AS point FROM SPATIALPOINTGEOM_dt p1 CROSS JOIN SPATIALPOINTGEOM_dt p2 WHERE p1.location = p2.location; +CREATE VIEW equal_geom AS SELECT p1.location AS point FROM SPATIALPOINTGEOM_dt p1 CROSS JOIN SPATIALPOINTGEOM_dt p2 WHERE p1.location = p2.location ORDER BY p1.location.STX; -CREATE VIEW point_distances_geom AS SELECT p1.location AS point1, p2.location AS point2, STDistance( p1.location, p2.location ) AS distance FROM SPATIALPOINTGEOM_dt p1 CROSS JOIN SPATIALPOINTGEOM_dt p2 WHERE p1.location <> p2.location; +CREATE VIEW point_distances_geom AS SELECT p1.location AS point1, p2.location AS point2, STDistance( p1.location, p2.location ) AS distance FROM SPATIALPOINTGEOM_dt p1 CROSS JOIN SPATIALPOINTGEOM_dt p2 WHERE p1.location <> p2.location ORDER BY p1.location.STX; CREATE TABLE SPATIALPOINTGEOG_dt (location geography) @@ -334,18 +395,43 @@ prepst#!#exec#!#GEOGRAPHY|-|location|-|LINESTRING(1 2, 3 4):4326 ~~ERROR (Message: Unsupported geometry type)~~ -CREATE VIEW TextFromGeog AS SELECT STAsText(location) AS TextRepresentation FROM SPATIALPOINTGEOG_dt; +CREATE VIEW TextFromGeog AS SELECT STAsText(location) AS TextRepresentation FROM SPATIALPOINTGEOG_dt ORDER BY location.Lat; + +CREATE VIEW BinaryFromGeog AS SELECT STAsBinary(location) AS BinaryRepresentation FROM SPATIALPOINTGEOG_dt ORDER BY location.Lat; + +CREATE VIEW CoordsFromGeog AS SELECT Long(location), Lat(location) AS Coordinates FROM SPATIALPOINTGEOG_dt ORDER BY location.Lat; + +CREATE VIEW GeogView AS SELECT location.Long, location.Lat AS Coordinates FROM SPATIALPOINTGEOG_dt ORDER BY location.Lat; + +CREATE TABLE test_table (geog geography) +INSERT INTO test_table(geog) VALUES(geography::Point(1, 2, 4326)); +~~ROW COUNT: 1~~ + + +CREATE VIEW SubqueryView AS SELECT (select geog from test_table ORDER BY geog.Lat).Lat AS Latitude; + +CREATE VIEW BrackExprView AS SELECT ( geog ).Lat AS Latitude from test_table; + +CREATE VIEW FuncExprView AS SELECT geography::Point(1, 2, 4326).Lat AS Latitude from test_table; + +CREATE FUNCTION func_getval() RETURNS TABLE AS RETURN ( SELECT location.STAsText() AS TextPoint FROM SPATIALPOINTGEOG_dt ORDER BY location.Lat ); + +CREATE PROCEDURE dbo.proc_getdata AS BEGIN DECLARE @Data TABLE ( TextPoint text ); INSERT INTO @Data SELECT * FROM dbo.func_getval(); SELECT * FROM @Data; END; + +CREATE VIEW TransformFromGeog AS SELECT ST_Transform(location, 4326) AS Modified_points FROM SPATIALPOINTGEOG_dt ORDER BY location.Lat; -CREATE VIEW BinaryFromGeog AS SELECT STAsBinary(location) AS BinaryRepresentation FROM SPATIALPOINTGEOG_dt; +CREATE VIEW equal_geog AS SELECT p1.location AS point FROM SPATIALPOINTGEOG_dt p1 CROSS JOIN SPATIALPOINTGEOG_dt p2 WHERE p1.location = p2.location ORDER BY p1.location.Lat; -CREATE VIEW CoordsFromGeog AS SELECT long(location), lat(location) AS Coordinates FROM SPATIALPOINTGEOG_dt; +CREATE VIEW point_distances_geog AS SELECT p1.location AS point1, p2.location AS point2, STDistance( p1.location, p2.location ) AS distance FROM SPATIALPOINTGEOG_dt p1 CROSS JOIN SPATIALPOINTGEOG_dt p2 WHERE p1.location <> p2.location ORDER BY p1.location.Lat; +CREATE TABLE SpatialData(ID INT PRIMARY KEY, SpatialLocation GEOGRAPHY); +INSERT INTO SpatialData (ID, SpatialLocation) VALUES (1, geography::Point(1, 2, 4326)), (2, geography::Point(3, 4, 4326)), (3, geography::Point(5, 6, 4326)), (4, geography::Point(7, 8, 4326)), (5, geography::Point(9, 10, 4326)); +~~ROW COUNT: 5~~ -CREATE VIEW TransformFromGeog AS SELECT ST_Transform(location, 4326) AS Modified_points FROM SPATIALPOINTGEOG_dt; -CREATE VIEW equal_geog AS SELECT p1.location AS point FROM SPATIALPOINTGEOG_dt p1 CROSS JOIN SPATIALPOINTGEOG_dt p2 WHERE p1.location = p2.location; +create function testspatial_tvf(@x int) returns table as return select location from SPATIALPOINTGEOG_dt; -CREATE VIEW point_distances_geog AS SELECT p1.location AS point1, p2.location AS point2, STDistance( p1.location, p2.location ) AS distance FROM SPATIALPOINTGEOG_dt p1 CROSS JOIN SPATIALPOINTGEOG_dt p2 WHERE p1.location <> p2.location; +CREATE TABLE babelfish_migration_mode_table (id_num INT IDENTITY(1,1), mig_mode VARCHAR(10)) #Testing Implicit CASTs to and from Geography data type for supported Explicit CASTs #UnSupported CASTs to and from Geography data type @@ -404,3 +490,18 @@ prepst#!#INSERT INTO SPATIALPOINT_dt(PrimaryKey, GeogColumn) values(?, ?) #!#int prepst#!#INSERT INTO SPATIALPOINT_dt(PrimaryKey, GeomColumn, GeogColumn) values(?, ?, ?) #!#int|-|PrimaryKey|-|6#!#GEOMETRY|-|GeomColumn|-|Point(1.0 2.0):4326#!#GEOGRAPHY|-|GeogColumn|-|Point(1.0 2.0):4326 ~~ROW COUNT: 1~~ + +create procedure geometry_proc_1 @a geometry, @b varchar(max) as select @a as a, @b as b; +create procedure geography_proc_1 @a geography, @b varchar(max) as select @a as a, @b as b; +create table geo_view_test(a geometry, b geography) + +create schema geom_schema; +CREATE FUNCTION geom_schema.STDistance(@point geometry) RETURNS nvarchar(max) AS BEGIN RETURN @point.STAsText(); END; +create table geometry_test(geom_schema geometry) +Insert INTO geometry_test VALUES(geometry::STGeomFromText('Point(47.65100 -22.34900)', 0)) +~~ROW COUNT: 1~~ + +create table STX(STX geometry) +Insert INTO STX VALUES(geometry::STGeomFromText('Point(47.65100 -22.34900)', 0)) +~~ROW COUNT: 1~~ + diff --git a/test/JDBC/expected/TestSpatialPoint-vu-verify.out b/test/JDBC/expected/TestSpatialPoint-vu-verify.out index 9521a1164e0..ed2e05a25ee 100644 --- a/test/JDBC/expected/TestSpatialPoint-vu-verify.out +++ b/test/JDBC/expected/TestSpatialPoint-vu-verify.out @@ -1,27 +1,67 @@ DECLARE @point geometry; SET @point = geometry::STPointFromText('POINT(-122.34900 47.65100)', 4326); SELECT STAsText(@point); +SELECT @point.STAsText(); Go ~~START~~ text POINT(-122.349 47.651) ~~END~~ +~~START~~ +text +POINT(-122.349 47.651) +~~END~~ + DECLARE @point geometry; SET @point = geometry::POINT(22.34900, -47.65100, 4326); SELECT STAsText(@point); +SELECT @point.STAsText(); +SELECT @point . STAsText ( ); Go ~~START~~ text POINT(22.349 -47.651) ~~END~~ +~~START~~ +text +POINT(22.349 -47.651) +~~END~~ + +~~START~~ +text +POINT(22.349 -47.651) +~~END~~ + + +DECLARE @point geometry; +SET @point = geometry::Point(1.0, 2.0, 4326); +SELECT @point.STX AS XCoordinate; +GO +~~START~~ +float +1.0 +~~END~~ + + +DECLARE @point1 geometry = geometry::Point(1.0, 2.0, 4326); +DECLARE @point2 geometry = geometry::Point(3.0, 4.0, 4326); +SELECT @point1.STDistance(@point2) AS Distance; +GO +~~START~~ +float +2.8284271247461903 +~~END~~ + DECLARE @point geometry; SET @point = geometry::STGeomFromText('POINT(-122.34900 47.65100)', 4326); -SELECT stx(@point); -SELECT sty(@point); +SELECT STX(@point); +SELECT STY(@point); +SELECT @point.STX; +SELECT @point.STY; Go ~~START~~ float @@ -33,11 +73,24 @@ float 47.651 ~~END~~ +~~START~~ +float +-122.349 +~~END~~ + +~~START~~ +float +47.651 +~~END~~ + DECLARE @point geometry; SET @point = geometry::POINT(22.34900, -47.65100, 4326); -SELECT stx(@point); -SELECT sty(@point); +SELECT STX(@point); +SELECT STY(@point); +SELECT @point.STX; +SELECT @point . STX; +SELECT @point.STY; Go ~~START~~ float @@ -49,31 +102,209 @@ float -47.651 ~~END~~ +~~START~~ +float +22.349 +~~END~~ + +~~START~~ +float +22.349 +~~END~~ + +~~START~~ +float +-47.651 +~~END~~ + DECLARE @point1 geometry, @point2 geometry; SET @point1 = geometry::STPointFromText('POINT(-122.34900 47.65100)', 4326); SET @point2 = geometry::STGeomFromText('POINT(-122.35000 47.65000)', 4326); SELECT STDistance(@point1, @point2); +SELECT @point1.STDistance(@point2); +SELECT @point1 . STDistance ( @point2 ); Go ~~START~~ float 0.0014142135623697993 ~~END~~ +~~START~~ +float +0.0014142135623697993 +~~END~~ + +~~START~~ +float +0.0014142135623697993 +~~END~~ + + +DECLARE @point geometry; +SET @point = geometry::STGeomFromText('POINT(-122.34900 47.65100)', 4326); +Insert INTO SPATIALPOINTGEOM_dt(location) VALUES(geometry::point(@point.STX, @point.STY,4326)) +go +~~ROW COUNT: 1~~ + + +DECLARE @STX geometry; +SET @STX = geometry::STGeomFromText('POINT(-122.34900 47.65100)', 4326); +select geometry::Point(@STX.STX, @STX.STY, 4326).STX, geometry::Point(@STX.STX, @STX.STY, 4326).STY; +go +~~START~~ +float#!#float +-122.349#!#47.651 +~~END~~ + + +DECLARE @STX geometry; +SET @STX = geometry::STGeomFromText('POINT(-122.34900 47.65100)', 4326); +select geometry::Point(@STX.STX, @STX.STY, 4326).STAsText(), geometry::Point(@STX.STX, @STX.STY, 4326).STAsBinary(), geometry::Point(@STX.STX, @STX.STY, 4326).STDistance(geometry::Point(@STX.STX, @STX.STY, 4326)); +go +~~START~~ +text#!#varbinary#!#float +POINT(-122.349 47.651)#!#01010000007593180456965EC017D9CEF753D34740#!#0.0 +~~END~~ + + +-- Null test for Geospatial functions +DECLARE @point1 geometry, @point2 geometry, @point3 geometry; +SET @point1 = geometry::STPointFromText(null, 4326); +SET @point2 = geometry::STGeomFromText(null, 4326); +SET @point3 = geometry::POINT(22.34900, -47.65100, 4326); +SELECT @point1.STX; +SELECT @point1.STY; +SELECT @point1.STAsText(); +SELECT @point1.STAsBinary(); +SELECT @point1.STDistance(@point2); +SELECT @point3.STDistance(@point2); +SELECT @point1.STDistance(@point3); +Go +~~START~~ +float + +~~END~~ + +~~START~~ +float + +~~END~~ + +~~START~~ +text + +~~END~~ + +~~START~~ +varbinary + +~~END~~ + +~~START~~ +float + +~~END~~ + +~~START~~ +float + +~~END~~ + +~~START~~ +float + +~~END~~ + + +-- Negative test for Geospatial functions +DECLARE @point1 geometry, @point2 varchar(50), @point3 int; +SET @point1 = geometry::POINT(22.34900, -47.65100, 4326);; +SET @point2 = 'Test_String'; +SELECT @point1.STDistance(@point2); +Go +~~ERROR (Code: 33557097)~~ + +~~ERROR (Message: parse error - invalid geometry)~~ + + +SELECT location.Lat from SPATIALPOINTGEOM_dt ORDER BY location.STX; +GO +~~ERROR (Code: 33557097)~~ + +~~ERROR (Message: column notation .lat applied to type geometry, which is not a composite type)~~ + + +SELECT * FROM GeomView; +GO +~~START~~ +float#!#float +#!# +-122.349#!#47.651 +1.0#!#2.0 +1.0#!#2.0 +1.0#!#2.0 +47.651#!#-22.349 +47.651#!#-22.349 +47.651#!#-22.349 +47.651#!#-22.349 +47.651#!#-22.349 +47.651#!#-22.349 +~~END~~ + + +SELECT * FROM ValFromGeom; +GO +~~START~~ +text#!#varbinary +#!# +POINT(-122.349 47.651)#!#01010000007593180456965EC017D9CEF753D34740 +POINT(1 2)#!#0101000000000000000000F03F0000000000000040 +POINT(1 2)#!#0101000000000000000000F03F0000000000000040 +POINT(1 2)#!#0101000000000000000000F03F0000000000000040 +POINT(47.651 -22.349)#!#010100000017D9CEF753D34740D34D6210585936C0 +POINT(47.651 -22.349)#!#010100000017D9CEF753D34740D34D6210585936C0 +POINT(47.651 -22.349)#!#010100000017D9CEF753D34740D34D6210585936C0 +POINT(47.651 -22.349)#!#010100000017D9CEF753D34740D34D6210585936C0 +POINT(47.651 -22.349)#!#010100000017D9CEF753D34740D34D6210585936C0 +POINT(47.651 -22.349)#!#010100000017D9CEF753D34740D34D6210585936C0 +~~END~~ + + +EXEC dbo.p_getcoordinates; +GO +~~ROW COUNT: 11~~ + +~~START~~ +float#!#float +#!# +-122.349#!#47.651 +1.0#!#2.0 +1.0#!#2.0 +1.0#!#2.0 +47.651#!#-22.349 +47.651#!#-22.349 +47.651#!#-22.349 +47.651#!#-22.349 +47.651#!#-22.349 +47.651#!#-22.349 +~~END~~ + SELECT * FROM TextFromGeom; GO ~~START~~ text -POINT(47.651 -22.349) + +POINT(-122.349 47.651) +POINT(1 2) +POINT(1 2) POINT(1 2) POINT(47.651 -22.349) - POINT(47.651 -22.349) -POINT(1 2) POINT(47.651 -22.349) POINT(47.651 -22.349) -POINT(1 2) +POINT(47.651 -22.349) POINT(47.651 -22.349) ~~END~~ @@ -82,15 +313,16 @@ SELECT * FROM BinaryFromGeom; GO ~~START~~ varbinary -010100000017D9CEF753D34740D34D6210585936C0 + +01010000007593180456965EC017D9CEF753D34740 +0101000000000000000000F03F0000000000000040 +0101000000000000000000F03F0000000000000040 0101000000000000000000F03F0000000000000040 010100000017D9CEF753D34740D34D6210585936C0 - 010100000017D9CEF753D34740D34D6210585936C0 -0101000000000000000000F03F0000000000000040 010100000017D9CEF753D34740D34D6210585936C0 010100000017D9CEF753D34740D34D6210585936C0 -0101000000000000000000F03F0000000000000040 +010100000017D9CEF753D34740D34D6210585936C0 010100000017D9CEF753D34740D34D6210585936C0 ~~END~~ @@ -99,15 +331,16 @@ SELECT * FROM CoordsFromGeom; GO ~~START~~ float#!#float -47.651#!#-22.349 +#!# +-122.349#!#47.651 +1.0#!#2.0 +1.0#!#2.0 1.0#!#2.0 47.651#!#-22.349 -#!# 47.651#!#-22.349 -1.0#!#2.0 47.651#!#-22.349 47.651#!#-22.349 -1.0#!#2.0 +47.651#!#-22.349 47.651#!#-22.349 ~~END~~ @@ -116,22 +349,24 @@ SELECT * FROM equal_geom; GO ~~START~~ geometry -E6100000010C17D9CEF753D34740D34D6210585936C0 -E6100000010C17D9CEF753D34740D34D6210585936C0 -E6100000010C17D9CEF753D34740D34D6210585936C0 -E6100000010C17D9CEF753D34740D34D6210585936C0 +E6100000010C7593180456965EC017D9CEF753D34740 E6100000010C000000000000F03F0000000000000040 E6100000010C000000000000F03F0000000000000040 E6100000010C000000000000F03F0000000000000040 -00000000010C17D9CEF753D34740D34D6210585936C0 +E6100000010C000000000000F03F0000000000000040 +E6100000010C000000000000F03F0000000000000040 +E6100000010C000000000000F03F0000000000000040 +E6100000010C000000000000F03F0000000000000040 +E6100000010C000000000000F03F0000000000000040 +E6100000010C000000000000F03F0000000000000040 +E6100000010C17D9CEF753D34740D34D6210585936C0 +E6100000010C17D9CEF753D34740D34D6210585936C0 +E6100000010C17D9CEF753D34740D34D6210585936C0 00000000010C17D9CEF753D34740D34D6210585936C0 E6100000010C17D9CEF753D34740D34D6210585936C0 E6100000010C17D9CEF753D34740D34D6210585936C0 E6100000010C17D9CEF753D34740D34D6210585936C0 E6100000010C17D9CEF753D34740D34D6210585936C0 -E6100000010C000000000000F03F0000000000000040 -E6100000010C000000000000F03F0000000000000040 -E6100000010C000000000000F03F0000000000000040 E6100000010C17D9CEF753D34740D34D6210585936C0 E6100000010C17D9CEF753D34740D34D6210585936C0 E6100000010C17D9CEF753D34740D34D6210585936C0 @@ -140,39 +375,943 @@ E6100000010C17D9CEF753D34740D34D6210585936C0 E6100000010C17D9CEF753D34740D34D6210585936C0 E6100000010C17D9CEF753D34740D34D6210585936C0 E6100000010C17D9CEF753D34740D34D6210585936C0 -E6100000010C000000000000F03F0000000000000040 -E6100000010C000000000000F03F0000000000000040 -E6100000010C000000000000F03F0000000000000040 00000000010C17D9CEF753D34740D34D6210585936C0 00000000010C17D9CEF753D34740D34D6210585936C0 +00000000010C17D9CEF753D34740D34D6210585936C0 +E6100000010C17D9CEF753D34740D34D6210585936C0 +~~END~~ + + +SELECT * FROM point_distances_geom; +GO +~~START~~ +geometry#!#geometry#!#float +~~ERROR (Code: 33557097)~~ + +~~ERROR (Message: ST_Distance: Operation on mixed SRID geometries (Point, 4326) != (Point, 0))~~ + + +SELECT location.STX from SPATIALPOINTGEOM_dt ORDER BY location.STX; +GO +~~START~~ +float + +-122.349 +1.0 +1.0 +1.0 +47.651 +47.651 +47.651 +47.651 +47.651 +47.651 +~~END~~ + + +SELECT SPATIALPOINTGEOM_dt.location.STY from SPATIALPOINTGEOM_dt ORDER BY location.STX; +GO +~~START~~ +float + +47.651 +2.0 +2.0 +2.0 +-22.349 +-22.349 +-22.349 +-22.349 +-22.349 +-22.349 +~~END~~ + + +SELECT location.STAsText() from SPATIALPOINTGEOM_dt ORDER BY location.STX; +GO +~~START~~ +text + +POINT(-122.349 47.651) +POINT(1 2) +POINT(1 2) +POINT(1 2) +POINT(47.651 -22.349) +POINT(47.651 -22.349) +POINT(47.651 -22.349) +POINT(47.651 -22.349) +POINT(47.651 -22.349) +POINT(47.651 -22.349) +~~END~~ + + +SELECT location.STAsBinary() from SPATIALPOINTGEOM_dt ORDER BY location.STX; +GO +~~START~~ +varbinary + +01010000007593180456965EC017D9CEF753D34740 +0101000000000000000000F03F0000000000000040 +0101000000000000000000F03F0000000000000040 +0101000000000000000000F03F0000000000000040 +010100000017D9CEF753D34740D34D6210585936C0 +010100000017D9CEF753D34740D34D6210585936C0 +010100000017D9CEF753D34740D34D6210585936C0 +010100000017D9CEF753D34740D34D6210585936C0 +010100000017D9CEF753D34740D34D6210585936C0 +010100000017D9CEF753D34740D34D6210585936C0 +~~END~~ + + +SELECT location.STDistance(geometry::STGeomFromText('POINT(-122.34900 47.65100)', 4326)) from SPATIALPOINTGEOM_dt ORDER BY location.STX; +GO +~~START~~ +float +~~ERROR (Code: 33557097)~~ + +~~ERROR (Message: ST_Distance: Operation on mixed SRID geometries (Point, 4326) != (Point, 0))~~ + + +SELECT [SPATIALPOINTGEOM_dt].[location].[STX] from [SPATIALPOINTGEOM_dt] ORDER BY location.STX; +GO +~~START~~ +float + +-122.349 +1.0 +1.0 +1.0 +47.651 +47.651 +47.651 +47.651 +47.651 +47.651 +~~END~~ + + +SELECT [location].[STY] from [SPATIALPOINTGEOM_dt] ORDER BY location.STX; +GO +~~START~~ +float + +47.651 +2.0 +2.0 +2.0 +-22.349 +-22.349 +-22.349 +-22.349 +-22.349 +-22.349 +~~END~~ + + +SELECT location FROM SPATIALPOINTGEOM_dt ORDER BY location.STX; +GO +~~START~~ +geometry + +E6100000010C7593180456965EC017D9CEF753D34740 +E6100000010C000000000000F03F0000000000000040 +E6100000010C000000000000F03F0000000000000040 +E6100000010C000000000000F03F0000000000000040 +E6100000010C17D9CEF753D34740D34D6210585936C0 +E6100000010C17D9CEF753D34740D34D6210585936C0 +E6100000010C17D9CEF753D34740D34D6210585936C0 +00000000010C17D9CEF753D34740D34D6210585936C0 +00000000010C17D9CEF753D34740D34D6210585936C0 +E6100000010C17D9CEF753D34740D34D6210585936C0 +~~END~~ + + +SELECT PointColumn.STX AS XCoordinate FROM YourTable ORDER BY PointColumn.STX; +GO +~~START~~ +float +3.0 +5.0 +~~END~~ + + +SELECT * FROM YourTable WHERE PointColumn.STX > 3.0 ORDER BY PointColumn.STX; +GO +~~START~~ +int#!#geometry +2#!#E6100000010C00000000000014400000000000001840 +~~END~~ + + +DECLARE @point geometry = geometry::Point(1.0, 2.0, 4326); +SELECT * FROM YourTable WHERE PointColumn.STX > @point.STX ORDER BY PointColumn.STX; +GO +~~START~~ +int#!#geometry +1#!#E6100000010C00000000000008400000000000001040 +2#!#E6100000010C00000000000014400000000000001840 +~~END~~ + + +SELECT ID, PointColumn.STX AS XCoordinate FROM YourTable ORDER BY PointColumn.STX; +GO +~~START~~ +int#!#float +1#!#3.0 +2#!#5.0 +~~END~~ + + +SELECT ID, dbo.GetXCoordinate(PointColumn) AS XCoordinate FROM YourTable ORDER BY PointColumn.STX; +GO +~~START~~ +int#!#float +1#!#3.0 +2#!#5.0 +~~END~~ + + +DECLARE @point geometry = geometry::Point(1.0, 2.0, 4326); +SELECT dbo.GetXCoordinate(@point); +GO +~~START~~ +float +1.0 +~~END~~ + + +SELECT * FROM TableA JOIN TableB ON TableA.PointA.STX = TableB.PointB.STX ORDER BY TableA.PointA.STX; +GO +~~START~~ +int#!#geometry#!#int#!#geometry +~~END~~ + + +DECLARE @point geometry = geometry::Point(1.0, 2.0, 4326); +SELECT * FROM TableA JOIN TableB ON TableA.PointA.STX > @point.STX ORDER BY TableA.PointA.STX; +GO +~~START~~ +int#!#geometry#!#int#!#geometry +~~END~~ + + +SELECT * FROM YourTable ORDER BY PointColumn.STX; +GO +~~START~~ +int#!#geometry +1#!#E6100000010C00000000000008400000000000001040 +2#!#E6100000010C00000000000014400000000000001840 +~~END~~ + + +DECLARE @point geometry = geometry::Point(1.0, 2.0, 4326); +SELECT * FROM YourTable ORDER BY @point.STX; +GO +~~START~~ +int#!#geometry +1#!#E6100000010C00000000000008400000000000001040 +2#!#E6100000010C00000000000014400000000000001840 +~~END~~ + + +SELECT ID, PointColumn.STX AS XCoordinate, +CASE WHEN PointColumn.STX > 3.0 THEN 'High X' +ELSE 'Low X' +END AS XCoordinateCategory FROM YourTable ORDER BY PointColumn.STX; +GO +~~START~~ +int#!#float#!#text +1#!#3.0#!#Low X +2#!#5.0#!#High X +~~END~~ + + +DECLARE @point geometry = geometry::Point(1.0, 2.0, 4326); +SELECT ID, PointColumn.STX AS XCoordinate, +CASE WHEN @point.STX > 3.0 THEN 'High X' +ELSE 'Low X' +END AS XCoordinateCategory FROM YourTable ORDER BY PointColumn.STX; +GO +~~START~~ +int#!#float#!#text +1#!#3.0#!#Low X +2#!#5.0#!#Low X +~~END~~ + + +WITH PointData AS ( SELECT ID, PointColumn.STX AS XCoordinate FROM YourTable ) +SELECT * FROM PointData WHERE XCoordinate > 3.0 ORDER BY XCoordinate; +GO +~~START~~ +int#!#float +2#!#5.0 +~~END~~ + + +DECLARE @point geometry = geometry::Point(1.0, 2.0, 4326); +WITH PointData AS ( SELECT ID, @point.STX AS XCoordinate FROM YourTable ) +SELECT * FROM PointData WHERE XCoordinate > 3.0 ORDER BY XCoordinate; +GO +~~START~~ +int#!#float +~~END~~ + + +SELECT PointColumn.STX AS XCoordinate, COUNT(*) AS PointCount +FROM GeomTab GROUP BY PointColumn.STX ORDER BY PointColumn.STX; +GO +~~START~~ +float#!#int +3.0#!#2 +~~END~~ + + +DECLARE @point geometry = geometry::Point(1.0, 2.0, 4326); +SELECT @point.STX AS XCoordinate, COUNT(*) AS PointCount +FROM YourTable GROUP BY PointColumn.STX ORDER BY PointColumn.STX; +GO +~~START~~ +float#!#int +1.0#!#1 +1.0#!#1 +~~END~~ + + +SELECT ID, PointColumn.STX AS XCoordinate, +PointColumn.STX - LAG(PointColumn.STX) OVER (ORDER BY ID) AS XCoordinateDifference +FROM YourTable ORDER BY PointColumn.STX; +GO +~~START~~ +int#!#float#!#float +1#!#3.0#!# +2#!#5.0#!#2.0 +~~END~~ + + +DECLARE @point geometry = geometry::Point(1.0, 2.0, 4326); +SELECT ID, @point.STX AS XCoordinate, +@point.STX - LAG(@point.STX) OVER (ORDER BY ID) AS XCoordinateDifference +FROM YourTable ORDER BY PointColumn.STX; +GO +~~START~~ +int#!#float#!#float +1#!#1.0#!# +2#!#1.0#!#0.0 +~~END~~ + + +DECLARE @XCoordinate FLOAT = 3.0; +DECLARE @DynamicQuery NVARCHAR(MAX); +SET @DynamicQuery = N' SELECT * FROM YourTable WHERE PointColumn.STX > ' + CAST(@XCoordinate AS NVARCHAR(MAX)) + ' ORDER BY PointColumn.STX'; +EXEC sp_executesql @DynamicQuery; +GO +~~START~~ +int#!#geometry +2#!#E6100000010C00000000000014400000000000001840 +~~END~~ + + +DECLARE @point geometry = geometry::Point(1.0, 2.0, 4326); +DECLARE @DynamicQuery NVARCHAR(MAX); +SET @DynamicQuery = N' SELECT * FROM YourTable WHERE PointColumn.STX > ' + CAST(@point.STX AS NVARCHAR(MAX)) + ' ORDER BY PointColumn.STX'; +EXEC sp_executesql @DynamicQuery; +GO +~~START~~ +int#!#geometry +1#!#E6100000010C00000000000008400000000000001040 +2#!#E6100000010C00000000000014400000000000001840 +~~END~~ + + +EXEC GetDistanceByXCoordinate @xCoordinate = 6.0; +GO +~~START~~ +float#!#float +0.0#!#5.0 +0.0#!#6.082762530298219 +~~END~~ + + +EXEC GetPointsByXCoordinate @XCoordinate = 4.0; +GO +~~START~~ +int#!#geometry +~~END~~ + + +EXEC GetPointsByXCoordinate1 @XCoordinate = 4.0; +GO +~~START~~ +int#!#float +~~END~~ + + +DECLARE @XCoordinate FLOAT = 3.0; +DECLARE @DynamicQuery NVARCHAR(MAX); +SET @DynamicQuery = N' SELECT * FROM YourTable WHERE PointColumn.STX > ' + CAST(@XCoordinate AS NVARCHAR(MAX)) + ' ORDER BY PointColumn.STX'; +EXEC sp_executesql @DynamicQuery; +GO +~~START~~ +int#!#geometry +2#!#E6100000010C00000000000014400000000000001840 +~~END~~ + + +SELECT ID, PointColumn.STX AS XCoordinate, CASE WHEN PointColumn.STX < 0 +THEN 'Negative X' WHEN PointColumn.STX = 0 THEN 'Zero X' +ELSE 'Positive X' END AS XCoordinateCategory FROM YourTable ORDER BY PointColumn.STX; +GO +~~START~~ +int#!#float#!#text +1#!#3.0#!#Positive X +2#!#5.0#!#Positive X +~~END~~ + + +DECLARE @point geometry = geometry::Point(1.0, 2.0, 4326); +SELECT ID, @point.STX AS XCoordinate, CASE WHEN @point.STX < 0 +THEN 'Negative X' WHEN @point.STX = 0 THEN 'Zero X' +ELSE 'Positive X' END AS XCoordinateCategory FROM YourTable ORDER BY PointColumn.STX; +GO +~~START~~ +int#!#float#!#text +1#!#1.0#!#Positive X +2#!#1.0#!#Positive X +~~END~~ + + +SELECT * FROM ( SELECT ID, +CASE WHEN PointColumn.STX BETWEEN 0 AND 5 THEN '0-5' +WHEN PointColumn.STX BETWEEN 5.1 AND 10 THEN '5.1-10' +ELSE '10.1+' +END AS XCoordRange +FROM YourTable ORDER BY PointColumn.STX +) AS Source +PIVOT ( COUNT(ID) FOR XCoordRange IN ([0-5], [5.1-10], [10.1+])) AS PivotTable; +GO +~~START~~ +int#!#int#!#int +2#!#0#!#0 +~~END~~ + + +SELECT ID, PointColumn.STX AS XCoordinate, +JSON_QUERY('{"XCoordinate":' + CAST(PointColumn.STX AS NVARCHAR(MAX)) + '}') AS XCoordinateJson +FROM YourTable ORDER BY PointColumn.STX; +GO +~~START~~ +int#!#float#!#nvarchar +1#!#3.0#!#{"XCoordinate": 3} +2#!#5.0#!#{"XCoordinate": 5} +~~END~~ + + +DECLARE @point geometry = geometry::Point(3.0, 2.0, 4326); +SELECT ID, @point.STX AS XCoordinate, +JSON_QUERY('{"XCoordinate":' + CAST(@point.STX AS NVARCHAR(MAX)) + '}') AS XCoordinateJson +FROM YourTable ORDER BY PointColumn.STX; +GO +~~START~~ +int#!#float#!#nvarchar +1#!#3.0#!#{"XCoordinate": 3} +2#!#3.0#!#{"XCoordinate": 3} +~~END~~ + + +SELECT [PointColumn].[STX] AS XCoordinate FROM [YourTable] ORDER BY PointColumn.STX; +GO +~~START~~ +float +3.0 +5.0 +~~END~~ + + +DECLARE @point geometry = geometry::Point(3.0, 2.0, 4326); +SELECT @point.[STX] AS XCoordinate +GO +~~START~~ +float +3.0 +~~END~~ + + +SELECT PointColumn.STX AS XCoordinate FROM YourTable ORDER BY PointColumn.STX; +GO +~~START~~ +float +3.0 +5.0 +~~END~~ + + +SELECT YourTable.PointColumn.STX AS XCoordinate FROM YourTable ORDER BY PointColumn.STX; +GO +~~START~~ +float +3.0 +5.0 +~~END~~ + + +SELECT dbo.YourTable.PointColumn.STX AS XCoordinate FROM YourTable ORDER BY PointColumn.STX; +GO +~~ERROR (Code: 33557097)~~ + +~~ERROR (Message: The multi-part identifier "dbo.YourTable.PointColumn.STX" could not be bound.)~~ + + +SELECT YourTable1.STX.STX AS XCoordinate FROM YourTable1 ORDER BY STX.STX; +GO +~~START~~ +float +3.0 +5.0 +~~END~~ + + +DECLARE @result geometry; +SET @result = dbo.GetGeometry(); +DECLARE @xCoordinate float; +SET @xCoordinate = @result.STX; +SELECT @result AS ResultGeometry, @xCoordinate AS XCoordinate; +GO +~~START~~ +geometry#!#float +E6100000010C000000000000F03F0000000000000040#!#1.0 +~~END~~ + + +DECLARE @referencePoint geometry = geometry::Point(0.0, 0.0, 4326); +UPDATE YourTable SET PointColumn = @referencePoint +WHERE PointColumn.STX >= @referencePoint.STX; +GO +~~ROW COUNT: 2~~ + +~~ROW COUNT: 2~~ + +~~ROW COUNT: 2~~ + + +SELECT ID, PointColumn1.STDistance(PointColumn2) AS Distance FROM YourTable2 ORDER BY PointColumn1.STX; +GO +~~START~~ +int#!#float +1#!#1.4142135623730951 +~~END~~ + + +DECLARE @point1 geometry = geometry::Point(1.0, 2.0, 4326); +SELECT ID, PointColumn1.STDistance(@point1) AS Distance FROM YourTable2 ORDER BY PointColumn1.STX; +GO +~~START~~ +int#!#float +1#!#2.8284271247461903 +~~END~~ + + +DECLARE @point1 geometry = geometry::Point(1.0, 2.0, 4326); +SELECT ID, @point1.STDistance(PointColumn2) AS Distance FROM YourTable2 ORDER BY PointColumn1.STX; +GO +~~START~~ +int#!#float +1#!#4.242640687119285 +~~END~~ + + +DECLARE @referencePoint geometry = geometry::Point(0.0, 0.0, 4326); +DECLARE @maxDistance float = 5.0; +SELECT * FROM YourTable WHERE PointColumn.STDistance(@referencePoint) <= @maxDistance ORDER BY PointColumn.STX; +GO +~~START~~ +int#!#geometry +1#!#E6100000010C00000000000000000000000000000000 +2#!#E6100000010C00000000000000000000000000000000 +~~END~~ + + +DECLARE @referencePoint geometry = geometry::Point(0.0, 0.0, 4326); +SELECT * FROM YourTable WHERE @referencePoint.STDistance(PointColumn) <= @referencePoint.STX ORDER BY PointColumn.STX; +GO +~~START~~ +int#!#geometry +1#!#E6100000010C00000000000000000000000000000000 +2#!#E6100000010C00000000000000000000000000000000 +~~END~~ + + +DECLARE @referencePoint geometry = geometry::Point(0.0, 0.0, 4326); +SELECT * FROM YourTable WHERE PointColumn.STDistance(@referencePoint) <= @referencePoint.STX ORDER BY PointColumn.STX; +GO +~~START~~ +int#!#geometry +1#!#E6100000010C00000000000000000000000000000000 +2#!#E6100000010C00000000000000000000000000000000 +~~END~~ + + +SELECT ID, dbo.CalculateDistance(PointColumn1, PointColumn2) AS Distance FROM YourTable2 ORDER BY PointColumn1.STX; +GO +~~START~~ +int#!#float +1#!#1.4142135623730951 +~~END~~ + + +DECLARE @referencePoint geometry = geometry::Point(0.0, 0.0, 4326); +SELECT ID, dbo.CalculateDistance(@referencePoint, PointColumn2) AS Distance FROM YourTable2 ORDER BY PointColumn1.STX; +GO +~~START~~ +int#!#float +1#!#6.4031242374328485 +~~END~~ + + +DECLARE @referencePoint geometry = geometry::Point(0.0, 0.0, 4326); +SELECT ID, dbo.CalculateDistance(PointColumn1, @referencePoint) AS Distance FROM YourTable2 ORDER BY PointColumn1.STX; +GO +~~START~~ +int#!#float +1#!#5.0 +~~END~~ + + +SELECT * FROM TableA JOIN TableB ON PointA.STDistance(TableB.PointB) <= 5.0 ORDER BY TableB.PointB.STX; +GO +~~START~~ +int#!#geometry#!#int#!#geometry +1#!#E6100000010C000000000000F03F0000000000000040#!#1#!#E6100000010C00000000000008400000000000001040 +~~END~~ + + +DECLARE @referencePoint geometry = geometry::Point(0.0, 0.0, 4326); +SELECT * FROM TableA JOIN TableB ON @referencePoint.STDistance(TableB.PointB) <= 5.0 ORDER BY TableB.PointB.STX; +GO +~~START~~ +int#!#geometry#!#int#!#geometry +1#!#E6100000010C000000000000F03F0000000000000040#!#1#!#E6100000010C00000000000008400000000000001040 +~~END~~ + + +DECLARE @referencePoint geometry = geometry::Point(0.0, 0.0, 4326); +SELECT * FROM TableA JOIN TableB ON PointA.STDistance(@referencePoint) <= 5.0 ORDER BY TableB.PointB.STX; +GO +~~START~~ +int#!#geometry#!#int#!#geometry +1#!#E6100000010C000000000000F03F0000000000000040#!#1#!#E6100000010C00000000000008400000000000001040 +~~END~~ + + +DECLARE @referencePoint geometry = geometry::Point(0.0, 0.0, 4326); +SELECT * FROM TableA JOIN TableB ON TableB.PointB.STDistance(@referencePoint) <= 5.0 ORDER BY TableB.PointB.STX; +GO +~~START~~ +int#!#geometry#!#int#!#geometry +1#!#E6100000010C000000000000F03F0000000000000040#!#1#!#E6100000010C00000000000008400000000000001040 +~~END~~ + + +SELECT * FROM YourTable2 ORDER BY PointColumn1.STDistance(PointColumn2); +GO +~~START~~ +int#!#geometry#!#geometry +1#!#E6100000010C00000000000008400000000000001040#!#E6100000010C00000000000010400000000000001440 +~~END~~ + + +DECLARE @referencePoint geometry = geometry::Point(0.0, 0.0, 4326); +SELECT * FROM YourTable ORDER BY PointColumn.STDistance(@referencePoint); +GO +~~START~~ +int#!#geometry +1#!#E6100000010C00000000000000000000000000000000 +2#!#E6100000010C00000000000000000000000000000000 +~~END~~ + + +DECLARE @referencePoint geometry = geometry::Point(0.0, 0.0, 4326); +SELECT * FROM YourTable ORDER BY @referencePoint.STDistance(PointColumn); +GO +~~START~~ +int#!#geometry +1#!#E6100000010C00000000000000000000000000000000 +2#!#E6100000010C00000000000000000000000000000000 +~~END~~ + + +DECLARE @thresholdDistance float = 3.0; +SELECT ID, PointColumn1.STDistance(PointColumn2) AS DistanceBetweenPoints, +CASE WHEN PointColumn1.STDistance(PointColumn2) <= @thresholdDistance THEN 'Close' ELSE 'Far' +END AS Proximity +FROM YourTable2 ORDER BY PointColumn1.STX; +GO +~~START~~ +int#!#float#!#text +1#!#1.4142135623730951#!#Close +~~END~~ + + +DECLARE @referencePoint geometry = geometry::Point(0.0, 0.0, 4326); +SELECT ID, PointColumn1.STDistance(@referencePoint) AS DistanceBetweenPoints, +CASE WHEN @referencePoint.STDistance(PointColumn2) <= @referencePoint.STX THEN 'Close' ELSE 'Far' +END AS Proximity +FROM YourTable2 ORDER BY PointColumn1.STX; +GO +~~START~~ +int#!#float#!#text +1#!#5.0#!#Far +~~END~~ + + +DECLARE @referencePoint geometry = geometry::Point(0.0, 0.0, 4326); +WITH DistanceCTE AS ( SELECT ID, PointColumn.STDistance(@referencePoint) AS Distance FROM YourTable ORDER BY PointColumn.STX) +SELECT * FROM DistanceCTE WHERE Distance <= 3.0; +GO +~~START~~ +int#!#float +1#!#0.0 +2#!#0.0 +~~END~~ + + +DECLARE @referencePoint geometry = geometry::Point(0.0, 0.0, 4326); +WITH DistanceCTE AS ( SELECT ID, @referencePoint.STDistance(PointColumn) AS Distance FROM YourTable ORDER BY PointColumn.STX) +SELECT * FROM DistanceCTE WHERE Distance <= 3.0; +GO +~~START~~ +int#!#float +1#!#0.0 +2#!#0.0 +~~END~~ + + +DECLARE @referencePoint geometry = geometry::Point(0.0, 0.0, 4326); +DECLARE @distanceInterval float = 5.0; +SELECT ROUND(PointColumn.STDistance(@referencePoint) / @distanceInterval, 0) * @distanceInterval AS DistanceGroup, +COUNT(*) AS PointCount +FROM YourTable +GROUP BY ROUND(PointColumn.STDistance(@referencePoint) / @distanceInterval, 0) * @distanceInterval; +GO +~~START~~ +float#!#int +0.0#!#2 +~~END~~ + + +DECLARE @referencePoint geometry = geometry::Point(1.0, 0.0, 4326); +SELECT ROUND(PointColumn.STDistance(@referencePoint) / @referencePoint.STX, 0) * @referencePoint.STX AS DistanceGroup, +COUNT(*) AS PointCount +FROM YourTable +GROUP BY ROUND(PointColumn.STDistance(@referencePoint) / @referencePoint.STX, 0) * @referencePoint.STX; +GO +~~START~~ +float#!#int +1.0#!#2 +~~END~~ + + +DECLARE @referencePoint geometry = geometry::Point(0.0, 0.0, 4326); +SELECT ID, PointColumn1.STDistance(PointColumn2) AS Distance, +PointColumn1.STDistance(@referencePoint) - LAG(PointColumn1.STDistance(PointColumn2)) OVER (ORDER BY ID) AS DistanceDifference +FROM YourTable2 ORDER BY PointColumn1.STX; +GO +~~START~~ +int#!#float#!#float +1#!#1.4142135623730951#!# +~~END~~ + + +DECLARE @referencePoint geometry = geometry::Point(0.0, 0.0, 4326); +SELECT ID, PointColumn.STDistance(@referencePoint) AS Distance, +@referencePoint.STDistance(PointColumn) - LAG(@referencePoint.STX) OVER (ORDER BY ID) AS DistanceDifference +FROM YourTable ORDER BY PointColumn.STX; +GO +~~START~~ +int#!#float#!#float +1#!#0.0#!# +2#!#0.0#!#0.0 +~~END~~ + + +DECLARE @referencePoint geometry = geometry::Point(0.0, 0.0, 4326); +DECLARE @maxDistance float = 3.0; +EXEC GetPointsWithinDistance @referencePoint, @maxDistance; +GO +~~START~~ +int#!#geometry +1#!#E6100000010C00000000000000000000000000000000 +2#!#E6100000010C00000000000000000000000000000000 +~~END~~ + + +DECLARE @referencePoint geometry = geometry::Point(0.0, 0.0, 4326); +DECLARE @maxDistance float = 3.0; +DECLARE @DynamicQuery NVARCHAR(MAX); +SET @DynamicQuery = N' +SELECT * FROM YourTable +WHERE PointColumn.STDistance(geometry::STGeomFromText(' + QUOTENAME(@referencePoint.STAsText(), '''') + ', 4326)) <= ' + CAST(@maxDistance AS NVARCHAR(MAX)) + ' ORDER BY PointColumn.STX'; +EXEC sp_executesql @DynamicQuery; +GO +~~START~~ +int#!#geometry +1#!#E6100000010C00000000000000000000000000000000 +2#!#E6100000010C00000000000000000000000000000000 +~~END~~ + + +DECLARE @referencePoint geometry = geometry::Point(0.0, 0.0, 4326); +DECLARE @DynamicQuery NVARCHAR(MAX); +SET @DynamicQuery = N' +SELECT * FROM YourTable +WHERE PointColumn.STDistance(geometry::STGeomFromText(' + QUOTENAME(@referencePoint.STAsText(), '''') + ', 4326)) <= ' + CAST(@referencePoint.STX AS NVARCHAR(MAX)) + ' ORDER BY PointColumn.STX'; +EXEC sp_executesql @DynamicQuery; +GO +~~START~~ +int#!#geometry +1#!#E6100000010C00000000000000000000000000000000 +2#!#E6100000010C00000000000000000000000000000000 +~~END~~ + + +DECLARE @referencePoint geometry = geometry::Point(0.0, 0.0, 4326); +DECLARE @thresholdDistance float = 3.0; +SELECT ID, PointColumn.STDistance(@referencePoint) AS DistanceToReferencePoint, +CASE WHEN PointColumn.STDistance(@referencePoint) <= @thresholdDistance THEN 'Close' +ELSE 'Far' +END AS Proximity +FROM YourTable ORDER BY PointColumn.STX; +GO +~~START~~ +int#!#float#!#text +1#!#0.0#!#Close +2#!#0.0#!#Close +~~END~~ + + +DECLARE @referencePoint geometry = geometry::Point(0.0, 0.0, 4326); +SELECT ID, @referencePoint.STDistance(PointColumn) AS DistanceToReferencePoint, +CASE WHEN @referencePoint.STDistance(PointColumn) <= @referencePoint.STY THEN 'Close' +ELSE 'Far' +END AS Proximity +FROM YourTable ORDER BY PointColumn.STX; +GO +~~START~~ +int#!#float#!#text +1#!#0.0#!#Close +2#!#0.0#!#Close +~~END~~ + + +DECLARE @distanceRanges TABLE (MinDistance float, MaxDistance float); +INSERT INTO @distanceRanges VALUES (0, 5), (5, 10), (10, 15); +SELECT * FROM ( SELECT ID, +CASE WHEN PointColumn1.STDistance(PointColumn2) BETWEEN 0 AND 5 THEN '0-5' +WHEN PointColumn1.STDistance(PointColumn2) BETWEEN 5.1 AND 10 THEN '5.1-10' +WHEN PointColumn1.STDistance(PointColumn2) BETWEEN 10.1 AND 15 THEN '10.1-15' +ELSE '15.1+' +END AS DistanceRange +FROM YourTable2 ORDER BY PointColumn1.STX +) AS Source +PIVOT ( COUNT(ID) FOR DistanceRange IN ([0-5], [5.1-10], [10.1-15], [15.1+])) AS PivotTable; +GO +~~ROW COUNT: 3~~ + +~~START~~ +int#!#int#!#int#!#int +1#!#0#!#0#!#0 +~~END~~ + + +DECLARE @referencePoint geometry = geometry::Point(0.0, 0.0, 4326); +SELECT ID, PointColumn.STDistance(@referencePoint) AS Distance, +JSON_QUERY('{"Distance":' + CAST(PointColumn.STDistance(@referencePoint) AS NVARCHAR(MAX)) + '}') AS DistanceJson +FROM YourTable ORDER BY PointColumn.STX; +GO +~~START~~ +int#!#float#!#nvarchar +1#!#0.0#!#{"Distance": 0} +2#!#0.0#!#{"Distance": 0} +~~END~~ + + +DECLARE @referencePoint geometry = geometry::Point(0.0, 0.0, 4326); +SELECT ID, @referencePoint.STDistance(PointColumn) AS Distance, +JSON_QUERY('{"Distance":' + CAST(@referencePoint.STDistance(PointColumn) AS NVARCHAR(MAX)) + '}') AS DistanceJson +FROM YourTable ORDER BY PointColumn.STX; +GO +~~START~~ +int#!#float#!#nvarchar +1#!#0.0#!#{"Distance": 0} +2#!#0.0#!#{"Distance": 0} +~~END~~ + + +SELECT [PointColumn1].STDistance([PointColumn2]) AS distance FROM [YourTable2] ORDER BY PointColumn1.STX; +GO +~~START~~ +float +1.4142135623730951 +~~END~~ + + +DECLARE @referencePoint geometry = geometry::Point(0.0, 0.0, 4326); +DECLARE @thresholdDistance float = 10.0; +DECLARE @sql NVARCHAR(MAX); +DECLARE @params NVARCHAR(MAX); +SET @sql = N' +SELECT ID, PointColumn.STDistance(@referencePoint) AS DistanceToReferencePoint, +CASE WHEN PointColumn.STDistance(@referencePoint) <= @thresholdDistance THEN ''Close'' +ELSE ''Far'' +END AS Proximity +FROM YourTable +WHERE PointColumn.STDistance(@referencePoint) <= @thresholdDistance ORDER BY PointColumn.STX;'; +SET @params = N'@referencePoint geometry, @thresholdDistance float'; +EXEC sp_executesql @sql, @params, @referencePoint, @thresholdDistance; +GO +~~START~~ +int#!#float#!#text +1#!#0.0#!#Close +2#!#0.0#!#Close +~~END~~ + + +DECLARE @referencePoint geometry = geometry::Point(0.0, 0.0, 4326); +SELECT PointColumn.STDistance(@referencePoint) AS Distance FROM YourTable ORDER BY PointColumn.STX; +SELECT YourTable.PointColumn.STDistance(@referencePoint) AS Distance FROM YourTable ORDER BY PointColumn.STX; +GO +~~START~~ +float +0.0 +0.0 +~~END~~ + +~~START~~ +float +0.0 +0.0 ~~END~~ -SELECT * FROM point_distances_geom; +DECLARE @referencePoint geometry = geometry::Point(0.0, 0.0, 4326); +SELECT dbo.YourTable.PointColumn.STDistance(@referencePoint) AS Distance FROM YourTable ORDER BY PointColumn.STX; GO -~~START~~ -geometry#!#geometry#!#float -E6100000010C17D9CEF753D34740D34D6210585936C0#!#E6100000010C000000000000F03F0000000000000040#!#52.62309000809436 ~~ERROR (Code: 33557097)~~ -~~ERROR (Message: ST_Distance: Operation on mixed SRID geometries (Point, 4326) != (Point, 0))~~ +~~ERROR (Message: Remote procedure/function reference with 4-part object name is not currently supported in Babelfish)~~ -SELECT location FROM SPATIALPOINTGEOM_dt; +DECLARE @referencePoint geometry = geometry::Point(0.0, 0.0, 4326); +UPDATE YourTable SET PointColumn = @referencePoint +WHERE PointColumn.STDistance(@referencePoint) <= 2.0; GO -~~START~~ -geometry -E6100000010C17D9CEF753D34740D34D6210585936C0 -E6100000010C000000000000F03F0000000000000040 -00000000010C17D9CEF753D34740D34D6210585936C0 - -E6100000010C17D9CEF753D34740D34D6210585936C0 -E6100000010C000000000000F03F0000000000000040 -E6100000010C17D9CEF753D34740D34D6210585936C0 -E6100000010C17D9CEF753D34740D34D6210585936C0 -E6100000010C000000000000F03F0000000000000040 -00000000010C17D9CEF753D34740D34D6210585936C0 -~~END~~ +~~ROW COUNT: 2~~ + + +DECLARE @referencePoint geometry = geometry::Point(0.0, 0.0, 4326); +UPDATE YourTable SET PointColumn = @referencePoint +WHERE @referencePoint.STDistance(PointColumn) <= 2.0; +GO +~~ROW COUNT: 2~~ -- Create Type Test Case currently Babelfish supports it but TSQL doesn't for spatial Types, Although it doesn't break anything @@ -447,27 +1586,41 @@ E6100000010C17D9CEF753D34740D34D6210585936C0 DECLARE @point geography; SET @point = geography::STGeomFromText('POINT(-122.34900 47.65100)', 4326); SELECT STAsText(@point); +SELECT @point.STAsText(); Go ~~START~~ text POINT(-122.349 47.651) ~~END~~ +~~START~~ +text +POINT(-122.349 47.651) +~~END~~ + DECLARE @point geography; SET @point = geography::POINT(22.34900, -47.65100, 4326); SELECT STAsText(@point); +SELECT @point.STAsText(); Go ~~START~~ text POINT(-47.651 22.349) ~~END~~ +~~START~~ +text +POINT(-47.651 22.349) +~~END~~ + DECLARE @point geography; SET @point = geography::STPointFromText('POINT(-122.34900 47.65100)', 4326); -SELECT long(@point); -SELECT lat(@point); +SELECT Long(@point); +SELECT Lat(@point); +SELECT @point.Long; +SELECT @point.Lat; Go ~~START~~ float @@ -479,11 +1632,23 @@ float 47.651 ~~END~~ +~~START~~ +float +-122.349 +~~END~~ + +~~START~~ +float +47.651 +~~END~~ + DECLARE @point geography; SET @point = geography::POINT(22.34900, -47.65100, 4326); -SELECT long(@point); -SELECT lat(@point); +SELECT Long(@point); +SELECT Lat(@point); +SELECT @point.Long; +SELECT @point.Lat; Go ~~START~~ float @@ -495,30 +1660,327 @@ float 22.349 ~~END~~ +~~START~~ +float +-47.651 +~~END~~ + +~~START~~ +float +22.349 +~~END~~ + DECLARE @point1 geography, @point2 geography; SET @point1 = geography::STPointFromText('POINT(-122.34900 47.65100)', 4326); SET @point2 = geography::STGeomFromText('POINT(-122.35000 47.65000)', 4326); SELECT STDistance(@point1, @point2); +SELECT @point1.STDistance(@point2); Go ~~START~~ float 134.1864008701007 ~~END~~ +~~START~~ +float +134.1864008701007 +~~END~~ -SELECT * FROM TextFromGeog; + +DECLARE @point geography; +SET @point = geography::STGeomFromText('POINT(-22.34900 47.65100)', 4326); +Insert INTO SPATIALPOINTGEOG_dt(location) VALUES(geography::point(@point.Long, @point.Lat, 4326)) +go +~~ROW COUNT: 1~~ + + +DECLARE @Lat geography; +SET @Lat = geography::STGeomFromText('POINT(-22.34900 47.65100)', 4326); +select geography::Point(@Lat.Long, @Lat.Lat, 4326).Long, geography::Point(@Lat.Long, @Lat.Lat, 4326).Lat; +go +~~START~~ +float#!#float +47.651#!#-22.349 +~~END~~ + + +DECLARE @Lat geography; +SET @Lat = geography::STGeomFromText('POINT(-22.34900 47.65100)', 4326); +select geography::Point(@Lat.Long, @Lat.Lat, 4326).STAsText(), geography::Point(@Lat.Long, @Lat.Lat, 4326).STAsBinary(), geography::Point(@Lat.Long, @Lat.Lat, 4326).STDistance(geography::Point(@Lat.Long, @Lat.Lat, 4326)); +go +~~START~~ +text#!#varbinary#!#float +POINT(47.651 -22.349)#!#010100000017D9CEF753D34740D34D6210585936C0#!#0.0 +~~END~~ + + +SELECT + SpatialData.ID, + SPATIALPOINTGEOG_dt.location.Lat, + SpatialLocation.STDistance(SPATIALPOINTGEOG_dt.location) +FROM + SpatialData +JOIN + SPATIALPOINTGEOG_dt ON SPATIALPOINTGEOG_dt.location.Long - SpatialData.SpatialLocation.Lat <= 10 +ORDER BY location.Lat; +GO +~~START~~ +int#!#float#!#float +1#!#2.0#!#156876.14940188668 +2#!#2.0#!#351485.0664919168 +3#!#2.0#!#647017.0083805197 +4#!#2.0#!#953316.5401136167 +5#!#2.0#!#1261960.137843746 +1#!#2.0#!#156876.14940188668 +2#!#2.0#!#351485.0664919168 +3#!#2.0#!#647017.0083805197 +4#!#2.0#!#953316.5401136167 +5#!#2.0#!#1261960.137843746 +1#!#2.0#!#156876.14940188668 +2#!#2.0#!#351485.0664919168 +3#!#2.0#!#647017.0083805197 +4#!#2.0#!#953316.5401136167 +5#!#2.0#!#1261960.137843746 +1#!#47.651#!#5678803.288585193 +2#!#47.651#!#5557193.284430087 +3#!#47.651#!#5446042.320579326 +4#!#47.651#!#5345543.26741007 +5#!#47.651#!#5255813.671417903 +~~END~~ + + +WITH RegionLocations AS ( + SELECT + SpatialData.ID, + SPATIALPOINTGEOG_dt.location.Lat + FROM + SpatialData + JOIN + SPATIALPOINTGEOG_dt ON SPATIALPOINTGEOG_dt.location.Long - SpatialData.SpatialLocation.Lat <= 10 + ORDER BY location.Lat +) +SELECT + Lat, + COUNT(ID) AS LocationCount +FROM + RegionLocations +GROUP BY + Lat; GO ~~START~~ +float#!#int +47.651#!#5 +2.0#!#15 +~~END~~ + + +-- Test with CTE +with mycte (a) +as (select SPATIALPOINTGEOG_dt.location from SPATIALPOINTGEOG_dt) +select a.STAsText() + from mycte x inner join SPATIALPOINTGEOG_dt y on x.a.Lat >= y.location.Long ORDER BY x.a.Lat; +go +~~START~~ +text +POINT(47.651 -22.349) +POINT(47.651 -22.349) +POINT(47.651 -22.349) +POINT(47.651 -22.349) +POINT(1 2) +POINT(1 2) +POINT(1 2) +POINT(1 2) +POINT(1 2) +POINT(1 2) +POINT(1 2) +POINT(1 2) +POINT(1 2) +POINT(1 2) +POINT(1 2) +POINT(1 2) +POINT(-22.349 47.651) +POINT(-22.349 47.651) +POINT(-22.349 47.651) +POINT(-22.349 47.651) +POINT(-22.349 47.651) +POINT(-22.349 47.651) +POINT(-22.349 47.651) +POINT(-22.349 47.651) +~~END~~ + + +-- Test with tvf +select f.STAsText() + from testspatial_tvf(1) f inner join SPATIALPOINTGEOG_dt t on f.location.Lat >= t.location.Long ORDER BY f.location.Lat; +go +~~START~~ text POINT(47.651 -22.349) +POINT(47.651 -22.349) +POINT(47.651 -22.349) +POINT(47.651 -22.349) +POINT(1 2) POINT(1 2) +POINT(1 2) +POINT(1 2) +POINT(1 2) +POINT(1 2) +POINT(1 2) +POINT(1 2) +POINT(1 2) +POINT(1 2) +POINT(1 2) +POINT(1 2) +POINT(-22.349 47.651) +POINT(-22.349 47.651) +POINT(-22.349 47.651) +POINT(-22.349 47.651) +POINT(-22.349 47.651) +POINT(-22.349 47.651) +POINT(-22.349 47.651) +POINT(-22.349 47.651) +~~END~~ + + +-- Null test for Geospatial functions +DECLARE @point1 geography, @point2 geography, @point3 geography; +SET @point1 = geography::STPointFromText(null, 4326); +SET @point2 = geography::STGeomFromText(null, 4326); +SET @point3 = geography::POINT(22.34900, -47.65100, 4326); +SELECT @point1.Long; +SELECT @point1.Lat; +SELECT @point1.STAsText(); +SELECT @point1.STAsBinary(); +SELECT @point1.STDistance(@point2); +SELECT @point3.STDistance(@point2); +SELECT @point1.STDistance(@point3); +Go +~~START~~ +float + +~~END~~ + +~~START~~ +float + +~~END~~ + +~~START~~ +text + +~~END~~ + +~~START~~ +varbinary + +~~END~~ + +~~START~~ +float + +~~END~~ + +~~START~~ +float + +~~END~~ + +~~START~~ +float + +~~END~~ + + +-- Negative test for Geospatial functions +DECLARE @point1 geography, @point2 varchar(50), @point3 int; +SET @point1 = geography::POINT(22.34900, -47.65100, 4326); +SET @point2 = 'Test_String'; +SELECT @point2.STDistance(@point1); +Go +~~ERROR (Code: 33557097)~~ + +~~ERROR (Message: parse error - invalid geometry)~~ + + +SELECT location.STY from SPATIALPOINTGEOG_dt ORDER BY location.Lat; +GO +~~ERROR (Code: 33557097)~~ + +~~ERROR (Message: column notation .sty applied to type geography, which is not a composite type)~~ + + +SELECT * FROM GeogView; +GO +~~START~~ +float#!#float +#!# +47.651#!#-22.349 +47.651#!#-22.349 +47.651#!#-22.349 +47.651#!#-22.349 +1.0#!#2.0 +1.0#!#2.0 +1.0#!#2.0 +-22.349#!#47.651 +~~END~~ + + +SELECT * FROM SubqueryView; +GO +~~START~~ +float +1.0 +~~END~~ + + +SELECT * FROM BrackExprView; +GO +~~START~~ +float +1.0 +~~END~~ + + +SELECT * FROM FuncExprView; +GO +~~START~~ +float +1.0 +~~END~~ + + +EXEC dbo.proc_getdata; +GO +~~ROW COUNT: 9~~ + +~~START~~ +text POINT(47.651 -22.349) +POINT(47.651 -22.349) +POINT(47.651 -22.349) +POINT(47.651 -22.349) +POINT(1 2) +POINT(1 2) POINT(1 2) POINT(-22.349 47.651) +~~END~~ + + +SELECT * FROM TextFromGeog; +GO +~~START~~ +text + +POINT(47.651 -22.349) +POINT(47.651 -22.349) POINT(47.651 -22.349) +POINT(47.651 -22.349) +POINT(1 2) POINT(1 2) +POINT(1 2) +POINT(-22.349 47.651) ~~END~~ @@ -526,14 +1988,15 @@ SELECT * FROM BinaryFromGeog; GO ~~START~~ varbinary -010100000017D9CEF753D34740D34D6210585936C0 -0101000000000000000000F03F0000000000000040 010100000017D9CEF753D34740D34D6210585936C0 -0101000000000000000000F03F0000000000000040 -0101000000D34D6210585936C017D9CEF753D34740 010100000017D9CEF753D34740D34D6210585936C0 +010100000017D9CEF753D34740D34D6210585936C0 +010100000017D9CEF753D34740D34D6210585936C0 +0101000000000000000000F03F0000000000000040 +0101000000000000000000F03F0000000000000040 0101000000000000000000F03F0000000000000040 +0101000000D34D6210585936C017D9CEF753D34740 ~~END~~ @@ -541,14 +2004,15 @@ SELECT * FROM CoordsFromGeog; GO ~~START~~ float#!#float -47.651#!#-22.349 -1.0#!#2.0 #!# 47.651#!#-22.349 -1.0#!#2.0 --22.349#!#47.651 47.651#!#-22.349 +47.651#!#-22.349 +47.651#!#-22.349 +1.0#!#2.0 1.0#!#2.0 +1.0#!#2.0 +-22.349#!#47.651 ~~END~~ @@ -556,14 +2020,15 @@ SELECT * FROM TransformFromGeog; GO ~~START~~ geography -E6100000010CD34D6210585936C017D9CEF753D34740 -E6100000010C0000000000000040000000000000F03F E6100000010CD34D6210585936C017D9CEF753D34740 -E6100000010C0000000000000040000000000000F03F -E6100000010C17D9CEF753D34740D34D6210585936C0 +E6100000010CD34D6210585936C017D9CEF753D34740 +E6100000010CD34D6210585936C017D9CEF753D34740 E6100000010CD34D6210585936C017D9CEF753D34740 E6100000010C0000000000000040000000000000F03F +E6100000010C0000000000000040000000000000F03F +E6100000010C0000000000000040000000000000F03F +E6100000010C17D9CEF753D34740D34D6210585936C0 ~~END~~ @@ -574,22 +2039,29 @@ geography E6100000010CD34D6210585936C017D9CEF753D34740 E6100000010CD34D6210585936C017D9CEF753D34740 E6100000010CD34D6210585936C017D9CEF753D34740 -E6100000010C0000000000000040000000000000F03F -E6100000010C0000000000000040000000000000F03F -E6100000010C0000000000000040000000000000F03F E6100000010CD34D6210585936C017D9CEF753D34740 E6100000010CD34D6210585936C017D9CEF753D34740 E6100000010CD34D6210585936C017D9CEF753D34740 -E6100000010C0000000000000040000000000000F03F -E6100000010C0000000000000040000000000000F03F -E6100000010C0000000000000040000000000000F03F -E6100000010C17D9CEF753D34740D34D6210585936C0 E6100000010CD34D6210585936C017D9CEF753D34740 E6100000010CD34D6210585936C017D9CEF753D34740 E6100000010CD34D6210585936C017D9CEF753D34740 +E6100000010CD34D6210585936C017D9CEF753D34740 +E6100000010CD34D6210585936C017D9CEF753D34740 +E6100000010CD34D6210585936C017D9CEF753D34740 +E6100000010CD34D6210585936C017D9CEF753D34740 +E6100000010CD34D6210585936C017D9CEF753D34740 +E6100000010CD34D6210585936C017D9CEF753D34740 +E6100000010CD34D6210585936C017D9CEF753D34740 +E6100000010C0000000000000040000000000000F03F +E6100000010C0000000000000040000000000000F03F +E6100000010C0000000000000040000000000000F03F E6100000010C0000000000000040000000000000F03F E6100000010C0000000000000040000000000000F03F E6100000010C0000000000000040000000000000F03F +E6100000010C0000000000000040000000000000F03F +E6100000010C0000000000000040000000000000F03F +E6100000010C0000000000000040000000000000F03F +E6100000010C17D9CEF753D34740D34D6210585936C0 ~~END~~ @@ -601,47 +2073,168 @@ E6100000010CD34D6210585936C017D9CEF753D34740#!#E6100000010C000000000000004000000 E6100000010CD34D6210585936C017D9CEF753D34740#!#E6100000010C0000000000000040000000000000F03F#!#5736178.674863189 E6100000010CD34D6210585936C017D9CEF753D34740#!#E6100000010C17D9CEF753D34740D34D6210585936C0#!#1.04243622548279E7 E6100000010CD34D6210585936C017D9CEF753D34740#!#E6100000010C0000000000000040000000000000F03F#!#5736178.674863189 -E6100000010C0000000000000040000000000000F03F#!#E6100000010CD34D6210585936C017D9CEF753D34740#!#5736178.674863189 -E6100000010C0000000000000040000000000000F03F#!#E6100000010CD34D6210585936C017D9CEF753D34740#!#5736178.674863189 -E6100000010C0000000000000040000000000000F03F#!#E6100000010C17D9CEF753D34740D34D6210585936C0#!#5535965.307328846 -E6100000010C0000000000000040000000000000F03F#!#E6100000010CD34D6210585936C017D9CEF753D34740#!#5736178.674863189 E6100000010CD34D6210585936C017D9CEF753D34740#!#E6100000010C0000000000000040000000000000F03F#!#5736178.674863189 E6100000010CD34D6210585936C017D9CEF753D34740#!#E6100000010C0000000000000040000000000000F03F#!#5736178.674863189 E6100000010CD34D6210585936C017D9CEF753D34740#!#E6100000010C17D9CEF753D34740D34D6210585936C0#!#1.04243622548279E7 E6100000010CD34D6210585936C017D9CEF753D34740#!#E6100000010C0000000000000040000000000000F03F#!#5736178.674863189 +E6100000010CD34D6210585936C017D9CEF753D34740#!#E6100000010C0000000000000040000000000000F03F#!#5736178.674863189 +E6100000010CD34D6210585936C017D9CEF753D34740#!#E6100000010C0000000000000040000000000000F03F#!#5736178.674863189 +E6100000010CD34D6210585936C017D9CEF753D34740#!#E6100000010C17D9CEF753D34740D34D6210585936C0#!#1.04243622548279E7 +E6100000010CD34D6210585936C017D9CEF753D34740#!#E6100000010C0000000000000040000000000000F03F#!#5736178.674863189 +E6100000010CD34D6210585936C017D9CEF753D34740#!#E6100000010C0000000000000040000000000000F03F#!#5736178.674863189 +E6100000010CD34D6210585936C017D9CEF753D34740#!#E6100000010C0000000000000040000000000000F03F#!#5736178.674863189 +E6100000010CD34D6210585936C017D9CEF753D34740#!#E6100000010C17D9CEF753D34740D34D6210585936C0#!#1.04243622548279E7 +E6100000010CD34D6210585936C017D9CEF753D34740#!#E6100000010C0000000000000040000000000000F03F#!#5736178.674863189 +E6100000010C0000000000000040000000000000F03F#!#E6100000010C17D9CEF753D34740D34D6210585936C0#!#5535965.307328846 +E6100000010C0000000000000040000000000000F03F#!#E6100000010CD34D6210585936C017D9CEF753D34740#!#5736178.674863189 +E6100000010C0000000000000040000000000000F03F#!#E6100000010C17D9CEF753D34740D34D6210585936C0#!#5535965.307328846 +E6100000010C0000000000000040000000000000F03F#!#E6100000010CD34D6210585936C017D9CEF753D34740#!#5736178.674863189 +E6100000010C0000000000000040000000000000F03F#!#E6100000010CD34D6210585936C017D9CEF753D34740#!#5736178.674863189 +E6100000010C0000000000000040000000000000F03F#!#E6100000010CD34D6210585936C017D9CEF753D34740#!#5736178.674863189 +E6100000010C0000000000000040000000000000F03F#!#E6100000010CD34D6210585936C017D9CEF753D34740#!#5736178.674863189 +E6100000010C0000000000000040000000000000F03F#!#E6100000010CD34D6210585936C017D9CEF753D34740#!#5736178.674863189 +E6100000010C0000000000000040000000000000F03F#!#E6100000010CD34D6210585936C017D9CEF753D34740#!#5736178.674863189 +E6100000010C0000000000000040000000000000F03F#!#E6100000010CD34D6210585936C017D9CEF753D34740#!#5736178.674863189 E6100000010C0000000000000040000000000000F03F#!#E6100000010CD34D6210585936C017D9CEF753D34740#!#5736178.674863189 E6100000010C0000000000000040000000000000F03F#!#E6100000010CD34D6210585936C017D9CEF753D34740#!#5736178.674863189 E6100000010C0000000000000040000000000000F03F#!#E6100000010C17D9CEF753D34740D34D6210585936C0#!#5535965.307328846 E6100000010C0000000000000040000000000000F03F#!#E6100000010CD34D6210585936C017D9CEF753D34740#!#5736178.674863189 +E6100000010C0000000000000040000000000000F03F#!#E6100000010CD34D6210585936C017D9CEF753D34740#!#5736178.674863189 E6100000010C17D9CEF753D34740D34D6210585936C0#!#E6100000010CD34D6210585936C017D9CEF753D34740#!#1.04243622548279E7 E6100000010C17D9CEF753D34740D34D6210585936C0#!#E6100000010C0000000000000040000000000000F03F#!#5535965.307328846 E6100000010C17D9CEF753D34740D34D6210585936C0#!#E6100000010CD34D6210585936C017D9CEF753D34740#!#1.04243622548279E7 E6100000010C17D9CEF753D34740D34D6210585936C0#!#E6100000010C0000000000000040000000000000F03F#!#5535965.307328846 E6100000010C17D9CEF753D34740D34D6210585936C0#!#E6100000010CD34D6210585936C017D9CEF753D34740#!#1.04243622548279E7 E6100000010C17D9CEF753D34740D34D6210585936C0#!#E6100000010C0000000000000040000000000000F03F#!#5535965.307328846 -E6100000010CD34D6210585936C017D9CEF753D34740#!#E6100000010C0000000000000040000000000000F03F#!#5736178.674863189 -E6100000010CD34D6210585936C017D9CEF753D34740#!#E6100000010C0000000000000040000000000000F03F#!#5736178.674863189 -E6100000010CD34D6210585936C017D9CEF753D34740#!#E6100000010C17D9CEF753D34740D34D6210585936C0#!#1.04243622548279E7 -E6100000010CD34D6210585936C017D9CEF753D34740#!#E6100000010C0000000000000040000000000000F03F#!#5736178.674863189 -E6100000010C0000000000000040000000000000F03F#!#E6100000010CD34D6210585936C017D9CEF753D34740#!#5736178.674863189 -E6100000010C0000000000000040000000000000F03F#!#E6100000010CD34D6210585936C017D9CEF753D34740#!#5736178.674863189 -E6100000010C0000000000000040000000000000F03F#!#E6100000010C17D9CEF753D34740D34D6210585936C0#!#5535965.307328846 -E6100000010C0000000000000040000000000000F03F#!#E6100000010CD34D6210585936C017D9CEF753D34740#!#5736178.674863189 +E6100000010C17D9CEF753D34740D34D6210585936C0#!#E6100000010CD34D6210585936C017D9CEF753D34740#!#1.04243622548279E7 +~~END~~ + + +SELECT location.Lat from SPATIALPOINTGEOG_dt ORDER BY location.Lat; +GO +~~START~~ +float + +-22.349 +-22.349 +-22.349 +-22.349 +2.0 +2.0 +2.0 +47.651 +~~END~~ + + +SELECT SPATIALPOINTGEOG_dt.location.Long from SPATIALPOINTGEOG_dt ORDER BY location.Lat; +GO +~~START~~ +float + +47.651 +47.651 +47.651 +47.651 +1.0 +1.0 +1.0 +-22.349 +~~END~~ + + +SELECT location.STAsText() from SPATIALPOINTGEOG_dt ORDER BY location.Lat; +GO +~~START~~ +text + +POINT(47.651 -22.349) +POINT(47.651 -22.349) +POINT(47.651 -22.349) +POINT(47.651 -22.349) +POINT(1 2) +POINT(1 2) +POINT(1 2) +POINT(-22.349 47.651) +~~END~~ + + +SELECT location.STAsBinary() from SPATIALPOINTGEOG_dt ORDER BY location.Lat; +GO +~~START~~ +varbinary + +010100000017D9CEF753D34740D34D6210585936C0 +010100000017D9CEF753D34740D34D6210585936C0 +010100000017D9CEF753D34740D34D6210585936C0 +010100000017D9CEF753D34740D34D6210585936C0 +0101000000000000000000F03F0000000000000040 +0101000000000000000000F03F0000000000000040 +0101000000000000000000F03F0000000000000040 +0101000000D34D6210585936C017D9CEF753D34740 +~~END~~ + + +SELECT location.STDistance(geography::STGeomFromText('POINT(-122.34900 47.65100)', 4326)) from SPATIALPOINTGEOG_dt ORDER BY location.Lat; +GO +~~START~~ +float + +1.7059874617785625E7 +1.7059874617785625E7 +1.7059874617785625E7 +1.7059874617785625E7 +1.2255731559616795E7 +1.2255731559616795E7 +1.2255731559616795E7 +6929242.948674276 +~~END~~ + + +SELECT [SPATIALPOINTGEOG_dt].[location].[Long] from [SPATIALPOINTGEOG_dt] ORDER BY location.Lat; +GO +~~START~~ +float + +47.651 +47.651 +47.651 +47.651 +1.0 +1.0 +1.0 +-22.349 +~~END~~ + + +SELECT [location].[Lat] from [SPATIALPOINTGEOG_dt] ORDER BY location.Lat; +GO +~~START~~ +float + +-22.349 +-22.349 +-22.349 +-22.349 +2.0 +2.0 +2.0 +47.651 ~~END~~ -SELECT location FROM SPATIALPOINTGEOG_dt; +SELECT location FROM SPATIALPOINTGEOG_dt ORDER BY location.Lat; GO ~~START~~ geography -E6100000010CD34D6210585936C017D9CEF753D34740 -E6100000010C0000000000000040000000000000F03F E6100000010CD34D6210585936C017D9CEF753D34740 -E6100000010C0000000000000040000000000000F03F -E6100000010C17D9CEF753D34740D34D6210585936C0 E6100000010CD34D6210585936C017D9CEF753D34740 +E6100000010CD34D6210585936C017D9CEF753D34740 +E6100000010CD34D6210585936C017D9CEF753D34740 +E6100000010C0000000000000040000000000000F03F E6100000010C0000000000000040000000000000F03F +E6100000010C0000000000000040000000000000F03F +E6100000010C17D9CEF753D34740D34D6210585936C0 ~~END~~ @@ -892,15 +2485,249 @@ E6100000010C17D9CEF753D34740D34D6210585936C0 ~~END~~ -SELECT * FROM SPATIALPOINT_dt; +SELECT + GeomColumn.STX AS XCoordinate, + GeomColumn.STY AS YCoordinate, + PrimaryKey, + GeogColumn.STDistance(geography::Point(7, 8, 4326)) AS DistanceToFixedPoint +FROM + SPATIALPOINT_dt ORDER BY GeomColumn.STX; +GO +~~START~~ +float#!#float#!#int#!#float +#!##!#2#!#5405374.929245813 +#!##!#5#!#5405374.929245813 +1.0#!#2.0#!#3#!#953316.5401136167 +1.0#!#2.0#!#6#!#953316.5401136167 +47.651#!#-22.349#!#1#!# +47.651#!#-22.349#!#4#!# +~~END~~ + + + +DECLARE @sql NVARCHAR(MAX); +SET @sql = + N'SELECT ' + + N'GeomColumn.STX AS XCoordinate, ' + + N'GeomColumn.STY AS YCoordinate, ' + + N'PrimaryKey, ' + + N'GeogColumn.STDistance(geography::Point(7, 8, 4326)) AS DistanceToFixedPoint ' + + N'FROM SPATIALPOINT_dt ORDER BY GeomColumn.STX'; +-- Execute the dynamic SQL +EXEC sp_executesql @sql; +GO +~~START~~ +float#!#float#!#int#!#float +#!##!#2#!#5405374.929245813 +#!##!#5#!#5405374.929245813 +1.0#!#2.0#!#3#!#953316.5401136167 +1.0#!#2.0#!#6#!#953316.5401136167 +47.651#!#-22.349#!#1#!# +47.651#!#-22.349#!#4#!# +~~END~~ + + +SELECT * FROM SPATIALPOINT_dt ORDER BY GeomColumn.STX; GO ~~START~~ int#!#geometry#!#geography -1#!#E6100000010C17D9CEF753D34740D34D6210585936C0#!# 2#!##!#E6100000010CD34D6210585936C017D9CEF753D34740 -3#!#E6100000010C000000000000F03F0000000000000040#!#E6100000010C0000000000000040000000000000F03F -4#!#E6100000010C17D9CEF753D34740D34D6210585936C0#!# 5#!##!#E6100000010CD34D6210585936C017D9CEF753D34740 +3#!#E6100000010C000000000000F03F0000000000000040#!#E6100000010C0000000000000040000000000000F03F 6#!#E6100000010C000000000000F03F0000000000000040#!#E6100000010C0000000000000040000000000000F03F +1#!#E6100000010C17D9CEF753D34740D34D6210585936C0#!# +4#!#E6100000010C17D9CEF753D34740D34D6210585936C0#!# +~~END~~ + + +-- Here we are testing ambiguity scenario for func_ref functions but we prioritize Geospatial Call in this case (Needs Documentation) +SELECT geom_schema.STDistance(geom_schema) from geometry_test +GO +~~START~~ +float +0.0 +~~END~~ + + +-- Here we are testing ambiguity scenario for col_ref functions but we prioritize Geospatial Call in this case (Needs Documentation) +SELECT STX.STX from STX +GO +~~START~~ +float +47.651 +~~END~~ + + +INSERT INTO babelfish_migration_mode_table SELECT current_setting('babelfishpg_tsql.migration_mode') +GO +~~ROW COUNT: 1~~ + + +-- test multi-db mode +SELECT set_config('role', 'jdbc_user', false); +GO +~~START~~ +text +jdbc_user +~~END~~ + +SELECT set_config('babelfishpg_tsql.migration_mode', 'multi-db', false); +GO +~~START~~ +text +multi-db +~~END~~ + + +CREATE DATABASE db1; +GO + +CREATE DATABASE db2; +GO + +USE db1; +GO + +CREATE TABLE SpatialData +( + SpatialPoint GEOMETRY, + PrimaryKey INT +); +GO + +INSERT INTO SpatialData (SpatialPoint, PrimaryKey) +VALUES + (geometry::Point(1, 2, 0), 1), + (geometry::Point(3, 4, 0), 2), + (geometry::Point(5, 6, 0), 3); +GO +~~ROW COUNT: 3~~ + + +USE db2; +GO + +CREATE TABLE SpatialData +( + SpatialPoint GEOMETRY, + PrimaryKey INT +); +GO + +INSERT INTO SpatialData (SpatialPoint, PrimaryKey) +VALUES + (geometry::Point(7, 8, 0), 4), + (geometry::Point(9, 10, 0), 5), + (geometry::Point(11, 12, 0), 6); +GO +~~ROW COUNT: 3~~ + + +DECLARE @sql NVARCHAR(MAX); +SET @sql = + N'SELECT ' + + N'[SpatialPoint].[STX] AS XCoordinate, ' + + N'[SpatialPoint].[STY] AS YCoordinate, ' + + N'[PrimaryKey] ' + + N'FROM [db1].[dbo].[SpatialData] ' + + N'UNION ALL ' + + N'SELECT ' + + N'[SpatialPoint].[STX] AS XCoordinate, ' + + N'[SpatialPoint].[STY] AS YCoordinate, ' + + N'[PrimaryKey] ' + + N'FROM [db2].[dbo].[SpatialData] ORDER BY SpatialPoint.STX'; +-- Execute the dynamic SQL +EXEC sp_executesql @sql; +GO +~~START~~ +float#!#float#!#int +1.0#!#2.0#!#1 +3.0#!#4.0#!#2 +5.0#!#6.0#!#3 +7.0#!#8.0#!#4 +9.0#!#10.0#!#5 +11.0#!#12.0#!#6 +~~END~~ + + +USE master +GO + +DROP DATABASE db1; +GO + +DROP DATABASE db2; +GO + +SELECT set_config('role', 'jdbc_user', false); +GO +~~START~~ +text +jdbc_user +~~END~~ + + +-- Reset migration mode to default +DECLARE @mig_mode VARCHAR(10) +SET @mig_mode = (SELECT mig_mode FROM babelfish_migration_mode_table WHERE id_num = 1) +SELECT CASE WHEN (SELECT set_config('babelfishpg_tsql.migration_mode', @mig_mode, false)) IS NOT NULL THEN 1 ELSE 0 END +GO +~~START~~ +int +1 +~~END~~ + + +SELECT name, object_name(t.system_type_id), principal_id, max_length, precision, scale , collation_name, is_nullable, is_user_defined, is_assembly_type, default_object_id, rule_object_id, is_table_type from sys.types t WHERE name = 'geometry' +go +~~START~~ +varchar#!#varchar#!#int#!#smallint#!#tinyint#!#tinyint#!#varchar#!#bit#!#bit#!#bit#!#int#!#int#!#bit +geometry#!#geometry#!##!#-1#!#0#!#0#!##!#1#!#0#!#1#!#0#!#0#!#0 +~~END~~ + + +SELECT name, object_name(t.system_type_id), principal_id, max_length, precision, scale , collation_name, is_nullable, is_user_defined, is_assembly_type, default_object_id, rule_object_id, is_table_type from sys.types t WHERE name = 'geography' +go +~~START~~ +varchar#!#varchar#!#int#!#smallint#!#tinyint#!#tinyint#!#varchar#!#bit#!#bit#!#bit#!#int#!#int#!#bit +geography#!#geography#!##!#-1#!#0#!#0#!##!#1#!#0#!#1#!#0#!#0#!#0 +~~END~~ + + +exec sp_sproc_columns_100 @procedure_name= 'geometry_proc_1' +GO +~~START~~ +varchar#!#varchar#!#nvarchar#!#varchar#!#smallint#!#smallint#!#varchar#!#int#!#int#!#smallint#!#smallint#!#smallint#!#varchar#!#nvarchar#!#smallint#!#smallint#!#int#!#int#!#varchar#!#tinyint +master#!#dbo#!#geometry_proc_1;1#!#@RETURN_VALUE#!#5#!#4#!#int#!#10#!#4#!#0#!#10#!#0#!##!##!#4#!##!##!#0#!#NO#!#56 +master#!#dbo#!#geometry_proc_1;1#!#@a#!#1#!#-151#!#geometry#!#0#!#-1#!#0#!##!#1#!##!##!#-151#!##!##!#1#!#YES#!#23 +master#!#dbo#!#geometry_proc_1;1#!#@b#!#1#!#12#!#varchar#!#0#!#8000#!#0#!##!#1#!##!##!#12#!##!##!#2#!#YES#!#39 +~~END~~ + + +exec sp_sproc_columns_100 @procedure_name= 'geography_proc_1' +GO +~~START~~ +varchar#!#varchar#!#nvarchar#!#varchar#!#smallint#!#smallint#!#varchar#!#int#!#int#!#smallint#!#smallint#!#smallint#!#varchar#!#nvarchar#!#smallint#!#smallint#!#int#!#int#!#varchar#!#tinyint +master#!#dbo#!#geography_proc_1;1#!#@RETURN_VALUE#!#5#!#4#!#int#!#10#!#4#!#0#!#10#!#0#!##!##!#4#!##!##!#0#!#NO#!#56 +master#!#dbo#!#geography_proc_1;1#!#@a#!#1#!#-151#!#geography#!#0#!#-1#!#0#!##!#1#!##!##!#-151#!##!##!#1#!#YES#!#23 +master#!#dbo#!#geography_proc_1;1#!#@b#!#1#!#12#!#varchar#!#0#!#8000#!#0#!##!#1#!##!##!#12#!##!##!#2#!#YES#!#39 +~~END~~ + + +select * from information_schema.columns where table_name = 'geo_view_test' +GO +~~START~~ +nvarchar#!#nvarchar#!#nvarchar#!#nvarchar#!#int#!#nvarchar#!#varchar#!#nvarchar#!#int#!#int#!#tinyint#!#smallint#!#int#!#smallint#!#nvarchar#!#nvarchar#!#nvarchar#!#nvarchar#!#nvarchar#!#nvarchar#!#nvarchar#!#nvarchar#!#nvarchar +master#!#dbo#!#geo_view_test#!#a#!#1#!##!#YES#!#geometry#!#-1#!#-1#!##!##!##!##!##!##!##!##!##!##!##!##!# +master#!#dbo#!#geo_view_test#!#b#!#2#!##!#YES#!#geography#!#-1#!#-1#!##!##!##!##!##!##!##!##!##!##!##!##!# +~~END~~ + + +select name , column_id , max_length , precision , scale , collation_name ,is_nullable , is_ansi_padded , is_rowguidcol , is_identity ,is_computed , is_filestream , is_replicated , is_non_sql_subscribed , is_merge_published , is_dts_replicated , is_xml_document , xml_collection_id , default_object_id , rule_object_id , is_sparse , is_column_set , generated_always_type , generated_always_type_desc , encryption_type , encryption_type_desc , encryption_algorithm_name , column_encryption_key_id , column_encryption_key_database_name , is_hidden , is_masked , graph_type , graph_type_desc from sys.columns where object_id = object_id('geo_view_test') ORDER BY name; +GO +~~START~~ +varchar#!#int#!#smallint#!#tinyint#!#tinyint#!#varchar#!#bit#!#bit#!#bit#!#bit#!#bit#!#bit#!#bit#!#bit#!#bit#!#bit#!#bit#!#int#!#int#!#int#!#bit#!#bit#!#tinyint#!#nvarchar#!#int#!#nvarchar#!#varchar#!#int#!#varchar#!#bit#!#bit#!#int#!#nvarchar +a#!#1#!#-1#!#0#!#0#!##!#1#!#0#!#0#!#0#!#0#!#0#!#0#!#0#!#0#!#0#!#0#!#0#!#0#!#0#!#0#!#0#!#0#!#NOT_APPLICABLE#!##!##!##!##!##!#0#!#0#!##!# +b#!#2#!#-1#!#0#!#0#!##!#1#!#0#!#0#!#0#!#0#!#0#!#0#!#0#!#0#!#0#!#0#!#0#!#0#!#0#!#0#!#0#!#0#!#NOT_APPLICABLE#!##!##!##!##!##!#0#!#0#!##!# ~~END~~ diff --git a/test/JDBC/expected/TestTvp.out b/test/JDBC/expected/TestTvp.out index 91df4b3de23..65f9395d948 100644 --- a/test/JDBC/expected/TestTvp.out +++ b/test/JDBC/expected/TestTvp.out @@ -1,12 +1,45 @@ create type tableType as table (a int, b smallint) create type table_variable_vu_type as table (a text not null, b int primary key, c int, d int) create proc table_variable_vu_proc1 (@x table_variable_vu_type readonly) as begin select tvp.b from @x tvp end + prepst#!#Select * from ? #!#tvp|-|tableType|-|utils/tvp-dotnet.csv|-|utils/tvp-dotnet.csv ~~START~~ int#!#smallint 1#!#1 ~~END~~ +prepst#!#Select * from ? #!#tvp|-|tableType|-|utils/tvp-dotnet.csv|-|utils/tvp-dotnet.csv +~~START~~ +int#!#smallint +1#!#1 +~~END~~ + +prepst#!#Select * from ? #!#tvp|-|tableType|-|utils/tvp-dotnet.csv|-|utils/tvp-dotnet.csv +~~START~~ +int#!#smallint +1#!#1 +~~END~~ + +prepst#!#Select * from ? #!#tvp|-|tableType|-|utils/tvp-dotnet.csv|-|utils/tvp-dotnet.csv +~~START~~ +int#!#smallint +1#!#1 +~~END~~ + +prepst#!#Select * from ? #!#tvp|-|tableType|-|utils/tvp-dotnet.csv|-|utils/tvp-dotnet.csv +~~START~~ +int#!#smallint +1#!#1 +~~END~~ + +prepst#!#Select * from ? #!#tvp|-|tableType|-|utils/tvp-dotnet.csv|-|utils/tvp-dotnet.csv +~~START~~ +int#!#smallint +1#!#1 +~~END~~ + + + declare @var1 table_variable_vu_type insert into @var1 values ('1', 2, 3, 4) exec sp_executesql N'EXEC table_variable_vu_proc1 @x = @p0', N'@p0 table_variable_vu_type readonly', @p0=@var1 ~~ROW COUNT: 1~~ diff --git a/test/JDBC/expected/babel_typecode.out b/test/JDBC/expected/babel_typecode.out index f12584fbff1..9bd049143a1 100644 --- a/test/JDBC/expected/babel_typecode.out +++ b/test/JDBC/expected/babel_typecode.out @@ -37,5 +37,7 @@ sys#!#sysname#!#sysname#!#5#!#31#!#5 sys#!#rowversion#!#timestamp#!#8#!#32#!#3 sys#!#timestamp#!#timestamp#!#8#!#33#!#3 sys#!#vector#!#vector#!#9#!#34#!#3 +sys#!#geometry#!#geometry#!#5#!#34#!#1 +sys#!#geography#!#geography#!#5#!#35#!#1 ~~END~~ diff --git a/test/JDBC/expected/forjsonauto-vu-cleanup.out b/test/JDBC/expected/forjsonauto-vu-cleanup.out index deafc10a834..e75fb46e409 100644 --- a/test/JDBC/expected/forjsonauto-vu-cleanup.out +++ b/test/JDBC/expected/forjsonauto-vu-cleanup.out @@ -55,6 +55,35 @@ GO DROP PROCEDURE forjson_vu_p_5 GO +DROP PROCEDURE forjson_vu_p_6 +GO + +DROP PROCEDURE forjson_vu_p_7 +GO + +DROP PROCEDURE forjson_vu_p_8 +GO + +DROP PROCEDURE forjson_vu_p_9 +GO + +DROP PROCEDURE forjson_vu_p_10 +GO + +DROP PROCEDURE forjson_vu_p_11 +GO + +DROP PROCEDURE forjson_vu_p_12 +GO + +DROP PROCEDURE forjson_vu_p_13 +GO + +DROP PROCEDURE forjson_vu_p_14 +GO + +DROP PROCEDURE forjson_vu_p_15 +GO DROP FUNCTION forjson_vu_f_1() GO diff --git a/test/JDBC/expected/forjsonauto-vu-prepare.out b/test/JDBC/expected/forjsonauto-vu-prepare.out index e310e292711..393f2ce002f 100644 --- a/test/JDBC/expected/forjsonauto-vu-prepare.out +++ b/test/JDBC/expected/forjsonauto-vu-prepare.out @@ -195,3 +195,79 @@ begin end; go +CREATE PROCEDURE forjson_vu_p_6 AS +BEGIN + select top 10 U.id, U.firstname, (select O.productId from forjson_auto_vu_t_orders O where O.userid = U.id for json auto) as details from forjson_auto_vu_t_users U for json auto +END +GO + +CREATE PROCEDURE forjson_vu_p_7 AS +BEGIN + select * from forjson_auto_vu_t_users U where + U.id = (SELECT MAX(O.userid) from forjson_auto_vu_t_orders O) + for json auto +END +GO + +CREATE PROCEDURE forjson_vu_p_8 AS +BEGIN + select * from forjson_auto_vu_t_users U where + U.id = (SELECT MAX(O.userid) from forjson_auto_vu_t_orders O for json auto) + for json auto +END +GO + +CREATE PROCEDURE forjson_vu_p_9 AS +BEGIN + select distinct top 10 + U.id, + (select distinct O.productId from forjson_auto_vu_t_orders O where O.userid = U.id) + as details + from forjson_auto_vu_t_users U + group by U.id + for json auto +END +GO + +CREATE PROCEDURE forjson_vu_p_10 AS +BEGIN + select distinct top 2 + U.Id, + O.orderdate + from forjson_auto_vu_t_users U INNER JOIN + forjson_auto_vu_t_orders O ON U.Id = O.Id + for json auto +END +GO + +CREATE PROCEDURE forjson_vu_p_11 AS +BEGIN + select distinct top 10 U.id, (select distinct O.productId from forjson_auto_vu_t_orders O where O.userid = U.id for json auto) as details from forjson_auto_vu_t_users U group by U.id for json auto +END +GO + +CREATE PROCEDURE forjson_vu_p_12 AS +BEGIN + select U.id, U.firstname, (select U.lastname, O.productId from forjson_auto_vu_t_orders O where O.userid = U.id for json auto) as details from forjson_auto_vu_t_users U for json auto +END +GO + +CREATE PROCEDURE forjson_vu_p_13 AS +BEGIN + select * from forjson_auto_vu_t_users U where U.Id = (SELECT MAX(O.userid) from forjson_auto_vu_t_orders O) for json auto +END +GO + +CREATE PROCEDURE forjson_vu_p_14 AS +BEGIN + select U.id, U.firstname, (select P.price, O.productId from forjson_auto_vu_t_orders O JOIN forjson_auto_vu_t_products P ON (P.id = O.productid) for json auto) as "details" from forjson_auto_vu_t_users U for json auto +END +GO + +CREATE PROCEDURE forjson_vu_p_15 AS + BEGIN + DECLARE @json_string NVARCHAR(2000) + SET @json_string = (select P.price, O.productId from forjson_auto_vu_t_orders O JOIN forjson_auto_vu_t_products P ON (P.id = O.productid) for json auto) + select U.id, U.firstname, @json_string as details from forjson_auto_vu_t_users U for json auto +END +GO diff --git a/test/JDBC/expected/forjsonauto-vu-verify.out b/test/JDBC/expected/forjsonauto-vu-verify.out index b907571f440..08cfb7aeab4 100644 --- a/test/JDBC/expected/forjsonauto-vu-verify.out +++ b/test/JDBC/expected/forjsonauto-vu-verify.out @@ -150,7 +150,88 @@ EXECUTE forjson_vu_p_5 GO ~~ERROR (Code: 33557097)~~ -~~ERROR (Message: Values for json auto is not currently supported )~~ +~~ERROR (Message: sub-select and values for json auto are not currently supported.)~~ + + +EXECUTE forjson_vu_p_6 +GO +~~START~~ +nvarchar +[{"id": 1, "firstname": "j", "details": {"productId": 1}}, {"id": 1, "firstname": "e", "details": {"productId": 1}}] +~~END~~ + + +EXECUTE forjson_vu_p_7 +GO +~~START~~ +nvarchar +[{"Id": 1, "firstname": "j", "lastname": "o", "email": "testemail"}, {"Id": 1, "firstname": "e", "lastname": "l", "email": "testemail2"}] +~~END~~ + + +EXECUTE forjson_vu_p_8 +GO +~~START~~ +nvarchar +~~ERROR (Code: 33557097)~~ + +~~ERROR (Message: sub-select and values for json auto are not currently supported.)~~ + + +EXECUTE forjson_vu_p_9 +GO +~~START~~ +nvarchar +[{"id": 1, "details": 1}] +~~END~~ + + +EXECUTE forjson_vu_p_10 +GO +~~START~~ +nvarchar +[{"Id": 1, "o": [{"orderdate": "2023-06-25"}]}] +~~END~~ + + +EXECUTE forjson_vu_p_11 +GO +~~START~~ +nvarchar +[{"id": 1, "details": {"productId": 1}}] +~~END~~ + + +EXECUTE forjson_vu_p_12 +GO +~~START~~ +nvarchar +[{"id": 1, "firstname": "j", "details": {"lastname": "o", "productId": 1}}, {"id": 1, "firstname": "e", "details": {"lastname": "l", "productId": 1}}] +~~END~~ + + +EXECUTE forjson_vu_p_13 +GO +~~START~~ +nvarchar +[{"Id": 1, "firstname": "j", "lastname": "o", "email": "testemail"}, {"Id": 1, "firstname": "e", "lastname": "l", "email": "testemail2"}] +~~END~~ + + +EXECUTE forjson_vu_p_14 +GO +~~START~~ +nvarchar +[{"id": 1, "firstname": "j", "details": {"o": [{"productId": 1}, {"productId": 1}], "price": "30"}}, {"id": 1, "firstname": "e", "details": {"o": [{"productId": 1}, {"productId": 1}], "price": "30"}}] +~~END~~ + + +EXECUTE forjson_vu_p_15 +GO +~~START~~ +nvarchar +[{"id": 1, "firstname": "j", "details": "[{\"price\": \"30\", \"o\": [{\"productId\": 1}, {\"productId\": 1}]}, {\"price\": \"20\", \"o\": [{\"productId\": 1}, {\"productId\": 1}]}]"}, {"id": 1, "firstname": "e", "details": "[{\"price\": \"30\", \"o\": [{\"productId\": 1}, {\"productId\": 1}]}, {\"price\": \"20\", \"o\": [{\"productId\": 1}, {\"productId\": 1}]}]"}] +~~END~~ SELECT forjson_vu_f_1() diff --git a/test/JDBC/expected/latest__verification_cleanup__13_5__sys-assembly_types-vu-verify.out b/test/JDBC/expected/latest__verification_cleanup__13_5__sys-assembly_types-vu-verify.out index 29afd1b3329..14c384dd6bf 100644 --- a/test/JDBC/expected/latest__verification_cleanup__13_5__sys-assembly_types-vu-verify.out +++ b/test/JDBC/expected/latest__verification_cleanup__13_5__sys-assembly_types-vu-verify.out @@ -8,7 +8,9 @@ int#!#varchar EXEC sys_assembly_types_proc_vu_prepare GO ~~START~~ -varchar#!#int#!#int#!#int#!#int#!#smallint#!#tinyint#!#tinyint#!#varchar#!#bit#!#bit#!#bit#!#int#!#int#!#int#!#varchar#!#bit#!#bit#!#nvarchar#!#nvarchar#!#bit +varchar#!#int#!#smallint#!#tinyint#!#tinyint#!#varchar#!#bit#!#bit#!#bit#!#int#!#int#!#int#!#varchar#!#bit#!#bit#!#nvarchar#!#nvarchar#!#bit +geometry#!##!#-1#!#0#!#0#!##!#1#!#0#!#1#!#0#!#0#!##!##!##!##!##!##!#0 +geography#!##!#-1#!#0#!#0#!##!#1#!#0#!#1#!#0#!#0#!##!##!##!##!##!##!#0 ~~END~~ @@ -16,14 +18,16 @@ SELECT * FROM sys_assembly_types_func_vu_prepare() GO ~~START~~ int -0 +2 ~~END~~ -- Test from sys-assembly_types.sql -SELECT * FROM sys.assembly_types +SELECT name, principal_id, max_length, precision, scale, collation_name, is_nullable, is_user_defined, is_assembly_type, default_object_id, rule_object_id, assembly_id, assembly_class, is_binary_ordered, is_fixed_length, prog_id, assembly_qualified_name, is_table_type FROM sys.assembly_types GO ~~START~~ -varchar#!#int#!#int#!#int#!#int#!#smallint#!#tinyint#!#tinyint#!#varchar#!#bit#!#bit#!#bit#!#int#!#int#!#int#!#varchar#!#bit#!#bit#!#nvarchar#!#nvarchar#!#bit +varchar#!#int#!#smallint#!#tinyint#!#tinyint#!#varchar#!#bit#!#bit#!#bit#!#int#!#int#!#int#!#varchar#!#bit#!#bit#!#nvarchar#!#nvarchar#!#bit +geometry#!##!#-1#!#0#!#0#!##!#1#!#0#!#1#!#0#!#0#!##!##!##!##!##!##!#0 +geography#!##!#-1#!#0#!#0#!##!#1#!#0#!#1#!#0#!#0#!##!##!##!##!##!##!#0 ~~END~~ diff --git a/test/JDBC/expected/latest__verification_cleanup__13_6__sys-assembly_types-vu-verify.out b/test/JDBC/expected/latest__verification_cleanup__13_6__sys-assembly_types-vu-verify.out index 29afd1b3329..14c384dd6bf 100644 --- a/test/JDBC/expected/latest__verification_cleanup__13_6__sys-assembly_types-vu-verify.out +++ b/test/JDBC/expected/latest__verification_cleanup__13_6__sys-assembly_types-vu-verify.out @@ -8,7 +8,9 @@ int#!#varchar EXEC sys_assembly_types_proc_vu_prepare GO ~~START~~ -varchar#!#int#!#int#!#int#!#int#!#smallint#!#tinyint#!#tinyint#!#varchar#!#bit#!#bit#!#bit#!#int#!#int#!#int#!#varchar#!#bit#!#bit#!#nvarchar#!#nvarchar#!#bit +varchar#!#int#!#smallint#!#tinyint#!#tinyint#!#varchar#!#bit#!#bit#!#bit#!#int#!#int#!#int#!#varchar#!#bit#!#bit#!#nvarchar#!#nvarchar#!#bit +geometry#!##!#-1#!#0#!#0#!##!#1#!#0#!#1#!#0#!#0#!##!##!##!##!##!##!#0 +geography#!##!#-1#!#0#!#0#!##!#1#!#0#!#1#!#0#!#0#!##!##!##!##!##!##!#0 ~~END~~ @@ -16,14 +18,16 @@ SELECT * FROM sys_assembly_types_func_vu_prepare() GO ~~START~~ int -0 +2 ~~END~~ -- Test from sys-assembly_types.sql -SELECT * FROM sys.assembly_types +SELECT name, principal_id, max_length, precision, scale, collation_name, is_nullable, is_user_defined, is_assembly_type, default_object_id, rule_object_id, assembly_id, assembly_class, is_binary_ordered, is_fixed_length, prog_id, assembly_qualified_name, is_table_type FROM sys.assembly_types GO ~~START~~ -varchar#!#int#!#int#!#int#!#int#!#smallint#!#tinyint#!#tinyint#!#varchar#!#bit#!#bit#!#bit#!#int#!#int#!#int#!#varchar#!#bit#!#bit#!#nvarchar#!#nvarchar#!#bit +varchar#!#int#!#smallint#!#tinyint#!#tinyint#!#varchar#!#bit#!#bit#!#bit#!#int#!#int#!#int#!#varchar#!#bit#!#bit#!#nvarchar#!#nvarchar#!#bit +geometry#!##!#-1#!#0#!#0#!##!#1#!#0#!#1#!#0#!#0#!##!##!##!##!##!##!#0 +geography#!##!#-1#!#0#!#0#!##!#1#!#0#!#1#!#0#!#0#!##!##!##!##!##!##!#0 ~~END~~ diff --git a/test/JDBC/expected/latest__verification_cleanup__13_7__sys-assembly_types-vu-verify.out b/test/JDBC/expected/latest__verification_cleanup__13_7__sys-assembly_types-vu-verify.out index 29afd1b3329..14c384dd6bf 100644 --- a/test/JDBC/expected/latest__verification_cleanup__13_7__sys-assembly_types-vu-verify.out +++ b/test/JDBC/expected/latest__verification_cleanup__13_7__sys-assembly_types-vu-verify.out @@ -8,7 +8,9 @@ int#!#varchar EXEC sys_assembly_types_proc_vu_prepare GO ~~START~~ -varchar#!#int#!#int#!#int#!#int#!#smallint#!#tinyint#!#tinyint#!#varchar#!#bit#!#bit#!#bit#!#int#!#int#!#int#!#varchar#!#bit#!#bit#!#nvarchar#!#nvarchar#!#bit +varchar#!#int#!#smallint#!#tinyint#!#tinyint#!#varchar#!#bit#!#bit#!#bit#!#int#!#int#!#int#!#varchar#!#bit#!#bit#!#nvarchar#!#nvarchar#!#bit +geometry#!##!#-1#!#0#!#0#!##!#1#!#0#!#1#!#0#!#0#!##!##!##!##!##!##!#0 +geography#!##!#-1#!#0#!#0#!##!#1#!#0#!#1#!#0#!#0#!##!##!##!##!##!##!#0 ~~END~~ @@ -16,14 +18,16 @@ SELECT * FROM sys_assembly_types_func_vu_prepare() GO ~~START~~ int -0 +2 ~~END~~ -- Test from sys-assembly_types.sql -SELECT * FROM sys.assembly_types +SELECT name, principal_id, max_length, precision, scale, collation_name, is_nullable, is_user_defined, is_assembly_type, default_object_id, rule_object_id, assembly_id, assembly_class, is_binary_ordered, is_fixed_length, prog_id, assembly_qualified_name, is_table_type FROM sys.assembly_types GO ~~START~~ -varchar#!#int#!#int#!#int#!#int#!#smallint#!#tinyint#!#tinyint#!#varchar#!#bit#!#bit#!#bit#!#int#!#int#!#int#!#varchar#!#bit#!#bit#!#nvarchar#!#nvarchar#!#bit +varchar#!#int#!#smallint#!#tinyint#!#tinyint#!#varchar#!#bit#!#bit#!#bit#!#int#!#int#!#int#!#varchar#!#bit#!#bit#!#nvarchar#!#nvarchar#!#bit +geometry#!##!#-1#!#0#!#0#!##!#1#!#0#!#1#!#0#!#0#!##!##!##!##!##!##!#0 +geography#!##!#-1#!#0#!#0#!##!#1#!#0#!#1#!#0#!#0#!##!##!##!##!##!##!#0 ~~END~~ diff --git a/test/JDBC/expected/latest__verification_cleanup__13_8__sys-assembly_types-vu-verify.out b/test/JDBC/expected/latest__verification_cleanup__13_8__sys-assembly_types-vu-verify.out index 29afd1b3329..14c384dd6bf 100644 --- a/test/JDBC/expected/latest__verification_cleanup__13_8__sys-assembly_types-vu-verify.out +++ b/test/JDBC/expected/latest__verification_cleanup__13_8__sys-assembly_types-vu-verify.out @@ -8,7 +8,9 @@ int#!#varchar EXEC sys_assembly_types_proc_vu_prepare GO ~~START~~ -varchar#!#int#!#int#!#int#!#int#!#smallint#!#tinyint#!#tinyint#!#varchar#!#bit#!#bit#!#bit#!#int#!#int#!#int#!#varchar#!#bit#!#bit#!#nvarchar#!#nvarchar#!#bit +varchar#!#int#!#smallint#!#tinyint#!#tinyint#!#varchar#!#bit#!#bit#!#bit#!#int#!#int#!#int#!#varchar#!#bit#!#bit#!#nvarchar#!#nvarchar#!#bit +geometry#!##!#-1#!#0#!#0#!##!#1#!#0#!#1#!#0#!#0#!##!##!##!##!##!##!#0 +geography#!##!#-1#!#0#!#0#!##!#1#!#0#!#1#!#0#!#0#!##!##!##!##!##!##!#0 ~~END~~ @@ -16,14 +18,16 @@ SELECT * FROM sys_assembly_types_func_vu_prepare() GO ~~START~~ int -0 +2 ~~END~~ -- Test from sys-assembly_types.sql -SELECT * FROM sys.assembly_types +SELECT name, principal_id, max_length, precision, scale, collation_name, is_nullable, is_user_defined, is_assembly_type, default_object_id, rule_object_id, assembly_id, assembly_class, is_binary_ordered, is_fixed_length, prog_id, assembly_qualified_name, is_table_type FROM sys.assembly_types GO ~~START~~ -varchar#!#int#!#int#!#int#!#int#!#smallint#!#tinyint#!#tinyint#!#varchar#!#bit#!#bit#!#bit#!#int#!#int#!#int#!#varchar#!#bit#!#bit#!#nvarchar#!#nvarchar#!#bit +varchar#!#int#!#smallint#!#tinyint#!#tinyint#!#varchar#!#bit#!#bit#!#bit#!#int#!#int#!#int#!#varchar#!#bit#!#bit#!#nvarchar#!#nvarchar#!#bit +geometry#!##!#-1#!#0#!#0#!##!#1#!#0#!#1#!#0#!#0#!##!##!##!##!##!##!#0 +geography#!##!#-1#!#0#!#0#!##!#1#!#0#!#1#!#0#!#0#!##!##!##!##!##!##!#0 ~~END~~ diff --git a/test/JDBC/expected/latest__verification_cleanup__13_9__sys-assembly_types-vu-verify.out b/test/JDBC/expected/latest__verification_cleanup__13_9__sys-assembly_types-vu-verify.out index 29afd1b3329..14c384dd6bf 100644 --- a/test/JDBC/expected/latest__verification_cleanup__13_9__sys-assembly_types-vu-verify.out +++ b/test/JDBC/expected/latest__verification_cleanup__13_9__sys-assembly_types-vu-verify.out @@ -8,7 +8,9 @@ int#!#varchar EXEC sys_assembly_types_proc_vu_prepare GO ~~START~~ -varchar#!#int#!#int#!#int#!#int#!#smallint#!#tinyint#!#tinyint#!#varchar#!#bit#!#bit#!#bit#!#int#!#int#!#int#!#varchar#!#bit#!#bit#!#nvarchar#!#nvarchar#!#bit +varchar#!#int#!#smallint#!#tinyint#!#tinyint#!#varchar#!#bit#!#bit#!#bit#!#int#!#int#!#int#!#varchar#!#bit#!#bit#!#nvarchar#!#nvarchar#!#bit +geometry#!##!#-1#!#0#!#0#!##!#1#!#0#!#1#!#0#!#0#!##!##!##!##!##!##!#0 +geography#!##!#-1#!#0#!#0#!##!#1#!#0#!#1#!#0#!#0#!##!##!##!##!##!##!#0 ~~END~~ @@ -16,14 +18,16 @@ SELECT * FROM sys_assembly_types_func_vu_prepare() GO ~~START~~ int -0 +2 ~~END~~ -- Test from sys-assembly_types.sql -SELECT * FROM sys.assembly_types +SELECT name, principal_id, max_length, precision, scale, collation_name, is_nullable, is_user_defined, is_assembly_type, default_object_id, rule_object_id, assembly_id, assembly_class, is_binary_ordered, is_fixed_length, prog_id, assembly_qualified_name, is_table_type FROM sys.assembly_types GO ~~START~~ -varchar#!#int#!#int#!#int#!#int#!#smallint#!#tinyint#!#tinyint#!#varchar#!#bit#!#bit#!#bit#!#int#!#int#!#int#!#varchar#!#bit#!#bit#!#nvarchar#!#nvarchar#!#bit +varchar#!#int#!#smallint#!#tinyint#!#tinyint#!#varchar#!#bit#!#bit#!#bit#!#int#!#int#!#int#!#varchar#!#bit#!#bit#!#nvarchar#!#nvarchar#!#bit +geometry#!##!#-1#!#0#!#0#!##!#1#!#0#!#1#!#0#!#0#!##!##!##!##!##!##!#0 +geography#!##!#-1#!#0#!#0#!##!#1#!#0#!#1#!#0#!#0#!##!##!##!##!##!##!#0 ~~END~~ diff --git a/test/JDBC/expected/latest__verification_cleanup__14_3__sys-assembly_types-vu-verify.out b/test/JDBC/expected/latest__verification_cleanup__14_3__sys-assembly_types-vu-verify.out index 29afd1b3329..14c384dd6bf 100644 --- a/test/JDBC/expected/latest__verification_cleanup__14_3__sys-assembly_types-vu-verify.out +++ b/test/JDBC/expected/latest__verification_cleanup__14_3__sys-assembly_types-vu-verify.out @@ -8,7 +8,9 @@ int#!#varchar EXEC sys_assembly_types_proc_vu_prepare GO ~~START~~ -varchar#!#int#!#int#!#int#!#int#!#smallint#!#tinyint#!#tinyint#!#varchar#!#bit#!#bit#!#bit#!#int#!#int#!#int#!#varchar#!#bit#!#bit#!#nvarchar#!#nvarchar#!#bit +varchar#!#int#!#smallint#!#tinyint#!#tinyint#!#varchar#!#bit#!#bit#!#bit#!#int#!#int#!#int#!#varchar#!#bit#!#bit#!#nvarchar#!#nvarchar#!#bit +geometry#!##!#-1#!#0#!#0#!##!#1#!#0#!#1#!#0#!#0#!##!##!##!##!##!##!#0 +geography#!##!#-1#!#0#!#0#!##!#1#!#0#!#1#!#0#!#0#!##!##!##!##!##!##!#0 ~~END~~ @@ -16,14 +18,16 @@ SELECT * FROM sys_assembly_types_func_vu_prepare() GO ~~START~~ int -0 +2 ~~END~~ -- Test from sys-assembly_types.sql -SELECT * FROM sys.assembly_types +SELECT name, principal_id, max_length, precision, scale, collation_name, is_nullable, is_user_defined, is_assembly_type, default_object_id, rule_object_id, assembly_id, assembly_class, is_binary_ordered, is_fixed_length, prog_id, assembly_qualified_name, is_table_type FROM sys.assembly_types GO ~~START~~ -varchar#!#int#!#int#!#int#!#int#!#smallint#!#tinyint#!#tinyint#!#varchar#!#bit#!#bit#!#bit#!#int#!#int#!#int#!#varchar#!#bit#!#bit#!#nvarchar#!#nvarchar#!#bit +varchar#!#int#!#smallint#!#tinyint#!#tinyint#!#varchar#!#bit#!#bit#!#bit#!#int#!#int#!#int#!#varchar#!#bit#!#bit#!#nvarchar#!#nvarchar#!#bit +geometry#!##!#-1#!#0#!#0#!##!#1#!#0#!#1#!#0#!#0#!##!##!##!##!##!##!#0 +geography#!##!#-1#!#0#!#0#!##!#1#!#0#!#1#!#0#!#0#!##!##!##!##!##!##!#0 ~~END~~ diff --git a/test/JDBC/expected/latest__verification_cleanup__14_3__sys-types-vu-verify.out b/test/JDBC/expected/latest__verification_cleanup__14_3__sys-types-vu-verify.out index cb98c5701c9..c836855bdd9 100644 --- a/test/JDBC/expected/latest__verification_cleanup__14_3__sys-types-vu-verify.out +++ b/test/JDBC/expected/latest__verification_cleanup__14_3__sys-types-vu-verify.out @@ -17,6 +17,8 @@ datetime2#!#8#!#26#!#6#!# datetimeoffset#!#10#!#33#!#6#!# decimal#!#17#!#38#!#38#!# float#!#8#!#53#!#0#!# +geography#!#-1#!#0#!#0#!# +geometry#!#-1#!#0#!#0#!# image#!#16#!#0#!#0#!# int#!#4#!#10#!#0#!# money#!#8#!#19#!#4#!# diff --git a/test/JDBC/expected/latest__verification_cleanup__14_5__sys-types-vu-verify.out b/test/JDBC/expected/latest__verification_cleanup__14_5__sys-types-vu-verify.out index cb98c5701c9..c836855bdd9 100644 --- a/test/JDBC/expected/latest__verification_cleanup__14_5__sys-types-vu-verify.out +++ b/test/JDBC/expected/latest__verification_cleanup__14_5__sys-types-vu-verify.out @@ -17,6 +17,8 @@ datetime2#!#8#!#26#!#6#!# datetimeoffset#!#10#!#33#!#6#!# decimal#!#17#!#38#!#38#!# float#!#8#!#53#!#0#!# +geography#!#-1#!#0#!#0#!# +geometry#!#-1#!#0#!#0#!# image#!#16#!#0#!#0#!# int#!#4#!#10#!#0#!# money#!#8#!#19#!#4#!# diff --git a/test/JDBC/expected/non_default_server_collation/chinese_prc_ci_as/latest__verification_cleanup__14_3__sys-types-vu-verify.out b/test/JDBC/expected/non_default_server_collation/chinese_prc_ci_as/latest__verification_cleanup__14_3__sys-types-vu-verify.out index ea365a79ef9..2a128337f17 100644 --- a/test/JDBC/expected/non_default_server_collation/chinese_prc_ci_as/latest__verification_cleanup__14_3__sys-types-vu-verify.out +++ b/test/JDBC/expected/non_default_server_collation/chinese_prc_ci_as/latest__verification_cleanup__14_3__sys-types-vu-verify.out @@ -17,6 +17,8 @@ datetime2#!#8#!#26#!#6#!# datetimeoffset#!#10#!#33#!#6#!# decimal#!#17#!#38#!#38#!# float#!#8#!#53#!#0#!# +geography#!#-1#!#0#!#0#!# +geometry#!#-1#!#0#!#0#!# image#!#16#!#0#!#0#!# int#!#4#!#10#!#0#!# money#!#8#!#19#!#4#!# diff --git a/test/JDBC/expected/non_default_server_collation/chinese_prc_ci_as/sys-systypes-vu-verify.out b/test/JDBC/expected/non_default_server_collation/chinese_prc_ci_as/sys-systypes-vu-verify.out index c65ded89d7a..dccd8906a31 100644 --- a/test/JDBC/expected/non_default_server_collation/chinese_prc_ci_as/sys-systypes-vu-verify.out +++ b/test/JDBC/expected/non_default_server_collation/chinese_prc_ci_as/sys-systypes-vu-verify.out @@ -16,6 +16,8 @@ datetime2#!#0#!#8#!#0#!#1#!##!# datetimeoffset#!#0#!#10#!#0#!#1#!##!# decimal#!#0#!#17#!#0#!#1#!##!# float#!#0#!#8#!#0#!#1#!##!# +geography#!#0#!#-1#!#0#!#1#!##!# +geometry#!#0#!#-1#!#0#!#1#!##!# image#!#0#!#16#!#0#!#1#!##!# int#!#0#!#4#!#0#!#1#!##!# money#!#0#!#8#!#0#!#1#!##!# diff --git a/test/JDBC/expected/non_default_server_collation/chinese_prc_ci_as/sys-types-vu-verify.out b/test/JDBC/expected/non_default_server_collation/chinese_prc_ci_as/sys-types-vu-verify.out index ea365a79ef9..2a128337f17 100644 --- a/test/JDBC/expected/non_default_server_collation/chinese_prc_ci_as/sys-types-vu-verify.out +++ b/test/JDBC/expected/non_default_server_collation/chinese_prc_ci_as/sys-types-vu-verify.out @@ -17,6 +17,8 @@ datetime2#!#8#!#26#!#6#!# datetimeoffset#!#10#!#33#!#6#!# decimal#!#17#!#38#!#38#!# float#!#8#!#53#!#0#!# +geography#!#-1#!#0#!#0#!# +geometry#!#-1#!#0#!#0#!# image#!#16#!#0#!#0#!# int#!#4#!#10#!#0#!# money#!#8#!#19#!#4#!# diff --git a/test/JDBC/expected/non_default_server_collation/chinese_prc_ci_as/sys-types.out b/test/JDBC/expected/non_default_server_collation/chinese_prc_ci_as/sys-types.out index 5d62d3dc1b7..e7107e123d3 100644 --- a/test/JDBC/expected/non_default_server_collation/chinese_prc_ci_as/sys-types.out +++ b/test/JDBC/expected/non_default_server_collation/chinese_prc_ci_as/sys-types.out @@ -17,6 +17,8 @@ datetime2#!#8#!#26#!#6#!# datetimeoffset#!#10#!#33#!#6#!# decimal#!#17#!#38#!#38#!# float#!#8#!#53#!#0#!# +geography#!#-1#!#0#!#0#!# +geometry#!#-1#!#0#!#0#!# image#!#16#!#0#!#0#!# int#!#4#!#10#!#0#!# money#!#8#!#19#!#4#!# diff --git a/test/JDBC/expected/non_default_server_collation/japanese_ci_as/sys-types-vu-verify.out b/test/JDBC/expected/non_default_server_collation/japanese_ci_as/sys-types-vu-verify.out index a9e42e5e130..8bb25726ab6 100644 --- a/test/JDBC/expected/non_default_server_collation/japanese_ci_as/sys-types-vu-verify.out +++ b/test/JDBC/expected/non_default_server_collation/japanese_ci_as/sys-types-vu-verify.out @@ -17,6 +17,8 @@ datetime2#!#8#!#26#!#6#!# datetimeoffset#!#10#!#33#!#6#!# decimal#!#17#!#38#!#38#!# float#!#8#!#53#!#0#!# +geography#!#-1#!#0#!#0#!# +geometry#!#-1#!#0#!#0#!# image#!#16#!#0#!#0#!# int#!#4#!#10#!#0#!# money#!#8#!#19#!#4#!# diff --git a/test/JDBC/expected/operator_atatvar-vu-cleanup.out b/test/JDBC/expected/operator_atatvar-vu-cleanup.out index a293980220a..c7fbcaf5df5 100644 --- a/test/JDBC/expected/operator_atatvar-vu-cleanup.out +++ b/test/JDBC/expected/operator_atatvar-vu-cleanup.out @@ -1,6 +1,9 @@ drop view v1_operator_atatvar go +drop view v2_operator_atatvar +go + drop procedure p1_operator_atatvar go @@ -9,3 +12,9 @@ go drop procedure p3_operator_atatvar go + +drop function f1_operator_atatvar +go + +drop function f2_operator_atatvar +go diff --git a/test/JDBC/expected/operator_atatvar-vu-prepare.out b/test/JDBC/expected/operator_atatvar-vu-prepare.out index 5d69e385e48..296bbba1479 100644 --- a/test/JDBC/expected/operator_atatvar-vu-prepare.out +++ b/test/JDBC/expected/operator_atatvar-vu-prepare.out @@ -2,6 +2,10 @@ create view v1_operator_atatvar as select c=@@max_precision where 0! =@@max_precision go +create view v2_operator_atatvar as +select c=@@max_precision where 0=@@max_precision +go + create procedure p1_operator_atatvar as if 1=@@max_precision select 'yes' else select 'no' @@ -29,3 +33,16 @@ create procedure p3_operator_atatvar @p int as select @p go + +create function f1_operator_atatvar(@p int) returns int +as +begin + if @p=@@spid return 1 + else return 0 +end +go + +create function f2_operator_atatvar(@p int) returns table +as + return select 1 as c where @p=@@max_precision +go diff --git a/test/JDBC/expected/operator_atatvar-vu-verify.out b/test/JDBC/expected/operator_atatvar-vu-verify.out index 7ea5e18fcdf..3cf25f4a827 100644 --- a/test/JDBC/expected/operator_atatvar-vu-verify.out +++ b/test/JDBC/expected/operator_atatvar-vu-verify.out @@ -317,6 +317,20 @@ tinyint ~~END~~ +select * from v2_operator_atatvar where 0!<@@max_precision +go +~~START~~ +tinyint +~~END~~ + + +select * from v2_operator_atatvar where case when 1!=@@max_precision then 1 else @@max_precision end=@@max_precision +go +~~START~~ +tinyint +~~END~~ + + declare @v int set @v=1 set @v+=@v @@ -378,3 +392,33 @@ int ~~END~~ +select dbo.f1_operator_atatvar(@@spid) +go +~~START~~ +int +1 +~~END~~ + + +select dbo.f1_operator_atatvar(@@spid-1) +go +~~START~~ +int +0 +~~END~~ + + +select * from dbo.f2_operator_atatvar(@@max_precision) +go +~~START~~ +int +1 +~~END~~ + + +select * from dbo.f2_operator_atatvar(@@max_precision-1) +go +~~START~~ +int +~~END~~ + diff --git a/test/JDBC/expected/order_by_offset_fetch_rows-before-15_6-or-16_2-vu-cleanup.out b/test/JDBC/expected/order_by_offset_fetch_rows-before-15_6-or-16_2-vu-cleanup.out new file mode 100644 index 00000000000..cd290408dcf --- /dev/null +++ b/test/JDBC/expected/order_by_offset_fetch_rows-before-15_6-or-16_2-vu-cleanup.out @@ -0,0 +1,8 @@ +DROP PROC p1_upgr_order_by_offset_fetch +go +DROP FUNCTION f1_upgr_order_by_offset_fetch +go +DROP VIEW v1_upgr_order_by_offset_fetch +go +DROP table t1_upgr_order_by_offset_fetch +go diff --git a/test/JDBC/expected/order_by_offset_fetch_rows-before-15_6-or-16_2-vu-prepare.out b/test/JDBC/expected/order_by_offset_fetch_rows-before-15_6-or-16_2-vu-prepare.out new file mode 100644 index 00000000000..9e6807a8257 --- /dev/null +++ b/test/JDBC/expected/order_by_offset_fetch_rows-before-15_6-or-16_2-vu-prepare.out @@ -0,0 +1,8 @@ +create table t1_upgr_order_by_offset_fetch(a int, b int) +go +CREATE PROC p1_upgr_order_by_offset_fetch @p int=1,@q int=1 AS SELECT * FROM t1_upgr_order_by_offset_fetch ORDER BY b OFFSET @p*@q ROWS FETCH NEXT square(@q)+1 ROWS ONLY +go +CREATE FUNCTION f1_upgr_order_by_offset_fetch(@p int, @q int) returns int as begin declare @v int SELECT @v=count(a) FROM t1_upgr_order_by_offset_fetch group by b ORDER BY b OFFSET @p*@q ROWS FETCH NEXT square(@q)+1 ROWS ONLY return @v end +go +CREATE VIEW v1_upgr_order_by_offset_fetch as select * FROM t1_upgr_order_by_offset_fetch ORDER BY b OFFSET 5 ROWS FETCH NEXT 3 rows only +go diff --git a/test/JDBC/expected/order_by_offset_fetch_rows-before-15_6-or-16_2-vu-verify.out b/test/JDBC/expected/order_by_offset_fetch_rows-before-15_6-or-16_2-vu-verify.out new file mode 100644 index 00000000000..88e2c4207ac --- /dev/null +++ b/test/JDBC/expected/order_by_offset_fetch_rows-before-15_6-or-16_2-vu-verify.out @@ -0,0 +1,73 @@ +insert t1_upgr_order_by_offset_fetch select generate_series, 0 from generate_series(1,100) +go +~~ROW COUNT: 100~~ + +update t1_upgr_order_by_offset_fetch set b=a +go +~~ROW COUNT: 100~~ + +exec p1_upgr_order_by_offset_fetch 1, 3 +go +~~START~~ +int#!#int +4#!#4 +5#!#5 +6#!#6 +7#!#7 +8#!#8 +9#!#9 +10#!#10 +11#!#11 +12#!#12 +13#!#13 +~~END~~ + +exec p1_upgr_order_by_offset_fetch 2, 3 +go +~~START~~ +int#!#int +7#!#7 +8#!#8 +9#!#9 +10#!#10 +11#!#11 +12#!#12 +13#!#13 +14#!#14 +15#!#15 +16#!#16 +~~END~~ + +p1_upgr_order_by_offset_fetch 3, 3 +go +~~START~~ +int#!#int +10#!#10 +11#!#11 +12#!#12 +13#!#13 +14#!#14 +15#!#15 +16#!#16 +17#!#17 +18#!#18 +19#!#19 +~~END~~ + +select dbo.f1_upgr_order_by_offset_fetch(1,1) +go +~~START~~ +int +1 +~~END~~ + +select * from v1_upgr_order_by_offset_fetch +go +~~START~~ +int#!#int +6#!#6 +7#!#7 +8#!#8 +~~END~~ + + diff --git a/test/JDBC/expected/order_by_offset_fetch_rows-vu-cleanup.out b/test/JDBC/expected/order_by_offset_fetch_rows-vu-cleanup.out new file mode 100644 index 00000000000..de82fbfa56f --- /dev/null +++ b/test/JDBC/expected/order_by_offset_fetch_rows-vu-cleanup.out @@ -0,0 +1,8 @@ +DROP PROC p1_order_by_offset_fetch +go +DROP FUNCTION f1_order_by_offset_fetch +go +DROP VIEW v1_order_by_offset_fetch +go +DROP table t1_order_by_offset_fetch +go diff --git a/test/JDBC/expected/order_by_offset_fetch_rows-vu-prepare.out b/test/JDBC/expected/order_by_offset_fetch_rows-vu-prepare.out new file mode 100644 index 00000000000..c7ad5f15567 --- /dev/null +++ b/test/JDBC/expected/order_by_offset_fetch_rows-vu-prepare.out @@ -0,0 +1,16 @@ +create table t1_order_by_offset_fetch(a int, b int) +go +insert t1_order_by_offset_fetch select generate_series, 0 from generate_series(1,100) +go +~~ROW COUNT: 100~~ + +update t1_order_by_offset_fetch set b=a +go +~~ROW COUNT: 100~~ + +CREATE PROC p1_order_by_offset_fetch @p int=1,@q int=1 AS SELECT * FROM t1_order_by_offset_fetch ORDER BY b OFFSET @p*@q ROWS FETCH NEXT square(@q)+1 ROWS ONLY +go +CREATE FUNCTION f1_order_by_offset_fetch(@p int, @q int) returns int as begin declare @v int SELECT @v=count(a) FROM t1_order_by_offset_fetch group by b ORDER BY b OFFSET @p*@q ROWS FETCH NEXT square(@q)+1 ROWS ONLY return @v end +go +CREATE VIEW v1_order_by_offset_fetch as select * FROM t1_order_by_offset_fetch ORDER BY b OFFSET 5 ROWS FETCH NEXT 3 rows only +go diff --git a/test/JDBC/expected/order_by_offset_fetch_rows-vu-verify.out b/test/JDBC/expected/order_by_offset_fetch_rows-vu-verify.out new file mode 100644 index 00000000000..2a69ad94377 --- /dev/null +++ b/test/JDBC/expected/order_by_offset_fetch_rows-vu-verify.out @@ -0,0 +1,390 @@ +declare @p int =2,@q int=3 SELECT * FROM t1_order_by_offset_fetch ORDER BY b OFFSET (@p*5) ROWS FETCH NEXT (5) ROWS ONLY +go +~~START~~ +int#!#int +11#!#11 +12#!#12 +13#!#13 +14#!#14 +15#!#15 +~~END~~ + +declare @p int =2,@q int=3 SELECT * FROM t1_order_by_offset_fetch ORDER BY b OFFSET (@p*5) ROW FETCH NEXT 5 ROW ONLY +go +~~START~~ +int#!#int +11#!#11 +12#!#12 +13#!#13 +14#!#14 +15#!#15 +~~END~~ + +declare @p int =2,@q int=3 SELECT * FROM t1_order_by_offset_fetch ORDER BY b OFFSET (@p*5) ROWS FETCH NEXT @q ROWS ONLY +go +~~START~~ +int#!#int +11#!#11 +12#!#12 +13#!#13 +~~END~~ + +declare @p int =2,@q int=3 SELECT * FROM t1_order_by_offset_fetch ORDER BY b OFFSET (@p*5) ROWS FETCH NEXT 1+2 ROWS ONLY +go +~~START~~ +int#!#int +11#!#11 +12#!#12 +13#!#13 +~~END~~ + +declare @p int =2,@q int=3 SELECT * FROM t1_order_by_offset_fetch ORDER BY b OFFSET (@p*5) ROWS FETCH NEXT (1+2) ROWS ONLY +go +~~START~~ +int#!#int +11#!#11 +12#!#12 +13#!#13 +~~END~~ + +declare @p int =2,@q int=3 SELECT * FROM t1_order_by_offset_fetch ORDER BY b OFFSET @p ROWS FETCH NEXT +3 ROWS ONLY +go +~~START~~ +int#!#int +3#!#3 +4#!#4 +5#!#5 +~~END~~ + +declare @p int =2,@q int=0 SELECT * FROM t1_order_by_offset_fetch ORDER BY b OFFSET @p ROWS FETCH NEXT @q ROWS ONLY +go +~~START~~ +int#!#int +~~END~~ + +declare @p int =0,@q int=1 SELECT * FROM t1_order_by_offset_fetch ORDER BY b OFFSET @p ROWS FETCH NEXT @q ROWS ONLY +go +~~START~~ +int#!#int +1#!#1 +~~END~~ + +declare @p int =2,@q int=3 SELECT * FROM t1_order_by_offset_fetch ORDER BY b OFFSET @p ROWS FETCH NEXT @q ROWS ONLY +go +~~START~~ +int#!#int +3#!#3 +4#!#4 +5#!#5 +~~END~~ + +declare @p int =2,@q int=3 SELECT * FROM t1_order_by_offset_fetch ORDER BY b OFFSET 1+1 ROWS FETCH NEXT 2 ROWS ONLY +go +~~START~~ +int#!#int +3#!#3 +4#!#4 +~~END~~ + +declare @p int =2,@q int=3 SELECT * FROM t1_order_by_offset_fetch ORDER BY b OFFSET 1+1 ROWS FETCH NEXT @q ROWS ONLY +go +~~START~~ +int#!#int +3#!#3 +4#!#4 +5#!#5 +~~END~~ + +declare @p int =2,@q int=0 SELECT * FROM t1_order_by_offset_fetch ORDER BY b OFFSET @p*1 ROWS FETCH NEXT @q ROWS ONLY +go +~~START~~ +int#!#int +~~END~~ + +declare @p int =2,@q int=1 SELECT * FROM t1_order_by_offset_fetch ORDER BY b OFFSET @p*1 ROWS FETCH NEXT @q ROWS ONLY +go +~~START~~ +int#!#int +3#!#3 +~~END~~ + +declare @p int =0,@q int=3 SELECT * FROM t1_order_by_offset_fetch ORDER BY b OFFSET @p*1 ROWS FETCH NEXT @q ROWS ONLY +go +~~START~~ +int#!#int +1#!#1 +2#!#2 +3#!#3 +~~END~~ + +declare @p int =1,@q int=3 SELECT * FROM t1_order_by_offset_fetch ORDER BY b OFFSET @p*1 ROWS FETCH NEXT @q ROWS ONLY +go +~~START~~ +int#!#int +2#!#2 +3#!#3 +4#!#4 +~~END~~ + +declare @p int =3,@q int=3 SELECT * FROM t1_order_by_offset_fetch ORDER BY b OFFSET @p+1 ROWS FETCH NEXT @q ROWS ONLY +go +~~START~~ +int#!#int +5#!#5 +6#!#6 +7#!#7 +~~END~~ + +declare @p int =3,@q int=3 SELECT * FROM t1_order_by_offset_fetch ORDER BY b OFFSET @p*2 ROWS FETCH NEXT @q ROWS ONLY +go +~~START~~ +int#!#int +7#!#7 +8#!#8 +9#!#9 +~~END~~ + +declare @p int =1,@q int=3 SELECT * FROM t1_order_by_offset_fetch ORDER BY b OFFSET @p*@q ROWS FETCH NEXT @q ROWS ONLY +go +~~START~~ +int#!#int +4#!#4 +5#!#5 +6#!#6 +~~END~~ + +declare @p int =2,@q int=3 SELECT * FROM t1_order_by_offset_fetch ORDER BY b OFFSET @p*@q ROWS FETCH NEXT @q ROWS ONLY +go +~~START~~ +int#!#int +7#!#7 +8#!#8 +9#!#9 +~~END~~ + +declare @p int=2,@q int=0 SELECT * FROM t1_order_by_offset_fetch ORDER BY b OFFSET @p*@q ROWS FETCH NEXT @q ROWS ONLY +go +~~START~~ +int#!#int +~~END~~ + +declare @p int=1,@q int=3 SELECT * FROM t1_order_by_offset_fetch ORDER BY b OFFSET @p*@q ROWS FETCH NEXT @q ROWS ONLY +go +~~START~~ +int#!#int +4#!#4 +5#!#5 +6#!#6 +~~END~~ + +declare @p int=2,@q int=3 SELECT * FROM t1_order_by_offset_fetch ORDER BY b OFFSET @p*@q ROWS FETCH NEXT @q ROWS ONLY +go +~~START~~ +int#!#int +7#!#7 +8#!#8 +9#!#9 +~~END~~ + +declare @p int =2,@q int=3 SELECT * FROM t1_order_by_offset_fetch ORDER BY b OFFSET square(2) ROWS FETCH NEXT @q ROWS ONLY +go +~~START~~ +int#!#int +5#!#5 +6#!#6 +7#!#7 +~~END~~ + +declare @p int =2,@q int=3 SELECT * FROM t1_order_by_offset_fetch ORDER BY b OFFSET square(1)*@p ROWS FETCH NEXT @q ROWS ONLY +go +~~START~~ +int#!#int +3#!#3 +4#!#4 +5#!#5 +~~END~~ + +declare @p int =2,@q int=3 SELECT * FROM t1_order_by_offset_fetch ORDER BY b OFFSET square(@p)+@p ROWS FETCH NEXT @q+1 ROWS ONLY +go +~~START~~ +int#!#int +7#!#7 +8#!#8 +9#!#9 +10#!#10 +~~END~~ + +declare @p int=2,@q int=3 SELECT * FROM t1_order_by_offset_fetch ORDER BY b OFFSET @p*1 ROWS FETCH NEXT @q ROWS ONLY +go +~~START~~ +int#!#int +3#!#3 +4#!#4 +5#!#5 +~~END~~ + +declare @p int =2,@q int=3 SELECT * FROM t1_order_by_offset_fetch ORDER BY b OFFSET square(1)*@p+1 ROWS FETCH NEXT @q ROWS ONLY +go +~~START~~ +int#!#int +4#!#4 +5#!#5 +6#!#6 +~~END~~ + +declare @p int =2,@q int=3 SELECT * FROM t1_order_by_offset_fetch ORDER BY b OFFSET square(1)*(@p) ROWS FETCH NEXT @q ROWS ONLY +go +~~START~~ +int#!#int +3#!#3 +4#!#4 +5#!#5 +~~END~~ + +declare @p int =2,@q int=3 SELECT * FROM t1_order_by_offset_fetch ORDER BY b OFFSET square(1)*@p ROWS FETCH NEXT @q ROWS ONLY +go +~~START~~ +int#!#int +3#!#3 +4#!#4 +5#!#5 +~~END~~ + +declare @p int =2,@q int=3 SELECT * FROM t1_order_by_offset_fetch ORDER BY b OFFSET @p*square(1) ROWS FETCH NEXT @q*square(1) ROWS ONLY +go +~~START~~ +int#!#int +3#!#3 +4#!#4 +5#!#5 +~~END~~ + +declare @p int =2,@q int=3 SELECT * FROM t1_order_by_offset_fetch ORDER BY b OFFSET square(1)*@p ROWS FETCH NEXT square(1)+@q ROWS ONLY +go +~~START~~ +int#!#int +3#!#3 +4#!#4 +5#!#5 +6#!#6 +~~END~~ + +declare @p int =2,@q int=3 SELECT * FROM t1_order_by_offset_fetch ORDER BY b OFFSET square(1)* @p ROWS FETCH NEXT square(@q)*@q+1 ROWS ONLY +go +~~START~~ +int#!#int +3#!#3 +4#!#4 +5#!#5 +6#!#6 +7#!#7 +8#!#8 +9#!#9 +10#!#10 +11#!#11 +12#!#12 +13#!#13 +14#!#14 +15#!#15 +16#!#16 +17#!#17 +18#!#18 +19#!#19 +20#!#20 +21#!#21 +22#!#22 +23#!#23 +24#!#24 +25#!#25 +26#!#26 +27#!#27 +28#!#28 +29#!#29 +30#!#30 +~~END~~ + +declare @p int =2,@q int=3 SELECT * FROM t1_order_by_offset_fetch ORDER BY b OFFSET square(1)*3+1 ROWS FETCH NEXT @p+1 ROWS ONLY +go +~~START~~ +int#!#int +5#!#5 +6#!#6 +7#!#7 +~~END~~ + +declare @p int =2,@q int=3 SELECT * FROM t1_order_by_offset_fetch ORDER BY b OFFSET (@p*@p) ROWS FETCH NEXT @p*@q ROWS ONLY +go +~~START~~ +int#!#int +5#!#5 +6#!#6 +7#!#7 +8#!#8 +9#!#9 +10#!#10 +~~END~~ + +exec p1_order_by_offset_fetch 1, 3 +go +~~START~~ +int#!#int +4#!#4 +5#!#5 +6#!#6 +7#!#7 +8#!#8 +9#!#9 +10#!#10 +11#!#11 +12#!#12 +13#!#13 +~~END~~ + +exec p1_order_by_offset_fetch 2, 3 +go +~~START~~ +int#!#int +7#!#7 +8#!#8 +9#!#9 +10#!#10 +11#!#11 +12#!#12 +13#!#13 +14#!#14 +15#!#15 +16#!#16 +~~END~~ + +p1_order_by_offset_fetch 3, 3 +go +~~START~~ +int#!#int +10#!#10 +11#!#11 +12#!#12 +13#!#13 +14#!#14 +15#!#15 +16#!#16 +17#!#17 +18#!#18 +19#!#19 +~~END~~ + +select dbo.f1_order_by_offset_fetch(1,1) +go +~~START~~ +int +1 +~~END~~ + +select * from v1_order_by_offset_fetch +go +~~START~~ +int#!#int +6#!#6 +7#!#7 +8#!#8 +~~END~~ + diff --git a/test/JDBC/expected/parallel_query/table-variable-vu-verify.out b/test/JDBC/expected/parallel_query/table-variable-vu-verify.out new file mode 100644 index 00000000000..bc2becc75f9 --- /dev/null +++ b/test/JDBC/expected/parallel_query/table-variable-vu-verify.out @@ -0,0 +1,278 @@ +--babel-1149 +select * from table_variable_vu_prepareitvf_1(5); +GO +~~START~~ +int#!#int +1#!#2 +~~END~~ + + +select * from table_variable_vu_preparemstvf_1(10); +GO +~~START~~ +nvarchar#!#int#!#int +hello1#!#1#!#100 +~~END~~ + + +select table_variable_vu_preparefunc_1(1); +GO +~~START~~ +int +1 +~~END~~ + + +exec table_variable_vu_prepareproc_1 +GO +~~ROW COUNT: 1~~ + +~~ROW COUNT: 1~~ + + +--babel-2647 +SELECT * from dbo.table_variable_vu_preparemstvf_2(); +go +~~START~~ +int +0 +~~END~~ + + +--babel-2903 +use master; +go + +select * from table_variable_vu_preparet1; +go +~~START~~ +int#!#int +1#!#1 +2#!#2 +~~END~~ + + +set BABELFISH_SHOWPLAN_ALL ON; +go + +declare @a int = 5, @b int = 5; +declare @c int; +execute table_variable_vu_prepareouter_proc @a, @b; +select @a, @b; +go +~~START~~ +text +Query Text: ASSIGN @a = SELECT 5 + Query Text: SELECT 5 + -> Result (cost=0.00..0.01 rows=1 width=4) +Query Text: ASSIGN @b = SELECT 5 + Query Text: SELECT 5 + -> Result (cost=0.00..0.01 rows=1 width=4) +Query Text: EXEC table_variable_vu_prepareouter_proc @a, @b + Query Text: DECLARE TABLE @t + Query Text: CREATE TEMPORARY TABLE IF NOT EXISTS @t_1 (a int, b int) + Query Text: ASSIGN @a = SELECT 3 + Query Text: SELECT 3 + -> Result (cost=0.00..0.01 rows=1 width=4) + Query Text: insert into table_variable_vu_preparet1 values ("@a", "@b"); + -> Insert on table_variable_vu_preparet1 (cost=0.00..0.01 rows=0 width=0) + -> Result (cost=0.00..0.01 rows=1 width=8) + Query Text: EXEC table_variable_vu_prepareinner_proc @b + Query Text: ASSIGN @b = SELECT (select top 1 a+b from table_variable_vu_preparet1 order by b) + Query Text: SELECT (select top 1 a+b from table_variable_vu_preparet1 order by b) + -> Result (cost=49.55..49.56 rows=1 width=4) + InitPlan 1 (returns $0) + -> Limit (cost=49.55..49.55 rows=1 width=8) + -> Sort (cost=49.55..55.20 rows=2260 width=8) + Sort Key: table_variable_vu_preparet1.b NULLS FIRST + -> Seq Scan on table_variable_vu_preparet1 (cost=0.00..38.25 rows=2260 width=8) + Query Text: insert into table_variable_vu_preparet1 values ("@b", "@b"); + -> Insert on table_variable_vu_preparet1 (cost=0.00..0.01 rows=0 width=0) + -> Result (cost=0.00..0.01 rows=1 width=8) + Query Text: insert into "@t" select * from table_variable_vu_preparet1; + -> Insert on "@t_1" (cost=0.00..32.60 rows=0 width=0) + -> Seq Scan on table_variable_vu_preparet1 (cost=0.00..32.60 rows=2260 width=8) + Query Text: select * from "@t" + -> Seq Scan on "@t_1" (cost=0.00..32.60 rows=2260 width=8) + Query Text: DROP TABLE @t_1 +Query Text: select "@a", "@b" +Gather (cost=0.00..0.01 rows=1 width=8) + Workers Planned: 1 + Single Copy: true + -> Result (cost=0.00..0.01 rows=1 width=8) +~~END~~ + + +set BABELFISH_SHOWPLAN_ALL Off; +go + +select * from table_variable_vu_preparet1; +go +~~START~~ +int#!#int +1#!#1 +2#!#2 +~~END~~ + + +--babel-3101 +select * from table_variable_vu_preparemy_splitstring('this,is,split') +GO +~~START~~ +nvarchar +this +is +split +~~END~~ + + +--babel-3088 +use table_variable_vu_preparedb +go + +exec table_variable_vu_prepareproc_2 1; +go +~~ROW COUNT: 1~~ + +~~START~~ +nvarchar +aaa +~~END~~ + + +use master +go + +--babel-2034 +SELECT count(*) FROM table_variable_vu_prepareCalculateEasDateTime(); +GO +~~START~~ +int +1 +~~END~~ + + +select * from table_variable_vu_preparemstvf_3(1); +GO +~~START~~ +text#!#int#!#int +hello1#!#1#!#100 +hello2#!#2#!#200 +~~END~~ + + +--babel-2676 +-- should return both rows +select * from table_variable_vu_preparemstvf_conditional(0) +go +~~START~~ +text +hello1 +hello2 +~~END~~ + + +-- should only return the first row +select * from table_variable_vu_preparemstvf_conditional(1) +go +~~START~~ +text +hello1 +~~END~~ + + +-- BABEL-3967 - table variable in sp_executesql +declare @var1 table_variable_vu_type +insert into @var1 values ('1', 2, 3, 4) +exec sp_executesql N'EXEC table_variable_vu_proc1 @x = @p0', N'@p0 table_variable_vu_type readonly', @p0=@var1 +go +~~ROW COUNT: 1~~ + +~~START~~ +int +2 +~~END~~ + + +declare @tableVar table_variable_vu_type; +insert into @tableVar values('1', 2, 3, 4); +declare @ret int; +select @ret = table_variable_vu_tvp_function(@tableVar); +select @ret +go +~~ROW COUNT: 1~~ + +~~START~~ +int +1 +~~END~~ + + +-- double-check that the underlying type for table_variable_vu_type is pass-by-val +select typbyval from pg_type where typname = 'table_variable_vu_type'; +go +~~START~~ +bit +1 +1 +~~END~~ + + +declare @tableVar table_variable_vu_schema.table_variable_vu_type +insert into @tableVar values ('a', 'b'), ('c', 'd') +select * from @tableVar +go +~~ROW COUNT: 2~~ + +~~START~~ +nvarchar#!#ntext +a#!#b +c#!#d +~~END~~ + + +declare @tableVar as table (x int) +insert into @tableVar values (1),(2),(3) +select * from @tableVar +select typbyval from pg_catalog.pg_type where typname like '@tablevar%'; +go +~~ROW COUNT: 3~~ + +~~START~~ +int +1 +2 +3 +~~END~~ + +~~START~~ +bit +1 +1 +1 +~~END~~ + + +select * from table_variable_vu_func2() +select typbyval from pg_catalog.pg_type where typname like '@sometable_table_variable_vu_func2%'; +go +~~START~~ +int#!#varchar +1234#!#abcd +~~END~~ + +~~START~~ +bit +1 +~~END~~ + + +-- BABEL-4337 - check nested TV for null; should not crash but throw an error +SELECT * FROM tv_nested_func2(NULL) +go +~~START~~ +int +~~ERROR (Code: 33557097)~~ + +~~ERROR (Message: table variable underlying typename is NULL. refname: @t)~~ + diff --git a/test/JDBC/expected/sys-assembly_types-vu-prepare.out b/test/JDBC/expected/sys-assembly_types-vu-prepare.out index 08bffefed13..5805dd44cdc 100644 --- a/test/JDBC/expected/sys-assembly_types-vu-prepare.out +++ b/test/JDBC/expected/sys-assembly_types-vu-prepare.out @@ -1,9 +1,9 @@ CREATE VIEW sys_assembly_types_view_vu_prepare AS -SELECT * FROM sys.assembly_types +SELECT name, principal_id, max_length, precision, scale, collation_name, is_nullable, is_user_defined, is_assembly_type, default_object_id, rule_object_id, assembly_id, assembly_class, is_binary_ordered, is_fixed_length, prog_id, assembly_qualified_name, is_table_type FROM sys.assembly_types GO CREATE PROC sys_assembly_types_proc_vu_prepare AS -SELECT * FROM sys.assembly_types +SELECT name, principal_id, max_length, precision, scale, collation_name, is_nullable, is_user_defined, is_assembly_type, default_object_id, rule_object_id, assembly_id, assembly_class, is_binary_ordered, is_fixed_length, prog_id, assembly_qualified_name, is_table_type FROM sys.assembly_types GO CREATE FUNCTION sys_assembly_types_func_vu_prepare() diff --git a/test/JDBC/expected/sys-assembly_types-vu-verify.out b/test/JDBC/expected/sys-assembly_types-vu-verify.out index 92c8d0e5853..f44bc0b062a 100644 --- a/test/JDBC/expected/sys-assembly_types-vu-verify.out +++ b/test/JDBC/expected/sys-assembly_types-vu-verify.out @@ -1,14 +1,18 @@ SELECT * FROM sys_assembly_types_view_vu_prepare GO ~~START~~ -varchar#!#int#!#int#!#int#!#int#!#smallint#!#tinyint#!#tinyint#!#varchar#!#bit#!#bit#!#bit#!#int#!#int#!#int#!#varchar#!#bit#!#bit#!#nvarchar#!#nvarchar#!#bit +varchar#!#int#!#smallint#!#tinyint#!#tinyint#!#varchar#!#bit#!#bit#!#bit#!#int#!#int#!#int#!#varchar#!#bit#!#bit#!#nvarchar#!#nvarchar#!#bit +geometry#!##!#-1#!#0#!#0#!##!#1#!#0#!#1#!#0#!#0#!##!##!##!##!##!##!#0 +geography#!##!#-1#!#0#!#0#!##!#1#!#0#!#1#!#0#!#0#!##!##!##!##!##!##!#0 ~~END~~ EXEC sys_assembly_types_proc_vu_prepare GO ~~START~~ -varchar#!#int#!#int#!#int#!#int#!#smallint#!#tinyint#!#tinyint#!#varchar#!#bit#!#bit#!#bit#!#int#!#int#!#int#!#varchar#!#bit#!#bit#!#nvarchar#!#nvarchar#!#bit +varchar#!#int#!#smallint#!#tinyint#!#tinyint#!#varchar#!#bit#!#bit#!#bit#!#int#!#int#!#int#!#varchar#!#bit#!#bit#!#nvarchar#!#nvarchar#!#bit +geometry#!##!#-1#!#0#!#0#!##!#1#!#0#!#1#!#0#!#0#!##!##!##!##!##!##!#0 +geography#!##!#-1#!#0#!#0#!##!#1#!#0#!#1#!#0#!#0#!##!##!##!##!##!##!#0 ~~END~~ @@ -16,14 +20,16 @@ SELECT * FROM sys_assembly_types_func_vu_prepare() GO ~~START~~ int -0 +2 ~~END~~ -- Test from sys-assembly_types.sql -SELECT * FROM sys.assembly_types +SELECT name, principal_id, max_length, precision, scale, collation_name, is_nullable, is_user_defined, is_assembly_type, default_object_id, rule_object_id, assembly_id, assembly_class, is_binary_ordered, is_fixed_length, prog_id, assembly_qualified_name, is_table_type FROM sys.assembly_types GO ~~START~~ -varchar#!#int#!#int#!#int#!#int#!#smallint#!#tinyint#!#tinyint#!#varchar#!#bit#!#bit#!#bit#!#int#!#int#!#int#!#varchar#!#bit#!#bit#!#nvarchar#!#nvarchar#!#bit +varchar#!#int#!#smallint#!#tinyint#!#tinyint#!#varchar#!#bit#!#bit#!#bit#!#int#!#int#!#int#!#varchar#!#bit#!#bit#!#nvarchar#!#nvarchar#!#bit +geometry#!##!#-1#!#0#!#0#!##!#1#!#0#!#1#!#0#!#0#!##!##!##!##!##!##!#0 +geography#!##!#-1#!#0#!#0#!##!#1#!#0#!#1#!#0#!#0#!##!##!##!##!##!##!#0 ~~END~~ diff --git a/test/JDBC/expected/sys-systypes-vu-verify.out b/test/JDBC/expected/sys-systypes-vu-verify.out index 7afbaa6c4cd..277c6a217db 100644 --- a/test/JDBC/expected/sys-systypes-vu-verify.out +++ b/test/JDBC/expected/sys-systypes-vu-verify.out @@ -16,6 +16,8 @@ datetime2#!#0#!#8#!#0#!#1#!##!# datetimeoffset#!#0#!#10#!#0#!#1#!##!# decimal#!#0#!#17#!#0#!#1#!##!# float#!#0#!#8#!#0#!#1#!##!# +geography#!#0#!#-1#!#0#!#1#!##!# +geometry#!#0#!#-1#!#0#!#1#!##!# image#!#0#!#16#!#0#!#1#!##!# int#!#0#!#4#!#0#!#1#!##!# money#!#0#!#8#!#0#!#1#!##!# diff --git a/test/JDBC/expected/sys-types-vu-verify.out b/test/JDBC/expected/sys-types-vu-verify.out index e039201042b..e03a839960c 100644 --- a/test/JDBC/expected/sys-types-vu-verify.out +++ b/test/JDBC/expected/sys-types-vu-verify.out @@ -17,6 +17,8 @@ datetime2#!#8#!#26#!#6#!# datetimeoffset#!#10#!#33#!#6#!# decimal#!#17#!#38#!#38#!# float#!#8#!#53#!#0#!# +geography#!#-1#!#0#!#0#!# +geometry#!#-1#!#0#!#0#!# image#!#16#!#0#!#0#!# int#!#4#!#10#!#0#!# money#!#8#!#19#!#4#!# diff --git a/test/JDBC/expected/sys-types.out b/test/JDBC/expected/sys-types.out index db2c2674f18..7512d39eba9 100644 --- a/test/JDBC/expected/sys-types.out +++ b/test/JDBC/expected/sys-types.out @@ -17,6 +17,8 @@ datetime2#!#8#!#26#!#6#!# datetimeoffset#!#10#!#33#!#6#!# decimal#!#17#!#38#!#38#!# float#!#8#!#53#!#0#!# +geography#!#-1#!#0#!#0#!# +geometry#!#-1#!#0#!#0#!# image#!#16#!#0#!#0#!# int#!#4#!#10#!#0#!# money#!#8#!#19#!#4#!# diff --git a/test/JDBC/expected/table_constraint_without_comma-vu-cleanup.out b/test/JDBC/expected/table_constraint_without_comma-vu-cleanup.out new file mode 100644 index 00000000000..e2722e2a8f5 --- /dev/null +++ b/test/JDBC/expected/table_constraint_without_comma-vu-cleanup.out @@ -0,0 +1,48 @@ +DROP FUNCTION f1_tvf_nocomma +go +DROP FUNCTION f2_tvf_nocomma +go +DROP FUNCTION f3_tvf_nocomma +go +DROP FUNCTION f4_tvf_nocomma +go +DROP FUNCTION f5_tvf_nocomma +go +DROP FUNCTION f6_tvf_nocomma +go +DROP FUNCTION f7_tvf_nocomma +go +DROP FUNCTION f8_tvf_nocomma +go +DROP FUNCTION f9_tvf_nocomma +go +DROP PROCEDURE p1_tv_nocomma +go +DROP PROCEDURE p2_tv_nocomma +go +DROP PROCEDURE p3_tv_nocomma +go +DROP PROCEDURE p4_tv_nocomma +go +DROP PROCEDURE p5_tv_nocomma +go +DROP PROCEDURE p6_tv_nocomma +go +DROP PROCEDURE p7_tv_nocomma +go +DROP PROCEDURE p8_tv_nocomma +go +DROP PROCEDURE p9_tv_nocomma +go +DROP TABLE t1_tvf_nocomma +go +DROP TABLE t2_tvf_nocomma +go +DROP TABLE t3_tvf_nocomma +go +DROP TABLE t4_tvf_nocomma +go +DROP TABLE t5_tvf_nocomma +go +DROP TABLE t6_tvf_nocomma +go diff --git a/test/JDBC/expected/table_constraint_without_comma-vu-prepare.out b/test/JDBC/expected/table_constraint_without_comma-vu-prepare.out new file mode 100644 index 00000000000..335ccc5cf2b --- /dev/null +++ b/test/JDBC/expected/table_constraint_without_comma-vu-prepare.out @@ -0,0 +1,153 @@ +CREATE FUNCTION f1_tvf_nocomma(@p INT) +RETURNS @tv TABLE (a INT NOT NULL, b INT NOT NULL PRIMARY KEY(a)) +AS +BEGIN + INSERT @tv VALUES(1,2) + IF @p > 0 INSERT @tv VALUES(1,3) + RETURN +END +go +CREATE FUNCTION f2_tvf_nocomma(@p INT) +RETURNS @tv TABLE (a INT NOT NULL, b INT NOT NULL PRIMARY KEY(a,b)) +AS +BEGIN + INSERT @tv VALUES(1,2) + IF @p > 0 INSERT @tv VALUES(1,2) + RETURN +END +go +CREATE FUNCTION f3_tvf_nocomma(@p INT) +RETURNS @tv TABLE (a INT NOT NULL, b INT NOT NULL PRIMARY KEY(a)) +AS +BEGIN + INSERT @tv VALUES(1,2) + IF @p > 0 INSERT @tv VALUES(1,3) + RETURN +END +go +CREATE FUNCTION f4_tvf_nocomma(@p INT) +RETURNS @tv TABLE (a INT NOT NULL, b INT NOT NULL UNIQUE(a,b)) +AS +BEGIN + INSERT @tv VALUES(1,2) + IF @p > 0 INSERT @tv VALUES(1,2) + RETURN +END +go +CREATE FUNCTION f5_tvf_nocomma(@p INT) +RETURNS @tv TABLE (a INT NOT NULL, b INT NOT NULL PRIMARY KEY) +AS +BEGIN + INSERT @tv VALUES(1,2) + IF @p > 0 INSERT @tv VALUES(2,2) + RETURN +END +go +CREATE FUNCTION f6_tvf_nocomma(@p INT) +RETURNS @tv TABLE (a INT NOT NULL PRIMARY KEY, b INT NOT NULL) +AS +BEGIN + INSERT @tv VALUES(1,2) + IF @p > 0 INSERT @tv VALUES(1,3) + RETURN +END +go +CREATE FUNCTION f7_tvf_nocomma(@p INT) +RETURNS @tv TABLE (a INT NOT NULL, b INT NOT NULL UNIQUE) +AS +BEGIN + INSERT @tv VALUES(1,2) + IF @p > 0 INSERT @tv VALUES(2,2) + RETURN +END +go +CREATE FUNCTION f8_tvf_nocomma(@p INT) +RETURNS @tv TABLE (a INT NOT NULL UNIQUE, b INT NOT NULL) +AS +BEGIN + INSERT @tv VALUES(1,2) + IF @p > 0 INSERT @tv VALUES(1,3) + RETURN +END +go +CREATE FUNCTION f9_tvf_nocomma(@p INT) +RETURNS @tv TABLE (a INT NOT NULL, b INT NOT NULL CHECK(a>0)) +AS +BEGIN + INSERT @tv VALUES(1,2) + IF @p > 0 INSERT @tv VALUES(0,3) + RETURN +END +go +CREATE PROCEDURE p1_tv_nocomma +AS +BEGIN + DECLARE @tv TABLE (a INT NOT NULL, b INT NOT NULL PRIMARY KEY(a)) + INSERT @tv VALUES(1,2) + INSERT @tv VALUES(1,3) +END +go +CREATE PROCEDURE p2_tv_nocomma +AS +BEGIN + DECLARE @tv TABLE (a INT NOT NULL, b INT NOT NULL PRIMARY KEY(a,b)) + INSERT @tv VALUES(1,2) + INSERT @tv VALUES(1,2) +END +go +CREATE PROCEDURE p3_tv_nocomma +AS +BEGIN + DECLARE @tv TABLE (a INT NOT NULL, b INT NOT NULL PRIMARY KEY(a)) + INSERT @tv VALUES(1,2) + INSERT @tv VALUES(1,3) +END +go +CREATE PROCEDURE p4_tv_nocomma +AS +BEGIN + DECLARE @tv TABLE (a INT NOT NULL, b INT NOT NULL UNIQUE(a,b)) + INSERT @tv VALUES(1,2) + INSERT @tv VALUES(1,2) +END +go +CREATE PROCEDURE p5_tv_nocomma +AS +BEGIN + DECLARE @tv TABLE (a INT NOT NULL, b INT NOT NULL PRIMARY KEY) + INSERT @tv VALUES(1,2) + INSERT @tv VALUES(2,2) +END +go +CREATE PROCEDURE p6_tv_nocomma +AS +BEGIN + DECLARE @tv TABLE (a INT NOT NULL PRIMARY KEY, b INT NOT NULL) + INSERT @tv VALUES(1,2) + INSERT @tv VALUES(1,3) +END +go +CREATE PROCEDURE p7_tv_nocomma +AS +BEGIN + DECLARE @tv TABLE (a INT NOT NULL, b INT NOT NULL UNIQUE) + INSERT @tv VALUES(1,2) + INSERT @tv VALUES(2,2) +END +go +CREATE PROCEDURE p8_tv_nocomma +AS +BEGIN + DECLARE @tv TABLE (a INT NOT NULL UNIQUE, b INT NOT NULL) + INSERT @tv VALUES(1,2) + INSERT @tv VALUES(1,3) +END +go +CREATE PROCEDURE p9_tv_nocomma +AS +BEGIN + DECLARE @tv TABLE (a INT NOT NULL, b INT NOT NULL CHECK(a>0)) + INSERT @tv VALUES(1,2) + INSERT @tv VALUES(0,3) +END +go diff --git a/test/JDBC/expected/table_constraint_without_comma-vu-verify.out b/test/JDBC/expected/table_constraint_without_comma-vu-verify.out new file mode 100644 index 00000000000..c931445829c --- /dev/null +++ b/test/JDBC/expected/table_constraint_without_comma-vu-verify.out @@ -0,0 +1,378 @@ +-- table variable +DECLARE @tv_nocomma TABLE(a INT NOT NULL, b INT PRIMARY KEY(a)) +insert @tv_nocomma values (1,2) +insert @tv_nocomma values (1,3) +go +~~ROW COUNT: 1~~ + +~~ERROR (Code: 2627)~~ + +~~ERROR (Message: duplicate key value violates unique constraint "@tv_nocomma_0_pkey")~~ + +DECLARE @tv_nocomma TABLE(a INT NOT NULL, b INT NOT NULL PRIMARY KEY(a,b)) +insert @tv_nocomma values (1,2) +insert @tv_nocomma values (1,2) +go +~~ROW COUNT: 1~~ + +~~ERROR (Code: 2627)~~ + +~~ERROR (Message: duplicate key value violates unique constraint "@tv_nocomma_0_pkey")~~ + +DECLARE @tv_nocomma TABLE(a INT NOT NULL, b INT UNIQUE(a)) +insert @tv_nocomma values (1,2) +insert @tv_nocomma values (1,3) +go +~~ROW COUNT: 1~~ + +~~ERROR (Code: 2627)~~ + +~~ERROR (Message: duplicate key value violates unique constraint "@tv_nocomma_0_a_key")~~ + +DECLARE @tv_nocomma TABLE(a INT NOT NULL, b INT NOT NULL UNIQUE(a,b)) +insert @tv_nocomma values (1,2) +insert @tv_nocomma values (1,2) +go +~~ROW COUNT: 1~~ + +~~ERROR (Code: 2627)~~ + +~~ERROR (Message: duplicate key value violates unique constraint "@tv_nocomma_0_a_b_key")~~ + + +-- already worked correctly before the fix: +DECLARE @tv_nocomma TABLE(a INT NOT NULL, b INT NOT NULL PRIMARY KEY) +insert @tv_nocomma values (1,2) +insert @tv_nocomma values (2,2) +go +~~ROW COUNT: 1~~ + +~~ERROR (Code: 2627)~~ + +~~ERROR (Message: duplicate key value violates unique constraint "@tv_nocomma_0_pkey")~~ + +DECLARE @tv_nocomma TABLE(a INT NOT NULL PRIMARY KEY, b INT NOT NULL) +insert @tv_nocomma values (1,2) +insert @tv_nocomma values (1,3) +go +~~ROW COUNT: 1~~ + +~~ERROR (Code: 2627)~~ + +~~ERROR (Message: duplicate key value violates unique constraint "@tv_nocomma_0_pkey")~~ + +DECLARE @tv_nocomma TABLE(a INT NOT NULL, b INT NOT NULL UNIQUE) +insert @tv_nocomma values (1,2) +insert @tv_nocomma values (2,2) +go +~~ROW COUNT: 1~~ + +~~ERROR (Code: 2627)~~ + +~~ERROR (Message: duplicate key value violates unique constraint "@tv_nocomma_0_b_key")~~ + +DECLARE @tv_nocomma TABLE(a INT NOT NULL UNIQUE, b INT NOT NULL) +insert @tv_nocomma values (1,2) +insert @tv_nocomma values (1,3) +go +~~ROW COUNT: 1~~ + +~~ERROR (Code: 2627)~~ + +~~ERROR (Message: duplicate key value violates unique constraint "@tv_nocomma_0_a_key")~~ + +DECLARE @tv_nocomma TABLE(a INT NOT NULL, b INT NOT NULL CHECK(a>0)) +insert @tv_nocomma values (1,2) +insert @tv_nocomma values (0,3) +go +~~ROW COUNT: 1~~ + +~~ERROR (Code: 547)~~ + +~~ERROR (Message: new row for relation "@tv_nocomma_0" violates check constraint "@tv_nocomma_0_a_check")~~ + + +-- TVF return table +SELECT * FROM f1_tvf_nocomma(0) +go +~~START~~ +int#!#int +1#!#2 +~~END~~ + +SELECT * FROM f1_tvf_nocomma(1) +go +~~START~~ +int#!#int +~~ERROR (Code: 2627)~~ + +~~ERROR (Message: duplicate key value violates unique constraint "@tv_1_pkey")~~ + +SELECT * FROM f2_tvf_nocomma(0) +go +~~START~~ +int#!#int +1#!#2 +~~END~~ + +SELECT * FROM f2_tvf_nocomma(1) +go +~~START~~ +int#!#int +~~ERROR (Code: 2627)~~ + +~~ERROR (Message: duplicate key value violates unique constraint "@tv_1_pkey")~~ + +SELECT * FROM f3_tvf_nocomma(0) +go +~~START~~ +int#!#int +1#!#2 +~~END~~ + +SELECT * FROM f3_tvf_nocomma(1) +go +~~START~~ +int#!#int +~~ERROR (Code: 2627)~~ + +~~ERROR (Message: duplicate key value violates unique constraint "@tv_1_pkey")~~ + +SELECT * FROM f4_tvf_nocomma(0) +go +~~START~~ +int#!#int +1#!#2 +~~END~~ + +SELECT * FROM f4_tvf_nocomma(1) +go +~~START~~ +int#!#int +~~ERROR (Code: 2627)~~ + +~~ERROR (Message: duplicate key value violates unique constraint "@tv_1_a_b_key")~~ + +SELECT * FROM f5_tvf_nocomma(0) +go +~~START~~ +int#!#int +1#!#2 +~~END~~ + +SELECT * FROM f5_tvf_nocomma(1) +go +~~START~~ +int#!#int +~~ERROR (Code: 2627)~~ + +~~ERROR (Message: duplicate key value violates unique constraint "@tv_1_pkey")~~ + +SELECT * FROM f6_tvf_nocomma(0) +go +~~START~~ +int#!#int +1#!#2 +~~END~~ + +SELECT * FROM f6_tvf_nocomma(1) +go +~~START~~ +int#!#int +~~ERROR (Code: 2627)~~ + +~~ERROR (Message: duplicate key value violates unique constraint "@tv_1_pkey")~~ + +SELECT * FROM f7_tvf_nocomma(0) +go +~~START~~ +int#!#int +1#!#2 +~~END~~ + +SELECT * FROM f7_tvf_nocomma(1) +go +~~START~~ +int#!#int +~~ERROR (Code: 2627)~~ + +~~ERROR (Message: duplicate key value violates unique constraint "@tv_1_b_key")~~ + +SELECT * FROM f8_tvf_nocomma(0) +go +~~START~~ +int#!#int +1#!#2 +~~END~~ + +SELECT * FROM f8_tvf_nocomma(1) +go +~~START~~ +int#!#int +~~ERROR (Code: 2627)~~ + +~~ERROR (Message: duplicate key value violates unique constraint "@tv_1_a_key")~~ + +SELECT * FROM f9_tvf_nocomma(0) +go +~~START~~ +int#!#int +1#!#2 +~~END~~ + +SELECT * FROM f9_tvf_nocomma(1) +go +~~START~~ +int#!#int +~~ERROR (Code: 547)~~ + +~~ERROR (Message: new row for relation "@tv_1" violates check constraint "@tv_f9_tvf_nocomma_a_check")~~ + + +-- stored procedures +EXECUTE p1_tv_nocomma +go +~~ROW COUNT: 1~~ + +~~ERROR (Code: 2627)~~ + +~~ERROR (Message: duplicate key value violates unique constraint "@tv_1_pkey")~~ + +EXECUTE p2_tv_nocomma +go +~~ROW COUNT: 1~~ + +~~ERROR (Code: 2627)~~ + +~~ERROR (Message: duplicate key value violates unique constraint "@tv_1_pkey")~~ + +EXECUTE p3_tv_nocomma +go +~~ROW COUNT: 1~~ + +~~ERROR (Code: 2627)~~ + +~~ERROR (Message: duplicate key value violates unique constraint "@tv_1_pkey")~~ + +EXECUTE p4_tv_nocomma +go +~~ROW COUNT: 1~~ + +~~ERROR (Code: 2627)~~ + +~~ERROR (Message: duplicate key value violates unique constraint "@tv_1_a_b_key")~~ + +EXECUTE p5_tv_nocomma +go +~~ROW COUNT: 1~~ + +~~ERROR (Code: 2627)~~ + +~~ERROR (Message: duplicate key value violates unique constraint "@tv_1_pkey")~~ + +EXECUTE p6_tv_nocomma +go +~~ROW COUNT: 1~~ + +~~ERROR (Code: 2627)~~ + +~~ERROR (Message: duplicate key value violates unique constraint "@tv_1_pkey")~~ + +EXECUTE p7_tv_nocomma +go +~~ROW COUNT: 1~~ + +~~ERROR (Code: 2627)~~ + +~~ERROR (Message: duplicate key value violates unique constraint "@tv_1_b_key")~~ + +EXECUTE p8_tv_nocomma +go +~~ROW COUNT: 1~~ + +~~ERROR (Code: 2627)~~ + +~~ERROR (Message: duplicate key value violates unique constraint "@tv_1_a_key")~~ + +EXECUTE p9_tv_nocomma +go +~~ROW COUNT: 1~~ + +~~ERROR (Code: 547)~~ + +~~ERROR (Message: new row for relation "@tv_1" violates check constraint "@tv_1_a_check")~~ + + +-- regular tables and #tmp tables already worked correctly before the fix: +create table t1_tvf_nocomma (a INT NOT NULL, b INT NOT NULL PRIMARY KEY(a)) +insert t1_tvf_nocomma values (1,2) +insert t1_tvf_nocomma values (1,3) +go +~~ROW COUNT: 1~~ + +~~ERROR (Code: 2627)~~ + +~~ERROR (Message: duplicate key value violates unique constraint "t1_tvf_nocomma_pkey")~~ + + +create table t2_tvf_nocomma (a INT NOT NULL, b INT NOT NULL PRIMARY KEY) +insert t2_tvf_nocomma values (1,2) +insert t2_tvf_nocomma values (1,3) +go +~~ROW COUNT: 1~~ + +~~ROW COUNT: 1~~ + + +create table t3_tvf_nocomma (a INT NOT NULL PRIMARY KEY, b INT NOT NULL) +insert t3_tvf_nocomma values (1,2) +insert t3_tvf_nocomma values (1,3) +go +~~ROW COUNT: 1~~ + +~~ERROR (Code: 2627)~~ + +~~ERROR (Message: duplicate key value violates unique constraint "t3_tvf_nocomma_pkey")~~ + + +create table t4_tvf_nocomma (a INT NOT NULL, b INT NOT NULL UNIQUE(a)) +insert t4_tvf_nocomma values (1,2) +insert t4_tvf_nocomma values (1,3) +go +~~ROW COUNT: 1~~ + +~~ERROR (Code: 2627)~~ + +~~ERROR (Message: duplicate key value violates unique constraint "t4_tvf_nocomma_a_key")~~ + + +create table t5_tvf_nocomma (a INT NOT NULL, b INT NOT NULL UNIQUE) +insert t5_tvf_nocomma values (1,2) +insert t5_tvf_nocomma values (1,3) +go +~~ROW COUNT: 1~~ + +~~ROW COUNT: 1~~ + + +create table t6_tvf_nocomma (a INT NOT NULL UNIQUE, b INT NOT NULL) +insert t6_tvf_nocomma values (1,2) +insert t6_tvf_nocomma values (1,3) +go +~~ROW COUNT: 1~~ + +~~ERROR (Code: 2627)~~ + +~~ERROR (Message: duplicate key value violates unique constraint "t6_tvf_nocomma_a_key")~~ + + +create table #t7_tvf_nocomma (a INT NOT NULL, b INT NOT NULL UNIQUE(a)) +insert #t7_tvf_nocomma values (1,2) +insert #t7_tvf_nocomma values (1,3) +go +~~ROW COUNT: 1~~ + +~~ERROR (Code: 2627)~~ + +~~ERROR (Message: duplicate key value violates unique constraint "#t7_tvf_nocomma_a_key")~~ + diff --git a/test/JDBC/expected/table_constraint_wo_comma-before-15_6-or-16_2-vu-cleanup.out b/test/JDBC/expected/table_constraint_wo_comma-before-15_6-or-16_2-vu-cleanup.out new file mode 100644 index 00000000000..ceaa628adab --- /dev/null +++ b/test/JDBC/expected/table_constraint_wo_comma-before-15_6-or-16_2-vu-cleanup.out @@ -0,0 +1,18 @@ +DROP PROCEDURE p1_tv_nocomma +go +DROP PROCEDURE p2_tv_nocomma +go +DROP PROCEDURE p3_tv_nocomma +go +DROP PROCEDURE p4_tv_nocomma +go +DROP PROCEDURE p5_tv_nocomma +go +DROP PROCEDURE p6_tv_nocomma +go +DROP PROCEDURE p7_tv_nocomma +go +DROP PROCEDURE p8_tv_nocomma +go +DROP PROCEDURE p9_tv_nocomma +go diff --git a/test/JDBC/expected/table_constraint_wo_comma-before-15_6-or-16_2-vu-prepare.out b/test/JDBC/expected/table_constraint_wo_comma-before-15_6-or-16_2-vu-prepare.out new file mode 100644 index 00000000000..a8602228ad2 --- /dev/null +++ b/test/JDBC/expected/table_constraint_wo_comma-before-15_6-or-16_2-vu-prepare.out @@ -0,0 +1,72 @@ +CREATE PROCEDURE p1_tv_nocomma +AS +BEGIN + DECLARE @tv TABLE (a INT NOT NULL, b INT NOT NULL PRIMARY KEY(a)) + INSERT @tv VALUES(1,2) + INSERT @tv VALUES(1,3) +END +go +CREATE PROCEDURE p2_tv_nocomma +AS +BEGIN + DECLARE @tv TABLE (a INT NOT NULL, b INT NOT NULL PRIMARY KEY(a,b)) + INSERT @tv VALUES(1,2) + INSERT @tv VALUES(1,2) +END +go +CREATE PROCEDURE p3_tv_nocomma +AS +BEGIN + DECLARE @tv TABLE (a INT NOT NULL, b INT NOT NULL PRIMARY KEY(a)) + INSERT @tv VALUES(1,2) + INSERT @tv VALUES(1,3) +END +go +CREATE PROCEDURE p4_tv_nocomma +AS +BEGIN + DECLARE @tv TABLE (a INT NOT NULL, b INT NOT NULL UNIQUE(a,b)) + INSERT @tv VALUES(1,2) + INSERT @tv VALUES(1,2) +END +go +CREATE PROCEDURE p5_tv_nocomma +AS +BEGIN + DECLARE @tv TABLE (a INT NOT NULL, b INT NOT NULL PRIMARY KEY) + INSERT @tv VALUES(1,2) + INSERT @tv VALUES(2,2) +END +go +CREATE PROCEDURE p6_tv_nocomma +AS +BEGIN + DECLARE @tv TABLE (a INT NOT NULL PRIMARY KEY, b INT NOT NULL) + INSERT @tv VALUES(1,2) + INSERT @tv VALUES(1,3) +END +go +CREATE PROCEDURE p7_tv_nocomma +AS +BEGIN + DECLARE @tv TABLE (a INT NOT NULL, b INT NOT NULL UNIQUE) + INSERT @tv VALUES(1,2) + INSERT @tv VALUES(2,2) +END +go +CREATE PROCEDURE p8_tv_nocomma +AS +BEGIN + DECLARE @tv TABLE (a INT NOT NULL UNIQUE, b INT NOT NULL) + INSERT @tv VALUES(1,2) + INSERT @tv VALUES(1,3) +END +go +CREATE PROCEDURE p9_tv_nocomma +AS +BEGIN + DECLARE @tv TABLE (a INT NOT NULL, b INT NOT NULL CHECK(a>0)) + INSERT @tv VALUES(1,2) + INSERT @tv VALUES(0,3) +END +go diff --git a/test/JDBC/expected/table_constraint_wo_comma-before-15_6-or-16_2-vu-verify.out b/test/JDBC/expected/table_constraint_wo_comma-before-15_6-or-16_2-vu-verify.out new file mode 100644 index 00000000000..b37b19f546e --- /dev/null +++ b/test/JDBC/expected/table_constraint_wo_comma-before-15_6-or-16_2-vu-verify.out @@ -0,0 +1,72 @@ +EXECUTE p1_tv_nocomma +go +~~ROW COUNT: 1~~ + +~~ERROR (Code: 2627)~~ + +~~ERROR (Message: duplicate key value violates unique constraint "@tv_1_pkey")~~ + +EXECUTE p2_tv_nocomma +go +~~ROW COUNT: 1~~ + +~~ERROR (Code: 2627)~~ + +~~ERROR (Message: duplicate key value violates unique constraint "@tv_1_pkey")~~ + +EXECUTE p3_tv_nocomma +go +~~ROW COUNT: 1~~ + +~~ERROR (Code: 2627)~~ + +~~ERROR (Message: duplicate key value violates unique constraint "@tv_1_pkey")~~ + +EXECUTE p4_tv_nocomma +go +~~ROW COUNT: 1~~ + +~~ERROR (Code: 2627)~~ + +~~ERROR (Message: duplicate key value violates unique constraint "@tv_1_a_b_key")~~ + +EXECUTE p5_tv_nocomma +go +~~ROW COUNT: 1~~ + +~~ERROR (Code: 2627)~~ + +~~ERROR (Message: duplicate key value violates unique constraint "@tv_1_pkey")~~ + +EXECUTE p6_tv_nocomma +go +~~ROW COUNT: 1~~ + +~~ERROR (Code: 2627)~~ + +~~ERROR (Message: duplicate key value violates unique constraint "@tv_1_pkey")~~ + +EXECUTE p7_tv_nocomma +go +~~ROW COUNT: 1~~ + +~~ERROR (Code: 2627)~~ + +~~ERROR (Message: duplicate key value violates unique constraint "@tv_1_b_key")~~ + +EXECUTE p8_tv_nocomma +go +~~ROW COUNT: 1~~ + +~~ERROR (Code: 2627)~~ + +~~ERROR (Message: duplicate key value violates unique constraint "@tv_1_a_key")~~ + +EXECUTE p9_tv_nocomma +go +~~ROW COUNT: 1~~ + +~~ERROR (Code: 547)~~ + +~~ERROR (Message: new row for relation "@tv_1" violates check constraint "@tv_1_a_check")~~ + diff --git a/test/JDBC/input/BABEL-4554-vu-cleanup.sql b/test/JDBC/input/BABEL-4554-vu-cleanup.sql new file mode 100644 index 00000000000..5983643d80b --- /dev/null +++ b/test/JDBC/input/BABEL-4554-vu-cleanup.sql @@ -0,0 +1,2 @@ +DROP TYPE babel_4554_type +GO \ No newline at end of file diff --git a/test/JDBC/input/BABEL-4554-vu-prepare.sql b/test/JDBC/input/BABEL-4554-vu-prepare.sql new file mode 100644 index 00000000000..7d4ceb9e9a1 --- /dev/null +++ b/test/JDBC/input/BABEL-4554-vu-prepare.sql @@ -0,0 +1,44 @@ +-- Verify that newly created temp tables have toasts in ENR. + +CREATE TABLE #babel_4554_temp_table(a varchar(4000), b nvarchar(MAX), c sysname) +GO + +-- 3: table, toast, index on toast +SELECT COUNT(*) FROM sys.babelfish_get_enr_list() +GO + +DROP TABLE #babel_4554_temp_table +GO + +-- 4: table, toast, index on toast, pkey +CREATE TABLE #babel_4554_temp_table_2(a sysname primary key, b nvarchar(MAX)) +GO + +SELECT COUNT(*) FROM sys.babelfish_get_enr_list() +GO + +-- 1: index +CREATE INDEX #babel_4554_idx1 ON #babel_4554_temp_table_2(b) +GO + +SELECT COUNT(*) FROM sys.babelfish_get_enr_list() +GO + +DROP INDEX #babel_4554_idx1 ON #babel_4554_temp_table_2 +GO + +DROP TABLE #babel_4554_temp_table_2 +GO + +-- Verify that non-ENR tables don't put their toasts in ENR. +CREATE TYPE babel_4554_type FROM INT +GO + +CREATE TABLE #babel_4554_temp_table_not_enr(a babel_4554_type, b nvarchar(MAX)) +GO + +SELECT COUNT(*) FROM sys.babelfish_get_enr_list() +GO + +DROP TABLE #babel_4554_temp_table_not_enr +GO diff --git a/test/JDBC/input/BABEL-4554-vu-verify.sql b/test/JDBC/input/BABEL-4554-vu-verify.sql new file mode 100644 index 00000000000..96c92b932f7 --- /dev/null +++ b/test/JDBC/input/BABEL-4554-vu-verify.sql @@ -0,0 +1,21 @@ +-- We should have no dangling entries here (taken from BABEL-4554 DA) + +select * +from pg_class where relname in +( + select relname + from pg_class c + where not exists + ( + SELECT * from pg_class d + WHERE c.oid = d.reltoastrelid + ) + AND relname in + ( + select s.relname from pg_stat_all_tables s where s.relname LIKE 'pg_toast_%' + ) + AND pg_table_size(c.oid) = 0 + AND c.relkind = 't' + AND c.relpersistence = 't' +) +GO \ No newline at end of file diff --git a/test/JDBC/input/BABEL-CROSS-DB.mix b/test/JDBC/input/BABEL-CROSS-DB.mix index 594fcd1b0e8..630af3bad34 100644 --- a/test/JDBC/input/BABEL-CROSS-DB.mix +++ b/test/JDBC/input/BABEL-CROSS-DB.mix @@ -338,6 +338,12 @@ DROP PROCEDURE p1 GO -- tsql +USE db1; +GO + +DROP TABLE db1_t1; +GO + USE master; GO diff --git a/test/JDBC/input/BABEL-GRANT.sql b/test/JDBC/input/BABEL-GRANT.sql index c175c338575..8388f782ffd 100644 --- a/test/JDBC/input/BABEL-GRANT.sql +++ b/test/JDBC/input/BABEL-GRANT.sql @@ -20,6 +20,10 @@ GO --- Prepare Objects --- +---- SCHEMA +CREATE SCHEMA scm; +GO + ---- TABLE CREATE TABLE t1 ( a int, b int); GO @@ -55,6 +59,18 @@ GO --- Basic Grant / Revoke --- +GRANT SELECT ON SCHEMA::scm TO guest; +GO + +GRANT SELECT ON SCHEMA::scm TO PUBLIC; +GO + +REVOKE SELECT ON SCHEMA::scm FROM PUBLIC; +GO + +GRANT INSERT ON SCHEMA::scm TO guest; +GO + GRANT ALL ON OBJECT::t1 TO guest WITH GRANT OPTION; GO @@ -145,16 +161,31 @@ GO REVOKE ALL TO alogin; -- database permission GO -GRANT SHOWPLAN ON OBJECT::t1 TO guest; -- unsupported permission +REVOKE SELECT ON SCHEMA::scm FROM guest; +GO + +GRANT showplan ON OBJECT::t1 TO guest; -- unsupported permission GO REVOKE SHOWPLAN ON OBJECT::t2 TO alogin; -- unsupported permission GO -GRANT ALL ON SCHEMA::scm TO guest; -- unsupported class +GRANT ALL ON SCHEMA::scm TO guest; +GO + +REVOKE ALL ON SCHEMA::scm TO guest; GO -REVOKE ALL ON SCHEMA::scm TO guest; -- unsupported class +GRANT create table ON OBJECT::t1 TO guest; -- unsupported permission +GO + +REVOKE create table ON OBJECT::t2 FROM alogin; -- unsupported permission +GO + +GRANT SELECT ON table::t1 TO guest; -- unsupported object +GO + +REVOKE SELECT ON table::t1 FROM guest; -- unsupported object GO GRANT ALL ON OBJECT::t1 TO guest WITH GRANT OPTION AS superuser; @@ -179,6 +210,9 @@ GO --- Clean Up --- +DROP SCHEMA scm; +GO + DROP VIEW IF EXISTS my_view; GO diff --git a/test/JDBC/input/BABEL-SESSION.mix b/test/JDBC/input/BABEL-SESSION.mix index 41c1c853985..d9f7be4a8ca 100644 --- a/test/JDBC/input/BABEL-SESSION.mix +++ b/test/JDBC/input/BABEL-SESSION.mix @@ -99,6 +99,21 @@ USE master; GO -- tsql +USE db1; +GO + +DROP TABLE tb1; +GO + +DROP TABLE janedoe_schema.t1; +GO + +DROP SCHEMA janedoe_schema; +GO + +USE master; +go + DROP DATABASE db1; GO diff --git a/test/JDBC/input/BABEL_OBJECT_ID-vu-cleanup.mix b/test/JDBC/input/BABEL_OBJECT_ID-vu-cleanup.mix index ed603c01cf6..5b12a9b58f8 100644 --- a/test/JDBC/input/BABEL_OBJECT_ID-vu-cleanup.mix +++ b/test/JDBC/input/BABEL_OBJECT_ID-vu-cleanup.mix @@ -39,6 +39,9 @@ GO DROP SCHEMA [babel_object_id_schema .with .dot_and_spaces] GO +DROP TYPE babel_object_id_type +GO + DROP TABLE [babel_object_id_t2 .with .dot_an_spaces] GO diff --git a/test/JDBC/input/BABEL_OBJECT_ID-vu-prepare.mix b/test/JDBC/input/BABEL_OBJECT_ID-vu-prepare.mix index 0eae8541577..ce10a6a5212 100644 --- a/test/JDBC/input/BABEL_OBJECT_ID-vu-prepare.mix +++ b/test/JDBC/input/BABEL_OBJECT_ID-vu-prepare.mix @@ -46,6 +46,9 @@ GO CREATE TABLE [babel_object_id_schema .with .dot_and_spaces]."babel_object_id_t3 .with .dot_and_spaces" (a int); GO +CREATE TYPE babel_object_id_type FROM int +GO + -- To test lookup in different database CREATE DATABASE babel_object_id_db; GO diff --git a/test/JDBC/input/BABEL_OBJECT_ID-vu-verify.mix b/test/JDBC/input/BABEL_OBJECT_ID-vu-verify.mix index 72abaca89fe..9762f33d824 100644 --- a/test/JDBC/input/BABEL_OBJECT_ID-vu-verify.mix +++ b/test/JDBC/input/BABEL_OBJECT_ID-vu-verify.mix @@ -104,6 +104,13 @@ GO SELECT OBJECT_NAME(OBJECT_ID('tempdb..#babel_object_id_temp_t1')) GO +-- Test temp objects not in ENR +CREATE TABLE #babel_object_id_temp_t2(a babel_object_id_type); +GO + +SELECT OBJECT_NAME(OBJECT_ID('#babel_object_id_temp_t2')) +GO + -- We can also specify object_type as parameter SELECT OBJECT_NAME(OBJECT_ID('#babel_object_id_temp_t1', 'U')) GO diff --git a/test/JDBC/input/GRANT_SCHEMA-vu-cleanup.mix b/test/JDBC/input/GRANT_SCHEMA-vu-cleanup.mix new file mode 100644 index 00000000000..156b92c61e6 --- /dev/null +++ b/test/JDBC/input/GRANT_SCHEMA-vu-cleanup.mix @@ -0,0 +1,66 @@ +-- tsql +-- Drop objects +use grant_schema_d1; +go + +drop table grant_schema_s1.grant_schema_t1; +go + +drop table grant_schema_s1.grant_schema_t2; +go + +drop table grant_schema_s1.grant_schema_t3; +go + +drop view grant_schema_s1.grant_schema_v1; +go + +drop view grant_schema_s1.grant_schema_v2; +go + +drop proc grant_schema_s1.grant_schema_p1; +go + +drop proc grant_schema_s1.grant_schema_p2; +go + +drop function grant_schema_s1.grant_schema_f1; +go + +drop function grant_schema_s1.grant_schema_f2; +go + +drop schema grant_schema_s1; +go + +drop table grant_schema_s2.grant_schema_t1; +go + +drop table grant_schema_s2.grant_schema_t2; +go + +drop schema grant_schema_s2; +go + +drop user grant_schema_u1; +go + +use master; +go + +drop database grant_schema_d1; +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) = 'grant_schema_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 grant_schema_l1; +go \ No newline at end of file diff --git a/test/JDBC/input/GRANT_SCHEMA-vu-prepare.mix b/test/JDBC/input/GRANT_SCHEMA-vu-prepare.mix new file mode 100644 index 00000000000..306cd64d582 --- /dev/null +++ b/test/JDBC/input/GRANT_SCHEMA-vu-prepare.mix @@ -0,0 +1,74 @@ +-- tsql +-- create objects +create database grant_schema_d1; +go + +use grant_schema_d1; +go + +create login grant_schema_l1 with password = '12345678' +go + +create user grant_schema_u1 for login grant_schema_l1; +go + +create schema grant_schema_s1; +go + +create table grant_schema_s1.grant_schema_t1(a int); +go + +create table grant_schema_s1.grant_schema_t2(b int); +go + +create table grant_schema_s1.grant_schema_t3(c int); +go + +create view grant_schema_s1.grant_schema_v1 as select 2; +go + +create view grant_schema_s1.grant_schema_v2 as select 2; +go + +create proc grant_schema_s1.grant_schema_p1 as select 2; +go + +create proc grant_schema_s1.grant_schema_p2 as select 2; +go + +CREATE FUNCTION grant_schema_s1.grant_schema_f1() RETURNS INT AS BEGIN RETURN (SELECT COUNT(*) FROM sys.objects) END +go + +CREATE FUNCTION grant_schema_s1.grant_schema_f2() RETURNS INT AS BEGIN RETURN (SELECT COUNT(*) FROM sys.objects) END +go + +create schema grant_schema_s2; +go + +create table grant_schema_s2.grant_schema_t1(a int); +go + +create table grant_schema_s2.grant_schema_t2(a int); +go + +-- GRANT OBJECT privilege +grant select on grant_schema_s1.grant_schema_t1 to grant_schema_u1; +go +grant select on grant_schema_s1.grant_schema_t3 to grant_schema_u1; +go +grant select on grant_schema_s1.grant_schema_v1 to grant_schema_u1; +go +grant select on grant_schema_s1.grant_schema_v2 to grant_schema_u1; +go +grant execute on grant_schema_s1.grant_schema_p1 to grant_schema_u1; +go +grant execute on grant_schema_s1.grant_schema_p2 to grant_schema_u1; +go +grant execute on grant_schema_s1.grant_schema_f1 to grant_schema_u1; +go +grant execute on grant_schema_s1.grant_schema_f2 to grant_schema_u1; +go +grant select on grant_schema_s2.grant_schema_t1 to grant_schema_u1; +go +grant select on grant_schema_s2.grant_schema_t2 to grant_schema_u1; +go \ No newline at end of file diff --git a/test/JDBC/input/GRANT_SCHEMA-vu-verify.mix b/test/JDBC/input/GRANT_SCHEMA-vu-verify.mix new file mode 100644 index 00000000000..09e9a233360 --- /dev/null +++ b/test/JDBC/input/GRANT_SCHEMA-vu-verify.mix @@ -0,0 +1,179 @@ +-- tsql user=grant_schema_l1 password=12345678 +-- User has OBJECT privileges, should be accessible. +use grant_schema_d1; +go + +select * from grant_schema_s1.grant_schema_t1; +go + +select * from grant_schema_s1.grant_schema_t2; -- case 1: has no permission +go + +select * from grant_schema_s1.grant_schema_v1; +go + +exec grant_schema_s1.grant_schema_p1; +go + +select * from grant_schema_s1.grant_schema_f1(); +go + +-- tsql +-- REVOKE OBJECT privilege +use grant_schema_d1; +go +revoke select on grant_schema_s1.grant_schema_t1 from grant_schema_u1; +go +revoke select on grant_schema_s1.grant_schema_v1 from grant_schema_u1; +go +revoke execute on grant_schema_s1.grant_schema_p1 from grant_schema_u1; +go +revoke execute on grant_schema_s1.grant_schema_f1 from grant_schema_u1; +go + +-- tsql user=grant_schema_l1 password=12345678 +-- User has no privileges, should not be accessible. +use grant_schema_d1; +go + +select * from grant_schema_s1.grant_schema_t1; +go + +select * from grant_schema_s1.grant_schema_v1; +go + +exec grant_schema_s1.grant_schema_p1; +go + +select * from grant_schema_s1.grant_schema_f1(); +go + +-- tsql +-- GRANT SCHEMA privilege +use grant_schema_d1; +go +grant select, execute on schema::grant_schema_s1 to grant_schema_u1; +go +use master; +go + +-- tsql user=grant_schema_l1 password=12345678 +-- User has SCHEMA privileges, should be accessible. +use grant_schema_d1; +go + +select * from grant_schema_s1.grant_schema_t1; +go + +select * from grant_schema_s1.grant_schema_t2; +go + +select * from grant_schema_s1.grant_schema_v1; +go + +exec grant_schema_s1.grant_schema_p1; +go + +select * from grant_schema_s1.grant_schema_f1(); +go + +-- User has OBJECT and SCHEMA privileges, should be accessible. +use grant_schema_d1; +go + +select * from grant_schema_s1.grant_schema_t3; +go + +select * from grant_schema_s1.grant_schema_v2; +go + +exec grant_schema_s1.grant_schema_p2; +go + +select * from grant_schema_s1.grant_schema_f2(); +go + +-- tsql +-- Case 6: User has SCHEMA privilege, REVOKE OBJECT privilege +use grant_schema_d1; +go +revoke select on grant_schema_s1.grant_schema_t3 from grant_schema_u1; +go +revoke select on grant_schema_s1.grant_schema_v2 from grant_schema_u1; +go +revoke execute on grant_schema_s1.grant_schema_p2 from grant_schema_u1; +go +revoke execute on grant_schema_s1.grant_schema_f2 from grant_schema_u1; +go + +-- tsql user=grant_schema_l1 password=12345678 +-- User has SCHEMA privileges, should be accessible. +use grant_schema_d1; +go + +select * from grant_schema_s1.grant_schema_t3; +go + +select * from grant_schema_s1.grant_schema_v2; +go + +exec grant_schema_s1.grant_schema_p2; +go + +select * from grant_schema_s1.grant_schema_f2(); +go + +-- tsql +-- User has OBJECT privilege, REVOKE OBJECT privilege +-- case 7: User has no privileges, should not be accessible. +use grant_schema_d1; +go +revoke select on grant_schema_s2.grant_schema_t2 from grant_schema_u1; +go +use master; +go + +-- tsql user=grant_schema_l1 password=12345678 +use grant_schema_d1; +go + +select * from grant_schema_s2.grant_schema_t2; +go + +-- tsql +-- User has OBJECT privilege, REVOKE SCHEMA privilege +-- case 8: User has OBJECT privileges, would not be accessible. +use grant_schema_d1; +go +revoke select on schema::grant_schema_s2 from grant_schema_u1; +go +use master; +go + +-- tsql user=grant_schema_l1 password=12345678 +use grant_schema_d1; +go + +select * from grant_schema_s2.grant_schema_t1; +go + +-- tsql +-- User has OBJECT privilege, GRANT and REVOKE SCHEMA privilege +-- case 5: User has OBJECT privileges, would not be accessible. +use grant_schema_d1; +go +grant select on schema::grant_schema_s2 to grant_schema_u1; +go + +revoke select on schema::grant_schema_s2 from grant_schema_u1; +go +use master; +go + +-- tsql user=grant_schema_l1 password=12345678 +use grant_schema_d1; +go + +select * from grant_schema_s2.grant_schema_t1; +go + diff --git a/test/JDBC/input/GRANT_SCHEMA.mix b/test/JDBC/input/GRANT_SCHEMA.mix new file mode 100644 index 00000000000..b3ca970117f --- /dev/null +++ b/test/JDBC/input/GRANT_SCHEMA.mix @@ -0,0 +1,677 @@ +-- tsql +-- create objects +create database babel_4344_d1; +go + +use babel_4344_d1; +go + +create login babel_4344_l1 with password = '12345678' +go + +create user babel_4344_u1 for login babel_4344_l1; +go + +create login αιώνια with password = '12345678' +go + +create user αιώνια for login αιώνια; +go + +create login ログイン with password = '12345678' +go + +create user ログイン for login ログイン; +go + +create schema babel_4344_s1; +go + +create schema "BAbel_4344 S1"; +go + +create table "babel_4344 s1"."babel_4344 t1"(a int); +go + +create schema αγάπη; +go + +create schema スキーマ; +go + +create schema babel_4344_s2 authorization babel_4344_u1; +go + +create table babel_4344_t1(a int); +go + +create table babel_4344_s1.babel_4344_t1(a int); +go + +create table babel_4344_s2.babel_4344_t1(a int); +go + +create table αγάπη.abc(a int); +go + +create table スキーマ.abc(a int); +go + +create table babel_4344_t3(a int, b int); +go + +create table babel_4344_s1.babel_4344_t3(a int, b int); +go + +create schema "update pg_class set oid = 0 where relname = 'babel_4344_t1'"; +go + +create view babel_4344_v1 as select 1; +go + +create view babel_4344_s1.babel_4344_v1 as select 2; +go + +create proc babel_4344_p1 as select 1; +go + +create proc babel_4344_s1.babel_4344_p1 as select 2; +go + +create proc babel_4344_s1.babel_4344_p3 as select 3; +go + +CREATE FUNCTION babel_4344_f1() returns int begin declare @a int; set @a = 1; return @a; end +go + +CREATE FUNCTION babel_4344_s1.babel_4344_f1() returns int begin declare @a int; set @a = 1; return @a; END +go + +-- tests with greek character (one byte) and japanese character (muti bytes) +grant SELECT on schema::babel_4344_S1 to public, αιώνια, ログイン; +go + +grant select on schema::αγάπη to αιώνια, ログイン; +go + +grant select on schema::スキーマ to ログイン, αιώνια; +go + +-- test special database roles +grant SELECT on schema::babel_4344_S1 to db_owner; -- throws an error +go + +grant SELECT on schema::babel_4344_S1 to sys; -- throws an error +go + +grant SELECT on schema::babel_4344_S1 to information_schema; -- throws an error +go + +grant SELECT on schema::babel_4344_S1 to dbo; -- throws an error +go + +-- tsql user=ログイン password=12345678 +use babel_4344_d1; +go + +select * from αγάπη.abc; +go + +select * from スキーマ.abc; +go + +select * from babel_4344_S1.babel_4344_t1; +go + +use master; +go + +-- tsql user=αιώνια password=12345678 +use babel_4344_d1; +go + +select * from αγάπη.abc; +go + +select * from スキーマ.abc; +go + +select * from babel_4344_S1.babel_4344_t1; +go + +use master; +go + +-- tsql user=babel_4344_l1 password=12345678 +use babel_4344_d1; +go + +-- User has select privileges, tables and views be accessible +select * from babel_4344_s1.babel_4344_t1 +go +select * from babel_4344_s1.babel_4344_v1; +go +use master; +go + +-- tsql +-- object names having more than 64 bytes +create schema abcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwzyzabcdefghijklmnopqrstuvwzyz +go + +create table abcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwzyzabcdefghijklmnopqrstuvwzyz.abcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwzyzabcdefghijklmnopqrstuvwzyz(a int); +go + +grant select on schema::abcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwzyzabcdefghijklmnopqrstuvwzyz to babel_4344_u1; +go + +revoke select on schema::abcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwzyzabcdefghijklmnopqrstuvwzyz from babel_4344_u1; +go + +grant select on abcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwzyzabcdefghijklmnopqrstuvwzyz.abcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwzyzabcdefghijklmnopqrstuvwzyz to babel_4344_u1; +go + +revoke select on abcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwzyzabcdefghijklmnopqrstuvwzyz.abcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwzyzabcdefghijklmnopqrstuvwzyz from babel_4344_u1; +go + +drop table abcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwzyzabcdefghijklmnopqrstuvwzyz.abcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwzyzabcdefghijklmnopqrstuvwzyz +go + +drop schema abcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwzyzabcdefghijklmnopqrstuvwzyz +go + +use babel_4344_d1; +go +revoke select on schema::babel_4344_s1 from public, αιώνια, ログイン; +go + +-- tsql user=babel_4344_l1 password=12345678 +use babel_4344_d1; +go + +-- User doesn't have any privileges, objects should not be accessible +select * from babel_4344_t1; +go +select * from babel_4344_s1.babel_4344_t1 +go +insert into babel_4344_s1.babel_4344_t1 values(1); +go +select * from babel_4344_v1; +go +select * from babel_4344_s1.babel_4344_v1; +go +exec babel_4344_p1; +go +exec babel_4344_s1.babel_4344_p1; +go +select * from babel_4344_f1(); +go +select * from babel_4344_s1.babel_4344_f1(); +go +use master; +go + +-- tsql +-- GRANT OBJECT privilege +use babel_4344_d1; +go +grant SELECT on schema::"bAbel_4344 s1" to BABEL_4344_U1; +go +grant SELECT on schema::"update pg_class set oid = 0 where relname = 'babel_4344_t1'" to BABEL_4344_U1; +go +grant SELECT on "babel_4344_t1" to BABEL_4344_U1; +go +grant SELECT on "babel_4344_s1".babel_4344_t1 to babel_4344_u1; +go +grant all on babel_4344_s1.babel_4344_t1 to "babel_4344_u1"; +go +grant select on babel_4344_t3(a) to babel_4344_u1; -- column privilege +go +grant select on babel_4344_s1.babel_4344_t3(a) to babel_4344_u1; -- column privilege +go +grant select on babel_4344_v1 to babel_4344_u1; +go +grant select on babel_4344_s1.babel_4344_v1 to babel_4344_u1; +go +grant execute on babel_4344_p1 to babel_4344_u1; +go +grant execute on babel_4344_s1.babel_4344_p1 to babel_4344_u1; +go +-- inside a transaction, permission will not be granted since it is rolled back +begin transaction; +exec sp_executesql N'grant execute on babel_4344_s1.babel_4344_p3 to babel_4344_u1;'; +rollback transaction; +go + +-- Mixed case +grant Execute on Babel_4344_F1 to Babel_4344_u1; +go +grant execute on BABEL_4344_s1.babel_4344_f1 to babEL_4344_u1; +go +-- Grant schema permission to its owner, should fail +grant select on schema::babel_4344_s2 to babel_4344_u1; -- should fail +go +grant select on schema::babel_4344_s2 to jdbc_user; -- should fail +go +grant SELECT on schema::"babel_4344_s2" to guest; -- should pass +go +grant select on schema::"" to guest; -- should fail +go +grant select on schema::non_existing_schema to guest; -- should fail +go +-- grant statement via a procedure +create procedure grant_perm_proc as begin exec('grant select on schema::[] to guest') end; +go +exec grant_perm_proc; -- should fail, invalid GRANT statement +go +-- non-existing role +grant SELECT on schema::dbo to guest, babel_4344_u3; -- should fail +go + +-- tsql user=babel_4344_l1 password=12345678 +-- User has OBJECT privileges, should be accessible. +use babel_4344_d1; +go +select * from babel_4344_t1; +go +select * from babel_4344_s1.babel_4344_t1 +go +insert into babel_4344_s1.babel_4344_t1 values(2); +go +select * from babel_4344_t3; -- not accessible, only column privilege is granted +go +select * from babel_4344_s1.babel_4344_t3 -- not accessible, only column privilege is granted +go +select * from babel_4344_v1; +go +select * from babel_4344_s1.babel_4344_v1; +go +exec babel_4344_p1; +go +exec babel_4344_s1.babel_4344_p1; +go +exec babel_4344_s1.babel_4344_p3; -- should fail, grant statement was rolled back +go +select * from BABEl_4344_f1(); +go +select * from babEL_4344_s1.babel_4344_f1(); +go +-- Grant schema permission to its owner +grant select on schema::babel_4344_s2 to babel_4344_u1; -- should fail +go +grant select on schema::babel_4344_s2 to guest; -- should pass +go +grant select on schema::babel_4344_s1 to babel_4344_u1; -- should fail +go +use master; +go + +-- tsql +-- GRANT SCHEMA privilege +use babel_4344_d1; +go +grant control on schema::babel_4344_s1 to babel_4344_u1; -- should fail, 'control' is not supported +go +grant select, insert, execute on schema::babel_4344_s1 to babel_4344_u1; +go +use master; +go + +-- psql +-- GRANT statement add an entry to the catalog +select schema_name, object_name, permission, grantee from sys.babelfish_schema_permissions +where schema_name = 'babel_4344_s1' collate "C" order by permission; -- and object_name = 'ALL' collate "C" +go + +-- tsql +-- GRANT SCHEMA privilege again +use babel_4344_d1; +go +grant select, insert, execute on schema::babel_4344_s1 to babel_4344_u1; +go +-- GRANT OBJECT privilege again +grant select on babel_4344_s1.babel_4344_v1 to babel_4344_u1; +go +use master; +go + +-- psql +-- check the consistency of catalog +select schema_name, object_name, permission, grantee from sys.babelfish_schema_permissions +where schema_name = 'babel_4344_s1' collate "C" order by permission; +go + +-- tsql user=babel_4344_l1 password=12345678 +-- User has OBJECT and SCHEMA privileges, should be accessible. +use babel_4344_d1; +go +select * from babel_4344_s1.babel_4344_t1 +go +insert into babel_4344_s1.babel_4344_t1 values(3); +go +select * from babel_4344_s1.babel_4344_t3 +go +select * from babel_4344_s1.babel_4344_v1; +go +exec babel_4344_s1.babel_4344_p1; +go +select * from babel_4344_s1.babel_4344_f1(); +go +use master; +go + +-- tsql +-- REVOKE SCHEMA privilege +use babel_4344_d1; +go +revoke select, insert, execute on schema::babel_4344_s1 from babel_4344_u1; +go +use master; +go + +-- tsql user=babel_4344_l1 password=12345678 +-- User has OBJECT privileges, should be accessible. +use babel_4344_d1; +go +select * from babel_4344_s1.babel_4344_t1 +go +insert into babel_4344_s1.babel_4344_t1 values(3); +go +select * from babel_4344_s1.babel_4344_t3 -- not accessible +go +select * from babel_4344_s1.babel_4344_v1; +go +exec babel_4344_s1.babel_4344_p1; +go +select * from babel_4344_s1.babel_4344_f1(); +go +select * from babel_4344_s2.babel_4344_t1; +go +use master; +go + +-- tsql +-- create new objects in same schema +use babel_4344_d1; +go +-- Grant the permissions again +grant select, insert, execute on schema::babel_4344_s1 to babel_4344_u1; +go +grant select, insert, execute on schema::information_schema to babel_4344_u1; +go +create table babel_4344_s1.babel_4344_t2(a int); +go +create view babel_4344_s1.babel_4344_v2 as select 2; +go +create proc babel_4344_s1.babel_4344_p2 as select 2; +go +CREATE FUNCTION babel_4344_s1.babel_4344_f2() RETURNS INT AS BEGIN RETURN (SELECT COUNT(*) FROM sys.objects) END +go +use master; +go + +-- tsql user=babel_4344_l1 password=12345678 +-- User has SCHEMA privileges,objects should be accessible. +use babel_4344_d1; +go +select * from babel_4344_s1.babel_4344_t2 +go +insert into babel_4344_s1.babel_4344_t1 values(4); +go +select * from babel_4344_s1.babel_4344_v2; +go +exec babel_4344_s1.babel_4344_p2; +go +select * from babel_4344_s1.babel_4344_f2(); +go +select * from "bAbel_4344 s1"."bAbel_4344 t1"; +go +use master; +go + +-- tsql +-- REVOKE OBJECT privileges +use babel_4344_d1; +go +REVOKE SELECT on schema::"bAbel_4344 s1" from "BABEL_4344_U1"; +go +REVOKE SELECT on schema::"update pg_class set oid = 0 where relname = 'babel_4344_t1'" from BABEL_4344_U1; +go +REVOKE all on babel_4344_s1.babel_4344_t1 FROM babel_4344_u1; +go +REVOKE select on babel_4344_s1.babel_4344_t3(a) FROM babel_4344_u1; +go +REVOKE select on babel_4344_s1.babel_4344_v1 FROM babel_4344_u1; +go +REVOKE execute on babel_4344_s1.babel_4344_p1 FROM babel_4344_u1; +go +REVOKE execute on babel_4344_s1.babel_4344_f1 FROM babel_4344_u1; +go +REVOKE all on babel_4344_s1.babel_4344_f1 FROM babel_4344_u1; +go + +-- tsql user=babel_4344_l1 password=12345678 +-- User has SCHEMA privileges, should be accessible. +use babel_4344_d1; +go +select * from babel_4344_s1.babel_4344_t1 +go +insert into babel_4344_s1.babel_4344_t1 values(5); +go +select * from babel_4344_s1.babel_4344_t3; +go +select * from babel_4344_s1.babel_4344_v1; +go +exec babel_4344_s1.babel_4344_p1; +go +select * from babel_4344_s1.babel_4344_f1(); +go +select * from babel_4344_s2.babel_4344_t1; +go +use master; +go + +-- tsql +-- REVOKE SCHEMA privileges +use babel_4344_d1; +go +revoke select, insert, execute on schema::babel_4344_s1 from babel_4344_u1; +go +use master; +go + +-- psql +-- REVOKE on schema removes the entry from the catalog +select * from sys.babelfish_schema_permissions where schema_name = 'babel_4344_s1' collate sys.database_default; +go + +-- tsql user=babel_4344_l1 password=12345678 +-- User has no privileges, shouldn't be accessible. +use babel_4344_d1; +go +select * from babel_4344_s1.babel_4344_t1; +go +insert into babel_4344_s1.babel_4344_t1 values(5); +go +select * from babel_4344_s1.babel_4344_t3; +go +select * from babel_4344_s1.babel_4344_v1; +go +exec babel_4344_s1.babel_4344_p1; +go +select * from babel_4344_s1.babel_4344_f1(); +go +use master; +go + +-- psql +-- grant object permission +grant select on babel_4344_s1.babel_4344_t1 to babel_4344_d1_babel_4344_u1; +go + +-- tsql +-- grant schema permission +use babel_4344_d1; +go +grant select on schema::babel_4344_s1 to babel_4344_u1; +go +use master +go + +-- tsql user=babel_4344_l1 password=12345678 +use babel_4344_d1; +go +select * from babel_4344_s1.babel_4344_t1; -- accessible +go +use master +go + +-- psql +-- revoke schema permission +revoke select on all tables in schema babel_4344_s1 from babel_4344_d1_babel_4344_u1; +go + +-- tsql user=babel_4344_l1 password=12345678 +use babel_4344_d1; +go +select * from babel_4344_s1.babel_4344_t1; -- not accessible +go +use master +go + +-- tsql +-- Drop objects +use babel_4344_d1; +go + +drop schema "update pg_class set oid = 0 where relname = 'babel_4344_t1'"; +go + +drop table babel_4344_t1; +go + +drop table babel_4344_s1.babel_4344_t1; +go + +drop table babel_4344_t3; +go + +drop table babel_4344_s1.babel_4344_t3; +go + +drop table babel_4344_s1.babel_4344_t2; +go + +drop view babel_4344_v1; +go + +drop view babel_4344_s1.babel_4344_v1; +go + +drop view babel_4344_s1.babel_4344_v2; +go + +drop proc babel_4344_p1; +go + +drop proc babel_4344_s1.babel_4344_p1; +go + +drop proc babel_4344_s1.babel_4344_p2; +go + +drop proc babel_4344_s1.babel_4344_p3; +go + +drop function babel_4344_f1; +go + +drop function babel_4344_s1.babel_4344_f1; +go + +drop function babel_4344_s1.babel_4344_f2; +go + +drop schema babel_4344_s1; +go + +drop table babel_4344_s2.babel_4344_t1; +go + +drop schema babel_4344_s2; +go + +drop table αγάπη.abc; +go + +drop schema αγάπη; +go + +drop table スキーマ.abc; +go + +drop schema スキーマ; +go + +drop table "babel_4344 s1"."babel_4344 t1"; +go + +drop schema "BAbel_4344 s1"; +go + +drop user babel_4344_u1; +go + +drop user αιώνια; +go + +drop user ログイン; +go + +use master; +go + +drop database babel_4344_d1; +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) = 'babel_4344_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 babel_4344_l1; +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) = 'αιώνια' 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 αιώνια; +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) = 'ログイン' 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 ログイン; +go diff --git a/test/JDBC/input/datatypes/TestSpatialPoint-vu-cleanup.txt b/test/JDBC/input/datatypes/TestSpatialPoint-vu-cleanup.txt index cfd1c8615f3..1b87814a1ea 100644 --- a/test/JDBC/input/datatypes/TestSpatialPoint-vu-cleanup.txt +++ b/test/JDBC/input/datatypes/TestSpatialPoint-vu-cleanup.txt @@ -18,8 +18,34 @@ DROP VIEW IF EXISTS TransformFromGeog DROP VIEW IF EXISTS equal_geog +DROP VIEW IF EXISTS GeomView + +DROP PROCEDURE IF EXISTS dbo.p_getcoordinates + +DROP FUNCTION IF EXISTS f_getval + +DROP VIEW IF EXISTS ValFromGeom + +DROP VIEW IF EXISTS GeogView + +DROP VIEW IF EXISTS SubqueryView + +DROP VIEW IF EXISTS FuncExprView + +DROP VIEW IF EXISTS BrackExprView + +DROP TABLE IF EXISTS test_table + +DROP PROCEDURE IF EXISTS dbo.proc_getdata + +DROP FUNCTION IF EXISTS func_getval + DROP VIEW IF EXISTS point_distances_geog +DROP function IF EXISTS testspatial_tvf; + +DROP TABLE IF EXISTS SpatialData; + DROP TABLE IF EXISTS SPATIALPOINTGEOM_dt DROP TABLE IF EXISTS GeomToVarbinary @@ -45,3 +71,53 @@ DROP TABLE IF EXISTS GeogToVarchar DROP TABLE IF EXISTS TypeToGeog DROP TABLE IF EXISTS SPATIALPOINT_dt + +drop procedure IF EXISTS geometry_proc_1; + +drop procedure IF EXISTS geography_proc_1; + +drop table IF EXISTS geo_view_test; + +DROP PROCEDURE IF EXISTS GetPointsByXCoordinate + +DROP PROCEDURE IF EXISTS GetPointsByXCoordinate1 + +DROP PROCEDURE IF EXISTS GetDistanceByXCoordinate + +DROP FUNCTION IF EXISTS dbo.GetXCoordinate + +DROP FUNCTION IF EXISTS GetGeometry + +DROP TRIGGER IF EXISTS trg_LogXCoordinateChange + +DROP TABLE IF EXISTS XCoordinateChangeLog + +DROP TRIGGER IF EXISTS trg_LogDistanceChange + +DROP TABLE IF EXISTS DistanceChangeLog + +DROP TABLE IF EXISTS YourTable + +DROP TABLE IF EXISTS GeomTab + +DROP TABLE IF EXISTS YourTable1 + +DROP TABLE IF EXISTS TableA + +DROP TABLE IF EXISTS TableB + +DROP PROCEDURE IF EXISTS GetPointsWithinDistance + +DROP FUNCTION IF EXISTS dbo.CalculateDistance + +DROP TABLE IF EXISTS YourTable2 + +Drop Table IF EXISTS babelfish_migration_mode_table + +DROP TABLE IF EXISTS geometry_test + +DROP FUNCTION IF EXISTS geom_schema.STDistance + +DROP SCHEMA IF EXISTS geom_schema + +DROP TABLE IF EXISTS STX diff --git a/test/JDBC/input/datatypes/TestSpatialPoint-vu-prepare.txt b/test/JDBC/input/datatypes/TestSpatialPoint-vu-prepare.txt index 67f3e3419f3..c6184e93243 100644 --- a/test/JDBC/input/datatypes/TestSpatialPoint-vu-prepare.txt +++ b/test/JDBC/input/datatypes/TestSpatialPoint-vu-prepare.txt @@ -42,6 +42,47 @@ INSERT INTO SPATIALPOINTGEOM_dt (location) VALUES ( geometry::STPointFromText('P #Positive Test for Point with SRID 4326 INSERT INTO SPATIALPOINTGEOM_dt (location) VALUES ( geometry::Point(47.65100, -22.34900, 4326) ) +CREATE TABLE YourTable ( ID INT PRIMARY KEY, PointColumn geometry ); + +INSERT INTO YourTable (ID, PointColumn) VALUES (1, geometry::Point(3.0, 4.0, 4326)), (2, geometry::Point(5.0, 6.0, 4326)); + +CREATE TABLE GeomTab ( ID INT PRIMARY KEY, PointColumn geometry ); + +INSERT INTO GeomTab (ID, PointColumn) VALUES (1, geometry::Point(3.0, 4.0, 4326)), (2, geometry::Point(3.0, 6.0, 4326)); + +CREATE FUNCTION dbo.GetXCoordinate(@point geometry) RETURNS float AS BEGIN RETURN @point.STX; END; + +CREATE PROCEDURE GetDistanceByXCoordinate @xCoordinate FLOAT AS BEGIN DECLARE @point geometry = geometry::Point(@xCoordinate, 0.0, 4326); SELECT @point.STY, YourTable.PointColumn.STDistance(@point) AS Distance FROM YourTable ORDER BY PointColumn.STX; END; + +CREATE TABLE TableA (ID INT PRIMARY KEY, PointA geometry); +CREATE TABLE TableB (ID INT PRIMARY KEY, PointB geometry); +INSERT INTO TableA (ID, PointA) VALUES (1, geometry::Point(1.0, 2.0, 4326)); +INSERT INTO TableB (ID, PointB) VALUES (1, geometry::Point(3.0, 4.0, 4326)); + +CREATE PROCEDURE GetPointsByXCoordinate @XCoordinate FLOAT AS BEGIN SELECT * FROM YourTable WHERE PointColumn.STX = @XCoordinate ORDER BY PointColumn.STX; END; + +CREATE PROCEDURE GetPointsByXCoordinate1 @XCoordinate FLOAT AS BEGIN DECLARE @Sql NVARCHAR(MAX); SET @Sql = N'SELECT ID, PointColumn.STX AS XCoordinate FROM YourTable WHERE PointColumn.STX = @ParamXCoordinate ORDER BY PointColumn.STX'; EXEC sp_executesql @Sql,N'@ParamXCoordinate FLOAT',@XCoordinate; END; + +CREATE TABLE YourTable1 ( ID INT PRIMARY KEY, STX geometry ); +INSERT INTO YourTable1 (ID, STX) VALUES (1, geometry::Point(3.0, 4.0, 4326)), (2, geometry::Point(5.0, 6.0, 4326)); + +CREATE FUNCTION GetGeometry() RETURNS geometry AS BEGIN RETURN geometry::Point(1.0, 2.0, 4326); END; + +CREATE TABLE XCoordinateChangeLog (PointID INT,OldXCoordinate FLOAT,NewXCoordinate FLOAT,ChangeDate DATETIME); + +CREATE TRIGGER trg_LogXCoordinateChange ON YourTable AFTER UPDATE AS BEGIN INSERT INTO XCoordinateChangeLog (PointID, OldXCoordinate, NewXCoordinate, ChangeDate) SELECT i.ID, d.PointColumn.STX, i.PointColumn.STX, GETDATE() FROM inserted i JOIN deleted d ON i.ID = d.ID WHERE i.PointColumn.STX <> d.PointColumn.STX; END; + +CREATE TABLE YourTable2 ( ID INT PRIMARY KEY, PointColumn1 geometry, PointColumn2 geometry ); +INSERT INTO YourTable2 (ID, PointColumn1, PointColumn2) VALUES (1, geometry::Point(3.0, 4.0, 4326), geometry::Point(4.0, 5.0, 4326)); + +CREATE FUNCTION dbo.CalculateDistance(@point1 geometry,@point2 geometry) RETURNS float AS BEGIN RETURN @point1.STDistance(@point2); END; + +CREATE PROCEDURE GetPointsWithinDistance @referencePoint geometry, @maxDistance float AS BEGIN SELECT * FROM YourTable WHERE PointColumn.STDistance(@referencePoint) <= @maxDistance ORDER BY PointColumn.STX; END; + +CREATE TABLE DistanceChangeLog (PointID INT,OldDistance FLOAT,NewDistance FLOAT,ChangeDate DATETIME); + +CREATE TRIGGER trg_LogDistanceChange ON YourTable AFTER UPDATE AS BEGIN DECLARE @referencePoint geometry = geometry::Point(0.0, 0.0, 4326); INSERT INTO DistanceChangeLog (PointID, OldDistance, NewDistance, ChangeDate) SELECT i.ID, d.PointColumn.STDistance(@referencePoint), i.PointColumn.STDistance(@referencePoint), GETDATE() FROM inserted i JOIN deleted d ON i.ID = d.ID WHERE i.PointColumn.STDistance(@referencePoint) <> d.PointColumn.STDistance(@referencePoint); END; + #Tests for Geometry type Prepared Statements prepst#!#INSERT INTO SPATIALPOINTGEOM_dt(location) values(@location) #!#GEOMETRY|-|location|-|Point(47.65100 -22.34900):4326 prepst#!#exec#!#GEOMETRY|-|location|-|Point(1.0 2.0):4326 @@ -58,15 +99,23 @@ prepst#!#exec#!#GEOMETRY|-|location|-|Point(1.0 ):4326 prepst#!#exec#!#GEOMETRY|-|location|-|Point(1.0 2.0 3.0 4.0):4326 prepst#!#exec#!#GEOMETRY|-|location|-|LINESTRING(1 2, 3 4):4326 -CREATE VIEW TextFromGeom AS SELECT STAsText(location) AS TextRepresentation FROM SPATIALPOINTGEOM_dt; +CREATE VIEW TextFromGeom AS SELECT STAsText(location) AS TextRepresentation FROM SPATIALPOINTGEOM_dt ORDER BY location.STX; + +CREATE VIEW BinaryFromGeom AS SELECT STAsBinary(location) AS BinaryRepresentation FROM SPATIALPOINTGEOM_dt ORDER BY location.STX; + +CREATE VIEW CoordsFromGeom AS SELECT STX(location), STY(location) AS Coordinates FROM SPATIALPOINTGEOM_dt ORDER BY location.STX; + +CREATE VIEW GeomView AS SELECT location.STX, location.STY AS Coordinates FROM SPATIALPOINTGEOM_dt ORDER BY location.STX; -CREATE VIEW BinaryFromGeom AS SELECT STAsBinary(location) AS BinaryRepresentation FROM SPATIALPOINTGEOM_dt; +CREATE VIEW ValFromGeom AS SELECT location.STAsText(), location.STAsBinary() FROM SPATIALPOINTGEOM_dt ORDER BY location.STX; -CREATE VIEW CoordsFromGeom AS SELECT STX(location), STY(location) AS Coordinates FROM SPATIALPOINTGEOM_dt; +CREATE FUNCTION f_getval() RETURNS TABLE AS RETURN ( SELECT location.STX AS XCoordinate, location.STY AS YCoordinate FROM SPATIALPOINTGEOM_dt ORDER BY location.STX ); -CREATE VIEW equal_geom AS SELECT p1.location AS point FROM SPATIALPOINTGEOM_dt p1 CROSS JOIN SPATIALPOINTGEOM_dt p2 WHERE p1.location = p2.location; +CREATE PROCEDURE dbo.p_getcoordinates AS BEGIN DECLARE @Coordinates TABLE ( XCoordinate float, YCoordinate float ); INSERT INTO @Coordinates SELECT * FROM dbo.f_getval(); SELECT * FROM @Coordinates; END; -CREATE VIEW point_distances_geom AS SELECT p1.location AS point1, p2.location AS point2, STDistance( p1.location, p2.location ) AS distance FROM SPATIALPOINTGEOM_dt p1 CROSS JOIN SPATIALPOINTGEOM_dt p2 WHERE p1.location <> p2.location; +CREATE VIEW equal_geom AS SELECT p1.location AS point FROM SPATIALPOINTGEOM_dt p1 CROSS JOIN SPATIALPOINTGEOM_dt p2 WHERE p1.location = p2.location ORDER BY p1.location.STX; + +CREATE VIEW point_distances_geom AS SELECT p1.location AS point1, p2.location AS point2, STDistance( p1.location, p2.location ) AS distance FROM SPATIALPOINTGEOM_dt p1 CROSS JOIN SPATIALPOINTGEOM_dt p2 WHERE p1.location <> p2.location ORDER BY p1.location.STX; CREATE TABLE SPATIALPOINTGEOG_dt (location geography) @@ -162,18 +211,39 @@ prepst#!#exec#!#GEOGRAPHY|-|location|-|Point(1.0 ):4326 prepst#!#exec#!#GEOGRAPHY|-|location|-|Point(1.0 2.0 3.0 4.0):4326 prepst#!#exec#!#GEOGRAPHY|-|location|-|LINESTRING(1 2, 3 4):4326 -CREATE VIEW TextFromGeog AS SELECT STAsText(location) AS TextRepresentation FROM SPATIALPOINTGEOG_dt; +CREATE VIEW TextFromGeog AS SELECT STAsText(location) AS TextRepresentation FROM SPATIALPOINTGEOG_dt ORDER BY location.Lat; + +CREATE VIEW BinaryFromGeog AS SELECT STAsBinary(location) AS BinaryRepresentation FROM SPATIALPOINTGEOG_dt ORDER BY location.Lat; + +CREATE VIEW CoordsFromGeog AS SELECT Long(location), Lat(location) AS Coordinates FROM SPATIALPOINTGEOG_dt ORDER BY location.Lat; + +CREATE VIEW GeogView AS SELECT location.Long, location.Lat AS Coordinates FROM SPATIALPOINTGEOG_dt ORDER BY location.Lat; -CREATE VIEW BinaryFromGeog AS SELECT STAsBinary(location) AS BinaryRepresentation FROM SPATIALPOINTGEOG_dt; +CREATE TABLE test_table (geog geography) +INSERT INTO test_table(geog) VALUES(geography::Point(1, 2, 4326)); -CREATE VIEW CoordsFromGeog AS SELECT long(location), lat(location) AS Coordinates FROM SPATIALPOINTGEOG_dt; +CREATE VIEW SubqueryView AS SELECT (select geog from test_table ORDER BY geog.Lat).Lat AS Latitude; +CREATE VIEW BrackExprView AS SELECT ( geog ).Lat AS Latitude from test_table; -CREATE VIEW TransformFromGeog AS SELECT ST_Transform(location, 4326) AS Modified_points FROM SPATIALPOINTGEOG_dt; +CREATE VIEW FuncExprView AS SELECT geography::Point(1, 2, 4326).Lat AS Latitude from test_table; -CREATE VIEW equal_geog AS SELECT p1.location AS point FROM SPATIALPOINTGEOG_dt p1 CROSS JOIN SPATIALPOINTGEOG_dt p2 WHERE p1.location = p2.location; +CREATE FUNCTION func_getval() RETURNS TABLE AS RETURN ( SELECT location.STAsText() AS TextPoint FROM SPATIALPOINTGEOG_dt ORDER BY location.Lat ); -CREATE VIEW point_distances_geog AS SELECT p1.location AS point1, p2.location AS point2, STDistance( p1.location, p2.location ) AS distance FROM SPATIALPOINTGEOG_dt p1 CROSS JOIN SPATIALPOINTGEOG_dt p2 WHERE p1.location <> p2.location; +CREATE PROCEDURE dbo.proc_getdata AS BEGIN DECLARE @Data TABLE ( TextPoint text ); INSERT INTO @Data SELECT * FROM dbo.func_getval(); SELECT * FROM @Data; END; + +CREATE VIEW TransformFromGeog AS SELECT ST_Transform(location, 4326) AS Modified_points FROM SPATIALPOINTGEOG_dt ORDER BY location.Lat; + +CREATE VIEW equal_geog AS SELECT p1.location AS point FROM SPATIALPOINTGEOG_dt p1 CROSS JOIN SPATIALPOINTGEOG_dt p2 WHERE p1.location = p2.location ORDER BY p1.location.Lat; + +CREATE VIEW point_distances_geog AS SELECT p1.location AS point1, p2.location AS point2, STDistance( p1.location, p2.location ) AS distance FROM SPATIALPOINTGEOG_dt p1 CROSS JOIN SPATIALPOINTGEOG_dt p2 WHERE p1.location <> p2.location ORDER BY p1.location.Lat; + +CREATE TABLE SpatialData(ID INT PRIMARY KEY, SpatialLocation GEOGRAPHY); +INSERT INTO SpatialData (ID, SpatialLocation) VALUES (1, geography::Point(1, 2, 4326)), (2, geography::Point(3, 4, 4326)), (3, geography::Point(5, 6, 4326)), (4, geography::Point(7, 8, 4326)), (5, geography::Point(9, 10, 4326)); + +create function testspatial_tvf(@x int) returns table as return select location from SPATIALPOINTGEOG_dt; + +CREATE TABLE babelfish_migration_mode_table (id_num INT IDENTITY(1,1), mig_mode VARCHAR(10)) #Testing Implicit CASTs to and from Geography data type for supported Explicit CASTs #UnSupported CASTs to and from Geography data type @@ -202,3 +272,14 @@ INSERT INTO SPATIALPOINT_dt (PrimaryKey, GeomColumn, GeogColumn) VALUES ( 3, geo prepst#!#INSERT INTO SPATIALPOINT_dt(PrimaryKey, GeomColumn) values(@PrimaryKey, @GeomColumn) #!#int|-|PrimaryKey|-|4#!#GEOMETRY|-|GeomColumn|-|Point(47.65100 -22.34900):4326 prepst#!#INSERT INTO SPATIALPOINT_dt(PrimaryKey, GeogColumn) values(@PrimaryKey, @GeogColumn) #!#int|-|PrimaryKey|-|5#!#GEOGRAPHY|-|GeogColumn|-|Point(47.65100 -22.34900):4326 prepst#!#INSERT INTO SPATIALPOINT_dt(PrimaryKey, GeomColumn, GeogColumn) values(@PrimaryKey, @GeomColumn, @GeogColumn) #!#int|-|PrimaryKey|-|6#!#GEOMETRY|-|GeomColumn|-|Point(1.0 2.0):4326#!#GEOGRAPHY|-|GeogColumn|-|Point(1.0 2.0):4326 + +create procedure geometry_proc_1 @a geometry, @b varchar(max) as select @a as a, @b as b; +create procedure geography_proc_1 @a geography, @b varchar(max) as select @a as a, @b as b; +create table geo_view_test(a geometry, b geography) + +create schema geom_schema; +CREATE FUNCTION geom_schema.STDistance(@point geometry) RETURNS nvarchar(max) AS BEGIN RETURN @point.STAsText(); END; +create table geometry_test(geom_schema geometry) +Insert INTO geometry_test VALUES(geometry::STGeomFromText('Point(47.65100 -22.34900)', 0)) +create table STX(STX geometry) +Insert INTO STX VALUES(geometry::STGeomFromText('Point(47.65100 -22.34900)', 0)) diff --git a/test/JDBC/input/datatypes/TestSpatialPoint-vu-verify.sql b/test/JDBC/input/datatypes/TestSpatialPoint-vu-verify.sql index 239f4e93ada..2412b45d906 100644 --- a/test/JDBC/input/datatypes/TestSpatialPoint-vu-verify.sql +++ b/test/JDBC/input/datatypes/TestSpatialPoint-vu-verify.sql @@ -1,31 +1,99 @@ DECLARE @point geometry; SET @point = geometry::STPointFromText('POINT(-122.34900 47.65100)', 4326); SELECT STAsText(@point); +SELECT @point.STAsText(); Go DECLARE @point geometry; SET @point = geometry::POINT(22.34900, -47.65100, 4326); SELECT STAsText(@point); +SELECT @point.STAsText(); +SELECT @point . STAsText ( ); Go +DECLARE @point geometry; +SET @point = geometry::Point(1.0, 2.0, 4326); +SELECT @point.STX AS XCoordinate; +GO + +DECLARE @point1 geometry = geometry::Point(1.0, 2.0, 4326); +DECLARE @point2 geometry = geometry::Point(3.0, 4.0, 4326); +SELECT @point1.STDistance(@point2) AS Distance; +GO + DECLARE @point geometry; SET @point = geometry::STGeomFromText('POINT(-122.34900 47.65100)', 4326); -SELECT stx(@point); -SELECT sty(@point); +SELECT STX(@point); +SELECT STY(@point); +SELECT @point.STX; +SELECT @point.STY; Go DECLARE @point geometry; SET @point = geometry::POINT(22.34900, -47.65100, 4326); -SELECT stx(@point); -SELECT sty(@point); +SELECT STX(@point); +SELECT STY(@point); +SELECT @point.STX; +SELECT @point . STX; +SELECT @point.STY; Go DECLARE @point1 geometry, @point2 geometry; SET @point1 = geometry::STPointFromText('POINT(-122.34900 47.65100)', 4326); SET @point2 = geometry::STGeomFromText('POINT(-122.35000 47.65000)', 4326); SELECT STDistance(@point1, @point2); +SELECT @point1.STDistance(@point2); +SELECT @point1 . STDistance ( @point2 ); Go +DECLARE @point geometry; +SET @point = geometry::STGeomFromText('POINT(-122.34900 47.65100)', 4326); +Insert INTO SPATIALPOINTGEOM_dt(location) VALUES(geometry::point(@point.STX, @point.STY,4326)) +go + +DECLARE @STX geometry; +SET @STX = geometry::STGeomFromText('POINT(-122.34900 47.65100)', 4326); +select geometry::Point(@STX.STX, @STX.STY, 4326).STX, geometry::Point(@STX.STX, @STX.STY, 4326).STY; +go + +DECLARE @STX geometry; +SET @STX = geometry::STGeomFromText('POINT(-122.34900 47.65100)', 4326); +select geometry::Point(@STX.STX, @STX.STY, 4326).STAsText(), geometry::Point(@STX.STX, @STX.STY, 4326).STAsBinary(), geometry::Point(@STX.STX, @STX.STY, 4326).STDistance(geometry::Point(@STX.STX, @STX.STY, 4326)); +go + +-- Null test for Geospatial functions +DECLARE @point1 geometry, @point2 geometry, @point3 geometry; +SET @point1 = geometry::STPointFromText(null, 4326); +SET @point2 = geometry::STGeomFromText(null, 4326); +SET @point3 = geometry::POINT(22.34900, -47.65100, 4326); +SELECT @point1.STX; +SELECT @point1.STY; +SELECT @point1.STAsText(); +SELECT @point1.STAsBinary(); +SELECT @point1.STDistance(@point2); +SELECT @point3.STDistance(@point2); +SELECT @point1.STDistance(@point3); +Go + +-- Negative test for Geospatial functions +DECLARE @point1 geometry, @point2 varchar(50), @point3 int; +SET @point1 = geometry::POINT(22.34900, -47.65100, 4326);; +SET @point2 = 'Test_String'; +SELECT @point1.STDistance(@point2); +Go + +SELECT location.Lat from SPATIALPOINTGEOM_dt ORDER BY location.STX; +GO + +SELECT * FROM GeomView; +GO + +SELECT * FROM ValFromGeom; +GO + +EXEC dbo.p_getcoordinates; +GO + SELECT * FROM TextFromGeom; GO @@ -41,7 +109,407 @@ GO SELECT * FROM point_distances_geom; GO -SELECT location FROM SPATIALPOINTGEOM_dt; +SELECT location.STX from SPATIALPOINTGEOM_dt ORDER BY location.STX; +GO + +SELECT SPATIALPOINTGEOM_dt.location.STY from SPATIALPOINTGEOM_dt ORDER BY location.STX; +GO + +SELECT location.STAsText() from SPATIALPOINTGEOM_dt ORDER BY location.STX; +GO + +SELECT location.STAsBinary() from SPATIALPOINTGEOM_dt ORDER BY location.STX; +GO + +SELECT location.STDistance(geometry::STGeomFromText('POINT(-122.34900 47.65100)', 4326)) from SPATIALPOINTGEOM_dt ORDER BY location.STX; +GO + +SELECT [SPATIALPOINTGEOM_dt].[location].[STX] from [SPATIALPOINTGEOM_dt] ORDER BY location.STX; +GO + +SELECT [location].[STY] from [SPATIALPOINTGEOM_dt] ORDER BY location.STX; +GO + +SELECT location FROM SPATIALPOINTGEOM_dt ORDER BY location.STX; +GO + +SELECT PointColumn.STX AS XCoordinate FROM YourTable ORDER BY PointColumn.STX; +GO + +SELECT * FROM YourTable WHERE PointColumn.STX > 3.0 ORDER BY PointColumn.STX; +GO + +DECLARE @point geometry = geometry::Point(1.0, 2.0, 4326); +SELECT * FROM YourTable WHERE PointColumn.STX > @point.STX ORDER BY PointColumn.STX; +GO + +SELECT ID, PointColumn.STX AS XCoordinate FROM YourTable ORDER BY PointColumn.STX; +GO + +SELECT ID, dbo.GetXCoordinate(PointColumn) AS XCoordinate FROM YourTable ORDER BY PointColumn.STX; +GO + +DECLARE @point geometry = geometry::Point(1.0, 2.0, 4326); +SELECT dbo.GetXCoordinate(@point); +GO + +SELECT * FROM TableA JOIN TableB ON TableA.PointA.STX = TableB.PointB.STX ORDER BY TableA.PointA.STX; +GO + +DECLARE @point geometry = geometry::Point(1.0, 2.0, 4326); +SELECT * FROM TableA JOIN TableB ON TableA.PointA.STX > @point.STX ORDER BY TableA.PointA.STX; +GO + +SELECT * FROM YourTable ORDER BY PointColumn.STX; +GO + +DECLARE @point geometry = geometry::Point(1.0, 2.0, 4326); +SELECT * FROM YourTable ORDER BY @point.STX; +GO + +SELECT ID, PointColumn.STX AS XCoordinate, +CASE WHEN PointColumn.STX > 3.0 THEN 'High X' +ELSE 'Low X' +END AS XCoordinateCategory FROM YourTable ORDER BY PointColumn.STX; +GO + +DECLARE @point geometry = geometry::Point(1.0, 2.0, 4326); +SELECT ID, PointColumn.STX AS XCoordinate, +CASE WHEN @point.STX > 3.0 THEN 'High X' +ELSE 'Low X' +END AS XCoordinateCategory FROM YourTable ORDER BY PointColumn.STX; +GO + +WITH PointData AS ( SELECT ID, PointColumn.STX AS XCoordinate FROM YourTable ) +SELECT * FROM PointData WHERE XCoordinate > 3.0 ORDER BY XCoordinate; +GO + +DECLARE @point geometry = geometry::Point(1.0, 2.0, 4326); +WITH PointData AS ( SELECT ID, @point.STX AS XCoordinate FROM YourTable ) +SELECT * FROM PointData WHERE XCoordinate > 3.0 ORDER BY XCoordinate; +GO + +SELECT PointColumn.STX AS XCoordinate, COUNT(*) AS PointCount +FROM GeomTab GROUP BY PointColumn.STX ORDER BY PointColumn.STX; +GO + +DECLARE @point geometry = geometry::Point(1.0, 2.0, 4326); +SELECT @point.STX AS XCoordinate, COUNT(*) AS PointCount +FROM YourTable GROUP BY PointColumn.STX ORDER BY PointColumn.STX; +GO + +SELECT ID, PointColumn.STX AS XCoordinate, +PointColumn.STX - LAG(PointColumn.STX) OVER (ORDER BY ID) AS XCoordinateDifference +FROM YourTable ORDER BY PointColumn.STX; +GO + +DECLARE @point geometry = geometry::Point(1.0, 2.0, 4326); +SELECT ID, @point.STX AS XCoordinate, +@point.STX - LAG(@point.STX) OVER (ORDER BY ID) AS XCoordinateDifference +FROM YourTable ORDER BY PointColumn.STX; +GO + +DECLARE @XCoordinate FLOAT = 3.0; +DECLARE @DynamicQuery NVARCHAR(MAX); +SET @DynamicQuery = N' SELECT * FROM YourTable WHERE PointColumn.STX > ' + CAST(@XCoordinate AS NVARCHAR(MAX)) + ' ORDER BY PointColumn.STX'; +EXEC sp_executesql @DynamicQuery; +GO + +DECLARE @point geometry = geometry::Point(1.0, 2.0, 4326); +DECLARE @DynamicQuery NVARCHAR(MAX); +SET @DynamicQuery = N' SELECT * FROM YourTable WHERE PointColumn.STX > ' + CAST(@point.STX AS NVARCHAR(MAX)) + ' ORDER BY PointColumn.STX'; +EXEC sp_executesql @DynamicQuery; +GO + +EXEC GetDistanceByXCoordinate @xCoordinate = 6.0; +GO + +EXEC GetPointsByXCoordinate @XCoordinate = 4.0; +GO + +EXEC GetPointsByXCoordinate1 @XCoordinate = 4.0; +GO + +DECLARE @XCoordinate FLOAT = 3.0; +DECLARE @DynamicQuery NVARCHAR(MAX); +SET @DynamicQuery = N' SELECT * FROM YourTable WHERE PointColumn.STX > ' + CAST(@XCoordinate AS NVARCHAR(MAX)) + ' ORDER BY PointColumn.STX'; +EXEC sp_executesql @DynamicQuery; +GO + +SELECT ID, PointColumn.STX AS XCoordinate, CASE WHEN PointColumn.STX < 0 +THEN 'Negative X' WHEN PointColumn.STX = 0 THEN 'Zero X' +ELSE 'Positive X' END AS XCoordinateCategory FROM YourTable ORDER BY PointColumn.STX; +GO + +DECLARE @point geometry = geometry::Point(1.0, 2.0, 4326); +SELECT ID, @point.STX AS XCoordinate, CASE WHEN @point.STX < 0 +THEN 'Negative X' WHEN @point.STX = 0 THEN 'Zero X' +ELSE 'Positive X' END AS XCoordinateCategory FROM YourTable ORDER BY PointColumn.STX; +GO + +SELECT * FROM ( SELECT ID, +CASE WHEN PointColumn.STX BETWEEN 0 AND 5 THEN '0-5' +WHEN PointColumn.STX BETWEEN 5.1 AND 10 THEN '5.1-10' +ELSE '10.1+' +END AS XCoordRange +FROM YourTable ORDER BY PointColumn.STX +) AS Source +PIVOT ( COUNT(ID) FOR XCoordRange IN ([0-5], [5.1-10], [10.1+])) AS PivotTable; +GO + +SELECT ID, PointColumn.STX AS XCoordinate, +JSON_QUERY('{"XCoordinate":' + CAST(PointColumn.STX AS NVARCHAR(MAX)) + '}') AS XCoordinateJson +FROM YourTable ORDER BY PointColumn.STX; +GO + +DECLARE @point geometry = geometry::Point(3.0, 2.0, 4326); +SELECT ID, @point.STX AS XCoordinate, +JSON_QUERY('{"XCoordinate":' + CAST(@point.STX AS NVARCHAR(MAX)) + '}') AS XCoordinateJson +FROM YourTable ORDER BY PointColumn.STX; +GO + +SELECT [PointColumn].[STX] AS XCoordinate FROM [YourTable] ORDER BY PointColumn.STX; +GO + +DECLARE @point geometry = geometry::Point(3.0, 2.0, 4326); +SELECT @point.[STX] AS XCoordinate +GO + +SELECT PointColumn.STX AS XCoordinate FROM YourTable ORDER BY PointColumn.STX; +GO + +SELECT YourTable.PointColumn.STX AS XCoordinate FROM YourTable ORDER BY PointColumn.STX; +GO + +SELECT dbo.YourTable.PointColumn.STX AS XCoordinate FROM YourTable ORDER BY PointColumn.STX; +GO + +SELECT YourTable1.STX.STX AS XCoordinate FROM YourTable1 ORDER BY STX.STX; +GO + +DECLARE @result geometry; +SET @result = dbo.GetGeometry(); +DECLARE @xCoordinate float; +SET @xCoordinate = @result.STX; +SELECT @result AS ResultGeometry, @xCoordinate AS XCoordinate; +GO + +DECLARE @referencePoint geometry = geometry::Point(0.0, 0.0, 4326); +UPDATE YourTable SET PointColumn = @referencePoint +WHERE PointColumn.STX >= @referencePoint.STX; +GO + +SELECT ID, PointColumn1.STDistance(PointColumn2) AS Distance FROM YourTable2 ORDER BY PointColumn1.STX; +GO + +DECLARE @point1 geometry = geometry::Point(1.0, 2.0, 4326); +SELECT ID, PointColumn1.STDistance(@point1) AS Distance FROM YourTable2 ORDER BY PointColumn1.STX; +GO + +DECLARE @point1 geometry = geometry::Point(1.0, 2.0, 4326); +SELECT ID, @point1.STDistance(PointColumn2) AS Distance FROM YourTable2 ORDER BY PointColumn1.STX; +GO + +DECLARE @referencePoint geometry = geometry::Point(0.0, 0.0, 4326); +DECLARE @maxDistance float = 5.0; +SELECT * FROM YourTable WHERE PointColumn.STDistance(@referencePoint) <= @maxDistance ORDER BY PointColumn.STX; +GO + +DECLARE @referencePoint geometry = geometry::Point(0.0, 0.0, 4326); +SELECT * FROM YourTable WHERE @referencePoint.STDistance(PointColumn) <= @referencePoint.STX ORDER BY PointColumn.STX; +GO + +DECLARE @referencePoint geometry = geometry::Point(0.0, 0.0, 4326); +SELECT * FROM YourTable WHERE PointColumn.STDistance(@referencePoint) <= @referencePoint.STX ORDER BY PointColumn.STX; +GO + +SELECT ID, dbo.CalculateDistance(PointColumn1, PointColumn2) AS Distance FROM YourTable2 ORDER BY PointColumn1.STX; +GO + +DECLARE @referencePoint geometry = geometry::Point(0.0, 0.0, 4326); +SELECT ID, dbo.CalculateDistance(@referencePoint, PointColumn2) AS Distance FROM YourTable2 ORDER BY PointColumn1.STX; +GO + +DECLARE @referencePoint geometry = geometry::Point(0.0, 0.0, 4326); +SELECT ID, dbo.CalculateDistance(PointColumn1, @referencePoint) AS Distance FROM YourTable2 ORDER BY PointColumn1.STX; +GO + +SELECT * FROM TableA JOIN TableB ON PointA.STDistance(TableB.PointB) <= 5.0 ORDER BY TableB.PointB.STX; +GO + +DECLARE @referencePoint geometry = geometry::Point(0.0, 0.0, 4326); +SELECT * FROM TableA JOIN TableB ON @referencePoint.STDistance(TableB.PointB) <= 5.0 ORDER BY TableB.PointB.STX; +GO + +DECLARE @referencePoint geometry = geometry::Point(0.0, 0.0, 4326); +SELECT * FROM TableA JOIN TableB ON PointA.STDistance(@referencePoint) <= 5.0 ORDER BY TableB.PointB.STX; +GO + +DECLARE @referencePoint geometry = geometry::Point(0.0, 0.0, 4326); +SELECT * FROM TableA JOIN TableB ON TableB.PointB.STDistance(@referencePoint) <= 5.0 ORDER BY TableB.PointB.STX; +GO + +SELECT * FROM YourTable2 ORDER BY PointColumn1.STDistance(PointColumn2); +GO + +DECLARE @referencePoint geometry = geometry::Point(0.0, 0.0, 4326); +SELECT * FROM YourTable ORDER BY PointColumn.STDistance(@referencePoint); +GO + +DECLARE @referencePoint geometry = geometry::Point(0.0, 0.0, 4326); +SELECT * FROM YourTable ORDER BY @referencePoint.STDistance(PointColumn); +GO + +DECLARE @thresholdDistance float = 3.0; +SELECT ID, PointColumn1.STDistance(PointColumn2) AS DistanceBetweenPoints, +CASE WHEN PointColumn1.STDistance(PointColumn2) <= @thresholdDistance THEN 'Close' ELSE 'Far' +END AS Proximity +FROM YourTable2 ORDER BY PointColumn1.STX; +GO + +DECLARE @referencePoint geometry = geometry::Point(0.0, 0.0, 4326); +SELECT ID, PointColumn1.STDistance(@referencePoint) AS DistanceBetweenPoints, +CASE WHEN @referencePoint.STDistance(PointColumn2) <= @referencePoint.STX THEN 'Close' ELSE 'Far' +END AS Proximity +FROM YourTable2 ORDER BY PointColumn1.STX; +GO + +DECLARE @referencePoint geometry = geometry::Point(0.0, 0.0, 4326); +WITH DistanceCTE AS ( SELECT ID, PointColumn.STDistance(@referencePoint) AS Distance FROM YourTable ORDER BY PointColumn.STX) +SELECT * FROM DistanceCTE WHERE Distance <= 3.0; +GO + +DECLARE @referencePoint geometry = geometry::Point(0.0, 0.0, 4326); +WITH DistanceCTE AS ( SELECT ID, @referencePoint.STDistance(PointColumn) AS Distance FROM YourTable ORDER BY PointColumn.STX) +SELECT * FROM DistanceCTE WHERE Distance <= 3.0; +GO + +DECLARE @referencePoint geometry = geometry::Point(0.0, 0.0, 4326); +DECLARE @distanceInterval float = 5.0; +SELECT ROUND(PointColumn.STDistance(@referencePoint) / @distanceInterval, 0) * @distanceInterval AS DistanceGroup, +COUNT(*) AS PointCount +FROM YourTable +GROUP BY ROUND(PointColumn.STDistance(@referencePoint) / @distanceInterval, 0) * @distanceInterval; +GO + +DECLARE @referencePoint geometry = geometry::Point(1.0, 0.0, 4326); +SELECT ROUND(PointColumn.STDistance(@referencePoint) / @referencePoint.STX, 0) * @referencePoint.STX AS DistanceGroup, +COUNT(*) AS PointCount +FROM YourTable +GROUP BY ROUND(PointColumn.STDistance(@referencePoint) / @referencePoint.STX, 0) * @referencePoint.STX; +GO + +DECLARE @referencePoint geometry = geometry::Point(0.0, 0.0, 4326); +SELECT ID, PointColumn1.STDistance(PointColumn2) AS Distance, +PointColumn1.STDistance(@referencePoint) - LAG(PointColumn1.STDistance(PointColumn2)) OVER (ORDER BY ID) AS DistanceDifference +FROM YourTable2 ORDER BY PointColumn1.STX; +GO + +DECLARE @referencePoint geometry = geometry::Point(0.0, 0.0, 4326); +SELECT ID, PointColumn.STDistance(@referencePoint) AS Distance, +@referencePoint.STDistance(PointColumn) - LAG(@referencePoint.STX) OVER (ORDER BY ID) AS DistanceDifference +FROM YourTable ORDER BY PointColumn.STX; +GO + +DECLARE @referencePoint geometry = geometry::Point(0.0, 0.0, 4326); +DECLARE @maxDistance float = 3.0; +EXEC GetPointsWithinDistance @referencePoint, @maxDistance; +GO + +DECLARE @referencePoint geometry = geometry::Point(0.0, 0.0, 4326); +DECLARE @maxDistance float = 3.0; +DECLARE @DynamicQuery NVARCHAR(MAX); +SET @DynamicQuery = N' +SELECT * FROM YourTable +WHERE PointColumn.STDistance(geometry::STGeomFromText(' + QUOTENAME(@referencePoint.STAsText(), '''') + ', 4326)) <= ' + CAST(@maxDistance AS NVARCHAR(MAX)) + ' ORDER BY PointColumn.STX'; +EXEC sp_executesql @DynamicQuery; +GO + +DECLARE @referencePoint geometry = geometry::Point(0.0, 0.0, 4326); +DECLARE @DynamicQuery NVARCHAR(MAX); +SET @DynamicQuery = N' +SELECT * FROM YourTable +WHERE PointColumn.STDistance(geometry::STGeomFromText(' + QUOTENAME(@referencePoint.STAsText(), '''') + ', 4326)) <= ' + CAST(@referencePoint.STX AS NVARCHAR(MAX)) + ' ORDER BY PointColumn.STX'; +EXEC sp_executesql @DynamicQuery; +GO + +DECLARE @referencePoint geometry = geometry::Point(0.0, 0.0, 4326); +DECLARE @thresholdDistance float = 3.0; +SELECT ID, PointColumn.STDistance(@referencePoint) AS DistanceToReferencePoint, +CASE WHEN PointColumn.STDistance(@referencePoint) <= @thresholdDistance THEN 'Close' +ELSE 'Far' +END AS Proximity +FROM YourTable ORDER BY PointColumn.STX; +GO + +DECLARE @referencePoint geometry = geometry::Point(0.0, 0.0, 4326); +SELECT ID, @referencePoint.STDistance(PointColumn) AS DistanceToReferencePoint, +CASE WHEN @referencePoint.STDistance(PointColumn) <= @referencePoint.STY THEN 'Close' +ELSE 'Far' +END AS Proximity +FROM YourTable ORDER BY PointColumn.STX; +GO + +DECLARE @distanceRanges TABLE (MinDistance float, MaxDistance float); +INSERT INTO @distanceRanges VALUES (0, 5), (5, 10), (10, 15); +SELECT * FROM ( SELECT ID, +CASE WHEN PointColumn1.STDistance(PointColumn2) BETWEEN 0 AND 5 THEN '0-5' +WHEN PointColumn1.STDistance(PointColumn2) BETWEEN 5.1 AND 10 THEN '5.1-10' +WHEN PointColumn1.STDistance(PointColumn2) BETWEEN 10.1 AND 15 THEN '10.1-15' +ELSE '15.1+' +END AS DistanceRange +FROM YourTable2 ORDER BY PointColumn1.STX +) AS Source +PIVOT ( COUNT(ID) FOR DistanceRange IN ([0-5], [5.1-10], [10.1-15], [15.1+])) AS PivotTable; +GO + +DECLARE @referencePoint geometry = geometry::Point(0.0, 0.0, 4326); +SELECT ID, PointColumn.STDistance(@referencePoint) AS Distance, +JSON_QUERY('{"Distance":' + CAST(PointColumn.STDistance(@referencePoint) AS NVARCHAR(MAX)) + '}') AS DistanceJson +FROM YourTable ORDER BY PointColumn.STX; +GO + +DECLARE @referencePoint geometry = geometry::Point(0.0, 0.0, 4326); +SELECT ID, @referencePoint.STDistance(PointColumn) AS Distance, +JSON_QUERY('{"Distance":' + CAST(@referencePoint.STDistance(PointColumn) AS NVARCHAR(MAX)) + '}') AS DistanceJson +FROM YourTable ORDER BY PointColumn.STX; +GO + +SELECT [PointColumn1].STDistance([PointColumn2]) AS distance FROM [YourTable2] ORDER BY PointColumn1.STX; +GO + +DECLARE @referencePoint geometry = geometry::Point(0.0, 0.0, 4326); +DECLARE @thresholdDistance float = 10.0; +DECLARE @sql NVARCHAR(MAX); +DECLARE @params NVARCHAR(MAX); +SET @sql = N' +SELECT ID, PointColumn.STDistance(@referencePoint) AS DistanceToReferencePoint, +CASE WHEN PointColumn.STDistance(@referencePoint) <= @thresholdDistance THEN ''Close'' +ELSE ''Far'' +END AS Proximity +FROM YourTable +WHERE PointColumn.STDistance(@referencePoint) <= @thresholdDistance ORDER BY PointColumn.STX;'; +SET @params = N'@referencePoint geometry, @thresholdDistance float'; +EXEC sp_executesql @sql, @params, @referencePoint, @thresholdDistance; +GO + +DECLARE @referencePoint geometry = geometry::Point(0.0, 0.0, 4326); +SELECT PointColumn.STDistance(@referencePoint) AS Distance FROM YourTable ORDER BY PointColumn.STX; +SELECT YourTable.PointColumn.STDistance(@referencePoint) AS Distance FROM YourTable ORDER BY PointColumn.STX; +GO + +DECLARE @referencePoint geometry = geometry::Point(0.0, 0.0, 4326); +SELECT dbo.YourTable.PointColumn.STDistance(@referencePoint) AS Distance FROM YourTable ORDER BY PointColumn.STX; +GO + +DECLARE @referencePoint geometry = geometry::Point(0.0, 0.0, 4326); +UPDATE YourTable SET PointColumn = @referencePoint +WHERE PointColumn.STDistance(@referencePoint) <= 2.0; +GO + +DECLARE @referencePoint geometry = geometry::Point(0.0, 0.0, 4326); +UPDATE YourTable SET PointColumn = @referencePoint +WHERE @referencePoint.STDistance(PointColumn) <= 2.0; GO -- Create Type Test Case currently Babelfish supports it but TSQL doesn't for spatial Types, Although it doesn't break anything @@ -139,31 +607,134 @@ GO DECLARE @point geography; SET @point = geography::STGeomFromText('POINT(-122.34900 47.65100)', 4326); SELECT STAsText(@point); +SELECT @point.STAsText(); Go DECLARE @point geography; SET @point = geography::POINT(22.34900, -47.65100, 4326); SELECT STAsText(@point); +SELECT @point.STAsText(); Go DECLARE @point geography; SET @point = geography::STPointFromText('POINT(-122.34900 47.65100)', 4326); -SELECT long(@point); -SELECT lat(@point); +SELECT Long(@point); +SELECT Lat(@point); +SELECT @point.Long; +SELECT @point.Lat; Go DECLARE @point geography; SET @point = geography::POINT(22.34900, -47.65100, 4326); -SELECT long(@point); -SELECT lat(@point); +SELECT Long(@point); +SELECT Lat(@point); +SELECT @point.Long; +SELECT @point.Lat; Go DECLARE @point1 geography, @point2 geography; SET @point1 = geography::STPointFromText('POINT(-122.34900 47.65100)', 4326); SET @point2 = geography::STGeomFromText('POINT(-122.35000 47.65000)', 4326); SELECT STDistance(@point1, @point2); +SELECT @point1.STDistance(@point2); Go +DECLARE @point geography; +SET @point = geography::STGeomFromText('POINT(-22.34900 47.65100)', 4326); +Insert INTO SPATIALPOINTGEOG_dt(location) VALUES(geography::point(@point.Long, @point.Lat, 4326)) +go + +DECLARE @Lat geography; +SET @Lat = geography::STGeomFromText('POINT(-22.34900 47.65100)', 4326); +select geography::Point(@Lat.Long, @Lat.Lat, 4326).Long, geography::Point(@Lat.Long, @Lat.Lat, 4326).Lat; +go + +DECLARE @Lat geography; +SET @Lat = geography::STGeomFromText('POINT(-22.34900 47.65100)', 4326); +select geography::Point(@Lat.Long, @Lat.Lat, 4326).STAsText(), geography::Point(@Lat.Long, @Lat.Lat, 4326).STAsBinary(), geography::Point(@Lat.Long, @Lat.Lat, 4326).STDistance(geography::Point(@Lat.Long, @Lat.Lat, 4326)); +go + +SELECT + SpatialData.ID, + SPATIALPOINTGEOG_dt.location.Lat, + SpatialLocation.STDistance(SPATIALPOINTGEOG_dt.location) +FROM + SpatialData +JOIN + SPATIALPOINTGEOG_dt ON SPATIALPOINTGEOG_dt.location.Long - SpatialData.SpatialLocation.Lat <= 10 +ORDER BY location.Lat; +GO + +WITH RegionLocations AS ( + SELECT + SpatialData.ID, + SPATIALPOINTGEOG_dt.location.Lat + FROM + SpatialData + JOIN + SPATIALPOINTGEOG_dt ON SPATIALPOINTGEOG_dt.location.Long - SpatialData.SpatialLocation.Lat <= 10 + ORDER BY location.Lat +) +SELECT + Lat, + COUNT(ID) AS LocationCount +FROM + RegionLocations +GROUP BY + Lat; +GO + +-- Test with CTE +with mycte (a) +as (select SPATIALPOINTGEOG_dt.location from SPATIALPOINTGEOG_dt) +select a.STAsText() + from mycte x inner join SPATIALPOINTGEOG_dt y on x.a.Lat >= y.location.Long ORDER BY x.a.Lat; +go + +-- Test with tvf +select f.STAsText() + from testspatial_tvf(1) f inner join SPATIALPOINTGEOG_dt t on f.location.Lat >= t.location.Long ORDER BY f.location.Lat; +go + +-- Null test for Geospatial functions +DECLARE @point1 geography, @point2 geography, @point3 geography; +SET @point1 = geography::STPointFromText(null, 4326); +SET @point2 = geography::STGeomFromText(null, 4326); +SET @point3 = geography::POINT(22.34900, -47.65100, 4326); +SELECT @point1.Long; +SELECT @point1.Lat; +SELECT @point1.STAsText(); +SELECT @point1.STAsBinary(); +SELECT @point1.STDistance(@point2); +SELECT @point3.STDistance(@point2); +SELECT @point1.STDistance(@point3); +Go + +-- Negative test for Geospatial functions +DECLARE @point1 geography, @point2 varchar(50), @point3 int; +SET @point1 = geography::POINT(22.34900, -47.65100, 4326); +SET @point2 = 'Test_String'; +SELECT @point2.STDistance(@point1); +Go + +SELECT location.STY from SPATIALPOINTGEOG_dt ORDER BY location.Lat; +GO + +SELECT * FROM GeogView; +GO + +SELECT * FROM SubqueryView; +GO + +SELECT * FROM BrackExprView; +GO + +SELECT * FROM FuncExprView; +GO + +EXEC dbo.proc_getdata; +GO + SELECT * FROM TextFromGeog; GO @@ -182,7 +753,28 @@ GO SELECT * FROM point_distances_geog; GO -SELECT location FROM SPATIALPOINTGEOG_dt; +SELECT location.Lat from SPATIALPOINTGEOG_dt ORDER BY location.Lat; +GO + +SELECT SPATIALPOINTGEOG_dt.location.Long from SPATIALPOINTGEOG_dt ORDER BY location.Lat; +GO + +SELECT location.STAsText() from SPATIALPOINTGEOG_dt ORDER BY location.Lat; +GO + +SELECT location.STAsBinary() from SPATIALPOINTGEOG_dt ORDER BY location.Lat; +GO + +SELECT location.STDistance(geography::STGeomFromText('POINT(-122.34900 47.65100)', 4326)) from SPATIALPOINTGEOG_dt ORDER BY location.Lat; +GO + +SELECT [SPATIALPOINTGEOG_dt].[location].[Long] from [SPATIALPOINTGEOG_dt] ORDER BY location.Lat; +GO + +SELECT [location].[Lat] from [SPATIALPOINTGEOG_dt] ORDER BY location.Lat; +GO + +SELECT location FROM SPATIALPOINTGEOG_dt ORDER BY location.Lat; GO SELECT * FROM GeogToVarbinary; @@ -268,5 +860,137 @@ GO Select CAST(CAST (0xE6100000010C17D9CEF753D34740D34D6210585936C0 AS image) as geography) GO -SELECT * FROM SPATIALPOINT_dt; +SELECT + GeomColumn.STX AS XCoordinate, + GeomColumn.STY AS YCoordinate, + PrimaryKey, + GeogColumn.STDistance(geography::Point(7, 8, 4326)) AS DistanceToFixedPoint +FROM + SPATIALPOINT_dt ORDER BY GeomColumn.STX; +GO + +DECLARE @sql NVARCHAR(MAX); +SET @sql = + N'SELECT ' + + N'GeomColumn.STX AS XCoordinate, ' + + N'GeomColumn.STY AS YCoordinate, ' + + N'PrimaryKey, ' + + N'GeogColumn.STDistance(geography::Point(7, 8, 4326)) AS DistanceToFixedPoint ' + + N'FROM SPATIALPOINT_dt ORDER BY GeomColumn.STX'; + +-- Execute the dynamic SQL +EXEC sp_executesql @sql; +GO + +SELECT * FROM SPATIALPOINT_dt ORDER BY GeomColumn.STX; +GO + +-- Here we are testing ambiguity scenario for func_ref functions but we prioritize Geospatial Call in this case (Needs Documentation) +SELECT geom_schema.STDistance(geom_schema) from geometry_test +GO + +-- Here we are testing ambiguity scenario for col_ref functions but we prioritize Geospatial Call in this case (Needs Documentation) +SELECT STX.STX from STX +GO + +INSERT INTO babelfish_migration_mode_table SELECT current_setting('babelfishpg_tsql.migration_mode') +GO + +-- test multi-db mode +SELECT set_config('role', 'jdbc_user', false); +GO +SELECT set_config('babelfishpg_tsql.migration_mode', 'multi-db', false); +GO + +CREATE DATABASE db1; +GO + +CREATE DATABASE db2; +GO + +USE db1; +GO + +CREATE TABLE SpatialData +( + SpatialPoint GEOMETRY, + PrimaryKey INT +); +GO + +INSERT INTO SpatialData (SpatialPoint, PrimaryKey) +VALUES + (geometry::Point(1, 2, 0), 1), + (geometry::Point(3, 4, 0), 2), + (geometry::Point(5, 6, 0), 3); +GO + +USE db2; +GO + +CREATE TABLE SpatialData +( + SpatialPoint GEOMETRY, + PrimaryKey INT +); +GO + +INSERT INTO SpatialData (SpatialPoint, PrimaryKey) +VALUES + (geometry::Point(7, 8, 0), 4), + (geometry::Point(9, 10, 0), 5), + (geometry::Point(11, 12, 0), 6); +GO + +DECLARE @sql NVARCHAR(MAX); +SET @sql = + N'SELECT ' + + N'[SpatialPoint].[STX] AS XCoordinate, ' + + N'[SpatialPoint].[STY] AS YCoordinate, ' + + N'[PrimaryKey] ' + + N'FROM [db1].[dbo].[SpatialData] ' + + N'UNION ALL ' + + N'SELECT ' + + N'[SpatialPoint].[STX] AS XCoordinate, ' + + N'[SpatialPoint].[STY] AS YCoordinate, ' + + N'[PrimaryKey] ' + + N'FROM [db2].[dbo].[SpatialData] ORDER BY SpatialPoint.STX'; +-- Execute the dynamic SQL +EXEC sp_executesql @sql; +GO + +USE master +GO + +DROP DATABASE db1; +GO + +DROP DATABASE db2; +GO + +SELECT set_config('role', 'jdbc_user', false); +GO + +-- Reset migration mode to default +DECLARE @mig_mode VARCHAR(10) +SET @mig_mode = (SELECT mig_mode FROM babelfish_migration_mode_table WHERE id_num = 1) +SELECT CASE WHEN (SELECT set_config('babelfishpg_tsql.migration_mode', @mig_mode, false)) IS NOT NULL THEN 1 ELSE 0 END +GO + +SELECT name, object_name(t.system_type_id), principal_id, max_length, precision, scale , collation_name, is_nullable, is_user_defined, is_assembly_type, default_object_id, rule_object_id, is_table_type from sys.types t WHERE name = 'geometry' +go + +SELECT name, object_name(t.system_type_id), principal_id, max_length, precision, scale , collation_name, is_nullable, is_user_defined, is_assembly_type, default_object_id, rule_object_id, is_table_type from sys.types t WHERE name = 'geography' +go + +exec sp_sproc_columns_100 @procedure_name= 'geometry_proc_1' +GO + +exec sp_sproc_columns_100 @procedure_name= 'geography_proc_1' +GO + +select * from information_schema.columns where table_name = 'geo_view_test' +GO + +select name , column_id , max_length , precision , scale , collation_name ,is_nullable , is_ansi_padded , is_rowguidcol , is_identity ,is_computed , is_filestream , is_replicated , is_non_sql_subscribed , is_merge_published , is_dts_replicated , is_xml_document , xml_collection_id , default_object_id , rule_object_id , is_sparse , is_column_set , generated_always_type , generated_always_type_desc , encryption_type , encryption_type_desc , encryption_algorithm_name , column_encryption_key_id , column_encryption_key_database_name , is_hidden , is_masked , graph_type , graph_type_desc from sys.columns where object_id = object_id('geo_view_test') ORDER BY name; GO diff --git a/test/JDBC/input/datatypes/TestTvp.txt b/test/JDBC/input/datatypes/TestTvp.txt index e978ef05012..929a2177741 100644 --- a/test/JDBC/input/datatypes/TestTvp.txt +++ b/test/JDBC/input/datatypes/TestTvp.txt @@ -1,8 +1,16 @@ create type tableType as table (a int, b smallint) create type table_variable_vu_type as table (a text not null, b int primary key, c int, d int) create proc table_variable_vu_proc1 (@x table_variable_vu_type readonly) as begin select tvp.b from @x tvp end + prepst#!#Select * from @a #!#tvp|-|tableType|-|utils/tvp-dotnet.csv|-|utils/tvp-dotnet.csv +prepst#!#Select * from @a #!#tvp|-|tableType|-|utils/tvp-dotnet.csv|-|utils/tvp-dotnet.csv +prepst#!#Select * from @a #!#tvp|-|tableType|-|utils/tvp-dotnet.csv|-|utils/tvp-dotnet.csv +prepst#!#Select * from @a #!#tvp|-|tableType|-|utils/tvp-dotnet.csv|-|utils/tvp-dotnet.csv +prepst#!#Select * from @a #!#tvp|-|tableType|-|utils/tvp-dotnet.csv|-|utils/tvp-dotnet.csv +prepst#!#Select * from @a #!#tvp|-|tableType|-|utils/tvp-dotnet.csv|-|utils/tvp-dotnet.csv + + declare @var1 table_variable_vu_type insert into @var1 values ('1', 2, 3, 4) exec sp_executesql N'EXEC table_variable_vu_proc1 @x = @p0', N'@p0 table_variable_vu_type readonly', @p0=@var1 drop procedure table_variable_vu_proc1; drop type table_variable_vu_type; -drop type tableType; \ No newline at end of file +drop type tableType; diff --git a/test/JDBC/input/forjson/forjsonauto-vu-cleanup.sql b/test/JDBC/input/forjson/forjsonauto-vu-cleanup.sql index 7ded18b1a8d..d409a0b27ab 100644 --- a/test/JDBC/input/forjson/forjsonauto-vu-cleanup.sql +++ b/test/JDBC/input/forjson/forjsonauto-vu-cleanup.sql @@ -55,6 +55,35 @@ GO DROP PROCEDURE forjson_vu_p_5 GO +DROP PROCEDURE forjson_vu_p_6 +GO + +DROP PROCEDURE forjson_vu_p_7 +GO + +DROP PROCEDURE forjson_vu_p_8 +GO + +DROP PROCEDURE forjson_vu_p_9 +GO + +DROP PROCEDURE forjson_vu_p_10 +GO + +DROP PROCEDURE forjson_vu_p_11 +GO + +DROP PROCEDURE forjson_vu_p_12 +GO + +DROP PROCEDURE forjson_vu_p_13 +GO + +DROP PROCEDURE forjson_vu_p_14 +GO + +DROP PROCEDURE forjson_vu_p_15 +GO DROP FUNCTION forjson_vu_f_1() GO diff --git a/test/JDBC/input/forjson/forjsonauto-vu-prepare.sql b/test/JDBC/input/forjson/forjsonauto-vu-prepare.sql index 25f254eaa28..9985c4c046e 100644 --- a/test/JDBC/input/forjson/forjsonauto-vu-prepare.sql +++ b/test/JDBC/input/forjson/forjsonauto-vu-prepare.sql @@ -181,3 +181,79 @@ begin end; go +CREATE PROCEDURE forjson_vu_p_6 AS +BEGIN + select top 10 U.id, U.firstname, (select O.productId from forjson_auto_vu_t_orders O where O.userid = U.id for json auto) as details from forjson_auto_vu_t_users U for json auto +END +GO + +CREATE PROCEDURE forjson_vu_p_7 AS +BEGIN + select * from forjson_auto_vu_t_users U where + U.id = (SELECT MAX(O.userid) from forjson_auto_vu_t_orders O) + for json auto +END +GO + +CREATE PROCEDURE forjson_vu_p_8 AS +BEGIN + select * from forjson_auto_vu_t_users U where + U.id = (SELECT MAX(O.userid) from forjson_auto_vu_t_orders O for json auto) + for json auto +END +GO + +CREATE PROCEDURE forjson_vu_p_9 AS +BEGIN + select distinct top 10 + U.id, + (select distinct O.productId from forjson_auto_vu_t_orders O where O.userid = U.id) + as details + from forjson_auto_vu_t_users U + group by U.id + for json auto +END +GO + +CREATE PROCEDURE forjson_vu_p_10 AS +BEGIN + select distinct top 2 + U.Id, + O.orderdate + from forjson_auto_vu_t_users U INNER JOIN + forjson_auto_vu_t_orders O ON U.Id = O.Id + for json auto +END +GO + +CREATE PROCEDURE forjson_vu_p_11 AS +BEGIN + select distinct top 10 U.id, (select distinct O.productId from forjson_auto_vu_t_orders O where O.userid = U.id for json auto) as details from forjson_auto_vu_t_users U group by U.id for json auto +END +GO + +CREATE PROCEDURE forjson_vu_p_12 AS +BEGIN + select U.id, U.firstname, (select U.lastname, O.productId from forjson_auto_vu_t_orders O where O.userid = U.id for json auto) as details from forjson_auto_vu_t_users U for json auto +END +GO + +CREATE PROCEDURE forjson_vu_p_13 AS +BEGIN + select * from forjson_auto_vu_t_users U where U.Id = (SELECT MAX(O.userid) from forjson_auto_vu_t_orders O) for json auto +END +GO + +CREATE PROCEDURE forjson_vu_p_14 AS +BEGIN + select U.id, U.firstname, (select P.price, O.productId from forjson_auto_vu_t_orders O JOIN forjson_auto_vu_t_products P ON (P.id = O.productid) for json auto) as "details" from forjson_auto_vu_t_users U for json auto +END +GO + +CREATE PROCEDURE forjson_vu_p_15 AS + BEGIN + DECLARE @json_string NVARCHAR(2000) + SET @json_string = (select P.price, O.productId from forjson_auto_vu_t_orders O JOIN forjson_auto_vu_t_products P ON (P.id = O.productid) for json auto) + select U.id, U.firstname, @json_string as details from forjson_auto_vu_t_users U for json auto +END +GO diff --git a/test/JDBC/input/forjson/forjsonauto-vu-verify.sql b/test/JDBC/input/forjson/forjsonauto-vu-verify.sql index 6c56020438e..628bcfec2b4 100644 --- a/test/JDBC/input/forjson/forjsonauto-vu-verify.sql +++ b/test/JDBC/input/forjson/forjsonauto-vu-verify.sql @@ -55,6 +55,36 @@ GO EXECUTE forjson_vu_p_5 GO +EXECUTE forjson_vu_p_6 +GO + +EXECUTE forjson_vu_p_7 +GO + +EXECUTE forjson_vu_p_8 +GO + +EXECUTE forjson_vu_p_9 +GO + +EXECUTE forjson_vu_p_10 +GO + +EXECUTE forjson_vu_p_11 +GO + +EXECUTE forjson_vu_p_12 +GO + +EXECUTE forjson_vu_p_13 +GO + +EXECUTE forjson_vu_p_14 +GO + +EXECUTE forjson_vu_p_15 +GO + SELECT forjson_vu_f_1() GO diff --git a/test/JDBC/input/operator_atatvar-vu-cleanup.sql b/test/JDBC/input/operator_atatvar-vu-cleanup.sql index a293980220a..c7fbcaf5df5 100644 --- a/test/JDBC/input/operator_atatvar-vu-cleanup.sql +++ b/test/JDBC/input/operator_atatvar-vu-cleanup.sql @@ -1,6 +1,9 @@ drop view v1_operator_atatvar go +drop view v2_operator_atatvar +go + drop procedure p1_operator_atatvar go @@ -9,3 +12,9 @@ go drop procedure p3_operator_atatvar go + +drop function f1_operator_atatvar +go + +drop function f2_operator_atatvar +go diff --git a/test/JDBC/input/operator_atatvar-vu-prepare.sql b/test/JDBC/input/operator_atatvar-vu-prepare.sql index 14f69b597fa..296bbba1479 100644 --- a/test/JDBC/input/operator_atatvar-vu-prepare.sql +++ b/test/JDBC/input/operator_atatvar-vu-prepare.sql @@ -2,6 +2,10 @@ create view v1_operator_atatvar as select c=@@max_precision where 0! =@@max_precision go +create view v2_operator_atatvar as +select c=@@max_precision where 0=@@max_precision +go + create procedure p1_operator_atatvar as if 1=@@max_precision select 'yes' else select 'no' @@ -28,4 +32,17 @@ go create procedure p3_operator_atatvar @p int as select @p -go \ No newline at end of file +go + +create function f1_operator_atatvar(@p int) returns int +as +begin + if @p=@@spid return 1 + else return 0 +end +go + +create function f2_operator_atatvar(@p int) returns table +as + return select 1 as c where @p=@@max_precision +go diff --git a/test/JDBC/input/operator_atatvar-vu-verify.sql b/test/JDBC/input/operator_atatvar-vu-verify.sql index e513cfad766..037ddfd9923 100644 --- a/test/JDBC/input/operator_atatvar-vu-verify.sql +++ b/test/JDBC/input/operator_atatvar-vu-verify.sql @@ -94,6 +94,12 @@ go select * from v1_operator_atatvar where case when 1!=@@max_precision then 1 else @@max_precision end=@@max_precision go +select * from v2_operator_atatvar where 0!<@@max_precision +go + +select * from v2_operator_atatvar where case when 1!=@@max_precision then 1 else @@max_precision end=@@max_precision +go + declare @v int set @v=1 set @v+=@v @@ -120,3 +126,14 @@ go execute('execute p3_operator_atatvar @p=@@max_precision') go +select dbo.f1_operator_atatvar(@@spid) +go + +select dbo.f1_operator_atatvar(@@spid-1) +go + +select * from dbo.f2_operator_atatvar(@@max_precision) +go + +select * from dbo.f2_operator_atatvar(@@max_precision-1) +go \ No newline at end of file diff --git a/test/JDBC/input/order_by_offset_fetch_rows-before-15_6-or-16_2-vu-cleanup.sql b/test/JDBC/input/order_by_offset_fetch_rows-before-15_6-or-16_2-vu-cleanup.sql new file mode 100644 index 00000000000..6025c743571 --- /dev/null +++ b/test/JDBC/input/order_by_offset_fetch_rows-before-15_6-or-16_2-vu-cleanup.sql @@ -0,0 +1,8 @@ +DROP PROC p1_upgr_order_by_offset_fetch +go +DROP FUNCTION f1_upgr_order_by_offset_fetch +go +DROP VIEW v1_upgr_order_by_offset_fetch +go +DROP table t1_upgr_order_by_offset_fetch +go \ No newline at end of file diff --git a/test/JDBC/input/order_by_offset_fetch_rows-before-15_6-or-16_2-vu-prepare.sql b/test/JDBC/input/order_by_offset_fetch_rows-before-15_6-or-16_2-vu-prepare.sql new file mode 100644 index 00000000000..ca1a86b3b6f --- /dev/null +++ b/test/JDBC/input/order_by_offset_fetch_rows-before-15_6-or-16_2-vu-prepare.sql @@ -0,0 +1,8 @@ +create table t1_upgr_order_by_offset_fetch(a int, b int) +go +CREATE PROC p1_upgr_order_by_offset_fetch @p int=1,@q int=1 AS SELECT * FROM t1_upgr_order_by_offset_fetch ORDER BY b OFFSET @p*@q ROWS FETCH NEXT square(@q)+1 ROWS ONLY +go +CREATE FUNCTION f1_upgr_order_by_offset_fetch(@p int, @q int) returns int as begin declare @v int SELECT @v=count(a) FROM t1_upgr_order_by_offset_fetch group by b ORDER BY b OFFSET @p*@q ROWS FETCH NEXT square(@q)+1 ROWS ONLY return @v end +go +CREATE VIEW v1_upgr_order_by_offset_fetch as select * FROM t1_upgr_order_by_offset_fetch ORDER BY b OFFSET 5 ROWS FETCH NEXT 3 rows only +go diff --git a/test/JDBC/input/order_by_offset_fetch_rows-before-15_6-or-16_2-vu-verify.sql b/test/JDBC/input/order_by_offset_fetch_rows-before-15_6-or-16_2-vu-verify.sql new file mode 100644 index 00000000000..3866ab3e719 --- /dev/null +++ b/test/JDBC/input/order_by_offset_fetch_rows-before-15_6-or-16_2-vu-verify.sql @@ -0,0 +1,15 @@ +insert t1_upgr_order_by_offset_fetch select generate_series, 0 from generate_series(1,100) +go +update t1_upgr_order_by_offset_fetch set b=a +go +exec p1_upgr_order_by_offset_fetch 1, 3 +go +exec p1_upgr_order_by_offset_fetch 2, 3 +go +p1_upgr_order_by_offset_fetch 3, 3 +go +select dbo.f1_upgr_order_by_offset_fetch(1,1) +go +select * from v1_upgr_order_by_offset_fetch +go + diff --git a/test/JDBC/input/order_by_offset_fetch_rows-vu-cleanup.sql b/test/JDBC/input/order_by_offset_fetch_rows-vu-cleanup.sql new file mode 100644 index 00000000000..a91f430520f --- /dev/null +++ b/test/JDBC/input/order_by_offset_fetch_rows-vu-cleanup.sql @@ -0,0 +1,8 @@ +DROP PROC p1_order_by_offset_fetch +go +DROP FUNCTION f1_order_by_offset_fetch +go +DROP VIEW v1_order_by_offset_fetch +go +DROP table t1_order_by_offset_fetch +go \ No newline at end of file diff --git a/test/JDBC/input/order_by_offset_fetch_rows-vu-prepare.sql b/test/JDBC/input/order_by_offset_fetch_rows-vu-prepare.sql new file mode 100644 index 00000000000..4235ed47092 --- /dev/null +++ b/test/JDBC/input/order_by_offset_fetch_rows-vu-prepare.sql @@ -0,0 +1,12 @@ +create table t1_order_by_offset_fetch(a int, b int) +go +insert t1_order_by_offset_fetch select generate_series, 0 from generate_series(1,100) +go +update t1_order_by_offset_fetch set b=a +go +CREATE PROC p1_order_by_offset_fetch @p int=1,@q int=1 AS SELECT * FROM t1_order_by_offset_fetch ORDER BY b OFFSET @p*@q ROWS FETCH NEXT square(@q)+1 ROWS ONLY +go +CREATE FUNCTION f1_order_by_offset_fetch(@p int, @q int) returns int as begin declare @v int SELECT @v=count(a) FROM t1_order_by_offset_fetch group by b ORDER BY b OFFSET @p*@q ROWS FETCH NEXT square(@q)+1 ROWS ONLY return @v end +go +CREATE VIEW v1_order_by_offset_fetch as select * FROM t1_order_by_offset_fetch ORDER BY b OFFSET 5 ROWS FETCH NEXT 3 rows only +go diff --git a/test/JDBC/input/order_by_offset_fetch_rows-vu-verify.sql b/test/JDBC/input/order_by_offset_fetch_rows-vu-verify.sql new file mode 100644 index 00000000000..2bb09eed607 --- /dev/null +++ b/test/JDBC/input/order_by_offset_fetch_rows-vu-verify.sql @@ -0,0 +1,78 @@ +declare @p int =2,@q int=3 SELECT * FROM t1_order_by_offset_fetch ORDER BY b OFFSET (@p*5) ROWS FETCH NEXT (5) ROWS ONLY +go +declare @p int =2,@q int=3 SELECT * FROM t1_order_by_offset_fetch ORDER BY b OFFSET (@p*5) ROW FETCH NEXT 5 ROW ONLY +go +declare @p int =2,@q int=3 SELECT * FROM t1_order_by_offset_fetch ORDER BY b OFFSET (@p*5) ROWS FETCH NEXT @q ROWS ONLY +go +declare @p int =2,@q int=3 SELECT * FROM t1_order_by_offset_fetch ORDER BY b OFFSET (@p*5) ROWS FETCH NEXT 1+2 ROWS ONLY +go +declare @p int =2,@q int=3 SELECT * FROM t1_order_by_offset_fetch ORDER BY b OFFSET (@p*5) ROWS FETCH NEXT (1+2) ROWS ONLY +go +declare @p int =2,@q int=3 SELECT * FROM t1_order_by_offset_fetch ORDER BY b OFFSET @p ROWS FETCH NEXT +3 ROWS ONLY +go +declare @p int =2,@q int=0 SELECT * FROM t1_order_by_offset_fetch ORDER BY b OFFSET @p ROWS FETCH NEXT @q ROWS ONLY +go +declare @p int =0,@q int=1 SELECT * FROM t1_order_by_offset_fetch ORDER BY b OFFSET @p ROWS FETCH NEXT @q ROWS ONLY +go +declare @p int =2,@q int=3 SELECT * FROM t1_order_by_offset_fetch ORDER BY b OFFSET @p ROWS FETCH NEXT @q ROWS ONLY +go +declare @p int =2,@q int=3 SELECT * FROM t1_order_by_offset_fetch ORDER BY b OFFSET 1+1 ROWS FETCH NEXT 2 ROWS ONLY +go +declare @p int =2,@q int=3 SELECT * FROM t1_order_by_offset_fetch ORDER BY b OFFSET 1+1 ROWS FETCH NEXT @q ROWS ONLY +go +declare @p int =2,@q int=0 SELECT * FROM t1_order_by_offset_fetch ORDER BY b OFFSET @p*1 ROWS FETCH NEXT @q ROWS ONLY +go +declare @p int =2,@q int=1 SELECT * FROM t1_order_by_offset_fetch ORDER BY b OFFSET @p*1 ROWS FETCH NEXT @q ROWS ONLY +go +declare @p int =0,@q int=3 SELECT * FROM t1_order_by_offset_fetch ORDER BY b OFFSET @p*1 ROWS FETCH NEXT @q ROWS ONLY +go +declare @p int =1,@q int=3 SELECT * FROM t1_order_by_offset_fetch ORDER BY b OFFSET @p*1 ROWS FETCH NEXT @q ROWS ONLY +go +declare @p int =3,@q int=3 SELECT * FROM t1_order_by_offset_fetch ORDER BY b OFFSET @p+1 ROWS FETCH NEXT @q ROWS ONLY +go +declare @p int =3,@q int=3 SELECT * FROM t1_order_by_offset_fetch ORDER BY b OFFSET @p*2 ROWS FETCH NEXT @q ROWS ONLY +go +declare @p int =1,@q int=3 SELECT * FROM t1_order_by_offset_fetch ORDER BY b OFFSET @p*@q ROWS FETCH NEXT @q ROWS ONLY +go +declare @p int =2,@q int=3 SELECT * FROM t1_order_by_offset_fetch ORDER BY b OFFSET @p*@q ROWS FETCH NEXT @q ROWS ONLY +go +declare @p int=2,@q int=0 SELECT * FROM t1_order_by_offset_fetch ORDER BY b OFFSET @p*@q ROWS FETCH NEXT @q ROWS ONLY +go +declare @p int=1,@q int=3 SELECT * FROM t1_order_by_offset_fetch ORDER BY b OFFSET @p*@q ROWS FETCH NEXT @q ROWS ONLY +go +declare @p int=2,@q int=3 SELECT * FROM t1_order_by_offset_fetch ORDER BY b OFFSET @p*@q ROWS FETCH NEXT @q ROWS ONLY +go +declare @p int =2,@q int=3 SELECT * FROM t1_order_by_offset_fetch ORDER BY b OFFSET square(2) ROWS FETCH NEXT @q ROWS ONLY +go +declare @p int =2,@q int=3 SELECT * FROM t1_order_by_offset_fetch ORDER BY b OFFSET square(1)*@p ROWS FETCH NEXT @q ROWS ONLY +go +declare @p int =2,@q int=3 SELECT * FROM t1_order_by_offset_fetch ORDER BY b OFFSET square(@p)+@p ROWS FETCH NEXT @q+1 ROWS ONLY +go +declare @p int=2,@q int=3 SELECT * FROM t1_order_by_offset_fetch ORDER BY b OFFSET @p*1 ROWS FETCH NEXT @q ROWS ONLY +go +declare @p int =2,@q int=3 SELECT * FROM t1_order_by_offset_fetch ORDER BY b OFFSET square(1)*@p+1 ROWS FETCH NEXT @q ROWS ONLY +go +declare @p int =2,@q int=3 SELECT * FROM t1_order_by_offset_fetch ORDER BY b OFFSET square(1)*(@p) ROWS FETCH NEXT @q ROWS ONLY +go +declare @p int =2,@q int=3 SELECT * FROM t1_order_by_offset_fetch ORDER BY b OFFSET square(1)*@p ROWS FETCH NEXT @q ROWS ONLY +go +declare @p int =2,@q int=3 SELECT * FROM t1_order_by_offset_fetch ORDER BY b OFFSET @p*square(1) ROWS FETCH NEXT @q*square(1) ROWS ONLY +go +declare @p int =2,@q int=3 SELECT * FROM t1_order_by_offset_fetch ORDER BY b OFFSET square(1)*@p ROWS FETCH NEXT square(1)+@q ROWS ONLY +go +declare @p int =2,@q int=3 SELECT * FROM t1_order_by_offset_fetch ORDER BY b OFFSET square(1)* @p ROWS FETCH NEXT square(@q)*@q+1 ROWS ONLY +go +declare @p int =2,@q int=3 SELECT * FROM t1_order_by_offset_fetch ORDER BY b OFFSET square(1)*3+1 ROWS FETCH NEXT @p+1 ROWS ONLY +go +declare @p int =2,@q int=3 SELECT * FROM t1_order_by_offset_fetch ORDER BY b OFFSET (@p*@p) ROWS FETCH NEXT @p*@q ROWS ONLY +go +exec p1_order_by_offset_fetch 1, 3 +go +exec p1_order_by_offset_fetch 2, 3 +go +p1_order_by_offset_fetch 3, 3 +go +select dbo.f1_order_by_offset_fetch(1,1) +go +select * from v1_order_by_offset_fetch +go \ No newline at end of file diff --git a/test/JDBC/input/table_constraint_without_comma-vu-cleanup.sql b/test/JDBC/input/table_constraint_without_comma-vu-cleanup.sql new file mode 100644 index 00000000000..a0c190ce01d --- /dev/null +++ b/test/JDBC/input/table_constraint_without_comma-vu-cleanup.sql @@ -0,0 +1,48 @@ +DROP FUNCTION f1_tvf_nocomma +go +DROP FUNCTION f2_tvf_nocomma +go +DROP FUNCTION f3_tvf_nocomma +go +DROP FUNCTION f4_tvf_nocomma +go +DROP FUNCTION f5_tvf_nocomma +go +DROP FUNCTION f6_tvf_nocomma +go +DROP FUNCTION f7_tvf_nocomma +go +DROP FUNCTION f8_tvf_nocomma +go +DROP FUNCTION f9_tvf_nocomma +go +DROP PROCEDURE p1_tv_nocomma +go +DROP PROCEDURE p2_tv_nocomma +go +DROP PROCEDURE p3_tv_nocomma +go +DROP PROCEDURE p4_tv_nocomma +go +DROP PROCEDURE p5_tv_nocomma +go +DROP PROCEDURE p6_tv_nocomma +go +DROP PROCEDURE p7_tv_nocomma +go +DROP PROCEDURE p8_tv_nocomma +go +DROP PROCEDURE p9_tv_nocomma +go +DROP TABLE t1_tvf_nocomma +go +DROP TABLE t2_tvf_nocomma +go +DROP TABLE t3_tvf_nocomma +go +DROP TABLE t4_tvf_nocomma +go +DROP TABLE t5_tvf_nocomma +go +DROP TABLE t6_tvf_nocomma +go diff --git a/test/JDBC/input/table_constraint_without_comma-vu-prepare.sql b/test/JDBC/input/table_constraint_without_comma-vu-prepare.sql new file mode 100644 index 00000000000..51e60e6ded2 --- /dev/null +++ b/test/JDBC/input/table_constraint_without_comma-vu-prepare.sql @@ -0,0 +1,153 @@ +CREATE FUNCTION f1_tvf_nocomma(@p INT) +RETURNS @tv TABLE (a INT NOT NULL, b INT NOT NULL PRIMARY KEY(a)) +AS +BEGIN + INSERT @tv VALUES(1,2) + IF @p > 0 INSERT @tv VALUES(1,3) + RETURN +END +go +CREATE FUNCTION f2_tvf_nocomma(@p INT) +RETURNS @tv TABLE (a INT NOT NULL, b INT NOT NULL PRIMARY KEY(a,b)) +AS +BEGIN + INSERT @tv VALUES(1,2) + IF @p > 0 INSERT @tv VALUES(1,2) + RETURN +END +go +CREATE FUNCTION f3_tvf_nocomma(@p INT) +RETURNS @tv TABLE (a INT NOT NULL, b INT NOT NULL PRIMARY KEY(a)) +AS +BEGIN + INSERT @tv VALUES(1,2) + IF @p > 0 INSERT @tv VALUES(1,3) + RETURN +END +go +CREATE FUNCTION f4_tvf_nocomma(@p INT) +RETURNS @tv TABLE (a INT NOT NULL, b INT NOT NULL UNIQUE(a,b)) +AS +BEGIN + INSERT @tv VALUES(1,2) + IF @p > 0 INSERT @tv VALUES(1,2) + RETURN +END +go +CREATE FUNCTION f5_tvf_nocomma(@p INT) +RETURNS @tv TABLE (a INT NOT NULL, b INT NOT NULL PRIMARY KEY) +AS +BEGIN + INSERT @tv VALUES(1,2) + IF @p > 0 INSERT @tv VALUES(2,2) + RETURN +END +go +CREATE FUNCTION f6_tvf_nocomma(@p INT) +RETURNS @tv TABLE (a INT NOT NULL PRIMARY KEY, b INT NOT NULL) +AS +BEGIN + INSERT @tv VALUES(1,2) + IF @p > 0 INSERT @tv VALUES(1,3) + RETURN +END +go +CREATE FUNCTION f7_tvf_nocomma(@p INT) +RETURNS @tv TABLE (a INT NOT NULL, b INT NOT NULL UNIQUE) +AS +BEGIN + INSERT @tv VALUES(1,2) + IF @p > 0 INSERT @tv VALUES(2,2) + RETURN +END +go +CREATE FUNCTION f8_tvf_nocomma(@p INT) +RETURNS @tv TABLE (a INT NOT NULL UNIQUE, b INT NOT NULL) +AS +BEGIN + INSERT @tv VALUES(1,2) + IF @p > 0 INSERT @tv VALUES(1,3) + RETURN +END +go +CREATE FUNCTION f9_tvf_nocomma(@p INT) +RETURNS @tv TABLE (a INT NOT NULL, b INT NOT NULL CHECK(a>0)) +AS +BEGIN + INSERT @tv VALUES(1,2) + IF @p > 0 INSERT @tv VALUES(0,3) + RETURN +END +go +CREATE PROCEDURE p1_tv_nocomma +AS +BEGIN + DECLARE @tv TABLE (a INT NOT NULL, b INT NOT NULL PRIMARY KEY(a)) + INSERT @tv VALUES(1,2) + INSERT @tv VALUES(1,3) +END +go +CREATE PROCEDURE p2_tv_nocomma +AS +BEGIN + DECLARE @tv TABLE (a INT NOT NULL, b INT NOT NULL PRIMARY KEY(a,b)) + INSERT @tv VALUES(1,2) + INSERT @tv VALUES(1,2) +END +go +CREATE PROCEDURE p3_tv_nocomma +AS +BEGIN + DECLARE @tv TABLE (a INT NOT NULL, b INT NOT NULL PRIMARY KEY(a)) + INSERT @tv VALUES(1,2) + INSERT @tv VALUES(1,3) +END +go +CREATE PROCEDURE p4_tv_nocomma +AS +BEGIN + DECLARE @tv TABLE (a INT NOT NULL, b INT NOT NULL UNIQUE(a,b)) + INSERT @tv VALUES(1,2) + INSERT @tv VALUES(1,2) +END +go +CREATE PROCEDURE p5_tv_nocomma +AS +BEGIN + DECLARE @tv TABLE (a INT NOT NULL, b INT NOT NULL PRIMARY KEY) + INSERT @tv VALUES(1,2) + INSERT @tv VALUES(2,2) +END +go +CREATE PROCEDURE p6_tv_nocomma +AS +BEGIN + DECLARE @tv TABLE (a INT NOT NULL PRIMARY KEY, b INT NOT NULL) + INSERT @tv VALUES(1,2) + INSERT @tv VALUES(1,3) +END +go +CREATE PROCEDURE p7_tv_nocomma +AS +BEGIN + DECLARE @tv TABLE (a INT NOT NULL, b INT NOT NULL UNIQUE) + INSERT @tv VALUES(1,2) + INSERT @tv VALUES(2,2) +END +go +CREATE PROCEDURE p8_tv_nocomma +AS +BEGIN + DECLARE @tv TABLE (a INT NOT NULL UNIQUE, b INT NOT NULL) + INSERT @tv VALUES(1,2) + INSERT @tv VALUES(1,3) +END +go +CREATE PROCEDURE p9_tv_nocomma +AS +BEGIN + DECLARE @tv TABLE (a INT NOT NULL, b INT NOT NULL CHECK(a>0)) + INSERT @tv VALUES(1,2) + INSERT @tv VALUES(0,3) +END +go diff --git a/test/JDBC/input/table_constraint_without_comma-vu-verify.sql b/test/JDBC/input/table_constraint_without_comma-vu-verify.sql new file mode 100644 index 00000000000..0f124dd8fa0 --- /dev/null +++ b/test/JDBC/input/table_constraint_without_comma-vu-verify.sql @@ -0,0 +1,133 @@ +-- table variable +DECLARE @tv_nocomma TABLE(a INT NOT NULL, b INT PRIMARY KEY(a)) +insert @tv_nocomma values (1,2) +insert @tv_nocomma values (1,3) +go +DECLARE @tv_nocomma TABLE(a INT NOT NULL, b INT NOT NULL PRIMARY KEY(a,b)) +insert @tv_nocomma values (1,2) +insert @tv_nocomma values (1,2) +go +DECLARE @tv_nocomma TABLE(a INT NOT NULL, b INT UNIQUE(a)) +insert @tv_nocomma values (1,2) +insert @tv_nocomma values (1,3) +go +DECLARE @tv_nocomma TABLE(a INT NOT NULL, b INT NOT NULL UNIQUE(a,b)) +insert @tv_nocomma values (1,2) +insert @tv_nocomma values (1,2) +go + +-- already worked correctly before the fix: +DECLARE @tv_nocomma TABLE(a INT NOT NULL, b INT NOT NULL PRIMARY KEY) +insert @tv_nocomma values (1,2) +insert @tv_nocomma values (2,2) +go +DECLARE @tv_nocomma TABLE(a INT NOT NULL PRIMARY KEY, b INT NOT NULL) +insert @tv_nocomma values (1,2) +insert @tv_nocomma values (1,3) +go +DECLARE @tv_nocomma TABLE(a INT NOT NULL, b INT NOT NULL UNIQUE) +insert @tv_nocomma values (1,2) +insert @tv_nocomma values (2,2) +go +DECLARE @tv_nocomma TABLE(a INT NOT NULL UNIQUE, b INT NOT NULL) +insert @tv_nocomma values (1,2) +insert @tv_nocomma values (1,3) +go +DECLARE @tv_nocomma TABLE(a INT NOT NULL, b INT NOT NULL CHECK(a>0)) +insert @tv_nocomma values (1,2) +insert @tv_nocomma values (0,3) +go + +-- TVF return table +SELECT * FROM f1_tvf_nocomma(0) +go +SELECT * FROM f1_tvf_nocomma(1) +go +SELECT * FROM f2_tvf_nocomma(0) +go +SELECT * FROM f2_tvf_nocomma(1) +go +SELECT * FROM f3_tvf_nocomma(0) +go +SELECT * FROM f3_tvf_nocomma(1) +go +SELECT * FROM f4_tvf_nocomma(0) +go +SELECT * FROM f4_tvf_nocomma(1) +go +SELECT * FROM f5_tvf_nocomma(0) +go +SELECT * FROM f5_tvf_nocomma(1) +go +SELECT * FROM f6_tvf_nocomma(0) +go +SELECT * FROM f6_tvf_nocomma(1) +go +SELECT * FROM f7_tvf_nocomma(0) +go +SELECT * FROM f7_tvf_nocomma(1) +go +SELECT * FROM f8_tvf_nocomma(0) +go +SELECT * FROM f8_tvf_nocomma(1) +go +SELECT * FROM f9_tvf_nocomma(0) +go +SELECT * FROM f9_tvf_nocomma(1) +go + +-- stored procedures +EXECUTE p1_tv_nocomma +go +EXECUTE p2_tv_nocomma +go +EXECUTE p3_tv_nocomma +go +EXECUTE p4_tv_nocomma +go +EXECUTE p5_tv_nocomma +go +EXECUTE p6_tv_nocomma +go +EXECUTE p7_tv_nocomma +go +EXECUTE p8_tv_nocomma +go +EXECUTE p9_tv_nocomma +go + +-- regular tables and #tmp tables already worked correctly before the fix: +create table t1_tvf_nocomma (a INT NOT NULL, b INT NOT NULL PRIMARY KEY(a)) +insert t1_tvf_nocomma values (1,2) +insert t1_tvf_nocomma values (1,3) +go + +create table t2_tvf_nocomma (a INT NOT NULL, b INT NOT NULL PRIMARY KEY) +insert t2_tvf_nocomma values (1,2) +insert t2_tvf_nocomma values (1,3) +go + +create table t3_tvf_nocomma (a INT NOT NULL PRIMARY KEY, b INT NOT NULL) +insert t3_tvf_nocomma values (1,2) +insert t3_tvf_nocomma values (1,3) +go + +create table t4_tvf_nocomma (a INT NOT NULL, b INT NOT NULL UNIQUE(a)) +insert t4_tvf_nocomma values (1,2) +insert t4_tvf_nocomma values (1,3) +go + +create table t5_tvf_nocomma (a INT NOT NULL, b INT NOT NULL UNIQUE) +insert t5_tvf_nocomma values (1,2) +insert t5_tvf_nocomma values (1,3) +go + +create table t6_tvf_nocomma (a INT NOT NULL UNIQUE, b INT NOT NULL) +insert t6_tvf_nocomma values (1,2) +insert t6_tvf_nocomma values (1,3) +go + +create table #t7_tvf_nocomma (a INT NOT NULL, b INT NOT NULL UNIQUE(a)) +insert #t7_tvf_nocomma values (1,2) +insert #t7_tvf_nocomma values (1,3) +go diff --git a/test/JDBC/input/table_constraint_wo_comma-before-15_6-or-16_2-vu-cleanup.sql b/test/JDBC/input/table_constraint_wo_comma-before-15_6-or-16_2-vu-cleanup.sql new file mode 100644 index 00000000000..dfbaf5acf73 --- /dev/null +++ b/test/JDBC/input/table_constraint_wo_comma-before-15_6-or-16_2-vu-cleanup.sql @@ -0,0 +1,18 @@ +DROP PROCEDURE p1_tv_nocomma +go +DROP PROCEDURE p2_tv_nocomma +go +DROP PROCEDURE p3_tv_nocomma +go +DROP PROCEDURE p4_tv_nocomma +go +DROP PROCEDURE p5_tv_nocomma +go +DROP PROCEDURE p6_tv_nocomma +go +DROP PROCEDURE p7_tv_nocomma +go +DROP PROCEDURE p8_tv_nocomma +go +DROP PROCEDURE p9_tv_nocomma +go diff --git a/test/JDBC/input/table_constraint_wo_comma-before-15_6-or-16_2-vu-prepare.sql b/test/JDBC/input/table_constraint_wo_comma-before-15_6-or-16_2-vu-prepare.sql new file mode 100644 index 00000000000..98951548722 --- /dev/null +++ b/test/JDBC/input/table_constraint_wo_comma-before-15_6-or-16_2-vu-prepare.sql @@ -0,0 +1,72 @@ +CREATE PROCEDURE p1_tv_nocomma +AS +BEGIN + DECLARE @tv TABLE (a INT NOT NULL, b INT NOT NULL PRIMARY KEY(a)) + INSERT @tv VALUES(1,2) + INSERT @tv VALUES(1,3) +END +go +CREATE PROCEDURE p2_tv_nocomma +AS +BEGIN + DECLARE @tv TABLE (a INT NOT NULL, b INT NOT NULL PRIMARY KEY(a,b)) + INSERT @tv VALUES(1,2) + INSERT @tv VALUES(1,2) +END +go +CREATE PROCEDURE p3_tv_nocomma +AS +BEGIN + DECLARE @tv TABLE (a INT NOT NULL, b INT NOT NULL PRIMARY KEY(a)) + INSERT @tv VALUES(1,2) + INSERT @tv VALUES(1,3) +END +go +CREATE PROCEDURE p4_tv_nocomma +AS +BEGIN + DECLARE @tv TABLE (a INT NOT NULL, b INT NOT NULL UNIQUE(a,b)) + INSERT @tv VALUES(1,2) + INSERT @tv VALUES(1,2) +END +go +CREATE PROCEDURE p5_tv_nocomma +AS +BEGIN + DECLARE @tv TABLE (a INT NOT NULL, b INT NOT NULL PRIMARY KEY) + INSERT @tv VALUES(1,2) + INSERT @tv VALUES(2,2) +END +go +CREATE PROCEDURE p6_tv_nocomma +AS +BEGIN + DECLARE @tv TABLE (a INT NOT NULL PRIMARY KEY, b INT NOT NULL) + INSERT @tv VALUES(1,2) + INSERT @tv VALUES(1,3) +END +go +CREATE PROCEDURE p7_tv_nocomma +AS +BEGIN + DECLARE @tv TABLE (a INT NOT NULL, b INT NOT NULL UNIQUE) + INSERT @tv VALUES(1,2) + INSERT @tv VALUES(2,2) +END +go +CREATE PROCEDURE p8_tv_nocomma +AS +BEGIN + DECLARE @tv TABLE (a INT NOT NULL UNIQUE, b INT NOT NULL) + INSERT @tv VALUES(1,2) + INSERT @tv VALUES(1,3) +END +go +CREATE PROCEDURE p9_tv_nocomma +AS +BEGIN + DECLARE @tv TABLE (a INT NOT NULL, b INT NOT NULL CHECK(a>0)) + INSERT @tv VALUES(1,2) + INSERT @tv VALUES(0,3) +END +go diff --git a/test/JDBC/input/table_constraint_wo_comma-before-15_6-or-16_2-vu-verify.sql b/test/JDBC/input/table_constraint_wo_comma-before-15_6-or-16_2-vu-verify.sql new file mode 100644 index 00000000000..90d0230d12c --- /dev/null +++ b/test/JDBC/input/table_constraint_wo_comma-before-15_6-or-16_2-vu-verify.sql @@ -0,0 +1,18 @@ +EXECUTE p1_tv_nocomma +go +EXECUTE p2_tv_nocomma +go +EXECUTE p3_tv_nocomma +go +EXECUTE p4_tv_nocomma +go +EXECUTE p5_tv_nocomma +go +EXECUTE p6_tv_nocomma +go +EXECUTE p7_tv_nocomma +go +EXECUTE p8_tv_nocomma +go +EXECUTE p9_tv_nocomma +go diff --git a/test/JDBC/input/table_variables/table-variable-vu-verify.sql b/test/JDBC/input/table_variables/table-variable-vu-verify.sql index 6fbdbdfe3d9..7c19e5ac220 100644 --- a/test/JDBC/input/table_variables/table-variable-vu-verify.sql +++ b/test/JDBC/input/table_variables/table-variable-vu-verify.sql @@ -1,3 +1,4 @@ +-- parallel_query_expected --babel-1149 select * from table_variable_vu_prepareitvf_1(5); GO diff --git a/test/JDBC/input/views/sys-assembly_types-vu-prepare.sql b/test/JDBC/input/views/sys-assembly_types-vu-prepare.sql index 08bffefed13..5805dd44cdc 100644 --- a/test/JDBC/input/views/sys-assembly_types-vu-prepare.sql +++ b/test/JDBC/input/views/sys-assembly_types-vu-prepare.sql @@ -1,9 +1,9 @@ CREATE VIEW sys_assembly_types_view_vu_prepare AS -SELECT * FROM sys.assembly_types +SELECT name, principal_id, max_length, precision, scale, collation_name, is_nullable, is_user_defined, is_assembly_type, default_object_id, rule_object_id, assembly_id, assembly_class, is_binary_ordered, is_fixed_length, prog_id, assembly_qualified_name, is_table_type FROM sys.assembly_types GO CREATE PROC sys_assembly_types_proc_vu_prepare AS -SELECT * FROM sys.assembly_types +SELECT name, principal_id, max_length, precision, scale, collation_name, is_nullable, is_user_defined, is_assembly_type, default_object_id, rule_object_id, assembly_id, assembly_class, is_binary_ordered, is_fixed_length, prog_id, assembly_qualified_name, is_table_type FROM sys.assembly_types GO CREATE FUNCTION sys_assembly_types_func_vu_prepare() diff --git a/test/JDBC/input/views/sys-assembly_types-vu-verify.sql b/test/JDBC/input/views/sys-assembly_types-vu-verify.sql index 4dff5510fee..0bb2b45bad2 100644 --- a/test/JDBC/input/views/sys-assembly_types-vu-verify.sql +++ b/test/JDBC/input/views/sys-assembly_types-vu-verify.sql @@ -8,5 +8,5 @@ SELECT * FROM sys_assembly_types_func_vu_prepare() GO -- Test from sys-assembly_types.sql -SELECT * FROM sys.assembly_types +SELECT name, principal_id, max_length, precision, scale, collation_name, is_nullable, is_user_defined, is_assembly_type, default_object_id, rule_object_id, assembly_id, assembly_class, is_binary_ordered, is_fixed_length, prog_id, assembly_qualified_name, is_table_type FROM sys.assembly_types GO diff --git a/test/JDBC/jdbc_schedule b/test/JDBC/jdbc_schedule index 9995dd1631a..90d5157c778 100644 --- a/test/JDBC/jdbc_schedule +++ b/test/JDBC/jdbc_schedule @@ -39,6 +39,9 @@ ignore#!#sys-types-before-dep-vu-cleanup ignore#!#sys-table_types-before-dep-vu-prepare ignore#!#sys-table_types-before-dep-vu-verify ignore#!#sys-table_types-before-dep-vu-cleanup +ignore#!#GRANT_SCHEMA-vu-prepare +ignore#!#GRANT_SCHEMA-vu-verify +ignore#!#GRANT_SCHEMA-vu-cleanup # These tests are meant for upgrade scenario prior to (potential) 14_5 release ignore#!#BABEL-3147-before-14_5-vu-prepare diff --git a/test/JDBC/parallel_query_jdbc_schedule b/test/JDBC/parallel_query_jdbc_schedule index 905bf400ee0..6803b7b1db1 100644 --- a/test/JDBC/parallel_query_jdbc_schedule +++ b/test/JDBC/parallel_query_jdbc_schedule @@ -6,8 +6,6 @@ # 5. To add a test, add test name (without extension, , and . For example if test file name is TestBigInt.txt write TestBigInt) on a new line # These tests are crashing/failing with parallel query mode is on. -ignore#!#table-variable-vu-verify - # These test should not get run in parallel query ignore#!#BABEL-1363 diff --git a/test/JDBC/upgrade/13_4/schedule b/test/JDBC/upgrade/13_4/schedule index f7561b3eb8f..13c60a4ef75 100644 --- a/test/JDBC/upgrade/13_4/schedule +++ b/test/JDBC/upgrade/13_4/schedule @@ -216,9 +216,11 @@ TestXML timefromparts triggers_with_transaction BABEL-4046 +table_constraint_wo_comma-before-15_6-or-16_2 getdate AUTO_ANALYZE-before-15-5-or-14-10 cast_eliminate +order_by_offset_fetch_rows-before-15_6-or-16_2 TestDatatypeAggSort babel_index_nulls_order-before-15-5 operator_binary_whitespace-before-15_6-or-16_2 diff --git a/test/JDBC/upgrade/13_5/preparation/sys-assembly_types-vu-prepare.sql b/test/JDBC/upgrade/13_5/preparation/sys-assembly_types-vu-prepare.sql index 08bffefed13..ef7c296a506 100644 --- a/test/JDBC/upgrade/13_5/preparation/sys-assembly_types-vu-prepare.sql +++ b/test/JDBC/upgrade/13_5/preparation/sys-assembly_types-vu-prepare.sql @@ -3,7 +3,7 @@ SELECT * FROM sys.assembly_types GO CREATE PROC sys_assembly_types_proc_vu_prepare AS -SELECT * FROM sys.assembly_types +SELECT name, principal_id, max_length, precision, scale, collation_name, is_nullable, is_user_defined, is_assembly_type, default_object_id, rule_object_id, assembly_id, assembly_class, is_binary_ordered, is_fixed_length, prog_id, assembly_qualified_name, is_table_type FROM sys.assembly_types GO CREATE FUNCTION sys_assembly_types_func_vu_prepare() diff --git a/test/JDBC/upgrade/13_5/schedule b/test/JDBC/upgrade/13_5/schedule index 5aeba4b971d..3c0ff342417 100644 --- a/test/JDBC/upgrade/13_5/schedule +++ b/test/JDBC/upgrade/13_5/schedule @@ -269,9 +269,11 @@ TestXML timefromparts triggers_with_transaction BABEL-4046 +table_constraint_wo_comma-before-15_6-or-16_2 getdate AUTO_ANALYZE-before-15-5-or-14-10 cast_eliminate +order_by_offset_fetch_rows-before-15_6-or-16_2 TestDatatypeAggSort babel_index_nulls_order-before-15-5 operator_binary_whitespace-before-15_6-or-16_2 diff --git a/test/JDBC/upgrade/13_6/preparation/sys-assembly_types-vu-prepare.sql b/test/JDBC/upgrade/13_6/preparation/sys-assembly_types-vu-prepare.sql index 08bffefed13..ef7c296a506 100644 --- a/test/JDBC/upgrade/13_6/preparation/sys-assembly_types-vu-prepare.sql +++ b/test/JDBC/upgrade/13_6/preparation/sys-assembly_types-vu-prepare.sql @@ -3,7 +3,7 @@ SELECT * FROM sys.assembly_types GO CREATE PROC sys_assembly_types_proc_vu_prepare AS -SELECT * FROM sys.assembly_types +SELECT name, principal_id, max_length, precision, scale, collation_name, is_nullable, is_user_defined, is_assembly_type, default_object_id, rule_object_id, assembly_id, assembly_class, is_binary_ordered, is_fixed_length, prog_id, assembly_qualified_name, is_table_type FROM sys.assembly_types GO CREATE FUNCTION sys_assembly_types_func_vu_prepare() diff --git a/test/JDBC/upgrade/13_6/schedule b/test/JDBC/upgrade/13_6/schedule index b8c1043a2a2..20c3ba53b98 100644 --- a/test/JDBC/upgrade/13_6/schedule +++ b/test/JDBC/upgrade/13_6/schedule @@ -323,6 +323,7 @@ TestXML timefromparts triggers_with_transaction BABEL-4046 +table_constraint_wo_comma-before-15_6-or-16_2 getdate BABEL-4410 AUTO_ANALYZE-before-15-5-or-14-10 @@ -333,3 +334,4 @@ BABEL-2999 drop_index-before-15_6-or-16_2 permission_restrictions_from_pg BABEL-730-before-15_6-or-16_1 +GRANT_SCHEMA diff --git a/test/JDBC/upgrade/13_7/schedule b/test/JDBC/upgrade/13_7/schedule index b9f6d73e619..ff2d30685b1 100644 --- a/test/JDBC/upgrade/13_7/schedule +++ b/test/JDBC/upgrade/13_7/schedule @@ -317,9 +317,11 @@ TestXML timefromparts triggers_with_transaction BABEL-4046 +table_constraint_wo_comma-before-15_6-or-16_2 getdate AUTO_ANALYZE-before-15-5-or-14-10 cast_eliminate +order_by_offset_fetch_rows-before-15_6-or-16_2 TestDatatypeAggSort babel_index_nulls_order-before-15-5 operator_binary_whitespace-before-15_6-or-16_2 diff --git a/test/JDBC/upgrade/13_8/preparation/sys-assembly_types-vu-prepare.sql b/test/JDBC/upgrade/13_8/preparation/sys-assembly_types-vu-prepare.sql index 08bffefed13..ef7c296a506 100644 --- a/test/JDBC/upgrade/13_8/preparation/sys-assembly_types-vu-prepare.sql +++ b/test/JDBC/upgrade/13_8/preparation/sys-assembly_types-vu-prepare.sql @@ -3,7 +3,7 @@ SELECT * FROM sys.assembly_types GO CREATE PROC sys_assembly_types_proc_vu_prepare AS -SELECT * FROM sys.assembly_types +SELECT name, principal_id, max_length, precision, scale, collation_name, is_nullable, is_user_defined, is_assembly_type, default_object_id, rule_object_id, assembly_id, assembly_class, is_binary_ordered, is_fixed_length, prog_id, assembly_qualified_name, is_table_type FROM sys.assembly_types GO CREATE FUNCTION sys_assembly_types_func_vu_prepare() diff --git a/test/JDBC/upgrade/13_8/schedule b/test/JDBC/upgrade/13_8/schedule index b9f6d73e619..ff2d30685b1 100644 --- a/test/JDBC/upgrade/13_8/schedule +++ b/test/JDBC/upgrade/13_8/schedule @@ -317,9 +317,11 @@ TestXML timefromparts triggers_with_transaction BABEL-4046 +table_constraint_wo_comma-before-15_6-or-16_2 getdate AUTO_ANALYZE-before-15-5-or-14-10 cast_eliminate +order_by_offset_fetch_rows-before-15_6-or-16_2 TestDatatypeAggSort babel_index_nulls_order-before-15-5 operator_binary_whitespace-before-15_6-or-16_2 diff --git a/test/JDBC/upgrade/13_9/preparation/sys-assembly_types-vu-prepare.sql b/test/JDBC/upgrade/13_9/preparation/sys-assembly_types-vu-prepare.sql index 08bffefed13..ef7c296a506 100644 --- a/test/JDBC/upgrade/13_9/preparation/sys-assembly_types-vu-prepare.sql +++ b/test/JDBC/upgrade/13_9/preparation/sys-assembly_types-vu-prepare.sql @@ -3,7 +3,7 @@ SELECT * FROM sys.assembly_types GO CREATE PROC sys_assembly_types_proc_vu_prepare AS -SELECT * FROM sys.assembly_types +SELECT name, principal_id, max_length, precision, scale, collation_name, is_nullable, is_user_defined, is_assembly_type, default_object_id, rule_object_id, assembly_id, assembly_class, is_binary_ordered, is_fixed_length, prog_id, assembly_qualified_name, is_table_type FROM sys.assembly_types GO CREATE FUNCTION sys_assembly_types_func_vu_prepare() diff --git a/test/JDBC/upgrade/13_9/schedule b/test/JDBC/upgrade/13_9/schedule index 63ca88a217d..2af9d65e15d 100644 --- a/test/JDBC/upgrade/13_9/schedule +++ b/test/JDBC/upgrade/13_9/schedule @@ -319,10 +319,12 @@ TestXML timefromparts triggers_with_transaction BABEL-4046 +table_constraint_wo_comma-before-15_6-or-16_2 getdate BABEL-4410 AUTO_ANALYZE-before-15-5-or-14-10 cast_eliminate +order_by_offset_fetch_rows-before-15_6-or-16_2 TestDatatypeAggSort babel_index_nulls_order-before-15-5 operator_binary_whitespace-before-15_6-or-16_2 @@ -330,3 +332,4 @@ BABEL-2999 drop_index-before-15_6-or-16_2 permission_restrictions_from_pg BABEL-730-before-15_6-or-16_1 +GRANT_SCHEMA diff --git a/test/JDBC/upgrade/14_10/schedule b/test/JDBC/upgrade/14_10/schedule index 9475e157e47..02d9e47f8a8 100644 --- a/test/JDBC/upgrade/14_10/schedule +++ b/test/JDBC/upgrade/14_10/schedule @@ -414,6 +414,7 @@ BABEL-4384 default_params BABEL-3326 cast_eliminate +order_by_offset_fetch_rows-before-15_6-or-16_2 TestDatatypeAggSort babel_index_nulls_order-before-15-5 operator_binary_whitespace-before-15_6-or-16_2 @@ -424,4 +425,5 @@ sys-parsename-before-15_6-or-16_1 permission_restrictions_from_pg BABEL-4529-before-15_6-or-14_11 BABEL-730-before-15_6-or-16_1 +GRANT_SCHEMA babel-4475 diff --git a/test/JDBC/upgrade/14_11/schedule b/test/JDBC/upgrade/14_11/schedule index 6464b74bc9a..6e6cc1eba9b 100644 --- a/test/JDBC/upgrade/14_11/schedule +++ b/test/JDBC/upgrade/14_11/schedule @@ -414,6 +414,7 @@ BABEL-4384 default_params BABEL-3326 cast_eliminate +order_by_offset_fetch_rows-before-15_6-or-16_2 TestDatatypeAggSort babel_index_nulls_order-before-15-5 operator_binary_whitespace-before-15_6-or-16_2 diff --git a/test/JDBC/upgrade/14_3/preparation/sys-assembly_types-vu-prepare.sql b/test/JDBC/upgrade/14_3/preparation/sys-assembly_types-vu-prepare.sql index 08bffefed13..ef7c296a506 100644 --- a/test/JDBC/upgrade/14_3/preparation/sys-assembly_types-vu-prepare.sql +++ b/test/JDBC/upgrade/14_3/preparation/sys-assembly_types-vu-prepare.sql @@ -3,7 +3,7 @@ SELECT * FROM sys.assembly_types GO CREATE PROC sys_assembly_types_proc_vu_prepare AS -SELECT * FROM sys.assembly_types +SELECT name, principal_id, max_length, precision, scale, collation_name, is_nullable, is_user_defined, is_assembly_type, default_object_id, rule_object_id, assembly_id, assembly_class, is_binary_ordered, is_fixed_length, prog_id, assembly_qualified_name, is_table_type FROM sys.assembly_types GO CREATE FUNCTION sys_assembly_types_func_vu_prepare() diff --git a/test/JDBC/upgrade/14_3/schedule b/test/JDBC/upgrade/14_3/schedule index 6816fd88458..69ee8effa2a 100644 --- a/test/JDBC/upgrade/14_3/schedule +++ b/test/JDBC/upgrade/14_3/schedule @@ -336,11 +336,13 @@ TestXML timefromparts triggers_with_transaction BABEL-4046 +table_constraint_wo_comma-before-15_6-or-16_2 BABEL_4330 BABEL-2619 BABEL-4410 AUTO_ANALYZE-before-15-5-or-14-10 cast_eliminate +order_by_offset_fetch_rows-before-15_6-or-16_2 TestDatatypeAggSort babel_index_nulls_order-before-15-5 operator_binary_whitespace-before-15_6-or-16_2 @@ -348,3 +350,4 @@ BABEL-2999 drop_index-before-15_6-or-16_2 permission_restrictions_from_pg BABEL-730-before-15_6-or-16_1 +GRANT_SCHEMA diff --git a/test/JDBC/upgrade/14_5/schedule b/test/JDBC/upgrade/14_5/schedule index d65e7e00249..65fc5be41df 100644 --- a/test/JDBC/upgrade/14_5/schedule +++ b/test/JDBC/upgrade/14_5/schedule @@ -350,12 +350,14 @@ TestXML timefromparts triggers_with_transaction BABEL-4046 +table_constraint_wo_comma-before-15_6-or-16_2 getdate BABEL_4330 BABEL-2619 BABEL-4410 AUTO_ANALYZE-before-15-5-or-14-10 cast_eliminate +order_by_offset_fetch_rows-before-15_6-or-16_2 TestDatatypeAggSort babel_index_nulls_order-before-15-5 operator_binary_whitespace-before-15_6-or-16_2 @@ -363,3 +365,4 @@ BABEL-2999 drop_index-before-15_6-or-16_2 permission_restrictions_from_pg BABEL-730-before-15_6-or-16_1 +GRANT_SCHEMA diff --git a/test/JDBC/upgrade/14_5/verification_cleanup/13_5/sys-assembly_types-vu-verify.sql b/test/JDBC/upgrade/14_5/verification_cleanup/13_5/sys-assembly_types-vu-verify.sql index 4dff5510fee..0bb2b45bad2 100644 --- a/test/JDBC/upgrade/14_5/verification_cleanup/13_5/sys-assembly_types-vu-verify.sql +++ b/test/JDBC/upgrade/14_5/verification_cleanup/13_5/sys-assembly_types-vu-verify.sql @@ -8,5 +8,5 @@ SELECT * FROM sys_assembly_types_func_vu_prepare() GO -- Test from sys-assembly_types.sql -SELECT * FROM sys.assembly_types +SELECT name, principal_id, max_length, precision, scale, collation_name, is_nullable, is_user_defined, is_assembly_type, default_object_id, rule_object_id, assembly_id, assembly_class, is_binary_ordered, is_fixed_length, prog_id, assembly_qualified_name, is_table_type FROM sys.assembly_types GO diff --git a/test/JDBC/upgrade/14_5/verification_cleanup/13_6/sys-assembly_types-vu-verify.sql b/test/JDBC/upgrade/14_5/verification_cleanup/13_6/sys-assembly_types-vu-verify.sql index 4dff5510fee..0bb2b45bad2 100644 --- a/test/JDBC/upgrade/14_5/verification_cleanup/13_6/sys-assembly_types-vu-verify.sql +++ b/test/JDBC/upgrade/14_5/verification_cleanup/13_6/sys-assembly_types-vu-verify.sql @@ -8,5 +8,5 @@ SELECT * FROM sys_assembly_types_func_vu_prepare() GO -- Test from sys-assembly_types.sql -SELECT * FROM sys.assembly_types +SELECT name, principal_id, max_length, precision, scale, collation_name, is_nullable, is_user_defined, is_assembly_type, default_object_id, rule_object_id, assembly_id, assembly_class, is_binary_ordered, is_fixed_length, prog_id, assembly_qualified_name, is_table_type FROM sys.assembly_types GO diff --git a/test/JDBC/upgrade/14_5/verification_cleanup/13_7/sys-assembly_types-vu-verify.sql b/test/JDBC/upgrade/14_5/verification_cleanup/13_7/sys-assembly_types-vu-verify.sql index 4dff5510fee..0bb2b45bad2 100644 --- a/test/JDBC/upgrade/14_5/verification_cleanup/13_7/sys-assembly_types-vu-verify.sql +++ b/test/JDBC/upgrade/14_5/verification_cleanup/13_7/sys-assembly_types-vu-verify.sql @@ -8,5 +8,5 @@ SELECT * FROM sys_assembly_types_func_vu_prepare() GO -- Test from sys-assembly_types.sql -SELECT * FROM sys.assembly_types +SELECT name, principal_id, max_length, precision, scale, collation_name, is_nullable, is_user_defined, is_assembly_type, default_object_id, rule_object_id, assembly_id, assembly_class, is_binary_ordered, is_fixed_length, prog_id, assembly_qualified_name, is_table_type FROM sys.assembly_types GO diff --git a/test/JDBC/upgrade/14_5/verification_cleanup/13_8/sys-assembly_types-vu-verify.sql b/test/JDBC/upgrade/14_5/verification_cleanup/13_8/sys-assembly_types-vu-verify.sql index 4dff5510fee..0bb2b45bad2 100644 --- a/test/JDBC/upgrade/14_5/verification_cleanup/13_8/sys-assembly_types-vu-verify.sql +++ b/test/JDBC/upgrade/14_5/verification_cleanup/13_8/sys-assembly_types-vu-verify.sql @@ -8,5 +8,5 @@ SELECT * FROM sys_assembly_types_func_vu_prepare() GO -- Test from sys-assembly_types.sql -SELECT * FROM sys.assembly_types +SELECT name, principal_id, max_length, precision, scale, collation_name, is_nullable, is_user_defined, is_assembly_type, default_object_id, rule_object_id, assembly_id, assembly_class, is_binary_ordered, is_fixed_length, prog_id, assembly_qualified_name, is_table_type FROM sys.assembly_types GO diff --git a/test/JDBC/upgrade/14_5/verification_cleanup/14_3/sys-assembly_types-vu-verify.sql b/test/JDBC/upgrade/14_5/verification_cleanup/14_3/sys-assembly_types-vu-verify.sql index 4dff5510fee..0bb2b45bad2 100644 --- a/test/JDBC/upgrade/14_5/verification_cleanup/14_3/sys-assembly_types-vu-verify.sql +++ b/test/JDBC/upgrade/14_5/verification_cleanup/14_3/sys-assembly_types-vu-verify.sql @@ -8,5 +8,5 @@ SELECT * FROM sys_assembly_types_func_vu_prepare() GO -- Test from sys-assembly_types.sql -SELECT * FROM sys.assembly_types +SELECT name, principal_id, max_length, precision, scale, collation_name, is_nullable, is_user_defined, is_assembly_type, default_object_id, rule_object_id, assembly_id, assembly_class, is_binary_ordered, is_fixed_length, prog_id, assembly_qualified_name, is_table_type FROM sys.assembly_types GO diff --git a/test/JDBC/upgrade/14_6/schedule b/test/JDBC/upgrade/14_6/schedule index ea17e6ac5b2..934e6d7f74e 100644 --- a/test/JDBC/upgrade/14_6/schedule +++ b/test/JDBC/upgrade/14_6/schedule @@ -385,12 +385,14 @@ TestXML timefromparts triggers_with_transaction BABEL-4046 +table_constraint_wo_comma-before-15_6-or-16_2 getdate BABEL_4330 BABEL-2619 BABEL-4410 AUTO_ANALYZE-before-15-5-or-14-10 cast_eliminate +order_by_offset_fetch_rows-before-15_6-or-16_2 TestDatatypeAggSort babel_index_nulls_order-before-15-5 operator_binary_whitespace-before-15_6-or-16_2 @@ -398,3 +400,4 @@ BABEL-2999 drop_index-before-15_6-or-16_2 permission_restrictions_from_pg BABEL-730-before-15_6-or-16_1 +GRANT_SCHEMA diff --git a/test/JDBC/upgrade/14_6/verification_cleanup/13_5/sys-assembly_types-vu-verify.sql b/test/JDBC/upgrade/14_6/verification_cleanup/13_5/sys-assembly_types-vu-verify.sql index 4dff5510fee..0bb2b45bad2 100644 --- a/test/JDBC/upgrade/14_6/verification_cleanup/13_5/sys-assembly_types-vu-verify.sql +++ b/test/JDBC/upgrade/14_6/verification_cleanup/13_5/sys-assembly_types-vu-verify.sql @@ -8,5 +8,5 @@ SELECT * FROM sys_assembly_types_func_vu_prepare() GO -- Test from sys-assembly_types.sql -SELECT * FROM sys.assembly_types +SELECT name, principal_id, max_length, precision, scale, collation_name, is_nullable, is_user_defined, is_assembly_type, default_object_id, rule_object_id, assembly_id, assembly_class, is_binary_ordered, is_fixed_length, prog_id, assembly_qualified_name, is_table_type FROM sys.assembly_types GO diff --git a/test/JDBC/upgrade/14_6/verification_cleanup/13_6/sys-assembly_types-vu-verify.sql b/test/JDBC/upgrade/14_6/verification_cleanup/13_6/sys-assembly_types-vu-verify.sql index 4dff5510fee..0bb2b45bad2 100644 --- a/test/JDBC/upgrade/14_6/verification_cleanup/13_6/sys-assembly_types-vu-verify.sql +++ b/test/JDBC/upgrade/14_6/verification_cleanup/13_6/sys-assembly_types-vu-verify.sql @@ -8,5 +8,5 @@ SELECT * FROM sys_assembly_types_func_vu_prepare() GO -- Test from sys-assembly_types.sql -SELECT * FROM sys.assembly_types +SELECT name, principal_id, max_length, precision, scale, collation_name, is_nullable, is_user_defined, is_assembly_type, default_object_id, rule_object_id, assembly_id, assembly_class, is_binary_ordered, is_fixed_length, prog_id, assembly_qualified_name, is_table_type FROM sys.assembly_types GO diff --git a/test/JDBC/upgrade/14_6/verification_cleanup/13_7/sys-assembly_types-vu-verify.sql b/test/JDBC/upgrade/14_6/verification_cleanup/13_7/sys-assembly_types-vu-verify.sql index 4dff5510fee..0bb2b45bad2 100644 --- a/test/JDBC/upgrade/14_6/verification_cleanup/13_7/sys-assembly_types-vu-verify.sql +++ b/test/JDBC/upgrade/14_6/verification_cleanup/13_7/sys-assembly_types-vu-verify.sql @@ -8,5 +8,5 @@ SELECT * FROM sys_assembly_types_func_vu_prepare() GO -- Test from sys-assembly_types.sql -SELECT * FROM sys.assembly_types +SELECT name, principal_id, max_length, precision, scale, collation_name, is_nullable, is_user_defined, is_assembly_type, default_object_id, rule_object_id, assembly_id, assembly_class, is_binary_ordered, is_fixed_length, prog_id, assembly_qualified_name, is_table_type FROM sys.assembly_types GO diff --git a/test/JDBC/upgrade/14_6/verification_cleanup/13_8/sys-assembly_types-vu-verify.sql b/test/JDBC/upgrade/14_6/verification_cleanup/13_8/sys-assembly_types-vu-verify.sql index 4dff5510fee..0bb2b45bad2 100644 --- a/test/JDBC/upgrade/14_6/verification_cleanup/13_8/sys-assembly_types-vu-verify.sql +++ b/test/JDBC/upgrade/14_6/verification_cleanup/13_8/sys-assembly_types-vu-verify.sql @@ -8,5 +8,5 @@ SELECT * FROM sys_assembly_types_func_vu_prepare() GO -- Test from sys-assembly_types.sql -SELECT * FROM sys.assembly_types +SELECT name, principal_id, max_length, precision, scale, collation_name, is_nullable, is_user_defined, is_assembly_type, default_object_id, rule_object_id, assembly_id, assembly_class, is_binary_ordered, is_fixed_length, prog_id, assembly_qualified_name, is_table_type FROM sys.assembly_types GO diff --git a/test/JDBC/upgrade/14_6/verification_cleanup/13_9/sys-assembly_types-vu-verify.sql b/test/JDBC/upgrade/14_6/verification_cleanup/13_9/sys-assembly_types-vu-verify.sql index 4dff5510fee..0bb2b45bad2 100644 --- a/test/JDBC/upgrade/14_6/verification_cleanup/13_9/sys-assembly_types-vu-verify.sql +++ b/test/JDBC/upgrade/14_6/verification_cleanup/13_9/sys-assembly_types-vu-verify.sql @@ -8,5 +8,5 @@ SELECT * FROM sys_assembly_types_func_vu_prepare() GO -- Test from sys-assembly_types.sql -SELECT * FROM sys.assembly_types +SELECT name, principal_id, max_length, precision, scale, collation_name, is_nullable, is_user_defined, is_assembly_type, default_object_id, rule_object_id, assembly_id, assembly_class, is_binary_ordered, is_fixed_length, prog_id, assembly_qualified_name, is_table_type FROM sys.assembly_types GO diff --git a/test/JDBC/upgrade/14_6/verification_cleanup/14_3/sys-assembly_types-vu-verify.sql b/test/JDBC/upgrade/14_6/verification_cleanup/14_3/sys-assembly_types-vu-verify.sql index 4dff5510fee..0bb2b45bad2 100644 --- a/test/JDBC/upgrade/14_6/verification_cleanup/14_3/sys-assembly_types-vu-verify.sql +++ b/test/JDBC/upgrade/14_6/verification_cleanup/14_3/sys-assembly_types-vu-verify.sql @@ -8,5 +8,5 @@ SELECT * FROM sys_assembly_types_func_vu_prepare() GO -- Test from sys-assembly_types.sql -SELECT * FROM sys.assembly_types +SELECT name, principal_id, max_length, precision, scale, collation_name, is_nullable, is_user_defined, is_assembly_type, default_object_id, rule_object_id, assembly_id, assembly_class, is_binary_ordered, is_fixed_length, prog_id, assembly_qualified_name, is_table_type FROM sys.assembly_types GO diff --git a/test/JDBC/upgrade/14_7/schedule b/test/JDBC/upgrade/14_7/schedule index 639768a4134..37cfe9dcd74 100644 --- a/test/JDBC/upgrade/14_7/schedule +++ b/test/JDBC/upgrade/14_7/schedule @@ -407,11 +407,13 @@ timefromparts triggers_with_transaction datetimeoffset-timezone-before-15_3 BABEL-4046 +table_constraint_wo_comma-before-15_6-or-16_2 getdate BABEL_4330 BABEL-2619 AUTO_ANALYZE-before-15-5-or-14-10 cast_eliminate +order_by_offset_fetch_rows-before-15_6-or-16_2 TestDatatypeAggSort babel_index_nulls_order-before-15-5 operator_binary_whitespace-before-15_6-or-16_2 diff --git a/test/JDBC/upgrade/14_8/schedule b/test/JDBC/upgrade/14_8/schedule index 02cc4498742..c2621375b41 100644 --- a/test/JDBC/upgrade/14_8/schedule +++ b/test/JDBC/upgrade/14_8/schedule @@ -405,12 +405,14 @@ timefromparts triggers_with_transaction datetimeoffset-timezone-before-15_3 BABEL-4046 +table_constraint_wo_comma-before-15_6-or-16_2 getdate BABEL_4330 BABEL-2619 AUTO_ANALYZE-before-15-5-or-14-10 default_params cast_eliminate +order_by_offset_fetch_rows-before-15_6-or-16_2 TestDatatypeAggSort babel_index_nulls_order-before-15-5 operator_binary_whitespace-before-15_6-or-16_2 diff --git a/test/JDBC/upgrade/14_9/schedule b/test/JDBC/upgrade/14_9/schedule index 5ff4a2538a9..bbe48ee6016 100644 --- a/test/JDBC/upgrade/14_9/schedule +++ b/test/JDBC/upgrade/14_9/schedule @@ -406,6 +406,7 @@ BABEL-4078 BABEL-3215 orderby BABEL-4046 +table_constraint_wo_comma-before-15_6-or-16_2 getdate BABEL_4330 BABEL-2619 @@ -413,6 +414,7 @@ BABEL-4410 AUTO_ANALYZE-before-15-5-or-14-10 default_params cast_eliminate +order_by_offset_fetch_rows-before-15_6-or-16_2 TestDatatypeAggSort babel_index_nulls_order-before-15-5 operator_binary_whitespace-before-15_6-or-16_2 diff --git a/test/JDBC/upgrade/15_1/schedule b/test/JDBC/upgrade/15_1/schedule index 80a07eb8081..9f5b43609f3 100644 --- a/test/JDBC/upgrade/15_1/schedule +++ b/test/JDBC/upgrade/15_1/schedule @@ -385,11 +385,13 @@ TestXML timefromparts triggers_with_transaction BABEL-4046 +table_constraint_wo_comma-before-15_6-or-16_2 getdate BABEL_4330 AUTO_ANALYZE-before-15-5-or-14-10 default_params cast_eliminate +order_by_offset_fetch_rows-before-15_6-or-16_2 TestDatatypeAggSort babel_index_nulls_order-before-15-5 operator_binary_whitespace-before-15_6-or-16_2 diff --git a/test/JDBC/upgrade/15_1/verification_cleanup/13_5/sys-assembly_types-vu-verify.sql b/test/JDBC/upgrade/15_1/verification_cleanup/13_5/sys-assembly_types-vu-verify.sql index 4dff5510fee..0bb2b45bad2 100644 --- a/test/JDBC/upgrade/15_1/verification_cleanup/13_5/sys-assembly_types-vu-verify.sql +++ b/test/JDBC/upgrade/15_1/verification_cleanup/13_5/sys-assembly_types-vu-verify.sql @@ -8,5 +8,5 @@ SELECT * FROM sys_assembly_types_func_vu_prepare() GO -- Test from sys-assembly_types.sql -SELECT * FROM sys.assembly_types +SELECT name, principal_id, max_length, precision, scale, collation_name, is_nullable, is_user_defined, is_assembly_type, default_object_id, rule_object_id, assembly_id, assembly_class, is_binary_ordered, is_fixed_length, prog_id, assembly_qualified_name, is_table_type FROM sys.assembly_types GO diff --git a/test/JDBC/upgrade/15_1/verification_cleanup/13_6/sys-assembly_types-vu-verify.sql b/test/JDBC/upgrade/15_1/verification_cleanup/13_6/sys-assembly_types-vu-verify.sql index 4dff5510fee..0bb2b45bad2 100644 --- a/test/JDBC/upgrade/15_1/verification_cleanup/13_6/sys-assembly_types-vu-verify.sql +++ b/test/JDBC/upgrade/15_1/verification_cleanup/13_6/sys-assembly_types-vu-verify.sql @@ -8,5 +8,5 @@ SELECT * FROM sys_assembly_types_func_vu_prepare() GO -- Test from sys-assembly_types.sql -SELECT * FROM sys.assembly_types +SELECT name, principal_id, max_length, precision, scale, collation_name, is_nullable, is_user_defined, is_assembly_type, default_object_id, rule_object_id, assembly_id, assembly_class, is_binary_ordered, is_fixed_length, prog_id, assembly_qualified_name, is_table_type FROM sys.assembly_types GO diff --git a/test/JDBC/upgrade/15_1/verification_cleanup/13_7/sys-assembly_types-vu-verify.sql b/test/JDBC/upgrade/15_1/verification_cleanup/13_7/sys-assembly_types-vu-verify.sql index 4dff5510fee..0bb2b45bad2 100644 --- a/test/JDBC/upgrade/15_1/verification_cleanup/13_7/sys-assembly_types-vu-verify.sql +++ b/test/JDBC/upgrade/15_1/verification_cleanup/13_7/sys-assembly_types-vu-verify.sql @@ -8,5 +8,5 @@ SELECT * FROM sys_assembly_types_func_vu_prepare() GO -- Test from sys-assembly_types.sql -SELECT * FROM sys.assembly_types +SELECT name, principal_id, max_length, precision, scale, collation_name, is_nullable, is_user_defined, is_assembly_type, default_object_id, rule_object_id, assembly_id, assembly_class, is_binary_ordered, is_fixed_length, prog_id, assembly_qualified_name, is_table_type FROM sys.assembly_types GO diff --git a/test/JDBC/upgrade/15_1/verification_cleanup/13_8/sys-assembly_types-vu-verify.sql b/test/JDBC/upgrade/15_1/verification_cleanup/13_8/sys-assembly_types-vu-verify.sql index 4dff5510fee..0bb2b45bad2 100644 --- a/test/JDBC/upgrade/15_1/verification_cleanup/13_8/sys-assembly_types-vu-verify.sql +++ b/test/JDBC/upgrade/15_1/verification_cleanup/13_8/sys-assembly_types-vu-verify.sql @@ -8,5 +8,5 @@ SELECT * FROM sys_assembly_types_func_vu_prepare() GO -- Test from sys-assembly_types.sql -SELECT * FROM sys.assembly_types +SELECT name, principal_id, max_length, precision, scale, collation_name, is_nullable, is_user_defined, is_assembly_type, default_object_id, rule_object_id, assembly_id, assembly_class, is_binary_ordered, is_fixed_length, prog_id, assembly_qualified_name, is_table_type FROM sys.assembly_types GO diff --git a/test/JDBC/upgrade/15_1/verification_cleanup/13_9/sys-assembly_types-vu-verify.sql b/test/JDBC/upgrade/15_1/verification_cleanup/13_9/sys-assembly_types-vu-verify.sql index 4dff5510fee..0bb2b45bad2 100644 --- a/test/JDBC/upgrade/15_1/verification_cleanup/13_9/sys-assembly_types-vu-verify.sql +++ b/test/JDBC/upgrade/15_1/verification_cleanup/13_9/sys-assembly_types-vu-verify.sql @@ -8,5 +8,5 @@ SELECT * FROM sys_assembly_types_func_vu_prepare() GO -- Test from sys-assembly_types.sql -SELECT * FROM sys.assembly_types +SELECT name, principal_id, max_length, precision, scale, collation_name, is_nullable, is_user_defined, is_assembly_type, default_object_id, rule_object_id, assembly_id, assembly_class, is_binary_ordered, is_fixed_length, prog_id, assembly_qualified_name, is_table_type FROM sys.assembly_types GO diff --git a/test/JDBC/upgrade/15_1/verification_cleanup/14_3/sys-assembly_types-vu-verify.sql b/test/JDBC/upgrade/15_1/verification_cleanup/14_3/sys-assembly_types-vu-verify.sql index 4dff5510fee..0bb2b45bad2 100644 --- a/test/JDBC/upgrade/15_1/verification_cleanup/14_3/sys-assembly_types-vu-verify.sql +++ b/test/JDBC/upgrade/15_1/verification_cleanup/14_3/sys-assembly_types-vu-verify.sql @@ -8,5 +8,5 @@ SELECT * FROM sys_assembly_types_func_vu_prepare() GO -- Test from sys-assembly_types.sql -SELECT * FROM sys.assembly_types +SELECT name, principal_id, max_length, precision, scale, collation_name, is_nullable, is_user_defined, is_assembly_type, default_object_id, rule_object_id, assembly_id, assembly_class, is_binary_ordered, is_fixed_length, prog_id, assembly_qualified_name, is_table_type FROM sys.assembly_types GO diff --git a/test/JDBC/upgrade/15_2/schedule b/test/JDBC/upgrade/15_2/schedule index c45f31b29d2..6a91ed3fabc 100644 --- a/test/JDBC/upgrade/15_2/schedule +++ b/test/JDBC/upgrade/15_2/schedule @@ -414,12 +414,14 @@ timefromparts triggers_with_transaction datetimeoffset-timezone-before-15_3 BABEL-4046 +table_constraint_wo_comma-before-15_6-or-16_2 getdate BABEL_4330 BABEL-4410 AUTO_ANALYZE-before-15-5-or-14-10 default_params cast_eliminate +order_by_offset_fetch_rows-before-15_6-or-16_2 TestDatatypeAggSort babel_index_nulls_order-before-15-5 operator_binary_whitespace-before-15_6-or-16_2 @@ -428,4 +430,5 @@ drop_index-before-15_6-or-16_2 BABEL-4606 permission_restrictions_from_pg BABEL-730-before-15_6-or-16_1 +GRANT_SCHEMA babel-4475 diff --git a/test/JDBC/upgrade/15_3/schedule b/test/JDBC/upgrade/15_3/schedule index f0b62ba48c4..19298c87653 100644 --- a/test/JDBC/upgrade/15_3/schedule +++ b/test/JDBC/upgrade/15_3/schedule @@ -437,11 +437,13 @@ timefromparts triggers_with_transaction datetimeoffset-timezone BABEL-4046 +table_constraint_wo_comma-before-15_6-or-16_2 getdate BABEL_4330 AUTO_ANALYZE-before-15-5-or-14-10 default_params cast_eliminate +order_by_offset_fetch_rows-before-15_6-or-16_2 TestDatatypeAggSort babel_index_nulls_order-before-15-5 operator_binary_whitespace-before-15_6-or-16_2 diff --git a/test/JDBC/upgrade/15_4/schedule b/test/JDBC/upgrade/15_4/schedule index 788a7f5a83a..754123ac70a 100644 --- a/test/JDBC/upgrade/15_4/schedule +++ b/test/JDBC/upgrade/15_4/schedule @@ -445,6 +445,7 @@ timefromparts triggers_with_transaction datetimeoffset-timezone BABEL-4046 +table_constraint_wo_comma-before-15_6-or-16_2 host_id linked_srv_4229 BABEL-4175 @@ -454,6 +455,7 @@ BABEL-4410 AUTO_ANALYZE-before-15-5-or-14-10 default_params cast_eliminate +order_by_offset_fetch_rows-before-15_6-or-16_2 TestDatatypeAggSort babel_index_nulls_order-before-15-5 operator_binary_whitespace-before-15_6-or-16_2 @@ -462,3 +464,4 @@ drop_index-before-15_6-or-16_2 BABEL-4606 permission_restrictions_from_pg BABEL-730-before-15_6-or-16_1 +GRANT_SCHEMA diff --git a/test/JDBC/upgrade/15_5/schedule b/test/JDBC/upgrade/15_5/schedule index 46dcdc1d0f8..cb95ff840d3 100644 --- a/test/JDBC/upgrade/15_5/schedule +++ b/test/JDBC/upgrade/15_5/schedule @@ -420,7 +420,6 @@ TestRowVersion TestSmallDatetime TestSmallInt TestSmallMoney -TestSpatialPoint Test-sp_addrole Test-sp_addrolemember Test-sp_babelfish_volatility @@ -462,6 +461,7 @@ alter_authorization_change_db_owner sp_changedbowner datetimeoffset-timezone BABEL-4046 +table_constraint_wo_comma-before-15_6-or-16_2 host_id linked_srv_4229 BABEL-4175 @@ -482,6 +482,7 @@ BABEL-4484 pivot #AUTO_ANALYZE #uncomment this test when preparing for new minor version cast_eliminate +order_by_offset_fetch_rows-before-15_6-or-16_2 TestDatatypeAggSort babel_index_nulls_order operator_binary_whitespace-before-15_6-or-16_2 diff --git a/test/JDBC/upgrade/latest/schedule b/test/JDBC/upgrade/latest/schedule index f581ee193ff..72a67eb6fff 100644 --- a/test/JDBC/upgrade/latest/schedule +++ b/test/JDBC/upgrade/latest/schedule @@ -461,6 +461,7 @@ TestXML timefromparts todatetimeoffset-dep triggers_with_transaction +order_by_offset_fetch_rows typeid-typename typeid-typename-dep print_null @@ -504,5 +505,6 @@ BABEL-4606 BABEL-4529 sys_availability_groups sys_availability_replicas +table_constraint_without_comma BABEL-730 babel-4475 diff --git a/test/JDBC/upgrade/latest/verification_cleanup/13_5/sys-assembly_types-vu-verify.sql b/test/JDBC/upgrade/latest/verification_cleanup/13_5/sys-assembly_types-vu-verify.sql index 4dff5510fee..0bb2b45bad2 100644 --- a/test/JDBC/upgrade/latest/verification_cleanup/13_5/sys-assembly_types-vu-verify.sql +++ b/test/JDBC/upgrade/latest/verification_cleanup/13_5/sys-assembly_types-vu-verify.sql @@ -8,5 +8,5 @@ SELECT * FROM sys_assembly_types_func_vu_prepare() GO -- Test from sys-assembly_types.sql -SELECT * FROM sys.assembly_types +SELECT name, principal_id, max_length, precision, scale, collation_name, is_nullable, is_user_defined, is_assembly_type, default_object_id, rule_object_id, assembly_id, assembly_class, is_binary_ordered, is_fixed_length, prog_id, assembly_qualified_name, is_table_type FROM sys.assembly_types GO diff --git a/test/JDBC/upgrade/latest/verification_cleanup/13_6/sys-assembly_types-vu-verify.sql b/test/JDBC/upgrade/latest/verification_cleanup/13_6/sys-assembly_types-vu-verify.sql index 4dff5510fee..0bb2b45bad2 100644 --- a/test/JDBC/upgrade/latest/verification_cleanup/13_6/sys-assembly_types-vu-verify.sql +++ b/test/JDBC/upgrade/latest/verification_cleanup/13_6/sys-assembly_types-vu-verify.sql @@ -8,5 +8,5 @@ SELECT * FROM sys_assembly_types_func_vu_prepare() GO -- Test from sys-assembly_types.sql -SELECT * FROM sys.assembly_types +SELECT name, principal_id, max_length, precision, scale, collation_name, is_nullable, is_user_defined, is_assembly_type, default_object_id, rule_object_id, assembly_id, assembly_class, is_binary_ordered, is_fixed_length, prog_id, assembly_qualified_name, is_table_type FROM sys.assembly_types GO diff --git a/test/JDBC/upgrade/latest/verification_cleanup/13_7/sys-assembly_types-vu-verify.sql b/test/JDBC/upgrade/latest/verification_cleanup/13_7/sys-assembly_types-vu-verify.sql index 4dff5510fee..0bb2b45bad2 100644 --- a/test/JDBC/upgrade/latest/verification_cleanup/13_7/sys-assembly_types-vu-verify.sql +++ b/test/JDBC/upgrade/latest/verification_cleanup/13_7/sys-assembly_types-vu-verify.sql @@ -8,5 +8,5 @@ SELECT * FROM sys_assembly_types_func_vu_prepare() GO -- Test from sys-assembly_types.sql -SELECT * FROM sys.assembly_types +SELECT name, principal_id, max_length, precision, scale, collation_name, is_nullable, is_user_defined, is_assembly_type, default_object_id, rule_object_id, assembly_id, assembly_class, is_binary_ordered, is_fixed_length, prog_id, assembly_qualified_name, is_table_type FROM sys.assembly_types GO diff --git a/test/JDBC/upgrade/latest/verification_cleanup/13_8/sys-assembly_types-vu-verify.sql b/test/JDBC/upgrade/latest/verification_cleanup/13_8/sys-assembly_types-vu-verify.sql index 4dff5510fee..0bb2b45bad2 100644 --- a/test/JDBC/upgrade/latest/verification_cleanup/13_8/sys-assembly_types-vu-verify.sql +++ b/test/JDBC/upgrade/latest/verification_cleanup/13_8/sys-assembly_types-vu-verify.sql @@ -8,5 +8,5 @@ SELECT * FROM sys_assembly_types_func_vu_prepare() GO -- Test from sys-assembly_types.sql -SELECT * FROM sys.assembly_types +SELECT name, principal_id, max_length, precision, scale, collation_name, is_nullable, is_user_defined, is_assembly_type, default_object_id, rule_object_id, assembly_id, assembly_class, is_binary_ordered, is_fixed_length, prog_id, assembly_qualified_name, is_table_type FROM sys.assembly_types GO diff --git a/test/JDBC/upgrade/latest/verification_cleanup/13_9/sys-assembly_types-vu-verify.sql b/test/JDBC/upgrade/latest/verification_cleanup/13_9/sys-assembly_types-vu-verify.sql index 4dff5510fee..0bb2b45bad2 100644 --- a/test/JDBC/upgrade/latest/verification_cleanup/13_9/sys-assembly_types-vu-verify.sql +++ b/test/JDBC/upgrade/latest/verification_cleanup/13_9/sys-assembly_types-vu-verify.sql @@ -8,5 +8,5 @@ SELECT * FROM sys_assembly_types_func_vu_prepare() GO -- Test from sys-assembly_types.sql -SELECT * FROM sys.assembly_types +SELECT name, principal_id, max_length, precision, scale, collation_name, is_nullable, is_user_defined, is_assembly_type, default_object_id, rule_object_id, assembly_id, assembly_class, is_binary_ordered, is_fixed_length, prog_id, assembly_qualified_name, is_table_type FROM sys.assembly_types GO diff --git a/test/JDBC/upgrade/latest/verification_cleanup/14_3/sys-assembly_types-vu-verify.sql b/test/JDBC/upgrade/latest/verification_cleanup/14_3/sys-assembly_types-vu-verify.sql index 4dff5510fee..0bb2b45bad2 100644 --- a/test/JDBC/upgrade/latest/verification_cleanup/14_3/sys-assembly_types-vu-verify.sql +++ b/test/JDBC/upgrade/latest/verification_cleanup/14_3/sys-assembly_types-vu-verify.sql @@ -8,5 +8,5 @@ SELECT * FROM sys_assembly_types_func_vu_prepare() GO -- Test from sys-assembly_types.sql -SELECT * FROM sys.assembly_types +SELECT name, principal_id, max_length, precision, scale, collation_name, is_nullable, is_user_defined, is_assembly_type, default_object_id, rule_object_id, assembly_id, assembly_class, is_binary_ordered, is_fixed_length, prog_id, assembly_qualified_name, is_table_type FROM sys.assembly_types GO diff --git a/test/dotnet/ExpectedOutput/TestPoint.out b/test/dotnet/ExpectedOutput/TestPoint.out index 402c335bfc6..c7e73919115 100644 --- a/test/dotnet/ExpectedOutput/TestPoint.out +++ b/test/dotnet/ExpectedOutput/TestPoint.out @@ -24,7 +24,7 @@ #Q#INSERT INTO POINTGEOG_dt(location) values(geography::STGeomFromText('Point(47.65100 -22.34900)', 4326)) #Q#INSERT INTO POINTGEOG_dt(location) values(geography::STPointFromText('Point(47.65100 -22.34900)', 4326)) #Q#INSERT INTO POINTGEOG_dt(location) values(geography::Point(47.65100, -22.34900, 4326)) -#Q#SELECT STAsText(location) FROM POINTGEOM_dt; +#Q#SELECT location.STAsText() FROM POINTGEOM_dt; #D#text POINT(47.651 -22.349) POINT(1 2) @@ -33,14 +33,14 @@ POINT(47.651 -22.349) POINT(47.651 -22.349) POINT(47.651 -22.349) POINT(47.651 -22.349) -#Q#SELECT STAsText(location) FROM POINTGEOG_dt; +#Q#SELECT location.STAsText() FROM POINTGEOG_dt; #D#text POINT(47.651 -22.349) POINT(1 2) POINT(47.651 -22.349) POINT(47.651 -22.349) POINT(-22.349 47.651) -#Q#SELECT STAsText(geom), STAsText(geog) FROM POINT_dt; +#Q#SELECT geom.STAsText(), geog.STAsText() FROM POINT_dt; #D#text#!#text POINT(47.651 -22.349)#!# #!#POINT(47.651 -22.349) diff --git a/test/dotnet/input/Datatypes/TestPoint.txt b/test/dotnet/input/Datatypes/TestPoint.txt index 78d99065345..d5e6b3f7bff 100644 --- a/test/dotnet/input/Datatypes/TestPoint.txt +++ b/test/dotnet/input/Datatypes/TestPoint.txt @@ -40,9 +40,9 @@ INSERT INTO POINTGEOG_dt(location) values(geography::STGeomFromText('Point(47.65 INSERT INTO POINTGEOG_dt(location) values(geography::STPointFromText('Point(47.65100 -22.34900)', 4326)) INSERT INTO POINTGEOG_dt(location) values(geography::Point(47.65100, -22.34900, 4326)) -SELECT STAsText(location) FROM POINTGEOM_dt; -SELECT STAsText(location) FROM POINTGEOG_dt; -SELECT STAsText(geom), STAsText(geog) FROM POINT_dt; +SELECT location.STAsText() FROM POINTGEOM_dt; +SELECT location.STAsText() FROM POINTGEOG_dt; +SELECT geom.STAsText(), geog.STAsText() FROM POINT_dt; DROP TABLE IF EXISTS POINTGEOM_dt; DROP TABLE IF EXISTS POINTGEOG_dt; diff --git a/test/python/expected/sql_validation_framework/expected_create.out b/test/python/expected/sql_validation_framework/expected_create.out index 08981826b0a..3c6e166f591 100644 --- a/test/python/expected/sql_validation_framework/expected_create.out +++ b/test/python/expected/sql_validation_framework/expected_create.out @@ -194,6 +194,7 @@ Could not find upgrade tests for procedure sys.sp_unprepare Could not find upgrade tests for procedure sys.sp_updatestats Could not find upgrade tests for table sys.babelfish_configurations Could not find upgrade tests for table sys.babelfish_helpcollation +Could not find upgrade tests for table sys.babelfish_schema_permissions Could not find upgrade tests for table sys.babelfish_syslanguages Could not find upgrade tests for table sys.service_settings Could not find upgrade tests for table sys.spt_datatype_info_table diff --git a/test/python/expected/upgrade_validation/expected_dependency.out b/test/python/expected/upgrade_validation/expected_dependency.out index d3aeaaed078..ad6931ef3c6 100644 --- a/test/python/expected/upgrade_validation/expected_dependency.out +++ b/test/python/expected/upgrade_validation/expected_dependency.out @@ -457,7 +457,6 @@ Function sys.geography(sys.bbf_varbinary) Function sys.geography(sys.bpchar) Function sys.geography(sys.geography,integer,boolean) Function sys.geography(text,integer,boolean) -Function sys.geography__point(double precision,double precision,integer) Function sys.geography__stflipcoordinates(sys.geography) Function sys.geography__stgeomfromtext(text,integer) Function sys.geography__stpointfromtext(text,integer)